SyuanYu 1 week ago
parent
commit
c4b015bd2b

+ 1 - 0
frontend/src/components/Navbar.vue

@@ -13,6 +13,7 @@ let menu = reactive([
   { title: "login", link: "/login" },
   { title: "register", link: "/signup" },
   { title: "ytViews", link: "/yt-views" },
+  { title: "aiReporter", link: "/ai-reporter" },
   // { title: "實體卡儲值", link: "/qrcode" },
 ]);
 

+ 72 - 0
frontend/src/components/SubscribePayment.vue

@@ -0,0 +1,72 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import type { PaymentData } from "@/interfaces";
+import { useMainStore } from "@/stores/main";
+
+const mainStore = useMainStore();
+let isLoading = ref(false);
+const credit = ref(1);
+
+function increment() {
+  credit.value++;
+}
+function decrement() {
+  if (credit.value > 1) {
+    credit.value--;
+  }
+}
+
+const epayment = ref("ecpay");
+
+async function ecpay() {
+  isLoading.value = true;
+  const data: PaymentData = {
+    item: `Credit ${60 * credit.value}`,
+    amount: 500 * credit.value,
+  };
+  if (data.amount <= 0) {
+    return;
+  }
+
+  const originalHTML = await mainStore.Payment(data, "zh");
+
+  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")
+  );
+  ecpayForm.submit();
+
+  setTimeout(() => {
+    isLoading.value = false;
+  }, 3000);
+}
+</script>
+
+<template>
+  <div class="d-flex align-center flex-wrap">
+    <button class="ms-2 mb-2">立即訂閱</button>
+  </div>
+
+  <div id="pay-form"></div>
+</template>
+
+<style lang="scss" scoped>
+button {
+  padding: 0.7rem 3rem;
+  color: #fff;
+  letter-spacing: 2px;
+  font-weight: 500;
+  border-radius: 4px;
+  background-image: linear-gradient(
+    -225deg,
+    rgb(234, 84, 19) 35%,
+    rgb(178, 69, 146) 100%
+  );
+}
+</style>

+ 2 - 1
frontend/src/language/en.json

@@ -71,5 +71,6 @@
     "emailRules": "Must be a valid e-mail.",
     "phoneNumber": "Phone Number (optional)",
     "feedback": "Feedback",
-    "green_screen": "Green Screen"
+    "greenScreen": "Green Screen",
+    "aiReporter": "AI Reporter"
 }

+ 2 - 1
frontend/src/language/zh.json

@@ -71,5 +71,6 @@
     "emailRules": "請輸入有效的電子郵件格式",
     "phoneNumber": "手機號碼(非必填)",
     "feedback": "意見回饋",
-    "green_screen": "綠幕"
+    "greenScreen": "綠幕",
+    "aiReporter": "AI 記者"
 }

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

@@ -43,6 +43,11 @@ const router = createRouter({
           name: 'yt-views',
           component: () => import('@/views/YTViews.vue'),
         },
+        {
+          path: 'ai-reporter',
+          name: 'ai-reporter',
+          component: () => import('@/views/aiReporter.vue'),
+        },
         {
           path: 'orders',
           name: 'orders',

+ 12 - 1
frontend/src/views/YTViews.vue

@@ -238,7 +238,7 @@ async function ECPaySubmit() {
         <h3 class="headline primary--text">YouTube 觀看數</h3>
       </v-card-title>
       <v-card-text>
-        <p class="ms-3">請選擇方案:</p>
+        <p class="mb-3 text-h6 text-center">請選擇方案</p>
         <v-row no-gutters class="pay-card">
           <v-col
             xs="12"
@@ -446,6 +446,15 @@ async function ECPaySubmit() {
 
 <style lang="scss">
 .pay-card {
+  .v-card {
+    border: 3px solid transparent;
+    transition: all 0.3s;
+
+    &:hover {
+      border: 3px solid var(--main-color);
+    }
+  }
+
   .v-card-title {
     h5 {
       font-size: 20px;
@@ -524,6 +533,8 @@ async function ECPaySubmit() {
     }
   }
   .submit-btn {
+    font-size: 1rem;
+    font-weight: bold;
     color: #fff;
     background-color: var(--main-color);
   }

+ 320 - 0
frontend/src/views/aiReporter.vue

@@ -0,0 +1,320 @@
+<script setup lang="ts">
+import { ref, reactive, computed, watch } from "vue";
+import { required, emailRules } from "@/utils";
+import { useMainStore } from "@/stores/main";
+import type { PaymentData } from "@/interfaces";
+// import type { YTViewsUserData } from "@/interfaces";
+import Navbar from "@/components/Navbar.vue";
+
+const mainStore = useMainStore();
+const urlRules = [
+  (v: any) =>
+    /^(http|https):\/\//.test(v) || "請輸入以 http 或 https 開頭的有效網址",
+];
+
+const items = reactive([
+  { title: "100% 真人觀看" },
+  { title: "包含影片設定費" },
+  { title: "開發票" },
+  { title: "包含成效報表" },
+]);
+
+const cardItems = reactive([
+  { view: "季訂方案", price: "3,600", param: 3600 },
+  { view: "半年方案", price: "5,040", param: 5040 },
+  { view: "一年方案", price: "7,200", param: 7200 },
+]);
+
+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;
+
+  console.log('assignView.value',assignView.value);
+  console.log('assignPrice.value',assignPrice.value);
+  
+  ecpay();
+}
+
+async function ecpay() {
+  const data: PaymentData = {
+    item: `AI記者訂閱制方案_${assignView.value}`,
+    amount: assignPrice.value,
+  };
+  if (data.amount <= 0) {
+    return;
+  }
+
+  const originalHTML = await mainStore.Payment(data, "zh");
+
+  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")
+  );
+  ecpayForm.submit();
+}
+
+// async function ecpay() {
+//   if (!assignPrice.value) {
+//     chooseError.value = true;
+//     window.scrollTo({ top: 0, behavior: "smooth" });
+//   } else {
+//     chooseError.value = false;
+//   }
+
+//   if (checkOtherTarget.value === "其他" && otherTarget.value !== "") {
+//     userData.target = `${target.value.join("、")}、${otherTarget.value}`;
+//   } else {
+//     userData.target = target.value.join("、");
+//   }
+
+//   if (checkOtherTheme.value === "其他" && otherTheme.value !== "") {
+//     userData.theme = `${theme.value.join("、")}、${otherTheme.value}`;
+//   } else {
+//     userData.theme = theme.value.join("、");
+//   }
+
+//   let lang = ref("");
+//   let getLang = localStorage.getItem("lang");
+
+//   // 綠界顯示語言
+//   if (!getLang || getLang === "zh") {
+//     lang.value = "ZH";
+//   } else {
+//     lang.value = "ENG";
+//   }
+
+//   let data: YTViewsUserData = {
+//     item: `YT觀看數(${assignView.value} 次觀看)`,
+//     amount: assignPrice.value,
+//     email: userData.email,
+//     name: userData.name,
+//     phone: userData.phone,
+//     company: userData.company,
+//     url: userData.url,
+//     area: userData.area,
+//     language: userData.language,
+//     ages: userData.ages.join("、"),
+//     target: userData.target,
+//     theme: userData.theme,
+//     taxID: userData.taxID,
+//   };
+
+//   const originalHTML = await mainStore.YTViewsPayment(data, lang.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>
+  <Navbar />
+
+  <v-container fluid class="mt-16">
+    <v-card class="ma-3 pa-3" style="box-shadow: none">
+      <v-card-title primary-title class="mb-3">
+        <h3 class="headline primary--text">AI 記者訂閱制方案</h3>
+      </v-card-title>
+      <v-card-text>
+        <p class="mb-3 text-h6 text-center">請選擇方案</p>
+        <v-row no-gutters class="pay-card">
+          <v-col
+            cols="12"
+            md="4"
+            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">
+                <v-card-title primary-title class="pa-0">
+                  <div class="d-flex flex-column">
+                    <h5 class="my-5 text-h5">{{ item.view }}</h5>
+                  </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>
+
+                <button class="my-5 submit-btn">
+                  立即訂閱
+                </button>
+
+                <!-- <v-card-actions class="d-flex justify-center">
+                  <v-btn @click="ecpay(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-card-text>
+    </v-card>
+  </v-container>
+
+  <div id="pay-form"></div>
+</template>
+
+<style lang="scss" scoped>
+.pay-card {
+  .v-card-title {
+    h5 {
+      font-weight: bold;
+    }
+    span {
+      font-size: 16px;
+      letter-spacing: 1px;
+    }
+    .price {
+      padding: 1rem 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);
+      }
+    }
+  }
+
+  .error {
+    color: #b00020;
+  }
+
+  .v-card {
+    .submit-btn {
+      width: 150px;
+      padding: 1rem;
+      border-radius: 100px;
+      font-size: 1rem;
+      font-weight: bold;
+      color: var(--main-color);
+      border: 2px solid var(--main-color);
+      background-color: #fff;
+      letter-spacing: 1px;
+      transition: all 0.3s;
+    }
+
+    &:hover {
+      .submit-btn {
+        color: #fff;
+        background-color: var(--main-color);
+      }
+    }
+  }
+}
+
+.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;
+    }
+  }
+}
+</style>

+ 1 - 1
frontend/src/views/main/Progress.vue

@@ -28,7 +28,7 @@ const headers = [
     key: "id",
   },
   {
-    title: t("green_screen"),
+    title: t("greenScreen"),
     key: "green_screen",
   },
 ];