This commit is contained in:
@ -30,7 +30,7 @@ const { title = '小帕的小窝', withGap = false } = Astro.props
|
||||
<a href="/">小帕的小窝</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/blogs"><Icon name="mdi:invoice-text-outline" />文章</a>
|
||||
<a href="/blog"><Icon name="mdi:invoice-text-outline" />文章</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/about"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { legacyClient } from '../clients'
|
||||
|
||||
export type ListBlogItemType = {
|
||||
export type LegacyListBlogItemType = {
|
||||
id: number
|
||||
title: string
|
||||
|
||||
@ -24,7 +24,7 @@ export type ListBlogItemType = {
|
||||
}
|
||||
}
|
||||
|
||||
export type BlogContentType = ListBlogItemType & {
|
||||
export type LegacyBlogContentType = LegacyListBlogItemType & {
|
||||
content: string
|
||||
}
|
||||
|
||||
@ -57,12 +57,12 @@ export const listBlogs = async ({
|
||||
_blog.updated_at = new Date(_blog.updated_at)
|
||||
|
||||
return _blog
|
||||
}) as ListBlogItemType[]
|
||||
}) as LegacyListBlogItemType[]
|
||||
}
|
||||
|
||||
export const getBlog: (
|
||||
blog_id: number,
|
||||
) => Promise<null | BlogContentType> = async (blog_id: number) => {
|
||||
) => Promise<null | LegacyBlogContentType> = async (blog_id: number) => {
|
||||
const resp = await legacyClient.get(`/v1/blog/${blog_id}`, {
|
||||
validateStatus: (status) => status == 200 || status == 404,
|
||||
})
|
||||
|
||||
27
src/lib/apis/legacy/user.ts
Normal file
27
src/lib/apis/legacy/user.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { legacyClient } from '../clients'
|
||||
|
||||
export type LegacyUserType = {
|
||||
id: number
|
||||
created_at: Date
|
||||
username: string
|
||||
nickname: string
|
||||
permission: number
|
||||
introduction: string
|
||||
avatar: {
|
||||
image_url: string
|
||||
}
|
||||
}
|
||||
|
||||
export const getUserInfo = async ({ username }: { username: string }) => {
|
||||
const resp = await legacyClient.get(`/v1/user/${username}/info`)
|
||||
if (resp.status != 200) {
|
||||
return null
|
||||
}
|
||||
return {
|
||||
...resp.data,
|
||||
created_at: new Date(resp.data.created_at),
|
||||
avatar: {
|
||||
image_url: 'https://legacy.passthem.top' + resp.data.avatar.image_url,
|
||||
},
|
||||
} as LegacyUserType
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
import FullLayoutV1 from '../layout/FullLayoutV1.astro'
|
||||
import { listBlogs, type ListBlogItemType } from '../lib/apis/legacy/blog'
|
||||
import { listBlogs, type LegacyListBlogItemType } from '../lib/apis/legacy/blog'
|
||||
import BlogCard from '../components/BlogCard.astro'
|
||||
import BlogHeaderImage from '../assets/blogs-header.webp'
|
||||
import { Image } from 'astro:assets'
|
||||
@ -10,7 +10,7 @@ export const prerender = false
|
||||
const _page = parseInt(Astro.url.searchParams.get('page') || '1')
|
||||
const page = isNaN(_page) ? 1 : Math.max(1, _page)
|
||||
|
||||
let blogs: ListBlogItemType[] = []
|
||||
let blogs: LegacyListBlogItemType[] = []
|
||||
|
||||
try {
|
||||
blogs = await listBlogs({ page, limit: 100 })
|
||||
@ -45,7 +45,7 @@ try {
|
||||
blogs.map((blog) => (
|
||||
<BlogCard
|
||||
title={blog.title}
|
||||
link={`/blogs/${blog.id}`}
|
||||
link={`/blog/${blog.id}`}
|
||||
featureImage={blog.featured_image?.image_url}
|
||||
author={{
|
||||
name: blog.author.nickname,
|
||||
@ -54,10 +54,7 @@ const formatDate = (date: Date) =>
|
||||
{
|
||||
blogData.author && (
|
||||
<div class="blog-info">
|
||||
<a
|
||||
class="author"
|
||||
href={`https://legacy.passthem.top/user/${blogData.author.username}`}
|
||||
>
|
||||
<a class="author" href={`/user/${blogData.author.username}`}>
|
||||
<div class="avatar">
|
||||
<Image
|
||||
class="image"
|
||||
@ -3,7 +3,7 @@ import type { APIRoute } from 'astro'
|
||||
import {
|
||||
getBlog,
|
||||
listBlogs,
|
||||
type ListBlogItemType,
|
||||
type LegacyListBlogItemType,
|
||||
} from '../lib/apis/legacy/blog'
|
||||
import { ensureShikiEngine } from '../lib/markdown'
|
||||
// import { toMarkdocTree } from '../lib/markdoc'
|
||||
@ -50,7 +50,7 @@ const _getBlog = async (blogId: number) => {
|
||||
}
|
||||
|
||||
export const GET = (async (context) => {
|
||||
let blogs: ListBlogItemType[] = []
|
||||
let blogs: LegacyListBlogItemType[] = []
|
||||
let pid = 0
|
||||
|
||||
let newBlogs = []
|
||||
@ -76,7 +76,7 @@ export const GET = (async (context) => {
|
||||
const rssItem: RSSFeedItem = {
|
||||
title: blog.title,
|
||||
description: `一篇由 ${blog.author.nickname} 写的博客`,
|
||||
link: `${site}/blogs/${blog.id}`,
|
||||
link: `${site}/blog/${blog.id}`,
|
||||
pubDate: new Date(blog.created_at),
|
||||
content: await _render(blogContent),
|
||||
author: blog.author.nickname,
|
||||
|
||||
89
src/pages/user/[user_id].astro
Normal file
89
src/pages/user/[user_id].astro
Normal file
@ -0,0 +1,89 @@
|
||||
---
|
||||
import FullLayoutV1 from '../../layout/FullLayoutV1.astro'
|
||||
import { getUserInfo, type LegacyUserType } from '../../lib/apis/legacy/user'
|
||||
import { Image } from 'astro:assets'
|
||||
|
||||
const { user_id = '' } = Astro.params
|
||||
var user_data: LegacyUserType
|
||||
|
||||
try {
|
||||
const _user_data = await getUserInfo({ username: user_id })
|
||||
if (_user_data === null) {
|
||||
return Astro.redirect('/404')
|
||||
}
|
||||
user_data = _user_data
|
||||
} catch (e) {
|
||||
console.warn('访问了不存在的用户', user_id)
|
||||
console.warn(e)
|
||||
return Astro.redirect('/404')
|
||||
}
|
||||
---
|
||||
|
||||
<FullLayoutV1>
|
||||
<div class="container">
|
||||
<div class="user-card">
|
||||
<div class="avatar">
|
||||
<Image
|
||||
src={user_data.avatar.image_url}
|
||||
densities={[1.5, 2]}
|
||||
width={150}
|
||||
height={150}
|
||||
alt=`用户 ${user_data.username} 的头像`
|
||||
/>
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<h1 class="name">
|
||||
<span class="nickname">{user_data.nickname}</span><span
|
||||
class="username">{user_data.username}</span
|
||||
>
|
||||
</h1>
|
||||
<h2 class="introduction">{user_data.introduction}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</FullLayoutV1>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100dvh;
|
||||
|
||||
.user-card {
|
||||
background-color: var(--color-bg-n);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 4rem;
|
||||
gap: 1rem;
|
||||
border-radius: 1rem;
|
||||
|
||||
@media (width >= 768px) {
|
||||
flex-direction: row;
|
||||
gap: 3rem;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
.name {
|
||||
display: flex;
|
||||
font-weight: 600;
|
||||
gap: 0.5rem;
|
||||
margin-block-end: 0.25rem;
|
||||
align-items: center;
|
||||
font-size: larger;
|
||||
|
||||
.username {
|
||||
opacity: 0.3;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.9em;
|
||||
|
||||
&::before {
|
||||
content: '@';
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user