|
@@ -1,119 +1,11 @@
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { ref, reactive, computed } from "vue";
|
|
|
|
|
|
+import { ref, reactive } from "vue";
|
|
import { required } from "@/utils";
|
|
import { required } from "@/utils";
|
|
import { useAdminStore } from "@/stores/admin";
|
|
import { useAdminStore } from "@/stores/admin";
|
|
import axios from "axios";
|
|
import axios from "axios";
|
|
import { useMainStore } from "@/stores/main";
|
|
import { useMainStore } from "@/stores/main";
|
|
|
|
|
|
const mainStore = useMainStore();
|
|
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() {
|
|
async function ECPaySubmit() {
|
|
/*
|
|
/*
|
|
const timestamp = Date.now()
|
|
const timestamp = Date.now()
|
|
@@ -156,29 +48,7 @@ async function ECPaySubmit() {
|
|
return axios.post("https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5", formData)
|
|
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(
|
|
let formHTML = originalHTML?.replace(
|
|
'<script type="text/javascript">document.getElementById("data_set").submit();</scr',
|
|
'<script type="text/javascript">document.getElementById("data_set").submit();</scr',
|
|
""
|
|
""
|
|
@@ -192,293 +62,20 @@ async function ECPaySubmit() {
|
|
console.log(ecpayForm);
|
|
console.log(ecpayForm);
|
|
ecpayForm.submit();
|
|
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>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
<v-container fluid>
|
|
<v-container fluid>
|
|
<v-card class="ma-3 pa-3">
|
|
<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-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-card>
|
|
</v-container>
|
|
</v-container>
|
|
|
|
|
|
<div id="pay-form"></div>
|
|
<div id="pay-form"></div>
|
|
</template>
|
|
</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>
|
|
|