SearchView.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <script setup lang="ts">
  2. import { message, type SelectProps } from "ant-design-vue";
  3. import { ref, watch, onMounted, h } from "vue";
  4. import { routeToSearch } from "@/router";
  5. import * as searchHistoryService from "@/services/searchHistory.service"
  6. import * as searchService from "@/services/search.service"
  7. import { LoadingOutlined } from '@ant-design/icons-vue';
  8. import SearchResultItem from "./components/SearchResultItem.vue";
  9. const keyword = ref("");
  10. const field = ref("TP");
  11. const placeholder = ref("请输入文献主题")
  12. const hotWords = ref(['建筑工程','工程设计','BIM',])
  13. const recommendWords = ref(['建筑工程', '施工技术', 'BIM', '工程造价', '质量控制'])
  14. const spinning = ref(true);
  15. const searchResult: any = ref([])
  16. const onSearch = () => {
  17. const kwd = keyword.value.trim();
  18. if (kwd.length == 0) {
  19. message.warning("请输入查询关键词");
  20. return;
  21. }
  22. routeToSearch({ type: 'simple', kw: kwd, field: field.value });
  23. }
  24. const fieldOptions = ref<SelectProps['options']>([
  25. { value: 'TP', label: '主题' },
  26. { value: 'TI', label: '标题' },
  27. { value: 'AU', label: '作者' },
  28. { value: 'KW', label: '关键词' },
  29. { value: 'AB', label: '摘要' },
  30. { value: 'UN', label: '机构' },
  31. ]);
  32. watch(field, (newValue) => {
  33. if (newValue == 'TI') {
  34. placeholder.value = "请输入文献标题"
  35. } else if (newValue == 'AU') {
  36. placeholder.value = "请输入文献作者"
  37. } else if (newValue == 'KW') {
  38. placeholder.value = "请输入文献关键词"
  39. } else if (newValue == 'AB') {
  40. placeholder.value = "请输入文献摘要"
  41. } else if (newValue == 'UN') {
  42. placeholder.value = "请输入文献机构"
  43. } else {
  44. placeholder.value = "请输入文献主题"
  45. }
  46. });
  47. onMounted(() => {
  48. getHoyKeyword(10);
  49. recommendsearch();
  50. })
  51. function getHoyKeyword(size: number){
  52. searchHistoryService.getHoyKeyword(size).then((resp) => {
  53. const words: any = resp;
  54. for (let item of words) {
  55. var expression = item.expression;
  56. var _expression = expression.match(/\((.+)\)/g);
  57. var $1 = RegExp.$1
  58. var index = hotWords.value.indexOf($1);
  59. if (hotWords.value.length == 5) {
  60. break;
  61. }
  62. if (index == -1) {
  63. if ($1.length > 1) {
  64. hotWords.value.push($1)
  65. }
  66. }
  67. }
  68. })
  69. }
  70. function recommendsearch() {
  71. spinning.value = true;
  72. let request = {
  73. from: 0,
  74. size: 2,
  75. sort: {PY: "desc"},
  76. query: ''
  77. }
  78. for (let item of recommendWords.value) {
  79. request.query = 'TP=('+item+')' ;
  80. searchService.search(request).then((resp) => {
  81. for (let doc of resp.docs) {
  82. searchResult.value.push(doc)
  83. }
  84. })
  85. }
  86. spinning.value = false;
  87. }
  88. function search(kwd: string){
  89. routeToSearch({ type: 'simple', kw: kwd, field: 'TP' });
  90. }
  91. </script>
  92. <template>
  93. <div class="search-wrap">
  94. <h1>智能搜索</h1>
  95. <!-- <a-divider></a-divider> -->
  96. <a-row type="flex">
  97. <a-col>
  98. <a-select
  99. ref="select"
  100. v-model:value="field"
  101. style="width: 120px"
  102. :options="fieldOptions"
  103. size="large"
  104. ></a-select>
  105. </a-col>
  106. <a-col flex="1">
  107. <a-input-search
  108. v-model:value="keyword"
  109. :placeholder="placeholder"
  110. enter-button
  111. size="large"
  112. @search="onSearch"
  113. />
  114. </a-col>
  115. </a-row>
  116. <a-row class="search-hotword">
  117. 热门关键词:
  118. <span v-for="(item, index) in hotWords" @click="search(item)" :key="index">
  119. {{item}}
  120. </span>
  121. </a-row>
  122. <a-row type="flex" class="search-result">
  123. <a-spin :spinning="spinning" :indicator="h(LoadingOutlined, { style: { fontSize: '24px', }, spin: true, })">
  124. <div>最新文献推荐</div>
  125. <div v-if="searchResult">
  126. <div v-for="(doc, index) in searchResult" :key="index" class="search-result-content">
  127. <SearchResultItem :data="doc"/>
  128. </div>
  129. </div>
  130. </a-spin>
  131. </a-row>
  132. </div>
  133. </template>
  134. <style scoped lang="scss">
  135. .search-wrap {
  136. width: 80%;
  137. margin: 0 auto;
  138. margin-top: 20px;
  139. h1 {
  140. font-size: 2rem;
  141. text-align: center;
  142. }
  143. .search-hotword {
  144. margin-top: 30px;
  145. span {
  146. cursor: pointer;
  147. margin-left: 20px;
  148. &:hover {
  149. text-decoration: underline;
  150. }
  151. }
  152. }
  153. .search-result{
  154. margin-top: 30px;
  155. }
  156. .search-result-content {
  157. > div {
  158. border: 1px gray solid;
  159. margin-bottom: 8px;
  160. }
  161. }
  162. }
  163. </style>