forked from Leaf/amber-ui
改进 将 lae 动画复制到 amber
This commit is contained in:
parent
0f97ab5bfa
commit
04051f674b
BIN
src/assets/audios/Popcorn.ogg
Normal file
BIN
src/assets/audios/Popcorn.ogg
Normal file
Binary file not shown.
BIN
src/assets/audios/alert.mp3
Normal file
BIN
src/assets/audios/alert.mp3
Normal file
Binary file not shown.
BIN
src/assets/audios/empty.mp3
Normal file
BIN
src/assets/audios/empty.mp3
Normal file
Binary file not shown.
BIN
src/assets/audios/error_1.wav
Normal file
BIN
src/assets/audios/error_1.wav
Normal file
Binary file not shown.
BIN
src/assets/audios/lock.mp3
Normal file
BIN
src/assets/audios/lock.mp3
Normal file
Binary file not shown.
BIN
src/assets/audios/success_1.wav
Normal file
BIN
src/assets/audios/success_1.wav
Normal file
Binary file not shown.
BIN
src/assets/audios/unlock.mp3
Normal file
BIN
src/assets/audios/unlock.mp3
Normal file
Binary file not shown.
1
src/assets/lottie/Balloon.json
Normal file
1
src/assets/lottie/Balloon.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Birthday-cake.json
Normal file
1
src/assets/lottie/Birthday-cake.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Cluster-Ready.json
Normal file
1
src/assets/lottie/Cluster-Ready.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Confetti-ball.json
Normal file
1
src/assets/lottie/Confetti-ball.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Dizzy-face.json
Normal file
1
src/assets/lottie/Dizzy-face.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Eyes.json
Normal file
1
src/assets/lottie/Eyes.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Flushed.json
Normal file
1
src/assets/lottie/Flushed.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Ghost.json
Normal file
1
src/assets/lottie/Ghost.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Glowing-star.json
Normal file
1
src/assets/lottie/Glowing-star.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Logo-dark.json
Normal file
1
src/assets/lottie/Logo-dark.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Logo-white.json
Normal file
1
src/assets/lottie/Logo-white.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Party-popper.json
Normal file
1
src/assets/lottie/Party-popper.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Partying-face.json
Normal file
1
src/assets/lottie/Partying-face.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Scrunched-mouth.json
Normal file
1
src/assets/lottie/Scrunched-mouth.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Thinking-face.json
Normal file
1
src/assets/lottie/Thinking-face.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/Wave.json
Normal file
1
src/assets/lottie/Wave.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/lae-jump-black.json
Normal file
1
src/assets/lottie/lae-jump-black.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/lae-jump.json
Normal file
1
src/assets/lottie/lae-jump.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/lae-mouse-leave-2.json
Normal file
1
src/assets/lottie/lae-mouse-leave-2.json
Normal file
File diff suppressed because one or more lines are too long
1
src/assets/lottie/lae-mouse-leave.json
Normal file
1
src/assets/lottie/lae-mouse-leave.json
Normal file
File diff suppressed because one or more lines are too long
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@ -15,6 +15,7 @@ declare module 'vue' {
|
||||
ChatSettings: typeof import('./components/settings/ChatSettings.vue')['default']
|
||||
LeftSettings: typeof import('./components/settings/LeftSettings.vue')['default']
|
||||
LibrarySettings: typeof import('./components/settings/LibrarySettings.vue')['default']
|
||||
Lottie: typeof import('./components/Lottie.vue')['default']
|
||||
MemorySettings: typeof import('./components/settings/MemorySettings.vue')['default']
|
||||
Menu: typeof import('./components/Menu.vue')['default']
|
||||
MessageList: typeof import('./components/chat/MessageList.vue')['default']
|
||||
|
89
src/components/Lottie.vue
Normal file
89
src/components/Lottie.vue
Normal file
@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div :id="id" :style="style"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import lottie, { AnimationConfigWithData, AnimationConfigWithPath, AnimationItem } from "lottie-web";
|
||||
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
|
||||
const id = ref("lottie-" + Math.random().toString(36).substring(3, 13));
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
loop: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 128,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
style: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const container: Ref<HTMLElement | null> = ref(null);
|
||||
|
||||
const animation: Ref<AnimationItem | null> = ref(null);
|
||||
|
||||
// const src = "/assets/lottie/" + props.name + ".json";
|
||||
|
||||
onMounted(() => {
|
||||
// get dom
|
||||
container.value = document.getElementById(id.value);
|
||||
|
||||
if (container.value) {
|
||||
container.value.style.height = props.height + "px";
|
||||
if (props.width) {
|
||||
container.value.style.width = props.width + "px";
|
||||
}
|
||||
if (props.center) {
|
||||
container.value.style.textAlign = "center";
|
||||
}
|
||||
}
|
||||
|
||||
// set height
|
||||
|
||||
// if width
|
||||
|
||||
// set center(text center)
|
||||
|
||||
if (container.value) {
|
||||
let options: AnimationConfigWithData = {
|
||||
container: container.value,
|
||||
renderer: "svg",
|
||||
loop: props.loop,
|
||||
autoplay: props.autoplay,
|
||||
animationData: props.data,
|
||||
};
|
||||
|
||||
animation.value = lottie.loadAnimation(options);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (animation.value !== null) {
|
||||
animation.value.destroy();
|
||||
}
|
||||
});
|
||||
</script>
|
@ -159,6 +159,7 @@ import router from "@/router";
|
||||
import element from "@/config/element";
|
||||
import { useIsMobile } from "@/utils/composables";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { useDialog } from "naive-ui";
|
||||
|
||||
// 获取组件传入的 chatId
|
||||
const chatId: Ref<string | number | undefined | null> = ref(null);
|
||||
@ -193,7 +194,8 @@ const processing = ref(false);
|
||||
const fileUpload = ref();
|
||||
const uploading = ref(false);
|
||||
const autoScroll = ref(true);
|
||||
const appStore = useAppStore()
|
||||
const appStore = useAppStore();
|
||||
const dialog = useDialog();
|
||||
|
||||
function onKeydown(e: KeyboardEvent) {
|
||||
// 带 shift 不触发
|
||||
@ -473,6 +475,13 @@ function streamChat(streamId: String, redirect = false) {
|
||||
let append = true;
|
||||
|
||||
switch (data.state) {
|
||||
case "failed":
|
||||
dialog.error({
|
||||
title: "推理失败",
|
||||
content: "目前无法完成推理,请稍后再试。",
|
||||
positiveText: "好",
|
||||
});
|
||||
break;
|
||||
case "tool_calling":
|
||||
// toolCalling.value = true;
|
||||
chatStore.toolName =
|
||||
@ -500,6 +509,15 @@ function streamChat(streamId: String, redirect = false) {
|
||||
" 中的 " +
|
||||
data.tool_call_message.function_name;
|
||||
|
||||
dialog.error({
|
||||
title: "工具调用失败",
|
||||
content:
|
||||
data.tool_call_message.tool_name +
|
||||
" 中的 " +
|
||||
data.tool_call_message.function_name,
|
||||
positiveText: "好",
|
||||
});
|
||||
|
||||
// toolError.value = true;
|
||||
append = false;
|
||||
setTimeout(() => {
|
||||
|
29
src/pages/errors/401.vue
Normal file
29
src/pages/errors/401.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<n-result :title="title" description="我们不能验证你的身份。">
|
||||
<template #icon>
|
||||
<Lottie :height="250" :data="DizzyFace" />
|
||||
</template>
|
||||
</n-result>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NResult } from "naive-ui";
|
||||
import Lottie from "@/components/Lottie.vue";
|
||||
import { computed } from "vue";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import DizzyFace from "@/assets/lottie/Dizzy-face.json";
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const user = computed(() => {
|
||||
return userStore.user;
|
||||
});
|
||||
|
||||
const title = computed(() => {
|
||||
if (user.value.name) {
|
||||
return "你不是 " + user.value.name;
|
||||
} else {
|
||||
return "这不是你的账号";
|
||||
}
|
||||
});
|
||||
</script>
|
36
src/pages/errors/404.vue
Normal file
36
src/pages/errors/404.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<n-result
|
||||
description="我们知道你很急,但是我们确实找不到。"
|
||||
status="404"
|
||||
title="资源不存在"
|
||||
>
|
||||
<template #icon>
|
||||
<Lottie :height="250" :data="ThinkingFace" />
|
||||
</template>
|
||||
|
||||
<template v-if="show_footer" #footer>
|
||||
<n-button @click="goTo('/')">回到首页</n-button>
|
||||
</template>
|
||||
</n-result>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NButton, NResult } from "naive-ui";
|
||||
|
||||
import router from "@/router";
|
||||
import Lottie from "@/components/Lottie.vue";
|
||||
import ThinkingFace from "@/assets/lottie/Thinking-face.json";
|
||||
|
||||
// import { defineProps } from 'vue'
|
||||
|
||||
defineProps({
|
||||
show_footer: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
function goTo(path: any) {
|
||||
router.push({ name: path });
|
||||
}
|
||||
</script>
|
14
src/pages/errors/500.vue
Normal file
14
src/pages/errors/500.vue
Normal file
@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<n-result description="我们的锅" status="500" title="服务器错误">
|
||||
<template #icon>
|
||||
<Lottie :height="250" :data="ScrunchedMouth" />
|
||||
</template>
|
||||
<template #footer> </template>
|
||||
</n-result>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NResult } from "naive-ui";
|
||||
import Lottie from "@/components/Lottie.vue";
|
||||
import ScrunchedMouth from "@/assets/lottie/scrunched-mouth.json";
|
||||
</script>
|
3
src/pages/errors/Base.vue
Normal file
3
src/pages/errors/Base.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
@ -2,6 +2,9 @@ import { useUserStore } from "../stores/user";
|
||||
import { h, computed } from "vue";
|
||||
import { createDiscreteApi, darkTheme, lightTheme, useOsTheme } from "naive-ui";
|
||||
import type { ConfigProviderProps } from "naive-ui";
|
||||
import error401 from "@/pages/errors/401.vue";
|
||||
import error404 from "@/pages/errors/404.vue";
|
||||
import error500 from "@/pages/errors/500.vue";
|
||||
|
||||
const osThemeRef = useOsTheme();
|
||||
|
||||
@ -64,6 +67,40 @@ const response = {
|
||||
data = error.response.data.error.message;
|
||||
}
|
||||
|
||||
if (error.response.status === 401) {
|
||||
dialog.error({
|
||||
title: "401 未授权",
|
||||
content: () => {
|
||||
return h(error401, {
|
||||
show_footer: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
} else if (error.response.status === 404) {
|
||||
dialog.error({
|
||||
title: "404 未找到",
|
||||
content: () => {
|
||||
return h(error404, {
|
||||
show_footer: false,
|
||||
});
|
||||
},
|
||||
});
|
||||
} else if (error.response.status === 500) {
|
||||
dialog.error({
|
||||
title: "500 服务器错误",
|
||||
content: () => {
|
||||
return h(error500);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
if (data.length !== 0) {
|
||||
dialog.error({
|
||||
title: "错误",
|
||||
content: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
},
|
||||
};
|
||||
|
4
src/typed-router.d.ts
vendored
4
src/typed-router.d.ts
vendored
@ -24,6 +24,10 @@ declare module 'vue-router/auto-routes' {
|
||||
'/auth/login': RouteRecordInfo<'/auth/login', '/auth/login', Record<never, never>, Record<never, never>>,
|
||||
'/auth/logout': RouteRecordInfo<'/auth/logout', '/auth/logout', Record<never, never>, Record<never, never>>,
|
||||
'/chat/[id]/': RouteRecordInfo<'/chat/[id]/', '/chat/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
|
||||
'/errors/401': RouteRecordInfo<'/errors/401', '/errors/401', Record<never, never>, Record<never, never>>,
|
||||
'/errors/404': RouteRecordInfo<'/errors/404', '/errors/404', Record<never, never>, Record<never, never>>,
|
||||
'/errors/500': RouteRecordInfo<'/errors/500', '/errors/500', Record<never, never>, Record<never, never>>,
|
||||
'/errors/Base': RouteRecordInfo<'/errors/Base', '/errors/Base', Record<never, never>, Record<never, never>>,
|
||||
'/guest/': RouteRecordInfo<'/guest/', '/guest', Record<never, never>, Record<never, never>>,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user