gaoluyang
6 小时以前 6ef3449ab07299b34f7ad1e6e4c3d3da4b3d2d1b
pro
1.bom样式添加半成品
已修改2个文件
55 ■■■■■ 文件已修改
src/views/productionManagement/productStructure/DetailNew/MaterialCard.vue 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/DetailNew/index.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/DetailNew/MaterialCard.vue
@@ -1,24 +1,31 @@
<template>
  <div class="material-node">
    <!-- 当前节点卡片 -->
    <div :class="['node-card', isRoot ? 'root-card' : 'child-card']">
    <div :class="['node-card', isRoot ? 'root-card' : (row.nodeType === 'semiFinished' ? 'semi-finished-card' : 'child-card')]">
      <div class="node-header">
        <div class="node-label">
          <el-tag :type="isRoot ? '' : 'success'" size="small" effect="dark">
            {{ isRoot ? '成品' : '原料' }}
          <el-tag :type="isRoot ? '' : (row.nodeType === 'semiFinished' ? 'warning' : 'success')" size="small" effect="dark">
            {{ isRoot ? '成品' : (row.nodeType === 'semiFinished' ? '半成品' : '原料') }}
          </el-tag>
          <span class="node-title">{{ row.productName || '未选择产品' }}</span>
          <span v-if="row.model" class="node-sub">规格: {{ row.model }}</span>
          <span v-if="row.unit" class="node-sub">单位: {{ row.unit }}</span>
        </div>
        <div class="node-actions">
          <el-button v-if="editable"
                     type="primary"
          <template v-if="editable && (isRoot || row.nodeType === 'semiFinished')">
            <el-button type="primary"
                     text
                     size="small"
                     @click="handleAdd">
            + 添加{{ isRoot ? '原料' : '子级原料' }}
                       @click="handleAdd('semiFinished')">
              + 添加半成品
          </el-button>
            <el-button type="primary"
                       text
                       size="small"
                       @click="handleAdd('rawMaterial')">
              + 添加原料
            </el-button>
          </template>
          <el-button v-if="editable"
                     type="danger"
                     text
@@ -107,7 +114,7 @@
        :editable="editable"
        :process-options="processOptions"
        @remove="(id:string) => $emit('remove', id)"
        @add="(id:string) => $emit('add', id)"
        @add="(id:string, nodeType:string) => $emit('add', id, nodeType)"
        @select-product="(tempId: string, data: any) => $emit('selectProduct', tempId, data)"
        @process-change="(row: any, v: any) => $emit('processChange', row, v)"
        @quantity-change="$emit('quantityChange')"
@@ -131,7 +138,7 @@
const emit = defineEmits<{
  remove: [tempId: string]
  add: [tempId: string]
  add: [tempId: string, nodeType: string]
  selectProduct: [tempId: string, data: any]
  processChange: [row: any, value: any]
  quantityChange: []
@@ -143,8 +150,8 @@
  emit('selectProduct', props.row.tempId, null)
}
const handleAdd = () => {
  emit('add', props.row.tempId)
const handleAdd = (nodeType: string) => {
  emit('add', props.row.tempId, nodeType)
}
</script>
@@ -174,6 +181,11 @@
  background-color: #f0f9eb;
}
.semi-finished-card {
  border-left: 4px solid #e6a23c;
  background-color: #fdf6ec;
}
.node-header {
  display: flex;
  align-items: center;
src/views/productionManagement/productStructure/DetailNew/index.vue
@@ -31,6 +31,9 @@
                <el-tag type="" size="small" effect="dark">成品</el-tag>
                <span style="margin:0 4px">← 最上层(产出物)</span>
                <el-divider direction="vertical" />
                <el-tag type="warning" size="small" effect="dark">半成品</el-tag>
                <span style="margin:0 4px">(可继续展开)</span>
                <el-divider direction="vertical" />
                <span style="margin:0 4px">最下层(投入物)→</span>
                <el-tag type="success" size="small" effect="dark">原料</el-tag>
              </div>
@@ -47,7 +50,7 @@
                :editable="dataValue.isEdit"
                :process-options="dataValue.processOptions"
                @remove="(id: string) => removeItem(id)"
                @add="(id: string) => addChildItem(id)"
                @add="(id: string, nodeType: string) => addChildItem(id, nodeType)"
                @select-product="(tempId: string, _data: any) => { dataValue.currentRowName = tempId; dataValue.showProductDialog = true }"
                @process-change="(row: any, v: any) => handleProcessChange(row, v)"
                @quantity-change="handleUnitQuantityChange"
@@ -183,12 +186,17 @@
    item.operationName = processName;
  };
  const normalizeTreeData = (items: any[]) => {
  const normalizeTreeData = (items: any[], depth: number = 0) => {
    items.forEach((item: any) => {
      item.tempId = item.tempId || item.id || `${Date.now()}_${Math.random()}`;
      syncProcessOperationFields(item);
      if (depth > 0 && !item.nodeType) {
        item.nodeType = Array.isArray(item.children) && item.children.length > 0
          ? 'semiFinished'
          : 'rawMaterial';
      }
      if (Array.isArray(item.children) && item.children.length > 0) {
        normalizeTreeData(item.children);
        normalizeTreeData(item.children, depth + 1);
      }
    });
  };
@@ -520,7 +528,7 @@
    });
  };
  const newChildNode = (parentItem: any) => ({
  const newChildNode = (parentItem: any, nodeType: string = 'rawMaterial') => ({
    parentId: parentItem.id || "",
    parentTempId: parentItem.tempId || "",
    productName: "",
@@ -534,6 +542,7 @@
    unitQuantity: 1,
    demandedQuantity: 0,
    unit: "",
    nodeType,
    children: [],
    tempId: new Date().getTime(),
  });
@@ -542,12 +551,12 @@
    dataValue.dataList.push(newChildNode({ id: "", tempId: "" }));
  };
  const addChildItem = (parentTempId: string) => {
  const addChildItem = (parentTempId: string, nodeType: string = 'rawMaterial') => {
    const addToItem = (items: any[]): boolean => {
      for (const item of items) {
        if (item.tempId === parentTempId) {
          if (!item.children) item.children = [];
          item.children.push(newChildNode(item));
          item.children.push(newChildNode(item, nodeType));
          recalculateDemandedQuantities();
          return true;
        }