feat: 绩效模块重构 + UI 统一样式 + 标题联动

- 新增绩效模块(季度考核表,目标/完成/权重/评分,localStorage)
- 产品模块增加版本迭代/产品运营双Tab
- 方案模块Tab改为下划线样式
- 顶部标题随模块切换联动更新
- OPC来信弹窗恢复并采用信件样式排版
- 费用模块移入业务顶部Tab(平台费用)
- 侧边栏:项目→业务,台账→Focus,新增绩效
- 顶部品牌区增加版本号显示v1.0.0.2
This commit is contained in:
mac
2026-07-07 15:56:13 +08:00
parent c12389fb89
commit 075350a026
7 changed files with 208 additions and 29 deletions

View File

@@ -187,8 +187,13 @@ function renderProducts() {
return productSort.dir > 0 ? '<i data-lucide="chevron-up" style="width:12px;height:12px"></i>' : '<i data-lucide="chevron-down" style="width:12px;height:12px"></i>';
};
const sortTh = (f, label, extra='') => `<th class="px-3 py-2.5 font-semibold align-middle whitespace-nowrap cursor-pointer hover:text-blue-600 select-none" onclick="sortProducts('${f}')"><span class="inline-flex items-center gap-1">${label}${sortIcon(f)}</span>${extra}</th>`;
const tab = state.productTab || 'version';
const tabs = `<div class="finance-tabs" style="padding:0;border-bottom:1px solid #e2e8f0"><button onclick="switchProductTab('version')" class="finance-tab${tab==='version'?' active':''}" style="font-size:14px;font-weight:600">版本迭代</button><button onclick="switchProductTab('ops')" class="finance-tab${tab==='ops'?' active':''}" style="font-size:14px;font-weight:600">产品运营</button></div>`;
document.querySelector("#products").innerHTML = `
<div class="grid gap-4">
${tabs}
${tab === 'version' ? `
<div class="flex justify-end">
<button class="btn btn-primary btn-sm" onclick="openProductDrawer()"><i data-lucide="plus"></i>新增产品版本</button>
</div>
@@ -230,6 +235,7 @@ function renderProducts() {
</div>
</div>
<aside id="productDrawer" class="task-drawer"></aside>
` : `<section class="card p-6 max-w-4xl"><p class="text-slate-700 leading-relaxed mb-4"><strong>和内部联动真正快速做实交付很重要</strong></p><ol class="list-decimal list-inside space-y-3 text-slate-600 leading-relaxed"><li></li><li> H5 </li><li> H5 </li><li></li><li>AI </li><li> AI + 访</li><li></li></ol><hr class="my-6 border-slate-200"><p class="text-slate-700 font-semibold leading-relaxed"></p></section>`}
`;
if (window.lucide) window.lucide.createIcons();
}
@@ -342,3 +348,8 @@ window.cyclePriority = async (id) => {
renderProducts();
} catch (e) { toast("更新失败:" + e.message, "error"); }
};
window.switchProductTab = (v) => {
state.productTab = v;
renderProducts();
};