Initial Green_Datura site
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.next/
|
||||||
|
.next-dev-logs/
|
||||||
|
out/
|
||||||
|
node_modules/
|
||||||
|
tsconfig.tsbuildinfo
|
||||||
|
*.log
|
||||||
|
.env*
|
||||||
|
*.zip
|
||||||
|
deploy-single-file/
|
||||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Green_Datura 官网
|
||||||
|
|
||||||
|
基于 Next.js App Router 与 Ant Design 的单页官网,包含福州大学至诚学院 Green_Datura 网络安全俱乐部简介、荣誉成果和微信公众号入口。
|
||||||
|
|
||||||
|
静态构建产物输出到 `out/`
|
||||||
6
next-env.d.ts
vendored
Normal file
6
next-env.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/image-types/global" />
|
||||||
|
/// <reference path="./.next/types/routes.d.ts" />
|
||||||
|
|
||||||
|
// NOTE: This file should not be edited
|
||||||
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||||
13
next.config.mjs
Normal file
13
next.config.mjs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
|
||||||
|
const projectRoot = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
output: "export",
|
||||||
|
trailingSlash: true,
|
||||||
|
outputFileTracingRoot: projectRoot
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
2069
package-lock.json
generated
Normal file
2069
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
package.json
Normal file
24
package.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "cyber-school-team-site",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"typecheck": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@ant-design/icons": "^5.6.1",
|
||||||
|
"@ant-design/nextjs-registry": "^1.0.2",
|
||||||
|
"antd": "^5.25.0",
|
||||||
|
"next": "^15.3.0",
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-dom": "^19.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.10.2",
|
||||||
|
"@types/react": "^19.0.0",
|
||||||
|
"@types/react-dom": "^19.0.0",
|
||||||
|
"typescript": "^5.8.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/assets/cyber-hero.png
Normal file
BIN
public/assets/cyber-hero.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/assets/green-datura-logo-mark.png
Normal file
BIN
public/assets/green-datura-logo-mark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 191 KiB |
BIN
public/assets/green-datura-logo.png
Normal file
BIN
public/assets/green-datura-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
BIN
public/assets/green-datura-wechat-qrcode.png
Normal file
BIN
public/assets/green-datura-wechat-qrcode.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 224 KiB |
605
src/app/globals.css
Normal file
605
src/app/globals.css
Normal file
@@ -0,0 +1,605 @@
|
|||||||
|
:root {
|
||||||
|
--primary: #16a34a;
|
||||||
|
--accent: #52c41a;
|
||||||
|
--cyan: #0f766e;
|
||||||
|
--title: #12301f;
|
||||||
|
--light-title: #12301f;
|
||||||
|
--muted: #52715d;
|
||||||
|
--light-muted: rgba(34, 69, 48, 0.82);
|
||||||
|
--line: #d9e3f0;
|
||||||
|
--glass-line: rgba(22, 101, 52, 0.16);
|
||||||
|
--page-bg: #edfdf2;
|
||||||
|
--surface: #ffffff;
|
||||||
|
--glass: rgba(255, 255, 255, 0.72);
|
||||||
|
--glass-strong: rgba(255, 255, 255, 0.86);
|
||||||
|
--dark: #e4f9ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
scroll-padding-top: 78px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 12% 8%, rgba(34, 197, 94, 0.18), transparent 30%),
|
||||||
|
radial-gradient(circle at 82% 24%, rgba(15, 118, 110, 0.1), transparent 28%),
|
||||||
|
linear-gradient(145deg, #f4fff7 0%, #dff7e8 48%, #f8fff9 100%);
|
||||||
|
color: var(--light-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-shell {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 20;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 24px;
|
||||||
|
height: 64px;
|
||||||
|
padding: 0 32px;
|
||||||
|
background: rgba(244, 255, 247, 0.84);
|
||||||
|
border-bottom: 1px solid var(--glass-line);
|
||||||
|
box-shadow:
|
||||||
|
0 18px 45px rgba(0, 0, 0, 0.2),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.16);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
min-width: 148px;
|
||||||
|
color: var(--title);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-logo {
|
||||||
|
display: block;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
object-fit: contain;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.24));
|
||||||
|
}
|
||||||
|
|
||||||
|
.kicker-logo {
|
||||||
|
display: block;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
object-fit: contain;
|
||||||
|
filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.28));
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor .ant-anchor {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor .ant-anchor-link {
|
||||||
|
padding-inline: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header .site-anchor .ant-anchor-link-title {
|
||||||
|
color: rgba(18, 48, 31, 0.72) !important;
|
||||||
|
font-weight: 600;
|
||||||
|
transition: color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header .site-anchor .ant-anchor-link-title:hover,
|
||||||
|
.site-header .site-anchor .ant-anchor-link-active > .ant-anchor-link-title {
|
||||||
|
color: #166534 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor .ant-anchor-ink {
|
||||||
|
background: rgba(82, 196, 26, 0.58);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-section {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 640px;
|
||||||
|
overflow: hidden;
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(244, 255, 247, 0.98) 0%, rgba(229, 250, 236, 0.9) 36%, rgba(220, 252, 231, 0.56) 74%, rgba(220, 252, 231, 0.24) 100%),
|
||||||
|
linear-gradient(180deg, rgba(244, 255, 247, 0.18) 0%, rgba(237, 253, 242, 0.82) 100%),
|
||||||
|
url("/assets/cyber-hero.png");
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-section::after {
|
||||||
|
position: absolute;
|
||||||
|
inset: auto 0 0;
|
||||||
|
height: 130px;
|
||||||
|
background: linear-gradient(180deg, rgba(245, 247, 251, 0), var(--page-bg));
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-inner,
|
||||||
|
.section-inner {
|
||||||
|
width: min(1180px, calc(100% - 48px));
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-inner {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
padding: 96px 0 118px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy {
|
||||||
|
max-width: 650px;
|
||||||
|
padding: 30px;
|
||||||
|
background: linear-gradient(135deg, rgba(255, 255, 255, 0.86), rgba(231, 250, 238, 0.68));
|
||||||
|
border: 1px solid var(--glass-line);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow:
|
||||||
|
0 26px 70px rgba(0, 0, 0, 0.24),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.18),
|
||||||
|
inset 0 0 24px rgba(255, 255, 255, 0.04);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy.ant-card,
|
||||||
|
.intro-copy.ant-card,
|
||||||
|
.stats-panel.ant-card,
|
||||||
|
.timeline-panel.ant-card {
|
||||||
|
color: var(--light-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-kicker,
|
||||||
|
.section-kicker,
|
||||||
|
.stats-kicker {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-kicker {
|
||||||
|
color: #15803d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title.ant-typography {
|
||||||
|
margin: 14px 0 18px;
|
||||||
|
color: var(--title);
|
||||||
|
font-size: 64px;
|
||||||
|
line-height: 1.06;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-text.ant-typography {
|
||||||
|
max-width: 590px;
|
||||||
|
color: rgba(34, 69, 48, 0.8);
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 1.72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-actions {
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-primary.ant-btn-color-primary {
|
||||||
|
color: #ffffff;
|
||||||
|
background: var(--primary);
|
||||||
|
border-color: var(--primary);
|
||||||
|
box-shadow: 0 8px 18px rgba(22, 163, 74, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-primary.ant-btn-color-primary:not(:disabled):not(.ant-btn-disabled):hover {
|
||||||
|
color: #ffffff;
|
||||||
|
background: #15803d;
|
||||||
|
border-color: #15803d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-secondary-button {
|
||||||
|
color: #166534;
|
||||||
|
border-color: rgba(22, 101, 52, 0.24);
|
||||||
|
background: rgba(255, 255, 255, 0.72);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding: 92px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section::before {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(rgba(22, 101, 52, 0.06) 1px, transparent 1px),
|
||||||
|
linear-gradient(90deg, rgba(22, 101, 52, 0.06) 1px, transparent 1px);
|
||||||
|
background-size: 44px 44px;
|
||||||
|
mask-image: linear-gradient(180deg, transparent, #000 16%, #000 84%, transparent);
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading {
|
||||||
|
position: relative;
|
||||||
|
max-width: 720px;
|
||||||
|
margin-bottom: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading .ant-typography {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading h2.ant-typography,
|
||||||
|
.wechat-copy h2.ant-typography {
|
||||||
|
margin-top: 12px;
|
||||||
|
color: var(--light-title);
|
||||||
|
font-size: 38px;
|
||||||
|
line-height: 1.18;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading .ant-typography + .ant-typography,
|
||||||
|
.wechat-copy .ant-typography + .ant-typography {
|
||||||
|
margin-top: 14px;
|
||||||
|
color: var(--light-muted);
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.78;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-section {
|
||||||
|
background: linear-gradient(180deg, rgba(237, 253, 242, 0.96), rgba(220, 248, 230, 0.92));
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-copy {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100%;
|
||||||
|
padding: 34px;
|
||||||
|
color: var(--light-muted);
|
||||||
|
background: var(--glass);
|
||||||
|
border: 1px solid var(--glass-line);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow:
|
||||||
|
0 22px 55px rgba(0, 0, 0, 0.18),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.14);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-copy .ant-typography {
|
||||||
|
color: var(--light-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-copy h3.ant-typography {
|
||||||
|
margin: 0 0 18px;
|
||||||
|
color: var(--light-title);
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-copy p.ant-typography {
|
||||||
|
color: var(--light-muted);
|
||||||
|
line-height: 1.78;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-grid .ant-tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 32px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
background: rgba(34, 197, 94, 0.14);
|
||||||
|
border-color: rgba(82, 196, 26, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.culture-grid {
|
||||||
|
margin-top: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.culture-item {
|
||||||
|
padding: 16px;
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
border: 1px solid rgba(22, 101, 52, 0.12);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||||
|
color: var(--light-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.culture-icon {
|
||||||
|
display: inline-grid;
|
||||||
|
place-items: center;
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
color: #166534;
|
||||||
|
background: rgba(82, 196, 26, 0.16);
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.culture-item strong {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
color: var(--light-title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.culture-item p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--light-muted);
|
||||||
|
line-height: 1.65;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-panel {
|
||||||
|
display: grid;
|
||||||
|
gap: 16px;
|
||||||
|
height: 100%;
|
||||||
|
padding: 30px;
|
||||||
|
color: #ffffff;
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(22, 163, 74, 0.86), rgba(15, 118, 110, 0.52)),
|
||||||
|
rgba(255, 255, 255, 0.1);
|
||||||
|
border: 1px solid var(--glass-line);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow:
|
||||||
|
0 24px 55px rgba(0, 0, 0, 0.2),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.16);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-kicker {
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-tile {
|
||||||
|
min-height: 112px;
|
||||||
|
padding: 20px;
|
||||||
|
background: rgba(255, 255, 255, 0.16);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.26);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-tile .ant-card-body,
|
||||||
|
.stat-tile-content {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-tile .ant-statistic-title,
|
||||||
|
.stat-tile .ant-statistic-content {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-tile .ant-statistic-title {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.honors-section {
|
||||||
|
background:
|
||||||
|
linear-gradient(180deg, rgba(228, 249, 236, 0.94) 0%, rgba(239, 253, 244, 0.98) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-panel {
|
||||||
|
position: relative;
|
||||||
|
padding: 34px 34px 10px;
|
||||||
|
background: var(--glass);
|
||||||
|
border: 1px solid var(--glass-line);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow:
|
||||||
|
0 22px 55px rgba(0, 0, 0, 0.18),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.14);
|
||||||
|
backdrop-filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
display: grid;
|
||||||
|
gap: 6px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-year {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item strong {
|
||||||
|
color: var(--light-title);
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--light-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-section {
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(220, 252, 231, 0.86), rgba(209, 250, 229, 0.74)),
|
||||||
|
var(--dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-inner {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-copy {
|
||||||
|
max-width: 660px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-copy .section-kicker,
|
||||||
|
.wechat-copy h2.ant-typography {
|
||||||
|
color: var(--title);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-copy .ant-typography + .ant-typography {
|
||||||
|
color: var(--light-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-card {
|
||||||
|
flex: 0 0 320px;
|
||||||
|
padding: 28px;
|
||||||
|
background: rgba(255, 255, 255, 0.88);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.45);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow:
|
||||||
|
0 22px 55px rgba(0, 0, 0, 0.24),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-qrcode-image {
|
||||||
|
display: block;
|
||||||
|
width: min(238px, 100%);
|
||||||
|
height: auto;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-card span {
|
||||||
|
color: var(--muted);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-footer {
|
||||||
|
color: rgba(18, 48, 31, 0.72);
|
||||||
|
text-align: center;
|
||||||
|
background: #dcfce7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.site-header {
|
||||||
|
padding: 0 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand {
|
||||||
|
min-width: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor {
|
||||||
|
overflow-x: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor .ant-anchor {
|
||||||
|
min-width: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor .ant-anchor-link {
|
||||||
|
padding-inline: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-section {
|
||||||
|
min-height: 620px;
|
||||||
|
background-position: 60% center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title.ant-typography {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-text.ant-typography {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
padding: 72px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading h2.ant-typography,
|
||||||
|
.wechat-copy h2.ant-typography {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-inner {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-card {
|
||||||
|
flex-basis: auto;
|
||||||
|
max-width: 340px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 560px) {
|
||||||
|
html {
|
||||||
|
scroll-padding-top: 68px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-header {
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-anchor .ant-anchor-link {
|
||||||
|
padding-inline: 8px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-inner,
|
||||||
|
.section-inner {
|
||||||
|
width: min(100% - 32px, 1180px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-section {
|
||||||
|
min-height: 590px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-inner {
|
||||||
|
padding: 74px 0 96px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title.ant-typography {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-text.ant-typography {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-copy,
|
||||||
|
.stats-panel,
|
||||||
|
.timeline-panel {
|
||||||
|
padding: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading h2.ant-typography,
|
||||||
|
.wechat-copy h2.ant-typography {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.culture-item-content {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wechat-card {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/app/layout.tsx
Normal file
29
src/app/layout.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
import { AntdRegistry } from "@ant-design/nextjs-registry";
|
||||||
|
import "antd/dist/reset.css";
|
||||||
|
import "./globals.css";
|
||||||
|
import { Providers } from "./providers";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Green_Datura 官网",
|
||||||
|
description: "展示福州大学至诚学院 Green_Datura 网络安全俱乐部简介、荣誉成果与微信公众号入口。",
|
||||||
|
icons: {
|
||||||
|
icon: "/assets/green-datura-logo-mark.png"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<body>
|
||||||
|
<AntdRegistry>
|
||||||
|
<Providers>{children}</Providers>
|
||||||
|
</AntdRegistry>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
69
src/app/page.tsx
Normal file
69
src/app/page.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ArrowRightOutlined } from "@ant-design/icons";
|
||||||
|
import { Anchor, Button, Card, Flex, Layout, Space, Typography } from "antd";
|
||||||
|
import type { AnchorProps } from "antd";
|
||||||
|
import { Honors } from "@/components/Honors";
|
||||||
|
import { TeamIntro } from "@/components/TeamIntro";
|
||||||
|
import { WeChatSection } from "@/components/WeChatSection";
|
||||||
|
|
||||||
|
const { Content, Footer, Header } = Layout;
|
||||||
|
const { Paragraph, Title } = Typography;
|
||||||
|
|
||||||
|
const navItems: AnchorProps["items"] = [
|
||||||
|
{ key: "home", href: "#home", title: "首页" },
|
||||||
|
{ key: "intro", href: "#intro", title: "俱乐部简介" },
|
||||||
|
{ key: "honors", href: "#honors", title: "荣誉成果" },
|
||||||
|
{ key: "wechat", href: "#wechat", title: "微信公众号" }
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<Layout className="site-shell">
|
||||||
|
<Header className="site-header">
|
||||||
|
<a className="brand" href="#home" aria-label="Green_Datura 首页">
|
||||||
|
<img className="brand-logo" src="/assets/green-datura-logo-mark.png" alt="" />
|
||||||
|
<span>Green_Datura</span>
|
||||||
|
</a>
|
||||||
|
<Anchor
|
||||||
|
affix={false}
|
||||||
|
direction="horizontal"
|
||||||
|
targetOffset={76}
|
||||||
|
items={navItems}
|
||||||
|
className="site-anchor"
|
||||||
|
/>
|
||||||
|
</Header>
|
||||||
|
|
||||||
|
<Content>
|
||||||
|
<section id="home" className="hero-section">
|
||||||
|
<div className="hero-inner">
|
||||||
|
<Card className="hero-copy" variant="borderless" styles={{ body: { padding: 0 } }}>
|
||||||
|
<Space className="hero-kicker" size={8}>
|
||||||
|
<img className="kicker-logo" src="/assets/green-datura-logo-mark.png" alt="" />
|
||||||
|
福州大学至诚学院
|
||||||
|
</Space>
|
||||||
|
<Title className="hero-title">Green_Datura</Title>
|
||||||
|
<Paragraph className="hero-text">
|
||||||
|
成立于 2020 年 3 月的至诚学院网络安全俱乐部,寓意生生不息的希望,面向 CTF、漏洞挖掘与校园安全实践持续成长。
|
||||||
|
</Paragraph>
|
||||||
|
<Flex gap={12} wrap="wrap" className="hero-actions">
|
||||||
|
<Button type="primary" size="large" href="#intro" icon={<ArrowRightOutlined />}>
|
||||||
|
了解俱乐部
|
||||||
|
</Button>
|
||||||
|
<Button size="large" href="#honors" className="hero-secondary-button">
|
||||||
|
查看荣誉
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<TeamIntro />
|
||||||
|
<Honors />
|
||||||
|
<WeChatSection />
|
||||||
|
</Content>
|
||||||
|
|
||||||
|
<Footer className="site-footer">Green_Datura · 生生不息,代代传承</Footer>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
48
src/app/providers.tsx
Normal file
48
src/app/providers.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import type { ReactNode } from "react";
|
||||||
|
import { ConfigProvider } from "antd";
|
||||||
|
import zhCN from "antd/locale/zh_CN";
|
||||||
|
|
||||||
|
type ProvidersProps = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Providers({ children }: ProvidersProps) {
|
||||||
|
return (
|
||||||
|
<ConfigProvider
|
||||||
|
locale={zhCN}
|
||||||
|
theme={{
|
||||||
|
token: {
|
||||||
|
colorPrimary: "#16a34a",
|
||||||
|
colorSuccess: "#52c41a",
|
||||||
|
colorText: "#12301f",
|
||||||
|
colorBgLayout: "#edfdf2",
|
||||||
|
colorBgContainer: "rgba(255, 255, 255, 0.82)",
|
||||||
|
colorBorder: "rgba(22, 101, 52, 0.16)",
|
||||||
|
borderRadius: 8,
|
||||||
|
fontFamily:
|
||||||
|
'Inter, "Segoe UI", "PingFang SC", "Microsoft YaHei", Arial, sans-serif'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Button: {
|
||||||
|
borderRadius: 8,
|
||||||
|
controlHeight: 42
|
||||||
|
},
|
||||||
|
Card: {
|
||||||
|
borderRadiusLG: 8
|
||||||
|
},
|
||||||
|
Anchor: {
|
||||||
|
linkPaddingBlock: 8,
|
||||||
|
linkPaddingInlineStart: 12
|
||||||
|
},
|
||||||
|
Tag: {
|
||||||
|
borderRadiusSM: 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
45
src/components/Honors.tsx
Normal file
45
src/components/Honors.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Card, Space, Timeline, Typography } from "antd";
|
||||||
|
import { TrophyOutlined } from "@ant-design/icons";
|
||||||
|
import { timelineHonors, type HonorLevel } from "@/data/honors";
|
||||||
|
|
||||||
|
const { Title } = Typography;
|
||||||
|
|
||||||
|
const levelColor: Record<HonorLevel, string> = {
|
||||||
|
attackDefense: "#52c41a",
|
||||||
|
ctf: "#1677ff",
|
||||||
|
vulnerability: "#13c2c2",
|
||||||
|
campus: "#faad14"
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Honors() {
|
||||||
|
const timelineItems = timelineHonors.map((honor) => ({
|
||||||
|
color: levelColor[honor.level],
|
||||||
|
children: (
|
||||||
|
<div className="timeline-item">
|
||||||
|
<span className="timeline-year">{honor.year}</span>
|
||||||
|
<strong>{honor.event}</strong>
|
||||||
|
<p>{honor.award}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id="honors" className="section honors-section">
|
||||||
|
<div className="section-inner">
|
||||||
|
<div className="section-heading">
|
||||||
|
<Space className="section-kicker" size={8}>
|
||||||
|
<TrophyOutlined />
|
||||||
|
荣誉成果
|
||||||
|
</Space>
|
||||||
|
<Title level={2}>用成绩记录持续进步</Title>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card className="timeline-panel" variant="borderless" styles={{ body: { padding: 0 } }}>
|
||||||
|
<Timeline mode="left" items={timelineItems} />
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
116
src/components/TeamIntro.tsx
Normal file
116
src/components/TeamIntro.tsx
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Card, Col, Flex, Row, Space, Statistic, Tag, Typography } from "antd";
|
||||||
|
import {
|
||||||
|
AimOutlined,
|
||||||
|
BugOutlined,
|
||||||
|
CodeOutlined,
|
||||||
|
ExperimentOutlined,
|
||||||
|
TeamOutlined
|
||||||
|
} from "@ant-design/icons";
|
||||||
|
|
||||||
|
const { Paragraph, Title } = Typography;
|
||||||
|
|
||||||
|
const directions = [
|
||||||
|
"WEB安全研究",
|
||||||
|
"渗透测试",
|
||||||
|
"漏洞挖掘",
|
||||||
|
"代码审计",
|
||||||
|
"二进制安全",
|
||||||
|
"移动安全",
|
||||||
|
"数据安全",
|
||||||
|
"密码安全"
|
||||||
|
];
|
||||||
|
|
||||||
|
const stats = [
|
||||||
|
{ title: "成立时间", value: "2020年3月" },
|
||||||
|
{ title: "研究方向", value: "8+" },
|
||||||
|
{ title: "CNVD上报", value: "20+" }
|
||||||
|
];
|
||||||
|
|
||||||
|
const cultureItems = [
|
||||||
|
{ icon: <AimOutlined />, title: "生生不息", text: "Green_Datura 寓意生生不息的希望,俱乐部希望在至诚延续、代代传承。" },
|
||||||
|
{ icon: <ExperimentOutlined />, title: "实战实践", text: "参与国家级、省级攻防演练、CTF 赛事与漏洞响应平台,把学习转化为真实安全能力。" },
|
||||||
|
{ icon: <TeamOutlined />, title: "校园守护", text: "在学院网信办老师协作下,参与维护学校网络安全。" }
|
||||||
|
];
|
||||||
|
|
||||||
|
export function TeamIntro() {
|
||||||
|
return (
|
||||||
|
<section id="intro" className="section intro-section">
|
||||||
|
<div className="section-inner">
|
||||||
|
<div className="section-heading">
|
||||||
|
<Space className="section-kicker" size={8}>
|
||||||
|
<BugOutlined />
|
||||||
|
俱乐部简介
|
||||||
|
</Space>
|
||||||
|
<Title level={2}>富有活力的年轻安全团队</Title>
|
||||||
|
<Paragraph>
|
||||||
|
Green_Datura 团队于 2020 年成立,由福州大学至诚学院的网络安全爱好者组成,在计算机工程系支持下发展,并由黄巧云老师担任指导。
|
||||||
|
团队长期参与攻防演练、CTF 赛事与校园网络安全维护。
|
||||||
|
</Paragraph>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Row gutter={[24, 24]} align="stretch">
|
||||||
|
<Col xs={24} lg={14}>
|
||||||
|
<Card className="intro-copy" variant="borderless" styles={{ body: { padding: 0 } }}>
|
||||||
|
<Title level={3}>研究方向</Title>
|
||||||
|
<Flex wrap="wrap" gap={10} className="tag-grid">
|
||||||
|
{directions.map((item) => (
|
||||||
|
<Tag key={item} color="blue">
|
||||||
|
{item}
|
||||||
|
</Tag>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
<Paragraph>
|
||||||
|
目前俱乐部成员研究方向包括但不限于 WEB 安全、渗透测试、漏洞挖掘、代码审计、二进制安全、移动安全、数据安全和密码安全等。团队曾向腾讯、美团、华为、
|
||||||
|
微博、BOSS直聘、京东、58同城、百卓网络、星网锐捷、嘀嗒出行和厦门航空等平台报告漏洞,并在国家信息安全漏洞库(CNVD)上报超过 20 项。
|
||||||
|
</Paragraph>
|
||||||
|
<Flex vertical gap={14} className="culture-grid">
|
||||||
|
{cultureItems.map((item) => (
|
||||||
|
<Card
|
||||||
|
className="culture-item"
|
||||||
|
key={item.title}
|
||||||
|
size="small"
|
||||||
|
variant="borderless"
|
||||||
|
styles={{ body: { padding: 0 } }}
|
||||||
|
>
|
||||||
|
<Flex gap={14} align="flex-start" className="culture-item-content">
|
||||||
|
<span className="culture-icon">{item.icon}</span>
|
||||||
|
<div>
|
||||||
|
<strong>{item.title}</strong>
|
||||||
|
<p>{item.text}</p>
|
||||||
|
</div>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={24} lg={10}>
|
||||||
|
<Card className="stats-panel" variant="borderless" styles={{ body: { padding: 0 } }}>
|
||||||
|
<Flex vertical gap={16}>
|
||||||
|
<Space className="stats-kicker" size={8}>
|
||||||
|
<CodeOutlined />
|
||||||
|
Club Profile
|
||||||
|
</Space>
|
||||||
|
{stats.map((item) => (
|
||||||
|
<Card
|
||||||
|
className="stat-tile"
|
||||||
|
key={item.title}
|
||||||
|
size="small"
|
||||||
|
variant="borderless"
|
||||||
|
styles={{ body: { padding: 0 } }}
|
||||||
|
>
|
||||||
|
<Flex align="center" className="stat-tile-content">
|
||||||
|
<Statistic title={item.title} value={item.value} />
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
56
src/components/WeChatSection.tsx
Normal file
56
src/components/WeChatSection.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Button, Card, Flex, Image, Space, Typography } from "antd";
|
||||||
|
import { LinkOutlined, WechatOutlined } from "@ant-design/icons";
|
||||||
|
|
||||||
|
const { Paragraph, Title } = Typography;
|
||||||
|
|
||||||
|
const WECHAT_URL =
|
||||||
|
"https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=Mzg4NDY5NjIyNw==#wechat_redirect";
|
||||||
|
|
||||||
|
export function WeChatSection() {
|
||||||
|
return (
|
||||||
|
<section id="wechat" className="section wechat-section">
|
||||||
|
<Flex className="section-inner wechat-inner" align="center" gap={54}>
|
||||||
|
<div className="wechat-copy">
|
||||||
|
<Space className="section-kicker" size={8}>
|
||||||
|
<WechatOutlined />
|
||||||
|
微信公众号
|
||||||
|
</Space>
|
||||||
|
<Title level={2}>关注招新通知与技术分享</Title>
|
||||||
|
<Paragraph>
|
||||||
|
欢迎关注 Green_Datura 微信公众号,获取比赛资讯、技术分享、招新通知以及团队动态。俱乐部每年面向大一、大二招新,欢迎对网络安全感兴趣并愿意投入时间精力的同学加入。
|
||||||
|
</Paragraph>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
href={WECHAT_URL}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
icon={<LinkOutlined />}
|
||||||
|
>
|
||||||
|
关注公众号
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card
|
||||||
|
className="wechat-card"
|
||||||
|
aria-label="微信公众号二维码"
|
||||||
|
variant="borderless"
|
||||||
|
styles={{ body: { padding: 0 } }}
|
||||||
|
>
|
||||||
|
<Flex vertical align="center" gap={16}>
|
||||||
|
<Image
|
||||||
|
src="/assets/green-datura-wechat-qrcode.png"
|
||||||
|
alt="Green_Datura 微信公众号二维码"
|
||||||
|
width={238}
|
||||||
|
preview={false}
|
||||||
|
className="wechat-qrcode-image"
|
||||||
|
/>
|
||||||
|
<span>扫码访问公众号入口</span>
|
||||||
|
</Flex>
|
||||||
|
</Card>
|
||||||
|
</Flex>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
101
src/data/honors.ts
Normal file
101
src/data/honors.ts
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
export type HonorLevel = "attackDefense" | "ctf" | "vulnerability" | "campus";
|
||||||
|
|
||||||
|
export type Honor = {
|
||||||
|
year: string;
|
||||||
|
event: string;
|
||||||
|
award: string;
|
||||||
|
level: HonorLevel;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const timelineHonors: Honor[] = [
|
||||||
|
{
|
||||||
|
year: "2025年11月26日",
|
||||||
|
event: "2025第九届一带一路暨金砖国家技能发展与技术创新大赛 - 第二届网络安全防护治理实战技能区域赛",
|
||||||
|
award: "省级一等奖",
|
||||||
|
level: "ctf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024-2025年",
|
||||||
|
event: "第五届福建省“闽盾杯”网络安全空间大赛",
|
||||||
|
award: "二等奖 1 项,三等奖 1 项",
|
||||||
|
level: "ctf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024年12月15日",
|
||||||
|
event: "2024深育杯大学生网络安全大赛网络攻防赛道",
|
||||||
|
award: "国家级特等奖",
|
||||||
|
level: "ctf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024年",
|
||||||
|
event: "“数字中国创新大赛”数字安全赛道",
|
||||||
|
award: "铜奖 1 项,优秀奖 3 项",
|
||||||
|
level: "ctf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024年",
|
||||||
|
event: "“闽盾-2024”网络安全攻防演练",
|
||||||
|
award: "优秀攻击方",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024年",
|
||||||
|
event: "福建省文旅厅攻防演练",
|
||||||
|
award: "第二名",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024年",
|
||||||
|
event: "眉山市攻防护网行动",
|
||||||
|
award: "攻击队排名第六,得分超过 24,000 分",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2024年",
|
||||||
|
event: "福州网信市护行动",
|
||||||
|
award: "三等奖,得分超过 20,000 分",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023-2024年",
|
||||||
|
event: "第四届福建省“闽盾杯”网络安全空间大赛",
|
||||||
|
award: "二等奖 1 项,三等奖 1 项",
|
||||||
|
level: "ctf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023-2024年",
|
||||||
|
event: "第 20 届信息安全与对抗技术竞赛",
|
||||||
|
award: "个人挑战赛一等奖 8 项,另获多项二等奖、三等奖",
|
||||||
|
level: "ctf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023年",
|
||||||
|
event: "交通运输部海事局攻防演练",
|
||||||
|
award: "第一名",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023年",
|
||||||
|
event: "福建省生态环境护网行动(红队)",
|
||||||
|
award: "总分超过 7,000 分,排名第二",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023年",
|
||||||
|
event: "福建省教育攻防护网行动(红队)",
|
||||||
|
award: "高校组二等奖",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023年",
|
||||||
|
event: "“闽盾-2023”网络安全攻防演练",
|
||||||
|
award: "优秀攻击方",
|
||||||
|
level: "attackDefense"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
year: "2023年",
|
||||||
|
event: "福州市攻防护网行动(红队)",
|
||||||
|
award: "攻击队三等奖,得分超过 10,000 分",
|
||||||
|
level: "attackDefense"
|
||||||
|
}
|
||||||
|
];
|
||||||
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user