Files
opc-manager/templates/index.html
mac 8430c93b97 feat: 新增采购模块 + 财务表格重建
采购模块:
- 新增 purchase_records 表 + CRUD 路由 + bootstrap 数据加载
- 前端采购管理页面: 表格 + 弹窗新增/编辑 + 侧边栏入口

财务模块:
- 表格新增签约金额、执行率、回款率、付款率、毛利、毛利率列
- 状态/日期筛选统一为无边框下拉框,移至页面顶部工具栏
- 删除 metric 卡片,新增 11 张汇总卡片(签约金额~现金流)
- 表格合计行移至表头下方,后改为汇总卡片
- 所有单元格统一水平/垂直居中
- 修复季度视图 gross 变量缺失、合计行遗漏
2026-07-06 13:04:56 +08:00

128 lines
7.2 KiB
HTML
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.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>科普慰心斋OPC 工作台</title>
<script src="{{ url_for('static', filename='vendor/tailwind.js') }}"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
brand: {
50: '#eff6ff',
600: '#2563eb',
700: '#1d4ed8'
}
}
}
}
}
</script>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<script src="{{ url_for('static', filename='vendor/chart.js') }}" defer></script>
<script src="{{ url_for('static', filename='vendor/squire.js') }}" defer></script>
<script src="{{ url_for('static', filename='vendor/lucide.js') }}" defer></script>
</head>
<body class="min-h-screen bg-slate-50 text-slate-950">
<div class="flex min-h-screen">
<!-- 左侧工作台切换栏 -->
<aside class="w-[72px] bg-slate-900 flex flex-col items-center py-6 gap-1 shrink-0 sticky top-0 h-screen overflow-y-auto" id="workspaceSidebar">
<div class="flex flex-col items-center mb-2 cursor-pointer" onclick="document.getElementById('userAvatar').click()">
<div class="w-10 h-10 rounded-full bg-slate-700 flex items-center justify-center text-white font-bold text-sm hover:ring-2 hover:ring-blue-400 transition-all" id="userAvatar" title=""></div>
<span class="text-[10px] text-slate-400 mt-1.5 max-w-[64px] truncate text-center" id="userDisplayName" title=""></span>
</div>
<!-- 分隔线 -->
<div class="w-8 h-px bg-slate-700 my-2"></div>
<!-- 工作台切换按钮 -->
<div class="flex flex-col items-center cursor-pointer hover:bg-slate-800 rounded-lg py-2 px-1 w-14 transition-colors" onclick="toggleTenantMenu(event)">
<i data-lucide="layout-grid" style="width:18px;height:18px;color:#94a3b8"></i>
<span class="text-[10px] text-slate-400 mt-1 max-w-[56px] truncate text-center" id="currentTenantLabel">工作台</span>
<i data-lucide="chevron-down" style="width:12px;height:12px;color:#64748b;margin-top:2px"></i>
</div>
<!-- 分隔线 -->
<div class="w-8 h-px bg-slate-700 my-2"></div>
<!-- 导航 Tab 图标 -->
<div class="flex flex-col items-center gap-1 w-14" id="sidebarTabs">
<div class="sidebar-tab active" data-tab="home" onclick="switchTab('home')" title="首页">
<i data-lucide="home" style="width:20px;height:20px"></i>
<span class="text-[10px] mt-1">首页</span>
</div>
<div class="sidebar-tab" data-tab="finance" onclick="switchTab('finance')" title="经营管理">
<i data-lucide="briefcase-business" style="width:20px;height:20px"></i>
<span class="text-[10px] mt-1">财务</span>
</div>
<div class="sidebar-tab" data-tab="purchase" onclick="switchTab('purchase')" title="采购管理">
<i data-lucide="shopping-cart" style="width:20px;height:20px"></i>
<span class="text-[10px] mt-1">采购</span>
</div>
<div class="sidebar-tab" data-tab="projects" onclick="switchTab('projects')" title="重点工作与台账">
<i data-lucide="file-text" style="width:20px;height:20px"></i>
<span class="text-[10px] mt-1">台账</span>
</div>
<div class="sidebar-tab" data-tab="proposals" onclick="switchTab('proposals')" title="业务方案">
<i data-lucide="package" style="width:20px;height:20px"></i>
<span class="text-[10px] mt-1">方案</span>
</div>
<div class="sidebar-tab" data-tab="products" onclick="switchTab('products')" title="产品迭代">
<i data-lucide="wallet-cards" style="width:20px;height:20px"></i>
<span class="text-[10px] mt-1">产品</span>
</div>
</div>
</aside>
<!-- 主内容区 -->
<div class="flex-1 min-w-0">
<header class="topbar border-b border-slate-200 bg-white px-8 py-5">
<div class="flex items-center gap-3">
<div>
<p class="eyebrow text-xs font-semibold uppercase tracking-[0.18em] text-blue-700">OPC Manager</p>
<div class="flex items-center gap-3 mt-1">
<h1 class="text-2xl font-semibold" id="workspaceTitle">科普 OPC 工作台</h1>
</div>
</div>
</div>
</header>
<main class="px-8 py-6">
<section id="home" class="panel active"></section>
<section id="projects" class="panel"></section>
<section id="proposals" class="panel"></section>
<section id="products" class="panel"></section>
<section id="finance" class="panel"></section>
<section id="purchase" class="panel"></section>
</main>
</div><!-- 关闭主内容区 -->
</div><!-- 关闭 flex 容器 -->
<aside id="drawer" class="drawer" aria-hidden="true"></aside>
<div id="taskModal" class="task-modal"></div>
<!-- 新增项目模态框 -->
<div id="newProjectModal" class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/40" onclick="closeNewProjectModal()">
<div class="bg-white rounded-2xl shadow-2xl w-full max-w-md mx-4" onclick="event.stopPropagation()">
<div class="flex items-center justify-between px-6 py-4 border-b border-slate-100">
<h3 class="text-lg font-semibold text-slate-800">新增项目</h3>
<button class="btn btn-ghost btn-sm rounded-full w-8 h-8 p-0" onclick="closeNewProjectModal()"><i data-lucide="x"></i></button>
</div>
<form onsubmit="createOperation(event)" class="p-6 grid gap-4">
<label class="block"><span class="text-xs font-medium text-slate-500">项目名称</span><input name="project_name" required class="form-ctrl mt-1"></label>
<label class="block"><span class="text-xs font-medium text-slate-500">项目备注</span><textarea name="notes" rows="3" class="form-ctrl mt-1" placeholder="可选"></textarea></label>
<div class="flex justify-end gap-3 pt-3 border-t border-slate-100">
<button type="button" class="btn btn-ghost btn-sm" onclick="closeNewProjectModal()">取消</button>
<button type="submit" class="btn btn-primary btn-sm">创建</button>
</div>
</form>
</div>
</div>
<script src="{{ url_for('static', filename='modules/utils.js') }}"></script>
<script src="{{ url_for('static', filename='modules/home.js') }}"></script>
<script src="{{ url_for('static', filename='modules/projects.js') }}"></script>
<script src="{{ url_for('static', filename='modules/proposals.js') }}"></script>
<script src="{{ url_for('static', filename='modules/products.js') }}"></script>
<script src="{{ url_for('static', filename='modules/finance.js') }}"></script>
<script src="{{ url_for('static', filename='modules/purchase.js') }}"></script>
<script src="{{ url_for('static', filename='modules/drawer.js') }}"></script>
<script src="{{ url_for('static', filename='modules/admin.js') }}"></script>
<script src="{{ url_for('static', filename='app.js') }}"></script>
</body>
</html>