Explorar o código

报价评估pdf

cz hai 1 ano
pai
achega
7d6098a3b8

+ 181 - 0
src/components/PDF/quotationPDF.vue

@@ -0,0 +1,181 @@
+<template>
+  <div>
+    <div id="pdfDom" ref="pdfDom" style="padding: 20px 20px 0; text-align: center;font-size:12px;color:#333333" v-loading="loading">
+      <table border="1" style="width: 100%" class="table">
+        <tr>
+          <td colspan="12" style="text-align:center">{{pdfData.code}} 报价单</td>
+        </tr>
+        <tr>
+          <td style="width:10%">产品编码</td>
+          <td style="width:10%">产品名称</td>
+          <td style="width:7%">产品数量</td>
+          <td style="width:7%">类型</td>
+          <td style="width:10%">编码</td>
+          <td style="width:10%">名称</td>
+          <td style="width:8%" class="align-right">模具</td>
+          <td style="width:7%" class="align-right">数量/件</td>
+          <td style="width:8%" class="align-right">单价</td>
+          <td style="width:7%" class="align-right">总量</td>
+          <td style="width:8%" class="align-right">总价</td>
+          <td style="width:8%" class="align-right">小计</td>
+        </tr>
+        <template v-if="pdfData.quotationProductList && pdfData.quotationProductList.length > 0" v-for="(item, index) in pdfData.quotationProductList"
+                  :key="item.productId">
+          <tr v-if="item.quotationEstimateList && item.quotationEstimateList.length>0" v-for="(row, sonIndex) in item.quotationEstimateList"
+              :key="row.id">
+            <td v-if="sonIndex==0" :rowspan="item.quotationEstimateList.length">{{item.productCode}}</td>
+            <td v-if="sonIndex==0" :rowspan="item.quotationEstimateList.length">{{item.productName}}</td>
+            <td v-if="sonIndex==0" :rowspan="item.quotationEstimateList.length">{{item.quantity}}</td>
+            <td v-if="row.isFirstRow" :rowspan="getRowSpan(item,row.type)">{{getLabel(row.type)}}</td>
+            <td>{{row.code}}</td>
+            <td>{{row.name}}</td>
+            <td class="align-right">
+              <span v-if="row.type==1">{{row.moldName}}</span>
+              <span v-else>-</span>
+            </td>
+            <td class="align-right">
+              <span v-if="row.type==1">-</span>
+              <span v-else>{{row.quantity}}</span>
+            </td>
+            <td class="align-right">{{moneyFormat(row.price,2)}}</td>
+            <td class="align-right">{{row.totalQuantity}}</td>
+            <td class="align-right">{{moneyFormat(row.amount,2)}}</td>
+            <td v-if="sonIndex==0" :rowspan="item.quotationEstimateList.length" class="align-right">{{moneyFormat(item.productAmount,2)}}</td>
+          </tr>
+        </template>
+        <tr>
+          <td colspan="11">报价总金额</td>
+          <td class="align-right">{{moneyFormat(pdfData.prodAmount,2)}} </td>
+        </tr>
+      </table>
+    </div>
+    <div style="text-align: center;margin-top:20px">
+      <el-button type="primary" v-print="printObj" size="default" v-debounce>打印</el-button>
+      <el-button type="primary" @click="clickDownload()" size="default" v-debounce>下载PDF</el-button>
+      <el-button type="primary" @click="exportExcel()" size="default" v-debounce>导出Excel</el-button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import $ from "jquery";
+const { proxy } = getCurrentInstance();
+const pdfData = ref({});
+const props = defineProps({
+  rowData: Object,
+});
+
+const loading = ref(false);
+const getPdfData = (query) => {
+  loading.value = true;
+  proxy.post("/quotationEstimate/printPdf", query).then((res) => {
+    for (let i = 0; i < res.quotationProductList.length; i++) {
+      const iele = res.quotationProductList[i];
+      let productAmount = 0;
+      let type1Status = true;
+      let type2Status = true;
+      let type3Status = true;
+      if (iele.quotationEstimateList && iele.quotationEstimateList.length > 0) {
+        for (let j = 0; j < iele.quotationEstimateList.length; j++) {
+          const jele = iele.quotationEstimateList[j];
+          productAmount += Number(jele.amount);
+          if (jele.type == 1 && type1Status) {
+            jele.isFirstRow = true;
+            type1Status = false;
+          } else if (jele.type == 2 && type2Status) {
+            jele.isFirstRow = true;
+            type2Status = false;
+          } else if (jele.type == 3 && type3Status) {
+            jele.isFirstRow = true;
+            type3Status = false;
+          } else {
+            jele.isFirstRow = false;
+          }
+        }
+      }
+      iele.productAmount = parseFloat(productAmount).toFixed(2);
+    }
+    pdfData.value = res;
+    loading.value = false;
+  });
+};
+
+const getRowSpan = (productData, type) => {
+  if (
+    productData.quotationEstimateList &&
+    productData.quotationEstimateList.length > 0
+  ) {
+    return productData.quotationEstimateList.filter((x) => x.type == type)
+      .length;
+  }
+};
+const labelObj = {
+  1: "原材料",
+  2: "包材辅材",
+  3: "工序",
+};
+const getLabel = (type) => {
+  return labelObj[type];
+};
+
+watch(
+  () => props.rowData,
+  (val) => {
+    if (props.rowData.id) {
+      getPdfData({ quotationId: props.rowData.id });
+    }
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+
+const printObj = ref({
+  id: "pdfDom",
+  popTitle: "",
+  extraCss:
+    "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
+  extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
+});
+
+const clickDownload = () => {
+  proxy.getPdf("报价单PDF文件");
+};
+
+const pdfDom = ref(null);
+const exportExcel = () => {
+  // pdfDom.value.exportExcel();
+  // isShowImg.value = false;
+  loading.value = true;
+  setTimeout(() => {
+    $("#pdfDom").table2excel({
+      exclude: ".noExl",
+      sheetName: `${pdfData.value.code} 报价单`,
+      filename: `${pdfData.value.code} 报价单`,
+      exclude_img: false,
+      exclude_links: false,
+      exclude_inputs: true,
+    });
+    // isShowImg.value = true;
+    loading.value = false;
+  }, 500);
+};
+</script>
+
+<style lang="scss" scoped>
+.table {
+  border-collapse: collapse;
+  border-spacing: 0;
+  width: 100%;
+  td {
+    text-align: left;
+    padding: 4px;
+    font-size: 12px;
+    // padding: 5px 10px;
+  }
+  .align-right {
+    text-align: right;
+  }
+}
+</style>

+ 1 - 1
src/views/EHSD/procurement/purchasedEHSD/index.vue

@@ -131,7 +131,7 @@
                   </div>
                 </template>
               </el-table-column>
-              <el-table-column label="采购数量" prop="purchaseQuantity" width="100" />
+              <!-- <el-table-column label="采购数量" prop="purchaseQuantity" width="100" /> -->
               <el-table-column label="到货数量" prop="quantity" width="100" />
             </el-table>
           </div>

+ 10 - 9
src/views/EHSD/productLibrary/companyProduct/index.vue

@@ -39,7 +39,7 @@
         </template>
         <template #price="{ item }">
           <div v-if="item.price">
-            <span>{{ item.currency }} {{ moneyFormat(item.price ,2)}}</span>
+            <span> {{ moneyFormat(item.price ,2)}}</span>
           </div>
           <div v-else></div>
         </template>
@@ -602,14 +602,14 @@ const formConfig = computed(() => {
       filterable: true,
       disabled: false,
       fn: (val) => {
-        let current = rawMaterialData.value.find((x) => x.value == val);
-        if (current) {
-          formData.data.price = Number(
-            parseFloat(
-              current["length"] * current.width * current.price
-            ).toFixed(2)
-          );
-        }
+        // let current = rawMaterialData.value.find((x) => x.value == val);
+        // if (current) {
+        //   formData.data.price = Number(
+        //     parseFloat(
+        //       current["length"] * current.width * current.price
+        //     ).toFixed(2)
+        //   );
+        // }
         getPriceData();
       },
     },
@@ -621,6 +621,7 @@ const formConfig = computed(() => {
       min: 0.01,
       controls: false,
       itemWidth: 50,
+      disabled: true,
     },
     // {
     //   type: "selectInput",

+ 180 - 0
src/views/EHSD/saleContract/businessReport/index.vue

@@ -0,0 +1,180 @@
+<template>
+  <div class="pageIndexClass">
+    <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" :selectConfig="selectConfig"
+             highlight-current-row @get-list="getList">
+      <template #code="{ item }">
+        <div v-if="Number(item.sumPayMoney) > Number(item.amount)" style="cursor: pointer; color: #f54a45" @click="handleClickCode(item)">
+          {{ item.code }}
+        </div>
+        <div v-else style="cursor: pointer; color: #409eff" @click="handleClickCode(item)">
+          {{ item.code }}
+        </div>
+      </template>
+
+    </byTable>
+
+  </div>
+</template>
+
+<script setup>
+import byTable from "@/components/byTable/index";
+const { proxy } = getCurrentInstance();
+const payStatus = ref([
+  {
+    label: "未付款",
+    value: 0,
+  },
+  {
+    label: "部分付款",
+    value: 10,
+  },
+  {
+    label: "已付款",
+    value: 20,
+  },
+]);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 0,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+    status: "",
+    payStatus: "",
+  },
+});
+const loading = ref(false);
+const selectConfig = computed(() => {
+  return [];
+});
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "订单类型",
+        prop: "a",
+        width: 130,
+      },
+    },
+    {
+      attrs: {
+        label: "订单号",
+        prop: "code",
+        width: 180,
+      },
+    },
+
+    {
+      attrs: {
+        label: "业务公司",
+        prop: "b",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "业务部门",
+        prop: "c",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "工厂",
+        prop: "userName",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "订单归属",
+        prop: "d",
+        width: 140,
+      },
+    },
+
+    {
+      attrs: {
+        label: "订单金额",
+        prop: "amount",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "下单时间",
+        prop: "createTime",
+        width: 160,
+      },
+    },
+    {
+      attrs: {
+        label: "交期",
+        prop: "e",
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "完工入库时间",
+        prop: "createTime",
+        width: 160,
+      },
+    },
+
+    {
+      attrs: {
+        label: "出货时间",
+        prop: "f",
+
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "出货间隔时间",
+        prop: "g",
+
+        width: 140,
+      },
+    },
+    {
+      attrs: {
+        label: "出货不及时率",
+        prop: "h",
+
+        width: 140,
+      },
+    },
+  ];
+});
+
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy.post("/ehsdPurchase/page", sourceList.value.pagination).then((res) => {
+    console.log(res);
+    sourceList.value.data = res.rows.map((x) => ({
+      ...x,
+      a: "常规订单",
+      b: "三梵实业",
+      c: "业务部",
+      d: "三梵体育",
+      e: "2024-02-15",
+      f: "2024-02-14",
+      g: "10",
+      h: "10%",
+    }));
+    sourceList.value.pagination.total = res.total;
+    setTimeout(() => {
+      loading.value = false;
+    }, 200);
+  });
+};
+
+getList();
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 24 - 1
src/views/EHSD/saleContract/priceSheetEstimate/index.vue

@@ -431,6 +431,10 @@
         <el-button @click="openSelectMaterial = false" size="defualt" v-debounce>关 闭</el-button>
       </template>
     </el-dialog>
+
+    <el-dialog title="打印" v-if="openPrint" v-model="openPrint" width="840">
+      <QuotationPDF :rowData="rowData"></QuotationPDF>
+    </el-dialog>
   </div>
 </template>
 
@@ -440,7 +444,7 @@ import byForm from "@/components/byForm/index";
 import { ref } from "vue";
 import * as echarts from "echarts";
 import SelectMaterial from "@/components/product/SelectMaterial.vue";
-
+import QuotationPDF from "@/components/PDF/quotationPDF.vue";
 const { proxy } = getCurrentInstance();
 const sourceList = ref({
   data: [],
@@ -598,6 +602,19 @@ const config = computed(() => {
                 },
               }
             : {},
+          row.quotationStatus == 2 && row.status == 30
+            ? {
+                attrs: {
+                  label: "打印",
+                  type: "primary",
+                  text: true,
+                },
+                el: "button",
+                click() {
+                  handlePrint(row);
+                },
+              }
+            : {},
         ];
       },
     },
@@ -1162,6 +1179,12 @@ const changeTotalAmount = () => {
   }
   formData.data.totalAmount = parseFloat(money).toFixed(2);
 };
+const openPrint = ref(false);
+const rowData = ref({});
+const handlePrint = (row) => {
+  openPrint.value = true;
+  rowData.value = row;
+};
 </script>
 
 <style lang="scss" scoped>

+ 2 - 2
src/views/EHSD/saleContract/priceSheetForeign/index.vue

@@ -96,7 +96,7 @@
           <div>
             <el-button type="primary" text v-debounce v-if="item.status !=88" @click="handleGenerate(item,false)">生成订单</el-button>
             <el-button type="primary" text v-debounce v-if="item.status !=88" @click="handleGenerate(item,true)">生成样品单</el-button>
-            <el-button type="primary" text v-debounce v-if="item.status !=88" @click="getDtl(item)">调价</el-button>
+            <!-- <el-button type="primary" text v-debounce v-if="item.status !=88" @click="getDtl(item)">调价</el-button> -->
             <el-button type="danger" text v-debounce v-if="item.status !=0 && item.status !=88" @click="handleRepeal(item)">作废</el-button>
           </div>
           <!-- <el-button type="primary" text v-debounce @click="handleFollow(item)">跟进</el-button> -->
@@ -239,7 +239,7 @@
                    @click="handleGenerate(leftRowData,false)">生成订单</el-button>
         <el-button type="primary" v-debounce v-if="leftRowData.status !=88 &&leftRowData.status !=70"
                    @click="handleGenerate(leftRowData,true)">生成样品单</el-button>
-        <el-button type="primary" v-debounce v-if="leftRowData.status !=88 &&leftRowData.status !=70" @click="getDtl(leftRowData)">调价</el-button>
+        <!-- <el-button type="primary" v-debounce v-if="leftRowData.status !=88 &&leftRowData.status !=70" @click="getDtl(leftRowData)">调价</el-button> -->
         <el-button type="danger" v-debounce v-if="leftRowData.status !=0 && leftRowData.status !=88 &&leftRowData.status !=70"
                    @click="handleRepeal(leftRowData)">作废</el-button>
       </template>

+ 1 - 0
src/views/MES/processScheduling/index.vue

@@ -42,6 +42,7 @@
           <template #isOverdue="{item}">
             <div style="width: 100%">
               <span class="red" v-if="item.isOverdue=='1'"> 逾期 </span>
+              <span v-else> 未逾期 </span>
             </div>
           </template>
 

+ 1 - 0
src/views/MES/productionOrder/index.vue

@@ -15,6 +15,7 @@
         <template #isOverdue="{item}">
           <div style="width: 100%">
             <span class="red" v-if="item.isOverdue=='1'"> 逾期 </span>
+            <span v-else> 未逾期</span>
           </div>
         </template>
 

+ 1 - 0
src/views/MES/productionTask/index.vue

@@ -44,6 +44,7 @@
       <template #isOverdue="{item}">
         <div style="width: 100%">
           <span class="red" v-if="item.isOverdue=='1'"> 逾期 </span>
+          <span v-else> 未逾期 </span>
         </div>
       </template>
 

+ 34 - 2
src/views/product/material/index.vue

@@ -368,6 +368,27 @@ const formOption = reactive({
 });
 const formDom = ref(null);
 const treeListData = ref([]);
+function findNodeById(treeData, nodeId) {
+  // 遍历当前层级的所有节点
+  for (let i = 0; i < treeData.length; i++) {
+    let node = treeData[i];
+    // 如果当前节点的 ID 匹配目标节点的 ID,则返回当前节点
+    if (node.id === nodeId) {
+      return node;
+    }
+    // 如果当前节点有子节点,则递归调用当前函数继续查找子节点
+    if (node.children && node.children.length > 0) {
+      let foundNode = findNodeById(node.children, nodeId);
+      // 如果在子节点中找到了目标节点,则返回找到的节点
+      if (foundNode) {
+        return foundNode;
+      }
+    }
+  }
+  // 如果遍历完所有节点仍未找到目标节点,则返回 null
+  return null;
+}
+const isShowLabel = ref(false);
 const formConfig = computed(() => {
   return [
     {
@@ -381,6 +402,17 @@ const formConfig = computed(() => {
       data: treeData.value,
       itemWidth: 100,
       disabled: false,
+      fn: (val) => {
+        let current = findNodeById(treeData.value, val);
+        console.log(current, "sss");
+        if (current) {
+          if (current.id == 100) {
+            isShowLabel.value = true;
+          } else {
+            isShowLabel.value = current.parentIdSet.includes("100");
+          }
+        }
+      },
     },
     {
       type: "input",
@@ -477,7 +509,7 @@ const formConfig = computed(() => {
     {
       type: "number",
       prop: "costPrice",
-      label: "成本价",
+      label: "成本价" + isShowLabel.value ? "(cm²)" : "",
       precision: 2,
       min: 0.01,
       controls: false,
@@ -495,7 +527,7 @@ const formConfig = computed(() => {
     {
       type: "number",
       prop: "price",
-      label: "销售价",
+      label: "销售价" + isShowLabel.value ? "(cm²)" : "",
       precision: 2,
       min: 0.01,
       controls: false,