123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- <script setup>
- import { ref, reactive, computed } from "vue";
- import axios from "axios";
- 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); // 新增層級按鈕
- let regionsVal = ref(null); // 地區
- let languageVal = ref(null); // 語言
- let searchError = ref(false); // 查詢狀態
- // 取得最大層數
- async function getStage() {
- if (!regionsVal.value || !languageVal.value) {
- searchError.value = true;
- return;
- } else {
- searchError.value = false;
- }
- searchLoading.value = true;
- let url = `https://cmm.ai:8083/get_stage3?kw=${kwVal.value}®ion=${regionsVal.value}&language=${languageVal.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 insertRegionsVal = ref(null); // 新增地區
- // let insertLanguageVal = ref(null); // 新增語言
- // 新增關鍵字
- async function insertKw() {
- if (!regionsVal.value || !languageVal.value) {
- alert("請選擇要新增的地區及語言");
- return;
- }
- let email = localStorage.getItem("email");
- let url = `https://cmm.ai:8083/insert_kw3?kw=${kwVal.value}®ion=${regionsVal.value}&language=${languageVal.value}&email=${email}`;
- try {
- let response = await axios.put(url);
- console.log("新增關鍵字", response);
- if (response.status === 200) {
- alert("關鍵字已加入排程");
- // 清空地區及語言
- // insertRegionsVal.value = null;
- // insertLanguageVal.value = null;
- // 關閉查詢結果
- // searchState.value = false;
- }
- getKwStateList();
- } catch (error) {
- console.error("error", error);
- }
- }
- // let insertDialog = ref(false);
- // let insertState = ref(false); // 新增層級
- let graphContent = ref(""); // html code
- // 取得 html
- async function getHtml() {
- console.log("getHtml");
- let url = `https://cmm.ai:8083/get_html3?kw=${kwVal.value}®ion=${regionsVal.value}&language=${languageVal.value}&stage=${stageVal.value}`;
- try {
- let response = await axios.get(url);
- graphContent.value = response.data.data;
- // 生成 html 並另開分頁
- const newWindow = window.open();
- if (newWindow) {
- newWindow.document.open();
- newWindow.document.write(graphContent.value);
- newWindow.document.close();
- } else {
- alert("無法打開新頁面,請允許瀏覽器的彈出窗口。");
- }
- } catch (error) {
- console.error("操作失敗", error);
- alert("操作失敗,請重新操作。");
- }
- }
- // 地區
- 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" },
- ];
- let stateList = reactive([]);
- // 取得關鍵字狀態
- async function getKwStateList() {
- let email = localStorage.getItem("email");
- let url = `https://cmm.ai:8083/get_user_kw_state3?email=${email}`;
- try {
- let response = await axios.get(url);
- console.log("response", response.data.message);
- let list = response.data.message;
- if (list.length) {
- stateList.length = 0;
- list.map((item) => {
- stateList.push(item);
- });
- console.log("stateList", stateList);
- }
- } catch (error) {
- console.error("error", error);
- }
- }
- getKwStateList();
- const headers = [
- {
- title: "關鍵字",
- sortable: true,
- key: "kw",
- align: "left",
- },
- {
- title: "狀態",
- sortable: true,
- key: "state",
- align: "left",
- },
- ];
- // 計算下拉選單層級數
- const filteredStage = computed(() => {
- return Array.from({ length: maxStage.value }, (_, i) => (i + 1).toString());
- });
- // 插入資料
- // function insertData(kw) {
- // let url = `https://cmm.ai:8084/insert_data3?kw=${kwVal.value}`;
- // axios.put(url).then(function (response) {
- // const message = response.data.message; // 假設 API 返回一個帶有消息的 JSON
- // alert(message);
- // });
- // }
- // // 將所有流程包進來
- // async function processData() {
- // console.log("processData", kwVal.value, stageVal.value);
- // const url = `https://cmm.ai:8084/check_kw_in_data3?kw=${kwVal.value}&stage=${stageVal.value}`;
- // try {
- // let response = await axios.get(url);
- // const message = response.data.message;
- // console.log("response", response);
- // if (message === "已查詢到關鍵字, 立即為您產圖.") {
- // var confirmNextStep = confirm(
- // "已查詢到關鍵字,立即為您產圖。" +
- // "\n是否要執行下一步操作?(點確定後將另開分頁)"
- // );
- // if (confirmNextStep) {
- // getHtml();
- // } else {
- // alert("取消操作");
- // }
- // }
- // } catch (error) {
- // console.error("操作失敗", error);
- // alert("操作失敗,請重新操作。");
- // }
- // }
- </script>
- <template>
- <v-container fluid class="knowledge-graph">
- <v-card class="mt-10 ma-3 pa-sm-5">
- <v-card-title primary-title>
- <h3 class="card-title mb-3">GEN SEO</h3>
- </v-card-title>
- <v-card-text class="card-content">
- <div class="d-flex flex-column">
- <v-text-field
- v-model="kwVal"
- label="關鍵字"
- density="compact"
- prepend-inner-icon="search"
- variant="solo"
- hide-details
- class="mr-5 search-field"
- ></v-text-field>
- <div class="d-flex align-center 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>
- <!-- <v-select
- v-model="stageVal"
- label="層級"
- density="compact"
- :items="['1', '2', '3', '4', '5']"
- variant="solo"
- hide-details
- class="my-7 my-md-0 mx-md-5"
- ></v-select> -->
- <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>
- <p v-if="searchError" class="text-error mt-3 ml-3">
- 請選擇查詢地區及語言
- </p>
- </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="insertKw()"
- variant="outlined"
- color="primary"
- size="small"
- >
- 新增層級
- </v-btn>
- <!-- <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="insertRegionsVal"
- label="地區"
- density="compact"
- :items="regionsList"
- item-title="region"
- item-value="code"
- variant="solo"
- hide-details
- :rules="[(value) => !!value || '尚未選擇地區']"
- ></v-select>
- <v-select
- v-model="insertLanguageVal"
- 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="filteredStage"
- variant="solo"
- hide-details
- ></v-select>
- <button @click="getHtml()" class="search-btn ml-3">查看結果</button>
- </span>
- </div>
- <div v-else>
- <p>未查詢到符合的關鍵字</p>
- <v-btn
- @click="insertKw()"
- variant="outlined"
- color="primary"
- class="mt-3"
- >
- 新增關鍵字
- </v-btn>
- <!-- <p>未查詢到關鍵字,請選擇要搜尋的地區及語言:</p>
- <span class="d-flex mt-5">
- <v-select
- v-model="insertRegionsVal"
- label="地區"
- density="compact"
- :items="regionsList"
- item-title="region"
- item-value="code"
- variant="solo"
- hide-details
- :rules="[(value) => !!value || '尚未選擇地區']"
- ></v-select>
- <v-select
- v-model="insertLanguageVal"
- 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>
- <!-- 關鍵字狀態清單 -->
- <v-data-table
- v-if="stateList.length"
- class="pa-5"
- :headers="headers"
- :items="stateList"
- >
- <template v-slot:item.state="{ item }">
- <span v-if="item.raw.state === '已完成'">
- <v-icon icon="check_circle" color="success" />
- 已完成
- </span>
- <span v-else-if="item.raw.state === '等待中'">
- <v-icon icon="pending" color="warning" />
- 等待中
- </span>
- <span v-else-if="item.raw.state === '運行中'">
- <v-progress-circular
- indeterminate
- color="info"
- style="width: 20px"
- ></v-progress-circular>
- 運行中
- </span>
- <!-- <span v-else>
- <v-icon icon="warning" color="error" />
- 失敗
- </span> -->
- </template>
- </v-data-table>
- </v-container>
- </template>
- <style lang="scss">
- .knowledge-graph {
- .v-select {
- max-width: 10rem;
- }
- .v-data-table-footer {
- margin-top: 1rem;
- }
- .search-field {
- max-width: 21rem;
- }
- .search-btn {
- 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%,
- rgb(178, 69, 146) 100%
- );
- }
- .card-content {
- max-width: 800px;
- }
- .v-text-field .v-field {
- border-radius: 100px;
- }
- .v-input {
- @media (max-width: 960px) {
- width: 100%;
- }
- }
- }
- </style>
|