已添加6个文件
已修改25个文件
1325 ■■■■■ 文件已修改
src/assets/BI/kpiIcons/kpi-cartCutout.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/BI/kpiIcons/kpi-cloud.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/BI/kpiIcons/kpi-dataBoard.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/BI/kpiIcons/kpi-dbIcon.png 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/BI/kpiIcons/kpi-shield.png 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/ProductSelectDialog.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/dispatchLog/Record.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/Record.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Qualified.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Unqualified.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockReport/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementReport/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/largeScreen/index.vue 1089 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/processRouteItem/index.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/Detail/index.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/Detail/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/New.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/Input.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/components/Detail.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrder/index.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/components/formDia.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/processInspection/components/formDia.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/processInspection/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/BI/kpiIcons/kpi-cartCutout.png
src/assets/BI/kpiIcons/kpi-cloud.png
src/assets/BI/kpiIcons/kpi-dataBoard.png
src/assets/BI/kpiIcons/kpi-dbIcon.png
src/assets/BI/kpiIcons/kpi-shield.png
src/views/basicData/product/ProductSelectDialog.vue
@@ -23,6 +23,7 @@
      <el-table-column prop="productName" label="产品大类" min-width="160" />
      <el-table-column prop="model" label="型号名称" min-width="200" />
      <el-table-column prop="unit" label="单位" min-width="160" />
      <el-table-column prop="materialCode" label="料号" min-width="100" />
    </el-table>
    <div class="mt-3 flex justify-end">
src/views/inventoryManagement/dispatchLog/Record.vue
@@ -66,6 +66,11 @@
                    prop="model"
                    show-overflow-tooltip
                />
        <el-table-column
                    label="料号"
                    prop="materialCode"
                    show-overflow-tooltip
                />
                <el-table-column
                    label="单位"
                    prop="unit"
@@ -432,6 +437,7 @@
                <tr>
                  <th>产品名称</th>
                  <th>规格型号</th>
                  <th>料号</th>
                  <th>单位</th>
                  <th>单价</th>
                  <th>零售数量</th>
@@ -442,6 +448,7 @@
                <tr>
                  <td>${item.productName || '砂灰砖'}</td>
                  <td>${item.model || '标准'}</td>
                  <td>${item.materialCode || ''}</td>
                  <td>${item.unit || '块'}</td>
                  <td>${item.taxInclusiveUnitPrice || '0'}</td>
                  <td>${item.inboundNum || '2000'}</td>
src/views/inventoryManagement/receiptManagement/Record.vue
@@ -67,6 +67,9 @@
        <el-table-column label="规格型号"
                         prop="model"
                         show-overflow-tooltip/>
        <el-table-column label="料号"
                         prop="materialCode"
                         show-overflow-tooltip/>
        <el-table-column label="单位"
                         prop="unit"
                         show-overflow-tooltip/>
src/views/inventoryManagement/stockManagement/Qualified.vue
@@ -25,6 +25,7 @@
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="料号" prop="materialCode" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
src/views/inventoryManagement/stockManagement/Unqualified.vue
@@ -22,6 +22,7 @@
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="料号" prop="materialCode" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
src/views/inventoryManagement/stockReport/index.vue
@@ -186,6 +186,11 @@
             show-overflow-tooltip
           />
           <el-table-column
             label="料号"
             prop="materialCode"
             show-overflow-tooltip
           />
           <el-table-column
             label="单位"
             prop="unit"
             show-overflow-tooltip
src/views/procurementManagement/procurementLedger/index.vue
@@ -88,6 +88,8 @@
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
              <el-table-column label="料号"
                               prop="materialCode" />
              <el-table-column label="数量"
                               prop="quantity" />
              <el-table-column label="税率(%)"
@@ -405,6 +407,8 @@
                           prop="productCategory" />
          <el-table-column label="规格型号"
                           prop="specificationModel" />
          <el-table-column label="料号"
                           prop="materialCode" />
          <el-table-column label="单位"
                           prop="unit"
                           width="70" />
@@ -565,6 +569,15 @@
                           :label="item.model"
                           :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="料号:"
                          prop="materialCode">
              <el-input v-model="productForm.materialCode"
                        placeholder="请输入"
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
@@ -952,6 +965,7 @@
      productCategory: "",
      productModelId: "",
      specificationModel: "",
      materialCode: "",
      unit: "",
      quantity: "",
      taxInclusiveUnitPrice: "",
@@ -1587,9 +1601,11 @@
    if (index !== -1) {
      productForm.value.specificationModel = modelOptions.value[index].model;
      productForm.value.unit = modelOptions.value[index].unit;
      productForm.value.materialCode = modelOptions.value[index].materialCode;
    } else {
      productForm.value.specificationModel = null;
      productForm.value.unit = null;
      productForm.value.materialCode = null;
    }
  };
  const findNodeById = (nodes, productId) => {
src/views/procurementManagement/procurementReport/index.vue
@@ -111,6 +111,10 @@
    prop: 'specificationModel',
  },
  {
    label: '料号',
    prop: 'materialCode',
  },
  {
    label: '采购数量',
    prop: 'purchaseNum',
    width: 120,
src/views/productionManagement/largeScreen/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1089 @@
<template>
  <div class="large-screen">
    <div class="top-kpi-row">
      <div class="group-card group-card--wide">
        <div class="group-left">
          <div class="group-icon group-icon--order"></div>
        </div>
        <div class="group-right">
          <div class="group-metrics">
            <div class="metric metric--plain">
              <div class="metric-title">工单总数</div>
              <div class="metric-value">{{ kpi.workOrderTotal }}<span class="unit">条</span></div>
            </div>
            <div class="metric metric--plain">
              <div class="metric-title">进行中工单</div>
              <div class="metric-value">{{ kpi.workOrderDoing }}<span class="unit">条</span></div>
            </div>
            <div class="metric metric--plain">
              <div class="metric-title">完成工单</div>
              <div class="metric-value">{{ kpi.workOrderDone }}<span class="unit">条</span></div>
            </div>
          </div>
        </div>
      </div>
      <div class="group-card group-card--wide">
        <div class="group-left">
          <div class="group-icon group-icon--quality"></div>
        </div>
        <div class="group-right">
          <div class="group-metrics">
            <div class="metric metric--plain">
              <div class="metric-title">合格率</div>
              <div class="metric-value">{{ kpi.passRate }}<span class="unit">%</span></div>
            </div>
            <div class="metric metric--plain">
              <div class="metric-title">不良率</div>
              <div class="metric-value">{{ kpi.ngRate }}<span class="unit">%</span></div>
            </div>
            <div class="metric metric--plain">
              <div class="metric-title">总报废数</div>
              <div class="metric-value">{{ kpi.scrapTotal }}<span class="unit">条</span></div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="top-stat-row">
      <div class="stat-card stat-card--primary">
        <div class="stat-main">
          <div class="stat-value">{{ formatMoney(kpi.productionAmount) }}<span class="unit1">吨</span></div>
          <div class="stat-title">总生产总量</div>
          <div class="stat-sub">
            <span>较上月趋势:</span>
            <span class="trend" :class="kpi.productionAmountTrend >= 0 ? 'up' : 'down'">
              {{ kpi.productionAmountTrend >= 0 ? '+' : '' }}{{ kpi.productionAmountTrend }}%
            </span>
            <svg
              class="trend-arrow-svg"
              :class="[
                kpi.productionAmountTrend >= 0 ? '' : 'trend-arrow-svg--up',
                kpi.productionAmountTrend >= 0 ? 'is-up' : 'is-down'
              ]"
              viewBox="0 0 16 10"
              aria-hidden="true"
            >
              <path d="M1 2 L6 7 L10 3 L15 3" />
              <path d="M13 1 L15 3 L13 5" />
            </svg>
          </div>
        </div>
        <div class="stat-primary-decor"></div>
      </div>
      <div class="stat-card">
        <div class="stat-main">
          <div class="stat-value">{{ formatMoney(kpi.productionCost) }}<span class="unit">吨</span></div>
          <div class="stat-title">生产总消耗</div>
          <div class="stat-sub">
            <span>较上月趋势:</span>
            <span class="trend" :class="kpi.productionCostTrend >= 0 ? 'up' : 'down'">
              {{ kpi.productionCostTrend >= 0 ? '+' : '' }}{{ kpi.productionCostTrend }}%
            </span>
            <svg
              class="trend-arrow-svg"
              :class="[
                kpi.productionCostTrend >= 0 ? '' : 'trend-arrow-svg--up',
                kpi.productionCostTrend >= 0 ? 'is-up' : 'is-down'
              ]"
              viewBox="0 0 16 10"
              aria-hidden="true"
            >
              <path d="M1 2 L6 7 L10 3 L15 3" />
              <path d="M13 1 L15 3 L13 5" />
            </svg>
          </div>
        </div>
        <div class="stat-icon stat-icon--cost"></div>
      </div>
      <div class="stat-card">
        <div class="stat-main">
          <div class="stat-value">{{ kpi.supplierCount }}<span class="unit">å®¶</span></div>
          <div class="stat-title">产品总供应公司</div>
          <div class="stat-sub">
            <span>较上月趋势:</span>
            <span class="trend" :class="kpi.supplierCountTrend >= 0 ? 'up' : 'down'">
              {{ kpi.supplierCountTrend >= 0 ? '+' : '' }}{{ kpi.supplierCountTrend }}%
            </span>
            <svg
              class="trend-arrow-svg"
              :class="[
                kpi.supplierCountTrend >= 0 ? '' : 'trend-arrow-svg--up',
                kpi.supplierCountTrend >= 0 ? 'is-up' : 'is-down'
              ]"
              viewBox="0 0 16 10"
              aria-hidden="true"
            >
              <path d="M1 2 L6 7 L10 3 L15 3" />
              <path d="M13 1 L15 3 L13 5" />
            </svg>
          </div>
        </div>
        <div class="stat-icon stat-icon--supplier"></div>
      </div>
    </div>
    <div class="mid-row">
      <div class="panel panel--rect">
        <div class="panel-header">
          <div class="panel-title">产品产出分析</div>
        </div>
        <div class="panel-body">
          <div class="product-pie-wrapper">
            <Echarts
              :chartStyle="chartStyle"
              :legend="categoryPieLegend"
              :tooltip="categoryPieTooltip"
              :series="categoryPieSeries"
              :xAxis="[]"
              :yAxis="[]"
              :color="categoryPieColors"
              :options="transparentOptions"
              style="height: 100%"
            />
          </div>
          <div class="category-cards">
            <div v-for="(it, idx) in categoryPieData" :key="it.name" class="category-card">
              <div class="category-name">产品大类{{ idx + 1 }}</div>
              <div class="category-val">{{ it.value }}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="panel panel--rect">
        <div class="panel-header">
          <div class="panel-title">不良原因统计分析</div>
        </div>
        <div class="panel-body">
          <div class="ng-layout">
            <div class="ng-list">
              <div class="ng-list-head">
                <div class="ng-col ng-col--name">不良原因</div>
                <div class="ng-col ng-col--pct">占比</div>
                <div class="ng-col ng-col--val">数量</div>
              </div>
              <div class="ng-list-body">
                <div v-for="(row, idx) in ngRows" :key="row.name" class="ng-row">
                  <div class="ng-col ng-col--name">
                    <span class="ng-dot" :style="{ backgroundColor: ngColors[idx % ngColors.length] }"></span>
                    <span class="ng-name">{{ row.name }}</span>
                  </div>
                  <div class="ng-col ng-col--pct">{{ row.percent }}%</div>
                  <div class="ng-col ng-col--val">{{ row.value }}</div>
                </div>
              </div>
            </div>
            <div class="ng-chart">
              <div class="donut-wrap">
                <Echarts
                  :chartStyle="chartStyle"
                  :legend="{ show: false }"
                  :tooltip="pieTooltip"
                  :series="pieSeries"
                  :color="ngColors"
                  :xAxis="[]"
                  :yAxis="[]"
                  :options="transparentOptions"
                  style="height: 100%"
                />
                <div class="donut-center">
                  <div class="donut-label">不良原因</div>
                  <div class="donut-value">{{ formatMoney(ngTotal) }}</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="bottom-row">
      <div class="panel panel-full">
        <div class="panel-header">
          <div class="panel-title">工序不良原因分析</div>
          <div class="panel-actions">
            <div class="panel-action">年份</div>
            <el-date-picker
              v-model="currentYear"
              type="year"
              format="YYYYå¹´"
              value-format="YYYY"
              :clearable="false"
              class="panel-year-picker"
              size="small"
            />
          </div>
        </div>
        <div class="panel-body">
          <div class="bottom-chart-wrap">
            <div class="chart-unit">单位:%</div>
            <Echarts
              :chartStyle="{ width: '100%', height: '260px' }"
              :grid="lineGrid"
              :legend="lineLegend"
              :tooltip="axisTooltip"
              :xAxis="lineXAxis"
              :yAxis="lineYAxis"
              :series="lineSeries"
              :options="transparentOptions"
              style="height: 100%"
            />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script setup>
import { computed, ref } from 'vue'
import * as echarts from 'echarts'
import Echarts from '@/components/Echarts/echarts.vue'
import { ElSelect, ElOption, ElDatePicker } from 'element-plus'
const chartStyle = { width: '100%', height: '100%' }
const transparentOptions = {
  backgroundColor: 'transparent',
  textStyle: { color: '#3a3a3a' },
}
const kpi = ref({
  workOrderTotal: 378,
  workOrderDoing: 108,
  workOrderDone: 238,
  passRate: 98,
  ngRate: 8,
  scrapTotal: 38,
  productionAmount: 989878,
  productionAmountTrend: 16,
  productionQty: 19878,
  productionQtyTrend: 16,
  productionCost: 69878,
  productionCostTrend: -16,
  supplierCount: 48,
  supplierCountTrend: 16,
  totalOutput: 1000,
})
const currentYear = ref('2025')
function formatMoney(n) {
  const num = Number(n || 0)
  return num.toLocaleString('zh-CN', { maximumFractionDigits: 0 })
}
const axisTooltip = {
  trigger: 'axis',
  axisPointer: { type: 'shadow' },
  formatter: (params) => {
    const first = params?.[0]
    const x = first?.axisValueLabel || ''
    const lines = [`${x}`]
    params.forEach((p) => {
      if (!p) return
      const name = p.seriesName
      const v = p.data
      lines.push(`${name}: ${v}`)
    })
    return lines.join('<br/>')
  },
}
// ä¸­éƒ¨å·¦ä¾§ï¼šé¥¼çŠ¶å›¾ï¼ˆæŒ‰äº§å“å¤§ç±»ç»Ÿè®¡äº§å‡ºæ•°é‡ï¼‰
const categoryPieColors = ['#2D5BFF', '#4E8AFF', '#00A4ED', '#26C6DA', '#7C3AED', '#F59E0B', '#EF4444', '#10B981']
const categoryPieData = ref([
  { name: '产品大类1', value: 600 },
  { name: '产品大类2', value: 200 },
  { name: '产品大类3', value: 200 },
  { name: '产品大类4', value: 200 },
  { name: '产品大类5', value: 200 },
])
const categoryPieLegend = computed(() => {
  // è®¾è®¡å›¾ä¸­é¥¼å›¾æœ¬èº«æ˜¾ç¤ºå æ¯”标签,不额外展示图例
  return {
    show: false,
    data: categoryPieData.value.map((d) => d.name),
  }
})
const categoryPieTooltip = {
  trigger: 'item',
  formatter: (p) => `${p.marker} ${p.name}<br/>产出数量:${p.value}<br/>占比:${p.percent}%`,
}
const categoryPieSeries = computed(() => [
  {
    name: '产出数量',
    type: 'pie',
    radius: ['40%', '68%'],
    center: ['50%', '45%'],
    avoidLabelOverlap: false,
    label: {
      show: true,
      formatter: (p) => `${p.name} ${p.percent}%`,
      color: '#6b7280',
      fontSize: 12,
    },
    labelLine: {
      show: true,
      lineStyle: { color: '#e5e7eb' },
      length: 16,
      length2: 20,
    },
    data: categoryPieData.value,
    emphasis: {
      scale: true,
      scaleSize: 8,
    },
  },
])
// ä¸­éƒ¨å³ä¾§ï¼šçޝ形饼图
const ngColors = ['#2D5BFF', '#26C6DA', '#F59E0B', '#7C3AED', '#60A5FA', '#10B981']
const ngReasonData = ref([
  { name: '不良原因1', value: 300 },
  { name: '不良原因3', value: 200 },
  { name: '不良原因4', value: 100 },
  { name: '不良原因5', value: 100 },
  { name: '不良原因6', value: 100 },
])
const ngTotal = computed(() => ngReasonData.value.reduce((s, it) => s + Number(it.value || 0), 0))
const ngRows = computed(() => {
  const total = ngTotal.value || 0
  return ngReasonData.value.map((it) => {
    const v = Number(it.value || 0)
    const p = total ? Math.round((v / total) * 100) : 0
    return { name: it.name, value: v, percent: p }
  })
})
const pieTooltip = {
  trigger: 'item',
  formatter: (p) => `${p.marker} ${p.name}:${p.value}(${p.percent}%)`,
}
const pieSeries = computed(() => [
  {
    name: '不良原因',
    type: 'pie',
    radius: ['52%', '76%'],
    center: ['50%', '50%'],
    avoidLabelOverlap: true,
    label: { show: false },
    labelLine: { show: false },
    data: ngReasonData.value,
  },
])
// åº•部:折线图(年份联动的每个工序不良率)
const lineGrid = { left: '4%', right: '4%', top: 60, bottom: 30, containLabel: true }
const lineLegend = computed(() => {
  return {
    show: true,
    top: 8,
    textStyle: { color: '#666' },
    data: ['平均不良率', '工序A', '工序B', '工序C'],
  }
})
const chartDataByYear = {
  '2023': {
    x: ['2023/02/21', '2023/03/02', '2023/03/13', '2023/03/24', '2023/04/04', '2023/04/15', '2023/04/28'],
    bar: [30, 32, 35, 40, 38, 42, 39],
    lineA: [45, 48, 52, 60, 55, 62, 58],
    lineB: [30, 32, 38, 45, 40, 48, 42],
    lineC: [20, 24, 30, 35, 32, 38, 33],
  },
  '2024': {
    x: ['2024/02/21', '2024/03/02', '2024/03/13', '2024/03/24', '2024/04/04', '2024/04/15', '2024/04/28'],
    bar: [28, 30, 33, 37, 35, 39, 36],
    lineA: [42, 46, 50, 58, 53, 60, 56],
    lineB: [28, 31, 36, 43, 38, 46, 40],
    lineC: [18, 21, 27, 33, 29, 35, 30],
  },
  '2025': {
    x: ['2025/02/21', '2025/03/02', '2025/03/13', '2025/03/24', '2025/04/04', '2025/04/15', '2025/04/28'],
    bar: [32, 34, 37, 42, 40, 45, 41],
    lineA: [45, 49, 54, 61, 57, 64, 60],
    lineB: [31, 33, 39, 47, 41, 50, 44],
    lineC: [21, 25, 31, 37, 34, 40, 35],
  },
}
const chartData = computed(() => {
  return chartDataByYear[currentYear.value] || chartDataByYear['2025']
})
const lineXAxis = computed(() => {
  return [
    {
      type: 'category',
      data: chartData.value.x,
      axisTick: { show: false },
      axisLabel: { color: '#666' },
    },
  ]
})
const lineYAxis = computed(() => {
  return [
    {
      type: 'value',
      axisLabel: { color: '#666' },
      splitLine: { lineStyle: { color: 'rgba(0,0,0,0.06)' } },
      name: '不良率(%)',
    },
  ]
})
const lineSeries = computed(() => [
  {
    name: '平均不良率',
    type: 'bar',
    barWidth: 18,
    data: chartData.value.bar,
    itemStyle: {
      color: 'rgba(59, 130, 246, 0.15)',
      borderRadius: [4, 4, 0, 0],
    },
  },
  {
    name: '工序A',
    type: 'line',
    smooth: true,
    data: chartData.value.lineA,
    symbol: 'circle',
    symbolSize: 6,
    lineStyle: { width: 2, color: '#3b82f6' },
    itemStyle: { color: '#3b82f6' },
  },
  {
    name: '工序B',
    type: 'line',
    smooth: true,
    data: chartData.value.lineB,
    symbol: 'circle',
    symbolSize: 6,
    lineStyle: { width: 2, color: '#f59e0b' },
    itemStyle: { color: '#f59e0b' },
  },
  {
    name: '工序C',
    type: 'line',
    smooth: true,
    data: chartData.value.lineC,
    symbol: 'circle',
    symbolSize: 6,
    lineStyle: { width: 2, color: '#10b981' },
    itemStyle: { color: '#10b981' },
  },
])
</script>
<style scoped>
.large-screen {
  padding: 18px 20px;
  background: #f5f7fb;
}
.top-kpi-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.top-stat-row {
  margin-top: 12px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 12px;
}
.group-card {
  background: #fff;
  border-radius: 8px;
  padding: 14px 16px;
  box-shadow: 0 6px 22px rgba(16, 24, 40, 0.08);
  border: 1px solid rgba(2, 6, 23, 0.06);
  display: grid;
  grid-template-columns: 120px 1fr;
  min-height: 112px;
}
.group-card--wide {
  grid-column: span 1;
}
.group-left {
  display: flex;
  align-items: center;
  justify-content: center;
}
.group-icon {
  width: 110px;
  height: 110px;
  border-radius: 18px;
  background: transparent;
  border: 0;
  position: relative;
  overflow: hidden;
}
.group-icon::before {
  content: none;
}
.group-icon::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}
.group-icon--order::after {
  background-image: url('@/assets/BI/kpiIcons/kpi-dataBoard.png');
}
.group-icon--quality::after {
  background-image: url('@/assets/BI/kpiIcons/kpi-shield.png');
}
.group-right {
  display: flex;
  align-items: center;
  padding-left: 60px;
}
.group-metrics {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  width: 100%;
}
.metric {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
}
.metric--plain .metric-title {
  font-weight: 400;
  font-size: 16px;
  color: #111827;
  line-height: 1.1;
}
.metric-value {
  margin-top: 10px;
  font-size: 30px;
  font-weight: 400;
  color: #111827;
  line-height: 1;
  letter-spacing: 0.5px;
}
.metric-sub {
  margin-top: 10px;
  font-size: 12px;
  color: rgba(2, 6, 23, 0.58);
}
.unit {
  margin-left: 4px;
  font-size: 12px;
  font-weight: 600;
  color: rgba(2, 6, 23, 0.55);
}
.unit1 {
  margin-left: 4px;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
}
.stat-card {
  background: #fff;
  border-radius: 8px;
  padding: 14px 18px;
  box-shadow: 0 6px 22px rgba(16, 24, 40, 0.08);
  border: 1px solid rgba(2, 6, 23, 0.06);
  display: grid;
  grid-template-columns: 1fr 58px;
  column-gap: 12px;
  align-items: center;
  min-height: 116px;
}
.stat-card--primary {
  background: linear-gradient(135deg, #2f6bff 0%, #3a87ff 100%);
  border-color: rgba(47, 107, 255, 0.18);
  color: #fff;
  grid-template-columns: 1fr 1fr;
  position: relative;
  overflow: hidden;
}
.stat-card--primary .stat-title,
.stat-card--primary .stat-sub,
.stat-card--primary .stat-value,
.stat-card--primary .trend {
  color: #fff;
}
.stat-card--primary .trend.up,
.stat-card--primary .trend.down {
  color: #fff;
}
.stat-card--primary .trend-arrow-svg.is-up {
  color: #fff;
}
.stat-card--primary .trend-arrow-svg.is-down {
  color: #fff;
}
.stat-primary-decor {
  width: 100%;
  height: 100%;
  border-radius: 12px;
  position: relative;
}
.stat-primary-decor::after {
  content: none;
}
.stat-card--primary::after {
  content: '';
  position: absolute;
  right: -12px;
  bottom: -22px;
  width: 120px;
  height: 120px;
  background-image: url('@/assets/BI/kpiIcons/kpi-cartCutout.png');
  background-repeat: no-repeat;
  background-position: right bottom;
  background-size: contain;
  opacity: 0.95;
  pointer-events: none;
}
.stat-main {
  display: flex;
  flex-direction: column;
}
.stat-title {
  margin-top: 8px;
  font-size: 13px;
  color: rgba(17, 24, 39, 0.86);
}
.stat-value {
  font-size: 38px;
  font-weight: 400;
  color: #111827;
  line-height: 1;
  letter-spacing: 0.2px;
}
.currency-sign {
  font-size: 0.58em;
  margin-right: 2px;
  vertical-align: 8%;
}
.stat-sub {
  margin-top: 10px;
  font-size: 12px;
  color: rgba(17, 24, 39, 0.75);
  display: flex;
  align-items: center;
  gap: 4px;
}
.trend {
    font-size: 20px;
  font-weight: 400;
  color: #16a34a;
}
.trend.up {
  color: #16a34a;
}
.trend.down {
  color: #dc2626;
}
.trend-arrow-svg {
  width: 17px;
  height: 11px;
  margin-left: 3px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.trend-arrow-svg--up {
  transform: scaleY(-1);
  transform-origin: center;
}
.trend-arrow-svg.is-up {
  color: #16a34a;
}
.trend-arrow-svg.is-down {
  color: #dc2626;
}
.stat-icon {
  width: 54px;
  height: 54px;
  border-radius: 999px;
  border: 1px solid rgba(2, 6, 23, 0.04);
  box-shadow: 0 4px 10px rgba(2, 6, 23, 0.08), inset 0 2px 10px rgba(255, 255, 255, 0.55);
}
.stat-card--blue .stat-icon {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.25);
}
.stat-icon--money {
  background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.12) 45%),
    linear-gradient(135deg, rgba(255, 183, 77, 0.22), rgba(255, 171, 64, 0.4));
}
.stat-icon--qty {
  background: transparent;
  border: 0;
  box-shadow: none;
  background-image: url('@/assets/BI/kpiIcons/kpi-dataBoard.png');
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}
.stat-icon--cost {
  background: transparent;
  border: 0;
  box-shadow: none;
  background-image: url('@/assets/BI/kpiIcons/kpi-dbIcon.png');
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}
.stat-icon--supplier {
  background: transparent;
  border: 0;
  box-shadow: none;
  background-image: url('@/assets/BI/kpiIcons/kpi-cloud.png');
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}
.mid-row {
  margin-top: 14px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: stretch;
}
.bottom-row {
  margin-top: 14px;
}
.panel {
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 18px rgba(20, 28, 47, 0.06);
  border: 1px solid rgba(20, 28, 47, 0.06);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 360px;
}
.panel--rect {
  border-radius: 0;
}
.panel-full {
  min-height: 320px;
}
.panel-header {
  padding: 12px 14px;
  border-bottom: 1px solid rgba(2, 6, 23, 0.06);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.panel-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: rgba(2, 6, 23, 0.6);
  white-space: nowrap;
}
.panel-select {
  min-width: 88px;
}
:deep(.panel-select .el-select__wrapper) {
  width: 88px;
}
:deep(.panel-select .el-select__selected-text) {
  white-space: nowrap;
}
.panel-title {
  font-weight: 800;
  color: #030303;
  font-size: 14px;
  letter-spacing: 1px;
  position: relative;
  padding-left: 10px;
}
.panel-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 14px;
  border-radius: 999px;
  background: #0047ff;
}
.panel-subtitle {
  margin-top: 6px;
  font-size: 13px;
  color: rgba(2, 6, 23, 0.58);
}
.panel-body {
  padding: 12px 14px 14px;
  flex: 1;
  min-height: 280px;
  position: relative;
  display: flex;
  flex-direction: column;
}
.bottom-chart-wrap {
  width: 90%;
  margin: 0 auto;
}
.product-pie-wrapper {
  flex: 0 0 260px;
}
.chart-unit {
  font-size: 12px;
  color: rgba(107, 114, 128, 1);
  margin-bottom: 4px;
}
.category-cards {
  margin-top: 18px;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
}
.category-card {
  height: 64px;
  background: #f9fafb;
  border-radius: 6px;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.category-name {
  font-size: 13px;
  color: rgba(17, 24, 39, 0.7);
}
.category-val {
  margin-top: 6px;
  font-size: 14px;
  color: rgba(17, 24, 39, 0.9);
}
.donut-wrap {
  position: relative;
  height: 100%;
}
.donut-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
}
.donut-label {
  font-size: 12px;
  color: rgba(2, 6, 23, 0.58);
}
.donut-value {
  margin-top: 6px;
  font-size: 28px;
  font-weight: 900;
  color: #111827;
}
.ng-layout {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 14px;
  height: 100%;
}
.ng-list {
  padding: 8px 10px;
  background: #f7f8fb;
  border-radius: 6px;
}
.ng-list-title {
  font-weight: 400;
  font-size: 14px;
  color: rgba(2, 6, 23, 0.75);
  margin: 4px 0 10px;
}
.ng-list-head {
  display: grid;
  grid-template-columns: 1fr 64px 64px;
  gap: 6px;
  padding: 10px 8px 8px;
  border-radius: 0;
  background: transparent;
  color: rgba(2, 6, 23, 0.6);
  font-size: 13px;
  font-weight: 400;
  border-bottom: 1px solid rgba(2, 6, 23, 0.08);
}
.ng-list-body {
  margin-top: 2px;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.ng-row {
  display: grid;
  grid-template-columns: 1fr 64px 64px;
  gap: 6px;
  padding: 12px 8px;
  border-radius: 0;
  border: 0;
  border-bottom: 1px dashed rgba(2, 6, 23, 0.14);
  background: transparent;
}
.ng-col {
  display: flex;
  align-items: center;
  font-size: 18px;
  color: rgba(2, 6, 23, 0.72);
}
.ng-col--pct,
.ng-col--val {
  justify-content: flex-end;
  font-variant-numeric: tabular-nums;
}
.ng-col--val {
  font-weight: 400;
  color: rgba(2, 6, 23, 0.86);
}
.ng-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  margin-right: 8px;
}
.ng-name {
  font-weight: 400;
  color: rgba(2, 6, 23, 0.78);
}
.ng-col--pct,
.ng-col--val {
  font-size: 20px;
  color: rgba(2, 6, 23, 0.82);
}
.ng-chart {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ng-chart .donut-wrap {
  width: 100%;
  max-width: 360px;
  height: 320px;
}
@media (max-width: 1100px) {
  .ng-layout {
    grid-template-columns: 1fr;
  }
  .donut-wrap :deep(canvas) {
    margin: 0 auto;
  }
}
@media (max-width: 1600px) {
  /* ä¿®å¤æ—§å¸ƒå±€æ®‹ç•™ï¼šé¿å…å¼ºè¡Œ span å¯¼è‡´ top-kpi/top-stat ç½‘格错位 */
  .top-stat-row {
    grid-template-columns: 1fr 1fr 1fr;
  }
  .top-kpi-row {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 1100px) {
  .mid-row {
    grid-template-columns: 1fr;
  }
}
</style>
src/views/productionManagement/processRoute/index.vue
@@ -80,6 +80,10 @@
    prop: "model",
  },
  {
    label: "料号",
    prop: "materialCode",
  },
  {
    label: "BOM编号",
    prop: "bomNo",
  },
@@ -174,6 +178,7 @@
      processRouteCode: row.processRouteCode || '',
      productName: row.productName || '',
      model: row.model || '',
      materialCode: row.materialCode || '',
      bomNo: row.bomNo || '',
      description: row.description || '',
      type: 'route',
src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -31,6 +31,14 @@
        </div>
        <div class="info-item">
          <div class="info-label-wrapper">
            <span class="info-label">料号</span>
          </div>
          <div class="info-value-wrapper">
            <span class="info-value">{{ routeInfo.materialCode || '-' }}</span>
          </div>
        </div>
        <div class="info-item">
          <div class="info-label-wrapper">
            <span class="info-label">BOM编号</span>
          </div>
          <div class="info-value-wrapper">
@@ -81,6 +89,7 @@
      </el-table-column>
      <el-table-column label="产品名称" prop="productName" min-width="160" />
      <el-table-column label="规格名称" prop="model" min-width="140" />
      <el-table-column label="料号" prop="materialCode" min-width="140" />
      <el-table-column label="单位" prop="unit" width="100" />
      <el-table-column label="是否质检" prop="isQuality" width="100">
        <template #default="scope">
@@ -246,6 +255,7 @@
  processRouteCode: '',
  productName: '',
  model: '',
  materialCode: '',
  bomNo: '',
  description: ''
});
@@ -328,6 +338,7 @@
    processRouteCode: route.query.processRouteCode || '',
    productName: route.query.productName || '',
    model: route.query.model || '',
    materialCode: route.query.materialCode || '',
    bomNo: route.query.bomNo || '',
    description: route.query.description || ''
  };
src/views/productionManagement/productStructure/Detail/index.vue
@@ -53,6 +53,8 @@
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column prop="materialCode"
                               label="料号" />
              <el-table-column prop="processName"
                               label="消耗工序">
                <template #default="{ row, $index }">
@@ -145,6 +147,8 @@
                       prop="productName" />
      <el-table-column label="规格型号"
                       prop="model" />
      <el-table-column label="料号"
                       prop="materialCode" />
    </el-table>
    <product-select-dialog v-if="dataValue.showProductDialog"
                           v-model:model-value="dataValue.showProductDialog"
@@ -195,6 +199,7 @@
  const routeProductModelName = computed(
    () => route.query.productModelName || ""
  );
  const routeMaterialCode = computed(() => route.query.materialCode || "");
  const routeOrderId = computed(() => route.query.orderId);
  const pageType = computed(() => route.query.type);
  const isOrderPage = computed(
@@ -216,6 +221,7 @@
    {
      productName: "",
      model: "",
      materialCode: "",
      bomNo: "",
    },
  ]);
@@ -270,7 +276,8 @@
    if (isTopLevel) {
      if (
        productData.productName === tableData[0].productName &&
        productData.model === tableData[0].model
        productData.model === tableData[0].model &&
        productData.materialCode === tableData[0].materialCode
      ) {
        //  æŸ¥æ‰¾æ˜¯å¦å·²ç»æœ‰å…¶ä»–顶层行已经是这个产品
        const hasOther = dataValue.dataList.some(
@@ -294,6 +301,7 @@
      if (item.tempId === dataValue.currentRowName) {
        item.productName = productData.productName;
        item.model = productData.model;
        item.materialCode = productData.materialCode;
        item.productModelId = productData.id;
        item.unit = productData.unit || "";
        return;
@@ -306,6 +314,7 @@
    if (item.tempId === tempId) {
      item.productName = productData.productName;
      item.model = productData.model;
      item.materialCode = productData.materialCode;
      item.productModelId = productData.id;
      item.unit = productData.unit || "";
      return true;
@@ -507,6 +516,7 @@
    // ä»Žè·¯ç”±å‚数回显数据
    tableData[0].productName = routeProductName.value as string;
    tableData[0].model = routeProductModelName.value as string;
    tableData[0].materialCode = routeMaterialCode.value as string;
    tableData[0].bomNo = routeBomNo.value as string;
    // è®¢å•情况下禁用编辑
src/views/productionManagement/productStructure/index.vue
@@ -83,6 +83,11 @@
    minWidth: 140
  },
  {
    label: "料号",
    prop: "materialCode",
    minWidth: 100
  },
  {
    label: "版本号",
    prop: "version",
    width: 100
@@ -422,6 +427,7 @@
      id: row.id,
      bomNo: row.bomNo || '',
      productName: row.productName || '',
      materialCode: row.materialCode || '',
      productModelName: row.productModelName || ''
    }
  });
src/views/productionManagement/productionCosting/index.vue
@@ -102,6 +102,11 @@
        prop: "productModelName",
    minWidth: 100,
    },
  {
    label: "料号",
    prop: "materialCode",
    minWidth: 100,
  },
    {
        label: "单位",
        prop: "unit",
src/views/productionManagement/productionOrder/Detail/index.vue
@@ -11,6 +11,7 @@
          <span class="mr12">生产批号:{{ header.lotNo || "-" }}</span>
          <span class="mr12">产品名称:{{ header.productCategory || "-" }}</span>
          <span class="mr12">规格:{{ header.specificationModel || "-" }}</span>
          <span class="mr12">料号:{{ header.materialCode || "-" }}</span>
        </div>
      </div>
    </el-card>
@@ -204,6 +205,7 @@
  lotNo: route.query.lotNo,
  productCategory: route.query.productCategory,
  specificationModel: route.query.specificationModel,
  materialCode: route.query.materialCode,
}));
// å·¥åºæ•°æ®ï¼ˆæŽ¥å£æ›¿æ¢ï¼‰
src/views/productionManagement/productionOrder/New.vue
@@ -31,6 +31,13 @@
        </el-form-item>
        <el-form-item
            label="料号"
            prop="materialCode"
        >
          <el-input v-model="formState.materialCode"  disabled />
        </el-form-item>
        <el-form-item
            label="单位"
            prop="unit"
        >
@@ -128,6 +135,7 @@
  routeId: undefined,
  productName: "",
  productModelName: "",
  materialCode: "",
  unit: "",
  priority: undefined,
  quantity: 0,
@@ -161,6 +169,7 @@
    productName: "",
    productModelName: "",
    unit: "",
    materialCode: "",
    priority: priority_type.value && priority_type.value.length > 0 ? priority_type.value[2].value : undefined,
    quantity: '',
    lotNo: "",
@@ -177,6 +186,7 @@
    formState.value.productModelName = product.model;
    formState.value.productModelId = product.id;
    formState.value.unit = product.unit;
    formState.value.materialCode = product.materialCode || "";
    showProductSelectDialog.value = false;
    fetchRouteOptions( product.id);
    // è§¦å‘表单验证更新
src/views/productionManagement/productionOrder/index.vue
@@ -168,6 +168,11 @@
      width: '120px',
    },
    {
      label: "料号",
      prop: "materialCode",
      width: '120px',
    },
    {
      label: "工艺路线编号",
      prop: "processRouteCode",
      width: '200px',
@@ -399,6 +404,7 @@
          processRouteCode: data.processRouteCode || "",
          productName: data.productName || "",
          model: data.model || "",
          materialCode: data.materialCode || "",
          bomNo: data.bomNo || "",
          description: data.description || "",
          orderId,
@@ -419,6 +425,7 @@
        bomNo: row.bomNo || "",
        productName: row.productCategory || "",
        productModelName: row.specificationModel || "",
        materialCode: row.materialCode || "",
        orderId: row.id,
        type: "order",
      },
@@ -435,6 +442,7 @@
        lotNo: row.lotNo || "",
        productCategory: row.productCategory || "",
        specificationModel: row.specificationModel || "",
        materialCode: row.materialCode || "",
      },
    });
  };
src/views/productionManagement/productionReporting/Input.vue
@@ -67,6 +67,10 @@
    prop: 'model',
  },
  {
    label: '投入料号',
    prop: 'materialCode',
  },
  {
    label: '投入数量',
    prop: 'quantity',
  },
src/views/productionManagement/productionReporting/components/Detail.vue
@@ -56,6 +56,7 @@
      <el-descriptions-item label="工单编号">{{ row.workOrderNo || '-' }}</el-descriptions-item>
      <el-descriptions-item label="产品名称">{{ row.productName || '-' }}</el-descriptions-item>
      <el-descriptions-item label="产品规格型号">{{ row.productModelName || '-' }}</el-descriptions-item>
      <el-descriptions-item label="料号">{{ row.materialCode || '-' }}</el-descriptions-item>
      <el-descriptions-item label="产出数量">{{ row.quantity  || '-' }}</el-descriptions-item>
      <el-descriptions-item label="报废数量">{{ row.scrapQty || '-' }}</el-descriptions-item>
      <el-descriptions-item label="单位">{{ row.unit || '-' }}</el-descriptions-item>
src/views/productionManagement/productionReporting/index.vue
@@ -231,6 +231,11 @@
    width: 120,
  },
  {
    label: "料号",
    prop: "materialCode",
    width: 120,
  },
  {
    label: "产出数量",
    prop: "quantity",
    width: 120,
src/views/productionManagement/workOrder/index.vue
@@ -110,6 +110,10 @@
              <span class="info-label">产品规格</span>
              <span class="info-value">{{ transferCardRowData.model }}</span>
            </div>
            <div class="info-item">
              <span class="info-label">料号</span>
              <span class="info-value">{{ transferCardRowData.materialCode }}</span>
            </div>
            <!-- <div class="info-item">
              <span class="info-label">工单状态</span>
              <span class="info-value">{{ 
@@ -330,6 +334,10 @@
    prop: "model",
  },
  {
    label: "料号",
    prop: "materialCode",
  },
  {
    label: "单位",
    prop: "unit",
  },
src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -57,13 +57,24 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入" disabled/>
            <el-form-item label="料号:" prop="materialCode">
              <el-input v-model="form.materialCode" placeholder="请输入" disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="不良数量:" prop="defectiveQuantity">
              <el-input v-model="form.defectiveQuantity" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入" disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="合格数量:" prop="qualifiedQuantity">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.qualifiedQuantity" placeholder="请输入" clearable :precision="2" disabled/>
            </el-form-item>
          </el-col>
        </el-row>
@@ -77,13 +88,6 @@
          </el-col>
          <el-col :span="12">
            <el-form-item label="合格数量:" prop="qualifiedQuantity">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.qualifiedQuantity" placeholder="请输入" clearable :precision="2" disabled/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="检测单位:" prop="checkCompany">
              <el-input v-model="form.checkCompany" placeholder="请输入" clearable/>
            </el-form-item>
@@ -96,14 +100,13 @@
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="检验员:" prop="checkName">
                            <el-select v-model="form.checkName" placeholder="请选择" clearable>
                                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                                                     :value="item.nickName"/>
                            </el-select>
              <el-select v-model="form.checkName" placeholder="请选择" clearable>
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                           :value="item.nickName"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
@@ -167,6 +170,7 @@
    testStandardId: "",
    defectiveReason: undefined,
    unit: "",
    materialCode: "",
    qualifiedQuantity: "",
    quantity: "",
    checkCompany: "",
@@ -304,6 +308,7 @@
          if (selectedModel) {
            form.value.model = selectedModel.model || '';
            form.value.unit = selectedModel.unit || '';
            form.value.materialCode = selectedModel.materialCode || '';
          }
        }
        
@@ -343,6 +348,7 @@
const getModels = (value) => {
  form.value.productModelId = undefined;
  form.value.unit = undefined;
  form.value.materialCode = undefined;
  modelOptions.value = [];
  currentProductId.value = value
  form.value.productName = findNodeById(productOptions.value, value);
@@ -357,6 +363,7 @@
const handleChangeModel = (value) => {
  form.value.model = modelOptions.value.find(item => item.id == value)?.model || '';
  form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || '';
  form.value.materialCode = modelOptions.value.find(item => item.id == value)?.materialCode || '';
}
const findNodeById = (nodes, productId) => {
src/views/qualityManagement/finalInspection/index.vue
@@ -113,6 +113,10 @@
    prop: "model",
  },
  {
    label: "料号",
    prop: "materialCode",
  },
  {
    label: "单位",
    prop: "unit",
  },
src/views/qualityManagement/processInspection/components/formDia.vue
@@ -43,28 +43,27 @@
          <el-col :span="12">
            <el-form-item label="指标选择:" prop="testStandardId">
              <el-select
                v-model="form.testStandardId"
                placeholder="请选择指标"
                clearable
                @change="handleTestStandardChange"
                style="width: 100%"
                  v-model="form.testStandardId"
                  placeholder="请选择指标"
                  clearable
                  @change="handleTestStandardChange"
                  style="width: 100%"
              >
                <el-option
                  v-for="item in testStandardOptions"
                  :key="item.id"
                  :label="item.standardName || item.standardNo"
                  :value="item.id"
                    v-for="item in testStandardOptions"
                    :key="item.id"
                    :label="item.standardName || item.standardNo"
                    :value="item.id"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入" disabled/>
            <el-form-item label="料号:" prop="materialCode">
              <el-input v-model="form.materialCode" placeholder="请输入" disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="不良数量:" prop="defectiveQuantity">
              <el-input-number
@@ -80,18 +79,19 @@
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="单位:" prop="unit">
              <el-input v-model="form.unit" placeholder="请输入" disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="合格数量:" prop="qualifiedQuantity">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.qualifiedQuantity" placeholder="请输入" clearable :precision="2" disabled/>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量:" prop="quantity">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.quantity" placeholder="请输入" clearable :precision="2" :disabled="operationType !== 'add'"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="不良原因:" prop="defectiveReason">
              <el-select v-model="form.defectiveReason" placeholder="请选择" clearable style="width: 100%">
@@ -105,13 +105,20 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="数量:" prop="quantity">
              <el-input-number :step="0.01" :min="0" style="width: 100%" v-model="form.quantity" placeholder="请输入" clearable :precision="2" :disabled="operationType !== 'add'"/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="检测单位:" prop="checkCompany">
              <el-input v-model="form.checkCompany" placeholder="请输入" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="检验员:" prop="checkName">
              <el-select v-model="form.checkName" placeholder="请选择" clearable>
@@ -119,14 +126,14 @@
                           :value="item.nickName"/>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检测结果:" prop="checkResult">
              <el-select v-model="form.checkResult">
                <el-option label="合格" value="合格" />
                <el-option label="不合格" value="不合格" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="检测日期:" prop="checkTime">
@@ -193,6 +200,7 @@
    model: "",
    testStandardId: "",
    unit: "",
    materialCode: "",
    quantity: "",
    defectiveQuantity: "",
    defectiveReason: "",
@@ -309,6 +317,7 @@
        model: "",
        testStandardId: "",
        unit: "",
    materialCode: "",
        quantity: "",
        checkCompany: "",
        checkResult: "",
@@ -393,6 +402,7 @@
const getModels = (value) => {
  form.value.productModelId = undefined;
  form.value.unit = undefined;
  form.value.materialCode = undefined;
  modelOptions.value = [];
  currentProductId.value = value
  form.value.productName = findNodeById(productOptions.value, value);
@@ -407,6 +417,7 @@
const handleChangeModel = (value) => {
  form.value.model = modelOptions.value.find(item => item.id == value)?.model || '';
  form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || '';
  form.value.materialCode = modelOptions.value.find(item => item.id == value)?.materialCode || '';
}
const findNodeById = (nodes, productId) => {
src/views/qualityManagement/processInspection/index.vue
@@ -118,6 +118,10 @@
    prop: "model",
  },
  {
    label: "料号",
    prop: "materialCode",
  },
  {
    label: "单位",
    prop: "unit",
  },
src/views/salesManagement/salesLedger/index.vue
@@ -47,6 +47,7 @@
              <el-table-column label="产品大类" prop="productCategory" />
              <el-table-column label="规格型号" prop="specificationModel" />
              <el-table-column label="单位" prop="unit" />
              <el-table-column label="料号" prop="materialCode" />
                            <el-table-column label="产品状态"
                                                             width="100px"
                                                             align="center">
@@ -228,6 +229,7 @@
                    <el-table-column label="产品大类" prop="productCategory" />
                    <el-table-column label="规格型号" prop="specificationModel" />
                    <el-table-column label="单位" prop="unit" />
                    <el-table-column label="料号" prop="materialCode" />
                    <el-table-column label="数量" prop="quantity" />
                    <el-table-column label="税率(%)" prop="taxRate" />
                    <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
@@ -360,6 +362,14 @@
                            </el-select>
                        </el-form-item>
                    </el-col>
          <el-col :span="24">
            <el-form-item label="料号:"
                          prop="materialCode">
              <el-input v-model="productForm.materialCode"
                        placeholder="请输入"
                        disabled />
            </el-form-item>
          </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
@@ -537,7 +547,7 @@
                                    <thead>
                                    <tr>
                                        <th>序号</th>
                                        <th>物料编号</th>
                                        <th>料号</th>
                                        <th>品名/规格</th>
                                        <th>单位</th>
                                        <th>数量</th>
@@ -753,6 +763,7 @@
    productForm: {
        productCategory: "",
        specificationModel: "",
    materialCode: "",
        unit: "",
        quantity: "",
        taxInclusiveUnitPrice: "",
@@ -955,9 +966,11 @@
    if (index !== -1) {
        productForm.value.specificationModel = modelOptions.value[index].model;
        productForm.value.unit = modelOptions.value[index].unit;
    productForm.value.materialCode = modelOptions.value[index].materialCode;
    } else {
        productForm.value.specificationModel = null;
        productForm.value.unit = null;
    productForm.value.materialCode = null;
    }
};
const findNodeById = (nodes, productId) => {
@@ -1792,7 +1805,7 @@
              <thead>
                <tr>
                  <th>序号</th>
                  <th>物料编号</th>
                  <th>料号</th>
                  <th>品名/规格</th>
                  <th>单位</th>
                  <th>数量</th>