feat(core): 初始化项目基础架构和CMS功能模块

- 添加Docker相关配置文件(.dockerignore, .env.example, .gitignore)
- 实现服务端API代理功能,支持文件、模块和服务器API转发
- 创建文章详情页、栏目文章列表页和单页内容展示页面
- 集成Ant Design Vue组件库并实现SSR样式提取功能
- 定义API响应数据结构类型和应用布局组件
- 开发开发者应用中心和文章管理页面
- 实现CMS导航菜单获取和多租户切换功能
This commit is contained in:
2026-01-27 00:14:08 +08:00
commit 775841eed3
315 changed files with 47072 additions and 0 deletions

507
app/pages/index.vue Normal file
View File

@@ -0,0 +1,507 @@
<template>
<main class="home">
<section class="mx-auto max-w-screen-xl px-4 py-6">
<div class="grid grid-cols-12 gap-6">
<div class="col-span-12 lg:col-span-7">
<div class="panel">
<a-image :src="featured.image" :preview="false" class="featured-image" />
<div class="p-4">
<div class="featured-title">{{ featured.title }}</div>
<div class="featured-meta">{{ featured.date }}</div>
</div>
</div>
</div>
<div class="col-span-12 lg:col-span-5">
<div class="panel notice">
<div class="notice-head">
<div class="notice-title">
<NotificationOutlined />
公告
</div>
<a class="notice-more" href="#" @click.prevent>更多</a>
</div>
<div class="notice-list">
<a
v-for="n in notices"
:key="n.title"
class="notice-item"
href="#"
@click.prevent
>
<div class="notice-item-title">{{ n.title }}</div>
<div class="notice-item-desc">{{ n.desc }}</div>
</a>
</div>
</div>
</div>
</div>
<div class="mt-6 grid grid-cols-12 gap-6">
<div class="col-span-12 lg:col-span-7">
<div class="panel">
<div class="section-pill">
<span class="pill-left">
<FileTextOutlined />
申报指南
</span>
<span class="pill-right">Declaration Guide</span>
</div>
<div class="mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2">
<a-card
v-for="g in guides"
:key="g.title"
class="guide-card"
:bordered="true"
hoverable
@click="navigateTo(g.to)"
>
<a-space>
<a-avatar :size="44" class="guide-icon">
<component :is="g.icon" />
</a-avatar>
<div>
<div class="guide-title">{{ g.title }}</div>
<div class="guide-desc">{{ g.desc }}</div>
</div>
</a-space>
</a-card>
</div>
</div>
</div>
<div class="col-span-12 lg:col-span-5">
<div class="panel login">
<div class="login-hero">
<div class="login-hero-title">破产重整债权申报系统</div>
<div class="login-hero-sub">SUBMIT REQUIREMENTS</div>
</div>
<div class="p-4">
<a-space direction="vertical" class="w-full" size="middle">
<a-button type="primary" block size="large" @click="navigateTo('/login')">
<template #icon><LoginOutlined /></template>
用户登录申报
</a-button>
<a-button block size="large" @click="navigateTo('/create-app')">
<template #icon><UserAddOutlined /></template>
新用户注册申报
</a-button>
<div class="flex items-center justify-between text-sm text-gray-500">
<span>申报审核系统</span>
<a href="#" class="text-red-600" @click.prevent>忘记密码</a>
</div>
</a-space>
</div>
</div>
</div>
</div>
</section>
<section class="banner">
<div class="mx-auto max-w-screen-xl px-4 py-10">
<div class="banner-title">致力于专业破产事务服务</div>
</div>
</section>
<section class="mx-auto max-w-screen-xl px-4 py-10">
<div class="section-title">
<div class="section-title-main">新闻资讯</div>
<div class="section-title-sub">NEWS INFORMATION</div>
</div>
<div class="mt-6 grid grid-cols-12 gap-6">
<div v-for="c in columns" :key="c.title" class="col-span-12 lg:col-span-4">
<div class="panel">
<div class="column-head">
<div class="column-title">{{ c.title }}</div>
<a href="#" class="column-more" @click.prevent>更多 +</a>
</div>
<div class="column-list">
<a
v-for="it in c.items"
:key="it"
class="column-item"
href="#"
@click.prevent
>
{{ it }}
</a>
</div>
</div>
</div>
</div>
<div class="mt-10">
<div class="section-title">
<div class="section-title-main">典型案例</div>
<div class="section-title-sub">CLASSIC CASE</div>
</div>
<div class="mt-6 grid grid-cols-12 gap-6">
<a-card
v-for="c in cases"
:key="c.title"
hoverable
class="case-card col-span-12 sm:col-span-6 lg:col-span-3"
@click="navigateTo(c.to)"
>
<template #cover>
<a-image :src="c.image" :preview="false" class="case-image" />
</template>
<a-typography-title :level="5" class="!mb-2 case-title">{{ c.title }}</a-typography-title>
<div class="case-meta">{{ c.date }}</div>
</a-card>
</div>
</div>
</section>
</main>
</template>
<script setup lang="ts">
import {
FileTextOutlined,
LoginOutlined,
NotificationOutlined,
ProfileOutlined,
SafetyCertificateOutlined,
UserAddOutlined
} from '@ant-design/icons-vue'
const featured = {
image:
'https://images.unsplash.com/photo-1521737604893-d14cc237f11d?auto=format&fit=crop&w=1400&q=80',
title: '行于思清算公司受指定担任广西民族包装有限公司管理人',
date: '2023-10-11'
}
const notices = [
{
title: '关于公开招募破产清算管理主体框架及维修施工单位的公告',
desc: '南宁市中级人民法院根据有关规定...'
},
{
title: '钦州市王明年丰全仓储有限公司重整投资人招募公告',
desc: '钦州市王明年丰全仓储有限公司...'
},
{
title: '钦州市王明年丰全仓储有限公司 预重整债权申报公告',
desc: '债权申报相关材料及申报途径...'
},
{
title: '钦州市王明年丰全仓储有限公司 预重整债权申报公告(补充)',
desc: '补充说明及常见问题...'
}
]
const guides = [
{ title: '线上实名认证指南', desc: '快速完成实名认证', to: '/flow', icon: ProfileOutlined },
{ title: '债权人提交材料指南', desc: '材料清单与提交规范', to: '/articles', icon: FileTextOutlined },
{ title: '债权人网上申报指南', desc: '在线申报流程说明', to: '/login', icon: SafetyCertificateOutlined },
{ title: '公司自主清算债权登记材料范本', desc: '模板下载与填写说明', to: '/deploy', icon: FileTextOutlined }
]
const columns = [
{
title: '新闻动态',
items: [
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...'
]
},
{
title: '法律法规',
items: [
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...'
]
},
{
title: '权威发布',
items: [
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...',
'标题新闻标题新闻标题新闻标题新闻标题...'
]
}
]
const cases = [
{
title: '广西南院审理的印象刘三姐重整案...',
date: '2023-10-17',
to: '/articles',
image:
'https://images.unsplash.com/photo-1450101499163-c8848c66ca85?auto=format&fit=crop&w=900&q=80'
},
{
title: '广西南院审理的印象刘三姐重整案...',
date: '2023-10-17',
to: '/articles',
image:
'https://images.unsplash.com/photo-1520607162513-77705c0f0d4a?auto=format&fit=crop&w=900&q=80'
},
{
title: '广西南院审理的印象刘三姐重整案...',
date: '2023-10-17',
to: '/articles',
image:
'https://images.unsplash.com/photo-1521790797524-b2497295b8a0?auto=format&fit=crop&w=900&q=80'
},
{
title: '广西南院审理的印象刘三姐重整案...',
date: '2023-10-17',
to: '/articles',
image:
'https://images.unsplash.com/photo-1554224155-6726b3ff858f?auto=format&fit=crop&w=900&q=80'
}
]
</script>
<style scoped>
.home {
background: #f4f6f8;
}
.panel {
background: #fff;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 10px;
overflow: hidden;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.04);
}
.featured-image :deep(img) {
width: 100%;
height: 360px;
object-fit: cover;
}
.featured-title {
font-size: 16px;
font-weight: 700;
color: rgba(0, 0, 0, 0.88);
}
.featured-meta {
margin-top: 6px;
font-size: 12px;
color: rgba(0, 0, 0, 0.5);
}
.notice {
height: 100%;
}
.notice-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
background: linear-gradient(90deg, #c30000, #e11d48);
color: #fff;
}
.notice-title {
display: inline-flex;
align-items: center;
gap: 8px;
font-weight: 800;
}
.notice-more {
color: rgba(255, 255, 255, 0.9);
font-size: 12px;
}
.notice-list {
padding: 10px 14px 14px;
}
.notice-item {
display: block;
padding: 10px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
text-decoration: none;
}
.notice-item:last-child {
border-bottom: 0;
}
.notice-item-title {
font-size: 13px;
font-weight: 700;
color: rgba(0, 0, 0, 0.85);
line-height: 1.35;
}
.notice-item-desc {
margin-top: 4px;
font-size: 12px;
color: rgba(0, 0, 0, 0.55);
line-height: 1.4;
}
.section-pill {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
border-radius: 9999px;
background: linear-gradient(90deg, #c30000, #e11d48);
color: #fff;
font-weight: 800;
}
.pill-left {
display: inline-flex;
align-items: center;
gap: 8px;
}
.pill-right {
font-weight: 700;
font-size: 12px;
opacity: 0.9;
}
.guide-card {
border-radius: 10px;
}
.guide-icon {
background: rgba(195, 0, 0, 0.1);
color: #c30000;
}
.guide-title {
font-size: 14px;
font-weight: 800;
color: rgba(0, 0, 0, 0.88);
}
.guide-desc {
margin-top: 3px;
font-size: 12px;
color: rgba(0, 0, 0, 0.55);
}
.login-hero {
padding: 18px 16px;
background:
radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.22), transparent 55%),
linear-gradient(90deg, #c30000, #e11d48);
color: #fff;
}
.login-hero-title {
font-size: 18px;
font-weight: 900;
}
.login-hero-sub {
margin-top: 6px;
font-size: 12px;
letter-spacing: 0.12em;
opacity: 0.9;
}
.banner {
background:
radial-gradient(circle at 20% 30%, rgba(195, 0, 0, 0.18), transparent 55%),
linear-gradient(180deg, #ffffff, #f8fafc);
border-top: 1px solid rgba(0, 0, 0, 0.06);
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.banner-title {
text-align: center;
font-size: 28px;
font-weight: 900;
color: #c30000;
}
.section-title {
text-align: center;
}
.section-title-main {
font-size: 18px;
font-weight: 900;
color: rgba(0, 0, 0, 0.88);
}
.section-title-sub {
margin-top: 4px;
font-size: 12px;
letter-spacing: 0.12em;
color: rgba(0, 0, 0, 0.45);
}
.column-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 14px 10px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.column-title {
font-weight: 900;
color: rgba(0, 0, 0, 0.88);
}
.column-more {
font-size: 12px;
color: rgba(195, 0, 0, 0.95);
text-decoration: none;
}
.column-list {
padding: 10px 14px 14px;
}
.column-item {
display: block;
padding: 8px 0;
font-size: 13px;
color: rgba(0, 0, 0, 0.78);
text-decoration: none;
border-bottom: 1px dashed rgba(0, 0, 0, 0.08);
}
.column-item:last-child {
border-bottom: 0;
}
.case-card {
border-radius: 10px;
overflow: hidden;
}
.case-image :deep(img) {
width: 100%;
height: 160px;
object-fit: cover;
}
.case-title {
color: rgba(195, 0, 0, 0.95);
}
.case-meta {
font-size: 12px;
color: rgba(0, 0, 0, 0.5);
}
</style>