diff --git a/.gitignore b/.gitignore index 5d8e194..5fd955a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ build electron .local.env + +.vs/ diff --git a/database/graphql/homework_reply.graphql b/database/graphql/homework_reply.graphql new file mode 100644 index 0000000..8ebe315 --- /dev/null +++ b/database/graphql/homework_reply.graphql @@ -0,0 +1,74 @@ +# 作业三:聊天室消息的单层回复 + +# 1. 发一条回复消息:reply_to 指向被回复的消息 +mutation replyMessage( + $user_uuid: uuid!, + $room_uuid: uuid!, + $content: String!, + $reply_to: uuid! +) { + insert_message_one(object: { + user_uuid: $user_uuid, + room_uuid: $room_uuid, + content: $content, + reply_to: $reply_to + }) { + uuid + content + # 自引用外键的对象关系名:Hasura 中为目标表名 message + message { + uuid + content + } + } +} + +# 2. 查询某个会议的消息,并带出每条消息回复的目标(单层) +query messagesWithReply($room_uuid: uuid!) { + message( + where: { room_uuid: { _eq: $room_uuid } }, + order_by: { created_at: asc } + ) { + uuid + content + created_at + user { + username + } + # 回复目标(通过 message.reply_to 外键的对象关系) + message { + uuid + content + user { + username + } + } + } +} + +# 3. 查询某条消息收到了哪些回复 +query messageReplies($uuid: uuid!) { + message(where: { reply_to: { _eq: $uuid } }) { + uuid + content + user { + username + } + message { + uuid + content + } + } +} + +# 4. 订阅某个会议的新消息(含回复关系),方便聊天室实时更新 +subscription messagesByRoomWithReply($room_uuid: uuid!) { + message(where: { room_uuid: { _eq: $room_uuid } }) { + uuid + content + message { + uuid + content + } + } +} diff --git a/database/sql/homework_reply.sql b/database/sql/homework_reply.sql new file mode 100644 index 0000000..c94ee8d --- /dev/null +++ b/database/sql/homework_reply.sql @@ -0,0 +1,14 @@ +-- 作业三:聊天室消息支持回复之前的某条消息(单层回复) +-- 设计:给 message 增加可空的 reply_to 列,自引用 message.uuid。 +-- 被回复的消息删除时 reply_to 置空,避免出现悬空引用。 + +alter table public.message + add column if not exists reply_to uuid; + +alter table public.message + drop constraint if exists message_reply_to_fkey; + +alter table public.message + add constraint message_reply_to_fkey + foreign key (reply_to) references public.message (uuid) + on delete set null; diff --git a/database/sql/message.sql b/database/sql/message.sql index 51c8108..2639f9b 100644 --- a/database/sql/message.sql +++ b/database/sql/message.sql @@ -42,3 +42,4 @@ insert into public.message (user_uuid, room_uuid, content) values ('00000000-0000-0000-0000-000000000004', '00000000-0000-0000-0000-100000000003', '好了,今天就到这里吧'); update public.message set created_at = '2021-01-01 00:00:00' where room_uuid = '00000000-0000-0000-0000-100000000002'; +-- 信息由AI生成 \ No newline at end of file diff --git a/frontend/public/about-me.html b/frontend/public/about-me.html new file mode 100644 index 0000000..ffe9c6c --- /dev/null +++ b/frontend/public/about-me.html @@ -0,0 +1,75 @@ + + + + + + 关于我 + + + + +
+
+ +
+

关于我

+
+ +
+
+

基本信息

+ + + + + + + + + +
姓名赵奕然
班级无56
+ +
+ +

我的爱好

+
    +
  • 弹琴
  • +
  • 打游戏
  • +
  • 视频
  • +
+
+ +
+

一些趣事

+
    +
  1. 你被骗了
  2. +
+
永不放弃你
+ +
+ +

联系方式

+

+ 邮箱: + zhaoyr25@mails.tsinghua.edu.cn +

+

+ 返回首页 +

+
+
+ +
+

GitHub

+
+ +
+

加载中...

+

+
+ +
+
+
+ + diff --git a/frontend/public/about-me.js b/frontend/public/about-me.js new file mode 100644 index 0000000..cffeae6 --- /dev/null +++ b/frontend/public/about-me.js @@ -0,0 +1,46 @@ +const themeToggle = document.getElementById("theme-toggle"); + +// ===== 功能 1:亮色 / 暗色模式 ===== +const applyTheme = (dark) => { + document.body.classList.toggle("dark", dark); + themeToggle.textContent = dark ? "切换到亮色模式" : "切换到暗色模式"; +}; + +const savedTheme = localStorage.getItem("about-me-theme"); +applyTheme(savedTheme === "dark"); + +themeToggle.addEventListener("click", () => { + const dark = !document.body.classList.contains("dark"); + applyTheme(dark); + localStorage.setItem("about-me-theme", dark ? "dark" : "light"); +}); + +// ===== 功能 2:拉取 GitHub 公开资料(网络资源) ===== +const githubAvatar = document.getElementById("github-avatar"); +const githubName = document.getElementById("github-name"); +const githubRepos = document.getElementById("github-repos"); +const githubError = document.getElementById("github-error"); + +const loadGithubProfile = async () => { + try { + const response = await fetch("https://api.github.com/users/Victor-692"); + if (!response.ok) { + throw new Error(`HTTP ${response.status}`); + } + const user = await response.json(); + + githubAvatar.src = user.avatar_url; + githubAvatar.hidden = false; + githubName.textContent = user.name || user.login; + githubRepos.textContent = `公开仓库数:${user.public_repos}`; + githubError.hidden = true; + } catch (err) { + console.error(err); + githubName.textContent = "GitHub 资料加载失败"; + githubRepos.textContent = ""; + githubError.hidden = false; + githubError.textContent = "请检查网络后刷新页面。"; + } +}; + +loadGithubProfile(); diff --git a/frontend/public/index.css b/frontend/public/index.css index 1cb6bf9..bdc1881 100644 --- a/frontend/public/index.css +++ b/frontend/public/index.css @@ -63,17 +63,140 @@ line-height: 2em; } -#clock { - position: absolute; - bottom: 0; - left: 12px; - width: 40vw; +/* ===== 关于我页面 ===== */ +#about-me-frame { + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + padding: 32px 16px; + box-sizing: border-box; + background: linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%); } -#motto { +.about-me-card { + background-color: rgba(255, 255, 255, 0.35); +} + +#about-me-header { + width: min(640px, 92vw); + text-align: center; +} + +#about-me-avatar { + width: 88px; + height: 88px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + font-size: 40px; + color: #ffffff; + background: linear-gradient(135deg, #6a82fb 0%, #fc5c7d 100%); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); +} + +.about-me-subtitle { + color: rgba(0, 0, 0, 0.65); +} + +#about-me-grid { + width: min(920px, 94vw); + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 16px; +} + +.about-me-col { + flex: 1 1 320px; + max-width: 460px; +} + +.about-me-quote { + margin: 12px 0; + padding: 8px 16px; + border-left: 4px solid #6a82fb; + border-radius: 4px; + background-color: rgba(255, 255, 255, 0.35); + color: rgba(0, 0, 0, 0.75); +} + +#about-me-header { + position: relative; +} + +.theme-toggle { position: absolute; - bottom: 0; + top: 12px; right: 12px; - text-align: right; - width: 40vw; + padding: 6px 12px; + border: none; + border-radius: 16px; + cursor: pointer; + color: #ffffff; + background: linear-gradient(135deg, #6a82fb 0%, #fc5c7d 100%); +} + +#about-me-github { + width: min(450px, 94vw); +} + +#github-profile { + display: flex; + align-items: center; + gap: 16px; +} + +#github-avatar { + width: 72px; + height: 72px; + border-radius: 50%; +} + +#github-info p { + margin: 4px 0; +} + +#github-error { + color: #b00020; +} + +/* ===== 暗色模式 ===== */ +body.dark #about-me-frame { + background: linear-gradient(135deg, #23272f 0%, #30384a 100%); +} + +body.dark .about-me-card { + background-color: rgba(255, 255, 255, 0.08); + color: #e8e8e8; +} + +body.dark .about-me-quote { + background-color: rgba(255, 255, 255, 0.08); + color: #cfd3dc; +} + +body.dark .styled-table th, +body.dark .styled-table td, +body.dark #about-me-github a { + color: #d7dbe3; +} + +#clock { + position: absolute; + bottom: 0; + left: 12px; + width: 40vw; +} + +#motto { + position: absolute; + bottom: 0; + right: 12px; + text-align: right; + width: 40vw; } diff --git a/frontend/public/index.html b/frontend/public/index.html index fe08636..e2938a1 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -28,6 +28,8 @@

这是一个趣味会议软件

进入主页      关于这个工程 +      + 关于我

当前时间加载中... ...

每日一句加载中... ...