Skip to content

Commit 09a6e62

Browse files
committed
ui ok
1 parent cdd6c57 commit 09a6e62

File tree

3 files changed

+93
-121
lines changed

3 files changed

+93
-121
lines changed

packages/ui/components/Bases.vue

Lines changed: 45 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
11
<template>
2-
<div class="circular-selector">
3-
<div
4-
class="card-container"
5-
:style="{
6-
transform: `translateX(-50%) rotateY(${rotation.toString()}deg)`,
7-
}"
8-
>
9-
<div
10-
v-for="item in model.items"
11-
:key="item.id"
12-
class="card"
13-
:style="{
14-
transform: `rotateY(${getRotationAngle(
15-
item.id
16-
)}deg) translateZ(200px)`,
17-
}"
18-
@click="selectItem(item.id)"
19-
>
20-
<div class="name">{{ item.name }} 知识库</div>
21-
<div class="id">WebDAV地址 /dav/{{ item.id }}</div>
22-
<div class="delete-icon" @click.stop="deleteItem(item.id)">x</div>
2+
<div class="floating-cards">
3+
<div v-for="item in model.items" :key="item.id" class="floating-card">
4+
<div class="name">
5+
<span class="name-text">{{ item.name }}</span>
6+
<span class="name-suffix"> 知识库</span>
237
</div>
8+
<a
9+
class="id"
10+
:href="`/dav/${item.id}`"
11+
target="_blank"
12+
rel="noopener noreferrer"
13+
>
14+
<i class="fa fa-external-link"></i> WebDAV 管理
15+
</a>
16+
<div class="delete-icon" @click.stop="deleteItem(item.id)">x</div>
2417
</div>
2518
</div>
2619
</template>
@@ -29,110 +22,75 @@
2922
import { deleteV0Base } from "app/client";
3023
const model = defineModel<{
3124
items: Array<{ id: string; name: string }>;
32-
target: string;
3325
}>({
3426
default: () => ({
3527
items: [
3628
{ id: "1", name: "知识库 1" },
3729
{ id: "2", name: "知识库 2" },
3830
{ id: "3", name: "知识库 3" },
3931
],
40-
target: "1",
4132
}),
4233
});
4334
44-
const rotation = ref(0);
45-
46-
const updateRotation = () => {
47-
const index = model.value.items.findIndex(
48-
(item) => item.id === model.value.target
49-
);
50-
if (index !== -1) {
51-
const angle = (360 / model.value.items.length) * index;
52-
rotation.value = -angle;
53-
}
54-
};
55-
56-
const getRotationAngle = (id: string) => {
57-
const index = model.value.items.findIndex((item) => item.id === id);
58-
return (360 / model.value.items.length) * index;
59-
};
60-
61-
const selectItem = (id: string) => {
62-
model.value = {
63-
...model.value,
64-
target: id,
65-
};
66-
};
67-
6835
const deleteItem = async (id: string) => {
6936
model.value.items = model.value.items.filter((item) => item.id !== id);
70-
if (model.value.target === id) {
71-
if (model.value.items.length > 0) {
72-
model.value.target = model.value.items[0].id;
73-
} else {
74-
model.value.target = "";
75-
}
76-
}
7737
await deleteV0Base({ body: { id } });
78-
updateRotation();
7938
};
80-
81-
onMounted(() => {
82-
updateRotation();
83-
});
84-
85-
watch(
86-
() => model.value.target,
87-
() => {
88-
updateRotation();
89-
},
90-
{ immediate: true }
91-
);
9239
</script>
9340

9441
<style scoped>
95-
.circular-selector {
96-
position: relative;
97-
width: 400px;
98-
height: 250px;
99-
margin: 0 auto;
100-
perspective: 1000px;
101-
}
102-
103-
.card-container {
104-
position: absolute;
105-
left: 50%;
106-
width: 200px;
107-
height: 200px;
108-
transform-style: preserve-3d;
109-
transition: transform 0.5s ease;
42+
.floating-cards {
43+
display: flex;
44+
flex-wrap: wrap;
45+
justify-content: center;
46+
gap: 20px;
47+
padding: 20px;
11048
}
11149
112-
.card {
113-
position: absolute;
50+
.floating-card {
11451
width: 200px;
11552
height: 200px;
116-
/* 美化背景 */
11753
background: linear-gradient(135deg, #6e8efb, #a777e3);
11854
border-radius: 10px;
11955
display: flex;
12056
flex-direction: column;
12157
justify-content: center;
12258
align-items: center;
12359
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
124-
color: white; /* 文字颜色 */
60+
color: white;
61+
position: relative;
62+
transition: transform 0.3s ease;
63+
}
64+
65+
.floating-card:hover {
66+
transform: translateY(-10px);
12567
}
12668
12769
.name {
128-
font-size: 20px;
70+
font-size: 24px;
12971
text-align: center;
72+
margin-bottom: 10px;
73+
}
74+
75+
.name-text {
76+
font-weight: bold;
77+
}
78+
79+
.name-suffix {
80+
font-size: 20px;
81+
color: rgba(255, 255, 255, 0.8);
13082
}
13183
13284
.id {
13385
font-size: 14px;
13486
position: absolute;
13587
bottom: 10px;
88+
text-decoration: underline;
89+
cursor: pointer;
90+
}
91+
92+
.id i {
93+
margin-right: 5px;
13694
}
13795
13896
.delete-icon {

packages/ui/components/SearchMain.vue

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,37 @@
11
<template>
22
<div class="w-full max-w-3xl pa-6">
3-
<!-- 设置 -->
4-
<Transition
5-
enter-active-class="animate-fade-in-up animate-duration-500 animate-ease-out"
6-
leave-active-class="animate-fade-out-down animate-duration-500 animate-ease-in"
7-
mode="out-in"
8-
>
9-
<Settings v-if="settings" />
10-
</Transition>
11-
12-
<Transition
13-
enter-active-class="animate-fade-in-down animate-duration-500 animate-ease-out"
14-
leave-active-class="animate-fade-out-up animate-duration-500 animate-ease-in"
15-
mode="out-in"
16-
>
17-
<div v-if="!settings">
18-
<!-- 搜索框容器 -->
19-
<Searcher v-model="searchVal" />
20-
21-
<!-- 搜索结果展示区 -->
22-
<MDCards v-model="searchVal.searchResults" />
23-
</div>
24-
</Transition>
3+
<!-- 知识库选择器 -->
4+
<select v-model="selectedId">
5+
<!-- 循环遍历 model.items 生成选项 -->
6+
<option v-for="item in model.items" :key="item.id" :value="item.id">
7+
{{ item.name }}
8+
</option>
9+
</select>
10+
<!-- 搜索框容器 -->
11+
<Searcher v-model="searchVal" />
12+
<!-- 搜索结果展示区 -->
13+
<MDCards v-model="searchVal.searchResults" />
2514
</div>
2615
</template>
2716

2817
<script setup lang="ts">
2918
import { type SearchResult } from "app/client";
19+
import { ref, reactive, watch } from "vue";
3020
31-
const id = defineModel("id", {
32-
type: String,
33-
default: () => "",
34-
});
21+
const model = defineProps<{
22+
items: { id: string; name: string }[];
23+
}>();
3524
36-
const tokenStore = useTokenStore();
25+
const selectedId = ref<string>("");
3726
38-
const settings = ref(tokenStore.token ? false : true);
3927
const searchVal = reactive({
40-
id: id.value,
28+
id: selectedId.value,
4129
q: "",
4230
searchResults: [] as SearchResult[],
4331
});
32+
33+
watch(selectedId, (newId) => {
34+
searchVal.id = newId;
35+
// 可以在这里添加重新搜索的逻辑
36+
});
4437
</script>

packages/ui/pages/index.vue

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,46 @@
11
<template>
2+
<!-- 新增导航栏 -->
3+
<div
4+
class="fixed top-0 left-0 right-0 flex justify-center backdrop-blur-md p-2"
5+
>
6+
<button
7+
:class="{ 'font-bold': !search }"
8+
@click="search = false"
9+
class="px-4 py-2 mx-2 rounded-md hover:bg-gray-200"
10+
>
11+
知识库管理
12+
</button>
13+
<button
14+
:class="{ 'font-bold': search }"
15+
@click="search = true"
16+
class="px-4 py-2 mx-2 rounded-md hover:bg-gray-200"
17+
>
18+
搜索预览
19+
</button>
20+
</div>
21+
222
<Settings />
3-
<AddBase />
423
<Checker v-model:loading="loading" />
524

6-
<Bases v-model:model-value="v" />
25+
<AddBase v-if="!search" />
726
<Transition
827
enter-active-class="animate-fade-in-up animate-duration-500 animate-ease-out"
928
leave-active-class="animate-fade-out-down animate-duration-500 animate-ease-in"
1029
mode="out-in"
30+
v-if="!loading"
1131
>
12-
<SearchMain v-if="!loading" v-model:id="v.target" />
32+
<SearchMain v-if="search" v-bind:items="v.items" />
33+
<Bases v-else v-model:model-value="v" />
1334
</Transition>
1435
</template>
1536

1637
<script setup lang="ts">
1738
import { getV0Base } from "app/client";
1839
40+
const search = ref(true);
1941
const loading = ref(true);
20-
const v = ref<{ items: { id: string; name: string }[]; target: string }>({
42+
const v = ref<{ items: { id: string; name: string }[] }>({
2143
items: [],
22-
target: "",
2344
});
2445
2546
onMounted(async () => {

0 commit comments

Comments
 (0)