SyuanYu преди 2 години
родител
ревизия
182b08422a

BIN
frontend/src/assets/img/anchor/Angela.webp


BIN
frontend/src/assets/img/anchor/主播-01.webp


BIN
frontend/src/assets/img/anchor/主播-02.webp


BIN
frontend/src/assets/img/anchor/主播-03.webp


BIN
frontend/src/assets/img/anchor/主播-04.webp


BIN
frontend/src/assets/img/anchor/主播-05.webp


BIN
frontend/src/assets/img/anchor/主播-06.webp


BIN
frontend/src/assets/img/anchor/主播-07.webp


BIN
frontend/src/assets/img/template/鏡面-01.webp


BIN
frontend/src/assets/img/template/鏡面-02.webp


BIN
frontend/src/assets/img/template/鏡面-03.webp


BIN
frontend/src/assets/img/template/鏡面-04.webp


BIN
frontend/src/assets/img/template/鏡面-05.webp


BIN
frontend/src/assets/img/template/鏡面-06.webp


+ 1 - 1
frontend/src/plugins/vuetify.ts

@@ -16,7 +16,7 @@ export const vuetify = createVuetify({
     mobileBreakpoint: 'sm',
     thresholds: {
       xs: 0,
-      sm: 600,
+      sm: 767,
       md: 960,
       lg: 1264,
       xl: 1904,

+ 174 - 19
frontend/src/views/main/Upload.vue

@@ -1,38 +1,118 @@
 <script setup lang="ts">
-import { ref, reactive, watch } from "vue";
+import { ref, reactive, watch, computed } from "vue";
 import { useMainStore } from "@/stores/main";
 import { required } from "@/utils";
 import { useI18n } from "vue-i18n";
+import { useDisplay } from "vuetify";
 import type { VideoCreate } from "@/interfaces";
 import router from "@/router";
 
 const { t } = useI18n();
+const { name } = useDisplay();
+const width = computed(() => {
+  switch (name.value) {
+    case "xs":
+      return 6;
+    case "sm":
+      return 4;
+    case "md":
+      return 3;
+    case "lg":
+      return 2;
+  }
+  return "auto";
+});
+
 const valid = ref(true);
 const dialog = ref(false);
 const title = ref("");
 const zipFiles = ref();
 const Form = ref();
 let anchor = ref(0);
+let templateId = ref(0);
+
 const anchorList = reactive([
   {
     anchor_id: 0,
     language_id: 1,
-    name: "Angela",
+    name: "Peggy",
   },
   {
     anchor_id: 1,
     language_id: 1,
-    name: "Peggy",
+    name: "Jocelyn",
   },
   {
     anchor_id: 2,
     language_id: 1,
-    name: "Jocelyn",
+    name: "Summer",
   },
   {
     anchor_id: 3,
     language_id: 1,
-    name: "Summer",
+    name: "Angela",
+  },
+  {
+    anchor_id: 4,
+    language_id: 1,
+    name: "主播-01",
+  },
+  {
+    anchor_id: 5,
+    language_id: 1,
+    name: "主播-02",
+  },
+  {
+    anchor_id: 6,
+    language_id: 1,
+    name: "主播-03",
+  },
+  {
+    anchor_id: 7,
+    language_id: 1,
+    name: "主播-04",
+  },
+  {
+    anchor_id: 8,
+    language_id: 1,
+    name: "主播-05",
+  },
+  {
+    anchor_id: 9,
+    language_id: 1,
+    name: "主播-06",
+  },
+  {
+    anchor_id: 10,
+    language_id: 1,
+    name: "主播-07",
+  },
+]);
+
+const templateList = reactive([
+  {
+    template_id: 0,
+    img: "../src/assets/img/template/鏡面-01.webp",
+  },
+  {
+    template_id: 1,
+    img: "../src/assets/img/template/鏡面-02.webp",
+  },
+  {
+    template_id: 2,
+    img: "../src/assets/img/template/鏡面-03.webp",
+  },
+  {
+    template_id: 3,
+    img: "../src/assets/img/template/鏡面-04.webp",
+  },
+  {
+    template_id: 4,
+    img: "../src/assets/img/template/鏡面-05.webp",
+  },
+  {
+    template_id: 5,
+    img: "../src/assets/img/template/鏡面-06.webp",
   },
 ]);
 
@@ -43,8 +123,9 @@ let items = reactive([
 ]);
 
 // 取得圖片路徑
-const getImageUrl = (name: string) => {
-  return new URL(`../../assets/img/anchor/${name}.webp`, import.meta.url).href;
+const getImageUrl = (imgFolder: string, name: string) => {
+  return new URL(`../../assets/img/${imgFolder}/${name}.webp`, import.meta.url)
+    .href;
 };
 
 const mainStore = useMainStore();
@@ -108,34 +189,67 @@ async function Submit() {
           ></v-select> -->
         </v-form>
 
-        <!-- <v-expansion-panels class="anchor-list">
+        <v-expansion-panels class="anchor-list">
           <v-expansion-panel title="選擇主播">
+            <v-expansion-panel-text class="p-0">
+              <v-item-group mandatory v-model="anchor">
+                <v-container fluid>
+                  <ul>
+                    <li v-for="n in anchorList" :key="n.anchor_id">
+                      <v-item v-slot="{ isSelected, toggle }">
+                        <v-card
+                          :color="isSelected ? 'primary' : ''"
+                          class="d-flex flex-column align-center"
+                          dark
+                          @click="toggle"
+                          :title="n.name"
+                        >
+                          <v-scroll-y-transition>
+                            <img :src="getImageUrl('anchor', n.name)" alt="" />
+                          </v-scroll-y-transition>
+                        </v-card>
+                      </v-item>
+                    </li>
+                  </ul>
+                </v-container>
+              </v-item-group>
+            </v-expansion-panel-text>
+          </v-expansion-panel>
+        </v-expansion-panels>
+
+        <v-expansion-panels class="template-list mt-6">
+          <v-expansion-panel title="選擇模板">
             <v-expansion-panel-text class="p-0">
               <v-sheet class="mx-auto">
                 <v-slide-group
                   v-model="anchor"
-                  selected-class="bg-success"
+                  selected-class="bg-primary"
                   show-arrows
                 >
                   <v-slide-group-item
-                    v-for="n in anchorList"
-                    :key="n.anchor_id"
+                    v-for="n in templateList"
+                    :key="n.template_id"
                     v-slot="{ isSelected, toggle, selectedClass }"
                   >
                     <v-card
                       color="grey-lighten-1"
                       :class="['ma-4', selectedClass]"
                       @click="toggle"
-                      :title="n.name"
                     >
-                      <img :src="getImageUrl(n.name)" alt="" />
+                      <span
+                        class="choose-btn"
+                        :class="{ 'active-color': isSelected }"
+                      >
+                        <v-icon icon="done" color="white" />
+                      </span>
+                      <img :src="n.img" alt="" />
                     </v-card>
                   </v-slide-group-item>
                 </v-slide-group>
               </v-sheet>
             </v-expansion-panel-text>
           </v-expansion-panel>
-        </v-expansion-panels> -->
+        </v-expansion-panels>
       </v-card-text>
       <v-card-actions>
         <v-spacer></v-spacer>
@@ -234,12 +348,29 @@ async function Submit() {
 
 <style lang="scss">
 .anchor-list {
-  padding-left: 40px;
+  ul {
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
+    grid-gap: 20px;
+    justify-content: center;
+    padding: initial;
+    li {
+      list-style-type: none;
+    }
+  }
   img {
-    width: 130px;
-    height: 110px;
+    width: 100%;
+    height: 140px;
     object-fit: cover;
   }
+
+  .v-card--variant-elevated {
+    box-shadow: 0px 2px 5px 1px
+        var(--v-shadow-key-umbra-opacity, rgba(0, 0, 0, 0.2)),
+      0px 1px 1px 0px var(--v-shadow-key-penumbra-opacity, rgba(0, 0, 0, 0.14)),
+      0px 1px 3px 0px var(--v-shadow-key-penumbra-opacity, rgba(0, 0, 0, 0.12));
+  }
+
   .v-card-item {
     padding: 0;
     text-align: center;
@@ -254,14 +385,38 @@ async function Submit() {
       rgb(178, 69, 146) 100%
     ) !important;
   }
+  .v-expansion-panel-text__wrapper {
+    padding: 0 !important;
+  }
+}
+
+.anchor-list,
+.template-list {
+  padding-left: 40px;
   .v-expansion-panel-title {
     height: 55px;
     min-height: 0;
   }
-  .v-expansion-panel-text__wrapper {
-    padding: 0 !important;
+}
+
+.template-list {
+  img {
+    width: 100%;
+    height: 180px;
+  }
+  .choose-btn {
+    padding: 5px;
+    position: absolute;
+    right: 8px;
+    bottom: 13px;
+    background: #ccc;
+    border-radius: 100px;
+  }
+  .active-color {
+    background: #ea5413;
   }
 }
+
 .step-list {
   list-style: none;
   img {