批量推送

This commit is contained in:
郭庆泰
2026-08-16 21:24:53 +08:00
parent 0c093076a4
commit ccfd03a6eb
55 changed files with 3772 additions and 577 deletions
+31 -78
View File
@@ -77,83 +77,16 @@
<div class="specialty-inner">
<div class="section-title">七大专项计划</div>
<div class="specialty-list">
<div class="specialty-card">
<div class="specialty-no">01</div>
<div v-for="(p, i) in specialPlans" :key="p.id" class="specialty-card" @click="openPlan(p.id)">
<div class="specialty-no">{{ String(i + 1).padStart(2, '0') }}</div>
<div class="specialty-body">
<h3 class="specialty-title">规范化诊疗及医疗质量提升专项计划(2026)</h3>
<p class="specialty-desc">聚焦临床诊疗规范制定与质量提升,推动各级医疗机构诊疗标准化同质化</p>
<h3 class="specialty-title">{{ p.title }}</h3>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div class="specialty-card">
<div class="specialty-no">02</div>
<div class="specialty-body">
<h3 class="specialty-title">科研创新专项行动计划(2026-2030)</h3>
<p class="specialty-desc">支持医学科研创新,推动整合医学研究成果转化与产业化应用,构建协同创新生态</p>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div class="specialty-card">
<div class="specialty-no">03</div>
<div class="specialty-body">
<h3 class="specialty-title">医疗卫生人才培育专项行动计划(2026-2030)</h3>
<p class="specialty-desc">建立多层次医学人才培养体系,重点加强基层医疗人才与跨学科复合型人才建设</p>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div class="specialty-card">
<div class="specialty-no">04</div>
<div class="specialty-body">
<h3 class="specialty-title">医院管理及高质量发展促进专项计划(2026-2030)</h3>
<p class="specialty-desc">推动医院管理现代化,提升运营效率与服务水平,助力公立医院高质量发展</p>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div class="specialty-card">
<div class="specialty-no">05</div>
<div class="specialty-body">
<h3 class="specialty-title">社会公益与可及性提升专项计划(2026-2030)</h3>
<p class="specialty-desc">聚焦医疗服务的可及性与公平性,开展公益救助基层帮扶与健康科普活动</p>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div class="specialty-card">
<div class="specialty-no">06</div>
<div class="specialty-body">
<h3 class="specialty-title">政学协作综合项目专项计划(2026-2030)</h3>
<p class="specialty-desc">搭建政府与学术机构协同平台,推动政策研究与决策支持,促进政产学研用深度融合</p>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div class="specialty-card">
<div class="specialty-no">07</div>
<div class="specialty-body">
<h3 class="specialty-title">组织建设与内部治理专项计划(2026-2030)</h3>
<p class="specialty-desc">完善学会组织架构,健全内部治理机制,提升规范化专业化信息化管理水平</p>
<div class="specialty-action">
<span class="specialty-link">查看详情</span>
<span class="specialty-link">项目提案</span>
</div>
</div>
</div>
<div v-if="!specialPlans.length" class="specialty-empty">暂无专项计划</div>
</div>
</div>
</section>
@@ -215,11 +148,26 @@ import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/store/user'
import { logout as logoutApi } from '@/api/auth'
import request from '@/utils/request'
const router = useRouter()
const userStore = useUserStore()
const isScrolled = ref(false)
const specialPlans = ref([])
async function loadSpecialPlans() {
try {
const r = await request({ url: '/business/public/specialPlan/list', method: 'get' })
specialPlans.value = (r.data && r.data.data) || r.data || []
} catch (e) {
specialPlans.value = []
}
}
function openPlan(id) {
window.open(`/#/special-plan/${id}`, '_blank')
}
const topNavClass = computed(() => isScrolled.value ? 'is-scrolled' : '')
const loggedIn = computed(() => !!userStore.token)
const userName = computed(() => userStore.user?.userName || '用户')
@@ -266,12 +214,6 @@ const planSvg = `<svg viewBox="0 150 1200 370" xmlns="http://www.w3.org/2000/svg
<g transform="translate(904 362)"><polygon points="-30,0 -15,-26 15,-26 30,0 15,26 -15,26" fill="url(#hexGrad)"/><text y="6" font-size="19">07</text></g>
<g transform="translate(986 468)"><polygon points="-34,0 -17,-29 17,-29 34,0 17,29 -17,29" fill="url(#hexGrad)"/><text y="7" font-size="22">08</text></g>
</g>
<g transform="translate(600 360)">
<circle cx="0" cy="0" r="40" fill="#fff" stroke="#e0e7ff" stroke-width="2"/>
<circle cx="0" cy="0" r="30" fill="url(#centerGrad)"/>
<rect x="-16" y="-5" width="32" height="10" fill="#fff"/>
<rect x="-5" y="-16" width="10" height="32" fill="#fff"/>
</g>
<text x="600" y="430" fill="var(--brand-primary)" text-anchor="middle" font-family="Microsoft YaHei, sans-serif" font-size="32" font-weight="bold" letter-spacing="6">2025-2030年</text>
<line x1="540" y1="447" x2="600" y2="447" stroke="var(--brand-primary)" stroke-width="1.5" opacity="0.4"/>
<line x1="600" y1="447" x2="660" y2="447" stroke="var(--brand-primary)" stroke-width="1.5" opacity="0.4"/>
@@ -291,7 +233,10 @@ function handleScroll() {
isScrolled.value = window.scrollY > 10
}
onMounted(() => window.addEventListener('scroll', handleScroll, { passive: true }))
onMounted(() => {
window.addEventListener('scroll', handleScroll, { passive: true })
loadSpecialPlans()
})
onBeforeUnmount(() => window.removeEventListener('scroll', handleScroll))
function onHome() { isScrolled.value = false }
@@ -632,8 +577,16 @@ a { color: inherit; text-decoration: none; }
background: #fff;
border: 1px solid #e5e7eb;
display: flex;
cursor: pointer;
transition: border-color 0.2s, transform 0.2s;
}
.specialty-empty {
grid-column: 1 / -1;
text-align: center;
color: #9ca3af;
padding: 60px 0;
font-size: 14px;
}
.specialty-card:hover {
border-color: var(--brand-primary);