This commit is contained in:
SunWuyuan
2025-03-22 18:21:51 +08:00
parent c0d235a0fe
commit 16da372bbc
6 changed files with 1587 additions and 47 deletions
+201 -46
View File
@@ -8,57 +8,162 @@
</v-card-item>
<v-card-text>
<v-row justify="center" align="center">
<v-col cols="12" md="8" class="text-center">
<v-avatar size="120" class="mb-4">
<v-img
src="https://avatars.githubusercontent.com/u/88357633?v=4"
alt="Sunwuyuan"
/>
</v-avatar>
<v-row>
<v-col cols="12" md="8" class="mx-auto">
<div class="d-flex flex-column align-start">
<v-avatar size="120" class="mb-4">
<v-img
src="https://github.com/Sunwuyuan.png"
alt="Sunwuyuan"
/>
</v-avatar>
<h2 class="text-h5 mb-2">Classworks</h2>
<p class="text-body-1 mb-4">
由 <a
href="https://github.com/sunwuyuan"
target="_blank"
class="text-decoration-none font-weight-medium"
>Sunwuyuan</a> 开发
</p>
<h2 class="text-h5 mb-2">Classworks</h2>
<p class="text-body-1 mb-4">适用于班级大屏的作业板小工具</p>
<div class="d-flex gap-2 flex-wrap mb-6">
<v-btn
color="red"
variant="tonal"
href="https://github.com/ClassworksDev/Classworks/issues"
target="_blank"
prepend-icon="mdi-bug"
>
报告问题
</v-btn>
<v-btn
variant="text"
href="https://github.com/ClassworksDev/Classworks"
target="_blank"
prepend-icon="mdi-github"
>
前端
</v-btn>
<v-btn
variant="text"
href="https://github.com/ClassworksDev/ClassworksServer"
target="_blank"
prepend-icon="mdi-github"
>
后端
</v-btn>
</div>
<v-divider class="mb-4 w-100"></v-divider>
<h3 class="text-h6 mb-2">备注与致谢</h3>
<v-list class="mb-4 bg-transparent">
<v-list-item
href="https://github.com/EnderWolf006/HomeworkBoard"
target="_blank"
append-icon="mdi-link"
>
<v-list-item-title>
本项目受到 HomeworkBoard 的启发而开发
</v-list-item-title>
<v-list-item-subtitle>
感谢 EnderWolf006 (@EnderWolf) fhzit(@Hellofhz) KeyFac
等人的贡献
</v-list-item-subtitle>
</v-list-item>
<v-list-item
href="https://houlangs.com"
target="_blank"
append-icon="mdi-link"
>
<v-list-item-title>
Classworks 由<strong>厚浪云</strong>提供
</v-list-item-title>
<v-list-item-subtitle>
长江后浪推前浪 浮事新人换旧人
</v-list-item-subtitle>
</v-list-item>
<v-list-item
href="https://zerocat.houlangs.com"
target="_blank"
append-icon="mdi-link"
>
<v-list-item-title>
感谢 ZeroCat 社区的开发者们
</v-list-item-title>
<v-list-item-subtitle>
新一代,开源,编程社区
</v-list-item-subtitle>
</v-list-item>
<v-divider class="ma-1"></v-divider>
<v-list-item
href="https://github.com/HUSX100/IslandCaller"
target="_blank"
append-icon="mdi-link"
>
<v-list-item-title>
本项目与 IslandCaller 无关
</v-list-item-title>
<v-list-item-subtitle>
IslandCaller 是由 HUSX100 开发的基于 ClassIsland
提醒服务的轻量级点名器
</v-list-item-subtitle>
</v-list-item>
<v-list-item
href="https://classisland.tech"
target="_blank"
append-icon="mdi-link"
>
<v-list-item-title>
本项目与 ClassIsland 无关
</v-list-item-title>
<v-list-item-subtitle>
ClassIsland 是由 HelloWRC
开发的适用于班级大屏的课表信息显示工具
</v-list-item-subtitle>
</v-list-item>
</v-list>
<div class="d-flex justify-center gap-2 flex-wrap">
<v-btn
color="primary"
variant="outlined"
href="https://github.com/ClassworksDev/Classworks"
target="_blank"
prepend-icon="mdi-github"
variant="text"
class="mb-4"
prepend-icon="mdi-package-variant"
@click="showDeps = true"
>
前端 GitHub
查看使用的第三方库
</v-btn>
<v-btn
color="primary"
variant="outlined"
href="https://github.com/ClassworksDev/ClassworksServer"
target="_blank"
prepend-icon="mdi-github"
<v-dialog
v-model="showDeps"
transition="dialog-bottom-transition"
fullscreen
>
后端 GitHub
</v-btn>
<v-btn
color="primary"
variant="outlined"
href="https://github.com/ClassworksDev/Classworks/issues"
target="_blank"
prepend-icon="mdi-bug"
>
报告问题
</v-btn>
<v-card
><v-toolbar>
<v-btn icon="mdi-close" @click="showDeps = false"></v-btn>
<v-toolbar-title>使用的第三方库</v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-card-text>
<v-list>
<v-list-item
v-for="dep in Dependencies"
:key="dep.name"
:href="'https://www.npmjs.com/package/' + dep.name"
target="_blank"
append-icon="mdi-link"
>
<v-list-item-title>
{{ dep.name }}
</v-list-item-title>
<v-list-item-subtitle>
v{{ dep.version }}
</v-list-item-subtitle>
</v-list-item>
</v-list>
</v-card-text>
</v-card>
</v-dialog>
<p class="text-caption text-medium-emphasis">
Copyright © {{ new Date().getFullYear() }} Sunwuyuan
</p>
</div>
<p class="mt-4 text-caption text-medium-emphasis">
GPL License © 2024
</p>
</v-col>
</v-row>
</v-card-text>
@@ -66,7 +171,57 @@
</template>
<script>
import { ref, onMounted } from "vue";
import packageJson from "../../../package.json";
export default {
name: 'AboutCard'
}
name: "AboutCard",
setup() {
const Dependencies = ref([]);
const showDeps = ref(false); // 添加对话框显示状态
const loadDependencies = () => {
try {
// 合并 dependencies 和 devDependencies
const allDependencies = {
...(packageJson.dependencies || {}),
...(packageJson.devDependencies || {}),
};
// 转换为数组并过滤掉不需要显示的依赖
const deps = Object.entries(allDependencies).map(([name, version]) => ({
name,
version: version.replace(/[\^~]/g, ""),
description: getDependencyDescription(name),
}));
Dependencies.value = deps;
} catch (error) {
console.error("加载依赖信息失败:", error);
Dependencies.value = [];
}
};
const getDependencyDescription = (name) => {
const descriptions = {
vue: "渐进式 JavaScript 框架",
vuetify: "材料设计组件框架",
axios: "Promise 基础的 HTTP 客户端",
pinia: "Vue 状态管理库",
"vue-router": "Vue.js 官方路由管理器",
"@vitejs/plugin-vue": "Vite 的 Vue 插件",
};
return descriptions[name] || "";
};
onMounted(() => {
loadDependencies();
});
return {
Dependencies,
showDeps,
};
},
};
</script>
@@ -0,0 +1,158 @@
<template>
<settings-card
border
title="回声洞"
icon="mdi-thought-bubble"
@click="handleClick"
>
<v-card-text>
<div ref="typewriter" class="typewriter-text"></div>
<div ref="sourceWriter" class="source-text text-caption text-grey"></div>
</v-card-text>
<div class="d-flex align-center">
<transition name="fade">
<div v-if="currentQuote?.contributor" class="contributor">
<v-chip>
<v-avatar start>
<v-img
:src="`https://github.com/${currentQuote.contributor}.png`"
></v-img> </v-avatar
>{{ currentQuote.contributor }}
</v-chip>
</div>
</transition>
</div>
</settings-card>
</template>
<script>
import Typewriter from "typewriter-effect/dist/core";
import quotes from "@/data/echoChamber.json";
import SettingsCard from "@/components/SettingsCard.vue";
export default {
name: "EchoChamberCard",
components: { SettingsCard },
data() {
return {
typewriter: null,
sourceWriter: null,
currentQuote: {
text: this.INITIAL_TEXT,
author: this.INITIAL_SOURCE,
},
showCopySuccess: false,
hasClicked: false,
INITIAL_TEXT: "点击此处可以查看 Classworks 用户群里沙雕群友们的发言",
INITIAL_SOURCE: "点击后会复制当前句子到剪贴板中",
};
},
mounted() {
this.initTypewriters();
},
methods: {
getRandomQuote() {
const index = Math.floor(Math.random() * quotes.quotes.length);
return quotes.quotes[index];
},
initTypewriters() {
// 主文本打字机
this.typewriter = new Typewriter(this.$refs.typewriter, {
delay: 50,
deleteSpeed: 30,
loop: false,
});
// 来源文本打字机
this.sourceWriter = new Typewriter(this.$refs.sourceWriter, {
delay: 30,
deleteSpeed: 20,
loop: false,
cursor: "",
});
// 显示初始提示
this.typewriter.typeString(this.INITIAL_TEXT).start();
this.sourceWriter.typeString(this.INITIAL_SOURCE).start();
},
typeQuote(quote) {
this.typewriter.deleteAll(30).typeString(quote.text).start();
if (quote.author) {
this.sourceWriter.deleteAll(20).typeString(`${quote.author}`).start();
}
},
refreshQuote() {
this.currentQuote = this.getRandomQuote();
this.typeQuote(this.currentQuote);
},
async handleClick() {
if (!this.hasClicked) {
this.hasClicked = true;
this.currentQuote = this.getRandomQuote();
}
await this.copyToClipboard();
this.refreshQuote();
},
async copyToClipboard() {
if (!this.currentQuote) return;
const quote = this.currentQuote;
const text = `${quote.text}\n${
quote.author ? `作者:${quote.author}` : ""
}\n${quote.contributor ? `贡献者:${quote.contributor}` : ""}${
quote.link
? `\n来源:${quote.link}`
: quote.contributor
? "\n来源:https://github.com/" + quote.contributor
: ""
}`;
try {
await navigator.clipboard.writeText(text);
this.showCopySuccess = true;
} catch (err) {
console.error("复制失败:", err);
}
},
},
beforeUnmount() {
if (this.typewriter) {
this.typewriter.stop();
}
if (this.sourceWriter) {
this.sourceWriter.stop();
}
},
};
</script>
<style scoped>
.cursor-pointer {
cursor: pointer;
}
.source-text {
opacity: 0.7;
font-size: 0.9em;
}
.contributor {
opacity: 0.7;
font-size: 0.9em;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -42,6 +42,7 @@
<theme-settings-card border />
</v-col>
<!-- 开发者选项卡片 -->
<v-col :cols="12" :md="settings.developer.enabled ? 12 : 6">
<settings-card
@@ -133,6 +134,10 @@
/>
</v-col>
<!-- 添加回声洞卡片 -->
<v-col cols="12">
<echo-chamber-card border />
</v-col>
<!-- 关于卡片 -->
<v-col cols="12">
<about-card />
@@ -152,6 +157,7 @@ import RefreshSettingsCard from '@/components/settings/cards/RefreshSettingsCard
import DisplaySettingsCard from '@/components/settings/cards/DisplaySettingsCard.vue';
import DataProviderSettingsCard from '@/components/settings/cards/DataProviderSettingsCard.vue';
import ThemeSettingsCard from '@/components/settings/cards/ThemeSettingsCard.vue';
import EchoChamberCard from '@/components/settings/cards/EchoChamberCard.vue';
import {
getSetting,
setSetting,
@@ -177,7 +183,8 @@ export default {
StudentListCard,
AboutCard,
DataProviderSettingsCard,
ThemeSettingsCard
ThemeSettingsCard,
EchoChamberCard
},
setup() {
const { mobile } = useDisplay();