434 lines
15 KiB
JavaScript
434 lines
15 KiB
JavaScript
import fs from 'fs'
|
||
import path from 'path'
|
||
import { fileURLToPath } from 'url'
|
||
|
||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||
|
||
const themes = [
|
||
{
|
||
id: '01',
|
||
file: '01-dark-sidebar.html',
|
||
title: '01 · 深色侧栏藏青',
|
||
desc: '侧栏 #0f172a · 点缀天蓝 · Logo 绿最跳眼',
|
||
note: '风格差异大:深色导航 + 白内容区,很多 LIS/HIS 系统采用;Logo 绿色会非常醒目。',
|
||
primary: '#38bdf8',
|
||
dark: '#0ea5e9',
|
||
bg: 'rgba(56, 189, 248, 0.14)',
|
||
border: '#e2e8f0',
|
||
swatches: ['#0f172a', '#38bdf8', '#f8fafc', '#e2e8f0'],
|
||
darkSidebar: true,
|
||
recommended: true
|
||
},
|
||
{
|
||
id: '02',
|
||
file: '02-warm-stone.html',
|
||
title: '02 · 暖石米灰',
|
||
desc: '暖灰主色 #57534e · 米白底 · 不冷不艳',
|
||
note: '偏纸质/档案感,长时间看不疲劳;适合财务、合规、大量表格录入。',
|
||
primary: '#57534e',
|
||
dark: '#44403c',
|
||
bg: '#f5f5f4',
|
||
border: '#e7e5e4',
|
||
pageBg: '#fafaf9',
|
||
tableHead: '#f5f5f4',
|
||
text: '#292524',
|
||
textMuted: '#78716c',
|
||
swatches: ['#57534e', '#44403c', '#fafaf9', '#e7e5e4'],
|
||
warm: true
|
||
},
|
||
{
|
||
id: '03',
|
||
file: '03-medical-blue.html',
|
||
title: '03 · 经典医院蓝',
|
||
desc: '主色 #0077b6 · 传统医疗信息系统气质',
|
||
note: '比 Tailwind 蓝更「医院感」;稳重、熟悉,中老年用户接受度高。',
|
||
primary: '#0077b6',
|
||
dark: '#023e8a',
|
||
bg: '#e8f4fa',
|
||
border: '#bde0fe',
|
||
swatches: ['#0077b6', '#023e8a', '#e8f4fa', '#bde0fe']
|
||
},
|
||
{
|
||
id: '04',
|
||
file: '04-zinc-minimal.html',
|
||
title: '04 · 锌灰极简',
|
||
desc: '几乎无彩色 · 主按钮 #18181b · Logo 是唯一亮点',
|
||
note: '极简 B 端:界面本身不抢戏,状态 Tag 保留语义色;适合数据密集页面。',
|
||
primary: '#52525b',
|
||
dark: '#3f3f46',
|
||
bg: '#f4f4f5',
|
||
border: '#e4e4e7',
|
||
cta: '#18181b',
|
||
ctaDark: '#27272a',
|
||
swatches: ['#52525b', '#18181b', '#fafafa', '#e4e4e7']
|
||
},
|
||
{
|
||
id: '05',
|
||
file: '05-soft-violet.html',
|
||
title: '05 · 薄雾紫',
|
||
desc: '主色 #7c6fad · 舒缓、偏医疗康养',
|
||
note: '低饱和紫,比靛蓝更柔;适合客服、客户档案类模块,主列表页需实测。',
|
||
primary: '#7c6fad',
|
||
dark: '#6b5b95',
|
||
bg: '#f3f0f8',
|
||
border: '#ddd6fe',
|
||
swatches: ['#7c6fad', '#6b5b95', '#f3f0f8', '#ddd6fe']
|
||
},
|
||
{
|
||
id: '06',
|
||
file: '06-navy-authority.html',
|
||
title: '06 · 墨蓝权威',
|
||
desc: '主色 #1e3a5f · 传统企业门户',
|
||
note: '深藏青,权威合规感强;与绿色 Logo 对比清晰,适合审批流、协议类页面。',
|
||
primary: '#1e3a5f',
|
||
dark: '#152a45',
|
||
bg: '#eef2f6',
|
||
border: '#c5d0dc',
|
||
swatches: ['#1e3a5f', '#152a45', '#eef2f6', '#c5d0dc']
|
||
}
|
||
]
|
||
|
||
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
|
||
? ['导航', '按钮', '浅底', '边']
|
||
: theme.darkSidebar
|
||
? ['侧栏', '点缀', '内容', '边']
|
||
: ['主色', '深', '浅底', '边']
|
||
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: ${theme.text || '#1e293b'};`,
|
||
` --text-muted: ${theme.textMuted || '#64748b'};`,
|
||
` --border: ${theme.border};`,
|
||
` --bg-page: ${theme.pageBg || '#fefefe'};`,
|
||
` --surface: #ffffff;`,
|
||
` --table-head: ${theme.tableHead || '#f8fafc'};`,
|
||
` --row-alt: ${theme.warm ? '#f5f5f4' : '#fafafa'};`,
|
||
` --row-hover: ${theme.warm ? '#ececea' : '#f1f5f9'};`,
|
||
` --shadow: 0 1px 3px rgba(0, 0, 0, 0.05);`,
|
||
` --radius: 10px;`
|
||
]
|
||
if (theme.darkSidebar) {
|
||
lines.push(` --sidebar-bg: #0f172a;`, ` --sidebar-border: #1e293b;`)
|
||
}
|
||
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>' : ''
|
||
const bodyClass = theme.warm ? ' class="layout-warm"' : ''
|
||
const sidebarClass = theme.darkSidebar ? 'sidebar sidebar--dark' : 'sidebar'
|
||
|
||
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 B</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${bodyClass}>
|
||
<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="${sidebarClass}">
|
||
<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)
|
||
}
|