Merge pull request #64 from Learnware-LAMDA/feat(frontend)/heter_search

feat(frontend): add heterogeneous search support
This commit is contained in:
AnnyTerfect 2023-10-30 22:37:58 +08:00 committed by GitHub
commit d342c4a7cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 5 deletions

View File

@ -6,4 +6,6 @@ export default {
UploadStatisticalRequirement: "Upload statistical requirement",
SpecificationScore: "Specification score",
Updated: "Updated",
HeterogeneousSearch: "Heterogeneous Search",
TurnOffHeterogeneousSearch: "Turn off heterogeneous search",
};

View File

@ -6,4 +6,6 @@ export default {
UploadStatisticalRequirement: "上传统计需求",
SpecificationScore: "规约匹配分数",
Updated: "更新于",
HeterogeneousSearch: "异构查搜",
TurnOffHeterogeneousSearch: "关闭异构查搜",
};

View File

@ -41,6 +41,7 @@ function searchLearnware({
libraryType,
scenarioList,
files,
heterogeneousMode,
page,
limit,
}: {
@ -50,6 +51,7 @@ function searchLearnware({
libraryType: LibraryType | "";
scenarioList: ScenarioList;
files: Files;
heterogeneousMode: boolean;
page: number;
limit: number;
}): Promise<{
@ -75,6 +77,7 @@ function searchLearnware({
const fd = new FormData();
fd.append("semantic_specification", JSON.stringify(semanticSpec));
fd.append("statistical_specification", (files.length > 0 && files[0]) || "");
fd.append("heterogeneous_mode", String(heterogeneousMode));
fd.append("limit", String(limit));
fd.append("page", String(page));
return fd;

View File

@ -1,14 +1,18 @@
<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick, onActivated } from "vue";
import { useDisplay } from "vuetify";
import { useI18n } from "vue-i18n";
import { searchLearnware } from "../request/engine";
import UserRequirement from "../components/Search/UserRequirement.vue";
import PageLearnwareList from "../components/Learnware/PageLearnwareList.vue";
import MultiRecommendedLearnwareList from "../components/Learnware/MultiRecommendedLearnwareList.vue";
import type { Filter, LearnwareCardInfo } from "@beiming-system/types/learnware";
import { promiseReadFile } from "../utils";
const display = useDisplay();
const { t } = useI18n();
const filters = ref<Filter>({
name: "",
dataType: "",
@ -24,6 +28,8 @@ const singleRecommendedLearnwarePage = ref(1);
const singleRecommendedLearnwarePageNum = ref(1);
const singleRecommendedLearnwarePageSize = ref(Math.ceil(display.height.value / 900) * 10);
const singleRecommendedLearnwareItems = ref<LearnwareCardInfo[]>([]);
const heterogeneousMode = ref<boolean>(false);
const rkmeTypeTable = ref<boolean>(false);
const loading = ref(false);
const contentRef = ref<HTMLDivElement | null>(null);
@ -44,11 +50,22 @@ const showMultiRecommended = computed(
const multiRecommendedTips = ref(true);
const singleRecommendedTips = ref(true);
const showHeterogeneousSearchSwitch = computed(
() =>
singleRecommendedLearnwareItems.value?.length === 0 &&
multiRecommendedLearnwareItems.value?.length === 0 &&
rkmeTypeTable.value,
);
function pageChange(newPage: number): void {
singleRecommendedLearnwarePage.value = newPage;
}
function fetchByFilterAndPage(filters: Filter, page: number): void {
function fetchByFilterAndPage(
filters: Filter,
page: number,
heterogeneousMode: boolean = false,
): void {
showError.value = false;
loading.value = true;
@ -59,6 +76,7 @@ function fetchByFilterAndPage(filters: Filter, page: number): void {
libraryType: filters.libraryType,
scenarioList: filters.scenarioList,
files: filters.files,
heterogeneousMode,
page,
limit: singleRecommendedLearnwarePageSize.value,
})
@ -134,11 +152,11 @@ watch(
);
watch(
() => [filters.value, singleRecommendedLearnwarePage.value],
() => [filters.value, singleRecommendedLearnwarePage.value, heterogeneousMode.value],
(newVal) => {
const [newFilters, newPage] = newVal as [Filter, number];
const [newFilters, newPage, newHeterogeneousMode] = newVal as [Filter, number, boolean];
fetchByFilterAndPage(newFilters, newPage - 1);
fetchByFilterAndPage(newFilters, newPage - 1, newHeterogeneousMode);
if (contentRef.value) {
if (display.name.value !== "xs") {
@ -149,6 +167,27 @@ watch(
{ deep: true },
);
watch(
() => filters.value.files,
(newVal) => {
rkmeTypeTable.value = false;
if (newVal.length > 0) {
promiseReadFile(newVal[0])
.then((res: ArrayBuffer) => new TextDecoder("ascii").decode(res))
.then((res) => JSON.parse(res))
.then((res) => {
if (res.type === "table") {
rkmeTypeTable.value = true;
}
})
.catch((err) => {
console.error(err);
});
}
},
{ deep: true },
);
onActivated(() => {
if (contentRef.value) {
contentRef.value.scrollTop = scrollTop.value;
@ -183,7 +222,13 @@ onMounted(() => {
</v-card-actions>
</v-scroll-y-transition>
<user-requirement v-model:value="filters" />
<user-requirement v-model:value="filters">
<template v-if="heterogeneousMode" #prepend>
<v-btn block variant="outlined" color="red" @click="() => (heterogeneousMode = false)">
{{ t("Search.TurnOffHeterogeneousSearch") }}
</v-btn>
</template>
</user-requirement>
<div ref="contentRef" class="content">
<v-card v-if="showMultiRecommended" flat class="sm:m-2 mt-4 bg-transparent">
@ -237,6 +282,17 @@ onMounted(() => {
@page-change="pageChange"
/>
</v-card>
<div v-if="showHeterogeneousSearchSwitch && !heterogeneousMode" class="text-center">
<v-btn
class="px-8"
variant="outlined"
color="red"
@click="() => (heterogeneousMode = true)"
>
{{ t("Search.HeterogeneousSearch") }}
</v-btn>
</div>
</div>
</div>
</template>