Browse Source

feat: 菜单搜索功能支持拼音搜索,比如搜图片裁剪,输入`tp`或`tupian`等对应拼音即可

xiaoxian521 1 year ago
parent
commit
5f71e0aad7

+ 17 - 7
src/layout/components/search/components/SearchModal.vue

@@ -1,11 +1,13 @@
 <script setup lang="ts">
+import { match } from "pinyin-pro";
+import { useI18n } from "vue-i18n";
 import { useRouter } from "vue-router";
-import { cloneDeep } from "@pureadmin/utils";
 import SearchResult from "./SearchResult.vue";
 import SearchFooter from "./SearchFooter.vue";
 import { useNav } from "@/layout/hooks/useNav";
 import { transformI18n } from "@/plugins/i18n";
 import { ref, computed, shallowRef } from "vue";
+import { cloneDeep, isAllEmpty } from "@pureadmin/utils";
 import { useDebounceFn, onKeyStroke } from "@vueuse/core";
 import { usePermissionStoreHook } from "@/store/modules/permission";
 import Search from "@iconify-icons/ri/search-line";
@@ -23,6 +25,7 @@ const { device } = useNav();
 const emit = defineEmits<Emits>();
 const props = withDefaults(defineProps<Props>(), {});
 const router = useRouter();
+const { locale } = useI18n();
 
 const keyword = ref("");
 const scrollbarRef = ref();
@@ -62,12 +65,19 @@ function flatTree(arr) {
 /** 查询 */
 function search() {
   const flatMenusData = flatTree(menusData.value);
-  resultOptions.value = flatMenusData.filter(
-    menu =>
-      keyword.value &&
-      transformI18n(menu.meta?.title)
-        .toLocaleLowerCase()
-        .includes(keyword.value.toLocaleLowerCase().trim())
+  resultOptions.value = flatMenusData.filter(menu =>
+    keyword.value
+      ? transformI18n(menu.meta?.title)
+          .toLocaleLowerCase()
+          .includes(keyword.value.toLocaleLowerCase().trim()) ||
+        (locale.value === "zh" &&
+          !isAllEmpty(
+            match(
+              transformI18n(menu.meta?.title).toLocaleLowerCase(),
+              keyword.value.toLocaleLowerCase().trim()
+            )
+          ))
+      : false
   );
   if (resultOptions.value?.length > 0) {
     activePath.value = resultOptions.value[0].path;

+ 4 - 4
src/layout/components/search/components/SearchResult.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { useI18n } from "vue-i18n";
+import { transformI18n } from "@/plugins/i18n";
 import { useResizeObserver } from "@vueuse/core";
 import { useEpThemeStoreHook } from "@/store/modules/epTheme";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
@@ -7,8 +7,6 @@ import { ref, computed, getCurrentInstance, onMounted } from "vue";
 import enterOutlined from "@/assets/svg/enter_outlined.svg?component";
 import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line";
 
-const { t } = useI18n();
-
 interface optionsItem {
   path: string;
   meta?: {
@@ -98,7 +96,9 @@ defineExpose({ handleScroll });
       @mouseenter="handleMouse(item)"
     >
       <component :is="useRenderIcon(item.meta?.icon ?? Bookmark2Line)" />
-      <span class="result-item-title">{{ t(item.meta?.title) }}</span>
+      <span class="result-item-title">
+        {{ transformI18n(item.meta?.title) }}
+      </span>
       <enterOutlined />
     </div>
   </div>