This commit is contained in:
Jimmy
2026-04-27 15:24:41 +08:00
parent 29954a7af0
commit 0cea74ad97
8 changed files with 2123 additions and 0 deletions

220
web_ui/templates/home.html Normal file
View File

@@ -0,0 +1,220 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ERP 成本与数据看板 - 主控台</title>
<!-- 引入 ElementUI 样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入 Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<!-- 引入 ElementUI 组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- 引入 axios -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
body {
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.dashboard-container {
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
padding: 40px;
width: 80%;
max-width: 900px;
text-align: center;
}
.header-title {
color: #303133;
font-size: 28px;
margin-bottom: 10px;
font-weight: 600;
}
.header-subtitle {
color: #909399;
font-size: 16px;
margin-bottom: 40px;
}
.nav-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
}
.nav-card {
border: 1px solid #ebeef5;
border-radius: 8px;
padding: 30px 20px;
cursor: pointer;
transition: all 0.3s cubic-bezier(.25,.8,.25,1);
background-color: #fafafa;
display: flex;
flex-direction: column;
align-items: center;
}
.nav-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.08);
border-color: #409EFF;
background-color: #ecf5ff;
}
.nav-card i {
font-size: 48px;
color: #409EFF;
margin-bottom: 15px;
}
.nav-card h3 {
margin: 0 0 10px 0;
color: #303133;
font-size: 20px;
}
.nav-card p {
margin: 0;
color: #606266;
font-size: 14px;
line-height: 1.5;
}
/* 特定卡片的颜色定制 */
.card-receipt:hover { border-color: #67C23A; background-color: #f0f9eb; }
.card-receipt i { color: #67C23A; }
.card-bom-tree:hover { border-color: #409EFF; background-color: #ecf5ff; }
.card-bom-tree i { color: #409EFF; }
.card-bom-compare:hover { border-color: #E6A23C; background-color: #fdf6ec; }
.card-bom-compare i { color: #E6A23C; }
.action-group {
margin-top: 40px;
padding-top: 30px;
border-top: 1px dashed #ebeef5;
display: flex;
justify-content: center;
gap: 20px;
}
</style>
</head>
<body>
<div class="dashboard-container" id="app">
<div class="header-title">ERP 数据分析与成本管控台</div>
<div class="header-subtitle">请选择您需要进入的业务模块</div>
<div class="nav-grid">
<!-- 卡片 1: 收货明细表 -->
<div class="nav-card card-receipt" onclick="window.location.href='/receipts'">
<i class="el-icon-document"></i>
<h3>收货明细报表</h3>
<p>查看、搜索所有历史收货记录及详细价格数据。</p>
</div>
<!-- 卡片 2: BOM 雷达图 -->
<div class="nav-card card-bom-tree" onclick="window.location.href='/bom'">
<i class="el-icon-share"></i>
<h3>BOM 成本雷达图</h3>
<p>以关系图谱形式可视化展示产品的层级结构与汇总成本。</p>
</div>
<!-- 卡片 3: 期间成本对比 -->
<div class="nav-card card-bom-compare" onclick="window.location.href='/compare'">
<i class="el-icon-data-line"></i>
<h3>期间成本对比分析表</h3>
<p>跨时间段核算 BOM 最新价差异,支持虚拟件过滤与历史价回溯。</p>
</div>
</div>
<div class="action-group">
<el-button
type="success"
:icon="syncing ? '' : 'el-icon-refresh'"
:loading="syncing"
@click="syncReceipts"
round>
<span v-text="syncing ? '正在后台同步增量数据,请稍候...' : '读取最新收货明细报表'"></span>
</el-button>
<el-button
type="primary"
:icon="syncingBom ? '' : 'el-icon-refresh-right'"
:loading="syncingBom"
@click="syncBom"
round>
<span v-text="syncingBom ? '正在后台抓取 BOM 树,耗时较长,请稍候...' : '读取最新 BOM 表'"></span>
</el-button>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
syncing: false,
syncingBom: false
}
},
methods: {
syncReceipts() {
this.syncing = true;
axios.post('/api/sync_receipts')
.then(res => {
if (res.data.success) {
this.$message.success('明细同步成功!' + res.data.message);
} else {
this.$message.error('同步失败:' + res.data.message);
}
})
.catch(err => {
this.$message.error('请求发生异常,请检查后端日志。');
console.error(err);
})
.finally(() => {
this.syncing = false;
});
},
syncBom() {
this.syncingBom = true;
axios.post('/api/sync_bom')
.then(res => {
if (res.data.success) {
this.$message.success('BOM 同步成功!' + res.data.message);
} else {
this.$message.error('同步失败:' + res.data.message);
}
})
.catch(err => {
this.$message.error('请求发生异常,这可能需要较长时间,请检查控制台日志。');
console.error(err);
})
.finally(() => {
this.syncingBom = false;
});
}
}
});
</script>
</body>
</html>