SyuanYu 1 anno fa
parent
commit
caf3b0f775

+ 7 - 3
frontend/src/api.ts

@@ -1,6 +1,6 @@
 import axios from "axios";
 import { apiUrl } from "@/env";
-import type { IUserProfile, IUserProfileUpdate, IUserProfileCreate, Video, VideoCreate, ArticleCreate, ImageDownload, VideoUploaded } from "@/interfaces";
+import type { IUserProfile, IUserProfileUpdate, IUserProfileCreate, Video, VideoCreate, ArticleCreate, ImageDownload, VideoUploaded, YTViewsUserData } from "@/interfaces";
 
 function authHeaders(token: string) {
   return {
@@ -17,7 +17,7 @@ export const api = {
     params.append("password", password);
     return axios.post(`${apiUrl}/api/v1/login/access-token`, params);
   },
-  async qrLogInGetToken(username: string, password: string,ser_no: string) {
+  async qrLogInGetToken(username: string, password: string, ser_no: string) {
     const params = new URLSearchParams();
     params.append("username", username);
     params.append("password", password);
@@ -30,7 +30,7 @@ export const api = {
 
     return axios.post(`${apiUrl}/api/v1/login/google/access-token`, params);
   },
-  async qrGoogleLogin(username: string,ser_no: string) {
+  async qrGoogleLogin(username: string, ser_no: string) {
     const params = new URLSearchParams();
     params.append("username", username);
     params.append("password", "google");
@@ -140,4 +140,8 @@ export const api = {
     formData.append("amount", amount.toString());
     return axios.post<string>(`${apiUrl}/api/v1/payment/ecpayTestPay`, formData, authHeaders(token))
   },
+  async uploadPayment(token: string, user_data: YTViewsUserData, name: string, amount: number) {
+    let data = { items: name, amount: amount, remark: user_data }
+    return axios.post<{ msg: string }>(`${apiUrl}/api/v1/payment/ecpay-payment/`, data, authHeaders(token));
+  },
 };

+ 1 - 1
frontend/src/interfaces/index.ts

@@ -87,7 +87,7 @@ export interface YTViewsUserData {
   url: string;
   area: string;
   language: string;
-  age: [] | null;
+  age: string | null;
   object: string;
   theme: string;
   tax: string | null;

+ 5 - 0
frontend/src/router/index.ts

@@ -68,6 +68,11 @@ const router = createRouter({
               name: 'progress',
               component: () => import('@/views/main/Progress.vue'),
             },
+            {
+              path: 'yt-views',
+              name: 'yt-views',
+              component: () => import('@/views/main/YTViews.vue'),
+            },
             {
               path: 'profile',
               name: 'profile',

+ 18 - 5
frontend/src/stores/main.ts

@@ -4,7 +4,7 @@ import { api } from "@/api"
 import router from "@/router"
 import { getLocalToken, removeLocalToken, saveLocalToken } from "@/utils";
 import type { AppNotification } from '@/interfaces';
-import type { IUserProfile, IUserProfileCreate, IUserProfileUpdate, MainState, Video, VideoCreate, ArticleCreate, Image, ImageDownload, VideoUploaded } from '@/interfaces';
+import type { IUserProfile, IUserProfileCreate, IUserProfileUpdate, MainState, Video, VideoCreate, ArticleCreate, Image, ImageDownload, VideoUploaded, YTViewsUserData } from '@/interfaces';
 import i18n from '@/plugins/i18n'
 import { wsUrl } from "@/env";
 
@@ -454,16 +454,29 @@ export const useMainStore = defineStore("MainStoreId", {
         await mainStore.checkApiError(error);
       }
     },
-    async ecpayPaymentHTML(amount:number) {
+    async ecpayPaymentHTML(amount: number) {
       const mainStore = useMainStore();
       try {
         const response = await api.ecpayPaymentHTML(mainStore.token, amount)
         if (response) {
           return response.data;
-        } 
-      }catch (error) {
+        }
+      } catch (error) {
+        await mainStore.checkApiError(error);
+      }
+    },
+    async uploadPayment(user_data: YTViewsUserData, name: string, amount: number) {
+      const mainStore = useMainStore();
+      try {
+        const response = (
+          await Promise.all([
+            api.uploadPayment(mainStore.token, user_data, name, amount),
+            await new Promise<void>((resolve, _) => setTimeout(() => resolve(), 0)),
+          ])
+        );
+      } catch (error) {
         await mainStore.checkApiError(error);
       }
-    }
+    },
   }
 });

+ 7 - 7
frontend/src/views/main/Main.vue

@@ -111,24 +111,24 @@ const routeGuardAdmin = async (
             <v-list-item to="/main/progress" prepend-icon="list">
               <v-list-item-title>{{ t("progress") }}</v-list-item-title>
             </v-list-item>
-            <v-list-item to="/main/make-article" prepend-icon="article">
+            <!-- <v-list-item to="/main/make-article" prepend-icon="article">
               <v-list-item-title>{{ t("article") }}</v-list-item-title>
-            </v-list-item>
-            <v-list-item to="/main/make-image" prepend-icon="image">
+            </v-list-item> -->
+            <!-- <v-list-item to="/main/make-image" prepend-icon="image">
               <v-list-item-title>圖片優化</v-list-item-title>
-            </v-list-item>
+            </v-list-item> -->
             <!-- <v-list-item to="/main/profile/view" prepend-icon="person">
               <v-list-item-title>{{ t("userProfile") }}</v-list-item-title>
             </v-list-item> -->
+            <v-list-item to="/main/yt-views" prepend-icon="ondemand_video">
+              <v-list-item-title>網紅加速器</v-list-item-title>
+            </v-list-item>
             <v-list-item to="/main/profile/edit" prepend-icon="edit">
               <v-list-item-title>{{ t("editProfile") }}</v-list-item-title>
             </v-list-item>
             <v-list-item to="/main/profile/password" prepend-icon="key">
               <v-list-item-title>{{ t("changePassword") }}</v-list-item-title>
             </v-list-item>
-            <v-list-item to="/main/admin/test-ecpay" prepend-icon="payments">
-              <v-list-item-title>網紅加速器</v-list-item-title>
-            </v-list-item>
           </v-list>
         </v-sheet>
         <v-divider></v-divider>

+ 456 - 0
frontend/src/views/main/YTViews.vue

@@ -0,0 +1,456 @@
+<script setup lang="ts">
+import { ref, reactive, computed } from "vue";
+import type { YTViewsUserData } from "@/interfaces";
+import { useMainStore } from "@/stores/main";
+
+const mainStore = useMainStore();
+const fieldRules = [(value: string) => !!value || "此欄位為必填項目"];
+
+const items = reactive([
+  { title: "100% 真人觀看" },
+  { title: "包含影片設定費" },
+  { title: "開發票" },
+  { title: "包含成效報表" },
+]);
+
+const cardItems = reactive([
+  { view: "5,000", price: "2,700", originalPrice: "3,500", param: 2700 },
+  { view: "10,000", price: "4,400", originalPrice: "5,000", param: 4400 },
+  { view: "30,000", price: "12,400", originalPrice: "13,000", param: 12400 },
+  { view: "50,000", price: "20,400", originalPrice: "21,000", param: 20400 },
+]);
+
+const ageOptions = [
+  { label: "18 - 24 歲" },
+  { label: "25 - 34 歲" },
+  { label: "35 - 44 歲" },
+  { label: "45 - 54 歲" },
+  { label: "55 - 64 歲" },
+  { label: "65 歲以上" },
+];
+
+const objectOptions = [
+  { label: "交通工具與運輸" },
+  { label: "媒體和娛樂" },
+  { label: "家居與園藝" },
+  { label: "新聞與政治" },
+  { label: "旅遊" },
+  { label: "生活型態與興趣" },
+  { label: "科技" },
+  { label: "美容與健康" },
+  { label: "美食與餐飲" },
+  { label: "購物愛好者" },
+  { label: "運動與健身" },
+  { label: "銀行與金融" },
+];
+
+const themeOptions = [
+  { label: "人文與社會" },
+  { label: "保健" },
+  { label: "全球地點(各地區)" },
+  { label: "參考資料(圖書館、博物館與目錄、清單等)" },
+  { label: "圖書與文學" },
+  { label: "家居與園藝" },
+  { label: "寵物與動物" },
+  { label: "工作與教育" },
+  { label: "工商業" },
+  { label: "房地產" },
+  { label: "新聞" },
+  { label: "旅遊與交通" },
+  { label: "汽車與交通工具" },
+  { label: "法律與政府" },
+  { label: "科學" },
+  { label: "網路社群" },
+  { label: "網際網路與電信" },
+  { label: "美容與健身" },
+  { label: "美食佳飲" },
+  { label: "興趣與休閒" },
+  { label: "藝術與娛樂" },
+  { label: "購物" },
+  { label: "遊戲" },
+  { label: "運動" },
+  { label: "金融" },
+  { label: "電腦和電子產品" },
+];
+
+let chooseError = ref(false);
+let assignView = ref();
+let assignPrice = ref();
+
+function activeBtn(view: string, param: number) {
+  assignView.value = view;
+  assignPrice.value = param;
+  chooseError.value = false;
+}
+
+let userData = reactive({
+  email: "",
+  name: "",
+  company: "",
+  url: "",
+  area: "",
+  language: "",
+  age: [],
+  object: "",
+  theme: "",
+  tax: "",
+});
+
+// 其他選項
+let object = ref("");
+let theme = ref("");
+let otherObject = ref("");
+let otherTheme = ref("");
+
+// 檢查必填欄位
+const isSubmitDisabled = computed(() => {
+  return (
+    !userData.email ||
+    !userData.name ||
+    !userData.url ||
+    !userData.area ||
+    !userData.language ||
+    !object.value ||
+    !theme.value
+  );
+});
+
+async function ECPaySubmit() {
+  if (!assignPrice.value) {
+    chooseError.value = true;
+    window.scrollTo({ top: 0, behavior: "smooth" });
+  } else {
+    chooseError.value = false;
+  }
+
+  if (object.value === "其他" && otherObject.value !== "") {
+    userData.object = otherObject.value;
+  } else {
+    userData.object = object.value;
+  }
+
+  if (theme.value === "其他" && otherTheme.value !== "") {
+    userData.theme = otherTheme.value;
+  } else {
+    userData.theme = theme.value;
+  }
+
+  let data: YTViewsUserData = {
+    email: userData.email,
+    name: userData.name,
+    company: userData.company,
+    url: userData.url,
+    area: userData.area,
+    language: userData.language,
+    age: userData.age.join("、"),
+    object: userData.object,
+    theme: userData.theme,
+    tax: userData.tax,
+  };
+
+  await mainStore.uploadPayment(data, assignView.value, assignPrice.value);
+
+  const originalHTML = await mainStore.ecpayPaymentHTML(assignPrice.value);
+  let formHTML = originalHTML?.replace(
+    '<script type="text/javascript">document.getElementById("data_set").submit();</scr',
+    ""
+  );
+  formHTML = formHTML?.replace("ipt>", "");
+  const payFormElement = document.getElementById("pay-form");
+  payFormElement!.innerHTML = formHTML!;
+  const ecpayForm: HTMLFormElement = <HTMLFormElement>(
+    document.getElementById("data_set")
+  );
+  console.log(ecpayForm);
+  ecpayForm.submit();
+}
+
+// 資料存進 Google Sheets
+// async function saveData() {
+//   const scriptURL =
+//     "https://script.google.com/macros/s/AKfycbxCcfiOQ695DaxIa3peClqRRTWNj2aUNLbx7ty8U2wKlyU7wreQLioHG-sls5MPKBdlRQ/exec";
+
+//   let formdata = new FormData();
+//   formdata.append("email", userData.email);
+//   formdata.append("name", userData.name);
+//   formdata.append("company", userData.company);
+//   formdata.append("url", userData.url);
+//   formdata.append("area", userData.area);
+//   formdata.append("language", userData.language);
+//   formdata.append("age", userData.age.join("、"));
+//   formdata.append("object", userData.object);
+//   formdata.append("theme", userData.theme);
+//   formdata.append("tax", userData.tax);
+
+//   axios
+//     .post(scriptURL, formdata)
+//     .then(function (response) {
+//       console.log(response.data);
+//     })
+//     .catch(function (error) {
+//       console.log(error);
+//     });
+// }
+</script>
+
+<template>
+  <v-container fluid>
+    <v-card class="ma-3 pa-3">
+      <v-card-title primary-title class="mb-3">
+        <h3 class="headline primary--text">YouTube 觀看數</h3>
+      </v-card-title>
+      <v-card-text>
+        <p class="ms-3">請選擇方案:</p>
+        <v-row no-gutters class="pay-card">
+          <v-col
+            xs="12"
+            sm="6"
+            lg="3"
+            v-for="(item, index) in cardItems"
+            :key="index"
+          >
+            <button @click="activeBtn(item.view, item.param)" class="w-100">
+              <v-card
+                class="ma-3 py-3"
+                :class="{ active: assignPrice === item.param }"
+              >
+                <v-card-title primary-title class="pa-0">
+                  <div class="d-flex flex-column">
+                    <section class="d-flex mx-auto">
+                      <img
+                        width="30"
+                        height="30"
+                        src="@/assets/img/icon/play-button.png"
+                        alt=""
+                        class="me-2"
+                      />
+                      <h5 class="m-0">{{ item.view }}</h5>
+                    </section>
+                    <span class="text-center" style="color: #7c8ba7"
+                      >Views</span
+                    >
+                  </div>
+                  <p class="price">
+                    NT${{ item.price }} <br />
+                    <small>NT${{ item.originalPrice }}</small>
+                  </p>
+                </v-card-title>
+
+                <v-card-text class="d-flex align-center justify-center mt-3">
+                  <ul>
+                    <li
+                      v-for="(item, index) in items"
+                      :key="index"
+                      class="d-flex align-center"
+                    >
+                      <img
+                        width="30"
+                        src="@/assets/img/icon/check.png"
+                        alt=""
+                      />
+                      {{ item.title }}
+                    </li>
+                  </ul>
+                </v-card-text>
+
+                <!-- <v-card-actions class="d-flex justify-center">
+                  <v-btn @click="ECPaySubmit(item.param)"> Buy Now </v-btn>
+                </v-card-actions> -->
+              </v-card>
+            </button>
+          </v-col>
+          <p class="ms-3 error" v-show="chooseError">尚未選擇方案</p>
+        </v-row>
+
+        <v-sheet max-width="500" class="mx-auto mt-10">
+          <v-form @submit.prevent class="ECPay-form">
+            <v-text-field
+              v-model="userData.email"
+              :rules="fieldRules"
+              label="電子郵件"
+              required
+            ></v-text-field>
+            <v-text-field
+              v-model="userData.name"
+              :rules="fieldRules"
+              label="姓名"
+              required
+            ></v-text-field>
+            <v-text-field
+              v-model="userData.company"
+              label="公司 / 所屬產業"
+            ></v-text-field>
+            <v-text-field
+              v-model="userData.url"
+              :rules="fieldRules"
+              label="YouTube 影片網址"
+              required
+            ></v-text-field>
+            <v-text-field
+              v-model="userData.area"
+              :rules="fieldRules"
+              label="影片放送地區(國家 / 縣市)"
+              required
+            ></v-text-field>
+            <v-text-field
+              v-model="userData.language"
+              :rules="fieldRules"
+              label="受眾語言"
+              required
+            ></v-text-field>
+
+            <p class="mt-5">客層(未選擇的話視為全部)</p>
+            <div class="checkbox ms-5">
+              <v-checkbox
+                v-for="option in ageOptions"
+                v-model="userData.age"
+                :key="option.label"
+                :label="option.label"
+                :value="option.label"
+                color="primary"
+              ></v-checkbox>
+            </div>
+
+            <p class="mt-10 mb-3">
+              目標對象區隔(興趣、習慣)<span class="text-red-darken-1">*</span>
+            </p>
+            <div class="ms-5">
+              <v-radio-group v-model="object">
+                <v-radio
+                  v-for="option in objectOptions"
+                  :key="option.label"
+                  :label="option.label"
+                  :value="option.label"
+                  color="primary"
+                ></v-radio>
+                <v-radio label="其他" value="其他" color="primary"></v-radio>
+                <input v-model="otherObject" type="text" class="other" />
+              </v-radio-group>
+            </div>
+
+            <p class="mt-5 mb-3">
+              影片主題 <span class="text-red-darken-1">*</span>
+            </p>
+            <div class="ms-5">
+              <v-radio-group v-model="theme">
+                <v-radio
+                  v-for="option in themeOptions"
+                  :key="option.label"
+                  :label="option.label"
+                  :value="option.label"
+                  color="primary"
+                ></v-radio>
+
+                <v-radio label="其他" value="其他" color="primary"></v-radio>
+                <input v-model="otherTheme" type="text" class="other" />
+              </v-radio-group>
+            </div>
+
+            <v-text-field
+              type="number"
+              label="是否需要統編(可填寫統編號碼)"
+              v-model="userData.tax"
+            ></v-text-field>
+
+            <v-btn
+              @click="ECPaySubmit()"
+              type="submit"
+              block
+              class="mt-2 submit-btn"
+              :disabled="isSubmitDisabled"
+              >送出</v-btn
+            >
+          </v-form>
+        </v-sheet>
+      </v-card-text>
+    </v-card>
+  </v-container>
+
+  <div id="pay-form"></div>
+</template>
+
+<style lang="scss">
+.pay-card {
+  .v-card-title {
+    h5 {
+      font-size: 20px;
+    }
+    span {
+      font-size: 16px;
+      letter-spacing: 1px;
+    }
+    .price {
+      padding: 10px 0;
+      font-size: 26px;
+      font-weight: 600;
+      text-align: center;
+      color: #fff;
+      background-color: var(--main-color);
+      letter-spacing: 2px;
+      small {
+        display: block;
+        margin-top: -3px;
+        font-size: 18px;
+        font-weight: 100;
+        text-decoration: line-through;
+      }
+    }
+  }
+
+  .v-card-text {
+    ul {
+      padding: 0;
+      list-style: none;
+    }
+  }
+
+  .v-card-actions {
+    button {
+      padding: 5px 15px;
+      color: #fff;
+      border-radius: 100px;
+      background-color: var(--main-color);
+      border: 1px solid transparent;
+      &:hover {
+        color: var(--main-color);
+        background-color: #fff;
+        border: 1px solid var(--main-color);
+      }
+    }
+  }
+
+  .active {
+    border: 3px solid var(--main-color);
+  }
+
+  .error {
+    color: #b00020;
+  }
+}
+
+.ECPay-form {
+  font-size: 16px;
+  .checkbox {
+    margin-left: 5px;
+    list-style: none;
+    .v-input {
+      height: 40px;
+    }
+  }
+  .v-input__details {
+    padding-top: 0;
+    padding-bottom: 3px;
+  }
+  .other {
+    margin-left: 40px;
+    border-bottom: 1px solid #333;
+    &:focus-visible {
+      outline: none !important;
+    }
+  }
+  .submit-btn {
+    color: #fff;
+    background-color: var(--main-color);
+  }
+}
+</style>

+ 8 - 411
frontend/src/views/main/admin/TestECPay.vue

@@ -1,119 +1,11 @@
 <script setup lang="ts">
-import { ref, reactive, computed } from "vue";
+import { ref, reactive } from "vue";
 import { required } from "@/utils";
 import { useAdminStore } from "@/stores/admin";
 import axios from "axios";
 import { useMainStore } from "@/stores/main";
 
 const mainStore = useMainStore();
-const fieldRules = [(value: string) => !!value || "此欄位為必填項目"];
-
-const items = reactive([
-  { title: "100% 真人觀看" },
-  { title: "包含影片設定費" },
-  { title: "開發票" },
-  { title: "包含成效報表" },
-]);
-const cardItems = reactive([
-  { view: "5,000", price: "2,700", originalPrice: "3,500", param: 2700 },
-  { view: "10,000", price: "4,400", originalPrice: "5,000", param: 4400 },
-  { view: "30,000", price: "12,400", originalPrice: "13,000", param: 12400 },
-  { view: "50,000", price: "20,400", originalPrice: "21,000", param: 20400 },
-]);
-
-const ageOptions = [
-  { label: "18 - 24 歲" },
-  { label: "25 - 34 歲" },
-  { label: "35 - 44 歲" },
-  { label: "45 - 54 歲" },
-  { label: "55 - 64 歲" },
-  { label: "65 歲以上" },
-];
-
-const objectOptions = [
-  { label: "交通工具與運輸" },
-  { label: "媒體和娛樂" },
-  { label: "家居與園藝" },
-  { label: "新聞與政治" },
-  { label: "旅遊" },
-  { label: "生活型態與興趣" },
-  { label: "科技" },
-  { label: "美容與健康" },
-  { label: "美食與餐飲" },
-  { label: "購物愛好者" },
-  { label: "運動與健身" },
-  { label: "銀行與金融" },
-];
-
-const themeOptions = [
-  { label: "人文與社會" },
-  { label: "保健" },
-  { label: "全球地點(各地區)" },
-  { label: "參考資料(圖書館、博物館與目錄、清單等)" },
-  { label: "圖書與文學" },
-  { label: "家居與園藝" },
-  { label: "寵物與動物" },
-  { label: "工作與教育" },
-  { label: "工商業" },
-  { label: "房地產" },
-  { label: "新聞" },
-  { label: "旅遊與交通" },
-  { label: "汽車與交通工具" },
-  { label: "法律與政府" },
-  { label: "科學" },
-  { label: "網路社群" },
-  { label: "網際網路與電信" },
-  { label: "美容與健身" },
-  { label: "美食佳飲" },
-  { label: "興趣與休閒" },
-  { label: "藝術與娛樂" },
-  { label: "購物" },
-  { label: "遊戲" },
-  { label: "運動" },
-  { label: "金融" },
-  { label: "電腦和電子產品" },
-];
-
-let chooseError = ref(false);
-let selectedBtn = ref();
-
-function activeBtn(param: any) {
-  selectedBtn.value = param;
-  chooseError.value = false;
-}
-
-let userData = reactive({
-  email: "",
-  name: "",
-  company: "",
-  url: "",
-  area: "",
-  language: "",
-  age: [],
-  object: "",
-  theme: "",
-  tax: "",
-});
-
-// 其他選項
-let object = ref("");
-let theme = ref("");
-let otherObject = ref("");
-let otherTheme = ref("");
-
-// 檢查必填欄位
-const isSubmitDisabled = computed(() => {
-  return (
-    !userData.email ||
-    !userData.name ||
-    !userData.url ||
-    !userData.area ||
-    !userData.language ||
-    !object.value ||
-    !theme.value
-  );
-});
-
 async function ECPaySubmit() {
   /*
   const timestamp = Date.now()
@@ -156,29 +48,7 @@ async function ECPaySubmit() {
   return axios.post("https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5", formData)
   */
 
-  // 是否選擇方案
-  if (!selectedBtn.value) {
-    chooseError.value = true;
-    window.scrollTo({ top: 0, behavior: "smooth" }); // 捲動至上方
-  } else {
-    chooseError.value = false;
-  }
-
-  if (object.value === "其他" && otherObject.value !== "") {
-    userData.object = otherObject.value;
-  } else {
-    userData.object = object.value;
-  }
-
-  if (theme.value === "其他" && otherTheme.value !== "") {
-    userData.theme = otherTheme.value;
-  } else {
-    userData.theme = theme.value;
-  }
-
-  await saveData();
-
-  const originalHTML = await mainStore.ecpayPaymentHTML(selectedBtn.value);
+  const originalHTML = await mainStore.ecpayPaymentHTML(500);
   let formHTML = originalHTML?.replace(
     '<script type="text/javascript">document.getElementById("data_set").submit();</scr',
     ""
@@ -192,293 +62,20 @@ async function ECPaySubmit() {
   console.log(ecpayForm);
   ecpayForm.submit();
 }
-
-// 資料存進 Google Sheets
-async function saveData() {
-  const scriptURL =
-    "https://script.google.com/macros/s/AKfycbxCcfiOQ695DaxIa3peClqRRTWNj2aUNLbx7ty8U2wKlyU7wreQLioHG-sls5MPKBdlRQ/exec";
-
-  let formdata = new FormData();
-  formdata.append("email", userData.email);
-  formdata.append("name", userData.name);
-  formdata.append("company", userData.company);
-  formdata.append("url", userData.url);
-  formdata.append("area", userData.area);
-  formdata.append("language", userData.language);
-  formdata.append("age", userData.age.join("、"));
-  formdata.append("object", userData.object);
-  formdata.append("theme", userData.theme);
-  formdata.append("tax", userData.tax);
-
-  axios
-    .post(scriptURL, formdata)
-    .then(function (response) {
-      console.log(response.data);
-    })
-    .catch(function (error) {
-      console.log(error);
-    });
-}
 </script>
 
 <template>
   <v-container fluid>
     <v-card class="ma-3 pa-3">
-      <v-card-title primary-title class="mb-3">
-        <h3 class="headline primary--text">YouTube 觀看數</h3>
+      <v-card-title primary-title>
+        <div class="headline primary--text">Test ECPay</div>
       </v-card-title>
-      <v-card-text>
-        <p class="ms-3">請選擇方案:</p>
-        <v-row no-gutters class="pay-card">
-          <v-col
-            xs="12"
-            sm="6"
-            lg="3"
-            v-for="(item, index) in cardItems"
-            :key="index"
-          >
-            <button @click="activeBtn(item.param)" class="w-100">
-              <v-card
-                class="ma-3 py-3"
-                :class="{ active: selectedBtn === item.param }"
-              >
-                <v-card-title primary-title class="pa-0">
-                  <div class="d-flex flex-column">
-                    <section class="d-flex mx-auto">
-                      <img
-                        width="30"
-                        height="30"
-                        src="@/assets/img/icon/play-button.png"
-                        alt=""
-                        class="me-2"
-                      />
-                      <h5 class="m-0">{{ item.view }}</h5>
-                    </section>
-                    <span class="text-center" style="color: #7c8ba7"
-                      >Views</span
-                    >
-                  </div>
-                  <p class="price">
-                    NT${{ item.price }} <br />
-                    <small>NT${{ item.originalPrice }}</small>
-                  </p>
-                </v-card-title>
-
-                <v-card-text class="d-flex align-center justify-center mt-3">
-                  <ul>
-                    <li
-                      v-for="(item, index) in items"
-                      :key="index"
-                      class="d-flex align-center"
-                    >
-                      <img
-                        width="30"
-                        src="@/assets/img/icon/check.png"
-                        alt=""
-                      />
-                      {{ item.title }}
-                    </li>
-                  </ul>
-                </v-card-text>
-
-                <!-- <v-card-actions class="d-flex justify-center">
-                  <v-btn @click="ECPaySubmit(item.param)"> Buy Now </v-btn>
-                </v-card-actions> -->
-              </v-card>
-            </button>
-          </v-col>
-          <p class="ms-3 error" v-show="chooseError">尚未選擇方案</p>
-        </v-row>
-
-        <v-sheet max-width="500" class="mx-auto mt-10">
-          <v-form @submit.prevent class="ECPay-form">
-            <v-text-field
-              v-model="userData.email"
-              :rules="fieldRules"
-              label="電子郵件"
-              required
-            ></v-text-field>
-            <v-text-field
-              v-model="userData.name"
-              :rules="fieldRules"
-              label="姓名"
-              required
-            ></v-text-field>
-            <v-text-field
-              v-model="userData.company"
-              label="公司 / 所屬產業"
-            ></v-text-field>
-            <v-text-field
-              v-model="userData.url"
-              :rules="fieldRules"
-              label="YouTube 影片網址"
-              required
-            ></v-text-field>
-            <v-text-field
-              v-model="userData.area"
-              :rules="fieldRules"
-              label="影片放送地區(國家 / 縣市)"
-              required
-            ></v-text-field>
-            <v-text-field
-              v-model="userData.language"
-              :rules="fieldRules"
-              label="受眾語言"
-              required
-            ></v-text-field>
-
-            <p class="mt-5">客層(未選擇的話視為全部)</p>
-            <div class="checkbox ms-5">
-              <v-checkbox
-                v-for="option in ageOptions"
-                v-model="userData.age"
-                :key="option.label"
-                :label="option.label"
-                :value="option.label"
-                color="primary"
-              ></v-checkbox>
-            </div>
-
-            <p class="mt-10 mb-3">
-              目標對象區隔(興趣、習慣)<span class="text-red-darken-1">*</span>
-            </p>
-            <div class="ms-5">
-              <v-radio-group v-model="object">
-                <v-radio
-                  v-for="option in objectOptions"
-                  :key="option.label"
-                  :label="option.label"
-                  :value="option.label"
-                  color="primary"
-                ></v-radio>
-                <v-radio label="其他" value="其他" color="primary"></v-radio>
-                <input v-model="otherObject" type="text" class="other" />
-              </v-radio-group>
-            </div>
-
-            <p class="mt-5 mb-3">
-              影片主題 <span class="text-red-darken-1">*</span>
-            </p>
-            <div class="ms-5">
-              <v-radio-group v-model="theme">
-                <v-radio
-                  v-for="option in themeOptions"
-                  :key="option.label"
-                  :label="option.label"
-                  :value="option.label"
-                  color="primary"
-                ></v-radio>
-
-                <v-radio label="其他" value="其他" color="primary"></v-radio>
-                <input v-model="otherTheme" type="text" class="other" />
-              </v-radio-group>
-            </div>
-
-            <v-text-field
-              type="number"
-              label="是否需要統編(可填寫統編號碼)"
-              v-model="userData.tax"
-            ></v-text-field>
-
-            <v-btn
-              @click="ECPaySubmit()"
-              type="submit"
-              block
-              class="mt-2 submit-btn"
-              :disabled="isSubmitDisabled"
-              >送出</v-btn
-            >
-          </v-form>
-        </v-sheet>
-      </v-card-text>
+      <v-card-actions>
+        <v-spacer></v-spacer>
+        <v-btn @click="ECPaySubmit"> Send </v-btn>
+      </v-card-actions>
     </v-card>
   </v-container>
 
   <div id="pay-form"></div>
 </template>
-
-<style lang="scss">
-.pay-card {
-  .v-card-title {
-    h5 {
-      font-size: 20px;
-    }
-    span {
-      font-size: 16px;
-      letter-spacing: 1px;
-    }
-    .price {
-      padding: 10px 0;
-      font-size: 26px;
-      font-weight: 600;
-      text-align: center;
-      color: #fff;
-      background-color: var(--main-color);
-      letter-spacing: 2px;
-      small {
-        display: block;
-        margin-top: -3px;
-        font-size: 18px;
-        font-weight: 100;
-        text-decoration: line-through;
-      }
-    }
-  }
-
-  .v-card-text {
-    ul {
-      padding: 0;
-      list-style: none;
-    }
-  }
-
-  .v-card-actions {
-    button {
-      padding: 5px 15px;
-      color: #fff;
-      border-radius: 100px;
-      background-color: var(--main-color);
-      border: 1px solid transparent;
-      &:hover {
-        color: var(--main-color);
-        background-color: #fff;
-        border: 1px solid var(--main-color);
-      }
-    }
-  }
-
-  .active {
-    border: 3px solid var(--main-color);
-  }
-
-  .error {
-    color: #b00020;
-  }
-}
-
-.ECPay-form {
-  font-size: 16px;
-  .checkbox {
-    margin-left: 5px;
-    list-style: none;
-    .v-input {
-      height: 40px;
-    }
-  }
-  .v-input__details {
-    padding-top: 0;
-    padding-bottom: 3px;
-  }
-  .other {
-    margin-left: 40px;
-    border-bottom: 1px solid #333;
-    &:focus-visible {
-      outline: none !important;
-    }
-  }
-  .submit-btn {
-    color: #fff;
-    background-color: var(--main-color);
-  }
-}
-</style>