gaoluyang
2026-06-12 ac00bb7b8eae1bf6aabb7f1ae67c2e5aa5b8ae90
src/views/index.vue
@@ -113,10 +113,11 @@
          <div class="panel-title-row">
            <div class="panel-title">生产订单进度</div>
            <el-radio-group v-model="orderFilter" size="small">
              <el-radio-button label="all">全部({{ orderProgressMeta.total }})</el-radio-button>
              <el-radio-button label="inProgress">进行中({{ orderProgressMeta.inProgressCount }})</el-radio-button>
              <el-radio-button label="completed">已完成({{ orderProgressMeta.completedCount }})</el-radio-button>
              <el-radio-button label="paused">已暂停({{ orderProgressMeta.pausedCount }})</el-radio-button>
              <el-radio-button :value="'all'">全部({{ orderProgressMeta.total }})</el-radio-button>
              <el-radio-button :value="'waiting'">待开始({{ orderProgressMeta.waitingCount }})</el-radio-button>
              <el-radio-button :value="'inProgress'">进行中({{ orderProgressMeta.inProgressCount }})</el-radio-button>
              <el-radio-button :value="'completed'">已完成({{ orderProgressMeta.completedCount }})</el-radio-button>
              <el-radio-button :value="'paused'">已暂停({{ orderProgressMeta.pausedCount }})</el-radio-button>
            </el-radio-group>
          </div>
          <el-table :data="filteredOrders" stripe>
@@ -319,7 +320,7 @@
      <div class="process-selection-wrapper">
        <el-checkbox-group v-model="tempProcessIds">
          <div class="process-grid">
            <el-checkbox v-for="item in processOptions" :key="item.id" :label="item.id" border>
            <el-checkbox v-for="item in processOptions" :key="item.id" :value="item.id" border>
              {{ item.name }}
            </el-checkbox>
          </div>
@@ -454,10 +455,13 @@
});
const orderProgressMeta = ref({
  status: "all",
  tab: "all",
  bizDate: null,
  total: 0,
  pageNum: 1,
  pageSize: 10,
  waitingCount: 0,
  inProgressCount: 0,
  completedCount: 0,
  pausedCount: 0,
@@ -708,7 +712,7 @@
    const lines = list
        .map((p) => {
          const colorBox = `<span style="display:inline-block;margin-right:6px;border-radius:2px;width:10px;height:10px;background:${p.color}"></span>`;
          return `${colorBox}${p.seriesName}<b style="float:right;">${Number(p.value || 0).toFixed(2)}</b>`;
          return `${colorBox}${p.seriesName}<b style="float:right;">${Number(p.value || 0).toFixed(4)}</b>`;
        })
        .join("<br/>");
    return `<div style="min-width:140px;"><div style="font-weight:700;margin-bottom:6px;">${name}</div>${lines}</div>`;
@@ -824,7 +828,7 @@
    value: formatNumber(productionOverviewData.value.totalOutput),
    subLabel: "累计报废",
    subValue: formatNumber(productionOverviewData.value.totalScrap),
    trend: `良率 ${Number(productionOverviewData.value.yieldRate || 0).toFixed(2)}%`,
    trend: `良率 ${Number(productionOverviewData.value.yieldRate || 0).toFixed(4)}%`,
    icon: Operation,
    visible: visibleModules.value.production,
  },
@@ -832,8 +836,36 @@
const productionOrders = ref([]);
const orderFilterOptions = ["all", "waiting", "inProgress", "completed", "paused"];
const orderFilterAliasMap = {
  1: "waiting",
  2: "inProgress",
  3: "completed",
  4: "paused",
};
const orderFilter = ref("all");
const filteredOrders = computed(() => productionOrders.value);
const normalizeOrderFilter = (value, fallback = "all") => {
  const safeFallback = orderFilterOptions.includes(fallback) ? fallback : "all";
  const text = String(value ?? "").trim();
  if (orderFilterAliasMap[text]) {
    return orderFilterAliasMap[text];
  }
  return orderFilterOptions.includes(text) ? text : safeFallback;
};
const parseCount = (value) => {
  if (value === null || value === undefined || value === "") return null;
  const num = Number(value);
  return Number.isFinite(num) ? num : null;
};
const resolveProgressCount = (rawValue, currentStatus, targetStatus, total) => {
  const count = parseCount(rawValue);
  if (count !== null) return count;
  return currentStatus === targetStatus ? total : 0;
};
const getCompareTrend = (value) => {
  const num = Number(value || 0);
@@ -844,7 +876,7 @@
const getCompareText = (value) => {
  const num = Number(value || 0);
  const abs = Math.abs(num).toFixed(2);
  const abs = Math.abs(num).toFixed(4);
  if (num > 0) return `较昨日 ↑ ${abs}%`;
  if (num < 0) return `较昨日 ↓ ${abs}%`;
  return "较昨日 持平";
@@ -862,7 +894,7 @@
      key: "oee",
      label: "设备 OEE",
      percent: clampPercent(oee),
      display: `${oee.toFixed(2)}%`,
      display: `${oee.toFixed(4)}%`,
      delta: getCompareText(oeeCompare),
      trend: getCompareTrend(oeeCompare),
      color: "#2d8cff",
@@ -871,7 +903,7 @@
      key: "order",
      label: "订单达成率",
      percent: clampPercent(orderAchievement),
      display: `${orderAchievement.toFixed(2)}%`,
      display: `${orderAchievement.toFixed(4)}%`,
      delta: getCompareText(orderCompare),
      trend: getCompareTrend(orderCompare),
      color: "#31d2ff",
@@ -880,7 +912,7 @@
      key: "defect",
      label: "不良率",
      percent: clampPercent(defectRate),
      display: `${defectRate.toFixed(2)}%`,
      display: `${defectRate.toFixed(4)}%`,
      delta: getCompareText(defectCompare),
      trend: getCompareTrend(defectCompare),
      color: "#f6a23f",
@@ -1090,7 +1122,7 @@
const trendText = (value) => {
  const num = Number(value || 0);
  const flag = num >= 0 ? "↑" : "↓";
  return `${flag} ${Math.abs(num).toFixed(1)}%`;
  return `${flag} ${Math.abs(num).toFixed(4)}%`;
};
const ratioNumber = (numerator, denominator) => {
@@ -1100,7 +1132,7 @@
  return (n / d) * 100;
};
const ratioText = (numerator, denominator) => `${ratioNumber(numerator, denominator).toFixed(1)}%`;
const ratioText = (numerator, denominator) => `${ratioNumber(numerator, denominator).toFixed(4)}%`;
const clampPercent = (val) => Math.max(0, Math.min(100, Number(val || 0)));
@@ -1198,27 +1230,36 @@
const refreshProductionOrderProgress = async () => {
  try {
    const res = await productionOrderProgress({
      status: orderFilter.value,
      tab: orderFilter.value,
      pageNum: 1,
      pageSize: 10,
    });
    const data = res?.data || {};
    const statusValue = normalizeOrderFilter(data.status, orderFilter.value);
    const total = Number(data.total || 0);
    orderProgressMeta.value = {
      status: statusValue,
      tab: data.tab || orderFilter.value,
      total: Number(data.total || 0),
      bizDate: data.bizDate || null,
      total,
      pageNum: Number(data.pageNum || 1),
      pageSize: Number(data.pageSize || 10),
      inProgressCount: Number(data.inProgressCount || 0),
      completedCount: Number(data.completedCount || 0),
      pausedCount: Number(data.pausedCount || 0),
      waitingCount: resolveProgressCount(data.waitingCount, statusValue, "waiting", total),
      inProgressCount: resolveProgressCount(data.inProgressCount, statusValue, "inProgress", total),
      completedCount: resolveProgressCount(data.completedCount, statusValue, "completed", total),
      pausedCount: resolveProgressCount(data.pausedCount, statusValue, "paused", total),
    };
    productionOrders.value = (data.records || []).map(mapOrderProgressRecord);
  } catch {
    orderProgressMeta.value = {
      status: orderFilter.value,
      tab: orderFilter.value,
      bizDate: null,
      total: 0,
      pageNum: 1,
      pageSize: 10,
      waitingCount: 0,
      inProgressCount: 0,
      completedCount: 0,
      pausedCount: 0,
@@ -1229,7 +1270,10 @@
const refreshTodayProductionPlan = async () => {
  try {
    const res = await todayProductionPlan({ limit: 4 });
    const res = await todayProductionPlan({
      limit: 4,
      planDate: nowDate.value,
    });
    const data = res?.data || {};
    todayPlanTotal.value = Number(data.total || 0);
    todayPlanList.value = (data.records || []).map(mapTodayPlanRecord);
@@ -1263,9 +1307,12 @@
const statisticsReceivable = async () => {
  const res = await statisticsReceivablePayable({ type: 1 });
  const data = res?.data || {};
  const payableMoney = Number(data.payableMoney ?? 0);
  const receivableMoney = Number(data.receivableMoney ?? 0);
  barSeries.value[0].data = [
    { value: res.data.payableMoney, itemStyle: { color: barColors2[0] } },
    { value: res.data.receivableMoney, itemStyle: { color: barColors2[1] } },
    { value: payableMoney, itemStyle: { color: barColors2[0] } },
    { value: receivableMoney, itemStyle: { color: barColors2[1] } },
  ];
};
@@ -1275,15 +1322,16 @@
  barSeries1.value[0].data = [];
  barSeries1.value[1].data = [];
  barSeries1.value[2].data = [];
  (res.data.item || []).forEach((item) => {
  const data = res.data || {};
  (data.item || []).forEach((item) => {
    xAxis1.value[0].data.push(item.date);
    barSeries1.value[0].data.push(item.supplierNum);
    barSeries1.value[1].data.push(item.processNum);
    barSeries1.value[2].data.push(item.factoryNum);
  });
  qualityStatisticsObject.value.supplierNum = res.data.supplierNum;
  qualityStatisticsObject.value.processNum = res.data.processNum;
  qualityStatisticsObject.value.factoryNum = res.data.factoryNum;
  qualityStatisticsObject.value.supplierNum = data.supplierNum || 0;
  qualityStatisticsObject.value.processNum = data.processNum || 0;
  qualityStatisticsObject.value.factoryNum = data.factoryNum || 0;
};
const getAmountHalfYearNum = async () => {