Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19ae81ae6e | ||
|
|
535af35911 | ||
|
|
fc338f426a | ||
|
|
5300ee426d | ||
|
|
8ac6f1af6b | ||
|
|
8c81fae334 |
1
app.py
1
app.py
@@ -137,6 +137,7 @@ def compute_stats():
|
|||||||
all_study_items.append({
|
all_study_items.append({
|
||||||
'name': name.strip(),
|
'name': name.strip(),
|
||||||
'done': si.get('done', False) if isinstance(si, dict) else False,
|
'done': si.get('done', False) if isinstance(si, dict) else False,
|
||||||
|
'note': si.get('note', '') if isinstance(si, dict) else '',
|
||||||
'pillar': pillar
|
'pillar': pillar
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1009,34 +1009,82 @@
|
|||||||
Blueprint — 蓝图六板块
|
Blueprint — 蓝图六板块
|
||||||
================================================================ */
|
================================================================ */
|
||||||
|
|
||||||
|
var blueprintData = null;
|
||||||
|
var blueprintFilter = 'all';
|
||||||
|
|
||||||
function loadBlueprint() {
|
function loadBlueprint() {
|
||||||
apiGetStats(function(err, data) {
|
apiGetStats(function(err, data) {
|
||||||
if (err || !data || !data.pillar_breakdown) return;
|
if (err || !data || !data.pillar_breakdown) return;
|
||||||
var pb = data.pillar_breakdown;
|
blueprintData = data.pillar_breakdown;
|
||||||
PILLARS.forEach(function(p){
|
renderBlueprintList();
|
||||||
var el = document.getElementById('bp-count-' + p.name);
|
|
||||||
var info = pb[p.name] || {};
|
|
||||||
var m = info.morning || 0, e = info.evening || 0, s = info.study || 0;
|
|
||||||
if (el) el.textContent = '立志' + m + ' · 责善' + e + ' · 勤学' + s;
|
|
||||||
// 显示详情列表
|
|
||||||
var detailEl = document.getElementById('bp-detail-' + p.name);
|
|
||||||
if (detailEl) {
|
|
||||||
var html = '';
|
|
||||||
(info.morning_items || []).forEach(function(mi){
|
|
||||||
html += '<div class="bp-item" data-type="morning">🥼 ' + esc(mi.text) + '</div>';
|
|
||||||
});
|
|
||||||
(info.evening_items || []).forEach(function(ei){
|
|
||||||
html += '<div class="bp-item" data-type="evening">🔍 ' + esc(ei.mistake || ei.improvement) + '</div>';
|
|
||||||
});
|
|
||||||
(info.study_items || []).forEach(function(si){
|
|
||||||
html += '<div class="bp-item" data-type="study">📚 ' + esc(si.name) + '</div>';
|
|
||||||
});
|
|
||||||
detailEl.innerHTML = html || '<div class="bp-empty">暂无记录</div>';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderBlueprintPillars(pb) {
|
||||||
|
var container = document.getElementById('blueprint-pillars');
|
||||||
|
if (!container) return;
|
||||||
|
var html = '';
|
||||||
|
PILLARS.forEach(function(p){
|
||||||
|
html += '<div class="blueprint-pillar" data-pillar="' + p.name + '">' +
|
||||||
|
'<div class="bp-icon">' + p.emoji + '</div>' +
|
||||||
|
'<div class="bp-name">' + p.name + '</div>' +
|
||||||
|
'</div>';
|
||||||
|
});
|
||||||
|
container.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBlueprintList() {
|
||||||
|
var list = document.getElementById('bp-list');
|
||||||
|
var empty = document.getElementById('bp-list-empty');
|
||||||
|
if (!list || !blueprintData) return;
|
||||||
|
var items = [];
|
||||||
|
PILLARS.forEach(function(p){
|
||||||
|
var info = blueprintData[p.name] || {};
|
||||||
|
if (blueprintFilter === 'all' || blueprintFilter === 'morning') {
|
||||||
|
(info.morning_items || []).forEach(function(mi){ items.push({pillar: p, text: mi.text, type: 'morning'}); });
|
||||||
|
}
|
||||||
|
if (blueprintFilter === 'all' || blueprintFilter === 'evening') {
|
||||||
|
(info.evening_items || []).forEach(function(ei){ items.push({pillar: p, text: ei.mistake || ei.improvement, improvement: ei.improvement, type: 'evening'}); });
|
||||||
|
}
|
||||||
|
if (blueprintFilter === 'all' || blueprintFilter === 'study') {
|
||||||
|
(info.study_items || []).forEach(function(si){ items.push({pillar: p, text: si.name, type: 'study', done: si.done, note: si.note}); });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (items.length === 0) {
|
||||||
|
list.innerHTML = '';
|
||||||
|
if (empty) empty.style.display = 'block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (empty) empty.style.display = 'none';
|
||||||
|
var typeLabels = {morning: '立志', evening: '责善', study: '勤学'};
|
||||||
|
var pillarColors = {
|
||||||
|
'医疗服务': '#4A6CF7', '医药营销': '#D97706', '医疗支付': '#059669',
|
||||||
|
'AI 智能': '#7C3AED', '公司治理': '#DC2626', '个人修养': '#0891B2'
|
||||||
|
};
|
||||||
|
var html = '';
|
||||||
|
items.forEach(function(item){
|
||||||
|
var dot = '<span class="bp-pillar-dot" style="background:' + (pillarColors[item.pillar.name] || '#94A3B8') + '"></span>';
|
||||||
|
var extra = '';
|
||||||
|
if (item.type === 'study' && item.note) extra = '<span class="bp-item-note">' + esc(item.note) + '</span>';
|
||||||
|
if (item.type === 'evening' && item.improvement) extra = '<span class="bp-item-note evening">→ ' + esc(item.improvement) + '</span>';
|
||||||
|
html += '<div class="bp-list-item">' +
|
||||||
|
dot +
|
||||||
|
'<span class="bp-item-pillar">' + item.pillar.name + '</span>' +
|
||||||
|
'<span class="bp-item-type ' + item.type + '">' + (typeLabels[item.type] || item.type) + '</span>' +
|
||||||
|
'<span class="bp-item-text">' + esc(item.text) + '</span>' +
|
||||||
|
extra +
|
||||||
|
'</div>';
|
||||||
|
});
|
||||||
|
list.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.filterBlueprint = function(btn) {
|
||||||
|
blueprintFilter = btn.dataset.filter;
|
||||||
|
document.querySelectorAll('.bp-tab').forEach(function(t){ t.classList.remove('active'); });
|
||||||
|
btn.classList.add('active');
|
||||||
|
renderBlueprintList();
|
||||||
|
};
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
Init
|
Init
|
||||||
================================================================ */
|
================================================================ */
|
||||||
|
|||||||
118
static/style.css
118
static/style.css
@@ -1428,59 +1428,93 @@ body {
|
|||||||
Blueprint Panel
|
Blueprint Panel
|
||||||
═══════════════════════════════════════════ */
|
═══════════════════════════════════════════ */
|
||||||
|
|
||||||
.blueprint-mission {
|
/* Tab 筛选 */
|
||||||
font-size: 15px;
|
.bp-tabs {
|
||||||
font-weight: 600;
|
display: flex;
|
||||||
color: var(--primary);
|
gap: 4px;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 20px;
|
||||||
padding: 12px 16px;
|
border-bottom: 1.5px solid var(--border);
|
||||||
background: var(--primary-light);
|
padding-bottom: 0;
|
||||||
border-radius: var(--radius);
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
.bp-tab {
|
||||||
.blueprint-pillars {
|
display: inline-flex;
|
||||||
display: grid;
|
align-items: center;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
gap: 5px;
|
||||||
gap: 16px;
|
padding: 8px 16px;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--text-dim);
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
margin-bottom: -1.5px;
|
||||||
|
transition: all 0.15s;
|
||||||
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
|
.bp-tab .icon-sm { opacity: 0.6; }
|
||||||
|
.bp-tab:hover { color: var(--text); }
|
||||||
|
.bp-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
|
||||||
|
.bp-tab.active .icon-sm { opacity: 1; }
|
||||||
|
|
||||||
.blueprint-pillar {
|
/* 明细列表 */
|
||||||
|
.bp-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1px;
|
||||||
|
}
|
||||||
|
.bp-list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px 14px;
|
||||||
background: var(--card);
|
background: var(--card);
|
||||||
border: 1.5px solid var(--border);
|
border-bottom: 0.5px solid var(--border);
|
||||||
border-radius: var(--radius);
|
transition: background 0.15s;
|
||||||
padding: 20px 16px;
|
|
||||||
text-align: center;
|
|
||||||
transition: border-color 0.2s, box-shadow 0.2s;
|
|
||||||
}
|
}
|
||||||
.blueprint-pillar:hover {
|
.bp-list-item:hover { background: var(--bg); }
|
||||||
border-color: var(--primary);
|
.bp-pillar-dot {
|
||||||
box-shadow: 0 4px 16px rgba(74,108,247,0.08);
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
.bp-item-pillar {
|
||||||
.bp-icon { font-size: 32px; margin-bottom: 8px; }
|
font-size: 12px;
|
||||||
.bp-name { font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
|
|
||||||
.bp-desc { font-size: 11px; color: var(--text-muted); margin-bottom: 10px; line-height: 1.5; }
|
|
||||||
.bp-count { font-size: 13px; font-weight: 600; color: var(--primary); }
|
|
||||||
|
|
||||||
.bp-detail {
|
|
||||||
margin-top: 10px;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 11px;
|
|
||||||
max-height: 120px;
|
|
||||||
overflow-y: auto;
|
|
||||||
border-top: 1px solid var(--border);
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
.bp-item {
|
|
||||||
padding: 2px 0;
|
|
||||||
color: var(--text-dim);
|
color: var(--text-dim);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.bp-item-type {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.bp-item-type.morning { background: var(--warning-light); color: #D97706; }
|
||||||
|
.bp-item-type.evening { background: var(--danger-light); color: var(--danger); }
|
||||||
|
.bp-item-type.study { background: var(--success-light); color: var(--success); }
|
||||||
|
.bp-item-text {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.bp-item-note {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-left: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.bp-item-note.evening { color: var(--danger); }
|
||||||
|
.bp-list-empty {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
text-align: center;
|
||||||
|
padding: 32px 0;
|
||||||
}
|
}
|
||||||
.bp-empty { color: var(--text-muted); text-align: center; padding: 6px 0; }
|
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
.blueprint-pillars { grid-template-columns: repeat(2, 1fr); }
|
.quad-grid { grid-template-columns: 1fr; grid-template-rows: auto; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,8 +108,8 @@
|
|||||||
历史记录
|
历史记录
|
||||||
</a>
|
</a>
|
||||||
<a class="nav-item" data-panel="blueprint" onclick="switchPanel('blueprint')">
|
<a class="nav-item" data-panel="blueprint" onclick="switchPanel('blueprint')">
|
||||||
<svg class="icon-sm"><use href="#icon-star"/></svg>
|
<svg class="icon-sm"><use href="#icon-sun"/></svg>
|
||||||
蓝图
|
人生蓝图
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -276,55 +276,26 @@
|
|||||||
<!-- ── 蓝图面板 ── -->
|
<!-- ── 蓝图面板 ── -->
|
||||||
<section class="panel" id="panel-blueprint">
|
<section class="panel" id="panel-blueprint">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
<h2>蓝图 · 数字医疗集团</h2>
|
<h2>人生蓝图</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="blueprint-mission">
|
<!-- Tab 筛选 -->
|
||||||
一辈子,干成一件事 — 用 AI 重构医疗全链路
|
<div class="bp-tabs">
|
||||||
</div>
|
<button class="bp-tab active" data-filter="all" onclick="filterBlueprint(this)">
|
||||||
<div class="blueprint-pillars" id="blueprint-pillars">
|
<svg class="icon-sm"><use href="#icon-list-bullet"/></svg> 全部
|
||||||
<div class="blueprint-pillar" data-pillar="医疗服务">
|
</button>
|
||||||
<div class="bp-icon">🥼</div>
|
<button class="bp-tab" data-filter="morning" onclick="filterBlueprint(this)">
|
||||||
<div class="bp-name">医疗服务</div>
|
<svg class="icon-sm"><use href="#icon-bolt"/></svg> 立志
|
||||||
<div class="bp-desc">诊疗能力 · 临床路径 · 医疗质量</div>
|
</button>
|
||||||
<div class="bp-count" id="bp-count-医疗服务">—</div>
|
<button class="bp-tab" data-filter="evening" onclick="filterBlueprint(this)">
|
||||||
<div class="bp-detail" id="bp-detail-医疗服务"></div>
|
<svg class="icon-sm"><use href="#icon-magnifying-glass"/></svg> 责善
|
||||||
</div>
|
</button>
|
||||||
<div class="blueprint-pillar" data-pillar="医药营销">
|
<button class="bp-tab" data-filter="study" onclick="filterBlueprint(this)">
|
||||||
<div class="bp-icon">💊</div>
|
<svg class="icon-sm"><use href="#icon-book-open"/></svg> 勤学
|
||||||
<div class="bp-name">医药营销</div>
|
</button>
|
||||||
<div class="bp-desc">科普 · 科研 · 学术会议 · 患者管理</div>
|
|
||||||
<div class="bp-count" id="bp-count-医药营销">—</div>
|
|
||||||
<div class="bp-detail" id="bp-detail-医药营销"></div>
|
|
||||||
</div>
|
|
||||||
<div class="blueprint-pillar" data-pillar="医疗支付">
|
|
||||||
<div class="bp-icon">🛡️</div>
|
|
||||||
<div class="bp-name">医疗支付</div>
|
|
||||||
<div class="bp-desc">医保 · 商保 · 支付闭环</div>
|
|
||||||
<div class="bp-count" id="bp-count-医疗支付">—</div>
|
|
||||||
<div class="bp-detail" id="bp-detail-医疗支付"></div>
|
|
||||||
</div>
|
|
||||||
<div class="blueprint-pillar" data-pillar="AI 智能">
|
|
||||||
<div class="bp-icon">🤖</div>
|
|
||||||
<div class="bp-name">AI 智能</div>
|
|
||||||
<div class="bp-desc">数字人 · 智能平台 · AI 赋能</div>
|
|
||||||
<div class="bp-count" id="bp-count-AI 智能">—</div>
|
|
||||||
<div class="bp-detail" id="bp-detail-AI 智能"></div>
|
|
||||||
</div>
|
|
||||||
<div class="blueprint-pillar" data-pillar="公司治理">
|
|
||||||
<div class="bp-icon">🏛️</div>
|
|
||||||
<div class="bp-name">公司治理</div>
|
|
||||||
<div class="bp-desc">组织 · 人才 · 制度 · 文化</div>
|
|
||||||
<div class="bp-count" id="bp-count-公司治理">—</div>
|
|
||||||
<div class="bp-detail" id="bp-detail-公司治理"></div>
|
|
||||||
</div>
|
|
||||||
<div class="blueprint-pillar" data-pillar="个人修养">
|
|
||||||
<div class="bp-icon">🎯</div>
|
|
||||||
<div class="bp-name">个人修养</div>
|
|
||||||
<div class="bp-desc">立志 · 责善 · 改过 · 勤学</div>
|
|
||||||
<div class="bp-count" id="bp-count-个人修养">—</div>
|
|
||||||
<div class="bp-detail" id="bp-detail-个人修养"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 明细列表 -->
|
||||||
|
<div class="bp-list" id="bp-list"></div>
|
||||||
|
<div class="bp-list-empty" id="bp-list-empty" style="display:none">暂无记录</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
Reference in New Issue
Block a user