mo пре 1 година
родитељ
комит
12027c812e

+ 128 - 0
package-lock.json

@@ -15,14 +15,17 @@
         "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",
         "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"
       },
@@ -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",
@@ -3561,6 +3572,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",
@@ -4705,6 +4724,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",
@@ -7104,6 +7135,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",
@@ -7244,6 +7280,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 +7319,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 +7646,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 +7789,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",
@@ -10408,6 +10480,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",
@@ -10743,6 +10820,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",
@@ -11645,6 +11730,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",
@@ -13542,6 +13636,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",
@@ -13648,6 +13747,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 +13779,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 +14033,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 +14123,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",

+ 3 - 0
package.json

@@ -28,14 +28,17 @@
     "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",
     "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"
   },

+ 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: '活动节目单'
         }
       },
       {

+ 317 - 29
src/views/activity-record/detail.module.less

@@ -1,21 +1,324 @@
 .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: 100;
+      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;
+
+          :global {
+            .topSwiper {
+              width: 311px;
+              height: 175px;
+              .van-image {
+                width: 311px;
+                height: 175px;
+              }
+              video {
+                width: 311px;
+                height: 175px;
+              }
+            }
+            .thumbs-swiper {
+              .slide {
+                img {
+                  display: block;
+                  width: 74px;
+                  height: 46px;
+                  object-fit: cover;
+                }
+                video {
+                  width: 74px;
+                  height: 46px;
+                }
+              }
+            }
+          }
+
+          .top-swiper {
+            height: 80%;
+            width: 100%;
+          }
+
+          .thumbs-swiper {
+            height: 20%;
+            box-sizing: border-box;
+            padding: 5px 0;
+
+            .slide {
+              width: 25%;
+              height: 100%;
+              opacity: 1;
+              &:not(.swiper-slide-thumb-active) {
+                opacity: 0.4;
+              }
+            }
+          }
+        }
+        .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;
+        }
+      }
+    }
+  }
   .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 +358,6 @@
   }
 }
 
-.pTitle {
-  font-size: 14px;
-  color: var(--k-gray-2);
-  line-height: 20px;
-  margin: 20px 15px 12px;
-}
-
 .pCellGroup {
   .imgType {
     width: 46px;
@@ -111,29 +407,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 +449,4 @@
       overflow: hidden;
     }
   }
-
-}
+}

+ 440 - 106
src/views/activity-record/detail.tsx

@@ -1,8 +1,20 @@
 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
+} from 'vant';
+import { defineComponent, 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';
@@ -20,12 +32,33 @@ 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 { state } from '@/state';
+import SwiperClass, { Navigation, Thumbs } from 'swiper';
+import { Swiper, SwiperSlide } from 'swiper/vue';
+import 'swiper/css';
+import 'swiper/css/navigation';
+import 'swiper/css/thumbs';
 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,9 +70,14 @@ export default defineComponent({
       detail: [] as any[],
       headerDetail: {} as any,
       castStatus: false,
-      studentAllList: [] as any
+      studentAllList: [] as any,
+      navBarHeight: state.navBarHeight
     });
-
+    const thumbsSwiper = ref<SwiperClass>();
+    const setThumbsSwiper = (swiper: SwiperClass) => {
+      thumbsSwiper.value = swiper;
+    };
+    const modules = [Navigation, Thumbs];
     const getDetail = async () => {
       try {
         const { data } = await request.get(
@@ -91,16 +129,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,14 +154,168 @@ 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 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>
+      <div class={styles.detail} id="preview-container">
+        {/* <MHeader>
           {{
             right: () => (
-              <Icon
-                name={iconEdit}
-                class={styles.iconEdit}
+              <>
+                <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> */}
+        <div
+          class={styles.detailTop}
+          style={{ 'padding-top': state.navBarHeight + 'px' }}>
+          <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',
@@ -131,86 +323,78 @@ export default defineComponent({
                       id: forms.id
                     }
                   });
+                }}></Image>
+              <Image src={shareIcon}></Image>
+            </div>
+          </div>
+          <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>
+                  )
                 }}
-              />
-            )
-          }}
-        </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>
+              </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,19 +407,38 @@ 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 && (
+                    <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>
+                  <div class={styles.progItemList}>
+                    <Swiper
+                      class="topSwiper"
+                      style={{
+                        '--swiper-navigation-color': '#fff',
+                        '--swiper-pagination-color': '#fff'
+                      }}
+                      modules={modules}
+                      space-between={10}
+                      ref={thumbsSwiper}>
+                      {item.attachmentUrl.map(
+                        (i: any, index: number) =>
+                          index <= 3 && (
+                            <SwiperSlide class="slide">
                               <div
                                 class={styles.photo}
                                 onClick={() => {
@@ -265,16 +468,147 @@ export default defineComponent({
                                   ''
                                 )}
                               </div>
-                            )
-                        )}
-                      </div>
-                    ) : (
-                      ''
-                    )}
-                  </Cell>
-                </CellGroup>
-              </>
-            ))}
+                            </SwiperSlide>
+                          )
+                      )}
+                    </Swiper>
+                    <Swiper
+                      class="thumbs-swiper"
+                      modules={modules}
+                      space-between={10}
+                      slides-per-view={4}
+                      watch-slides-progress={true}
+                      prevent-clicks={false}
+                      prevent-clicks-propagation={false}
+                      onSwiper={setThumbsSwiper}>
+                      {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"
+                                  />
+                                ) : (
+                                  <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>
+                            </SwiperSlide>
+                          )
+                      )}
+                    </Swiper>
+                  </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}>
+                        <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> */}
+                </div>
+              ))}
+            </div>
           </div>
         </SkeletionDetailModal>
 

BIN
src/views/activity-record/images/back-icon.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/jiemu-icon.png


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


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


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


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


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