更新首页

This commit is contained in:
2026-09-11 12:25:38 +08:00
parent 9e24153eac
commit c29c3be942
326 changed files with 6564 additions and 44307 deletions
+126 -682
View File
@@ -1,16 +1,9 @@
<template>
<div class="about-subpage">
<!-- 顶部 Banner -->
<div class="about-banner">
<div class="mx-auto max-w-screen-xl px-4">
<h1 class="banner-title">关于我们</h1>
<p class="banner-desc">广西决策咨询网 · 汇聚智慧服务决策</p>
</div>
</div>
<!-- <div class="about-banner"></div>-->
<div class="mx-auto max-w-screen-xl px-4 py-8">
<a-row :gutter="[32, 0]">
<!-- 左侧导航 -->
<a-col :xs="24" :lg="6">
<div class="side-nav">
<div class="side-nav-title">关于我们</div>
@@ -27,227 +20,24 @@
</div>
</a-col>
<!-- 右侧内容 -->
<a-col :xs="24" :lg="18">
<!-- 学会简介 -->
<div v-show="currentSection === 'intro'" class="content-card">
<h2 class="content-title">学会简介</h2>
<div class="content-body">
<p>广西决策咨询学会广西决策咨询中心是在中共广西壮族自治区委员会广西壮族自治区人民政府的领导下由全区各高校科研机构政府部门从事决策咨询研究的专家学者和实际工作者自愿组成的学术性非营利性社会组织</p>
<p>学会以服务党政决策为核心使命围绕广西经济社会发展中的重大问题开展战略性综合性前瞻性研究为自治区党委政府重大决策提供智力支撑</p>
<div class="info-highlight">
<div class="highlight-item">
<div class="highlight-number">200+</div>
<div class="highlight-label">签约专家</div>
</div>
<div class="highlight-item">
<div class="highlight-number">20</div>
<div class="highlight-label">服务历史</div>
</div>
<div class="highlight-item">
<div class="highlight-number">1000+</div>
<div class="highlight-label">咨询报告</div>
</div>
<div class="highlight-item">
<div class="highlight-number">50+</div>
<div class="highlight-label">重大课题</div>
</div>
</div>
<h3>主要职能</h3>
<div class="function-list">
<div class="function-item" v-for="item in mainFunctions" :key="item.title">
<div class="function-icon">{{ item.icon }}</div>
<div class="function-content">
<h4>{{ item.title }}</h4>
<p>{{ item.desc }}</p>
</div>
</div>
</div>
<div class="content-card">
<div v-if="loading" class="content-loading">
<a-skeleton active :paragraph="{ rows: 10 }" />
</div>
</div>
<!-- 组织机构 -->
<div v-show="currentSection === 'organization'" class="content-card">
<h2 class="content-title">组织机构</h2>
<div class="content-body">
<div class="org-chart">
<div class="org-level org-top">
<div class="org-box org-primary">理事会</div>
</div>
<div class="org-connector"></div>
<div class="org-level org-mid">
<div class="org-box org-secondary">常务理事会</div>
</div>
<div class="org-connector"></div>
<div class="org-level org-bottom">
<div class="org-box org-third">学术委员会</div>
<div class="org-box org-third">秘书处</div>
<div class="org-box org-third">专家委员会</div>
</div>
</div>
<h3 class="mt-8">主要领导</h3>
<div class="leader-grid">
<div v-for="leader in leaders" :key="leader.name" class="leader-card">
<div class="leader-avatar">{{ leader.name.charAt(0) }}</div>
<div class="leader-info">
<div class="leader-name">{{ leader.name }}</div>
<div class="leader-pos">{{ leader.position }}</div>
</div>
</div>
</div>
<h3 class="mt-8">专家委员会成员</h3>
<div class="committee-tags">
<a-tag v-for="name in committeeMembers" :key="name" color="blue" style="margin-bottom:8px">{{ name }}</a-tag>
</div>
<div v-else-if="!hasCurrentArticle" class="content-empty">
<a-empty description="暂无内容" />
</div>
</div>
<!-- 学会章程 -->
<div v-show="currentSection === 'charter'" class="content-card">
<h2 class="content-title">学会章程</h2>
<div class="content-body charter-body">
<div v-for="chapter in charter" :key="chapter.title" class="charter-chapter">
<h3>{{ chapter.title }}</h3>
<div v-for="(item, idx) in chapter.items" :key="idx" class="charter-item">
<span class="charter-no">{{ idx + 1 }}</span>
<span>{{ item }}</span>
</div>
<template v-else>
<h2 class="content-title">{{ currentArticle.title || currentNavLabel }}</h2>
<div class="content-meta">
<span v-if="currentArticle.publishTime">发布时间{{ currentArticle.publishTime }}</span>
<span v-if="currentArticle.source">来源{{ currentArticle.source }}</span>
</div>
</div>
</div>
<!-- 咨询服务 -->
<div v-show="currentSection === 'consultation'" class="content-card">
<h2 class="content-title">咨询服务</h2>
<div class="content-body">
<p class="service-intro">广西决策咨询网为各级政府机构科研单位及企业提供专业系统的决策咨询服务涵盖政策研究战略规划项目评估等多个领域</p>
<div class="service-cards">
<div v-for="service in consultationServices" :key="service.title" class="service-card">
<div class="service-icon">{{ service.icon }}</div>
<h3>{{ service.title }}</h3>
<p>{{ service.desc }}</p>
<div class="service-tags-wrap">
<a-tag v-for="tag in service.tags" :key="tag">{{ tag }}</a-tag>
</div>
</div>
</div>
<div class="contact-box">
<h3>联系我们</h3>
<div class="contact-grid">
<div class="contact-item">
<span class="contact-icon">📞</span>
<div>
<div class="contact-label">联系电话</div>
<div class="contact-value">0771-5386339</div>
</div>
</div>
<div class="contact-item">
<span class="contact-icon">📧</span>
<div>
<div class="contact-label">电子邮箱</div>
<div class="contact-value">gxjzxzx@126.com</div>
</div>
</div>
<div class="contact-item">
<span class="contact-icon">📍</span>
<div>
<div class="contact-label">办公地址</div>
<div class="contact-value">广西南宁市良庆区五象大道401号</div>
</div>
</div>
<div class="contact-item">
<span class="contact-icon"></span>
<div>
<div class="contact-label">工作时间</div>
<div class="contact-value">周一至周五 9:00-17:30</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 加入我们 -->
<div v-show="currentSection === 'join'" class="content-card">
<h2 class="content-title">加入我们</h2>
<div class="content-body">
<p>我们热忱欢迎符合条件的单位和个人加入广西决策咨询学会共同推动广西决策咨询事业高质量发展</p>
<div class="join-cards">
<div class="join-card enterprise-card">
<div class="join-card-icon">🏢</div>
<h3>企业会员</h3>
<div class="join-qualifications">
<h4>入会资格</h4>
<ul>
<li>在广西依法注册具有法人资格的企事业单位</li>
<li>认同学会章程支持学会工作</li>
<li>具有一定规模和社会影响力</li>
</ul>
<h4>所需材料</h4>
<ul>
<li>入会申请表加盖公章</li>
<li>营业执照副本</li>
<li>法人代表身份证</li>
<li>单位简介</li>
</ul>
</div>
<a-button type="primary" block size="large" @click="navigateTo('/about/join/enterprise')">
企业会员申请
</a-button>
</div>
<div class="join-card personal-card">
<div class="join-card-icon">👤</div>
<h3>个人会员</h3>
<div class="join-qualifications">
<h4>入会资格</h4>
<ul>
<li>热爱决策咨询研究认同学会章程</li>
<li>大学本科及以上学历</li>
<li>具有相关专业工作经历</li>
</ul>
<h4>所需材料</h4>
<ul>
<li>入会申请表本人签字</li>
<li>个人简介及研究成果</li>
<li>职称证书或学历证书</li>
<li>身份证复印件</li>
</ul>
</div>
<a-button block size="large" @click="navigateTo('/about/join/personal')">
个人会员申请
</a-button>
</div>
</div>
<div class="download-section">
<h3>📥 资料下载</h3>
<div class="download-list">
<a href="#" class="download-item">
<span class="download-icon">📄</span>
<span class="download-name">企业会员入会申请表.docx</span>
<a-button size="small" type="primary" ghost>下载</a-button>
</a>
<a href="#" class="download-item">
<span class="download-icon">📄</span>
<span class="download-name">个人会员入会申请表.docx</span>
<a-button size="small" type="primary" ghost>下载</a-button>
</a>
<a href="#" class="download-item">
<span class="download-icon">📋</span>
<span class="download-name">广西决策咨询学会章程.pdf</span>
<a-button size="small" type="primary" ghost>下载</a-button>
</a>
</div>
</div>
</div>
<div class="content-body article-body" v-html="currentArticleContent" />
</template>
</div>
</a-col>
</a-row>
@@ -256,9 +46,12 @@
</template>
<script setup lang="ts">
import { pageSiteArticles, type SiteArticle } from '@/api/site'
useHead({ title: '关于我们 - 决策咨询网' })
const route = useRoute()
const router = useRouter()
const navItems = [
{ key: 'intro', label: '学会简介', icon: '🏛️' },
@@ -268,7 +61,6 @@ const navItems = [
{ key: 'join', label: '加入我们', icon: '🤝' },
]
// 根据路由path判断当前section
const sectionMap: Record<string, string> = {
'/about': 'intro',
'/about/organization': 'organization',
@@ -283,8 +75,76 @@ const currentSection = ref(
'intro'
)
const loading = ref(false)
const articleMap = ref<Record<string, SiteArticle | null>>({})
const currentArticle = computed(() => articleMap.value[currentSection.value] || null)
const hasCurrentArticle = computed(() => Boolean(currentArticle.value?.articleId))
const currentNavLabel = computed(() => {
return navItems.find((item) => item.key === currentSection.value)?.label || '关于我们'
})
const currentArticleContent = computed(() => {
const article = currentArticle.value
if (!article) {
return ''
}
if (article.content && /<[a-z][\s\S]*>/i.test(article.content)) {
return article.content
}
const text = article.content || article.overview || ''
if (!text) {
return '<p>暂无内容</p>'
}
return text
.split(/\n+/)
.map((item) => item.trim())
.filter(Boolean)
.map((item) => `<p>${escapeHtml(item)}</p>`)
.join('')
})
function escapeHtml(value: string) {
return value
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
}
function switchSection(key: string) {
currentSection.value = key
if (key === 'join') {
router.push('/about/join')
return
}
const target = Object.entries(sectionMap).find(([, value]) => value === key)?.[0] || '/about'
router.push(target)
}
async function loadArticles() {
loading.value = true
try {
const resultEntries = await Promise.all(
navItems.map(async (item) => {
const data = await pageSiteArticles({
page: 1,
limit: 1,
category: 'about',
type: item.key,
})
return [item.key, data.list?.[0] || null] as const
})
)
articleMap.value = Object.fromEntries(resultEntries)
} finally {
loading.value = false
}
}
watch(() => route.path, (newPath) => {
@@ -295,55 +155,9 @@ watch(() => route.query.section, (sec) => {
if (sec) currentSection.value = sec as string
})
const mainFunctions = [
{ icon: '🔬', title: '决策咨询研究', desc: '围绕广西经济社会发展重大问题,开展战略性、综合性、前瞻性研究' },
{ icon: '📝', title: '政策建议提供', desc: '为各级政府提供有参考价值的政策建议和咨询报告' },
{ icon: '👥', title: '专家交流合作', desc: '搭建区内外专家学者交流合作平台,推动学术思想碰撞' },
{ icon: '📡', title: '成果宣传推广', desc: '多渠道发布和推广决策咨询研究成果,服务社会各界' },
]
const leaders = [
{ name: '陈某某', position: '会长' },
{ name: '李某某', position: '副会长' },
{ name: '王某某', position: '副会长' },
{ name: '张某某', position: '秘书长' },
]
const committeeMembers = ['张教授', '李研究员', '王专家', '刘学者', '赵教授', '黄学者', '林研究员', '吴教授']
const charter = [
{
title: '第一章 总则',
items: [
'广西决策咨询学会是由全区从事决策咨询研究的专家学者和实际工作者自愿组成的学术性、非营利性社会组织。',
'学会的宗旨是:以服务党政决策为核心使命,汇聚全区高端智慧,围绕经济社会发展重大问题开展研究,为科学决策提供智力支撑。',
]
},
{
title: '第二章 业务范围',
items: [
'开展决策咨询理论与应用研究,撰写决策咨询报告。',
'组织学术交流、研讨会议等活动,促进学科发展。',
'为政府机构、企事业单位提供专业决策咨询服务。',
'培养决策咨询专业人才,开展业务培训。',
]
},
{
title: '第三章 会员',
items: [
'凡符合本章程规定,经申请并经理事会审议通过,即为本学会会员。',
'会员分为单位会员(企业会员)和个人会员两类。',
'会员有权出席会员大会,参与学会活动,享受学会提供的服务和资源。',
]
},
]
const consultationServices = [
{ icon: '🎯', title: '政策研究', desc: '深入研究党中央国务院及自治区重要政策,提供权威解读和实施建议', tags: ['政策解读', '战略规划'] },
{ icon: '🗺️', title: '规划咨询', desc: '为地方政府、园区和企业提供区域规划、产业规划、专项规划编制咨询', tags: ['区域规划', '产业规划'] },
{ icon: '📊', title: '项目评估', desc: '对重大投资项目开展可行性研究、风险评估和后评价服务', tags: ['可行性研究', '风险评估'] },
{ icon: '🔍', title: '专题调研', desc: '根据委托需求开展实地调研,形成翔实的调研报告和对策建议', tags: ['实地调研', '对策建议'] },
]
onMounted(() => {
loadArticles()
})
</script>
<style scoped>
@@ -362,21 +176,6 @@ const consultationServices = [
opacity: 0.1;
}
.banner-title {
color: #fff;
font-size: 36px;
font-weight: 700;
margin: 0 0 12px;
position: relative;
}
.banner-desc {
color: rgba(255,255,255,0.75);
font-size: 16px;
margin: 0;
position: relative;
}
.side-nav {
background: #fff;
border-radius: 12px;
@@ -434,415 +233,60 @@ const consultationServices = [
font-size: 24px;
font-weight: 700;
color: #1e3a5f;
margin: 0 0 24px;
margin: 0 0 16px;
padding-bottom: 16px;
border-bottom: 2px solid #e8f0fe;
}
.content-body h3 {
font-size: 18px;
font-weight: 600;
.content-meta {
display: flex;
flex-wrap: wrap;
gap: 16px;
margin-bottom: 20px;
color: #94a3b8;
font-size: 13px;
}
.content-loading,
.content-empty {
padding: 8px 0;
}
.article-body {
color: #334155;
font-size: 15px;
line-height: 1.9;
}
.article-body :deep(h2),
.article-body :deep(h3),
.article-body :deep(h4) {
color: #1f2937;
margin: 24px 0 12px;
}
.content-body p {
font-size: 15px;
color: #4b5563;
line-height: 1.8;
margin: 0 0 12px;
text-indent: 2em;
.article-body :deep(p) {
margin: 0 0 14px;
}
/* 数据亮点 */
.info-highlight {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin: 24px 0;
padding: 24px;
background: linear-gradient(135deg, #eff6ff, #dbeafe);
border-radius: 12px;
.article-body :deep(img) {
max-width: 100%;
height: auto;
}
.highlight-item {
text-align: center;
}
.highlight-number {
font-size: 32px;
font-weight: 800;
color: #1e3a5f;
}
.highlight-label {
font-size: 13px;
color: #6b7280;
margin-top: 4px;
}
/* 职能列表 */
.function-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.function-item {
display: flex;
gap: 12px;
padding: 16px;
background: #f9fafb;
border-radius: 10px;
}
.function-icon {
font-size: 28px;
flex-shrink: 0;
}
.function-content h4 {
font-size: 15px;
font-weight: 600;
color: #1f2937;
margin: 0 0 4px;
}
.function-content p {
font-size: 13px;
color: #6b7280;
margin: 0;
text-indent: 0;
line-height: 1.5;
}
/* 组织结构图 */
.org-chart {
text-align: center;
padding: 20px;
}
.org-level {
display: flex;
justify-content: center;
gap: 20px;
}
.org-connector {
height: 24px;
width: 2px;
background: #d1d5db;
margin: 0 auto;
}
.org-box {
padding: 10px 24px;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
}
.org-primary {
background: #1e3a5f;
color: #fff;
min-width: 120px;
}
.org-secondary {
background: #3b82f6;
color: #fff;
min-width: 140px;
}
.org-third {
background: #eff6ff;
color: #1e3a5f;
border: 1px solid #bfdbfe;
min-width: 110px;
}
.leader-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
.leader-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 16px;
background: #f9fafb;
border-radius: 10px;
}
.leader-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
background: #1e3a5f;
color: #fff;
font-size: 20px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
}
.leader-name {
font-size: 15px;
font-weight: 600;
color: #1f2937;
}
.leader-pos {
font-size: 12px;
color: #6b7280;
}
.committee-tags {
margin-top: 8px;
}
/* 章程 */
.charter-body .charter-chapter {
margin-bottom: 24px;
}
.charter-chapter h3 {
font-size: 17px;
font-weight: 700;
color: #1e3a5f;
background: #eff6ff;
padding: 10px 16px;
border-radius: 6px;
margin: 0 0 12px;
}
.charter-item {
display: flex;
gap: 12px;
padding: 10px 16px;
font-size: 14px;
color: #4b5563;
line-height: 1.8;
border-bottom: 1px dashed #f0f0f0;
}
.charter-no {
color: #1e3a5f;
font-weight: 600;
flex-shrink: 0;
width: 48px;
}
/* 咨询服务 */
.service-intro {
text-indent: 2em;
}
.service-cards {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin: 24px 0;
}
.service-card {
padding: 24px;
background: #f9fafb;
border-radius: 12px;
border: 1px solid #e5e7eb;
transition: all 0.2s;
}
.service-card:hover {
border-color: #1e3a5f;
box-shadow: 0 4px 12px rgba(30,58,95,0.1);
}
.service-icon {
font-size: 36px;
margin-bottom: 12px;
}
.service-card h3 {
font-size: 16px;
font-weight: 700;
color: #1e3a5f;
margin: 0 0 8px;
}
.service-card p {
font-size: 13px;
color: #6b7280;
margin: 0 0 12px;
text-indent: 0;
line-height: 1.6;
}
.service-tags-wrap {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.contact-box {
background: #1e3a5f;
border-radius: 16px;
padding: 32px;
margin-top: 24px;
}
.contact-box h3 {
color: #fff;
font-size: 18px;
margin: 0 0 20px;
}
.contact-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.contact-item {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 16px;
background: rgba(255,255,255,0.08);
border-radius: 10px;
}
.contact-icon {
font-size: 20px;
}
.contact-label {
font-size: 12px;
color: rgba(255,255,255,0.65);
margin-bottom: 4px;
}
.contact-value {
font-size: 14px;
color: #fff;
font-weight: 500;
}
/* 加入我们 */
.join-cards {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24px;
margin: 24px 0;
}
.join-card {
padding: 28px;
border-radius: 16px;
border: 2px solid transparent;
}
.enterprise-card {
background: #eff6ff;
border-color: #bfdbfe;
}
.personal-card {
background: #f0fdf4;
border-color: #bbf7d0;
}
.join-card-icon {
font-size: 40px;
margin-bottom: 12px;
}
.join-card h3 {
font-size: 20px;
font-weight: 700;
color: #1f2937;
.article-body :deep(ul),
.article-body :deep(ol) {
padding-left: 22px;
margin: 0 0 16px;
}
.join-qualifications h4 {
font-size: 14px;
font-weight: 600;
color: #374151;
margin: 12px 0 8px;
}
@media (max-width: 920px) {
.content-card {
padding: 24px;
}
.join-qualifications ul {
padding-left: 18px;
margin: 0 0 12px;
}
.join-qualifications li {
font-size: 13px;
color: #4b5563;
line-height: 2;
}
.download-section {
background: #f9fafb;
border-radius: 12px;
padding: 24px;
margin-top: 24px;
}
.download-section h3 {
font-size: 16px;
font-weight: 600;
color: #1f2937;
margin: 0 0 16px;
}
.download-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.download-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 8px;
text-decoration: none;
color: #374151;
transition: all 0.2s;
}
.download-item:hover {
border-color: #1e3a5f;
}
.download-icon {
font-size: 18px;
}
.download-name {
flex: 1;
font-size: 14px;
color: #374151;
}
.mt-6 { margin-top: 24px; }
.mt-8 { margin-top: 32px; }
@media (max-width: 768px) {
.info-highlight { grid-template-columns: repeat(2, 1fr); }
.function-list { grid-template-columns: 1fr; }
.service-cards { grid-template-columns: 1fr; }
.join-cards { grid-template-columns: 1fr; }
.leader-grid { grid-template-columns: repeat(2, 1fr); }
.contact-grid { grid-template-columns: 1fr; }
.content-card { padding: 20px; }
.about-banner {
padding: 36px 0 20px;
}
}
</style>
+178
View File
@@ -0,0 +1,178 @@
<template>
<div class="downloads-page">
<div class="page-header">
<h1 class="page-title">入会资料下载</h1>
<p class="page-desc">下载企业会员个人会员入会申请材料完成填写盖章或签字后上传审核</p>
</div>
<div class="downloads-grid">
<div v-for="item in downloadItems" :key="item.title" class="download-card">
<div class="download-icon">{{ item.icon }}</div>
<div class="download-body">
<h3>{{ item.title }}</h3>
<p>{{ item.desc }}</p>
<div class="download-tags">
<a-tag v-for="tag in item.tags" :key="tag" color="blue">{{ tag }}</a-tag>
</div>
</div>
<div class="download-actions">
<a-button type="primary" ghost @click="handleDownload(item.title)">下载模板</a-button>
</div>
</div>
</div>
<div class="review-section">
<h2>资格审核与资料上传</h2>
<p>请选择对应身份进入申请系统填写表单并上传盖章或签字后的申请表及证明材料</p>
<div class="review-actions">
<a-button type="primary" size="large" @click="navigateTo('/about/join/enterprise')">企业会员申请</a-button>
<a-button size="large" @click="navigateTo('/about/join/personal')">个人会员申请</a-button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { message } from 'ant-design-vue'
useHead({ title: '入会资料下载 - 决策咨询网' })
const downloadItems = [
{
icon: '🏢',
title: '企业会员入会申请表',
desc: '适用于企业会员入会申请,需填写完整信息并加盖单位公章后上传。',
tags: ['企业会员', '盖章上传'],
},
{
icon: '👤',
title: '个人会员入会申请表',
desc: '适用于个人会员入会申请,需本人签字后连同证明材料一并提交审核。',
tags: ['个人会员', '签字上传'],
},
{
icon: '📋',
title: '学会章程与入会须知',
desc: '提交申请前请先阅读章程与入会须知,确认资格条件与资料清单。',
tags: ['章程', '资格说明'],
},
]
function handleDownload(name: string) {
message.info(`资料「${name}」下载功能待接入实际文件,当前已预留下载入口`)
}
</script>
<style scoped>
.downloads-page {
max-width: 1100px;
margin: 0 auto;
padding: 40px 20px 64px;
}
.page-header {
text-align: center;
margin-bottom: 32px;
}
.page-title {
font-size: 32px;
font-weight: 700;
color: #1f2937;
margin: 0 0 12px;
}
.page-desc {
font-size: 15px;
color: #6b7280;
margin: 0;
}
.downloads-grid {
display: grid;
gap: 20px;
}
.download-card {
display: flex;
align-items: center;
gap: 20px;
padding: 24px;
background: #fff;
border-radius: 16px;
box-shadow: 0 6px 20px rgba(15, 23, 42, 0.06);
}
.download-icon {
width: 64px;
height: 64px;
border-radius: 16px;
background: linear-gradient(135deg, #dbeafe 0%, #eff6ff 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
flex-shrink: 0;
}
.download-body {
flex: 1;
}
.download-body h3 {
margin: 0 0 8px;
font-size: 18px;
color: #1f2937;
}
.download-body p {
margin: 0 0 12px;
color: #6b7280;
line-height: 1.7;
}
.download-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.download-actions {
flex-shrink: 0;
}
.review-section {
margin-top: 32px;
padding: 32px;
border-radius: 16px;
background: linear-gradient(135deg, #1e3a5f 0%, #2563eb 100%);
color: #fff;
}
.review-section h2 {
margin: 0 0 10px;
font-size: 24px;
}
.review-section p {
margin: 0 0 20px;
color: rgba(255, 255, 255, 0.82);
}
.review-actions {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
@media (max-width: 768px) {
.download-card {
flex-direction: column;
align-items: flex-start;
}
.download-actions {
width: 100%;
}
}
</style>
+53 -9
View File
@@ -65,6 +65,17 @@
<h3 class="section-title">资质证明材料</h3>
<p class="section-desc">请上传以下材料以便我们审核您的入会资格</p>
<div class="materials-tip">
<div>企业会员需提交入会申请表加盖公章营业执照法人身份证企业简介</div>
<a-button type="link" @click="navigateTo('/about/join/downloads')">前往资料下载</a-button>
</div>
<a-form-item label="入会申请表(加盖公章)">
<a-upload :before-upload="beforeUpload" :custom-request="handleUpload('applicationForm')">
<a-button><UploadOutlined /> 上传申请表</a-button>
</a-upload>
</a-form-item>
<a-form-item label="营业执照">
<a-upload :before-upload="beforeUpload" :custom-request="handleUpload('license')">
<a-button><UploadOutlined /> 上传营业执照</a-button>
@@ -115,9 +126,22 @@
<script setup lang="ts">
import { message } from 'ant-design-vue'
import { CheckCircleOutlined, UploadOutlined } from '@ant-design/icons-vue'
import { submitSiteJoinApplication, uploadSiteJoinApplicationFile } from '@/api/site'
useHead({ title: '企业会员申请 - 决策咨询网' })
type UploadRequestOption = {
file: File
onSuccess: (response?: unknown) => void
onError: (error?: unknown) => void
}
type UploadResult = {
path: string
url: string
name: string
}
const currentStep = ref(0)
const submitting = ref(false)
@@ -129,6 +153,7 @@ const formData = reactive({
email: '',
address: '',
bio: '',
applicationForm: '',
license: '',
idCard: '',
intro: '',
@@ -144,14 +169,17 @@ function beforeUpload(file: File) {
}
function handleUpload(type: string) {
return async (option: any) => {
return async (option: UploadRequestOption) => {
try {
// TODO: 调用上传API
option.onSuccess()
const form = new FormData()
form.append('file', option.file)
const data = await uploadSiteJoinApplicationFile(form)
formData[type as keyof typeof formData] = data.path
option.onSuccess(data)
message.success('上传成功')
} catch {
option.onError()
message.error('上传失败')
} catch (e: unknown) {
option.onError(e)
message.error(e instanceof Error ? e.message : '上传失败')
}
}
}
@@ -169,11 +197,14 @@ function handleNext() {
async function handleSubmit() {
submitting.value = true
try {
// TODO: 调用API提交申请
await submitSiteJoinApplication({
type: 'enterprise',
...formData,
})
message.success('提交成功,请等待审核')
navigateTo('/about/join')
} catch (e: any) {
message.error(e?.message || '提交失败')
} catch (e: unknown) {
message.error(e instanceof Error ? e.message : '提交失败')
} finally {
submitting.value = false
}
@@ -229,6 +260,19 @@ async function handleSubmit() {
margin: -10px 0 20px;
}
.materials-tip {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 20px;
padding: 14px 16px;
background: #f8fafc;
border: 1px solid #dbeafe;
border-radius: 12px;
color: #475569;
}
.upload-hint {
font-size: 12px;
color: #9ca3af;
+127
View File
@@ -0,0 +1,127 @@
<template>
<div class="join-entry-page">
<div class="page-header">
<h1 class="page-title">加入我们</h1>
<p class="page-desc">请选择企业会员或个人会员申请入口按要求提交资料审核</p>
</div>
<div class="join-cards">
<div class="join-card enterprise-card">
<div class="join-card-icon">🏢</div>
<h3>企业会员申请</h3>
<p>适用于依法注册具有法人资格的企事业单位</p>
<ul>
<li>填写企业备案信息</li>
<li>上传申请表营业执照等材料</li>
<li>提交后等待后台审核</li>
</ul>
<a-button type="primary" block size="large" @click="navigateTo('/about/join/enterprise')">
进入企业会员申请
</a-button>
</div>
<div class="join-card personal-card">
<div class="join-card-icon">👤</div>
<h3>个人会员申请</h3>
<p>适用于具备相应专业背景认同学会章程的个人申请者</p>
<ul>
<li>填写个人备案信息</li>
<li>上传签字申请表及证明材料</li>
<li>提交后等待后台审核</li>
</ul>
<a-button block size="large" @click="navigateTo('/about/join/personal')">
进入个人会员申请
</a-button>
</div>
</div>
<div class="entry-actions">
<a-button @click="navigateTo('/about/join/downloads')">资料下载</a-button>
<a-button @click="navigateTo('/about')">返回关于我们</a-button>
</div>
</div>
</template>
<script setup lang="ts">
useHead({ title: '加入我们 - 决策咨询网' })
</script>
<style scoped>
.join-entry-page {
max-width: 1100px;
margin: 0 auto;
padding: 40px 20px 64px;
}
.page-header {
text-align: center;
margin-bottom: 36px;
}
.page-title {
margin: 0 0 12px;
font-size: 32px;
font-weight: 700;
color: #1f2937;
}
.page-desc {
margin: 0;
color: #6b7280;
font-size: 15px;
}
.join-cards {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 24px;
}
.join-card {
padding: 28px;
border-radius: 18px;
background: #fff;
box-shadow: 0 6px 20px rgba(15, 23, 42, 0.06);
}
.join-card-icon {
font-size: 36px;
margin-bottom: 16px;
}
.join-card h3 {
margin: 0 0 10px;
font-size: 22px;
color: #1f2937;
}
.join-card p {
margin: 0 0 16px;
color: #6b7280;
line-height: 1.8;
}
.join-card ul {
margin: 0 0 20px;
padding-left: 20px;
color: #475569;
line-height: 1.8;
}
.entry-actions {
display: flex;
justify-content: center;
gap: 16px;
margin-top: 28px;
}
@media (max-width: 820px) {
.join-cards {
grid-template-columns: 1fr;
}
.entry-actions {
flex-direction: column;
}
}
</style>
+83 -12
View File
@@ -89,6 +89,23 @@
<h3 class="section-title">资质证明材料</h3>
<p class="section-desc">请上传相关证明材料以便我们审核您的入会资格</p>
<div class="materials-tip">
<div>个人会员需提交入会申请表签字简介研究成果职称证书学历证书身份证研究成果或获奖证明</div>
<a-button type="link" @click="navigateTo('/about/join/downloads')">前往资料下载</a-button>
</div>
<a-form-item label="入会申请表(签字)">
<a-upload :before-upload="beforeUpload" :custom-request="handleUpload('applicationForm')">
<a-button><UploadOutlined /> 上传申请表</a-button>
</a-upload>
</a-form-item>
<a-form-item label="个人简介">
<a-upload :before-upload="beforeUpload" :custom-request="handleUpload('profile')">
<a-button><UploadOutlined /> 上传简介</a-button>
</a-upload>
</a-form-item>
<a-form-item label="身份证">
<a-upload :before-upload="beforeUpload" :custom-request="handleUpload('idCard')">
<a-button><UploadOutlined /> 上传身份证</a-button>
@@ -143,25 +160,41 @@
</template>
<script setup lang="ts">
import dayjs, { type Dayjs } from 'dayjs'
import { message } from 'ant-design-vue'
import { CheckCircleOutlined, UploadOutlined } from '@ant-design/icons-vue'
import { submitSiteJoinApplication, uploadSiteJoinApplicationFile } from '@/api/site'
useHead({ title: '个人会员申请 - 决策咨询网' })
type UploadRequestOption = {
file: File
onSuccess: (response?: unknown) => void
onError: (error?: unknown) => void
}
type UploadResult = {
path: string
url: string
name: string
}
const currentStep = ref(0)
const submitting = ref(false)
const formData = reactive({
name: '',
gender: undefined,
birthday: undefined,
education: undefined,
gender: undefined as string | undefined,
birthday: undefined as Dayjs | undefined,
education: undefined as string | undefined,
title: '',
organization: '',
phone: '',
email: '',
researchArea: '',
bio: '',
applicationForm: '',
profile: '',
idCard: '',
diploma: '',
certificate: '',
@@ -178,14 +211,21 @@ function beforeUpload(file: File) {
}
function handleUpload(type: string) {
return async (option: any) => {
return async (option: UploadRequestOption) => {
try {
// TODO: 调用上传API
option.onSuccess()
const form = new FormData()
form.append('file', option.file)
const data = await uploadSiteJoinApplicationFile(form)
if (type === 'achievements') {
formData.achievements.push(data.path)
} else {
formData[type as Exclude<keyof typeof formData, 'achievements' | 'birthday'>] = data.path as never
}
option.onSuccess(data)
message.success('上传成功')
} catch {
option.onError()
message.error('上传失败')
} catch (e: unknown) {
option.onError(e)
message.error(e instanceof Error ? e.message : '上传失败')
}
}
}
@@ -203,11 +243,29 @@ function handleNext() {
async function handleSubmit() {
submitting.value = true
try {
// TODO: 调用API提交申请
await submitSiteJoinApplication({
type: 'personal',
name: formData.name,
gender: formData.gender,
birthday: formData.birthday ? dayjs(formData.birthday).format('YYYY-MM-DD') : '',
education: formData.education,
title: formData.title,
organization: formData.organization,
phone: formData.phone,
email: formData.email,
researchArea: formData.researchArea,
bio: formData.bio,
applicationForm: formData.applicationForm,
profile: formData.profile,
idCard: formData.idCard,
diploma: formData.diploma,
certificate: formData.certificate,
achievements: formData.achievements,
})
message.success('提交成功,请等待审核')
navigateTo('/about/join')
} catch (e: any) {
message.error(e?.message || '提交失败')
} catch (e: unknown) {
message.error(e instanceof Error ? e.message : '提交失败')
} finally {
submitting.value = false
}
@@ -263,6 +321,19 @@ async function handleSubmit() {
margin: -10px 0 20px;
}
.materials-tip {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 20px;
padding: 14px 16px;
background: #f8fafc;
border: 1px solid #dbeafe;
border-radius: 12px;
color: #475569;
}
.upload-hint {
font-size: 12px;
color: #9ca3af;