gaoluyang
2026-09-21 afb7ee6979f9172f023e418e6da9d4ecba7f3eb2
徐州-鼎业智能
1.生产订单页面当前工序进度与工序生产进度列展示修改
已修改3个文件
403 ■■■■■ 文件已修改
.gitignore 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
multiple/config.json 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -13,6 +13,7 @@
# Editor directories and files
.idea
.vscode
.claude
*.suo
*.ntvs*
*.njsproj
multiple/config.json
@@ -15,276 +15,6 @@
    "logo": "logo/Logo.png",
    "favicon": "favicon/favicon.ico"
  },
  "BTYX": {
    "env": {
      "VITE_APP_TITLE": "河南帮太优选食品有限公司",
      "VITE_BASE_API": "http://1.15.17.182:9056",
      "VITE_JAVA_API": "http://1.15.17.182:9057"
    },
    "logo": "logo/BTYXLogo.png",
    "favicon": "favicon/BTYXfavicon.ico"
  },
  "ZXZN": {
    "env": {
      "VITE_APP_TITLE": "河南智芯智能机器人有限公司",
      "VITE_BASE_API": "http://192.168.0.200:9001",
      "VITE_JAVA_API": "http://192.168.0.200:9000"
    },
    "logo": "logo/ZXZNLogo.png",
    "favicon": "favicon/ZXZNfavicon.ico"
  },
  "SDTX": {
    "env": {
      "VITE_APP_TITLE": "河南善鼎通信科技有限公司",
      "VITE_BASE_API": "http://36.213.156.184:9001",
      "VITE_JAVA_API": "http://36.213.156.184:9000"
    },
    "logo": "logo/SDTXLogo.png",
    "favicon": "favicon/SDTXfavicon.ico"
  },
  "ZQSY": {
    "env": {
      "VITE_APP_TITLE": "泽淇实业",
      "VITE_BASE_API": "http://36.213.128.159:9000",
      "VITE_JAVA_API": "http://36.213.128.159:9001"
    },
    "logo": "logo/ZQSYLogo.png",
    "favicon": "favicon/ZQSYfavicon.ico"
  },
  "JXJH": {
    "env": {
      "VITE_APP_TITLE": "浚县江海水泥制品有限公司",
      "VITE_BASE_API": "http://36.139.201.20:9000",
      "VITE_JAVA_API": "http://36.139.201.20:9001"
    },
    "logo": "logo/JXJHLogo.png",
    "favicon": "favicon/JXJHfavicon.ico"
  },
  "YTJZ": {
    "env": {
      "VITE_APP_TITLE": "豫泰建筑材料有限公司",
      "VITE_BASE_API": "http://36.139.201.181:9000",
      "VITE_JAVA_API": "http://36.139.201.181:9001"
    },
    "logo": "logo/YTJZLogo.png",
    "favicon": "favicon/YTJZfavicon.ico"
  },
  "HYLQ": {
    "env": {
      "VITE_APP_TITLE": "航逸路桥工程有限公司",
      "VITE_BASE_API": "http://36.139.202.111:9000",
      "VITE_JAVA_API": "http://36.139.202.111:9001"
    },
    "logo": "logo/HYLQLogo.png",
    "favicon": "favicon/HYLQfavicon.ico"
  },
  "QXY": {
    "env": {
      "VITE_APP_TITLE": "强信宇电器云主机",
      "VITE_BASE_API": "http://36.134.154.10:9000",
      "VITE_JAVA_API": "http://36.134.154.10:9001"
    },
    "logo": "logo/QXYLogo.png",
    "favicon": "favicon/QXYfavicon.ico"
  },
  "HYJC": {
    "env": {
      "VITE_APP_TITLE": "恒洋建材",
      "VITE_BASE_API": "http://36.138.94.178:9000",
      "VITE_JAVA_API": "http://36.138.94.178:9001"
    },
    "logo": "logo/HYJCLogo.png",
    "favicon": "favicon/HYJCfavicon.ico"
  },
  "JHY": {
    "env": {
      "VITE_APP_TITLE": "山西省榆社县晋和园食品有限公司",
      "VITE_BASE_API": "http://223.15.233.27:9001",
      "VITE_JAVA_API": "http://223.15.233.27:9002"
    },
    "logo": "logo/JHYLogo.png",
    "favicon": "favicon/JHYfavicon.ico"
  },
  "XCDQ": {
    "env": {
      "VITE_APP_TITLE": "旭晨电器管理系统",
      "VITE_BASE_API": "http://36.133.45.183:9001",
      "VITE_JAVA_API": "http://36.133.45.183:9002"
    },
    "logo": "logo/XCDQLogo.png",
    "favicon": "favicon/XCDQfavicon.ico"
  },
  "LMJN": {
    "env": {
      "VITE_APP_TITLE": "绿美节能管理系统",
      "VITE_BASE_API": "http://1.15.17.182:9105",
      "VITE_JAVA_API": "http://1.15.17.182:9106"
    },
    "logo": "logo/Logo.png",
    "favicon": "favicon/favicon.ico"
  },
  "XSWH": {
    "env": {
      "VITE_APP_TITLE": "兴盛旺海管理系统",
      "VITE_BASE_API": "http://36.138.177.225:9001",
      "VITE_JAVA_API": "http://36.138.177.225:9002"
    },
    "logo": "logo/XSWHLogo.png",
    "favicon": "favicon/XSWHfavicon.ico"
  },
  "TDDQ": {
    "env": {
      "VITE_APP_TITLE": "河南同德电气有限公司",
      "VITE_BASE_API": "http://36.137.101.88:9001",
      "VITE_JAVA_API": "http://36.137.101.88:9002"
    },
    "logo": "logo/TDDQLogo.png",
    "favicon": "favicon/TDDQfavicon.ico"
  },
  "JHJM": {
    "env": {
      "VITE_APP_TITLE": "鹤壁市锦汇精密机械有限公司",
      "VITE_BASE_API": "http://103.189.141.42:9001",
      "VITE_JAVA_API": "http://103.189.141.42:9002"
    },
    "logo": "logo/JHJMLogo.png",
    "favicon": "favicon/JHJMfavicon.ico"
  },
  "DDGW": {
    "env": {
      "VITE_APP_TITLE": "河南东大高温节能材料有限公司",
      "VITE_BASE_API": "http://36.133.40.190:81",
      "VITE_JAVA_API": "http://36.133.40.190:82"
    },
    "logo": "logo/DDGWLogo.png",
    "favicon": "favicon/DDGWfavicon.ico"
  },
  "DDGW-TEST": {
    "env": {
      "VITE_APP_TITLE": "河南东大高温节能材料有限公司",
      "VITE_BASE_API": "http://36.133.40.190:83",
      "VITE_JAVA_API": "http://36.133.40.190:84"
    },
    "logo": "logo/DDGWLogo.png",
    "favicon": "favicon/DDGWfavicon.ico"
  },
  "XHZG": {
    "env": {
      "VITE_APP_TITLE": "鹤壁欣弘重工有限公司",
      "VITE_BASE_API": "http://103.189.141.42:9001",
      "VITE_JAVA_API": "http://103.189.141.42:9002"
    },
    "logo": "logo/XHZGLogo.png",
    "favicon": "favicon/XHZGfavicon.ico"
  },
  "SDKS": {
    "env": {
      "VITE_APP_TITLE": "鹤壁市四达矿山设备有限公司",
      "VITE_BASE_API": "http://36.213.180.217:9520",
      "VITE_JAVA_API": "http://36.213.180.217:9521"
    },
    "logo": "logo/SDKSLogo.png",
    "favicon": "favicon/SDKSfavicon.ico"
  },
  "JMTM": {
    "env": {
      "VITE_APP_TITLE": "河南捷美特镁科技有限公司",
      "VITE_BASE_API": "http://36.133.40.61:81",
      "VITE_JAVA_API": "http://36.133.40.61:82"
    },
    "logo": "logo/JMTMLogo.png",
    "favicon": "favicon/JMTMfavicon.ico"
  },
  "CHMY": {
    "env": {
      "VITE_APP_TITLE": "鹤壁昌宏镁业有限公司",
      "VITE_BASE_API": "http://36.133.39.224:81",
      "VITE_JAVA_API": "http://36.133.39.224:82"
    },
    "logo": "logo/CHMYLogo.png",
    "favicon": "favicon/CHMYfavicon.ico"
  },
  "SJDQ": {
    "env": {
      "VITE_APP_TITLE": "鹤壁市山城区盛久电器有限公司",
      "VITE_BASE_API": "http://36.139.201.235:81",
      "VITE_JAVA_API": "http://36.139.201.235:82"
    },
    "logo": "logo/SJDQLogo.png",
    "favicon": "favicon/SJDQfavicon.ico"
  },
  "TXDQ": {
    "env": {
      "VITE_APP_TITLE": "鹤壁泰信电气有限公司",
      "VITE_BASE_API": "http://36.133.46.171:81",
      "VITE_JAVA_API": "http://36.133.46.171:82"
    },
    "logo": "logo/TXDQLogo.png",
    "favicon": "favicon/TXDQfavicon.ico"
  },
  "SMDQ": {
    "env": {
      "VITE_APP_TITLE": "鹤壁市晟铭电器有限公司",
      "VITE_BASE_API": "http://36.137.102.125:81",
      "VITE_JAVA_API": "http://36.137.102.125:82"
    },
    "logo": "logo/SMDQLogo.png",
    "favicon": "favicon/SMDQfavicon.ico"
  },
  "BCKJ": {
    "env": {
      "VITE_APP_TITLE": "河南冰驰科技有限公司",
      "VITE_BASE_API": "http://36.133.209.54:81",
      "VITE_JAVA_API": "http://36.133.209.54:82"
    },
    "logo": "logo/BCKJLogo.png",
    "favicon": "favicon/BCKJfavicon.ico"
  },
  "HMCL": {
    "env": {
      "VITE_APP_TITLE": "鹤壁浩镁材料有限公司",
      "VITE_BASE_API": "http://36.213.90.123:9522",
      "VITE_JAVA_API": "http://36.213.90.123:9523"
    },
    "logo": "logo/HMCLLogo.png",
    "favicon": "favicon/HMCLfavicon.ico"
  },
  "DTZG": {
    "env": {
      "VITE_APP_TITLE": "徐州东特重工科技有限公司",
      "VITE_BASE_API": "http://36.213.90.123:9510",
      "VITE_JAVA_API": "http://36.213.90.123:9511"
    },
    "logo": "logo/DTZGLogo.png",
    "favicon": "favicon/DTZGfavicon.ico"
  },
  "XLZN": {
    "env": {
      "VITE_APP_TITLE": "江苏旭龙智能科技有限公司",
      "VITE_BASE_API": "http://36.213.90.123:9512",
      "VITE_JAVA_API": "http://36.213.90.123:9513"
    },
    "logo": "logo/XLZNLogo.png",
    "favicon": "favicon/XLZNfavicon.ico"
  },
  "SKJS": {
    "env": {
      "VITE_APP_TITLE": "徐州什克金属制品有限公司",
      "VITE_BASE_API": "http://36.213.90.123:9514",
      "VITE_JAVA_API": "http://36.213.90.123:9515"
    },
    "logo": "logo/SKJSLogo.png",
    "favicon": "favicon/SKJSFavicon.ico"
  },
  "YJYY": {
    "env": {
      "VITE_APP_TITLE": "徐州永佳液压设备有限公司",
      "VITE_BASE_API": "http://36.213.90.123:9516",
      "VITE_JAVA_API": "http://36.213.90.123:9517"
    },
    "logo": "logo/YJYYLogo.png",
    "favicon": "favicon/YJYYFavicon.ico"
  },
  "DYZN": {
    "env": {
      "VITE_APP_TITLE": "鼎业智能科技(江苏)有限公司",
src/views/productionManagement/productionOrder/index.vue
@@ -89,18 +89,21 @@
                       :status="toProgressPercentage(row?.completionStatus) >= 100 ? 'success' : ''" />
        </template>
        <template #currentProcess="{ row }">
          <template v-if="getCurrentProcess(row)">
            <el-tag v-if="getCurrentProcess(row).done"
                    type="success"
                    size="small">全部完成</el-tag>
            <div v-else
                 class="current-process-name"
                 :title="`${getCurrentProcess(row).name} · ${getCurrentProcess(row).pct}%`">
              <span class="process-color-dot"
                    :style="{ background: getCurrentProcess(row).color || '#909399' }"></span>
              <span :style="readableTextColor(getCurrentProcess(row).color) ? { color: readableTextColor(getCurrentProcess(row).color) } : {}">{{ getCurrentProcess(row).name }}</span>
          <div v-if="currentProcessStage(row)"
               class="process-progress-container">
            <div class="process-step">
              <div class="step-content">
                <div class="step-boxes"
                     :title="`${currentProcessStage(row).name} ${currentProcessStage(row).percentage}%`">
                  <div v-for="(color, i) in currentProcessStage(row).boxes"
                       :key="i"
                       class="step-box"
                       :style="{ background: color }"></div>
            </div>
          </template>
                <div class="step-name">{{ currentProcessStage(row).name }}</div>
              </div>
            </div>
          </div>
          <span v-else>-</span>
        </template>
        <template #processRouteStatus="{ row }">
@@ -110,14 +113,18 @@
                 :key="index"
                 class="process-step">
              <div class="step-content">
                <div class="step-circle"
                     :title="`${item.name} ${item.percentage}%`"
                     :style="{ background: item.color || '#409EFF', opacity: item.percentage >= 100 ? 1 : item.percentage > 0 ? 0.6 : 0.25 }"></div>
                <div class="step-boxes"
                     :title="`${item.name} ${item.percentage}%`">
                  <div v-for="(color, i) in processStateBoxes(row.processRouteStatus, index)"
                       :key="i"
                       class="step-box"
                       :style="{ background: color }"></div>
                </div>
                <div class="step-name">{{ item.name }}</div>
              </div>
              <div v-if="index < row.processRouteStatus.length - 1"
                   class="step-line"
                   :style="{ background: item.percentage >= 100 ? '#67c23a' : '#dcdfe6' }"></div>
                   :style="{ background: processLineColor(item.percentage) }"></div>
            </div>
          </div>
          <span v-else>-</span>
@@ -314,7 +321,7 @@
      dataType: "slot",
      slot: "currentProcess",
      align: "center",
      width: 160,
      width: PROCESS_STEP_WIDTH,
    },
    {
      label: "销售单号",
@@ -544,40 +551,42 @@
    return "#67c23a";
  };
  // hex 色转 rgba(用于光晕/淡底),非 hex 返回空串
  const hexToRgba = (hex, alpha) => {
    if (typeof hex !== "string") return "";
    const m = hex.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
    if (!m) return "";
    let n = m[1];
    if (n.length === 3) n = n.split("").map(c => c + c).join("");
    const v = parseInt(n, 16);
    return `rgba(${(v >> 16) & 255}, ${(v >> 8) & 255}, ${v & 255}, ${alpha})`;
  // 工序/阶段三态配色:已完成绿、进行中蓝、未开始灰
  const STAGE_DONE_COLOR = "#67c23a";
  const STAGE_DOING_COLOR = "#409eff";
  const STAGE_IDLE_COLOR = "#dcdfe6";
  // 每道工序一个三态框组:待开始 / 生产中 / 生产完成。
  // 0% 时亮「待开始」,开工未完工时「待开始」转绿、「生产中」亮蓝,完工后三个框全绿;
  // 前一道工序没完工,后面的工序三个框全灰(上一步不完成下一步不亮)
  const processStateBoxes = (list, index) => {
    const pct = toProgressPercentage(list?.[index]?.percentage);
    if (pct >= 100) return [STAGE_DONE_COLOR, STAGE_DONE_COLOR, STAGE_DONE_COLOR];
    const currentIndex = (list || []).findIndex(
      item => toProgressPercentage(item.percentage) < 100
    );
    if (index > currentIndex) return [STAGE_IDLE_COLOR, STAGE_IDLE_COLOR, STAGE_IDLE_COLOR];
    return pct > 0
      ? [STAGE_DONE_COLOR, STAGE_DOING_COLOR, STAGE_IDLE_COLOR]
      : [STAGE_DOING_COLOR, STAGE_IDLE_COLOR, STAGE_IDLE_COLOR];
  };
  // 过浅的工序色在白底上文字不可读,回退常规文字色
  const isLightColor = hex => {
    const rgba = hexToRgba(hex, 1);
    if (!rgba) return false;
    const [r, g, b] = rgba.match(/\d+/g).map(Number);
    return (0.299 * r + 0.587 * g + 0.114 * b) / 255 > 0.72;
  };
  const readableTextColor = color =>
    !color || isLightColor(color) ? "" : color;
  // 当前工序:第一道完成度不足100%的工序;全部完成返回 done
  const getCurrentProcess = row => {
    const list = row.processRouteStatus;
  // 当前工序:第一道未完工的工序,只给它一组三态框;全部完工时落在最后一道工序上
  const currentProcessStage = row => {
    const list = row?.processRouteStatus;
    if (!Array.isArray(list) || list.length === 0) return null;
    const current = list.find(item => toProgressPercentage(item.percentage) < 100);
    if (!current) return { done: true };
    let index = list.findIndex(item => toProgressPercentage(item.percentage) < 100);
    if (index === -1) index = list.length - 1;
    return {
      done: false,
      name: current.name || "未知工序",
      color: current.color || "",
      pct: toProgressPercentage(current.percentage),
      name: list[index].name || "未知工序",
      percentage: toProgressPercentage(list[index].percentage),
      boxes: processStateBoxes(list, index),
    };
  };
  // 工序之间的连线:前一道完工才点亮
  const processLineColor = val =>
    toProgressPercentage(val) >= 100 ? STAGE_DONE_COLOR : STAGE_IDLE_COLOR;
  // 交期预警的文字提示(颜色之外的无障碍冗余指示)
  const deliveryHint = row => {
@@ -949,22 +958,6 @@
    margin-top: unset;
  }
  .current-process-name {
    display: inline-flex;
    flex-direction: column;
    align-items: stretch; // 色条宽度由文字撑开,两者等宽
    padding: 4px 0;
    font-size: 14px;
    color: #303133;
    .process-color-dot {
      display: block;
      height: 16px;
      border-radius: 4px;
      margin-bottom: 6px;
    }
  }
  .process-progress-container {
    display: inline-flex;
    align-items: center;
@@ -984,12 +977,17 @@
        flex-shrink: 0;
        z-index: 1;
        .step-circle {
          width: 36px;
          height: 36px;
          border-radius: 50%;
        .step-boxes {
          display: flex;
          gap: 4px;
          margin-bottom: 6px;
        }
        .step-box {
          width: 20px;
          height: 20px;
          border-radius: 4px;
          box-sizing: border-box;
          margin-bottom: 4px;
        }
        .step-name {
@@ -1004,12 +1002,12 @@
      }
      .step-line {
        width: 130px; // 贯穿相邻两圆心,两端被圆圈(z-index更高)遮挡
        width: 130px; // 贯穿相邻两组框,两端被框组(z-index更高)遮挡
        height: 2px;
        border-radius: 1px;
        background-color: #dcdfe6;
        flex-shrink: 0;
        margin: 17px -48px 0; // 线在34px槽位居中:(130-34)/2=48;顶边17px对准圆心
        margin: 9px -48px 0; // 线在34px槽位居中:(130-34)/2=48;顶边9px对准20px框组的垂直中心
      }
    }
  }