Explorar el Código

Merge branch 'recodr-detail'

mo hace 1 año
padre
commit
7591e59eef
Se han modificado 39 ficheros con 2019 adiciones y 177 borrados
  1. 624 8
      package-lock.json
  2. 4 0
      package.json
  3. BIN
      src/common/images/smallLogo.png
  4. 26 0
      src/components/m-qrcode/index.module.less
  5. 63 0
      src/components/m-qrcode/index.tsx
  6. 20 0
      src/helpers/utils.ts
  7. 8 0
      src/router/router-root.ts
  8. 1 1
      src/router/routes-common.ts
  9. 149 0
      src/views/activity-record/detail-swiper.tsx
  10. 613 28
      src/views/activity-record/detail.module.less
  11. 510 139
      src/views/activity-record/detail.tsx
  12. BIN
      src/views/activity-record/images/array-icon.png
  13. BIN
      src/views/activity-record/images/back-icon.png
  14. BIN
      src/views/activity-record/images/bottomBg.png
  15. BIN
      src/views/activity-record/images/c-ball.png
  16. BIN
      src/views/activity-record/images/colorBg.png
  17. BIN
      src/views/activity-record/images/d-ball.png
  18. BIN
      src/views/activity-record/images/detailBG.png
  19. BIN
      src/views/activity-record/images/die-icon.png
  20. BIN
      src/views/activity-record/images/dot-icon.png
  21. BIN
      src/views/activity-record/images/eidt-icon.png
  22. BIN
      src/views/activity-record/images/h-ball.png
  23. BIN
      src/views/activity-record/images/horn-icon.png
  24. BIN
      src/views/activity-record/images/iconSaveImage.png
  25. BIN
      src/views/activity-record/images/iconWechat.png
  26. BIN
      src/views/activity-record/images/jiemu-icon.png
  27. BIN
      src/views/activity-record/images/logo.png
  28. BIN
      src/views/activity-record/images/note-icon.png
  29. BIN
      src/views/activity-record/images/palyBtn.png
  30. BIN
      src/views/activity-record/images/popupQrcodeBg.png
  31. BIN
      src/views/activity-record/images/programTitle.png
  32. BIN
      src/views/activity-record/images/q-ball.png
  33. BIN
      src/views/activity-record/images/schoolIcon.png
  34. BIN
      src/views/activity-record/images/share-icon.png
  35. BIN
      src/views/activity-record/images/shareBg.png
  36. BIN
      src/views/activity-record/images/shareBottom.png
  37. BIN
      src/views/activity-record/images/timerBg.png
  38. BIN
      src/views/activity-record/images/typeCard.png
  39. 1 1
      src/views/activity-record/skeletion-detail-modal.tsx

+ 624 - 8
package-lock.json

@@ -15,14 +15,18 @@
         "clean-deep": "^3.4.0",
         "dayjs": "^1.11.7",
         "echarts": "^5.4.2",
+        "html2canvas": "^1.4.1",
         "numeral": "^2.0.6",
         "plyr": "^3.7.8",
+        "qrcode": "^1.5.3",
         "query-string": "^8.1.0",
+        "swiper": "^9.3.2",
         "terser": "^5.17.6",
         "umi-request": "^1.4.0",
         "vant": "^4.1.2",
         "vconsole": "^3.15.0",
         "vue": "^3.2.47",
+        "vue-awesome-swiper": "^5.0.1",
         "vue-router": "^4.1.6",
         "vue3-lottie": "^2.7.0"
       },
@@ -3019,7 +3023,6 @@
       "version": "5.0.1",
       "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
       "engines": {
         "node": ">=8"
       }
@@ -3168,6 +3171,14 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "node_modules/base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
@@ -3453,6 +3464,82 @@
         "node": ">= 10"
       }
     },
+    "node_modules/cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      }
+    },
+    "node_modules/cliui/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/cliui/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "node_modules/cliui/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/cliui/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui/node_modules/wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/clone": {
       "version": "1.0.4",
       "resolved": "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz",
@@ -3561,6 +3648,14 @@
         "node": ">= 8"
       }
     },
+    "node_modules/css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/cssesc": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@@ -3611,6 +3706,14 @@
         }
       }
     },
+    "node_modules/decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/decode-uri-component": {
       "version": "0.4.1",
       "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz",
@@ -3675,6 +3778,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/dijkstrajs": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+      "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
+    },
     "node_modules/dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -3741,6 +3849,11 @@
       "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
       "dev": true
     },
+    "node_modules/encode-utf8": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
+      "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
+    },
     "node_modules/encoding": {
       "version": "0.1.13",
       "resolved": "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz",
@@ -4479,6 +4592,14 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
     "node_modules/get-intrinsic": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
@@ -4705,6 +4826,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "dependencies": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/human-signals": {
       "version": "4.3.1",
       "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz",
@@ -6353,6 +6486,14 @@
         "node": ">=10"
       }
     },
+    "node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
@@ -6431,7 +6572,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
       "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true,
       "engines": {
         "node": ">=8"
       }
@@ -6569,6 +6709,14 @@
         "url-polyfill": "^1.1.12"
       }
     },
+    "node_modules/pngjs": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
+      "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.4.23",
       "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.23.tgz",
@@ -6665,6 +6813,23 @@
         "node": ">=6"
       }
     },
+    "node_modules/qrcode": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz",
+      "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
+      "dependencies": {
+        "dijkstrajs": "^1.0.1",
+        "encode-utf8": "^1.0.3",
+        "pngjs": "^5.0.0",
+        "yargs": "^15.3.1"
+      },
+      "bin": {
+        "qrcode": "bin/qrcode"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
     "node_modules/qs": {
       "version": "6.11.1",
       "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.1.tgz",
@@ -6808,6 +6973,19 @@
         "jsesc": "bin/jsesc"
       }
     },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+    },
     "node_modules/resolve": {
       "version": "1.22.2",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz",
@@ -6987,6 +7165,11 @@
         "upper-case-first": "^2.0.2"
       }
     },
+    "node_modules/set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+    },
     "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -7104,6 +7287,11 @@
         "node": ">=12"
       }
     },
+    "node_modules/ssr-window": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
+      "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
+    },
     "node_modules/stdin-discarder": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
@@ -7173,7 +7361,6 @@
       "version": "6.0.1",
       "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
       "dependencies": {
         "ansi-regex": "^5.0.1"
       },
@@ -7244,6 +7431,17 @@
       "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
       "dev": true
     },
+    "node_modules/swiper": {
+      "version": "9.3.2",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-9.3.2.tgz",
+      "integrity": "sha512-Kj9Z4kXRmJR3YT/Wj+XLWj8P6IcRt+WG38uL8M3/Wny7+6sV0TlP9vnE1X+Co9c7VzNooojWGnFa+Wf/9+CUMA==",
+      "dependencies": {
+        "ssr-window": "^4.0.2"
+      },
+      "engines": {
+        "node": ">= 4.7.0"
+      }
+    },
     "node_modules/systemjs": {
       "version": "6.14.1",
       "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-6.14.1.tgz",
@@ -7272,6 +7470,14 @@
       "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
     },
+    "node_modules/text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
@@ -7591,6 +7797,14 @@
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
+    "node_modules/utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "dependencies": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "node_modules/v8flags": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/v8flags/-/v8flags-4.0.0.tgz",
@@ -7726,6 +7940,15 @@
         "@vue/shared": "3.2.47"
       }
     },
+    "node_modules/vue-awesome-swiper": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
+      "integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg==",
+      "peerDependencies": {
+        "swiper": "^7.0.0  || ^8.0.0",
+        "vue": "3.x"
+      }
+    },
     "node_modules/vue-demi": {
       "version": "0.14.5",
       "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz",
@@ -7954,6 +8177,11 @@
         "node": ">= 8"
       }
     },
+    "node_modules/which-module": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
+      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
+    },
     "node_modules/word-wrap": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -8057,6 +8285,11 @@
         "node": ">=12"
       }
     },
+    "node_modules/y18n": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+    },
     "node_modules/yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
@@ -8072,6 +8305,118 @@
         "node": ">= 14"
       }
     },
+    "node_modules/yargs": {
+      "version": "15.4.1",
+      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
+      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "dependencies": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^18.1.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs-parser": {
+      "version": "18.1.3",
+      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
+      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs-parser/node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/yargs/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/yargs/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/yargs/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
@@ -10297,8 +10642,7 @@
     "ansi-regex": {
       "version": "5.0.1",
       "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
     },
     "ansi-styles": {
       "version": "3.2.1",
@@ -10408,6 +10752,11 @@
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
+    },
     "base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
@@ -10648,6 +10997,69 @@
       "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
       "dev": true
     },
+    "cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+      "requires": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+        },
+        "string-width": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.1"
+          }
+        },
+        "wrap-ansi": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0"
+          }
+        }
+      }
+    },
     "clone": {
       "version": "1.0.4",
       "resolved": "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz",
@@ -10743,6 +11155,14 @@
         "which": "^2.0.1"
       }
     },
+    "css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "requires": {
+        "utrie": "^1.0.2"
+      }
+    },
     "cssesc": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
@@ -10779,6 +11199,11 @@
         "ms": "2.1.2"
       }
     },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
+    },
     "decode-uri-component": {
       "version": "0.4.1",
       "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.4.1.tgz",
@@ -10831,6 +11256,11 @@
       "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
       "dev": true
     },
+    "dijkstrajs": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+      "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
+    },
     "dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -10893,6 +11323,11 @@
       "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
       "dev": true
     },
+    "encode-utf8": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
+      "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
+    },
     "encoding": {
       "version": "0.1.13",
       "resolved": "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz",
@@ -11467,6 +11902,11 @@
       "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
       "dev": true
     },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
+    },
     "get-intrinsic": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
@@ -11645,6 +12085,15 @@
       "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
       "dev": true
     },
+    "html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "requires": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      }
+    },
     "human-signals": {
       "version": "4.3.1",
       "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz",
@@ -12948,6 +13397,11 @@
         "aggregate-error": "^3.0.0"
       }
     },
+    "p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
+    },
     "param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
@@ -13013,8 +13467,7 @@
     "path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
     },
     "path-is-absolute": {
       "version": "1.0.1",
@@ -13115,6 +13568,11 @@
         "url-polyfill": "^1.1.12"
       }
     },
+    "pngjs": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
+      "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
+    },
     "postcss": {
       "version": "8.4.23",
       "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.23.tgz",
@@ -13187,6 +13645,17 @@
       "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
       "dev": true
     },
+    "qrcode": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.3.tgz",
+      "integrity": "sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==",
+      "requires": {
+        "dijkstrajs": "^1.0.1",
+        "encode-utf8": "^1.0.3",
+        "pngjs": "^5.0.0",
+        "yargs": "^15.3.1"
+      }
+    },
     "qs": {
       "version": "6.11.1",
       "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.1.tgz",
@@ -13305,6 +13774,16 @@
         }
       }
     },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
+    },
+    "require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+    },
     "resolve": {
       "version": "1.22.2",
       "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz",
@@ -13448,6 +13927,11 @@
         "upper-case-first": "^2.0.2"
       }
     },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+    },
     "shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -13542,6 +14026,11 @@
       "resolved": "https://registry.npmmirror.com/split-on-first/-/split-on-first-3.0.0.tgz",
       "integrity": "sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA=="
     },
+    "ssr-window": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-4.0.2.tgz",
+      "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ=="
+    },
     "stdin-discarder": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
@@ -13598,7 +14087,6 @@
       "version": "6.0.1",
       "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
       "requires": {
         "ansi-regex": "^5.0.1"
       }
@@ -13648,6 +14136,14 @@
       "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
       "dev": true
     },
+    "swiper": {
+      "version": "9.3.2",
+      "resolved": "https://registry.npmmirror.com/swiper/-/swiper-9.3.2.tgz",
+      "integrity": "sha512-Kj9Z4kXRmJR3YT/Wj+XLWj8P6IcRt+WG38uL8M3/Wny7+6sV0TlP9vnE1X+Co9c7VzNooojWGnFa+Wf/9+CUMA==",
+      "requires": {
+        "ssr-window": "^4.0.2"
+      }
+    },
     "systemjs": {
       "version": "6.14.1",
       "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-6.14.1.tgz",
@@ -13672,6 +14168,14 @@
         }
       }
     },
+    "text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "requires": {
+        "utrie": "^1.0.2"
+      }
+    },
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
@@ -13918,6 +14422,14 @@
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
+    "utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "requires": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "v8flags": {
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/v8flags/-/v8flags-4.0.0.tgz",
@@ -14000,6 +14512,11 @@
         "@vue/shared": "3.2.47"
       }
     },
+    "vue-awesome-swiper": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/vue-awesome-swiper/-/vue-awesome-swiper-5.0.1.tgz",
+      "integrity": "sha512-mWjFJzUqA4lG+DmsmibvMpoiBnl+IH2SSeiiQ3i5M0t1y9FknTxnGT0DsMb2YdJLgjYMEK3sYOWzqgLnZMH8Lg=="
+    },
     "vue-demi": {
       "version": "0.14.5",
       "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz",
@@ -14161,6 +14678,11 @@
         "isexe": "^2.0.0"
       }
     },
+    "which-module": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
+      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
+    },
     "word-wrap": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.3.tgz",
@@ -14245,6 +14767,11 @@
       "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
       "dev": true
     },
+    "y18n": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+    },
     "yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
@@ -14257,6 +14784,95 @@
       "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
       "dev": true
     },
+    "yargs": {
+      "version": "15.4.1",
+      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
+      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "requires": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^18.1.2"
+      },
+      "dependencies": {
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+          "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "string-width": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+          "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.1"
+          }
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "18.1.3",
+      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
+      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "requires": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
+        }
+      }
+    },
     "yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",

+ 4 - 0
package.json

@@ -28,14 +28,18 @@
     "clean-deep": "^3.4.0",
     "dayjs": "^1.11.7",
     "echarts": "^5.4.2",
+    "html2canvas": "^1.4.1",
     "numeral": "^2.0.6",
     "plyr": "^3.7.8",
+    "qrcode": "^1.5.3",
     "query-string": "^8.1.0",
+    "swiper": "^9.3.2",
     "terser": "^5.17.6",
     "umi-request": "^1.4.0",
     "vant": "^4.1.2",
     "vconsole": "^3.15.0",
     "vue": "^3.2.47",
+    "vue-awesome-swiper": "^5.0.1",
     "vue-router": "^4.1.6",
     "vue3-lottie": "^2.7.0"
   },

BIN
src/common/images/smallLogo.png


+ 26 - 0
src/components/m-qrcode/index.module.less

@@ -0,0 +1,26 @@
+.qrcode {
+  position: relative;
+
+  .qrcodeCanvas {
+    width: 100% !important;
+    height: 100% !important;
+  }
+
+  .qrcodeLogo {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    margin-left: -20px;
+    margin-top: -20px;
+    width: 40px !important;
+    height: 40px !important;
+    border-radius: 4px;
+
+    &.small {
+      margin-left: -10px;
+      margin-top: -10px;
+      width: 20px !important;
+      height: 20px !important;
+    }
+  }
+}

+ 63 - 0
src/components/m-qrcode/index.tsx

@@ -0,0 +1,63 @@
+import { defineComponent, nextTick, onMounted, ref, watch } from 'vue';
+import logo from '@common/images/smallLogo.png';
+import QRCode from 'qrcode';
+import styles from './index.module.less';
+
+export default defineComponent({
+  props: {
+    text: {
+      type: String,
+      default: ''
+    },
+    size: {
+      type: String,
+      default: '200px'
+    },
+    logoSize: {
+      type: String,
+      default: 'default'
+    }
+  },
+  setup(props) {
+    const canvas = ref();
+
+    const init = () => {
+      QRCode.toCanvas(
+        canvas.value,
+        props.text,
+        {
+          margin: 1
+        },
+        (error: any) => {
+          if (error) console.log(error);
+          console.log('success');
+        }
+      );
+    };
+    watch(
+      () => props.text,
+      () => {
+        init();
+      }
+    );
+    onMounted(() => {
+      nextTick(() => {
+        init();
+      });
+    });
+    return () => (
+      <div
+        class={styles.qrcode}
+        style={{ width: props.size, height: props.size }}>
+        <canvas ref={canvas} class={styles.qrcodeCanvas}></canvas>
+        <img
+          src={logo}
+          class={[
+            styles.qrcodeLogo,
+            props.logoSize === 'small' && styles.small
+          ]}
+        />
+      </div>
+    );
+  }
+});

+ 20 - 0
src/helpers/utils.ts

@@ -132,3 +132,23 @@ export const toChinesNum = (num: any) => {
   }
   return overWan ? getWan(overWan) + '万' + getWan(noWan) : getWan(num);
 };
+
+// 教务地址
+export function vaildTeachingUrl() {
+  let url = window.location.href;
+  let returnUrl = '';
+  if (/online/.test(url)) {
+    //线上
+    returnUrl = 'https://manonline.dayaedu.com';
+  } else if (/dev/.test(url)) {
+    // dev 环境
+    returnUrl = 'http://mandev.dayaedu.com';
+  } else if (/test/.test(url)) {
+    // dev 环境
+    returnUrl = 'http://mantest.dayaedu.com';
+  } else {
+    // 默认dev环境
+    returnUrl = 'http://mantest.dayaedu.com';
+  }
+  return returnUrl;
+}

+ 8 - 0
src/router/router-root.ts

@@ -54,5 +54,13 @@ export default [
     meta: {
       title: '404'
     }
+  },
+  {
+    path: '/activity-record-detail',
+    name: 'activity-record-detail',
+    component: () => import('@/views/activity-record/detail'),
+    meta: {
+      title: '活动节目单'
+    }
   }
 ];

+ 1 - 1
src/router/routes-common.ts

@@ -111,7 +111,7 @@ export default [
         name: 'activity-record-detail',
         component: () => import('@/views/activity-record/detail'),
         meta: {
-          title: '活动详情'
+          title: '活动节目单'
         }
       },
       {

+ 149 - 0
src/views/activity-record/detail-swiper.tsx

@@ -0,0 +1,149 @@
+import { Cell, CellGroup, Skeleton, SkeletonParagraph, Image } from 'vant';
+import { defineComponent, onMounted, reactive, watch, ref } from 'vue';
+import styles from './detail.module.less';
+import SwiperClass, { Navigation, Thumbs, Pagination } from 'swiper';
+import { Swiper, SwiperSlide } from 'swiper/vue';
+import 'swiper/css';
+import 'swiper/css/navigation';
+import 'swiper/css/thumbs';
+import 'swiper/css/pagination';
+import iconVideoDefault from '@common/images/icon-video-c.png';
+import { checkFile } from '@/helpers/toolsValidate';
+import palyBtn from './images/palyBtn.png';
+import arrayIcon from './images/array-icon.png';
+export default defineComponent({
+  name: 'detail-swiper',
+  emits: ['showImageToas'],
+  props: {
+    item: {
+      type: Object,
+      default: {}
+    }
+  },
+  setup(props, { slots, emit }) {
+    const forms = reactive({
+      loading: false
+    });
+    const thumbsSwiper = ref<SwiperClass>();
+    const setThumbsSwiper = (swiper: SwiperClass) => {
+      thumbsSwiper.value = swiper;
+      console.log(thumbsSwiper.value, 'setThumbsSwiper');
+    };
+    const modules = [Navigation, Thumbs, Pagination];
+    onMounted(() => {});
+
+    return () => (
+      <>
+        <div class={styles.progItemList}>
+          <Swiper
+            class="topSwiper"
+            style={{
+              '--swiper-navigation-color': '#fff',
+              '--swiper-pagination-color': '#fff'
+            }}
+            modules={modules}
+            space-between={10}
+            pagination={true}
+            thumbs={{ swiper: thumbsSwiper.value }}>
+            {props.item.attachmentUrl.map(
+              (i: any, index: number) =>
+                index <= 3 && (
+                  <SwiperSlide class="slide">
+                    <div
+                      class={styles.photo}
+                      onClick={() => {
+                        emit('showImageToas', {
+                          imagePreview: props.item.attachmentUrl,
+                          imageShow: true,
+                          startPosition: index
+                        });
+                        // forms.imagePreview = item.attachmentUrl;
+                        // forms.imageShow = true;
+                        // forms.startPosition = index;
+                      }}>
+                      {checkFile(i, 'image') ? (
+                        <Image src={i + '@base@tag=imgScale'} fit="cover" />
+                      ) : (
+                        <div class={styles.videoWErap}>
+                          <Image src={palyBtn} class={styles.palyBtn}></Image>
+                          <video
+                            style={{ backgroundColor: '#F8F8F8' }}
+                            poster={iconVideoDefault}
+                            src={i + '#t=1,4'}
+                          />
+                        </div>
+                      )}
+
+                      {props.item.attachmentUrl.length > 4 && index === 3 ? (
+                        <div class={styles.photoMore}>
+                          +{props.item.attachmentUrl.length - 4}
+                        </div>
+                      ) : (
+                        ''
+                      )}
+                    </div>
+                  </SwiperSlide>
+                )
+            )}
+          </Swiper>
+          <div class={styles.thumbsWrap}>
+            <div
+              class={styles.thumbsMore}
+              onClick={() => {
+                emit('showImageToas', {
+                  imagePreview: props.item.attachmentUrl,
+                  imageShow: true,
+                  startPosition: 0
+                });
+              }}>
+              全部
+              <Image class={styles.arrayIcon} src={arrayIcon}></Image>
+            </div>
+            <Swiper
+              class="thumbs-swiper"
+              modules={modules}
+              space-between={10}
+              slides-per-view={4}
+              watch-slides-progress={true}
+              prevent-clicks={true}
+              prevent-clicks-propagation={false}
+              onSwiper={setThumbsSwiper}>
+              {props.item.attachmentUrl.map(
+                (i: any, index: number) =>
+                  index <= 3 && (
+                    <SwiperSlide class="slide">
+                      <div class={styles.photo}>
+                        {checkFile(i, 'image') ? (
+                          <Image
+                            src={i + '@base@tag=imgScale&w=120'}
+                            fit="cover"
+                          />
+                        ) : (
+                          <div class={styles.videoSmallWErap}>
+                            <Image src={palyBtn} class={styles.playBtn}></Image>
+                            <video
+                              style={{ backgroundColor: '#F8F8F8' }}
+                              poster={iconVideoDefault}
+                              src={i + '#t=1,4'}
+                            />
+                          </div>
+                        )}
+
+                        {props.item.attachmentUrl.length > 4 && index === 3 ? (
+                          <div class={styles.photoMore}>
+                            +{props.item.attachmentUrl.length - 4}
+                          </div>
+                        ) : (
+                          ''
+                        )}
+                      </div>
+                    </SwiperSlide>
+                  )
+              )}
+            </Swiper>
+          </div>
+        </div>
+      </>
+    );
+  }
+});

+ 613 - 28
src/views/activity-record/detail.module.less

@@ -1,21 +1,419 @@
 .detail {
   // height: 100vh;
   // overflow: hidden;
+  background-color: #b7f3d4;
+  .detailTop {
+    background: url('./images/detailBG.png') no-repeat;
+    background-size: 375px 346px;
+    width: 375px;
+    height: 346px;
+    .fixWrap {
+      width: 100%;
+      height: 30px;
+      top: 18px;
+      z-index: 500;
+      padding: 0 16px;
+      position: fixed;
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      justify-content: space-between;
+      img {
+        width: 30px;
+        height: 30px;
+        display: block;
+      }
+      .editIcon {
+        margin-right: 16px;
+      }
+    }
+    .wall {
+      height: 48px;
+    }
+    .jiemuIcon {
+      margin-top: 15px;
+      width: 210px;
+      height: 67px;
+      margin-left: 16px;
+    }
+    .typeCard {
+      width: 99px;
+      height: 29px;
+      background: url('./images/typeCard.png') no-repeat;
+      background-size: 99px 29px;
+      margin-left: 56px;
+      margin-top: 11px;
+      text-align: center;
+      line-height: 29px;
+      font-weight: 500;
+      color: #ffffff;
+      font-size: 14px;
+      margin-bottom: 43px;
+    }
+    .activeInfo {
+      width: 343px;
+      height: 87px;
+      position: relative;
+      border-radius: 16px;
+      background-clip: padding-box;
+      border: 1px solid transparent;
+      background-clip: padding-box, border-box;
+      background-origin: padding-box, border-box;
+      background-image: linear-gradient(
+          270deg,
+          #1dc2ff 0%,
+          #0283ff 48%,
+          #0bb7fe 100%
+        ),
+        linear-gradient(360deg, #d1fff6, #e5f8ff);
+
+      margin: 0 auto;
+      .hornIcon {
+        width: 50px;
+        height: 61px;
+        top: -12px;
+        left: -10px;
+        position: absolute;
+      }
+      .noteIcon {
+        width: 38px;
+        height: 34px;
+        right: -5px;
+        bottom: -6px;
+        position: absolute;
+      }
+      .headerName {
+        font-size: 18px;
+        font-family: Alibaba-PuHuiTi-B, Alibaba-PuHuiTi;
+        font-weight: normal;
+        color: #ffffff;
+        line-height: 25px;
+        text-align: center;
+        margin-top: 12px;
+      }
+      .headerTimes {
+        width: 186px;
+        height: 26px;
+        background: linear-gradient(90deg, #edfff1 0%, #def9ff 100%);
+        border-radius: 13px;
+        margin: 12px auto 12px;
+        text-align: center;
+        line-height: 26px;
+        font-weight: 500;
+        color: #1b93ff;
+      }
+    }
+  }
+  .programWrap {
+    background: linear-gradient(180deg, #adeee1 0%, #c5f5db 100%);
+    .programList {
+      padding: 15px;
+      position: relative;
+      border-radius: 28px 28px 0 0;
+      border-top: 2px solid #ffffff;
+      border-left: 2px solid #ffffff;
+      border-right: 2px solid #ffffff;
+      border-bottom: 2px solid transparent;
+
+      .programItem {
+        position: relative;
+        background: #ffffff;
+        box-shadow: inset 0px 1px 3px 0px rgba(152, 239, 213, 0.7);
+        border-radius: 22px;
+        background-clip: padding-box;
+        border: 2px solid transparent;
+        background-clip: padding-box, border-box;
+        background-origin: padding-box, border-box;
+        background-image: linear-gradient(270deg, #fff, #fff),
+          linear-gradient(
+            180deg,
+            rgba(255, 255, 255, 1),
+            rgba(201, 227, 255, 1)
+          );
+        margin-bottom: 20px;
+        .programInfo {
+          position: relative;
+          background-clip: padding-box;
+          border: 2px solid transparent;
+          background-clip: padding-box, border-box;
+          background-origin: padding-box, border-box;
+          background-image: linear-gradient(270deg, #f2ffe6, #def9ff),
+            linear-gradient(180deg, #bef6e9, #c1e3f7);
+          width: 311px;
+          min-height: 151px;
+          margin: 15px auto 20px;
+          border-radius: 16px;
+          z-index: 200;
+          padding: 10px 10px 15px;
+          .ballIcon {
+            position: absolute;
+            width: 57px;
+            height: 39px;
+            top: -9px;
+            right: -9px;
+            z-index: 100;
+          }
+          .programInfoTitleWrap {
+            position: relative;
+            border-radius: 100px 0px 0px 100px;
+            width: 247px;
+            height: 25px;
+            background: linear-gradient(
+              270deg,
+              rgba(255, 255, 255, 0),
+              rgba(255, 255, 255, 1)
+            );
+            display: flex;
+            flex-direction: row;
+            align-items: center;
+
+            .programInfoTitle {
+              // height: 25px;
+              background: linear-gradient(90deg, #037dff 0%, #6bdaff 80%);
+              border-radius: 100px 0px 0px 100px;
+              padding-left: 36px;
+              line-height: 25px;
+              font-weight: 600;
+              color: #ffffff;
+              position: relative;
+              z-index: 80;
+              padding-right: 5px;
+              &:after {
+                content: '';
+                width: 14px;
+                height: 25px;
+                position: absolute;
+                right: -6px;
+                top: 0;
+                transform: skew(-15deg);
+                background: #6bdaff 0%;
+                z-index: -1;
+              }
+            }
+
+            .dieIcon {
+              width: 34px;
+              height: 31px;
+              position: absolute;
+              left: -2px;
+              top: -3px;
+              z-index: 100;
+            }
+            .dotIcon {
+              width: 18px;
+              height: 9px;
+              margin-left: 12px;
+            }
+          }
+          .itemRow {
+            margin-top: 12px;
+            .label {
+              font-size: 14px;
+              font-weight: 500;
+              color: #6a7169;
+            }
+            .content {
+              font-size: 14px;
+              font-weight: 500;
+              color: #131415;
+              span {
+                color: #13a9ff;
+                margin-left: 12px;
+              }
+            }
+          }
+        }
+        .progItemList {
+          min-height: 237px;
+          width: 311px;
+          margin: 0 auto 20px;
+          background-image: linear-gradient(270deg, #dcf3ff, #effae5),
+            linear-gradient(180deg, #bef6e9, #c1e3f7);
+          border-radius: 10px;
+          overflow: hidden;
+          .videoWErap {
+            position: relative;
+            .palyBtn {
+              width: 46px !important;
+              height: 46px !important;
+              position: absolute;
+              left: 50%;
+              margin-left: -23px;
+              top: 50%;
+              margin-top: -23px;
+              z-index: 200;
+            }
+          }
+
+          .videoSmallWErap {
+            position: relative;
+            .playBtn {
+              width: 18px !important;
+              height: 18px !important;
+              position: absolute;
+              left: 50%;
+              margin-left: -9px;
+              top: 50%;
+              margin-top: -9px;
+              z-index: 200;
+              img {
+                width: 18px !important;
+                height: 18px !important;
+              }
+            }
+          }
+          :global {
+            .swiper-pagination-bullet-active {
+              width: 10px !important;
+              height: 4px;
+              border-radius: 2px;
+            }
+            .swiper-pagination-bullet {
+              width: 4px;
+              height: 4px;
+              border-radius: 2px;
+            }
+            .topSwiper {
+              width: 311px;
+              height: 175px;
+
+              .van-image {
+                width: 311px;
+                height: 175px;
+              }
+              video {
+                width: 311px;
+                height: 175px;
+              }
+            }
+
+            .thumbs-swiper {
+              .slide {
+                width: 70px;
+                height: 44px;
+                img {
+                  display: block;
+                  width: 62px;
+                  height: 42px;
+                  object-fit: cover !important;
+                }
+                video {
+                  width: 62px;
+                  height: 43px;
+                }
+              }
+            }
+            .thumbs-swiper {
+              box-sizing: border-box;
 
+              margin-top: 8px;
+              margin-left: 8px;
+              margin-bottom: 8px;
+
+              .slide {
+                width: 74px;
+                height: 46px;
+                background: #ffffff;
+                border-radius: 4px;
+                overflow: hidden;
+                background-clip: padding-box;
+                border: 3px solid transparent;
+                background-clip: padding-box, border-box;
+                background-origin: padding-box, border-box;
+                background-image: linear-gradient(225deg, #fff, #fff),
+                  linear-gradient(
+                    225deg,
+                    rgba(0, 98, 255, 1),
+                    rgba(46, 216, 255, 1)
+                  );
+
+                &:not(.swiper-slide-thumb-active) {
+                  background-image: linear-gradient(225deg, #fff, #fff),
+                    linear-gradient(225deg, transparent, transparent);
+                }
+              }
+            }
+          }
+          .thumbsWrap {
+            position: relative;
+
+            .thumbsMore {
+              z-index: 200;
+              position: absolute;
+              width: 23px;
+              height: 46px;
+              background: #ffffff;
+              border-radius: 4px 0px 0px 4px;
+              display: flex;
+              flex-direction: column;
+              align-items: center;
+              justify-content: center;
+              font-size: 11px;
+              font-weight: 500;
+              color: #131415;
+              text-align: center;
+              top: 0;
+              right: 0px;
+              .arrayIcon {
+                width: 13px;
+                height: 13px;
+              }
+            }
+          }
+        }
+
+        .colorBg {
+          width: 100%;
+          position: absolute;
+          top: -2px;
+          z-index: 99;
+        }
+        .pTitle {
+          position: relative;
+          top: -2px;
+          font-size: 17px;
+          color: #fff;
+          line-height: 43px;
+          width: 200px;
+          height: 43px;
+          margin: 0 auto;
+          background: url('./images/programTitle.png');
+          background-size: 200px 43px;
+          z-index: 100;
+          // margin: 20px 15px 12px;
+          text-align: center;
+        }
+      }
+    }
+    .bottomWrap {
+      position: relative;
+      .bottomBg {
+        width: 100%;
+      }
+      .logo {
+        width: 98px;
+        height: 32px;
+        position: absolute;
+        left: 50%;
+        margin-left: -49px;
+        top: 0;
+      }
+    }
+  }
   .iconEdit {
     font-size: 24px;
   }
 }
 
 .cellGroup {
-  margin-top: 12px;
+  // margin-top: 12px;
 
   .cellTitle {
     padding: 15px 12px;
 
     .tag {
       font-size: 12px;
-      background-color: #F2FFFC;
+      background-color: #f2fffc;
       padding: 3px 6px 2px;
       border-radius: 3px;
       margin-right: 6px;
@@ -55,13 +453,6 @@
   }
 }
 
-.pTitle {
-  font-size: 14px;
-  color: var(--k-gray-2);
-  line-height: 20px;
-  margin: 20px 15px 12px;
-}
-
 .pCellGroup {
   .imgType {
     width: 46px;
@@ -111,29 +502,22 @@
     }
   }
 
-
-  .photoList {
-    display: flex;
-    margin-top: 15px;
-  }
+  // .photoList {
+  //   display: flex;
+  //   margin-top: 15px;
+  // }
 
   .photo {
-    position: relative;
-    width: 76px !important;
-    height: 76px !important;
-    margin-top: 0 !important;
+    //   position: relative;
+    //   width: 76px !important;
+    //   height: 76px !important;
+    //   margin-top: 0 !important;
 
-    &+.photo {
-      margin-left: 7px;
-    }
+    //   & + .photo {
+    //     margin-left: 7px;
+    //   }
 
     :global {
-      .van-image {
-        width: inherit;
-        height: inherit;
-        border-radius: 4px;
-        overflow: hidden;
-      }
     }
 
     video {
@@ -160,5 +544,206 @@
       overflow: hidden;
     }
   }
+}
+
+.codeContainer {
+  .timerBg {
+    width: 131px;
+    height: 27px;
+    line-height: 27px;
+    text-align: center;
+    background: url('./images/timerBg.png');
+    background-size: 131px 27px;
+    position: absolute;
+    left: 25px;
+    top: 83px;
+    font-weight: 500;
+    color: #ffffff;
+    font-size: 12px;
+  }
+  .codeImg {
+    position: relative;
+    width: 315px;
+    height: 440px;
+    z-index: 9;
+    // background: url('./images/week/popup-week-banner.png') no-repeat top center;
+    // background-size: contain;
+    margin: 0 auto;
+    background-color: #ffffff;
+    border-radius: 8px;
+    overflow: hidden;
+    .popupWeekBanner {
+      width: 100%;
+      // position: absolute;
+      top: 0;
+      left: 0;
+      z-index: -1;
+    }
+
+    &.teacherCodeImg {
+      // background: url('./images/month/popup-week-banner.png') no-repeat top center;
+      // background-size: contain;
+      background-color: #ffffff;
+    }
+
+    .headerContantPopup {
+      padding-top: 23px;
+      padding-left: 18px;
+
+      .trainTimer {
+        &::before,
+        &::after {
+          display: none;
+        }
+        .point {
+          margin-left: 4px;
+          margin-right: 4px;
+          width: 6px;
+          height: 6px;
+        }
+      }
+    }
+
+    .codeTitle {
+      text-align: center;
+      padding-top: 13px;
+      font-size: 24px;
+      font-weight: bold;
+      color: #ffffff;
+      text-shadow: 1px 1px 7px #f4672a;
+      max-width: 90%;
+      padding-left: 5%;
+    }
+
+    .codeName {
+      padding: 36px 8px 0;
+      font-size: 18px;
+      font-weight: 600;
+      color: #ffffff;
+    }
+    .codeContent {
+      position: relative;
+      .schoolLogo {
+        width: 52px;
+        height: 52px;
+        border-radius: 50%;
+        overflow: hidden;
+        border: 3px solid #fff;
+        position: absolute;
+        top: -26px;
+        left: 50%;
+        margin-left: -26px;
+      }
+      .schoolName {
+        padding-top: 36px;
+        text-align: center;
+        font-weight: 500;
+        color: #000000;
+        line-height: 22px;
+        font-size: 16px;
+      }
+      .shareName {
+        padding-top: 4px;
+        font-size: 14px;
+
+        font-weight: 600;
+        color: #1b93ff;
+        line-height: 20px;
+        text-align: center;
+        padding-bottom: 12px;
+      }
+      .shareBottom {
+        width: 194px;
+        height: 38px;
+        margin: 16px auto 0;
+        display: block;
+      }
+      .codeQr {
+        position: relative;
+        margin: 0 auto 0;
+        width: 126px;
+        height: 126px;
+        padding: 12px;
+        // background: url('./images/popup-qrcode-bg.png') no-repeat center;
+        // background-size: contain;
+        border-radius: 11px;
+        overflow: hidden;
+        box-sizing: border-box;
+        img {
+          width: 100%;
+          height: 100%;
+        }
+
+        .popupQrcodeBg {
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 126px;
+          height: 126px;
+        }
+      }
+    }
+
+    .codeBtnText {
+      margin: 20px auto 0;
+      display: inline-block;
+      background: linear-gradient(
+        132deg,
+        rgba(199, 239, 243, 0.25) 0%,
+        rgba(229, 206, 251, 0.25) 40%,
+        rgba(147, 194, 254, 0.25) 100%
+      );
+      box-shadow: inset 0px 1px 0px 0px rgba(255, 255, 255, 0.62);
+      border-radius: 18px;
+      padding: 6px 16px;
+      font-size: 14px;
+      color: #000977;
+    }
 
-}
+    .codeTips {
+      padding-top: 10px;
+      font-size: 13px;
+      font-weight: 600;
+      color: #f16437;
+      line-height: 18px;
+      text-align: center;
+    }
+  }
+  .close {
+    position: absolute;
+    top: 12px;
+    right: 15px;
+  }
+  .codeBottom {
+    position: relative;
+    margin-top: 32px;
+    background: #ffffff;
+    border-radius: 20px 20px 0px 0px;
+    padding-bottom: 10px;
+  }
+  .title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333333;
+    line-height: 22px;
+    padding: 15px 15px 0;
+    i {
+      display: inline-block;
+      margin-right: 6px;
+      width: 4px;
+      height: 12px;
+      background: #01c1b5;
+      border-radius: 2px;
+    }
+  }
+  .shareImg {
+    width: 47px;
+    height: 47px;
+  }
+  .shareText {
+    padding-top: 6px;
+    font-size: 14px;
+    color: #333333;
+    line-height: 20px;
+  }
+}

+ 510 - 139
src/views/activity-record/detail.tsx

@@ -1,8 +1,23 @@
 import MHeader from '@/components/m-header';
-import { Cell, CellGroup, Col, Icon, Row, Tag, Image } from 'vant';
-import { defineComponent, onMounted, reactive } from 'vue';
+import {
+  Cell,
+  CellGroup,
+  Col,
+  Icon,
+  Row,
+  Tag,
+  Image,
+  showToast,
+  showFailToast,
+  showLoadingToast,
+  showSuccessToast,
+  Popup,
+  Grid,
+  GridItem
+} from 'vant';
+import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue';
 import styles from './detail.module.less';
-import { toChinesNum } from '@/helpers/utils';
+import { browser, toChinesNum } from '@/helpers/utils';
 import SOLO from './images/SOLO.png';
 import REPRISE from './images/REPRISE.png';
 import ENSEMBLE from './images/ENSEMBLE.png';
@@ -18,14 +33,41 @@ import { formatterTimer } from './operation';
 import MPopup from '@/components/m-popup';
 import CastModal from './components/cast-modal';
 import iconEdit from './images/icon-edit.png';
-import { checkFile } from '@/helpers/toolsValidate';
-import iconVideoDefault from '@common/images/icon-video-c.png';
 
+import html2canvas from 'html2canvas';
+import { postMessage, promisefiyPostMessage } from '@/helpers/native-message';
+import backIcon from './images/back-icon.png';
+import eidtIcon from './images/eidt-icon.png';
+import shareIcon from './images/share-icon.png';
+import jiemuIcon from './images/jiemu-icon.png';
+import hornIcon from './images/horn-icon.png';
+import noteIcon from './images/note-icon.png';
+import colorBg from './images/colorBg.png';
+import dieIcon from './images/die-icon.png';
+import dBall from './images/d-ball.png';
+import qBall from './images/q-ball.png';
+import cBall from './images/c-ball.png';
+import hBall from './images/h-ball.png';
+import dotIcon from './images/dot-icon.png';
+import Detailswiper from './detail-swiper';
+import bottomBg from './images/bottomBg.png';
+import logo from './images/logo.png';
+import MQrcode from '@/components/m-qrcode';
+import { state } from '@/state';
+import { useRect } from '@vant/use';
+import iconWechat from './images/iconWechat.png';
+import iconSaveImage from './images/iconSaveImage.png';
+import shareBg from './images/shareBg.png';
+import schoolIcon from './images/schoolIcon.png';
+import popupQrcodeBg from './images/popupQrcodeBg.png';
+import shareBottom from './images/shareBottom.png';
+import { vaildTeachingUrl } from '@/helpers/utils';
 export default defineComponent({
   name: 'detail-page',
   setup() {
     const route = useRoute();
     const router = useRouter();
+
     // console.log(toChinesNum(11));
     const forms = reactive({
       id: route.query.id,
@@ -37,7 +79,20 @@ export default defineComponent({
       detail: [] as any[],
       headerDetail: {} as any,
       castStatus: false,
-      studentAllList: [] as any
+      studentAllList: [] as any,
+      navBarHeight: state.navBarHeight
+    });
+
+    const shareForms = reactive({
+      id: route.query.id,
+      share: route.query.share as any,
+      showQrcode: false,
+      url:
+        vaildTeachingUrl() +
+        '/school/#/activity-record-detail' +
+        `?id=${route.query.id}`,
+      width: 0,
+      height: 0
     });
 
     const getDetail = async () => {
@@ -91,16 +146,16 @@ export default defineComponent({
       let image: string = '';
       switch (name) {
         case 'SOLO':
-          image = SOLO;
+          image = dBall;
           break;
         case 'REPRISE':
-          image = REPRISE;
+          image = cBall;
           break;
         case 'ENSEMBLE':
-          image = ENSEMBLE;
+          image = hBall;
           break;
         case 'UNISON':
-          image = UNISON;
+          image = qBall;
           break;
         default:
           image = SOLO;
@@ -116,101 +171,276 @@ export default defineComponent({
       // }, 1000);
       getDetail();
     });
+    const imgs = reactive({
+      saveLoading: false,
+      image: null as any,
+      shareLoading: false
+    });
+    const onSaveImg = async () => {
+      // 判断是否在保存中...
+      if (imgs.saveLoading) {
+        return;
+      }
+      imgs.saveLoading = true;
+      // 判断是否已经生成图片
+      if (imgs.image) {
+        saveImg();
+      } else {
+        const container: any = document.getElementById(`preview-container`);
+        html2canvas(container, {
+          allowTaint: true,
+          useCORS: true,
+          backgroundColor: null
+        })
+          .then(async canvas => {
+            const url = canvas.toDataURL('image/png');
+            imgs.image = url;
+            saveImg();
+          })
+          .catch(() => {
+            // closeToast();
+            imgs.saveLoading = false;
+          });
+      }
+    };
+    const showImageToas = (obj: any) => {
+      forms.imagePreview = obj.imagePreview;
+      forms.imageShow = obj.imageShow;
+      forms.startPosition = obj.index;
+      console.log(forms.imagePreview, 'showImageToas', obj);
+    };
+    const onShare = () => {
+      console.log('onShare');
+      if (imgs.shareLoading) {
+        return;
+      }
+      imgs.shareLoading = true;
+      if (imgs.image) {
+        openShare();
+        console.log('onShareimgs.image');
+      } else {
+        const container: any = document.getElementById(`preview-container`);
+
+        html2canvas(container, {
+          allowTaint: true,
+          foreignObjectRendering: true,
+          useCORS: true,
+          backgroundColor: null
+        })
+          .then(async canvas => {
+            const url = canvas.toDataURL('image/png');
+            imgs.image = url;
+            openShare();
+            console.log('onShareimgs.Noimage');
+          })
+          .catch(e => {
+            // closeToast();
+            console.log(e);
+            imgs.shareLoading = false;
+          });
+      }
+    };
+    const openShare = () => {
+      const image = imgs.image;
+      setTimeout(() => {
+        imgs.shareLoading = false;
+      }, 100);
+      if (image) {
+        console.log('postMessage', 'shareTripartite');
+        postMessage(
+          {
+            api: 'shareTripartite',
+            content: {
+              title: '',
+              desc: '',
+              image,
+              video: '',
+              type: 'image',
+              // button: ['copy']
+              shareType: 'wechat'
+            }
+          },
+          (res: any) => {
+            if (res && res.content) {
+              showToast(
+                res.content.message ||
+                  (res.content.status ? '分享成功' : '分享失败')
+              );
+            }
+          }
+        );
+      }
+    };
+    const saveImg = async () => {
+      showLoadingToast({ message: '图片生成中...', forbidClick: true });
+      setTimeout(() => {
+        imgs.saveLoading = false;
+      }, 100);
+      const res = await promisefiyPostMessage({
+        api: 'savePicture',
+        content: {
+          base64: imgs.image
+        }
+      });
+      if (res?.content?.status === 'success') {
+        showSuccessToast('保存成功');
+      } else {
+        showFailToast('保存失败');
+      }
+    };
+
     return () => (
       <div class={styles.detail}>
-        <MHeader>
+        {/* <MHeader>
           {{
             right: () => (
-              <Icon
-                name={iconEdit}
-                class={styles.iconEdit}
-                onClick={() => {
-                  router.push({
-                    path: '/activity-record-operation',
-                    query: {
-                      id: forms.id
-                    }
-                  });
-                }}
-              />
+              <>
+                <Icon
+                  name={iconEdit}
+                  class={styles.iconEdit}
+                  onClick={() => {
+                    router.push({
+                      path: '/activity-record-operation',
+                      query: {
+                        id: forms.id
+                      }
+                    });
+                  }}
+                />
+                <Icon
+                  name={iconEdit}
+                  class={styles.iconEdit}
+                  onClick={() => onShare()}
+                />
+              </>
             )
           }}
-        </MHeader>
-
-        <SkeletionIndexModal
-          v-model:show={forms.headerLoading}
-          showCount={[1]}
-          isLink={false}>
-          <CellGroup inset class={styles.cellGroup}>
-            <Cell center class={styles.cellTitle}>
-              {{
-                icon: () => (
-                  <Tag plain type="primary" class={styles.tag}>
-                    {activityStatus[forms.headerDetail.type]}
-                  </Tag>
-                ),
-                title: () => (
-                  <div class={[styles.title, 'van-ellipsis']}>
-                    {forms.headerDetail.name}
-                  </div>
-                )
-              }}
-            </Cell>
-            <Cell
-              class={styles.cellTimer}
-              center
-              title={`活动日期:${dayjs(forms.headerDetail.startTime).format(
-                'YYYY年MM月DD日'
-              )}`}
-              value={activeStatus[forms.headerDetail.status]}
-              valueClass={
-                forms.headerDetail.status === 'PROCESSING' ? styles.ing : ''
-              }></Cell>
-          </CellGroup>
-        </SkeletionIndexModal>
+        </MHeader> */}
+        <div
+          class={styles.detailTop}
+          style={{ 'padding-top': state.navBarHeight + 'px' }}>
+          {browser().isApp ? (
+            <>
+              {' '}
+              <div
+                class={styles.fixWrap}
+                style={{ top: state.navBarHeight + 30 + 'px' }}>
+                <div class={styles.fixWrapLeft}>
+                  <Image
+                    src={backIcon}
+                    onClick={() => {
+                      if (browser().isApp) {
+                        postMessage({
+                          api: 'goBack'
+                        });
+                      } else {
+                        router.back();
+                      }
+                    }}></Image>
+                </div>
+                <div class={styles.fixWrapRight}>
+                  <Image
+                    src={eidtIcon}
+                    class={styles.editIcon}
+                    onClick={() => {
+                      router.push({
+                        path: '/activity-record-operation',
+                        query: {
+                          id: forms.id
+                        }
+                      });
+                    }}></Image>
+                  <Image
+                    src={shareIcon}
+                    onClick={() => {
+                      shareForms.showQrcode = true;
+                      nextTick(() => {
+                        const previewContainer = document.querySelector(
+                          '#preview-container'
+                        ) as HTMLElement;
+                        const share = useRect(previewContainer);
+                        shareForms.width = share.width;
+                        shareForms.height = share.height;
+                        if (share.width > 0 && share.height > 0) {
+                          previewContainer.style.width =
+                            Math.round(share.width) + 'px';
+                          previewContainer.style.height =
+                            Math.round(share.height) + 'px';
+                        }
+                      });
+                    }}></Image>
+                </div>
+              </div>
+            </>
+          ) : null}
+          <div class={styles.wall}> </div>
+          <Image src={jiemuIcon} class={styles.jiemuIcon}></Image>
+          <div class={styles.typeCard}>
+            {' '}
+            {activityStatus[forms.headerDetail.type]}
+          </div>
+          <SkeletionIndexModal
+            v-model:show={forms.headerLoading}
+            showCount={[1]}
+            isLink={false}>
+            {/* <CellGroup inset class={styles.cellGroup}>
+              <Cell center class={styles.cellTitle}>
+                {{
+                  icon: () => (
+                    <Tag plain type="primary" class={styles.tag}>
+                      {activityStatus[forms.headerDetail.type]}
+                    </Tag>
+                  ),
+                  title: () => (
+                    <div class={[styles.title, 'van-ellipsis']}>
+                      {forms.headerDetail.name}
+                    </div>
+                  )
+                }}
+              </Cell>
+              <Cell
+                class={styles.cellTimer}
+                center
+                title={`活动日期:${dayjs(forms.headerDetail.startTime).format(
+                  'YYYY年MM月DD日'
+                )}`}
+                value={activeStatus[forms.headerDetail.status]}
+                valueClass={
+                  forms.headerDetail.status === 'PROCESSING' ? styles.ing : ''
+                }></Cell>
+            </CellGroup> */}
+            <div class={styles.activeInfo}>
+              <Image src={hornIcon} class={styles.hornIcon}></Image>
+              <h4 class={styles.headerName}> {forms.headerDetail.name}</h4>
+              <p class={styles.headerTimes}>{`活动日期:${dayjs(
+                forms.headerDetail.startTime
+              ).format('YYYY年MM月DD日')}`}</p>
+              <Image src={noteIcon} class={styles.noteIcon}></Image>
+            </div>
+          </SkeletionIndexModal>
+        </div>
 
         <SkeletionDetailModal
           v-model:show={forms.detailLoading}
           showCount={[1, 2]}>
-          <div
-            style={{
-              marginBottom: '18px'
-            }}>
-            {forms.detail.map((item: any, index: number) => (
-              <>
-                <div class={styles.pTitle}>节目{toChinesNum(index + 1)}</div>
-
-                <CellGroup inset class={styles.pCellGroup}>
-                  <Cell center>
-                    {{
-                      icon: () => (
-                        <img
-                          src={formatterImage(item.type)}
-                          class={styles.imgType}
-                        />
-                      ),
-                      title: () => (
-                        <div class={[styles.title, 'van-ellipsis']}>
-                          {item.name}
-                        </div>
-                      ),
-                      value: () => {
-                        const timer = formatterTimer(item.time);
-                        return (
-                          <span class={styles.time}>
-                            {timer.minute}分{timer.secord}秒
-                          </span>
-                        );
-                      }
-                    }}
-                  </Cell>
-                  <Cell
-                    center
-                    class={styles.moreCell}
-                    valueClass={styles.valueClass}>
-                    <Row class={styles.item}>
+          <div class={styles.programWrap}>
+            <div class={styles.programList}>
+              {forms.detail.map((item: any, index: number) => (
+                <div class={styles.programItem}>
+                  <Image src={colorBg} class={styles.colorBg}></Image>
+                  <div class={styles.pTitle}>节目{toChinesNum(index + 1)}</div>
+                  <div class={styles.programInfo}>
+                    <Image
+                      class={styles.ballIcon}
+                      src={formatterImage(item.type)}></Image>
+                    <div class={styles.programInfoTitleWrap}>
+                      <Image class={styles.dieIcon} src={dieIcon}></Image>
+                      <div class={styles.programInfoTitle}> {item.name}</div>
+                      <Image class={styles.dotIcon} src={dotIcon}></Image>
+                    </div>
+                    <Row class={styles.itemRow}>
                       <Col span={6} class={styles.label}>
-                        表演乐团
+                        表演乐团:
                       </Col>
                       <Col span={18} class={styles.content}>
                         {item.musicGroupName}
@@ -223,58 +453,130 @@ export default defineComponent({
                         </span>
                       </Col>
                     </Row>
-                    <Row class={styles.item} style={{ marginBottom: '0' }}>
+                    <Row class={styles.itemRow} style={{ marginBottom: '0' }}>
                       <Col span={6} class={styles.label}>
-                        表演团队
+                        表演团队
                       </Col>
                       <Col span={18} class={styles.content}>
                         {item.subjectNameList}
                       </Col>
                     </Row>
-                    {item.attachmentUrl ? (
-                      <div class={styles.photoList}>
-                        {item.attachmentUrl.map(
-                          (i: any, index: number) =>
-                            index <= 3 && (
-                              <div
-                                class={styles.photo}
-                                onClick={() => {
-                                  forms.imagePreview = item.attachmentUrl;
-                                  forms.imageShow = true;
-                                  forms.startPosition = index;
-                                }}>
-                                {checkFile(i, 'image') ? (
-                                  <Image
-                                    src={i + '@base@tag=imgScale&w=120'}
-                                    fit="cover"
-                                  />
-                                ) : (
-                                  <video
-                                    style={{ backgroundColor: '#F8F8F8' }}
-                                    poster={iconVideoDefault}
-                                    src={i + '#t=1,4'}
-                                  />
-                                )}
+                    <Row class={styles.itemRow} style={{ marginBottom: '0' }}>
+                      <Col span={6} class={styles.label}>
+                        节目时长:
+                      </Col>
+                      <Col span={18} class={styles.content}>
+                        {formatterTimer(item.time).minute}分
+                        {formatterTimer(item.time).secord}秒
+                      </Col>
+                    </Row>
+                  </div>
+                  <Detailswiper
+                    item={item}
+                    onShowImageToas={showImageToas}></Detailswiper>
+                  {/* <CellGroup inset class={styles.pCellGroup}>
+                    <Cell center>
+                      {{
+                        icon: () => (
+                          <img
+                            src={formatterImage(item.type)}
+                            class={styles.imgType}
+                          />
+                        ),
+                        title: () => (
+                          <div class={[styles.title, 'van-ellipsis']}>
+                            {item.name}
+                          </div>
+                        ),
+                        value: () => {
+                          const timer = formatterTimer(item.time);
+                          return (
+                            <span class={styles.time}>
+                              {timer.minute}分{timer.secord}秒
+                            </span>
+                          );
+                        }
+                      }}
+                    </Cell>
+                    <Cell
+                      center
+                      class={styles.moreCell}
+                      valueClass={styles.valueClass}>
+                      <Row class={styles.item}>
+                        <Col span={6} class={styles.label}>
+                          表演乐团
+                        </Col>
+                        <Col span={18} class={styles.content}>
+                          {item.musicGroupName}
+                          <span
+                            onClick={() => {
+                              if (item.studentNum <= 0) return;
+                              formatterStudentList(item.studentList);
+                            }}>
+                            共{item.studentNum}名 <Icon name="arrow" />
+                          </span>
+                        </Col>
+                      </Row>
+                      <Row class={styles.item} style={{ marginBottom: '0' }}>
+                        <Col span={6} class={styles.label}>
+                          表演团队
+                        </Col>
+                        <Col span={18} class={styles.content}>
+                          {item.subjectNameList}
+                        </Col>
+                      </Row>
+                      {item.attachmentUrl ? (
+                        <div class={styles.photoList}>
+                          {item.attachmentUrl.map(
+                            (i: any, index: number) =>
+                              index <= 3 && (
+                                <div
+                                  class={styles.photo}
+                                  onClick={() => {
+                                    forms.imagePreview = item.attachmentUrl;
+                                    forms.imageShow = true;
+                                    forms.startPosition = index;
+                                  }}>
+                                  {checkFile(i, 'image') ? (
+                                    <Image
+                                      src={i + '@base@tag=imgScale&w=120'}
+                                      fit="cover"
+                                    />
+                                  ) : (
+                                    <video
+                                      style={{ backgroundColor: '#F8F8F8' }}
+                                      poster={iconVideoDefault}
+                                      src={i + '#t=1,4'}
+                                    />
+                                  )}
 
-                                {item.attachmentUrl.length > 4 &&
-                                index === 3 ? (
-                                  <div class={styles.photoMore}>
-                                    +{item.attachmentUrl.length - 4}
-                                  </div>
-                                ) : (
-                                  ''
-                                )}
-                              </div>
-                            )
-                        )}
-                      </div>
-                    ) : (
-                      ''
-                    )}
-                  </Cell>
-                </CellGroup>
-              </>
-            ))}
+                                  {item.attachmentUrl.length > 4 &&
+                                  index === 3 ? (
+                                    <div class={styles.photoMore}>
+                                      +{item.attachmentUrl.length - 4}
+                                    </div>
+                                  ) : (
+                                    ''
+                                  )}
+                                </div>
+                              )
+                          )}
+                        </div>
+                      ) : (
+                        ''
+                      )}
+                    </Cell>
+                  </CellGroup> */}
+                </div>
+              ))}
+            </div>
+            <div class={styles.bottomWrap}>
+              {browser().isApp ? null : (
+                <Image class={styles.bottomBg} src={bottomBg}></Image>
+              )}
+
+              <Image class={styles.logo} src={logo}></Image>
+            </div>
           </div>
         </SkeletionDetailModal>
 
@@ -292,6 +594,75 @@ export default defineComponent({
             onClose={() => (forms.castStatus = false)}
           />
         </MPopup>
+
+        <Popup
+          v-model:show={shareForms.showQrcode}
+          position="bottom"
+          style={{ background: 'transparent' }}>
+          <div class={styles.codeContainer}>
+            <div
+              class={[styles.codeImg, styles.teacherCodeImg]}
+              id="preview-container">
+              <Image src={shareBg} class={styles.popupWeekBanner} />
+              <div class={styles.timerBg}>
+                {dayjs(forms.headerDetail.startTime).format('YYYY年MM月DD日')}
+              </div>
+              <div class={styles.codeContent}>
+                <Image
+                  class={styles.schoolLogo}
+                  src={
+                    forms.headerDetail?.cooperationOrganLogo
+                      ? forms.headerDetail?.cooperationOrganLogo
+                      : schoolIcon
+                  }></Image>
+                <div class={styles.schoolName}>
+                  {forms.headerDetail?.cooperationOrganName || '武汉小学'}
+                </div>
+                <div class={styles.shareName}>{forms.headerDetail.name}</div>
+                <div class={styles.codeQr}>
+                  <Image src={popupQrcodeBg} class={styles.popupQrcodeBg} />
+                  <MQrcode
+                    text={shareForms.url}
+                    size={'100%'}
+                    logoSize="small"
+                  />
+                </div>
+                <Image src={shareBottom} class={styles.shareBottom}></Image>
+              </div>
+            </div>
+            <div class={styles.codeBottom}>
+              <Icon
+                name="cross"
+                size={22}
+                class={styles.close}
+                color="#666"
+                onClick={() => (shareForms.showQrcode = false)}
+              />
+
+              <h3 class={styles.title}>
+                <i></i>分享方式
+              </h3>
+              <Grid columnNum={2} border={false}>
+                <GridItem onClick={onSaveImg}>
+                  {{
+                    icon: () => (
+                      <Image class={styles.shareImg} src={iconSaveImage} />
+                    ),
+                    text: () => <div class={styles.shareText}>保存图片</div>
+                  }}
+                </GridItem>
+                <GridItem onClick={onShare}>
+                  {{
+                    icon: () => (
+                      <Image class={styles.shareImg} src={iconWechat} />
+                    ),
+                    text: () => <div class={styles.shareText}>微信</div>
+                  }}
+                </GridItem>
+              </Grid>
+            </div>
+          </div>
+        </Popup>
       </div>
     );
   }

BIN
src/views/activity-record/images/array-icon.png


BIN
src/views/activity-record/images/back-icon.png


BIN
src/views/activity-record/images/bottomBg.png


BIN
src/views/activity-record/images/c-ball.png


BIN
src/views/activity-record/images/colorBg.png


BIN
src/views/activity-record/images/d-ball.png


BIN
src/views/activity-record/images/detailBG.png


BIN
src/views/activity-record/images/die-icon.png


BIN
src/views/activity-record/images/dot-icon.png


BIN
src/views/activity-record/images/eidt-icon.png


BIN
src/views/activity-record/images/h-ball.png


BIN
src/views/activity-record/images/horn-icon.png


BIN
src/views/activity-record/images/iconSaveImage.png


BIN
src/views/activity-record/images/iconWechat.png


BIN
src/views/activity-record/images/jiemu-icon.png


BIN
src/views/activity-record/images/logo.png


BIN
src/views/activity-record/images/note-icon.png


BIN
src/views/activity-record/images/palyBtn.png


BIN
src/views/activity-record/images/popupQrcodeBg.png


BIN
src/views/activity-record/images/programTitle.png


BIN
src/views/activity-record/images/q-ball.png


BIN
src/views/activity-record/images/schoolIcon.png


BIN
src/views/activity-record/images/share-icon.png


BIN
src/views/activity-record/images/shareBg.png


BIN
src/views/activity-record/images/shareBottom.png


BIN
src/views/activity-record/images/timerBg.png


BIN
src/views/activity-record/images/typeCard.png


+ 1 - 1
src/views/activity-record/skeletion-detail-modal.tsx

@@ -47,7 +47,7 @@ export default defineComponent({
               }}>
               {props.showCount.map(() => (
                 <>
-                  <SkeletonParagraph rowWidth={'20%'} class={styles.pTitle} />
+                  {/* <SkeletonParagraph rowWidth={'20%'} class={styles.pTitle} /> */}
 
                   <CellGroup inset class={styles.pCellGroup}>
                     <Cell center>