Browse Source

库存前端推送

Gogs 4 tháng trước cách đây
mục cha
commit
4ef71a4c4f

+ 282 - 0
src/views/storage/accuracy/index.vue

@@ -0,0 +1,282 @@
+<template>
+  <div class="semi-product">
+    <!-- 半成品概览 -->
+    <el-row :gutter="20" class="overview-row">
+      <el-col :span="6">
+        <el-card class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon" style="background-color: #409eff;">
+              <!-- Replace Box icon with text symbol -->
+              <span style="font-size:28px; color:#fff;">📦</span>
+            </div>
+            <div class="stat-info">
+              <div class="stat-label">半成品总数</div>
+              <div class="stat-value">-</div>
+              <div class="stat-unit">种</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon" style="background-color: #67c23a;">
+              <!-- Replace Goods icon with text symbol -->
+              <span style="font-size:28px; color:#fff;">📦</span>
+            </div>
+            <div class="stat-info">
+              <div class="stat-label">库存数量</div>
+              <div class="stat-value">-</div>
+              <div class="stat-unit">件</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card">
+          <div class="stat-content">
+            <div class="stat-icon" style="background-color: #909399;">
+              <!-- Replace Goods icon with text symbol -->
+              <span style="font-size:28px; color:#fff;">📦</span>
+            </div>
+            <div class="stat-info">
+              <div class="stat-label">预计可生产成品</div>
+              <div class="stat-value">-</div>
+              <div class="stat-unit">件</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 搜索与操作栏 -->
+    <el-card class="search-card">
+      <el-row :gutter="20" align="middle">
+        <el-col :span="6">
+          <el-input
+            placeholder="搜索半成品名称/编码"
+            clearable
+          >
+            <template #prefix>
+              <!-- Replace Search icon with text symbol -->
+              <span style="font-size:16px; color:#909399;">🔍</span>
+            </template>
+          </el-input>
+        </el-col>
+        <el-col :span="4">
+          <el-select placeholder="状态筛选" clearable>
+            <el-option label="全部" value="" />
+            <el-option label="在库" value="in-stock" />
+            <el-option label="在制" value="in-production" />
+            <el-option label="待检" value="pending" />
+            <el-option label="已用" value="used" />
+          </el-select>
+        </el-col>
+        <el-col :span="4">
+          <el-select placeholder="类别筛选" clearable>
+            <el-option label="全部" value="" />
+            <el-option label="电子元件" value="electronics" />
+            <el-option label="机械部件" value="mechanics" />
+            <el-option label="外壳模组" value="housing" />
+            <el-option label="电路板" value="pcb" />
+          </el-select>
+        </el-col>
+        <el-col :span="6">
+          <el-button type="primary">
+            <!-- Replace Search icon with text -->
+            🔍 搜索
+          </el-button>
+          <el-button>
+            <!-- Replace RefreshLeft icon with text -->
+            🔄 重置
+          </el-button>
+        </el-col>
+        <el-col :span="4" style="text-align: right;">
+          <el-button type="success">
+            <!-- Replace Plus icon with text -->
+            ➕ 新增半成品
+          </el-button>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 可组装成品能力 -->
+    <el-card class="assembly-card" style="margin-bottom: 20px;">
+      <template #header>
+        <div style="display:flex; justify-content:space-between; align-items:center;">
+          <span>可组装成品能力(基于入库库存)</span>
+          <el-button type="primary" size="small">刷新</el-button>
+        </div>
+      </template>
+      <el-table stripe style="width: 100%">
+        <el-table-column label="成品编码" width="180" />
+        <el-table-column label="名称" width="220" />
+        <el-table-column label="可组装数量" width="140" />
+        <el-table-column label="所需半成品及库存" />
+      </el-table>
+    </el-card>
+
+    <!-- 半成品列表 -->
+    <el-card class="table-card">
+      <el-table stripe style="width: 100%">
+        <el-table-column type="selection" width="55" />
+        <el-table-column label="编码" width="120" fixed />
+        <el-table-column label="半成品名称" width="200" />
+        <el-table-column label="类别" width="120" />
+        <el-table-column label="库存数量" width="100" />
+        <el-table-column label="安全库存" width="100" />
+        <el-table-column label="状态" width="100" />
+        <el-table-column label="可用于组装" width="150" />
+        <el-table-column label="供应商" width="150" />
+        <el-table-column label="采购周期" width="100" />
+        <el-table-column label="单价(元)" width="100" />
+        <el-table-column label="库存价值(元)" width="120" />
+        <el-table-column label="操作" width="240" fixed="right">
+          <template #default>
+            <el-button type="primary" size="small">详情</el-button>
+            <el-button type="success" size="small">编辑</el-button>
+            <el-button type="warning" size="small">组装</el-button>
+            <el-button type="danger" size="small">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <el-pagination
+        :current-page="1"
+        :page-size="10"
+        :total="0"
+        :page-sizes="[10, 20, 50, 100]"
+        layout="total, sizes, prev, pager, next, jumper"
+        style="margin-top: 20px; justify-content: flex-end;"
+      />
+    </el-card>
+
+    <!-- 半成品分析图表 -->
+    <el-row :gutter="20" class="charts-row">
+      <el-col :span="12">
+        <el-card>
+          <template #header>
+            <span>半成品库存分布</span>
+          </template>
+          <div style="height: 300px; display: flex; align-items: center; justify-content: center; color: #909399;">
+            暂无图表数据
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card>
+          <template #header>
+            <span>半成品使用趋势</span>
+          </template>
+          <div style="height: 300px; display: flex; align-items: center; justify-content: center; color: #909399;">
+            暂无图表数据
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+
+
+    <!-- 半成品周转分析 -->
+    <el-card class="turnover-card">
+      <template #header>
+        <span>半成品周转效率分析</span>
+      </template>
+      <el-table stripe>
+        <el-table-column label="半成品名称" width="200" />
+        <el-table-column label="平均周转天数" width="150" />
+        <el-table-column label="使用率" width="120" />
+        <el-table-column label="月消耗量" width="120" />
+        <el-table-column label="再订货点" width="120" />
+        <el-table-column label="库存状态" width="120" />
+        <el-table-column label="优化建议" min-width="250" />
+      </el-table>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+  // REMOVED ALL ICON IMPORTS (no @element-plus/icons-vue dependency)
+</script>
+
+<style scoped>
+  .semi-product {
+    width: 100%;
+  }
+
+  .overview-row {
+    margin-bottom: 20px;
+  }
+
+  .stat-card {
+    cursor: pointer;
+    transition: all 0.3s;
+  }
+
+  .stat-card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  }
+
+  .stat-content {
+    display: flex;
+    align-items: center;
+    gap: 15px;
+  }
+
+  .stat-icon {
+    width: 56px;
+    height: 56px;
+    border-radius: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+  }
+
+  .stat-info {
+    flex: 1;
+  }
+
+  .stat-label {
+    font-size: 14px;
+    color: #909399;
+    margin-bottom: 8px;
+  }
+
+  .stat-value {
+    font-size: 28px;
+    font-weight: bold;
+    color: #303133;
+    line-height: 1;
+  }
+
+  .stat-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-top: 4px;
+  }
+
+  .search-card {
+    margin-bottom: 20px;
+  }
+
+  .table-card {
+    margin-bottom: 20px;
+  }
+
+  .charts-row {
+    margin-bottom: 20px;
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .bom-card,
+  .turnover-card {
+    margin-bottom: 20px;
+  }
+</style>

+ 262 - 0
src/views/storage/cost/index.vue

@@ -0,0 +1,262 @@
+<template>
+  <div class="risk-warning">
+    <!-- 风险总览卡片 -->
+    <el-row :gutter="20" class="risk-overview">
+      <el-col :span="6">
+        <el-card class="risk-card critical">
+          <div class="risk-header">
+            <!-- Replace WarningFilled icon with symbol -->
+            <span style="font-size:32px; color:#f56c6c;">⚠️</span>
+            <div class="risk-info">
+              <div class="risk-label">高风险</div>
+              <div class="risk-count">-</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="risk-card warning">
+          <div class="risk-header">
+            <!-- Replace Warning icon with symbol -->
+            <span style="font-size:32px; color:#e6a23c;">⚠️</span>
+            <div class="risk-info">
+              <div class="risk-label">中风险</div>
+              <div class="risk-count">-</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="risk-card info">
+          <div class="risk-header">
+            <!-- Replace InfoFilled icon with symbol -->
+            <span style="font-size:32px; color:#409eff;">ℹ️</span>
+            <div class="risk-info">
+              <div class="risk-label">低风险</div>
+              <div class="risk-count">-</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="risk-card safe">
+          <div class="risk-header">
+            <!-- Replace SuccessFilled icon with symbol -->
+            <span style="font-size:32px; color:#67c23a;">✅</span>
+            <div class="risk-info">
+              <div class="risk-label">正常</div>
+              <div class="risk-count">-</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 风险列表与筛选 -->
+    <el-card class="risk-list-card">
+      <template #header>
+        <div class="card-header">
+          <span>风险预警列表</span>
+          <div class="filter-group">
+            <el-select placeholder="风险等级" size="default" style="width: 120px">
+              <el-option label="全部" value="" />
+              <el-option label="高风险" value="critical" />
+              <el-option label="中风险" value="warning" />
+              <el-option label="低风险" value="info" />
+            </el-select>
+            <el-select placeholder="风险类型" size="default" style="width: 140px">
+              <el-option label="全部" value="" />
+              <el-option label="缺货风险" value="stockout" />
+              <el-option label="超储风险" value="overstock" />
+              <el-option label="滞销风险" value="slow-moving" />
+              <el-option label="周转风险" value="turnover" />
+            </el-select>
+            <el-button type="primary">
+              <!-- Replace Refresh icon with symbol -->
+              🔄 刷新
+            </el-button>
+          </div>
+        </div>
+      </template>
+
+      <el-table stripe style="width: 100%" :loading="false">
+        <el-table-column label="编号" width="80" />
+        <el-table-column label="产品名称" width="200" />
+        <el-table-column label="产品编码" width="120" />
+        <el-table-column label="风险等级" width="120" />
+        <el-table-column label="风险类型" width="140" />
+        <el-table-column label="健康评分" width="150" />
+        <el-table-column label="周转率" width="100" />
+        <el-table-column label="风险评分" width="100" />
+        <el-table-column label="覆盖天数" width="110" />
+        <el-table-column label="当前库存" width="110" />
+        <el-table-column label="日均销量" width="110" />
+        <el-table-column label="风险描述" min-width="200" />
+        <el-table-column label="建议措施" min-width="200" />
+        <el-table-column label="检测时间" width="180" />
+      </el-table>
+
+      <el-pagination
+        :current-page="1"
+        :page-size="10"
+        :total="0"
+        :page-sizes="[10, 20, 50, 100]"
+        layout="total, sizes, prev, pager, next, jumper"
+        style="margin-top: 20px; justify-content: flex-end;"
+      />
+    </el-card>
+
+    <!-- 智能预警规则配置 -->
+    <el-card class="rule-card">
+      <template #header>
+        <div class="card-header">
+          <span>智能预警规则配置</span>
+          <el-button type="primary" size="small">
+            <!-- Replace Plus icon with symbol -->
+            ➕ 添加规则
+          </el-button>
+        </div>
+      </template>
+
+      <el-table stripe>
+        <el-table-column label="规则名称" width="200" />
+        <el-table-column label="触发条件" min-width="300" />
+        <el-table-column label="风险等级" width="120" />
+        <el-table-column label="状态" width="100" />
+        <el-table-column label="触发次数" width="100" />
+      </el-table>
+    </el-card>
+
+    <!-- 反馈优化建议 -->
+    <el-card class="feedback-card">
+      <template #header>
+        <div class="card-header">
+          <span>系统优化建议与反馈</span>
+          <el-tag type="success">智能分析</el-tag>
+        </div>
+      </template>
+
+      <el-timeline>
+        <el-timeline-item
+          timestamp="-"
+          placement="top"
+        >
+          <el-card>
+            <h4>暂无数据</h4>
+            <p class="feedback-content">暂无系统优化建议与反馈信息</p>
+            <div class="feedback-actions">
+              <el-button type="text" size="small">查看详情</el-button>
+            </div>
+          </el-card>
+        </el-timeline-item>
+      </el-timeline>
+    </el-card>
+  </div>
+</template>
+
+<script setup>
+  // REMOVED ALL ICON IMPORTS (no @element-plus/icons-vue dependency)
+</script>
+
+<style scoped>
+  .risk-warning {
+    width: 100%;
+  }
+
+  .risk-overview {
+    margin-bottom: 20px;
+  }
+
+  .risk-card {
+    cursor: pointer;
+    transition: all 0.3s;
+  }
+
+  .risk-card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  }
+
+  .risk-header {
+    display: flex;
+    align-items: center;
+    gap: 15px;
+  }
+
+  .risk-info {
+    flex: 1;
+  }
+
+  .risk-label {
+    font-size: 14px;
+    color: #909399;
+    margin-bottom: 8px;
+  }
+
+  .risk-count {
+    font-size: 32px;
+    font-weight: bold;
+    color: #303133;
+  }
+
+  .risk-list-card {
+    margin-bottom: 20px;
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .filter-group {
+    display: flex;
+    gap: 10px;
+  }
+
+  .charts-row {
+    margin-bottom: 20px;
+  }
+
+  .rule-card,
+  .feedback-card {
+    margin-bottom: 20px;
+  }
+
+  .feedback-content {
+    color: #606266;
+    font-size: 14px;
+    margin: 10px 0;
+    line-height: 1.6;
+  }
+
+  .feedback-actions {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    margin-top: 10px;
+  }
+
+  .health-cell {
+    display: flex;
+    flex-direction: column;
+    gap: 4px;
+  }
+
+  .health-value {
+    font-weight: 600;
+    color: #303133;
+  }
+
+  .score-breakdown {
+    display: flex;
+    flex-direction: column;
+    gap: 6px;
+  }
+  .score-line {
+    display: flex;
+    justify-content: space-between;
+    font-size: 12px;
+    color: #606266;
+  }
+</style>

+ 185 - 0
src/views/storage/efficiency/index.vue

@@ -0,0 +1,185 @@
+<template>
+  <div class="inventory-overview">
+    <div class="product-analysis">
+      <!-- 搜索框 -->
+      <div class="search-bar">
+        <input
+          v-model="sku"
+          placeholder="输入SKU查询"
+          @keyup.enter="search"
+        >
+        <button @click="search" :disabled="loading">
+          {{ loading ? '查询中...' : '查询' }}
+        </button>
+      </div>
+    </div>
+
+    <!-- SKU指标汇总表格 - 空表格 -->
+    <el-row :gutter="20" class="charts-row">
+      <el-col :span="24">
+        <el-card>
+          <template #header>
+            <div class="card-header">
+              <span>SKU指标汇总</span>
+              <el-button type="primary" size="small" @click="handleRefresh">
+                <span style="margin-right: 4px;">🔄</span> 刷新
+              </el-button>
+            </div>
+          </template>
+          <el-table :data="[]" stripe style="width: 100%" v-loading="false">
+            <el-table-column prop="sku" label="SKU" width="200" fixed />
+            <el-table-column prop="attribute" label="属性" width="140">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="spuName" label="SPU" width="200">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="purchaseQty" label="入库数量" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="salesQty" label="销售数量" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="inventory" label="现有库存" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="purchaseAmount" label="入库总资金" width="150" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="amountRatio" label="入库资金占比(%)" width="150" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="turnoverRate" label="库存周转率" align="right">
+              <template #default>
+                <el-tag type="info">—</el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+    </el-row>
+
+
+  </div>
+</template>
+
+<script setup>
+  // 完全移除所有图标依赖,仅保留空的刷新方法
+  const handleRefresh = () => {
+    // 后续可添加数据加载逻辑
+  }
+</script>
+
+<style scoped>
+  .product-analysis {
+    width: 90%;
+    max-width: 1200px;
+    margin: 20px auto;
+    font-family: Arial, sans-serif;
+  }
+
+  /* 搜索栏 */
+  .search-bar {
+    margin-bottom: 20px;
+    display: flex;
+    gap: 10px;
+  }
+  .search-bar input {
+    flex: 1;
+    padding: 8px 12px;
+    border: 1px solid #ddd;
+    border-radius: 4px;
+  }
+  .search-bar button {
+    padding: 8px 20px;
+    border: none;
+    background: #409eff;
+    color: #fff;
+    border-radius: 4px;
+    cursor: pointer;
+  }
+  .search-bar button:disabled {
+    background: #a0cfff;
+    cursor: not-allowed;
+  }
+
+  /* 空状态 */
+  .empty {
+    text-align: center;
+    padding: 50px 0;
+    color: #999;
+  }
+
+  /* 分析内容 */
+  .analysis-content {
+    display: grid;
+    gap: 20px;
+  }
+
+  .inventory-overview {
+    width: 100%;
+  }
+
+  .metrics-row {
+    margin-bottom: 20px;
+  }
+
+  .metric-card {
+    cursor: pointer;
+    transition: transform 0.3s;
+  }
+
+  .metric-card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  }
+
+  .metric-content {
+    display: flex;
+    align-items: center;
+    gap: 15px;
+  }
+
+  .metric-icon {
+    width: 60px;
+    height: 60px;
+    border-radius: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+  }
+
+  .metric-info {
+    flex: 1;
+  }
+
+  .metric-label {
+    font-size: 14px;
+    color: #909399;
+    margin-bottom: 8px;
+  }
+
+  .metric-value {
+    font-size: 28px;
+    font-weight: bold;
+    color: #303133;
+    line-height: 1;
+  }
+
+  .metric-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-top: 4px;
+  }
+
+  .charts-row {
+    margin-bottom: 20px;
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+</style>

+ 243 - 0
src/views/storage/overview/index.vue

@@ -0,0 +1,243 @@
+<template>
+  <div class="inventory-overview">
+    <!-- 关键指标卡片 - 纯文本替代图标 -->
+    <el-row :gutter="20" class="metrics-row">
+      <el-col :span="6">
+        <el-card class="metric-card">
+          <div class="metric-content">
+            <div class="metric-icon" style="background-color: #409eff;">
+              <span style="font-size: 30px; color: #fff;">📦</span>
+            </div>
+            <div class="metric-info">
+              <div class="metric-label">总体库存量</div>
+              <div class="metric-value">-</div>
+              <div class="metric-unit">件</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="metric-card">
+          <div class="metric-content">
+            <div class="metric-icon" style="background-color: #67c23a;">
+              <span style="font-size: 30px; color: #fff;">💰</span>
+            </div>
+            <div class="metric-info">
+              <div class="metric-label">库存价值</div>
+              <div class="metric-value">-</div>
+              <div class="metric-unit">万元</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="metric-card">
+          <div class="metric-content">
+            <div class="metric-icon" style="background-color: #e6a23c;">
+              <span style="font-size: 30px; color: #fff;">🔄</span>
+            </div>
+            <div class="metric-info">
+              <div class="metric-label">库存周转率</div>
+              <div class="metric-value">-</div>
+              <div class="metric-unit">天</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="metric-card">
+          <div class="metric-content">
+            <div class="metric-icon" style="background-color: #f56c6c;">
+              <span style="font-size: 30px; color: #fff;">🚚</span>
+            </div>
+            <div class="metric-info">
+              <div class="metric-label">在途库存比例</div>
+              <div class="metric-value">-</div>
+              <div class="metric-unit">%</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 每月入库/销售/库存对比图 - 空容器 -->
+    <el-row :gutter="20" class="charts-row">
+      <el-col :span="24">
+        <el-card>
+          <template #header>
+            <span>入库/销售/库存对比</span>
+          </template>
+          <div style="height: 300px; display: flex; align-items: center; justify-content: center; color: #909399;">
+            <div>暂无数据</div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- SKU指标汇总表格 - 空表格 -->
+    <el-row :gutter="20" class="charts-row">
+      <el-col :span="24">
+        <el-card>
+          <template #header>
+            <div class="card-header">
+              <span>SKU指标汇总</span>
+              <el-button type="primary" size="small" @click="handleRefresh">
+                <span style="margin-right: 4px;">🔄</span> 刷新
+              </el-button>
+            </div>
+          </template>
+          <el-table :data="[]" stripe style="width: 100%" v-loading="false">
+            <el-table-column prop="sku" label="SKU" width="200" fixed />
+            <el-table-column prop="attribute" label="属性" width="140">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="spuName" label="SPU" width="200">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="purchaseQty" label="入库数量" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="salesQty" label="销售数量" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="inventory" label="现有库存" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="purchaseAmount" label="入库总资金" width="150" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="amountRatio" label="入库资金占比(%)" width="150" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="turnoverRate" label="库存周转率" align="right">
+              <template #default>
+                <el-tag type="info">—</el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- SPU指标汇总表格 - 空表格 -->
+    <el-row :gutter="20" class="charts-row">
+      <el-col :span="24">
+        <el-card>
+          <template #header>
+            <div class="card-header">
+              <span>SPU指标汇总(成品)</span>
+              <el-button type="primary" size="small" @click="handleRefresh">
+                <span style="margin-right: 4px;">🔄</span> 刷新
+              </el-button>
+            </div>
+          </template>
+          <el-table :data="[]" stripe style="width: 100%" v-loading="false">
+            <el-table-column prop="spu" label="SPU" width="220" fixed />
+            <el-table-column prop="attribute" label="属性" width="140">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="skuCount" label="SKU数" width="90" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="purchaseQty" label="入库数量" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="salesQty" label="销售数量" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="inventory" label="现有库存" width="120" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="purchaseAmount" label="入库总资金" width="150" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="amountRatio" label="入库资金占比(%)" width="150" align="right">
+              <template #default>—</template>
+            </el-table-column>
+            <el-table-column prop="turnoverRate" label="库存周转率" align="right">
+              <template #default>
+                <el-tag type="info">—</el-tag>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+  // 完全移除所有图标依赖,仅保留空的刷新方法
+  const handleRefresh = () => {
+    // 后续可添加数据加载逻辑
+  }
+</script>
+
+<style scoped>
+  .inventory-overview {
+    width: 100%;
+  }
+
+  .metrics-row {
+    margin-bottom: 20px;
+  }
+
+  .metric-card {
+    cursor: pointer;
+    transition: transform 0.3s;
+  }
+
+  .metric-card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  }
+
+  .metric-content {
+    display: flex;
+    align-items: center;
+    gap: 15px;
+  }
+
+  .metric-icon {
+    width: 60px;
+    height: 60px;
+    border-radius: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #fff;
+  }
+
+  .metric-info {
+    flex: 1;
+  }
+
+  .metric-label {
+    font-size: 14px;
+    color: #909399;
+    margin-bottom: 8px;
+  }
+
+  .metric-value {
+    font-size: 28px;
+    font-weight: bold;
+    color: #303133;
+    line-height: 1;
+  }
+
+  .metric-unit {
+    font-size: 12px;
+    color: #909399;
+    margin-top: 4px;
+  }
+
+  .charts-row {
+    margin-bottom: 20px;
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+</style>

+ 451 - 0
src/views/storage/turnover/index.vue

@@ -0,0 +1,451 @@
+<template>
+  <div class="product-analysis">
+    <!-- 产品SKU搜索区域 -->
+    <div class="search-card">
+      <div class="search-row">
+        <div class="search-col search-input-col">
+          <div class="input-wrapper">
+            <span class="input-icon">🔍</span>
+            <input
+              type="text"
+              v-model="skuInput"
+              placeholder="请输入产品SKU(如:J06D01AS1)"
+              class="search-input"
+              @keyup.enter="searchProduct"
+            >
+            <button
+              class="clear-btn"
+              v-if="skuInput"
+              @click="clearInput"
+            >×</button>
+          </div>
+        </div>
+        <div class="search-col search-btn-col">
+          <button
+            class="search-btn"
+            :disabled="loading"
+            @click="searchProduct"
+          >
+            <span v-if="loading" class="loading-spinner"></span>
+            <span v-else>查询分析</span>
+          </button>
+        </div>
+        <div class="search-col search-info-col">
+          <span class="sku-tag" v-if="showProductArea">SKU: {{ skuInput }}</span>
+        </div>
+      </div>
+    </div>
+
+    <!-- 初始空状态 -->
+    <div class="empty-init" v-if="!showProductArea">
+      <div class="empty-icon">📦</div>
+      <div class="empty-text">请输入产品SKU进行查询分析</div>
+    </div>
+
+    <!-- 产品分析空框架 -->
+    <div class="analysis-content" v-else>
+      <!-- 关键指标卡片 -->
+      <div class="metrics-row">
+        <div class="metric-card">
+          <div class="metric-item">
+            <div class="metric-label">入库总量</div>
+            <div class="metric-value">-</div>
+            <div class="metric-unit">件</div>
+          </div>
+        </div>
+        <div class="metric-card">
+          <div class="metric-item">
+            <div class="metric-label">销售总量</div>
+            <div class="metric-value">-</div>
+            <div class="metric-unit">件</div>
+          </div>
+        </div>
+        <div class="metric-card">
+          <div class="metric-item">
+            <div class="metric-label">当前库存</div>
+            <div class="metric-value">-</div>
+            <div class="metric-unit">件</div>
+          </div>
+        </div>
+        <div class="metric-card">
+          <div class="metric-item">
+            <div class="metric-label">周转率</div>
+            <div class="metric-value">-</div>
+            <div class="metric-unit">次</div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 分段周转率表格 -->
+      <div class="card-container">
+        <div class="card-header">
+          <span>分段周转率</span>
+        </div>
+        <div class="table-container">
+          <table class="turnover-table">
+            <thead>
+            <tr>
+              <th width="220">统计区间</th>
+              <th width="160">销售出库 (件)</th>
+              <th width="220">时间加权平均库存 (件)</th>
+              <th>周转率 (次)</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr class="empty-row">
+              <td colspan="4">暂无数据</td>
+            </tr>
+            </tbody>
+          </table>
+        </div>
+      </div>
+
+      <!-- 库存趋势图占位 -->
+      <div class="card-container">
+        <div class="card-header">
+          <span>单品库存变化趋势(入库/销售/库存)</span>
+        </div>
+        <div class="chart-placeholder">
+          暂无图表数据
+        </div>
+      </div>
+
+      <!-- 预测与生命周期 -->
+      <div class="insights-row">
+        <div class="insight-card">
+          <div class="card-header">
+            <span>30天预测摘要</span>
+          </div>
+          <div class="empty-placeholder">
+            暂无预测数据
+          </div>
+        </div>
+        <div class="insight-card">
+          <div class="card-header">
+            <span>生命周期分段</span>
+          </div>
+          <div class="empty-placeholder">
+            暂无生命周期数据
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+  import { ref } from 'vue'
+
+  // 核心响应式状态
+  const skuInput = ref('')       // SKU输入值
+  const loading = ref(false)     // 加载状态
+  const showProductArea = ref(false) // 是否显示分析区域
+
+  // 清空输入框
+  const clearInput = () => {
+    skuInput.value = ''
+    showProductArea.value = false
+  }
+
+  // 搜索产品(仅UI状态切换,无数据处理)
+  const searchProduct = () => {
+    const sku = skuInput.value.trim()
+    if (!sku) {
+      alert('请输入产品SKU')
+      return
+    }
+
+    // 模拟加载状态
+    loading.value = true
+
+    // 仅延迟切换UI状态,无实际数据请求/处理
+    setTimeout(() => {
+      loading.value = false
+      showProductArea.value = true
+      alert(`已触发SKU "${sku}" 查询,当前为Vue空框架版本,无实际数据展示`)
+    }, 800)
+  }
+</script>
+
+<style scoped>
+  /* 全局基础样式 */
+  .product-analysis {
+    width: 100%;
+    padding: 20px;
+    box-sizing: border-box;
+    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
+    background-color: #f8f9fa;
+    min-height: 100vh;
+  }
+
+  /* 搜索区域样式 */
+  .search-card {
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 20px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+    margin-bottom: 20px;
+  }
+
+  .search-row {
+    display: flex;
+    align-items: center;
+    gap: 20px;
+    flex-wrap: wrap;
+  }
+
+  .search-col {
+    flex: 1;
+  }
+
+  .search-input-col {
+    flex: 2;
+    min-width: 300px;
+  }
+
+  .search-btn-col {
+    flex: none;
+    width: 140px;
+  }
+
+  .search-info-col {
+    flex: 1;
+    min-width: 200px;
+  }
+
+  .input-wrapper {
+    position: relative;
+    display: flex;
+    align-items: center;
+  }
+
+  .search-input {
+    width: 100%;
+    height: 40px;
+    padding: 0 40px 0 36px;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    font-size: 14px;
+    outline: none;
+    transition: border-color 0.3s;
+  }
+
+  .search-input:focus {
+    border-color: #409eff;
+  }
+
+  .input-icon {
+    position: absolute;
+    left: 12px;
+    font-size: 16px;
+    color: #909399;
+  }
+
+  .clear-btn {
+    position: absolute;
+    right: 12px;
+    width: 20px;
+    height: 20px;
+    border: none;
+    background: transparent;
+    font-size: 16px;
+    color: #909399;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .search-btn {
+    width: 100%;
+    height: 40px;
+    background: #409eff;
+    color: #fff;
+    border: none;
+    border-radius: 4px;
+    font-size: 14px;
+    cursor: pointer;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 8px;
+    transition: background-color 0.3s;
+  }
+
+  .search-btn:hover:not(:disabled) {
+    background: #337ecc;
+  }
+
+  .search-btn:disabled {
+    background: #a0cfff;
+    cursor: not-allowed;
+  }
+
+  .loading-spinner {
+    width: 16px;
+    height: 16px;
+    border: 2px solid #fff;
+    border-top: 2px solid transparent;
+    border-radius: 50%;
+    animation: spin 1s linear infinite;
+  }
+
+  @keyframes spin {
+    to {
+      transform: rotate(360deg);
+    }
+  }
+
+  .sku-tag {
+    display: inline-block;
+    height: 28px;
+    line-height: 28px;
+    padding: 0 10px;
+    background: #ecf5ff;
+    color: #409eff;
+    border-radius: 4px;
+    font-size: 12px;
+  }
+
+  /* 初始空状态 */
+  .empty-init {
+    padding: 100px 0;
+    text-align: center;
+  }
+
+  .empty-icon {
+    font-size: 64px;
+    color: #dcdfe6;
+    margin-bottom: 20px;
+  }
+
+  .empty-text {
+    font-size: 16px;
+    color: #909399;
+  }
+
+  /* 分析区域样式 */
+  .analysis-content {
+    display: flex;
+    flex-direction: column;
+    gap: 20px;
+  }
+
+  /* 关键指标卡片 */
+  .metrics-row {
+    display: flex;
+    gap: 20px;
+    flex-wrap: wrap;
+  }
+
+  .metric-card {
+    flex: 1;
+    min-width: 200px;
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 20px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+    text-align: center;
+    cursor: pointer;
+    transition: transform 0.3s, box-shadow 0.3s;
+  }
+
+  .metric-card:hover {
+    transform: translateY(-5px);
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  }
+
+  .metric-label {
+    font-size: 14px;
+    color: #909399;
+    margin-bottom: 10px;
+  }
+
+  .metric-value {
+    font-size: 32px;
+    font-weight: bold;
+    color: #303133;
+    margin-bottom: 5px;
+  }
+
+  .metric-unit {
+    font-size: 12px;
+    color: #909399;
+  }
+
+  /* 通用卡片容器 */
+  .card-container, .insight-card {
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 20px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
+  }
+
+  .card-header {
+    font-size: 16px;
+    font-weight: 500;
+    color: #303133;
+    margin-bottom: 16px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  /* 表格样式 */
+  .table-container {
+    width: 100%;
+    overflow-x: auto;
+  }
+
+  .turnover-table {
+    width: 100%;
+    border-collapse: collapse;
+    text-align: left;
+  }
+
+  .turnover-table th,
+  .turnover-table td {
+    padding: 12px;
+    border: 1px solid #ebeef5;
+  }
+
+  .turnover-table th {
+    background: #f5f7fa;
+    color: #606266;
+    font-weight: 500;
+  }
+
+  .empty-row td {
+    text-align: center;
+    color: #909399;
+  }
+
+  /* 图表占位符 */
+  .chart-placeholder {
+    height: 400px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #909399;
+    border: 1px dashed #dcdfe6;
+    border-radius: 4px;
+  }
+
+  /* 洞察区域 */
+  .insights-row {
+    display: flex;
+    gap: 20px;
+    flex-wrap: wrap;
+  }
+
+  .insight-card {
+    flex: 1;
+    min-width: 300px;
+  }
+
+  .empty-placeholder {
+    padding: 40px 0;
+    text-align: center;
+    color: #909399;
+  }
+</style>