Files
zkxw/docs/theme-demos/build-demos.mjs
T
2026-06-14 17:20:52 +08:00

419 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const themes = [
{
id: '00',
file: '00-fresh-mint-clash.html',
title: '00 · 现行薄荷绿(Logo 同色)',
desc: '主色 #10b981 与 Logo 同为绿色 · 层次易糊',
note: '对比基准:Logo 绿 + UI 绿叠在一起,是当前觉得「不好看」的典型情况。',
primary: '#10b981',
dark: '#059669',
bg: '#ecfdf5',
border: '#d9e8e2',
swatches: ['#10b981', '#059669', '#ecfdf5', '#d9e8e2'],
recommended: false
},
{
id: '01',
file: '01-slate-blue.html',
title: '01 · 深海蓝(推荐)',
desc: '主色 #2563eb · Logo 绿 + UI 蓝,专业医疗后台',
note: '推荐首选:与绿色 Logo 互补,成功/进行中仍用绿色 Tag,操作引导清晰。',
primary: '#2563eb',
dark: '#1d4ed8',
bg: '#eff6ff',
border: '#e2e8f0',
swatches: ['#2563eb', '#1d4ed8', '#eff6ff', '#e2e8f0'],
recommended: true
},
{
id: '02',
file: '02-bio-teal.html',
title: '02 · 生物青绿',
desc: '主色 #0d9488 · 偏蓝的 Teal,保留生命感',
note: '折中方案:比薄荷绿沉、比纯蓝更有生物气质;注意与成功 Tag 绿色区分。',
primary: '#0d9488',
dark: '#0f766e',
bg: '#f0fdfa',
border: '#cce7e4',
swatches: ['#0d9488', '#0f766e', '#f0fdfa', '#cce7e4'],
recommended: false
},
{
id: '03',
file: '03-graphite-blue.html',
title: '03 · 石墨灰 + 蓝色按钮',
desc: '导航 Slate #475569 · 主按钮 #0369a1',
note: '最克制:界面几乎无彩色,Logo 绿最突出;主按钮单独用蓝色强调。',
primary: '#475569',
dark: '#334155',
bg: '#f8fafc',
border: '#e2e8f0',
cta: '#0369a1',
ctaDark: '#0284c7',
swatches: ['#475569', '#0369a1', '#f8fafc', '#e2e8f0'],
recommended: false
},
{
id: '04',
file: '04-indigo-tech.html',
title: '04 · 靛蓝科技',
desc: '主色 #4f46e5 · 偏生物科技平台气质',
note: '辨识度高、略活泼;适合强调数字化,医疗场景需控制 Tag 饱和度。',
primary: '#4f46e5',
dark: '#4338ca',
bg: '#eef2ff',
border: '#c7d2fe',
swatches: ['#4f46e5', '#4338ca', '#eef2ff', '#c7d2fe'],
recommended: false
}
]
function themeJump(currentId) {
return themes
.map((t) => {
const cls = t.id === currentId ? 'is-current' : ''
return `<a class="${cls}" href="${t.file}">${t.id}</a>`
})
.join('')
}
function swatchesHtml(theme) {
const labels = theme.cta
? ['导航', '按钮', '浅底', '边']
: ['主色', '深', '浅底', '边']
return theme.swatches
.map((c, i) => `<span class="swatch"><i style="background:${c}"></i>${labels[i]}</span>`)
.join('')
}
function rootVars(theme) {
const lines = [
` --primary: ${theme.primary};`,
` --primary-dark: ${theme.dark};`,
` --primary-bg: ${theme.bg};`,
` --text: #1e293b;`,
` --text-muted: #64748b;`,
` --border: ${theme.border};`,
` --bg-page: #fefefe;`,
` --surface: #ffffff;`,
` --table-head: #f8fafc;`,
` --row-alt: #fafafa;`,
` --row-hover: #f1f5f9;`,
` --shadow: 0 1px 3px rgba(0, 0, 0, 0.05);`,
` --radius: 10px;`,
` --brand-green: #10b981;`,
` --brand-green-dark: #059669;`
]
if (theme.cta) {
lines.push(` --cta: ${theme.cta};`, ` --cta-dark: ${theme.ctaDark};`)
}
return lines.join('\n')
}
function renderPage(theme) {
const badge = theme.recommended
? '<span class="demo-badge">推荐</span>'
: theme.id === '00'
? '<span class="demo-badge demo-badge--warn">现状</span>'
: ''
return `<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>${theme.title} · 管理端界面 Demo</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
<style>
:root {
${rootVars(theme)}
}
</style>
<link rel="stylesheet" href="_demo-styles.css" />
</head>
<body>
<div class="demo-banner">
<div>
<h1>${badge}${theme.title}</h1>
<p>${theme.desc}</p>
</div>
<div class="demo-banner__actions">
<div class="swatch-row">${swatchesHtml(theme)}</div>
<div class="theme-jump">${themeJump(theme.id)}</div>
<a class="link-back" href="index.html">选型入口</a>
</div>
</div>
<div class="app-layout">
<aside class="sidebar">
<div class="brand">
<img class="brand-logo" src="../../web-admin/public/logo.png" alt="中科兴皖" width="36" height="36" />
<div class="brand-text">中科兴皖<small>一体化门户</small></div>
</div>
<div class="nav">
<div class="nav-group">
<div class="nav-group-title">市场运营</div>
<a href="#">工作台</a>
<a href="#" class="active">采集协议单</a>
<a href="#">样本接收</a>
<a href="#">缴费确认</a>
</div>
<div class="nav-group">
<div class="nav-group-title">质量管理</div>
<a href="#">质检工单</a>
<a href="#">环境检测</a>
</div>
<div class="nav-group">
<div class="nav-group-title">系统</div>
<a href="#">用户管理</a>
<a href="#">角色权限</a>
</div>
</div>
</aside>
<div class="main-col">
<header class="topbar">
<div class="crumb">市场运营 / <b>采集协议单</b></div>
<div class="topbar-right">
<span>管理员</span>
<div class="avatar">管</div>
</div>
</header>
<div class="work-tabs">
<div class="work-tab">工作台</div>
<div class="work-tab is-active">采集协议单</div>
<div class="work-tab">样本接收</div>
</div>
<div class="content">
<section class="panel">
<div class="panel-top">
<h2 class="title-bar-heading">采集协议单</h2>
</div>
<div class="entity-switch">
<div class="entity-card is-active">
<div class="entity-card__icon">📄</div>
<div>
<div class="entity-card__title">协议单管理</div>
<div class="entity-card__desc">协议审核与状态维护</div>
</div>
</div>
<div class="entity-card">
<div class="entity-card__icon">💰</div>
<div>
<div class="entity-card__title">缴费信息</div>
<div class="entity-card__desc">缴费计划与到账</div>
</div>
</div>
<div class="entity-card">
<div class="entity-card__icon">🏅</div>
<div>
<div class="entity-card__title">储存证管理</div>
<div class="entity-card__desc">储存证开具管理</div>
</div>
</div>
<div class="entity-card">
<div class="entity-card__icon">📅</div>
<div>
<div class="entity-card__title">满月待办</div>
<div class="entity-card__desc">满月事项跟进</div>
</div>
</div>
</div>
<div class="filter-block">
<div class="filter-grid">
<div class="field">
<label>关键词</label>
<input class="input" type="text" placeholder="协议编号 / 客户姓名 / 手机号" />
</div>
<div class="field">
<label>协议状态</label>
<select class="select"><option>全部</option><option>生效中</option><option>待生效</option></select>
</div>
<div class="field">
<label>预产期起</label>
<input class="input" type="date" />
</div>
<div class="field">
<label>预产期止</label>
<input class="input" type="date" />
</div>
</div>
<div class="filter-actions">
<button type="button" class="btn btn-primary">查询</button>
<button type="button" class="btn">重置</button>
</div>
</div>
<div class="list-toolbar">
<span class="sel-num">已选 <b>2</b> 项</span>
<button type="button" class="btn btn-primary">新增协议</button>
<button type="button" class="btn">批量审核</button>
<button type="button" class="btn">导出</button>
</div>
<div class="list-body">
<table>
<thead>
<tr>
<th><input type="checkbox" checked /></th>
<th>序号</th>
<th>状态</th>
<th>协议编号</th>
<th>客户姓名</th>
<th>手机号</th>
<th>预产期</th>
<th>缴费状态</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" checked /></td>
<td>1</td>
<td><span class="tag tag-primary">生效中</span></td>
<td>XY-2026-0042</td>
<td>张女士</td>
<td>138****6621</td>
<td>2026-08-12</td>
<td><span class="tag tag-success">已缴费</span></td>
<td>2026-03-01 10:22</td>
<td>
<button class="btn-op primary">查看</button>
<button class="btn-op">编辑</button>
<button class="btn-op">审核</button>
</td>
</tr>
<tr>
<td><input type="checkbox" checked /></td>
<td>2</td>
<td><span class="tag tag-info">待生效</span></td>
<td>XY-2026-0038</td>
<td>李先生</td>
<td>139****8890</td>
<td>2026-07-20</td>
<td><span class="tag tag-warning">缴费确认中</span></td>
<td>2026-02-28 15:06</td>
<td>
<button class="btn-op primary">查看</button>
<button class="btn-op">编辑</button>
<button class="btn-op">生效</button>
</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>3</td>
<td><span class="tag tag-warning">已过期</span></td>
<td>XY-2025-1201</td>
<td>王女士</td>
<td>136****3345</td>
<td>2025-12-08</td>
<td><span class="tag tag-success">已缴费</span></td>
<td>2026-02-28 09:18</td>
<td>
<button class="btn-op primary">查看</button>
<button class="btn-op">续签</button>
</td>
</tr>
<tr>
<td><input type="checkbox" /></td>
<td>4</td>
<td><span class="tag tag-danger">已作废</span></td>
<td>XY-2025-0899</td>
<td>赵先生</td>
<td>137****2210</td>
<td>2025-10-15</td>
<td><span class="tag tag-info">待缴费</span></td>
<td>2025-09-20 14:40</td>
<td>
<button class="btn-op primary">查看</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="pager">
<span>共 128 条</span>
<button class="pager-btn">‹</button>
<button class="pager-btn is-active">1</button>
<button class="pager-btn">2</button>
<button class="pager-btn">3</button>
<button class="pager-btn">›</button>
<span>10 条/页</span>
</div>
</section>
<div class="demo-bottom">
<div>
<div class="stats-row">
<div class="stat-card">
<div class="label">本月新增协议</div>
<div class="value">42</div>
</div>
<div class="stat-card">
<div class="label">生效中</div>
<div class="value">86</div>
</div>
<div class="stat-card warn">
<div class="label">待缴费</div>
<div class="value">12</div>
</div>
</div>
<p class="theme-note">${theme.note}</p>
</div>
<div class="dialog-preview">
<div class="dialog-head">查看协议 · XY-2026-0042</div>
<div class="dialog-body">
<div class="form-grid-2">
<div class="field">
<label>协议状态</label>
<div><span class="tag tag-primary">生效中</span></div>
</div>
<div class="field">
<label>缴费状态</label>
<div><span class="tag tag-success">已缴费</span></div>
</div>
<div class="field">
<label>客户姓名</label>
<input class="input" value="张女士" readonly />
</div>
<div class="field">
<label>手机号</label>
<input class="input" value="138****6621" readonly />
</div>
<div class="field" style="grid-column: 1 / -1">
<label>备注</label>
<input class="input" value="—" readonly />
</div>
</div>
</div>
<div class="dialog-foot">
<button class="btn">关闭</button>
<button class="btn btn-primary">确定</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>`
}
for (const theme of themes) {
fs.writeFileSync(path.join(__dirname, theme.file), renderPage(theme))
console.log('written', theme.file)
}