gaoluyang
2025-10-14 00cb3748cb383c97be847cfe40ac5102684a68c5
生产管控-智能排产、物料看板页面联调
已修改3个文件
393 ■■■■■ 文件已修改
src/api/productionScheduling/index.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionControl/intelligentScheduling/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionControl/stockMaterialBoard/index.vue 334 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionScheduling/index.js
@@ -13,7 +13,7 @@
export function getProductionSchedulingInventoryList(query) {
    return request({
        url: '/productHome/productionSchedulingInventoryList',
        method: 'GET',
        method: 'get',
        params: query
    })
}
@@ -22,7 +22,7 @@
export function getProductionSchedulingStatistics(query) {
    return request({
        url: '/productHome/productionSchedulingStatistics',
        method: 'GET',
        method: 'get',
        params: query
    })
}
@@ -31,7 +31,7 @@
export function getProductionSchedulingStatisticsList(query) {
    return request({
        url: '/productHome/productionSchedulingStatisticsList',
        method: 'GET',
        method: 'get',
        params: query
    })
}
@@ -62,3 +62,48 @@
        data: data
    })
}
// 获取物料看板统计数据
export function getMaterialStatistics(query) {
    return request({
        url: '/productHome/materialStatistics',
        method: 'get',
        params: query
    })
}
// 获取煤种分布数据
export function getCoalTypeDistribution(query) {
    return request({
        url: '/productHome/coalTypeDistribution',
        method: 'get',
        params: query
    })
}
// 获取热值分布数据
export function getHeatValueDistribution(query) {
    return request({
        url: '/productHome/heatValueDistribution',
        method: 'get',
        params: query
    })
}
// 获取车次编码分布数据
export function getCarCodeDistribution(query) {
    return request({
        url: '/productHome/carCodeDistribution',
        method: 'get',
        params: query
    })
}
// 获取最近交易记录
export function getRecentTransaction(query) {
    return request({
        url: '/productHome/recentTransaction',
        method: 'get',
        params: query
    })
}
src/views/productionControl/intelligentScheduling/index.vue
@@ -89,7 +89,7 @@
            <span>{{ scope.row.type === 1 ? '成品' : scope.row.type === 2 ? '原料' : '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="coalId" label="煤种" />
        <el-table-column prop="coalName" label="煤种" />
        <el-table-column prop="inventoryQuantity" label="当前库存"></el-table-column>
        <el-table-column prop="pendingReplenishment" label="待补库"></el-table-column>
        <el-table-column prop="unit" label="单位" />
@@ -287,12 +287,10 @@
    
    // 构建请求参数
    const params = {
      dto: {
        entryDateStart: searchParams.value.dateRange && searchParams.value.dateRange[0] ? 
          searchParams.value.dateRange[0].toISOString().split('T')[0] : '',
        entryDateEnd: searchParams.value.dateRange && searchParams.value.dateRange[1] ? 
          searchParams.value.dateRange[1].toISOString().split('T')[0] : ''
      }
    }
    
    // 调用接口获取数据
@@ -315,12 +313,10 @@
  try {
    // 构建请求参数
    const params = {
      dto: {
        entryDateStart: searchParams.value.dateRange && searchParams.value.dateRange[0] ? 
          searchParams.value.dateRange[0].toISOString().split('T')[0] : '',
        entryDateEnd: searchParams.value.dateRange && searchParams.value.dateRange[1] ? 
          searchParams.value.dateRange[1].toISOString().split('T')[0] : ''
      }
    }
    
    // 调用接口获取数据
@@ -340,12 +336,10 @@
  try {
    // 构建请求参数
    const params = {
      dto: {
        entryDateStart: searchParams.value.dateRange && searchParams.value.dateRange[0] ? 
          searchParams.value.dateRange[0].toISOString().split('T')[0] : '',
        entryDateEnd: searchParams.value.dateRange && searchParams.value.dateRange[1] ? 
          searchParams.value.dateRange[1].toISOString().split('T')[0] : ''
      }
    }
    
    // 调用接口获取数据
src/views/productionControl/stockMaterialBoard/index.vue
@@ -15,18 +15,12 @@
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :shortcuts="dateShortcuts"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item label="煤种">
          <el-input v-model="searchParams.coalType" placeholder="请输入煤种" clearable />
        </el-form-item>
        <el-form-item label="车次编码">
          <el-input v-model="searchParams.trainCode" placeholder="请输入车次编码" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch" :loading="loading">查询</el-button>
          <el-button @click="handleReset">重置</el-button>
          <el-button @click="handleRefresh">刷新</el-button>
        </el-form-item>
      </el-form>
    </el-card>
@@ -39,12 +33,7 @@
        </div>
        <div class="card-content">
          <div class="card-title">今日入库总量</div>
          <div class="card-value">{{ todayInStock.toFixed(2) }} 吨</div>
          <div class="card-percentage" :class="{ positive: todayInStockPercentage > 0, negative: todayInStockPercentage < 0 }">
            <i v-if="todayInStockPercentage > 0" class="el-icon-caret-top" />
            <i v-else-if="todayInStockPercentage < 0" class="el-icon-caret-bottom" />
            {{ Math.abs(todayInStockPercentage).toFixed(1) }}%
          </div>
          <div class="card-value">{{ todayInboundTotal.toFixed(2) }} 吨</div>
        </div>
      </div>
      
@@ -54,27 +43,7 @@
        </div>
        <div class="card-content">
          <div class="card-title">今日出库总量</div>
          <div class="card-value">{{ todayOutStock.toFixed(2) }} 吨</div>
          <div class="card-percentage" :class="{ positive: todayOutStockPercentage > 0, negative: todayOutStockPercentage < 0 }">
            <i v-if="todayOutStockPercentage > 0" class="el-icon-caret-top" />
            <i v-else-if="todayOutStockPercentage < 0" class="el-icon-caret-bottom" />
            {{ Math.abs(todayOutStockPercentage).toFixed(1) }}%
          </div>
        </div>
      </div>
      <div class="stat-card">
        <div class="card-icon">
          <i class="el-icon-takeaway-box" />
        </div>
        <div class="card-content">
          <div class="card-title">今日领料总量</div>
          <div class="card-value">{{ todayMaterialPick.toFixed(2) }} 吨</div>
          <div class="card-percentage" :class="{ positive: todayMaterialPickPercentage > 0, negative: todayMaterialPickPercentage < 0 }">
            <i v-if="todayMaterialPickPercentage > 0" class="el-icon-caret-top" />
            <i v-else-if="todayMaterialPickPercentage < 0" class="el-icon-caret-bottom" />
            {{ Math.abs(todayMaterialPickPercentage).toFixed(1) }}%
          </div>
          <div class="card-value">{{ todayOutboundTotal.toFixed(2) }} 吨</div>
        </div>
      </div>
      
@@ -111,20 +80,6 @@
        </div>
      </div>
      
      <!-- 产地分类 -->
      <div class="category-section">
        <h3 class="category-title"><i class="el-icon-location"></i> 产地分布</h3>
        <div class="category-items">
          <div v-for="item in originData" :key="item.name" class="category-item">
            <span class="item-name">{{ item.name }}</span>
            <div class="item-bar">
              <div class="item-progress" :style="{ width: item.percentage + '%' }"></div>
            </div>
            <span class="item-value">{{ item.value.toFixed(2) }} 吨 ({{ item.percentage.toFixed(1) }}%)</span>
          </div>
        </div>
      </div>
      <!-- 热值分类 -->
      <div class="category-section">
        <h3 class="category-title"><i class="el-icon-fire"></i> 热值分布</h3>
@@ -142,13 +97,17 @@
      <!-- 车次编码分类 -->
      <div class="category-section">
        <h3 class="category-title"><i class="el-icon-train"></i> 车次编码统计</h3>
        <el-table :data="trainCodeData" style="width: 100%">
          <el-table-column prop="trainCode" label="车次编码" width="160" />
          <el-table-column prop="count" label="次数" width="100" align="right" />
          <el-table-column prop="totalQuantity" label="总量(吨)" width="120" align="right">
            <template #default="scope">{{ scope.row.totalQuantity.toFixed(2) }}</template>
          </el-table-column>
        </el-table>
        <div class="train-code-list">
          <div v-for="item in trainCodeData" :key="item.code" class="train-code-item">
            <div class="train-code-info">
              <span class="train-code-label">{{ item.code }}</span>
              <div class="train-code-details">
                <span class="train-count">次数: {{ item.count }}</span>
                <span class="train-total">总量: {{ item.total.toFixed(2) }}吨</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-card>
@@ -160,24 +119,17 @@
        </div>
      </template>
      <el-table v-loading="loading" :data="recentTransactions" style="width: 100%">
        <el-table-column prop="code" label="编码" width="160" />
        <el-table-column prop="type" label="类型" width="80">
                <el-table-column prop="id" label="序号" width="60" type="index" align="center"/>
                <el-table-column prop="type" label="煤料类型" width="100">
          <template #default="scope">
            <span class="type-tag"
                  :class="{
                    'type-in': scope.row.type === '入库',
                    'type-out': scope.row.type === '出库',
                    'type-pick': scope.row.type === '领料'
                  }">
              {{ scope.row.type }}
            </span>
                        <span>{{ scope.row.type === 1 ? '成品' : scope.row.type === 2 ? '原料' : '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="coalType" label="煤种" width="100" />
        <el-table-column prop="origin" label="产地" width="100" />
        <el-table-column prop="calorificValue" label="热值" width="120" />
        <el-table-column prop="quantity" label="数量(吨)" width="120" />
        <el-table-column prop="trainCode" label="车次编码" width="120" />
        <el-table-column prop="supplierName" label="供应商名称" />
        <el-table-column prop="coalName" label="煤种" />
        <el-table-column prop="purchaseQuantity" label="采购数量" width="100" />
        <el-table-column prop="priceIncludingTax" label="    单价(含税)" />
        <el-table-column prop="totalPriceIncludingTax" label="总价(含税)" />
        <el-table-column prop="createTime" label="创建时间" width="180" />
      </el-table>
    </el-card>
@@ -187,6 +139,7 @@
<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { getMaterialStatistics, getCoalTypeDistribution, getHeatValueDistribution, getCarCodeDistribution, getRecentTransaction } from '@/api/productionScheduling'
// 搜索参数
const searchParams = ref({
@@ -200,56 +153,86 @@
  {
    text: '今天',
    value: () => {
      const formatDate = (date) => {
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        return `${year}-${month}-${day}`
      }
      const end = new Date()
      const start = new Date()
      return [start, end]
      return [formatDate(start), formatDate(end)]
    }
  },
  {
    text: '昨天',
    value: () => {
      const formatDate = (date) => {
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        return `${year}-${month}-${day}`
      }
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24)
      return [start, end]
      return [formatDate(start), formatDate(end)]
    }
  },
  {
    text: '近7天',
    value: () => {
      const formatDate = (date) => {
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        return `${year}-${month}-${day}`
      }
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      return [start, end]
      return [formatDate(start), formatDate(end)]
    }
  },
  {
    text: '近30天',
    value: () => {
      const formatDate = (date) => {
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        return `${year}-${month}-${day}`
      }
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
      return [start, end]
      return [formatDate(start), formatDate(end)]
    }
  },
  {
    text: '本月',
    value: () => {
      const formatDate = (date) => {
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0')
        const day = String(date.getDate()).padStart(2, '0')
        return `${year}-${month}-${day}`
      }
      const end = new Date()
      const start = new Date(end.getFullYear(), end.getMonth(), 1)
      return [start, end]
      return [formatDate(start), formatDate(end)]
    }
  }
]
// 统计数据
const todayInStock = ref(1250.75)
const todayInStockPercentage = ref(5.2)
const todayOutStock = ref(890.30)
const todayOutStockPercentage = ref(-2.1)
const todayMaterialPick = ref(320.45)
const todayMaterialPickPercentage = ref(10.3)
const currentTotalStock = ref(15680.95)
const todayInboundTotal = ref(0)
const todayOutboundTotal = ref(0)
const currentTotalStock = ref(0)
// 百分比数据(根据需要保留)
const todayInStockPercentage = ref(0)
const todayOutStockPercentage = ref(0)
// 分类数据 - 煤种分布
const coalTypeData = ref([
@@ -258,15 +241,6 @@
  { name: '褐煤', value: 2800, percentage: 18.7 },
  { name: '贫煤', value: 2500, percentage: 16.7 },
  { name: '瘦煤', value: 2680, percentage: 17.9 }
])
// 分类数据 - 产地分布
const originData = ref([
  { name: '山西', value: 5200, percentage: 33.1 },
  { name: '内蒙古', value: 3800, percentage: 24.2 },
  { name: '陕西', value: 2900, percentage: 18.5 },
  { name: '新疆', value: 2100, percentage: 13.4 },
  { name: '贵州', value: 1680, percentage: 10.7 }
])
// 分类数据 - 热值分布
@@ -279,23 +253,10 @@
])
// 分类数据 - 车次编码统计
const trainCodeData = ref([
  { trainCode: 'C12345', count: 12, totalQuantity: 4200.5 },
  { trainCode: 'C12346', count: 8, totalQuantity: 2800.2 },
  { trainCode: 'C12347', count: 10, totalQuantity: 3500.0 },
  { trainCode: 'C12348', count: 7, totalQuantity: 2450.8 },
  { trainCode: 'C12349', count: 5, totalQuantity: 1800.3 }
])
const trainCodeData = ref([])
// 模拟数据 - 最近交易记录
const recentTransactions = ref([
  { code: 'RK20230507001', type: '入库', coalType: '烟煤', origin: '山西', calorificValue: '5300大卡', quantity: 350.5, trainCode: 'C12345', createTime: '2023-05-07 09:30:15' },
  { code: 'CK20230507001', type: '出库', coalType: '无烟煤', origin: '内蒙古', calorificValue: '5800大卡', quantity: 280.2, trainCode: 'C12346', createTime: '2023-05-07 10:15:30' },
  { code: 'LL20230507001', type: '领料', coalType: '褐煤', origin: '新疆', calorificValue: '4200大卡', quantity: 120.8, trainCode: '', createTime: '2023-05-07 11:05:45' },
  { code: 'RK20230507002', type: '入库', coalType: '贫煤', origin: '陕西', calorificValue: '5100大卡', quantity: 400.0, trainCode: 'C12347', createTime: '2023-05-07 13:20:00' },
  { code: 'CK20230507002', type: '出库', coalType: '瘦煤', origin: '贵州', calorificValue: '5400大卡', quantity: 310.5, trainCode: 'C12348', createTime: '2023-05-07 14:45:15' },
  { code: 'LL20230507002', type: '领料', coalType: '烟煤', origin: '山西', calorificValue: '5300大卡', quantity: 200.0, trainCode: '', createTime: '2023-05-07 15:30:30' }
])
// 最近交易记录数据
const recentTransactions = ref([])
// 加载状态
const loading = ref(false)
@@ -306,52 +267,70 @@
    loading.value = true
    console.log('搜索参数:', searchParams.value)
    
    // 模拟API请求延迟
    await new Promise(resolve => setTimeout(resolve, 800))
    // 模拟数据更新
    todayInStock.value = 1000 + Math.random() * 500
    todayInStockPercentage.value = -10 + Math.random() * 20
    todayOutStock.value = 800 + Math.random() * 400
    todayOutStockPercentage.value = -10 + Math.random() * 20
    todayMaterialPick.value = 200 + Math.random() * 200
    todayMaterialPickPercentage.value = -10 + Math.random() * 20
    currentTotalStock.value = 15000 + Math.random() * 3000
    // 更新分类数据
    coalTypeData.value.forEach(item => {
      item.value = 2000 + Math.random() * 3000
    })
    originData.value.forEach(item => {
      item.value = 1500 + Math.random() * 4000
    })
    calorificData.value.forEach(item => {
      item.value = 500 + Math.random() * 5000
    })
    trainCodeData.value.forEach(item => {
      item.count = 3 + Math.floor(Math.random() * 15)
      item.totalQuantity = 1000 + Math.random() * 4000
    })
    // 重新计算百分比
    const calculatePercentages = (data) => {
      const total = data.reduce((sum, item) => sum + item.value, 0)
      data.forEach(item => {
        item.percentage = total > 0 ? (item.value / total) * 100 : 0
      })
    // 构建请求参数
    const params = {
      entryDateStart: searchParams.value.dateRange && searchParams.value.dateRange[0] ? searchParams.value.dateRange[0] : '',
        entryDateEnd: searchParams.value.dateRange && searchParams.value.dateRange[1] ? searchParams.value.dateRange[1] : ''
    }
    
    calculatePercentages(coalTypeData.value)
    calculatePercentages(originData.value)
    calculatePercentages(calorificData.value)
    // 调用API获取统计数据
    const response = await getMaterialStatistics(params)
    
    ElMessage.success('查询成功')
    // 根据项目中其他地方的代码风格,检查响应成功的条件应该是code === 200
    if (response.code === 200 && response.data) {
      // 更新统计数据
      todayInboundTotal.value = response.data.todayInboundTotal || 0
      todayOutboundTotal.value = response.data.todayOutboundTotal || 0
      currentTotalStock.value = response.data.currentInventoryTotal || 0
      // 可以在这里添加百分比的计算逻辑,如果API返回了相关数据
      // 暂时保留原有的模拟百分比数据
      todayInStockPercentage.value = -10 + Math.random() * 20
      todayOutStockPercentage.value = -10 + Math.random() * 20
    }
    // 调用API获取煤种分布数据
    const coalTypeResponse = await getCoalTypeDistribution(params)
    if (coalTypeResponse.code === 200 && coalTypeResponse.data) {
      // 根据接口响应更新煤种分布数据
      coalTypeData.value = coalTypeResponse.data.map(item => ({
        name: item.name || '',
        value: item.value || 0,
        percentage: item.percent || 0
      }))
    }
    // 调用API获取热值分布数据
    const heatValueResponse = await getHeatValueDistribution(params)
    if (heatValueResponse.code === 200 && heatValueResponse.data) {
      // 根据接口响应更新热值分布数据
      calorificData.value = heatValueResponse.data.map(item => ({
        name: item.name || '',
        value: item.value || 0,
        percentage: item.percent || 0
      }))
    }
    // 调用API获取车次编码分布数据
    const carCodeResponse = await getCarCodeDistribution(params)
    if (carCodeResponse.code === 200 && carCodeResponse.data) {
      // 根据接口响应更新车次编码数据
      trainCodeData.value = carCodeResponse.data
    }
    // 调用API获取最近交易记录
    const transactionResponse = await getRecentTransaction(params)
    if (transactionResponse.code === 200 && transactionResponse.data) {
      // 根据接口响应更新最近交易记录数据
      // 由于接口返回的数据结构与表格所需的结构不完全匹配,需要进行字段映射
      recentTransactions.value = transactionResponse.data
    }
  } catch (error) {
    console.error('查询失败:', error)
    ElMessage.error('查询失败,请稍后重试')
  } finally {
    loading.value = false
  }
@@ -383,10 +362,17 @@
// 初始化页面
onMounted(() => {
  // 默认查询近7天数据
  const formatDate = (date) => {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
  }
  const end = new Date()
  const start = new Date()
  start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  searchParams.value.dateRange = [start, end]
  searchParams.value.dateRange = [formatDate(start), formatDate(end)]
  
  // 初始加载数据
  handleSearch()
@@ -530,6 +516,44 @@
  gap: 8px;
}
.train-code-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.train-code-item {
  flex: 1;
  min-width: 200px;
  padding: 16px;
  background-color: #f5f7fa;
  border-radius: 8px;
}
.train-code-info {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.train-code-label {
  font-size: 16px;
  font-weight: 600;
  color: #409eff;
}
.train-code-details {
  display: flex;
  justify-content: space-between;
  font-size: 14px;
  color: #606266;
}
.train-count,
.train-total {
  display: inline-block;
}
.category-items {
  display: flex;
  flex-direction: column;
@@ -612,6 +636,18 @@
  border: 1px solid #FFCCC7;
}
/* 修复日期选择器被动事件监听器问题 */
.el-date-editor {
  touch-action: none;
}
/* 禁用日期选择器的默认选择器指示器的触摸交互 */
.el-date-picker__editor-wrap .el-input__inner::-webkit-calendar-picker-indicator {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}
/* 响应式设计 */
@media screen and (max-width: 1200px) {
  .stats-cards {