|
|
@@ -1,108 +1,285 @@
|
|
|
-<script setup lang="ts">
|
|
|
-import { onUnmounted, ref, type Ref, onMounted } from "vue";
|
|
|
-import { useRoute, useRouter } from "vue-router";
|
|
|
-import { useSideBarStore } from "@/stores/side-bar";
|
|
|
-import searchService from "@/services/search.service";
|
|
|
-import type { SearchResult } from "@/types/search.types";
|
|
|
-import SearchBox from "./components/SearchBox.vue";
|
|
|
-import SearchResultToolbar from "./components/SearchResultToolbar.vue";
|
|
|
-import SearchResultList from "./components/SearchResultList.vue";
|
|
|
-
|
|
|
-const sideBarStore = useSideBarStore();
|
|
|
-// 路由管理器
|
|
|
-const router = useRouter();
|
|
|
-// 当前路由对象
|
|
|
-const route = useRoute();
|
|
|
-
|
|
|
-// 关键词
|
|
|
-const keyword = ref("");
|
|
|
-// 字段
|
|
|
-const field = ref("TP");
|
|
|
-// 排序
|
|
|
-const sort = ref("Relevance");
|
|
|
-
|
|
|
-// 搜索结果
|
|
|
-const searchResult: Ref<SearchResult | null> = ref(null);
|
|
|
-
|
|
|
-function doSearch(field: string, keyword: string) {
|
|
|
- if (keyword && keyword.length == 0) {
|
|
|
- router.push({name: "SearchIndex"});
|
|
|
- return;
|
|
|
- }
|
|
|
- router.push({name: "SearchResult", query: { kw: keyword }});
|
|
|
- const query = `${field}=(${keyword})`;
|
|
|
- searchService.search(query).then((resp) => {
|
|
|
- searchResult.value = resp.data.data;
|
|
|
- }).catch((err) => {
|
|
|
- console.log(err);
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- // 收起左侧边栏
|
|
|
- sideBarStore.setCollapse(true);
|
|
|
- // 初始化关键词
|
|
|
- if (route.query.kw) {
|
|
|
- keyword.value = (route.query.kw as string).trim();
|
|
|
- }
|
|
|
- // 搜索
|
|
|
- doSearch(field.value, keyword.value);
|
|
|
-});
|
|
|
-
|
|
|
-onUnmounted(() => {
|
|
|
- sideBarStore.setCollapse(false);
|
|
|
-});
|
|
|
-
|
|
|
-</script>
|
|
|
-
|
|
|
-<template>
|
|
|
- <div class="search-result-wrap">
|
|
|
- <div class="search-box-wrap">
|
|
|
- <SearchBox v-model:keyword="keyword" v-model:field="field" @search="doSearch" />
|
|
|
- </div>
|
|
|
- <a-row type="flex" class="search-result-main" :gutter="10">
|
|
|
- <a-col :span="5">
|
|
|
- <div class="left-filter-header">
|
|
|
- 筛选
|
|
|
- </div>
|
|
|
- <a-space direction="vertical" style="width: 100%">
|
|
|
- <a-card title="Default size card">
|
|
|
- <p>card content</p>
|
|
|
- <p>card content</p>
|
|
|
- <p>card content</p>
|
|
|
- </a-card>
|
|
|
- <a-card title="Small size card">
|
|
|
- <p>card content</p>
|
|
|
- <p>card content</p>
|
|
|
- <p>card content</p>
|
|
|
- </a-card>
|
|
|
- </a-space>
|
|
|
- </a-col>
|
|
|
- <a-col :span="19">
|
|
|
- <SearchResultToolbar :data="searchResult" v-model:sort="sort" v-if="searchResult" />
|
|
|
- <SearchResultList :data="searchResult" v-if="searchResult" />
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
-.search-result-wrap {
|
|
|
- margin-top: 20px;
|
|
|
-
|
|
|
- .search-box-wrap {
|
|
|
- padding: 0 120px;
|
|
|
- }
|
|
|
-
|
|
|
- .search-result-main {
|
|
|
- margin-top: 20px;
|
|
|
- }
|
|
|
-
|
|
|
- @media (max-width: 1024px) {
|
|
|
- .search-box-wrap {
|
|
|
- padding: 0 20px;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-</style>
|
|
|
+<script setup lang="ts">
|
|
|
+ import {onUnmounted, ref, type Ref, onMounted} from "vue";
|
|
|
+ import {useRoute, useRouter} from "vue-router";
|
|
|
+ import {useSideBarStore} from "@/stores/side-bar";
|
|
|
+ import searchService from "@/services/search.service";
|
|
|
+ import type {SearchResult} from "@/types/search.types";
|
|
|
+ import SearchBox from "./components/SearchBox.vue";
|
|
|
+ import SearchResultToolbar from "./components/SearchResultToolbar.vue";
|
|
|
+ import SearchResultList from "./components/SearchResultList.vue";
|
|
|
+
|
|
|
+ const sideBarStore = useSideBarStore();
|
|
|
+ // 路由管理器
|
|
|
+ const router = useRouter();
|
|
|
+ // 当前路由对象
|
|
|
+ const route = useRoute();
|
|
|
+
|
|
|
+ // 关键词
|
|
|
+ const keyword = ref("");
|
|
|
+ // 字段
|
|
|
+ const field = ref("TP");
|
|
|
+ // 排序
|
|
|
+ const sort = ref("Relevance");
|
|
|
+
|
|
|
+ const page = ref(1);
|
|
|
+
|
|
|
+ const size = ref(10);
|
|
|
+
|
|
|
+ const authorChecked = ref(false);
|
|
|
+ const yearChecked = ref(false);
|
|
|
+
|
|
|
+ let yearValueArr: string[] = []
|
|
|
+ const authorValueArr: string[] = []
|
|
|
+
|
|
|
+ // 搜索结果
|
|
|
+ const searchResult: Ref<SearchResult | null> = ref(null);
|
|
|
+
|
|
|
+ // 搜索结果
|
|
|
+ const aggYearResult = ref(null);
|
|
|
+ // 搜索结果
|
|
|
+ const aggAuthorResult = ref(null);
|
|
|
+
|
|
|
+ function aggsYearSearch(field: string, keyword: string) {
|
|
|
+ if (keyword && keyword.length == 0) {
|
|
|
+ router.push({name: "SearchIndex"});
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const query = `${field}=(${keyword})`;
|
|
|
+ const aggYear = {
|
|
|
+ name: 'year',
|
|
|
+ field: 'year'
|
|
|
+ }
|
|
|
+ const aggs: { [key: string]: any } = {}
|
|
|
+ aggs.year = aggYear;
|
|
|
+ const param = {
|
|
|
+ query: query,
|
|
|
+ aggs: aggs
|
|
|
+ };
|
|
|
+ searchService.search(param).then((resp) => {
|
|
|
+ aggYearResult.value = resp.data.data.aggs.year ? resp.data.data.aggs.year : []
|
|
|
+ }).catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function aggsAuthorsSearch(field: string, keyword: string) {
|
|
|
+ if (keyword && keyword.length == 0) {
|
|
|
+ router.push({name: "SearchIndex"});
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const query = `${field}=(${keyword})`;
|
|
|
+ const aggAuthors = {
|
|
|
+ name: 'authors',
|
|
|
+ field: 'authors.keyword'
|
|
|
+ }
|
|
|
+ const aggs: { [key: string]: any } = {}
|
|
|
+ aggs.authors = aggAuthors;
|
|
|
+ const param = {
|
|
|
+ query: query,
|
|
|
+ aggs: aggs
|
|
|
+ };
|
|
|
+ searchService.search(param).then((resp) => {
|
|
|
+ aggAuthorResult.value = resp.data.data.aggs.authors ? resp.data.data.aggs.authors : []
|
|
|
+ }).catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function doSearch(field: string, keyword: string) {
|
|
|
+ if (keyword && keyword.length == 0) {
|
|
|
+ router.push({name: "SearchIndex"});
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ router.push({name: "SearchResult", query: {kw: keyword}});
|
|
|
+ const query = `${field}=(${keyword})`;
|
|
|
+ let sortParam = null;
|
|
|
+ if (sort.value === 'Relevance') {
|
|
|
+ sortParam = {"Relevance": "Relevance"}
|
|
|
+ } else if (sort.value === 'DateDesc') {
|
|
|
+ sortParam = {"year": "DESC"}
|
|
|
+ } else if (sort.value === 'DateAsc') {
|
|
|
+ sortParam = {"year": "ASC"}
|
|
|
+ } else if (sort.value === 'CitedDesc') {
|
|
|
+ sortParam = {"cited": "ASC"}
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ const param: { [key: string]: any } = {
|
|
|
+ query: query,
|
|
|
+ from: page.value,
|
|
|
+ size: size.value,
|
|
|
+ sort: sortParam
|
|
|
+ };
|
|
|
+ const aggs: { [key: string]: any } = {}
|
|
|
+ if (yearValueArr && yearValueArr.length > 0) {
|
|
|
+ var yearQuery: string = "PY=";
|
|
|
+ var pyKw = '('
|
|
|
+ for (let i = 0; i < yearValueArr.length; i++) {
|
|
|
+ if (i == 0) {
|
|
|
+ pyKw += yearValueArr[i]
|
|
|
+ } else {
|
|
|
+ pyKw += " " + yearValueArr[i]
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(pyKw);
|
|
|
+ if (i == yearValueArr.length - 1) {
|
|
|
+ pyKw += ')'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ param.query += ' AND ' + yearQuery + pyKw
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!authorValueArr || authorValueArr.length <= 0) {
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // var yearQuery: string = "PY=";
|
|
|
+ // console.log(yearValueArr);
|
|
|
+ // var pyKw = '('
|
|
|
+ // for (let i = 0; i < yearValueArr.length; i++) {
|
|
|
+ // if (i == 0) {
|
|
|
+ // pyKw += yearValueArr[i]
|
|
|
+ // } else {
|
|
|
+ // pyKw += " " + yearValueArr[i]
|
|
|
+ // }
|
|
|
+ //
|
|
|
+ // console.log(pyKw);
|
|
|
+ // if (i == yearValueArr.length - 1) {
|
|
|
+ // pyKw += ')'
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // param.query += ' AND ' + yearQuery + pyKw
|
|
|
+ }
|
|
|
+ searchResult.value = null
|
|
|
+ searchService.search(param).then((resp) => {
|
|
|
+ searchResult.value = resp.data.data;
|
|
|
+ if (!yearValueArr || yearValueArr.length <= 0) {
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ }).catch((err) => {
|
|
|
+ console.log(err);
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ // 收起左侧边栏
|
|
|
+ sideBarStore.setCollapse(true);
|
|
|
+ // 初始化关键词
|
|
|
+ if (route.query.kw) {
|
|
|
+ keyword.value = (route.query.kw as string).trim();
|
|
|
+ }
|
|
|
+ if (route.query.field) {
|
|
|
+ field.value = (route.query.field as string).trim();
|
|
|
+ }
|
|
|
+ // 搜索
|
|
|
+ doSearch(field.value, keyword.value);
|
|
|
+ aggsYearSearch(field.value, keyword.value);
|
|
|
+ aggsAuthorsSearch(field.value, keyword.value);
|
|
|
+ });
|
|
|
+
|
|
|
+ function changeFile(val) {
|
|
|
+ // 搜索
|
|
|
+ field.value = val
|
|
|
+ doSearch(field.value, keyword.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function changKeyword(val) {
|
|
|
+ keyword.value = val
|
|
|
+ doSearch(field.value, keyword.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function changeSort(val) {
|
|
|
+ sort.value = val
|
|
|
+ doSearch(field.value, keyword.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function changePagination(p, s) {
|
|
|
+ page.value = p
|
|
|
+ size.value = s
|
|
|
+ doSearch(field.value, keyword.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function changeYearChecked() {
|
|
|
+ yearValueArr = []
|
|
|
+ for (let valueKey in yearChecked.value) {
|
|
|
+ yearValueArr.push(yearChecked.value[valueKey])
|
|
|
+ }
|
|
|
+ doSearch(field.value, keyword.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function changeAuthorChecked() {
|
|
|
+ console.log(authorChecked.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ sideBarStore.setCollapse(false);
|
|
|
+ });
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="search-result-wrap">
|
|
|
+ <div class="search-box-wrap">
|
|
|
+ <SearchBox v-model:keyword="keyword" v-model:field="field" @search="doSearch" @update:field="changeFile"
|
|
|
+ @update:keyword="changKeyword"/>
|
|
|
+ </div>
|
|
|
+ <a-row type="flex" class="search-result-main" :gutter="10">
|
|
|
+ <a-col :span="5">
|
|
|
+ <div class="left-filter-header">
|
|
|
+ 筛选
|
|
|
+ </div>
|
|
|
+ <a-space direction="vertical" style="width: 100%" v-if="searchResult">
|
|
|
+ <a-card title="年份">
|
|
|
+ <a-checkbox-group v-model:value="yearChecked" style="width: 100%" @change="changeYearChecked"
|
|
|
+ v-if="aggYearResult && aggYearResult.length > 0">
|
|
|
+ <a-row v-for="(item, index) in aggYearResult" :key="index">
|
|
|
+ <a-col :span="20">
|
|
|
+ <a-checkbox :value="item.key">{{item.key}}</a-checkbox>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="4"> {{item.count}}</a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-checkbox-group>
|
|
|
+ </a-card>
|
|
|
+ <a-card title="作者">
|
|
|
+ <a-checkbox-group v-model:value="authorChecked" style="width: 100%"
|
|
|
+ @change="changeAuthorChecked">
|
|
|
+ <a-row v-for="(item, index) in aggAuthorResult" :key="index">
|
|
|
+ <a-col :span="20">
|
|
|
+ <a-checkbox :value="item.key">{{item.key}}</a-checkbox>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="4"> {{item.count}}</a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-checkbox-group>
|
|
|
+ </a-card>
|
|
|
+ </a-space>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="19">
|
|
|
+ <SearchResultToolbar :data="searchResult" v-model:sort="sort" v-if="searchResult"
|
|
|
+ @update:sort="changeSort" @update:pagination="changePagination"/>
|
|
|
+ <SearchResultList :data="searchResult" v-if="searchResult"/>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+ .search-result-wrap {
|
|
|
+ margin-top: 20px;
|
|
|
+
|
|
|
+ .search-box-wrap {
|
|
|
+ padding: 0 120px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-result-main {
|
|
|
+ margin-top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ @media (max-width: 1024px) {
|
|
|
+ .search-box-wrap {
|
|
|
+ padding: 0 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+</style>
|