已添加2个文件
已修改3个文件
816 ■■■■ 文件已修改
src/api/productionManagement/productWorkOrderFile.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/ProductSelectDialog.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/Detail/index.vue 568 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrder/components/filesDia.vue 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrder/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/productionManagement/productWorkOrderFile.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
import request from "@/utils/request";
// æŸ¥è¯¢å·¥å•附件列表
export function productWorkOrderFileListPage(query) {
  return request({
    url: "/productWorkOrderFile/listPage",
    method: "get",
    params: query,
  });
}
// æ–°å¢žå·¥å•附件
export function productWorkOrderFileAdd(data) {
  return request({
    url: "/productWorkOrderFile/add",
    method: "post",
    data,
  });
}
// åˆ é™¤å·¥å•附件
export function productWorkOrderFileDel(data) {
  return request({
    url: "/productWorkOrderFile/del",
    method: "delete",
    data,
  });
}
src/views/basicData/product/ProductSelectDialog.vue
@@ -43,7 +43,7 @@
        @select="handleSelect"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column type="index" label="#" width="60"/>
      <el-table-column type="index" label="序号" width="60"/>
      <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"/>
@@ -185,7 +185,7 @@
  loading.value = true;
  try {
    multipleSelection.value = []; // ç¿»é¡µ/搜索后清空选择更符合预期
    const res = await productModelList({
    const res:any = await productModelList({
      productName: query.productName.trim(),
      model: query.model.trim(),
      current: page.pageNum,
src/views/productionManagement/productStructure/Detail/index.vue
@@ -2,10 +2,6 @@
  <div class="app-container">
    <PageHeader content="产品结构详情">
      <template #right-button>
        <el-button v-if="dataValue.isEdit && !isOrderPage"
                   type="primary"
                   @click="addItem">添加
        </el-button>
        <el-button v-if="!dataValue.isEdit && !isOrderPage"
                   type="primary"
                   @click="dataValue.isEdit = true">编辑
@@ -22,34 +18,34 @@
        </el-button>
      </template>
    </PageHeader>
    <el-table
        :data="tableData"
        border
        :preserve-expanded-content="false"
        :default-expand-all="true"
        style="width: 100%"
    >
    <el-table :data="tableData"
              border
              :preserve-expanded-content="false"
              :default-expand-all="true"
              style="width: 100%">
      <el-table-column type="expand">
        <template #default="props">
          <el-form ref="form"
                   :model="dataValue">
            <el-table :data="dataValue.dataList"
                      row-key="tempId"
                      default-expand-all
                      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
                      style="width: 100%">
              <el-table-column prop="productName"
                               label="产品"/>
                               label="产品" />
              <el-table-column prop="model"
                               label="规格">
                <template #default="{ row, $index }">
                  <el-form-item v-if="dataValue.isEdit"
                                :prop="`dataList.${$index}.model`"
                                :rules="[{ required: true, message: '请选择规格', trigger: ['blur','change'] }]"
                                style="margin: 0">
                    <el-select v-model="row.model"
                               placeholder="请选择规格"
                               clearable
                               :disabled="!dataValue.isEdit"
                               :disabled="!dataValue.isEdit || dataValue.dataList.some(item => (item as any).tempId === row.tempId)"
                               style="width: 100%"
                               @visible-change="(v) => { if (v) openDialog($index) }">
                               @visible-change="(v) => { if (v) openDialog(row.tempId) }">
                      <el-option v-if="row.model"
                                 :label="row.model"
                                 :value="row.model" />
@@ -57,18 +53,18 @@
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column prop="processId"
              <el-table-column prop="processName"
                               label="消耗工序">
                <template #default="{ row, $index }">
                  <el-form-item :prop="`dataList.${$index}.processId`"
                                :rules="[{ required: true, message: '请选择消耗工序', trigger: 'change' }]"
                  <el-form-item v-if="dataValue.isEdit"
                                :rules="dataValue.dataList.some(item => (item as any).tempId === row.tempId) ? [] : [{ required: true, message: '请选择消耗工序', trigger: 'change' }]"
                                style="margin: 0">
                    <el-select v-model="row.processId"
                               placeholder="请选择"
                               filterable
                               clearable
                               style="width: 100%"
                               :disabled="!dataValue.isEdit">
                               :disabled="!dataValue.isEdit || dataValue.dataList.some(item => (item as any).tempId === row.tempId)">
                      <el-option v-for="item in dataValue.processOptions"
                                 :key="item.id"
                                 :label="item.name"
@@ -80,7 +76,7 @@
              <el-table-column prop="unitQuantity"
                               label="单位产出所需数量">
                <template #default="{ row, $index }">
                  <el-form-item :prop="`dataList.${$index}.unitQuantity`"
                  <el-form-item v-if="dataValue.isEdit"
                                :rules="[{ required: true, message: '请输入单位产出所需数量', trigger: ['blur','change'] }]"
                                style="margin: 0">
                    <el-input-number v-model="row.unitQuantity"
@@ -89,7 +85,7 @@
                                     :step="1"
                                     controls-position="right"
                                     style="width: 100%"
                                     :disabled="!dataValue.isEdit" />
                                     :disabled="!dataValue.isEdit || dataValue.dataList.some(item => (item as any).tempId === row.tempId)" />
                  </el-form-item>
                </template>
              </el-table-column>
@@ -97,7 +93,7 @@
                               prop="demandedQuantity"
                               label="需求总量">
                <template #default="{ row, $index }">
                  <el-form-item :prop="`dataList.${$index}.demandedQuantity`"
                  <el-form-item v-if="dataValue.isEdit"
                                :rules="[{ required: true, message: '请输入需求总量', trigger: ['blur','change'] }]"
                                style="margin: 0">
                    <el-input-number v-model="row.demandedQuantity"
@@ -106,29 +102,36 @@
                                     :step="1"
                                     controls-position="right"
                                     style="width: 100%"
                                     :disabled="!dataValue.isEdit" />
                                     :disabled="!dataValue.isEdit || dataValue.dataList.some(item => (item as any).tempId === row.tempId)" />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column prop="unit"
                               label="单位">
                <template #default="{ row, $index }">
                  <el-form-item :prop="`dataList.${$index}.unit`"
                  <el-form-item v-if="dataValue.isEdit"
                                :rules="[{ required: true, message: '请输入单位', trigger: ['blur','change'] }]"
                                style="margin: 0">
                    <el-input v-model="row.unit"
                              placeholder="请输入单位"
                              clearable
                              :disabled="!dataValue.isEdit" />
                               :disabled="!dataValue.isEdit || dataValue.dataList.some(item => (item as any).tempId === row.tempId)" />
                  </el-form-item>
                </template>
              </el-table-column>
              <el-table-column label="操作" fixed="right" width="100">
              <el-table-column label="操作"
                               fixed="right"
                               width="200">
                <template #default="{ row, $index }">
                  <el-button v-if="dataValue.isEdit"
                  <el-button v-if="dataValue.isEdit && !dataValue.dataList.some(item => (item as any).tempId === row.tempId)"
                             type="danger"
                             text
                             @click="dataValue.dataList.splice($index, 1)">删除
                             @click="removeItem(row.tempId)">删除
                  </el-button>
                  <el-button v-if="dataValue.isEdit"
                             type="primary"
                             text
                             @click="addItem2(row.tempId)">添加
                  </el-button>
                </template>
              </el-table-column>
@@ -136,11 +139,13 @@
          </el-form>
        </template>
      </el-table-column>
      <el-table-column label="BOM编号" prop="bomNo" />
      <el-table-column label="产品名称" prop="productName" />
      <el-table-column label="规格型号" prop="model" />
      <el-table-column label="BOM编号"
                       prop="bomNo" />
      <el-table-column label="产品名称"
                       prop="productName" />
      <el-table-column label="规格型号"
                       prop="model" />
    </el-table>
    <product-select-dialog v-if="dataValue.showProductDialog"
                           v-model:model-value="dataValue.showProductDialog"
                           @confirm="handleProduct" />
@@ -148,153 +153,364 @@
</template>
<script setup lang="ts">
import {
  computed,
  defineAsyncComponent,
  defineComponent,
  onMounted,
  reactive,
  ref,
} from "vue";
import { queryList, add } from "@/api/productionManagement/productStructure.js";
import { listProcessBom } from "@/api/productionManagement/productionOrder.js";
import { list } from "@/api/productionManagement/productionProcess";
import { ElMessage } from "element-plus";
import {useRoute, useRouter} from "vue-router";
  import {
    computed,
    defineAsyncComponent,
    defineComponent,
    onMounted,
    reactive,
    ref,
  } from "vue";
  import { queryList, add } from "@/api/productionManagement/productStructure.js";
  import { listProcessBom } from "@/api/productionManagement/productionOrder.js";
  import { list } from "@/api/productionManagement/productionProcess";
  import { ElMessage } from "element-plus";
  import { useRoute, useRouter } from "vue-router";
defineComponent({
  name: "StructureEdit",
});
const ProductSelectDialog = defineAsyncComponent(
    () => import("@/views/basicData/product/ProductSelectDialog.vue")
);
const form = ref();
const route = useRoute()
const router = useRouter()
const routeId = computed({
  get() {
    return route.query.id;
  },
  set(val) {
    emit('update:router', val)
  }
});
// ä»Žè·¯ç”±å‚数获取产品信息
const routeBomNo = computed(() => route.query.bomNo || '');
const routeProductName = computed(() => route.query.productName || '');
const routeProductModelName = computed(() => route.query.productModelName || '');
const routeOrderId = computed(() => route.query.orderId);
const pageType = computed(() => route.query.type);
const isOrderPage = computed(() => pageType.value === 'order' && routeOrderId.value);
const dataValue = reactive({
  dataList: [],
  productOptions: [],
  processOptions: [],
  showProductDialog: false,
  currentRowIndex: null,
  loading: false,
  isEdit: false,
});
const tableData = reactive([
  {
    productName: "",
    model: "",
    bomNo: "",
  }
])
const openDialog = index => {
  dataValue.currentRowIndex = index;
  dataValue.showProductDialog = true;
};
const fetchData = async () => {
  if (isOrderPage.value) {
    // è®¢å•情况:使用订单的产品结构接口
    const { data } = await listProcessBom({ orderId: routeOrderId.value });
    dataValue.dataList = data || [];
  } else {
    // éžè®¢å•情况:使用原来的接口
    const { data } = await queryList(routeId.value);
    dataValue.dataList = data || [];
  }
};
const fetchProcessOptions = async () => {
  const { data } = await list(routeId.value);
  dataValue.processOptions = data;
};
const handleProduct = row => {
  if (row?.length > 1) {
    ElMessage.error("只能选择一个产品");
  }
  dataValue.dataList[dataValue.currentRowIndex].productName =
      row[0].productName;
  dataValue.dataList[dataValue.currentRowIndex].model = row[0].model;
  dataValue.dataList[dataValue.currentRowIndex].productModelId = row[0].id;
  dataValue.dataList[dataValue.currentRowIndex].unit = row[0].unit || "";
  dataValue.showProductDialog = false;
};
const submit = () => {
  form.value
      .validate(valid => {
        dataValue.loading = true;
        if (valid) {
          add({
            bomId: routeId.value,
            productStructureList: dataValue.dataList || [],
          }).then(res => {
            router.push({
              path: '/productionManagement/productionManagement/productStructure/index',
            })
            ElMessage.success("保存成功");
            dataValue.loading = false;
          });
        }
      })
      .finally(() => {
        dataValue.loading = false;
      });
};
const addItem = () => {
  dataValue.dataList.push({
    productName: "",
    productId: "",
    model: undefined,
    productModelId: undefined,
    processId: "",
    unitQuantity: 0,
    demandedQuantity: 0,
    unit: "",
  defineComponent({
    name: "StructureEdit",
  });
};
const cancelEdit = () => {
  dataValue.isEdit = false;
  dataValue.dataList = dataValue.dataList.filter(item => item.id !== undefined);
};
  const ProductSelectDialog = defineAsyncComponent(
    () => import("@/views/basicData/product/ProductSelectDialog.vue")
  );
  const emit = defineEmits(["update:router"]);
  const form = ref();
onMounted(() => {
  // ä»Žè·¯ç”±å‚数回显数据
  tableData[0].productName = routeProductName.value;
  tableData[0].model = routeProductModelName.value;
  tableData[0].bomNo = routeBomNo.value;
  // è®¢å•情况下禁用编辑
  if (isOrderPage.value) {
  const route = useRoute();
  const router = useRouter();
  const routeId = computed({
    get() {
      return route.query.id;
    },
    set(val) {
      emit("update:router", val);
    },
  });
  // ä»Žè·¯ç”±å‚数获取产品信息
  const routeBomNo = computed(() => route.query.bomNo || "");
  const routeProductName = computed(() => route.query.productName || "");
  const routeProductModelName = computed(
    () => route.query.productModelName || ""
  );
  const routeOrderId = computed(() => route.query.orderId);
  const pageType = computed(() => route.query.type);
  const isOrderPage = computed(
    () => pageType.value === "order" && routeOrderId.value
  );
  const dataValue = reactive({
    dataList: [],
    productOptions: [],
    processOptions: [],
    showProductDialog: false,
    currentRowIndex: null,
    currentRowName: null,
    loading: false,
    isEdit: false,
  });
  const tableData = reactive([
    {
      productName: "",
      model: "",
      bomNo: "",
    },
  ]);
  const openDialog = (tempId: any) => {
    console.log(tempId, "tempId");
    dataValue.currentRowName = tempId;
    dataValue.showProductDialog = true;
  };
  const fetchData = async () => {
    if (isOrderPage.value) {
      // è®¢å•情况:使用订单的产品结构接口
      const { data } = await listProcessBom({ orderId: routeOrderId.value });
      dataValue.dataList = (data as any) || [];
    } else {
      // éžè®¢å•情况:使用原来的接口
      const { data } = await queryList(routeId.value);
      dataValue.dataList = (data as any) || [];
      // ä¸ºæ‰€æœ‰é¡¹åŠå…¶å­é¡¹è®¾ç½®name属性
      const setNameRecursively = (items: any[]) => {
        items.forEach((item: any) => {
          item.tempId = item.id;
          item.processName =
            dataValue.processOptions.find(option => option.id === item.processId)
              ?.name || "";
          if (item.children && item.children.length > 0) {
            setNameRecursively(item.children);
          }
        });
      };
      setNameRecursively(dataValue.dataList);
      console.log(dataValue.dataList, "dataValue.dataList");
    }
  };
  const fetchProcessOptions = async () => {
    const { data } = await list();
    dataValue.processOptions = data as any;
  };
  const handleProduct = (row: any) => {
    if (row?.length > 1) {
      ElMessage.error("只能选择一个产品");
    }
    const productData = row[0];
    //  æœ€å¤–层组件中,与当前产品相同的产品只能有一个
    const isTopLevel = dataValue.dataList.some(item => (item as any).tempId === dataValue.currentRowName);
    if (isTopLevel) {
      if (productData.productName === tableData[0].productName &&
        productData.model === tableData[0].model) {
        //  æŸ¥æ‰¾æ˜¯å¦å·²ç»æœ‰å…¶ä»–顶层行已经是这个产品
        const hasOther = dataValue.dataList.some(item =>
          (item as any).tempId !== dataValue.currentRowName &&
          (item as any).productName === tableData[0].productName &&
          (item as any).model === tableData[0].model
        );
        if (hasOther) {
          ElMessage.warning("最外层和当前产品一样的一级只能有一个");
          return;
        }
      }
    }
    // dataValue.dataList[dataValue.currentRowIndex].productName =
    //   row[0].productName;
    // dataValue.dataList[dataValue.currentRowIndex].model = row[0].model;
    // dataValue.dataList[dataValue.currentRowIndex].productModelId = row[0].id;
    // dataValue.dataList[dataValue.currentRowIndex].unit = row[0].unit || "";
    dataValue.dataList.map(item => {
      if (item.tempId === dataValue.currentRowName) {
        item.productName = productData.productName;
        item.model = productData.model;
        item.productModelId = productData.id;
        item.unit = productData.unit || "";
        return;
      }
      childItem(item, dataValue.currentRowName, productData);
    });
    dataValue.showProductDialog = false;
  };
  const childItem = (item: any, tempId: any, productData: any) => {
    if (item.tempId === tempId) {
      item.productName = productData.productName;
      item.model = productData.model;
      item.productModelId = productData.id;
      item.unit = productData.unit || "";
      return true;
    }
    if (item.children && item.children.length > 0) {
      for (let child of item.children) {
        if (childItem(child, tempId, productData)) {
          return true;
        }
      }
    }
    return false;
  };
  // é€’归校验所有层级的表单数据
  const validateAll = () => {
    let isValid = true;
    // æ ¡éªŒå‡½æ•°
    const validateItem = (item: any, isTopLevel = false) => {
      // æ ¡éªŒå½“前项的必填字段
      if (!item.model) {
        ElMessage.error("请选择规格");
        isValid = false;
        return;
      }
      if (!isTopLevel && !item.processId) {
        ElMessage.error("请选择消耗工序");
        isValid = false;
        return;
      }
      if (!item.unitQuantity) {
        ElMessage.error("请输入单位产出所需数量");
        isValid = false;
        return;
      }
      if (isOrderPage.value && !item.demandedQuantity) {
        ElMessage.error("请输入需求总量");
        isValid = false;
        return;
      }
      // if (!item.unit) {
      //   ElMessage.error("请输入单位");
      //   isValid = false;
      //   return;
      // }
      // é€’归校验子项
      if (item.children && item.children.length > 0) {
        item.children.forEach(child => {
          validateItem(child, false);
        });
      }
    };
    // éåŽ†æ‰€æœ‰é¡¶å±‚é¡¹
    dataValue.dataList.forEach(item => {
      validateItem(item, true);
    });
    return isValid;
  };
  const submit = () => {
    dataValue.loading = true;
    // å…ˆè¿›è¡Œè¡¨å•校验
    const valid = validateAll();
    console.log(dataValue.dataList, "dataValue.dataList");
    if (valid) {
      add({
        bomId: routeId.value,
        children: dataValue.dataList || [],
      })
        .then(res => {
          router.push({
            path: "/productionManagement/productionManagement/productStructure/index",
          });
          ElMessage.success("保存成功");
          dataValue.loading = false;
        })
        .catch(() => {
          dataValue.loading = false;
        });
    } else {
      dataValue.loading = false;
    }
  };
  const removeItem = (tempId:string) => {
    // å…ˆå°è¯•从顶层删除
    const topIndex = dataValue.dataList.findIndex(item => item.tempId === tempId);
    if (topIndex !== -1) {
      dataValue.dataList.splice(topIndex, 1);
      return;
    }
    // é€’归删除子项
    const delchildItem = (items: any[], tempId: any) => {
      for (let i = 0; i < items.length; i++) {
        const item = items[i];
        if (item.tempId === tempId) {
          items.splice(i, 1);
          return true;
        }
        if (item.children && item.children.length > 0) {
          if (delchildItem(item.children, tempId)) {
            return true;
          }
        }
      }
      return false;
    };
    dataValue.dataList.forEach(item => {
      if (item.children && item.children.length > 0) {
        delchildItem(item.children, tempId);
      }
    });
  };
  const addItem2 = tempId => {
    dataValue.dataList.map(item => {
      if (item.tempId === tempId) {
        if (!item.children) {
          item.children = [];
        }
        item.children.push({
          parentId: item.id || "",
          parentTempId: item.tempId || "",
          productName: "",
          productId: "",
          model: undefined,
          productModelId: undefined,
          processId: "",
          processName: "",
          unitQuantity: 0,
          demandedQuantity: 0,
          unit: "",
          children: [],
          tempId: new Date().getTime(),
        });
        return;
      }
      addchildItem(item, tempId);
    });
  };
  const addchildItem = (item: any, tempId: any) => {
    if (item.tempId === tempId) {
      console.log(item, "item");
      if (!item.children) {
        item.children = [];
      }
      item.children.push({
        parentId: item.id || "",
        parentTempId: item.tempId || "",
        productName: "",
        productId: "",
        model: undefined,
        productModelId: undefined,
        processId: "",
        unitQuantity: 0,
        demandedQuantity: 0,
        children: [],
        unit: "",
        tempId: new Date().getTime(),
      });
      return true;
    }
    if (item.children && item.children.length > 0) {
      for (let child of item.children) {
        if (addchildItem(child, tempId)) {
          return true;
        }
      }
    }
    return false;
  };
  const getPropPath = (row, field) => {
    // ä¸ºæ¯ä¸ªrow生成唯一的路径
    // ä½¿ç”¨row.id或索引作为唯一标识
    let path = "dataList";
    // ç®€å•实现:使用row的id或一个唯一标识
    const uniqueId = row.id || Math.floor(Math.random() * 10000);
    path += `.${uniqueId}`;
    return path + `.${field}`;
  };
  const cancelEdit = () => {
    dataValue.isEdit = false;
  }
  fetchData();
  fetchProcessOptions();
});
    // dataValue.dataList = dataValue.dataList.filter(item => item.id !== undefined);
    fetchData();
  };
  onMounted(async () => {
    // ä»Žè·¯ç”±å‚数回显数据
    tableData[0].productName = routeProductName.value as string;
    tableData[0].model = routeProductModelName.value as string;
    tableData[0].bomNo = routeBomNo.value as string;
    // è®¢å•情况下禁用编辑
    if (isOrderPage.value) {
      dataValue.isEdit = false;
    }
    // å…ˆåŠ è½½å·¥åºé€‰é¡¹ï¼Œå†åŠ è½½æ•°æ®ï¼Œç¡®ä¿el-select能够正确回显
    await fetchProcessOptions();
    await fetchData();
  });
</script>
src/views/productionManagement/workOrder/components/filesDia.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,202 @@
<template>
  <div>
    <el-dialog v-model="dialogVisible" title="工单附件" width="50%" @close="closeDia">
      <div style="margin-bottom: 10px; text-align: right">
        <el-upload
          v-model:file-list="fileList"
          class="upload-demo"
          :action="uploadUrl"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :before-upload="beforeUpload"
          name="file"
          :show-file-list="false"
          :headers="headers"
          accept="image/*"
          style="display: inline; margin-right: 10px"
        >
          <el-button type="primary">上传图片</el-button>
        </el-upload>
        <el-button type="danger" plain @click="handleDelete">删除</el-button>
      </div>
      <PIMTable
        rowKey="id"
        :column="tableColumn"
        :tableData="tableData"
        :page="page"
        :total="page.total"
        :tableLoading="tableLoading"
        :isSelection="true"
        @selection-change="handleSelectionChange"
        @pagination="paginationSearch"
        height="500"
      />
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeDia">关闭</el-button>
        </div>
      </template>
    </el-dialog>
    <filePreview ref="filePreviewRef" />
  </div>
</template>
<script setup>
import { ref, reactive, getCurrentInstance } from "vue";
import { ElMessageBox } from "element-plus";
import { getToken } from "@/utils/auth.js";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import filePreview from "@/components/filePreview/index.vue";
import {
  productWorkOrderFileAdd,
  productWorkOrderFileDel,
  productWorkOrderFileListPage,
} from "@/api/productionManagement/productWorkOrderFile.js";
const { proxy } = getCurrentInstance();
const emit = defineEmits(["close"]);
const dialogVisible = ref(false);
const currentWorkOrderId = ref("");
const selectedRows = ref([]);
const filePreviewRef = ref();
const tableColumn = ref([
  {
    label: "文件名称",
    prop: "name",
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    width: 120,
    operation: [
      {
        name: "下载",
        type: "text",
        clickFun: row => {
          proxy.$download.name(row.url);
        },
      },
      {
        name: "预览",
        type: "text",
        clickFun: row => {
          filePreviewRef.value?.open(row.url);
        },
      },
    ],
  },
]);
const page = reactive({
  current: 1,
  size: 100,
  total: 0,
});
const tableData = ref([]);
const fileList = ref([]);
const tableLoading = ref(false);
const headers = ref({
  Authorization: "Bearer " + getToken(),
});
const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload");
const beforeUpload = file => {
  const isImage = file?.type?.startsWith("image/");
  if (!isImage) {
    proxy.$modal.msgError("只能上传图片文件");
  }
  return isImage;
};
const openDialog = row => {
  dialogVisible.value = true;
  currentWorkOrderId.value = row.id;
  page.current = 1;
  getList();
};
const closeDia = () => {
  dialogVisible.value = false;
  emit("close");
};
const paginationSearch = obj => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  productWorkOrderFileListPage({
    workOrderId: currentWorkOrderId.value,
    current: page.current,
    size: page.size,
  })
    .then(res => {
      tableData.value = res.data.records || [];
      page.total = res.data.total || 0;
    })
    .finally(() => {
      tableLoading.value = false;
    });
};
const handleSelectionChange = selection => {
  selectedRows.value = selection;
};
function handleUploadSuccess(res) {
  if (res.code == 200) {
    const fileRow = {
      name: res.data.originalName,
      url: res.data.tempPath,
      workOrderId: currentWorkOrderId.value,
    };
    productWorkOrderFileAdd(fileRow).then(() => {
      proxy.$modal.msgSuccess("文件上传成功");
      getList();
    });
  } else {
    proxy.$modal.msgError("文件上传失败");
  }
}
function handleUploadError() {
  proxy.$modal.msgError("文件上传失败");
}
const handleDelete = () => {
  if (selectedRows.value.length === 0) {
    proxy.$modal.msgWarning("请选择数据");
    return;
  }
  const ids = selectedRows.value.map(item => item.id);
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      productWorkOrderFileDel(ids).then(() => {
        proxy.$modal.msgSuccess("删除成功");
        getList();
      });
    })
    .catch(() => {
      proxy.$modal.msg("已取消");
    });
};
defineExpose({
  openDialog,
});
</script>
<style scoped></style>
src/views/productionManagement/workOrder/index.vue
@@ -209,6 +209,7 @@
        </span>
      </template>
    </el-dialog>
    <FilesDia ref="workOrderFilesRef" />
  </div>
</template>
@@ -224,6 +225,7 @@
  import { getUserProfile, userListNoPageByTenantId } from "@/api/system/user.js";
  import QRCode from "qrcode";
  import { getCurrentInstance, reactive, toRefs } from "vue";
  import FilesDia from "./components/filesDia.vue";
  const { proxy } = getCurrentInstance();
  const tableColumn = ref([
@@ -311,6 +313,12 @@
          },
        },
        {
          name: "附件",
          clickFun: row => {
            openWorkOrderFiles(row);
          },
        },
        {
          name: "报工",
          clickFun: row => {
            showReportDialog(row);
@@ -330,6 +338,7 @@
  const transferCardQrUrl = ref("");
  const transferCardRowData = ref(null);
  const reportDialogVisible = ref(false);
  const workOrderFilesRef = ref(null);
  const userOptions = ref([]);
  const reportForm = reactive({
    planQuantity: 0,
@@ -450,6 +459,10 @@
    reportDialogVisible.value = true;
  };
  const openWorkOrderFiles = row => {
    workOrderFilesRef.value?.openDialog(row);
  };
  const handleReport = () => {
    if (reportForm.planQuantity <= 0) {
      ElMessageBox.alert("待生产数量为0,无法报工", "提示", {