chenlu
昨天 94c0a729da1b88ab4a0067f1e14a00264e0447cf
north-glass-erp/northglass-erp/src/views/sd/bom/OrderBOM.vue
@@ -45,7 +45,15 @@
  dataTotal : 0,
  pageSize : 50
})
let orderBomData =ref({
  productName:[]
})
let bomSum = ref({
  sumData:[],
  sumDatilsData:[]
})
let orderBomDetails = ref(null)
const xGrid = ref()
const gridOptions = reactive({
@@ -119,38 +127,28 @@
  columns:[
    {title: t('basicData.operate'), width: 110, slots: { default: 'button_slot' },fixed:"left",},
    {type: 'seq', title: t('basicData.Number'), width: 80 ,fixed:"left",},
    {field:'createOrder',title: t('searchOrder.createOrder'), width: 40, slots: { default: 'state' }},
    {field:'processReview',title: t('order.technology'), width: 40, filters:[{ data: '' }], slots: { default: 'state',filter: 'num2_filter' }},
    {field:'orderReview',title: t('basicData.review'), width: 40, filters:[{ data: '' }], slots: { default: 'state',filter: 'num2_filter' }},
    {field:'productionOrder',title: t('searchOrder.production'), width: 40, filters:[{ data: '' }], slots: { default: 'state',filter: 'num2_filter' }},
    {field:'processingCard',title: t('searchOrder.process'), width: 40, filters:[{ data: '' }], slots: { default: 'state',filter: 'num2_filter' }},
    {field:'warehousing',title: t('searchOrder.storage'), width: 40, filters:[{ data: '' }], slots: { default: 'state',filter: 'num2_filter' }},
    {field:'delivery',title: t('searchOrder.delivery'), width: 40,filters:[{ data: '' }], slots: { default: 'state',filter: 'num2_filter' }},
    {field: 'orderId',width:120,  title: t('order.orderId'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'customerId',width:120,  title: t('customer.customerNumber'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'customerName',width:120,  title: t('customer.customerName'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'project',width:120,  title: t('order.project'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'batch',width:120,  title: t('order.batch'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'quantity',width:120,  title: t('order.quantity'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'goodsQuantity',width:120,  title: t('searchOrder.inventoryNum'), sortable: true},
   // {field: 'goodsQuantity',width:120,  title: t('searchOrder.inventoryNum'), sortable: true},
    {field: 'area',width:120,  title: t('order.computeGrossArea'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'bomPrice',width:120,  title: t('bom.bomPrice'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'money',width:120,  title: t('order.money'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'createTime',width:120,filters:[{ data: '' }],slots: { filter: 'num1_filter' },   title: t('basicData.reportData'), sortable: true},
    {field: 'updateTime',width:120,   title: t('productStock.approvedDate'), sortable: true},
    {field: 'packType',width:120,  title: t('order.packType'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'orderType',width:120,  title: t('order.orderType'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'salesman',width:120,  title: t('order.salesman'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'creator',width:120,  title: t('product.creator'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'verifier',width:120,  title: t('basicData.review'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    //{field: 'verifier',width:120,  title: t('basicData.review'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'perimeter',width:120,  title: t('searchOrder.perimeter'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'deliveryDate',width:120,  title: t('order.deliveryDate'), sortable: true},
    {field: 'customerBatch',width:120,  title: t('order.customerBatch'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    //{field: '14',width:120,  title: '备注',filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'deliveryAddress',width:120,  title: t('order.deliveryAddress'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    //{field: 'deliveryAddress',width:120,  title: t('order.deliveryAddress'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true},
    {field: 'processingNote',width:120,  title: t('order.processingNote'),filters:[{ data: '' }],slots: { filter: 'num1_filter' }, sortable: true}
  ],
@@ -180,10 +178,10 @@
        if (columnIndex === 0) {
          return t('basicData.total')
        }
        const List = ["quantity",'goodsQuantity','area','perimeter','money']
        const List = ["quantity",'goodsQuantity','area','perimeter','money','bomPrice']
        if (List.includes(column.field)) {
          //return footSum(data, column.field)
          return total.value[column.field]
          return footSum(data, column.field)
          //return total.value[column.field]
        }
        return ''
      })
@@ -343,9 +341,9 @@
  },
  cellClick({ row }){
    rowClickIndex.value = row
    xGrid.value.menuConfig.body.options[0][3].children.forEach((item)=>{
      item.disabled=true
    })
    // xGrid.value.menuConfig.body.options[0][3].children.forEach((item)=>{
    //   item.disabled=true
    // })
    //判断是否入库
    if(row.warehousing>0){
      return
@@ -383,6 +381,9 @@
      /*total.dataTotal = res.data.total.dataTotal*1
      total.pageTotal= res.data.total.pageTotal*/
      orderInfo.selectDate = res.data.selectDate
      res.data.data.forEach((item)=>{
        item.bomPrice=(item.money/1.3).toFixed(2)
      })
      orderList.value = deepClone(res.data.data)
      xGrid.value.loadData(orderList.value)
    }else{
@@ -477,11 +478,110 @@
  selectOrderList()
}
//总价
const totalPriceSum = ref()
//页面跳转更新或者删除订单
const getTableRow =  (row,type) => {
  switch (type) {
    case 'edit': {
      dialogTableVisible.value = true
      if (row.orderId!="" && row.orderId!=null){
        request.post(`/BomData/getOrderBomData/${row.orderId}`,).then((res) => {
          if (res.code == 200 ) {
            orderBomData.value.productName =res.data.data
            bomSum.value.sumData = res.data.sumData
            bomSum.value.sumDatilsData  =res.data.sumDataDatils
            request.post(`/BomData/getBomDataProduct`,orderBomData.value).then((res) => {
              if (res.code == 200 ) {
                orderBomDetails.value=res.data.data
                orderBomData.value.productName.forEach((product, i) => {
                  const details = orderBomDetails.value[i]?.data || []
                  const perimeter = Number(product.perimeter || 0)
                  // hollow:重算 consume、materialPric
                  details.forEach(d => {
                    if (d.detail_type === 'hollow') {
                      const glueDepth = Number(d.glueDepth || 0)
                      const thickness = Number(d.thickness || 0)
                      const price = Number(d.price || 0)
                      // consume 保持为数字
                      const consume = (glueDepth / 100) * (thickness / 100) * perimeter
                      d.consume = Number(consume.toFixed(2))   // 需要保留2位就转回 number
                      // materialPric 也保持为数字
                      d.materialPric = Number((d.consume * price).toFixed(2))
                    }
                  })
                  // 生成 parts
                  const parts = product.product_name.split(/[*+]/)
                  parts.push("其它")
                  product.product_parts = parts.map((p, idx) => {
                    const assignedDetails = details.filter(d => Number(d.product_layer) === idx + 1)
                    return { name: p, details: assignedDetails }
                  })
                  // 每个 product 的总价(保证数字相加)
                  product.totalPrice = details.reduce(
                      (sum, d) => sum + Number(d.materialPric || 0),
                      0
                  )
                })
                //  成品合计:从 details 汇总
                const totalMap = new Map()
                orderBomDetails.value.forEach(block => {
                  const details = block?.data || []
                  details.forEach(d => {
                    const consume = Number(d.consume || 0)
                    const price = Number(d.price || 0)
                    const key = `${Number(d.material_id)}|${String(d.detail_type || '')}|${price}`
                    if (!totalMap.has(key)) {
                      totalMap.set(key, {
                        material_id: d.material_id,
                        material: d.material,
                        detail_type: d.detail_type,
                        price,
                        unit: d.unit,
                        type: d.type,
                        consume: 0,
                        materialPrice: 0
                      })
                    }
                    const row = totalMap.get(key)
                    row.consume += consume
                  })
                })
                const totalSumDatilsData = Array.from(totalMap.values()).map(r => ({
                  ...r,
                  consume: Number(r.consume.toFixed(2)),
                  materialPrice: Number(r.materialPrice.toFixed(2))
                }))
                bomSum.value.sumDatilsData = totalSumDatilsData
                // 汇总总金额
                totalPriceSum.value = orderBomData.value.productName.reduce(
                    (sum, p) => sum + Number(p.totalPrice || 0),
                    0
                )
                dialogTableVisible.value = true
              }
            })
          }
        })
      }
      break
    }
@@ -543,6 +643,7 @@
  }
}
</script>
<template>
@@ -598,7 +699,7 @@
                     link
                     type="primary"
                     size="small">
            生成BOM
            BOM查询
          </el-button>
        </template>
@@ -657,10 +758,88 @@
        id="print"
        v-model="dialogTableVisible"
        destroy-on-close
        style="width: 90%;height:90%;margin-top: 3vh "
        style="width: 600px;height: 600px"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
    >
      <el-card style="max-width: 480px;margin-left: 45px;margin-top: 20px">
        <!-- header -->
        <template #header>
          <div class="card-header">
            <span style="font-weight: bold">成品合计</span>
            &nbsp;&nbsp;&nbsp;
            <span>面积:{{ bomSum.sumData[0].area.toFixed(2) }}㎡</span>
            &nbsp;&nbsp;&nbsp;
            <span>数量:{{ bomSum.sumData[0].quantity }}</span>
            &nbsp;&nbsp;&nbsp;
            <span>周长:{{ bomSum.sumData[0].perimeter.toFixed(2) }}m</span>
          </div>
        </template>
        <!-- body -->
        <el-row
            v-for="(mat, idx) in bomSum.sumDatilsData"
            :key="idx"
            style="text-align: left; margin-bottom: 6px"
        >
          <el-col :span="8">{{ mat.material }}:</el-col>
          <el-col :span="8">{{ mat.consume }}㎡</el-col>
        </el-row>
        <!-- footer -->
        <template #footer>
          合计 ¥{{ totalPriceSum }}
        </template>
      </el-card>
      <el-card
          v-for="item in orderBomData.productName"
          :key="item.product_id"
          style="max-width: 480px;margin-left: 45px;margin-top: 20px"
      >
        <!-- header -->
        <template #header>
          <div class="card-header">
            <span style="font-weight: bold">{{ item.product_name }}</span>
            <br />
            <span>面积:{{ item.area }}</span>
            &nbsp;&nbsp;&nbsp;
            <span>数量:{{ item.quantity }}</span>
            &nbsp;&nbsp;&nbsp;
            <span>周长:{{ Number(item.perimeter).toFixed(2) }}</span>
          </div>
        </template>
        <!-- body -->
        <el-row
            v-for="(part, index) in item.product_parts"
            :key="index"
            style="text-align: left; margin-bottom: 6px"
        >
          <el-col :span="24">
              <el-row v-for="(d, j) in part.details"
                      :key="j"
                      style="text-align: left">
              <el-col :span="8">{{ d.material }}</el-col>
              <el-col :span="8">{{ d.consume }}{{d.unit}}</el-col>
              </el-row>
<!--            <hr v-if="part.details.length > 0" />-->
          </el-col>
        </el-row>
        <!-- footer -->
        <template #footer>合计 {{ item.totalPrice }}</template>
      </el-card>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary">转采购单</el-button>
          <el-button type="primary">
            领料
          </el-button>
        </div>
      </template>
    </el-dialog>
@@ -693,6 +872,8 @@
  background-color: orangered;
  border-color: orangered;
}
.el-row{
  text-align: center
}
</style>