feat: 基础文章编辑功能
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
import { defineConfig } from 'astro/config';
|
import { defineConfig } from 'astro/config';
|
||||||
import solidJs from '@astrojs/solid-js';
|
import solidJs from '@astrojs/solid-js';
|
||||||
import node from '@astrojs/node';
|
import node from '@astrojs/node';
|
||||||
import tailwindcss from "@tailwindcss/vite";
|
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -13,6 +12,6 @@ export default defineConfig({
|
|||||||
mode: 'standalone'
|
mode: 'standalone'
|
||||||
}),
|
}),
|
||||||
vite: {
|
vite: {
|
||||||
plugins: [tailwindcss()],
|
plugins: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -10,16 +10,16 @@
|
|||||||
"deploy": "./scripts/deploy.sh"
|
"deploy": "./scripts/deploy.sh"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "^9.5.1",
|
"@astrojs/node": "10.0.5",
|
||||||
"@astrojs/solid-js": "^5.1.3",
|
"@astrojs/solid-js": "^5.1.3",
|
||||||
"@tailwindcss/vite": "^4.3.2",
|
"astro": "^7.0.6",
|
||||||
"astro": "^5.15.8",
|
"dayjs": "^1.11.21",
|
||||||
"github-markdown-css": "^5.9.0",
|
"github-markdown-css": "^5.9.0",
|
||||||
"jsdom": "^29.1.1",
|
"jsdom": "^29.1.1",
|
||||||
"ky": "^2.0.2",
|
"ky": "^2.0.2",
|
||||||
"shiki": "^4.3.0",
|
"modern-normalize": "^3.0.1",
|
||||||
"solid-js": "^1.9.10",
|
"shiki": "^4.3.1",
|
||||||
"tailwindcss": "^4.3.2"
|
"solid-js": "^1.9.14"
|
||||||
},
|
},
|
||||||
"volta": {
|
"volta": {
|
||||||
"node": "22.21.1"
|
"node": "22.21.1"
|
||||||
|
|||||||
3916
pnpm-lock.yaml
generated
3916
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<a href="https://beian.miit.gov.cn/#/Integrated/index">
|
<a target="_blank" href="https://beian.miit.gov.cn/#/Integrated/index">
|
||||||
备案号:鄂ICP备2023000060号-2
|
备案号:鄂ICP备2023000060号-2
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { metadata } from "../consts";
|
|||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
box-shadow: rgba(17, 17, 26, 0.1) 0px 1px 0px;
|
box-shadow: rgba(17, 17, 26, 0.1) 0 1px 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,6 @@ import { metadata } from "../consts";
|
|||||||
|
|
||||||
.main-nav h1 {
|
.main-nav h1 {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
font-size: 30px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
@@ -38,7 +37,6 @@ import { metadata } from "../consts";
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* element: menu-item */
|
|
||||||
.main-nav .menu-item a {
|
.main-nav .menu-item a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
@@ -52,11 +50,11 @@ import { metadata } from "../consts";
|
|||||||
<h1>
|
<h1>
|
||||||
<a href="/">{metadata.siteTitle}</a>
|
<a href="/">{metadata.siteTitle}</a>
|
||||||
</h1>
|
</h1>
|
||||||
<ul class="menu">
|
<!--<ul class="menu">-->
|
||||||
<li class="menu-item"><a href="/">首页</a></li>
|
<!-- <li class="menu-item"><a href="/">首页</a></li>-->
|
||||||
<li class="menu-item"><a href="/">文章</a></li>
|
<!-- <li class="menu-item"><a href="/">文章</a></li>-->
|
||||||
<li class="menu-item"><a href="/">分类</a></li>
|
<!-- <li class="menu-item"><a href="/">分类</a></li>-->
|
||||||
<li class="menu-item"><a href="/">关于</a></li>
|
<!-- <li class="menu-item"><a href="/">关于</a></li>-->
|
||||||
</ul>
|
<!--</ul>-->
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
import "@/styles/base.css";
|
import "@/styles/global.css";
|
||||||
|
|
||||||
import BaseHeader from "@/components/BaseHeader.astro";
|
import BaseHeader from "@/components/BaseHeader.astro";
|
||||||
import BaseFooter from "@/components/BaseFooter.astro";
|
import BaseFooter from "@/components/BaseFooter.astro";
|
||||||
@@ -28,25 +28,3 @@ const { siteTitle } = metadata;
|
|||||||
<BaseFooter />
|
<BaseFooter />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
flex: 1;
|
|
||||||
max-width: var(--layout-width);
|
|
||||||
width: 100%;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 32px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
5
src/lib/format.ts
Normal file
5
src/lib/format.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
export const formatDatetime = (date: string,format = 'YYYY-MM-DD HH:mm') => {
|
||||||
|
return dayjs(date).format(format);
|
||||||
|
};
|
||||||
@@ -3,7 +3,36 @@ import {createHighlighter} from 'shiki'
|
|||||||
|
|
||||||
const highlighter = await createHighlighter({
|
const highlighter = await createHighlighter({
|
||||||
themes: ['github-dark-dimmed'],
|
themes: ['github-dark-dimmed'],
|
||||||
langs: ['javascript', 'typescript', 'css', 'tsx', 'less', 'scss', 'text'],
|
langs: [
|
||||||
|
"bash",
|
||||||
|
"json",
|
||||||
|
"yaml",
|
||||||
|
"xml",
|
||||||
|
"html",
|
||||||
|
"css",
|
||||||
|
"scss",
|
||||||
|
"javascript",
|
||||||
|
"typescript",
|
||||||
|
"jsx",
|
||||||
|
"tsx",
|
||||||
|
"vue",
|
||||||
|
"markdown",
|
||||||
|
"sql",
|
||||||
|
"graphql",
|
||||||
|
"python",
|
||||||
|
"java",
|
||||||
|
"go",
|
||||||
|
"rust",
|
||||||
|
"c",
|
||||||
|
"cpp",
|
||||||
|
"csharp",
|
||||||
|
"php",
|
||||||
|
"ruby",
|
||||||
|
"kotlin",
|
||||||
|
"swift",
|
||||||
|
"dockerfile",
|
||||||
|
"nginx"
|
||||||
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
const resolveLang = (lang) => {
|
const resolveLang = (lang) => {
|
||||||
|
|||||||
@@ -2,40 +2,81 @@
|
|||||||
import Layout from "@/layouts/Layout.astro";
|
import Layout from "@/layouts/Layout.astro";
|
||||||
import {http} from "@/lib/request.ts";
|
import {http} from "@/lib/request.ts";
|
||||||
import {highlightHtmlWithJsdom} from "@/lib/highlight.js";
|
import {highlightHtmlWithJsdom} from "@/lib/highlight.js";
|
||||||
import 'github-markdown-css/github-markdown-light.css';
|
import "github-markdown-css/github-markdown-light.css"
|
||||||
|
import "@/styles/github-markdown.css"
|
||||||
|
import {formatDatetime} from "@/lib/format.ts";
|
||||||
|
|
||||||
const { slug } = Astro.params;
|
const {slug} = Astro.params;
|
||||||
|
|
||||||
interface Post {
|
interface Post {
|
||||||
title: string;
|
title: string;
|
||||||
summary: string;
|
summary: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
cover: string;
|
cover: string;
|
||||||
published_at: string;
|
published_at: string;
|
||||||
content_html: string;
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {data} = await http.get<ApiResponse<Post>>(`post/${slug}`);
|
const {data} = await http.get<ApiResponse<Post>>(`post/${slug}`);
|
||||||
|
|
||||||
const content = await highlightHtmlWithJsdom(data.content_html)
|
const content = await highlightHtmlWithJsdom(data.content)
|
||||||
---
|
---
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<h1>{data.title}</h1>
|
<h1 class="post-title">{data.title}</h1>
|
||||||
|
|
||||||
<div>{data.published_at}</div>
|
<div class="published-at">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
class="lucide lucide-calendar-days-icon lucide-calendar-days">
|
||||||
|
<path d="M8 2v4"/>
|
||||||
|
<path d="M16 2v4"/>
|
||||||
|
<rect width="18" height="18" x="3" y="4" rx="2"/>
|
||||||
|
<path d="M3 10h18"/>
|
||||||
|
<path d="M8 14h.01"/>
|
||||||
|
<path d="M12 14h.01"/>
|
||||||
|
<path d="M16 14h.01"/>
|
||||||
|
<path d="M8 18h.01"/>
|
||||||
|
<path d="M12 18h.01"/>
|
||||||
|
<path d="M16 18h.01"/>
|
||||||
|
</svg>
|
||||||
|
{formatDatetime(data.published_at)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="post markdown-body" set:html={content}>
|
<div class="post markdown-body" set:html={content}></div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.post{
|
.post-title{
|
||||||
background: #fff;
|
margin-block-start: 0;
|
||||||
border-radius: 12px;
|
margin-block-end: 24px;
|
||||||
overflow: auto;
|
}
|
||||||
padding: 16px;
|
|
||||||
box-shadow: rgba(149, 157, 165, 0.2) 0px 2px 14px -4px;
|
@media (max-width: 768px) {
|
||||||
}
|
.post-title {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.published-at{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.published-at svg{
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: auto;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: rgba(149, 157, 165, 0.2) 0 2px 14px -4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--layout-width: 1200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
4
src/styles/css-reset.css
Normal file
4
src/styles/css-reset.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
12
src/styles/github-markdown.css
Normal file
12
src/styles/github-markdown.css
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.markdown-body pre code{
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-body h1,
|
||||||
|
.markdown-body h2,
|
||||||
|
.markdown-body h3,
|
||||||
|
.markdown-body h4,
|
||||||
|
.markdown-body h5,
|
||||||
|
.markdown-body h6 {
|
||||||
|
border-bottom: none ;
|
||||||
|
}
|
||||||
27
src/styles/global.css
Normal file
27
src/styles/global.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
@import "modern-normalize";
|
||||||
|
@import "css-reset.css";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--layout-width: 980px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
max-width: var(--layout-width);
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user