浏览代码

add genseo

SyuanYu 4 月之前
父节点
当前提交
a4c97f05e2

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

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

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

@@ -73,6 +73,7 @@
     "feedback": "Feedback",
     "greenScreen": "Green Screen",
     "aiReporter": "AI Reporter",
+    "genSeo": "Gen SEO",
     "autoCreateVideoMaterials": "Auto Create Video Materials",
     "generateZip": "Generate ZIP",
     "paragraph": "Paragraph",

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

@@ -73,6 +73,7 @@
     "feedback": "意見回饋",
     "greenScreen": "綠幕",
     "aiReporter": "AI 記者",
+    "genSeo": "算力傳媒",
     "autoCreateVideoMaterials": "自動製作影片素材",
     "generateZip": "生成 ZIP",
     "paragraph": "段落",

+ 6 - 1
frontend/src/router/index.ts

@@ -43,10 +43,15 @@ const router = createRouter({
           name: 'yt-views',
           component: () => import('@/views/YTViews.vue'),
         },
+        {
+          path: 'gen-seo',
+          name: 'gen-seo',
+          component: () => import('@/views/GenSeo.vue'),
+        },
         {
           path: 'ai-reporter',
           name: 'ai-reporter',
-          component: () => import('@/views/aiReporter.vue'),
+          component: () => import('@/views/AiReporter.vue'),
         },
         {
           path: 'orders',

+ 296 - 0
frontend/src/views/GenSeo.vue

@@ -0,0 +1,296 @@
+<script setup lang="ts">
+import { ref, reactive, computed, watch } from "vue";
+import { required, emailRules } from "@/utils";
+import { useMainStore } from "@/stores/main";
+import type { SimplePaymentData } 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: "影音新聞精修" },
+  { title: "Google News 收錄" },
+  { title: "國外網站收錄" },
+  { title: "國內外30個以上網路新聞收錄" },
+  { title: "發布報告" },
+]);
+
+const cardItems = reactive([
+  { view: "標準(1篇)", price: "6,800", param: 6800 },
+  { view: "專業(預購5篇)", price: "30,000", param: 30000 },
+  { view: "採購(10篇)", price: "50,000", param: 50000 },
+]);
+
+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: "",
+  taxID: "",
+  tradeDesc: "算力傳媒商業版",
+});
+
+// 檢查必填欄位
+const isSubmitDisabled = computed(() => {
+  return !userData.email || !userData.name;
+});
+
+async function ecpay() {
+  if (!assignView.value || !assignPrice.value) {
+    chooseError.value = true;
+    return;
+  }
+
+  const data: SimplePaymentData = {
+    email: userData.email,
+    name: userData.name,
+    taxID: userData.taxID,
+    tradeDesc: userData.tradeDesc,
+    item: `算力傳媒商業版_${assignView.value}`,
+    amount: assignPrice.value,
+  };
+
+  console.log("data", data);
+
+  const originalHTML = await mainStore.simplePayment(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();
+}
+</script>
+
+<template>
+  <Navbar />
+
+  <v-container fluid class="mt-16">
+    <v-card class="ma-2" style="box-shadow: none">
+      <v-card-title primary-title class="mb-3">
+        <h3 class="headline primary--text">算力傳媒商業版</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"
+                :class="{ active: assignPrice === item.param }"
+              >
+                <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 /></p>
+                </v-card-title>
+
+                <v-card-text
+                  class="d-flex align-center justify-center mt-3 pb-0"
+                >
+                  <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>
+            </button>
+          </v-col>
+          <p class="ms-3 error" v-show="chooseError">
+            <v-icon icon="error" class="me-1"></v-icon> 尚未選擇方案
+          </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="emailRules()"
+              label="電子郵件"
+              required
+            ></v-text-field>
+            <v-text-field
+              v-model="userData.name"
+              :rules="required()"
+              label="姓名"
+              required
+            ></v-text-field>
+
+            <v-text-field
+              v-model="userData.taxID"
+              type="number"
+              label="是否需要統編(可填寫統編號碼)"
+            ></v-text-field>
+
+            <v-btn
+              @click="ecpay()"
+              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" scoped>
+.info {
+  display: flex;
+  justify-content: center;
+  ul {
+    line-height: 2;
+  }
+}
+
+.pay-card {
+  .v-card {
+    border: 3px solid transparent;
+    transition: all 0.3s;
+
+    &:hover {
+      border: 3px solid var(--main-color);
+    }
+
+    &.active {
+      border: 3px solid var(--main-color);
+    }
+
+    .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;
+      }
+    }
+  }
+
+  .error {
+    display: flex;
+    align-items: center;
+    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;
+    }
+  }
+
+  .submit-btn {
+    font-size: 1rem;
+    font-weight: bold;
+    color: #fff;
+    background-color: var(--main-color);
+  }
+}
+</style>

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

@@ -233,7 +233,7 @@ async function ECPaySubmit() {
   <Navbar />
 
   <v-container fluid class="mt-16">
-    <v-card class="ma-3 pa-3">
+    <v-card class="ma-2" style="box-shadow: none">
       <v-card-title primary-title class="mb-3">
         <h3 class="headline primary--text">YouTube 觀看數</h3>
       </v-card-title>

+ 1 - 1
frontend/src/views/aiReporter.vue

@@ -84,7 +84,7 @@ async function ecpay() {
   <Navbar />
 
   <v-container fluid class="mt-16">
-    <v-card class="ma-3 pa-3" style="box-shadow: none">
+    <v-card class="ma-2" style="box-shadow: none">
       <v-card-title primary-title class="mb-3">
         <h3 class="headline primary--text">AI 記者訂閱制方案</h3>
       </v-card-title>