已修改11个文件
207 ■■■■■ 文件已修改
src/views/equipmentManagement/inspectionManagement/components/formDia.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/inspectionManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentLedger/index.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionTraceability/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/components/formDia.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/processInspection/components/formDia.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/receiptPaymentLedger/index.vue 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/systemArchitecture/index.vue 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/inspectionManagement/components/formDia.vue
@@ -237,6 +237,14 @@
    form.value = {...row}
    form.value.inspector = form.value.inspectorIds.split(',').map(Number)
    
    // 处理WEEKLY频率的回显:将frequencyDetail拆分为week和time
    if (form.value.frequencyType === 'WEEKLY' && form.value.frequencyDetail) {
      const parts = form.value.frequencyDetail.split(',')
      form.value.week = parts[0] || ''
      form.value.time = parts[1] || ''
      form.value.frequencyDetail = ''
    }
    // 如果有设备ID,自动设置设备信息
    if (form.value.taskId) {
      setDeviceModel(form.value.taskId);
src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue
@@ -230,7 +230,7 @@
  const formatDateTime = date => {
    if (!date) return "-";
    return dayjs(date).format("YYYY-MM-DD HH:mm:ss");
    return dayjs(date).format("YYYY-MM-DD");
  };
  const hasException = ref(null);
src/views/equipmentManagement/inspectionManagement/index.vue
@@ -197,7 +197,7 @@
      formatData: cell => {
        if (!cell) return "-";
        try {
          return dayjs(cell).format("YYYY-MM-DD HH:mm:ss");
          return dayjs(cell).format("YYYY-MM-DD");
        } catch {
          return cell;
        }
src/views/index.vue
@@ -214,7 +214,7 @@
        <div v-if="visiblePanels.todo" class="cockpit-panel todo-panel">
          <div class="panel-title-row">
            <div class="panel-title">待办事项</div>
            <span class="panel-more">更多</span>
            <span class="panel-more" @click="goToApprovalProcess">更多</span>
          </div>
          <ul class="todo-list" v-if="todoList.length > 0">
            <li v-for="item in todoList" :key="item.id" class="todo-item">
@@ -232,7 +232,7 @@
        <div v-if="visiblePanels.realtime" class="cockpit-panel realtime-panel">
          <div class="panel-title-row">
            <div class="panel-title">生产实时看板</div>
            <span class="panel-more">更多</span>
            <span class="panel-more" @click="goToProductionOrder">更多</span>
          </div>
          <div class="realtime-grid">
            <div class="realtime-item" v-for="item in realtimeBoard" :key="item.key">
@@ -278,7 +278,7 @@
        <div v-if="visiblePanels.plan" class="cockpit-panel plan-panel">
          <div class="panel-title-row">
            <div class="panel-title">今日生产计划</div>
            <span class="panel-more">{{ todayPlanTotal }}项</span>
            <span class="panel-more" @click="goToProductionPlan">{{ todayPlanTotal }}项</span>
          </div>
          <ul class="plan-list">
            <li v-for="item in todayPlanList" :key="item.orderNo" class="plan-item">
@@ -449,7 +449,6 @@
});
const realtimeBoardData = ref({
  deviceOee: { value: 0, compareYesterday: 0 },
  orderAchievementRate: { value: 0, compareYesterday: 0 },
  defectRate: { value: 0, compareYesterday: 0 },
});
@@ -883,22 +882,11 @@
};
const realtimeBoard = computed(() => {
  const oee = Number(realtimeBoardData.value.deviceOee?.value || 0);
  const orderAchievement = Number(realtimeBoardData.value.orderAchievementRate?.value || 0);
  const defectRate = Number(realtimeBoardData.value.defectRate?.value || 0);
  const oeeCompare = Number(realtimeBoardData.value.deviceOee?.compareYesterday || 0);
  const orderCompare = Number(realtimeBoardData.value.orderAchievementRate?.compareYesterday || 0);
  const defectCompare = Number(realtimeBoardData.value.defectRate?.compareYesterday || 0);
  return [
    {
      key: "oee",
      label: "设备 OEE",
      percent: clampPercent(oee),
      display: `${oee.toFixed(2)}%`,
      delta: getCompareText(oeeCompare),
      trend: getCompareTrend(oeeCompare),
      color: "#2d8cff",
    },
    {
      key: "order",
      label: "订单达成率",
@@ -906,7 +894,7 @@
      display: `${orderAchievement.toFixed(2)}%`,
      delta: getCompareText(orderCompare),
      trend: getCompareTrend(orderCompare),
      color: "#31d2ff",
      color: "#2d8cff",
    },
    {
      key: "defect",
@@ -1205,10 +1193,6 @@
    const res = await productionRealtimeBoard();
    const data = res?.data || {};
    realtimeBoardData.value = {
      deviceOee: {
        value: Number(data.deviceOee?.value || 0),
        compareYesterday: Number(data.deviceOee?.compareYesterday || 0),
      },
      orderAchievementRate: {
        value: Number(data.orderAchievementRate?.value || 0),
        compareYesterday: Number(data.orderAchievementRate?.compareYesterday || 0),
@@ -1220,7 +1204,6 @@
    };
  } catch {
    realtimeBoardData.value = {
      deviceOee: { value: 0, compareYesterday: 0 },
      orderAchievementRate: { value: 0, compareYesterday: 0 },
      defectRate: { value: 0, compareYesterday: 0 },
    };
@@ -1396,6 +1379,18 @@
const goToQuick = (path) => {
  if (!path) return;
  router.push(path).catch(() => {});
};
const goToProductionOrder = () => {
  router.push('/productionManagement/productionOrder').catch(() => {});
};
const goToApprovalProcess = () => {
  router.push('/collaborativeApproval/approvalProcess').catch(() => {});
};
const goToProductionPlan = () => {
  router.push('/productionManagement/productionPlan').catch(() => {});
};
watch(orderFilter, () => {
@@ -2094,7 +2089,7 @@
.realtime-grid {
  margin-top: 10px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
@@ -2102,12 +2097,12 @@
  border: 1px solid rgba(148, 163, 184, 0.2);
  border-radius: 12px;
  background: #f8fbff;
  padding: 10px 8px;
  padding: 16px 12px;
  text-align: center;
}
.realtime-value {
  font-size: 26px;
  font-size: 32px;
  color: #0f172a;
  font-weight: 700;
}
@@ -2432,7 +2427,7 @@
  }
  .realtime-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .quality-cards {
src/views/procurementManagement/paymentLedger/index.vue
@@ -42,16 +42,16 @@
                             prop="contractAmounts"
                             show-overflow-tooltip
                             :formatter="formattedNumber" />
            <el-table-column label="付款金额(元)"
                             prop="paymentAmount"
            <el-table-column label="已入库金额(元)"
                             prop="shippedAmount"
                             show-overflow-tooltip
                             :formatter="formattedNumber" />
            <el-table-column label="应付金额(元)"
                             prop="payableAmount"
            <el-table-column label="未入库金额(元)"
                             prop="unshippedAmount"
                             show-overflow-tooltip>
              <template #default="{ row, column }">
                <el-text type="danger">
                  {{ formattedNumber(row, column, row.payableAmount) }}
                  {{ formattedNumber(row, column, row.unshippedAmount) }}
                </el-text>
              </template>
            </el-table-column>
@@ -79,7 +79,7 @@
                    @pagination="sonPaginationSearch">
            <template #payableAmountSlot="{ row }">
              <el-text type="danger">
                {{ parseFloat(row.payableAmount).toFixed(2) }}
                {{ parseFloat(row.unshippedAmount).toFixed(2) }}
              </el-text>
            </template>
          </PIMTable>
@@ -145,18 +145,18 @@
      },
    },
    {
      label: "付款金额(元)",
      prop: "paymentAmount",
      label: "已入库金额(元)",
      prop: "shippedAmount",
      width: 200,
      formatData: params => {
        return params ? parseFloat(params).toFixed(2) : 0;
      },
    },
    {
      label: "应付金额(元)",
      label: "未入库金额(元)",
      dataType: "slot",
      width: 200,
      prop: "payableAmount",
      prop: "unshippedAmount",
      slot: "payableAmountSlot",
    },
  ]);
@@ -170,7 +170,7 @@
  const summarizeMainTable = param => {
    return proxy.summarizeTable(
      param,
      ["contractAmounts", "paymentAmount", "payableAmount"],
      ["contractAmounts", "shippedAmount", "unshippedAmount"],
      {
        ticketsNum: { noDecimal: true }, // 不保留小数
        futureTickets: { noDecimal: true }, // 不保留小数
@@ -181,20 +181,12 @@
  const summarizeMainTable1 = param => {
    let summarizeTable = proxy.summarizeTable(
      param,
      ["contractAmount", "invoiceAmount", "paymentAmount"],
      ["contractAmount", "shippedAmount", "unshippedAmount"],
      {
        ticketsNum: { noDecimal: true }, // 不保留小数
        futureTickets: { noDecimal: true }, // 不保留小数
      }
    );
    if (originalTableDataSon.value.length > 0) {
      summarizeTable[summarizeTable.length - 1] =
        originalTableDataSon.value[
          originalTableDataSon.value.length - 1
        ].payableAmount.toFixed(2);
    } else {
      summarizeTable[summarizeTable.length - 1] = 0.0;
    }
    return summarizeTable;
  };
  /** 搜索按钮操作 */
src/views/productionManagement/productionTraceability/index.vue
@@ -175,7 +175,7 @@
              <template #default="{ row }">
                <el-button type="primary"
                           link
                           @click="showInput(row.id)">查看投入</el-button>
                           @click="showInput(row.productionProductMainId)">查看投入</el-button>
                <el-button type="primary"
                           link
                           @click="showParamDetail(row.productionOperationParamList)">参数详情</el-button>
src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -209,11 +209,11 @@
    const n = Number(fromApi);
    if (!Number.isNaN(n)) return n;
  }
  const quantity = Number(form.value.quantity);
  const qualified = Number(form.value.qualifiedQuantity);
  if (!quantity || Number.isNaN(quantity)) return null;
  const qualifiedNum = Number.isNaN(qualified) ? 0 : qualified;
  return (qualifiedNum / quantity) * 100;
  const qualified = Number(form.value.qualifiedQuantity) || 0;
  const unqualified = Number(form.value.unqualifiedQuantity) || 0;
  const total = qualified + unqualified;
  if (!total || total === 0) return null;
  return (qualified / total) * 100;
});
const passRateDisplayText = computed(() => {
@@ -296,8 +296,8 @@
  if (operationType.value === 'edit' || operationType.value === 'view') {
    // 先保存 testStandardId,避免被清空
    const savedTestStandardId = row.testStandardId;
    // 先设置表单数据,但暂时清空 testStandardId,等选项加载完成后再设置
    form.value = {...row, testStandardId: ''}
    const { passRate, ...rowWithoutPassRate } = row;
    form.value = { ...rowWithoutPassRate, testStandardId: '' };
    currentProductId.value = row.productId || 0
    // 清空验证状态,避免数据加载过程中的校验闪烁
    nextTick(() => {
src/views/qualityManagement/processInspection/components/formDia.vue
@@ -268,11 +268,11 @@
      const n = Number(fromApi);
      if (!Number.isNaN(n)) return n;
    }
    const quantity = Number(form.value.quantity);
    const qualified = Number(form.value.qualifiedQuantity);
    if (!quantity || Number.isNaN(quantity)) return null;
    const qualifiedNum = Number.isNaN(qualified) ? 0 : qualified;
    return (qualifiedNum / quantity) * 100;
    const qualified = Number(form.value.qualifiedQuantity) || 0;
    const unqualified = Number(form.value.unqualifiedQuantity) || 0;
    const total = qualified + unqualified;
    if (!total || total === 0) return null;
    return (qualified / total) * 100;
  });
  const passRateDisplayText = computed(() => {
@@ -367,8 +367,8 @@
    if (operationType.value === "edit" || operationType.value === "view") {
      // 先保存 testStandardId,避免被清空
      const savedTestStandardId = row.testStandardId;
      // 先设置表单数据,但暂时清空 testStandardId,等选项加载完成后再设置
      form.value = { ...row, testStandardId: "" };
      const { passRate, ...rowWithoutPassRate } = row;
      form.value = { ...rowWithoutPassRate, testStandardId: "" };
      currentProductId.value = row.productId || 0;
      // 关键:编辑时加载规格型号下拉选项,才能反显 productModelId
      if (currentProductId.value) {
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -249,11 +249,11 @@
    const n = Number(fromApi);
    if (!Number.isNaN(n)) return n;
  }
  const quantity = Number(form.value.quantity);
  const qualified = Number(form.value.qualifiedQuantity);
  if (!quantity || Number.isNaN(quantity)) return null;
  const qualifiedNum = Number.isNaN(qualified) ? 0 : qualified;
  return (qualifiedNum / quantity) * 100;
  const qualified = Number(form.value.qualifiedQuantity) || 0;
  const unqualified = Number(form.value.unqualifiedQuantity) || 0;
  const total = qualified + unqualified;
  if (!total || total === 0) return null;
  return (qualified / total) * 100;
});
const passRateDisplayText = computed(() => {
@@ -315,7 +315,8 @@
  if (operationType.value === 'edit' || operationType.value === 'view') {
    // 先保存 testStandardId,避免被清空
    const savedTestStandardId = row.testStandardId;
    form.value = {...row}
    const { passRate, ...rowWithoutPassRate } = row;
    form.value = { ...rowWithoutPassRate, testStandardId: "" };
    currentProductId.value = row.productId || 0
    // 关键:编辑时加载规格型号下拉选项,才能反显 productModelId
    if (currentProductId.value) {
src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -41,18 +41,18 @@
                             show-overflow-tooltip
                             :formatter="formattedNumber"
                             width="200" />
            <el-table-column label="回款金额(元)"
                             prop="receiptPaymentAmount"
            <el-table-column label="已出库金额(元)"
                             prop="shippedAmount"
                             show-overflow-tooltip
                             :formatter="formattedNumber"
                             width="200" />
            <el-table-column label="应收金额(元)"
                             prop="receiptableAmount"
            <el-table-column label="未出库金额(元)"
                             prop="unshippedAmount"
                             show-overflow-tooltip
                             width="200">
              <template #default="{ row, column }">
                <el-text type="danger">
                  {{ formattedNumber(row, column, row.receiptableAmount) }}
                  {{ formattedNumber(row, column, row.unshippedAmount) }}
                </el-text>
              </template>
            </el-table-column>
@@ -91,18 +91,18 @@
                             show-overflow-tooltip
                             :formatter="formattedNumber"
                             width="200" />
            <el-table-column label="回款金额(元)"
                             prop="receiptPaymentAmount"
            <el-table-column label="已出库金额(元)"
                             prop="shippedAmount"
                             show-overflow-tooltip
                             :formatter="formattedNumber"
                             width="200" />
            <el-table-column label="应收金额(元)"
                             prop="receiptableAmount"
            <el-table-column label="未出库金额(元)"
                             prop="unshippedAmount"
                             show-overflow-tooltip
                             width="200">
              <template #default="{ row, column }">
                <el-text type="danger">
                  {{ formattedNumber(row, column, row.receiptableAmount) }}
                  {{ formattedNumber(row, column, row.unshippedAmount) }}
                </el-text>
              </template>
            </el-table-column>
@@ -180,7 +180,7 @@
  const summarizeMainTable = param => {
    return proxy.summarizeTable(
      param,
      ["invoiceTotal", "receiptPaymentAmount", "unReceiptPaymentAmount"],
      ["contractAmounts", "shippedAmount", "unshippedAmount"],
      {
        ticketsNum: { noDecimal: true }, // 不保留小数
        futureTickets: { noDecimal: true }, // 不保留小数
@@ -191,7 +191,7 @@
  const summarizeMainTable1 = param => {
    var summarizeTable = proxy.summarizeTable(
      param,
      ["contractAmount", "receiptPaymentAmount", "receiptableAmount"],
      ["contractAmount", "shippedAmount", "unshippedAmount"],
      {
        ticketsNum: { noDecimal: true }, // 不保留小数
        futureTickets: { noDecimal: true }, // 不保留小数
src/views/systemArchitecture/index.vue
@@ -22,7 +22,7 @@
        <div class="flow-row flow-row--top">
          <template v-for="item in basicFlow" :key="item.key">
            <div class="flow-item">
              <article class="flow-node">
              <article class="flow-node" @click.stop="goPage(item.key)">
                <div class="flow-node__icon">
                  <svg-icon :icon-class="item.icon" />
                </div>
@@ -50,7 +50,7 @@
          <div class="flow-grid flow-grid--sale">
            <template v-for="(item, index) in saleFlow" :key="item.key">
              <div class="grid-cell">
                <article class="flow-node">
                <article class="flow-node" @click.stop="goPage(item.key)">
                  <div class="flow-node__icon" :class="{ 'flow-node__icon--accent': item.accent }">
                    <svg-icon :icon-class="item.icon" />
                  </div>
@@ -98,7 +98,7 @@
          <div class="flow-grid flow-grid--purchase">
            <template v-for="(item, index) in purchaseFlow" :key="item.key">
              <div class="grid-cell">
                <article class="flow-node">
                <article class="flow-node" @click.stop="goPage(item.key)">
                  <div class="flow-node__icon" :class="{ 'flow-node__icon--accent': item.accent }">
                    <svg-icon :icon-class="item.icon" />
                  </div>
@@ -134,7 +134,7 @@
        <div class="flow-row flow-row--wide">
          <template v-for="(item, index) in produceFlow" :key="item.key">
            <div class="flow-item">
              <article class="flow-node">
              <article class="flow-node" @click.stop="goPage(item.key)">
                <div class="flow-node__icon" :class="{ 'flow-node__icon--green': item.green, 'flow-node__icon--accent': item.accent }">
                  <svg-icon :icon-class="item.icon" />
                </div>
@@ -162,7 +162,7 @@
        <div class="flow-row flow-row--store">
          <template v-for="(item, index) in storeFlow" :key="item.key">
            <div class="flow-item">
              <article class="flow-node">
              <article class="flow-node" @click.stop="goPage(item.key)">
                <div class="flow-node__icon">
                  <svg-icon :icon-class="item.icon" />
                </div>
@@ -178,7 +178,47 @@
</template>
<script setup>
import { useRouter } from 'vue-router'
import aiHead from '@/assets/images/head.svg'
const router = useRouter()
const routeMap = {
  'basic-role': '/system/role',
  'basic-user': '/system/user',
  'basic-post': '/system/post',
  'basic-dept': '/system/dept',
  'basic-product': '/basicData/product',
  'basic-approval': '/collaborativeApproval/approvalManagement',
  'sale-customer': '/salesManagement/customerFile',
  'sale-quote': '/salesManagement/salesQuotation',
  'sale-ledger': '/salesManagement/salesLedger',
  'sale-delivery': '/salesManagement/deliveryLedger',
  'sale-return': '/salesManagement/returnOrder',
  'purchase-supplier': '/procurementManagement/supplierManage',
  'purchase-ledger': '/procurementManagement/procurementLedger',
  'purchase-return': '/procurementManagement/purchaseReturnOrder',
  'purchase-contact': '/procurementManagement/paymentLedger',
  'purchase-report': '/procurementManagement/procurementReport',
  'produce-process': '/processDesign/productionManagement/productionProcess/index',
  'produce-bom': '/processDesign/productionManagement/productStructure/index',
  'produce-route': '/processDesign/processRoute',
  'produce-order': '/productionManagement/productionOrder',
  'produce-schedule': '/productionManagement/productionManagement/workOrderEdit/index',
  'produce-work': '/productionManagement/workOrderManagement',
  'produce-ledger': '/productionManagement/productionReporting',
  'produce-cost': '/productionManagement/productionCosting',
  'store-in': '/inventoryManagement/receiptManagement',
  'store-out': '/inventoryManagement/dispatchLog',
  'store-stock': '/inventoryManagement/stockManagement'
}
function goPage(key) {
  const path = routeMap[key]
  if (path) {
    router.push(path)
  }
}
const basicFlow = [
  { key: 'basic-role', name: '角色管理', icon: 'user' },
@@ -412,6 +452,7 @@
  align-items: center;
  gap: 8px;
  text-align: center;
  cursor: pointer;
}
.flow-node__icon {