|
@@ -1,9 +1,84 @@
|
|
|
<script setup>
|
|
|
-import { ref } from "vue";
|
|
|
+import { ref, reactive } from "vue";
|
|
|
import axios from "axios";
|
|
|
|
|
|
-let kwVal = ref("");
|
|
|
-let stageVal = ref(null);
|
|
|
+let kwVal = ref(""); // 關鍵字
|
|
|
+let stageVal = ref(null); // 指定層級
|
|
|
+let maxStage = ref(null); // 最大層級
|
|
|
+let haveStage = ref(false); // 是否有層級
|
|
|
+let searchState = ref(false); // 點擊查詢
|
|
|
+let searchLoading = ref(false); // 載入狀態
|
|
|
+let showStageBtn = ref(false); // 新增層級按鈕
|
|
|
+
|
|
|
+// 取得最大層數
|
|
|
+async function getStage() {
|
|
|
+ searchLoading.value = true;
|
|
|
+ let url = `https://cmm.ai:8083/get_stage3?kw=${kwVal.value}`;
|
|
|
+
|
|
|
+ try {
|
|
|
+ let response = await axios.get(url);
|
|
|
+ console.log("response", response);
|
|
|
+ console.log(response.data.message.headers);
|
|
|
+ searchState.value = true;
|
|
|
+ if (response.data.message.detail === "Failed to generate stage") {
|
|
|
+ haveStage.value = false;
|
|
|
+ } else {
|
|
|
+ maxStage.value = response.data.message;
|
|
|
+ haveStage.value = true;
|
|
|
+
|
|
|
+ // 層級小於五層才顯示新增按鈕
|
|
|
+ if (response.data.message < 5) {
|
|
|
+ showStageBtn.value = true;
|
|
|
+ } else {
|
|
|
+ showStageBtn.value = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log("response.data.message", response.data.message);
|
|
|
+
|
|
|
+ searchLoading.value = false;
|
|
|
+ } catch (error) {
|
|
|
+ console.error("error", error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+let insertError = ref(false);
|
|
|
+let regionsVal = ref(null); // 地區
|
|
|
+let languageVal = ref(null); // 語言
|
|
|
+
|
|
|
+// 新增關鍵字
|
|
|
+async function insertKw() {
|
|
|
+ if (!regionsVal.value || !languageVal.value) {
|
|
|
+ insertError.value = true;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ let url = `https://cmm.ai:8083/insert_kw3?kw=${kwVal.value}®ion=${regionsVal.value}&language=${languageVal.value}`;
|
|
|
+
|
|
|
+ try {
|
|
|
+ let response = await axios.put(url);
|
|
|
+ console.log("新增關鍵字", response);
|
|
|
+
|
|
|
+ if (response.status === 200) {
|
|
|
+ alert("關鍵字已加入排程中,請稍等");
|
|
|
+
|
|
|
+ // 清空地區及語言
|
|
|
+ regionsVal.value = null;
|
|
|
+ languageVal.value = null;
|
|
|
+ // 關閉查詢結果
|
|
|
+ searchState.value = false;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("error", error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+let insertDialog = ref(false);
|
|
|
+let insertState = ref(false); // 點新增層級
|
|
|
+
|
|
|
+// function insert() {
|
|
|
+// checkState.value = true;
|
|
|
+// }
|
|
|
|
|
|
// 將所有流程包進來
|
|
|
async function processData() {
|
|
@@ -63,17 +138,6 @@ async function getHtml() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 取得最大層數
|
|
|
-async function getStage() {
|
|
|
- let url = `https://cmm.ai:8084/get_stage3?kw=${kwVal.value}`;
|
|
|
- try {
|
|
|
- const response = await axios.get(url);
|
|
|
- console.log("取得最大層數 response", response);
|
|
|
- } catch (error) {
|
|
|
- console.error("取得最大層數失敗", error);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
// 插入資料
|
|
|
function insertData(kw) {
|
|
|
let url = `https://cmm.ai:8084/insert_data3?kw=${kwVal.value}`;
|
|
@@ -83,6 +147,61 @@ function insertData(kw) {
|
|
|
alert(message);
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+// 地區
|
|
|
+const regionsList = reactive([
|
|
|
+ { region: "台灣", code: "tw" },
|
|
|
+ { region: "馬來西亞", code: "my" },
|
|
|
+ { region: "美國", code: "us" },
|
|
|
+ { region: "加拿大", code: "ca" },
|
|
|
+ { region: "英國", code: "gb" },
|
|
|
+ { region: "中國", code: "cn" },
|
|
|
+ { region: "日本", code: "jp" },
|
|
|
+ { region: "韓國", code: "kr" },
|
|
|
+ { region: "德國", code: "de" },
|
|
|
+ { region: "法國", code: "fr" },
|
|
|
+ { region: "義大利", code: "it" },
|
|
|
+ { region: "西班牙", code: "es" },
|
|
|
+ { region: "澳大利亞", code: "au" },
|
|
|
+ { region: "印度", code: "in" },
|
|
|
+ { region: "巴西", code: "br" },
|
|
|
+ { region: "俄羅斯", code: "ru" },
|
|
|
+ { region: "南非", code: "za" },
|
|
|
+ { region: "新加坡", code: "sg" },
|
|
|
+]);
|
|
|
+
|
|
|
+// 語言
|
|
|
+const languageList = [
|
|
|
+ { language: "繁體中文", code: "zh-TW" },
|
|
|
+ { language: "英文", code: "en" },
|
|
|
+ { language: "簡體中文", code: "zh" },
|
|
|
+ { language: "西班牙語", code: "es" },
|
|
|
+ { language: "法語", code: "fr" },
|
|
|
+ { language: "德語", code: "de" },
|
|
|
+ { language: "意大利語", code: "it" },
|
|
|
+ { language: "葡萄牙語", code: "pt" },
|
|
|
+ { language: "俄語", code: "ru" },
|
|
|
+ { language: "日語", code: "ja" },
|
|
|
+ { language: "韓語", code: "ko" },
|
|
|
+ { language: "阿拉伯語", code: "ar" },
|
|
|
+ { language: "印地語", code: "hi" },
|
|
|
+ { language: "泰語", code: "th" },
|
|
|
+ { language: "越南語", code: "vi" },
|
|
|
+ { language: "土耳其語", code: "tr" },
|
|
|
+ { language: "希臘語", code: "el" },
|
|
|
+ { language: "希伯來語", code: "he" },
|
|
|
+ { language: "波蘭語", code: "pl" },
|
|
|
+ { language: "荷蘭語", code: "nl" },
|
|
|
+ { language: "瑞典語", code: "sv" },
|
|
|
+ { language: "丹麥語", code: "da" },
|
|
|
+ { language: "挪威語", code: "no" },
|
|
|
+ { language: "芬蘭語", code: "fi" },
|
|
|
+ { language: "捷克語", code: "cs" },
|
|
|
+ { language: "匈牙利語", code: "hu" },
|
|
|
+ { language: "斯洛伐克語", code: "sk" },
|
|
|
+ { language: "斯洛文尼亞語", code: "sl" },
|
|
|
+ { language: "克羅埃西亞語", code: "hr" },
|
|
|
+];
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
@@ -92,7 +211,7 @@ function insertData(kw) {
|
|
|
<h3 class="card-title mb-3">GEN SEO</h3>
|
|
|
</v-card-title>
|
|
|
<v-card-text class="card-content">
|
|
|
- <div class="d-flex flex-column flex-md-row align-center">
|
|
|
+ <div class="d-flex align-center">
|
|
|
<v-text-field
|
|
|
v-model="kwVal"
|
|
|
label="關鍵字"
|
|
@@ -100,9 +219,10 @@ function insertData(kw) {
|
|
|
prepend-inner-icon="search"
|
|
|
variant="solo"
|
|
|
hide-details
|
|
|
+ class="mr-5 search-field"
|
|
|
></v-text-field>
|
|
|
|
|
|
- <v-select
|
|
|
+ <!-- <v-select
|
|
|
v-model="stageVal"
|
|
|
label="層級"
|
|
|
density="compact"
|
|
@@ -110,9 +230,136 @@ function insertData(kw) {
|
|
|
variant="solo"
|
|
|
hide-details
|
|
|
class="my-7 my-md-0 mx-md-5"
|
|
|
- ></v-select>
|
|
|
+ ></v-select> -->
|
|
|
|
|
|
- <button @click="processData()" class="search-btn">查詢</button>
|
|
|
+ <button @click="getStage()" class="search-btn">
|
|
|
+ <v-progress-circular
|
|
|
+ v-if="searchLoading"
|
|
|
+ :width="3"
|
|
|
+ :size="20"
|
|
|
+ color="white"
|
|
|
+ class="pb-1"
|
|
|
+ indeterminate
|
|
|
+ ></v-progress-circular>
|
|
|
+ <p v-else>查詢</p>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </v-card-text>
|
|
|
+ </v-card>
|
|
|
+
|
|
|
+ <v-card v-if="searchState" class="mt-10 ma-3 pa-sm-5">
|
|
|
+ <v-card-title primary-title>
|
|
|
+ <h3 class="card-title mb-3">查詢結果</h3>
|
|
|
+ </v-card-title>
|
|
|
+ <v-card-text class="card-content">
|
|
|
+ <div v-if="haveStage" class="d-flex flex-column">
|
|
|
+ <span class="d-flex align-center">
|
|
|
+ <p class="pt-1 mr-5">目前最大層級:{{ maxStage }}</p>
|
|
|
+ <v-btn
|
|
|
+ v-if="showStageBtn"
|
|
|
+ @click="
|
|
|
+ insertDialog = true;
|
|
|
+ insertState = true;
|
|
|
+ "
|
|
|
+ variant="outlined"
|
|
|
+ color="primary"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ 新增層級
|
|
|
+ </v-btn>
|
|
|
+
|
|
|
+ <v-dialog v-model="insertDialog" width="auto">
|
|
|
+ <v-card width="400" title="新增層級">
|
|
|
+ <v-card-text class="d-flex mt-5">
|
|
|
+ <v-select
|
|
|
+ v-model="regionsVal"
|
|
|
+ label="地區"
|
|
|
+ density="compact"
|
|
|
+ :items="regionsList"
|
|
|
+ item-title="region"
|
|
|
+ item-value="code"
|
|
|
+ variant="solo"
|
|
|
+ hide-details
|
|
|
+ :rules="[(value) => !!value || '尚未選擇地區']"
|
|
|
+ ></v-select>
|
|
|
+
|
|
|
+ <v-select
|
|
|
+ v-model="languageVal"
|
|
|
+ label="語言"
|
|
|
+ density="compact"
|
|
|
+ :items="languageList"
|
|
|
+ item-title="language"
|
|
|
+ item-value="code"
|
|
|
+ variant="solo"
|
|
|
+ hide-details
|
|
|
+ class="mx-5"
|
|
|
+ :rules="[(value) => !!value || '尚未選擇語言']"
|
|
|
+ ></v-select>
|
|
|
+
|
|
|
+ <p v-if="insertError" class="text-error">請選擇地區及語言</p>
|
|
|
+
|
|
|
+ <v-btn @click="insertKw()" color="primary" class="mt-1"
|
|
|
+ >送出</v-btn
|
|
|
+ >
|
|
|
+ </v-card-text>
|
|
|
+
|
|
|
+ <v-card-actions>
|
|
|
+ <v-btn class="ms-auto mr-4" @click="insertDialog = false">
|
|
|
+ 關閉
|
|
|
+ </v-btn>
|
|
|
+ </v-card-actions>
|
|
|
+ </v-card>
|
|
|
+ </v-dialog>
|
|
|
+ <!-- <button @click="getStage()" class="insert-btn">新增層級</button> -->
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <span class="d-flex align-center mt-7">
|
|
|
+ <v-select
|
|
|
+ v-model="stageVal"
|
|
|
+ label="請選擇層級"
|
|
|
+ density="compact"
|
|
|
+ :items="['1', '2', '3', '4', '5']"
|
|
|
+ variant="solo"
|
|
|
+ hide-details
|
|
|
+ ></v-select>
|
|
|
+
|
|
|
+ <button @click="getHtml()" class="search-btn ml-3">查看結果</button>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-else>
|
|
|
+ <p>未查詢到關鍵字,請選擇要搜尋的地區及語言:</p>
|
|
|
+
|
|
|
+ <span class="d-flex mt-5">
|
|
|
+ <v-select
|
|
|
+ v-model="regionsVal"
|
|
|
+ label="地區"
|
|
|
+ density="compact"
|
|
|
+ :items="regionsList"
|
|
|
+ item-title="region"
|
|
|
+ item-value="code"
|
|
|
+ variant="solo"
|
|
|
+ hide-details
|
|
|
+ :rules="[(value) => !!value || '尚未選擇地區']"
|
|
|
+ ></v-select>
|
|
|
+
|
|
|
+ <v-select
|
|
|
+ v-model="languageVal"
|
|
|
+ label="語言"
|
|
|
+ density="compact"
|
|
|
+ :items="languageList"
|
|
|
+ item-title="language"
|
|
|
+ item-value="code"
|
|
|
+ variant="solo"
|
|
|
+ hide-details
|
|
|
+ class="mx-5"
|
|
|
+ :rules="[(value) => !!value || '尚未選擇語言']"
|
|
|
+ ></v-select>
|
|
|
+
|
|
|
+ <p v-if="insertError" class="text-error">請選擇地區及語言</p>
|
|
|
+
|
|
|
+ <button @click="insertKw()" class="search-btn">送出</button>
|
|
|
+ </span>
|
|
|
</div>
|
|
|
</v-card-text>
|
|
|
</v-card>
|
|
@@ -121,10 +368,20 @@ function insertData(kw) {
|
|
|
|
|
|
<style lang="scss">
|
|
|
.knowledge-graph {
|
|
|
+ .v-select {
|
|
|
+ max-width: 10rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-field {
|
|
|
+ max-width: 21rem;
|
|
|
+ }
|
|
|
+
|
|
|
.search-btn {
|
|
|
- padding: 10px 30px;
|
|
|
- border-radius: 100px;
|
|
|
+ padding: 13px 30px 10px;
|
|
|
color: #fff;
|
|
|
+ font-weight: 500;
|
|
|
+ letter-spacing: 2px;
|
|
|
+ border-radius: 100px;
|
|
|
background-image: linear-gradient(
|
|
|
-225deg,
|
|
|
rgb(234, 84, 19) 35%,
|