zzs 3 сар өмнө
parent
commit
3f43a760aa

+ 1 - 0
ruoyi-ui/package.json

@@ -53,6 +53,7 @@
     "js-beautify": "1.13.0",
     "js-cookie": "3.0.1",
     "jsencrypt": "3.0.0-rc.1",
+    "jszip": "^3.10.1",
     "moment": "^2.29.4",
     "nprogress": "0.2.0",
     "quill": "^1.3.7",

+ 14 - 0
ruoyi-ui/src/api/mark/mark.js

@@ -21,3 +21,17 @@ export function addMark(data) {
     data,
   });
 }
+export function getQuoteScore(params) {
+  return request({
+    url: "/bidding/mark/getQuoteScore",
+    method: "get",
+    params,
+  });
+}
+export function getTotal(params) {
+  return request({
+    url: "/bidding/mark/getTotal",
+    method: "get",
+    params,
+  });
+}

+ 9 - 0
ruoyi-ui/src/api/summary/summary.js

@@ -0,0 +1,9 @@
+import request from "@/utils/request";
+
+export function getSummary(params) {
+  return request({
+    url: "/bidding/summary/list",
+    method: "get",
+    params,
+  });
+}

+ 11 - 4
ruoyi-ui/src/api/system/tender/tender.js

@@ -94,10 +94,10 @@ export function findStopTender(query) {
 export function updateIsApply(data) {
   return request({
     // url: "/bidding/tender/updateIsApply?sid=" + data.sid + '&isApply=' + data.isApply,
-    url: '/bidding/tender/updateIsApply',
-    method: 'post',
-    data: data
-  })
+    url: "/bidding/tender/updateIsApply",
+    method: "post",
+    data: data,
+  });
 }
 
 // 重新开标
@@ -108,3 +108,10 @@ export function openTender(data) {
     data: data,
   });
 }
+export function openTenderTwo(data) {
+  return request({
+    url: "bidding/tender/openTenderTwo",
+    method: "put",
+    data: data,
+  });
+}

+ 344 - 3
ruoyi-ui/src/utils/markExcel.js

@@ -1,6 +1,6 @@
 import dayjs from "dayjs";
 /**
- *
+ * 资格审查
  * @param {*} workbook ExcelJs对象
  * @param {*} sName 项目名称
  * @param {*} kaibiaoTime 开标时间
@@ -186,7 +186,7 @@ export const genExamineExcel = (
 };
 
 /**
- *
+ * 响应性
  * @param {*} workbook ExcelJs对象
  * @param {*} sName 项目名称
  * @param {*} kaibiaoTime 开标时间
@@ -372,7 +372,7 @@ export const genRespondExcel = (
 };
 
 /**
- *
+ * 技术性
  * @param {*} workbook ExcelJs对象
  * @param {*} sName 项目名称
  * @param {*} kaibiaoTime 开标时间
@@ -569,3 +569,344 @@ export const genTechExcel = (
   rowLast.height = 20;
   rowLast.font = { name: "宋体", family: 4, size: 10 };
 };
+
+/**
+ * 投标得分
+ * @param {*} workbook ExcelJs对象
+ * @param {*} tableData 数据
+ */
+export const genBidScoreExcel = (workbook, tableData) => {
+  const worksheet = workbook.addWorksheet("报价得分");
+  const columnWidth = [5, 34.5, 21.13, 21.13, 21.13, 21.13];
+  for (let cw = 1; cw <= columnWidth.length; cw++) {
+    worksheet.getColumn(cw).width = columnWidth[cw - 1] + 0.62;
+  }
+  worksheet.addRow(["投标报价得分计算表"]);
+  worksheet.mergeCells("A1:F1");
+  worksheet.getCell("A1").alignment = {
+    vertical: "middle",
+    horizontal: "center",
+  };
+  const row1 = worksheet.getRow(1);
+  row1.height = 32;
+  row1.font = { name: "宋体", family: 4, size: 20, bold: true };
+
+  worksheet.addRow(["", ""]);
+  worksheet.mergeCells("A2:C2");
+  worksheet.mergeCells("D2:F2");
+  const row2 = worksheet.getRow(2);
+  row2.height = 48;
+
+  worksheet.addRow([
+    "序号",
+    "投标人名称",
+    "投标报价(元)",
+    "评标基准价",
+    "偏差率(%)",
+    "报价得分",
+  ]);
+
+  const row3 = worksheet.getRow(3);
+  row3.height = 33;
+  row3.font = { name: "宋体", family: 4, size: 10.5 };
+
+  const tableHeader = ["A3", "B3", "C3", "D3", "E3", "F3"];
+  for (let th of tableHeader) {
+    worksheet.getCell(th).alignment = {
+      vertical: "middle",
+      horizontal: "center",
+    };
+    worksheet.getCell(th).border = {
+      top: { style: "thin" },
+      left: { style: "thin" },
+      bottom: { style: "thin" },
+      right: { style: "thin" },
+    };
+  }
+  const tableStartNum = 4;
+
+  const tbody = ["A", "B", "C", "D", "E", "F"];
+
+  for (let i = 0; i < tableData.length; i++) {
+    const data = [
+      i + 1,
+      tableData[i].hName,
+      tableData[i].quotePrice,
+      tableData[i].level,
+      tableData[i].percent,
+      tableData[i].score,
+    ];
+    for (let j = 0; j < data.length; j++) {
+      const td = tbody[j];
+      worksheet.getCell(`${td}${i + tableStartNum}`).border = {
+        top: { style: "thin" },
+        left: { style: "thin" },
+        bottom: { style: "thin" },
+        right: { style: "thin" },
+      };
+      let alignment = { vertical: "middle", horizontal: "center" };
+      let value = data[j];
+
+      worksheet.getCell(`${td}${i + tableStartNum}`).alignment = alignment;
+      worksheet.getCell(`${td}${i + tableStartNum}`).value = value;
+      worksheet.getCell(`${td}${i + tableStartNum}`).font = {
+        name: "宋体",
+        family: 4,
+        size: 10.5,
+      };
+    }
+    const row = worksheet.getRow(i + tableStartNum);
+    row.height = 30;
+  }
+
+  const huiZhongRowNum = tableData.length + tableStartNum;
+  worksheet.mergeCells(`D${tableStartNum}:D${huiZhongRowNum - 1}`);
+
+  worksheet.getCell(`A${huiZhongRowNum}`).alignment = {
+    vertical: "middle",
+    wrapText: true,
+  };
+  worksheet.getCell(`A${huiZhongRowNum}`).value = {
+    richText: [
+      {
+        font: { name: "宋体", family: 4, size: 11 },
+        text: `1、以评标标准值为基准,投标人的投标报价等于评标标准值得满分7分;
+2、每低于评标标准值的1%扣0.5分;
+3、每高于评标标准值的1%扣0.6分;
+4、中间值按插入法计算,所有计算得分最终保留小数点后2位,第3位将四舍五入。
+5、评标基准价计算方法:通过初步评审的投标报价参加报价得分计算。
+(1)有效投标报价<5家时,取所有有效投标报价的算数平均值为评标标准值;
+(2)有效投标报价≥5家时,去掉最高投标报价和最低投标报价后,其余有效投标报价的算数平均值为评标标准值。
+(3)分数值保留至小数点后两位,第三位四舍五入。
+6、投标报价的偏差率计算公式:
+偏差率=(投标报价−评标基准价)/评标基准价×100%`,
+      },
+    ],
+  };
+  worksheet.mergeCells(`A${huiZhongRowNum}:F${huiZhongRowNum}`);
+  worksheet.getCell(`A${huiZhongRowNum}`).border = {
+    top: { style: "thin" },
+    left: { style: "thin" },
+    bottom: { style: "thin" },
+    right: { style: "thin" },
+  };
+  const rowDenfen = worksheet.getRow(huiZhongRowNum);
+  rowDenfen.height = 141;
+
+  const lastRowNum = huiZhongRowNum + 1;
+  worksheet.addRow(["评标委员会成员签字:"]);
+  worksheet.mergeCells(`A${lastRowNum}:E${lastRowNum}`);
+  worksheet.getCell(`A${lastRowNum}`).alignment = { vertical: "middle" };
+  const rowLast = worksheet.getRow(lastRowNum);
+  rowLast.height = 28;
+  rowLast.font = { name: "宋体", family: 4, size: 10.5 };
+};
+
+/**
+ * 得分汇总
+ * @param {*} workbook ExcelJs对象
+ * @param {*} tableData 数据
+ */
+export const genTotalScoreExcel = (workbook, tableData, zjNames) => {
+  const worksheet = workbook.addWorksheet("评分汇总");
+  const columnWidth = [
+    4.57, 35.25, 11.75, 11.75, 11.75, 11.75, 11.75, 9.48, 9.48, 9.48, 7.88,
+  ];
+  for (let cw = 1; cw <= columnWidth.length; cw++) {
+    worksheet.getColumn(cw).width = columnWidth[cw - 1] + 0.62;
+  }
+  worksheet.addRow([""]);
+  worksheet.mergeCells("A1:K1");
+  worksheet.getCell("A1").alignment = {
+    vertical: "middle",
+    horizontal: "center",
+  };
+  const row1 = worksheet.getRow(1);
+  row1.height = 30;
+  row1.font = { name: "宋体", family: 4, size: 16, bold: true };
+
+  worksheet.addRow(["评委评分汇总表"]);
+  worksheet.mergeCells("A2:K2");
+  worksheet.getCell("A2").alignment = {
+    vertical: "middle",
+    horizontal: "center",
+  };
+  const row2 = worksheet.getRow(2);
+  row2.height = 30;
+  row2.font = { name: "宋体", family: 4, size: 16, bold: true };
+
+  worksheet.addRow(["", ""]);
+  worksheet.mergeCells("A3:E3");
+  worksheet.mergeCells("F3:K3");
+  const row3 = worksheet.getRow(3);
+  row3.height = 48;
+
+  worksheet.addRow([
+    "序号",
+    "投标人名称",
+    "技术部分评分",
+    "",
+    "",
+    "",
+    "",
+    "综合得分",
+    "报价得分",
+    "总得分",
+    "排序",
+  ]);
+
+  worksheet.mergeCells("C4:G4");
+
+  //专家
+  let zjData = ["", ""];
+  zjData = zjData.concat(zjNames);
+  zjData.push("");
+  zjData.push("");
+  zjData.push("");
+  zjData.push("");
+  worksheet.addRow(zjData);
+
+  const mergeHeader = ["A", "B", "H", "I", "J", "K"];
+  for (let i = 0; i < mergeHeader.length; i++) {
+    worksheet.mergeCells(`${mergeHeader[i]}4:${mergeHeader[i]}5`);
+    worksheet.getCell(`${mergeHeader[i]}4`).alignment = {
+      vertical: "middle",
+      horizontal: "center",
+    };
+    worksheet.getCell(`${mergeHeader[i]}4`).border = {
+      top: { style: "thin" },
+      left: { style: "thin" },
+      bottom: { style: "thin" },
+      right: { style: "thin" },
+    };
+  }
+
+  const row4 = worksheet.getRow(4);
+  row4.height = 32;
+  row4.font = { name: "宋体", family: 4, size: 10.5, bold: true };
+
+  const row5 = worksheet.getRow(5);
+  row5.height = 46;
+  row5.font = { name: "宋体", family: 4, size: 10.5, bold: true };
+
+  const zjHeader = ["C", "D", "E", "F", "G"];
+  for (let i = 0; i < zjHeader.length; i++) {
+    worksheet.getCell(`${zjHeader[i]}4`).alignment = {
+      vertical: "middle",
+      horizontal: "center",
+    };
+    worksheet.getCell(`${zjHeader[i]}4`).font = {
+      name: "宋体",
+      family: 4,
+      size: 10.5,
+    };
+    worksheet.getCell(`${zjHeader[i]}4`).border = {
+      top: { style: "thin" },
+      left: { style: "thin" },
+      bottom: { style: "thin" },
+      right: { style: "thin" },
+    };
+    worksheet.getCell(`${zjHeader[i]}5`).alignment = {
+      vertical: "middle",
+      horizontal: "center",
+    };
+    worksheet.getCell(`${zjHeader[i]}5`).font = {
+      name: "宋体",
+      family: 4,
+      size: 10.5,
+    };
+    worksheet.getCell(`${zjHeader[i]}5`).border = {
+      top: { style: "thin" },
+      left: { style: "thin" },
+      bottom: { style: "thin" },
+      right: { style: "thin" },
+    };
+  }
+
+  const tableStartNum = 6;
+
+  const tbody = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
+
+  let zhongbiaoren = "";
+  for (let i = 0; i < tableData.length; i++) {
+    const techList = tableData[i].techList;
+    const data = [i + 1, tableData[i].hName];
+    if (i == 0) {
+      zhongbiaoren = tableData[i].hName;
+    }
+    for (let j = 0; j < techList.length; j++) {
+      data.push(techList[j].score);
+    }
+    data.push(tableData[i].averScore);
+    data.push(tableData[i].priceScore);
+    data.push(tableData[i].totalScore);
+    data.push(i + 1);
+    for (let j = 0; j < data.length; j++) {
+      const td = tbody[j];
+      worksheet.getCell(`${td}${i + tableStartNum}`).border = {
+        top: { style: "thin" },
+        left: { style: "thin" },
+        bottom: { style: "thin" },
+        right: { style: "thin" },
+      };
+      let alignment = { vertical: "middle", horizontal: "center" };
+      let value = data[j];
+      worksheet.getCell(`${td}${i + tableStartNum}`).alignment = alignment;
+      worksheet.getCell(`${td}${i + tableStartNum}`).value = value;
+      worksheet.getCell(`${td}${i + tableStartNum}`).font = {
+        name: "宋体",
+        family: 4,
+        size: 12,
+      };
+    }
+    const row = worksheet.getRow(i + tableStartNum);
+    row.height = 39;
+  }
+
+  const zhongbiaorenRowNum = tableData.length + tableStartNum;
+  worksheet.addRow(["预中标人", "", zhongbiaoren]);
+  worksheet.mergeCells(`A${zhongbiaorenRowNum}:B${zhongbiaorenRowNum}`);
+  worksheet.mergeCells(`C${zhongbiaorenRowNum}:K${zhongbiaorenRowNum}`);
+
+  worksheet.getCell(`A${zhongbiaorenRowNum}`).border = {
+    top: { style: "thin" },
+    left: { style: "thin" },
+    bottom: { style: "thin" },
+    right: { style: "thin" },
+  };
+  worksheet.getCell(`A${zhongbiaorenRowNum}`).alignment = {
+    vertical: "middle",
+    horizontal: "center",
+  };
+  worksheet.getCell(`A${zhongbiaorenRowNum}`).font = {
+    name: "宋体",
+    family: 4,
+    size: 12,
+  };
+  worksheet.getCell(`C${zhongbiaorenRowNum}`).border = {
+    top: { style: "thin" },
+    left: { style: "thin" },
+    bottom: { style: "thin" },
+    right: { style: "thin" },
+  };
+  worksheet.getCell(`C${zhongbiaorenRowNum}`).alignment = {
+    vertical: "middle",
+    horizontal: "center",
+  };
+  worksheet.getCell(`C${zhongbiaorenRowNum}`).font = {
+    name: "宋体",
+    family: 4,
+    size: 12,
+  };
+
+  const rowZhongbiaoren = worksheet.getRow(zhongbiaorenRowNum);
+  rowZhongbiaoren.height = 39;
+
+  const lastRowNum = zhongbiaorenRowNum + 1;
+  worksheet.addRow(["评标委员会全体成员签字:"]);
+  worksheet.mergeCells(`A${lastRowNum}:B${lastRowNum}`);
+  worksheet.getCell(`A${lastRowNum}`).alignment = { vertical: "bottom" };
+  const rowLast = worksheet.getRow(lastRowNum);
+  rowLast.height = 28;
+  rowLast.font = { name: "宋体", family: 4, size: 12 };
+};

+ 33 - 34
ruoyi-ui/src/views/tender/tender1/bidding.vue

@@ -24,7 +24,7 @@
       </el-tabs>
     </div>
     <div v-if="currentName === '投标'" class="div2">
-      <el-descriptions style="margin-top: 20px;" title="" :column="3" border :labelStyle="{width: '180px'}">
+      <el-descriptions style="margin-top: 20px;" title="" :column="3" border :labelStyle="{ width: '180px' }">
         <el-descriptions-item label="报价方式">
           <dict-tag :options="dict.type.quote_mode" :value="plan.quoteMode" />
         </el-descriptions-item>
@@ -53,19 +53,18 @@
           {{ tender.enrollNumber }}
         </el-descriptions-item>
       </el-descriptions>
-      <el-table v-if="isOverFirstTime" :data="quoteTableData" 
-        border style="width: 100%;margin-top: 20px;">
+      <el-table v-if="isOverFirstTime" :data="quoteTableData" border style="width: 100%;margin-top: 20px;">
         <el-table-column label="供应商名称" prop="hName" align="center" />
         <el-table-column label="供应商联系人" prop="contact" align="center" />
         <el-table-column label="供应商联系方式" prop="contactPhone" align="center" />
         <el-table-column v-if="isOverFirstTime" label="报价" prop="quotePrice" align="center">
           <template slot-scope="scope">
-            <span>{{scope.row.third ? scope.row.third : (scope.row.second ? scope.row.second : scope.row.first)}}</span>
+            <span>{{ scope.row.third ? scope.row.third : (scope.row.second ? scope.row.second : scope.row.first) }}</span>
           </template>
         </el-table-column>
         <el-table-column v-if="isOverFirstTime" label="报价时间" prop="quoteTime" align="center">
           <template slot-scope="scope">
-            <span>{{scope.row.quoteTime}}</span>
+            <span>{{ scope.row.quoteTime }}</span>
           </template>
         </el-table-column>
         <el-table-column v-if="plan.buyingMode == 2 && checkRole(['operator', 'commander'])" label="标书" align="center">
@@ -75,8 +74,7 @@
             </div>
           </template>
         </el-table-column>
-        <el-table-column v-if="plan.buyingMode == 2 && checkRole(['operator', 'commander'])" 
-          align="center" label="操作">
+        <el-table-column v-if="plan.buyingMode == 2 && checkRole(['operator', 'commander'])" align="center" label="操作">
           <template slot-scope="scope">
             <el-button v-if="scope.row.audit != 1" type="text" @click="handlePassAudit(scope.row)">审核通过</el-button>
             <span v-else>已审核通过</span>
@@ -92,8 +90,8 @@
     <div v-if="currentName === '专家'" class="div2">
       <!-- <el-tabs v-model="activeName2">
         <el-tab-pane label="组建评标委员会" name="expert" style="font-size: 16px"> -->
-          <CompExpert v-if="tender && tender.sid" :tender="tender"></CompExpert>
-        <!-- </el-tab-pane>
+      <CompExpert v-if="tender && tender.sid" :tender="tender"></CompExpert>
+      <!-- </el-tab-pane>
       </el-tabs> -->
     </div>
     <div v-if="currentName === '评标'" class="div2">
@@ -105,11 +103,13 @@
     </div>
     <div v-if="currentName === '定标'" class="div2">
       <el-tabs v-model="activeName4">
-        <el-tab-pane v-if="plan.buyingMode == 2 && checkRole(['operator', 'commander'])" label="确定中标人" name="determineWin" style="font-size: 16px">
-          <el-button v-if="checkRole(['operator', 'commander']) && tender && tender.sProjectState >= 3 && tender.sProjectState <= 6" 
+        <el-tab-pane v-if="plan.buyingMode == 2 && checkRole(['operator', 'commander'])" label="确定中标人"
+          name="determineWin" style="font-size: 16px">
+          <el-button
+            v-if="checkRole(['operator', 'commander']) && tender && tender.sProjectState >= 3 && tender.sProjectState <= 6"
             type="primary" @click="handleAbortiveTender" v-loading.fullscreen.lock="fullscreenLoading">流标</el-button>
-          <el-button v-if="checkRole(['operator', 'commander']) && tender && tender.sProjectState == 6" 
-            type="primary" @click="handleReOpenBid" v-loading.fullscreen.lock="fullscreenLoading">重新开标</el-button>
+          <el-button v-if="checkRole(['operator', 'commander']) && tender && tender.sProjectState == 6" type="primary"
+            @click="handleReOpenBid" v-loading.fullscreen.lock="fullscreenLoading">重新开标</el-button>
 
           <CompDetermineWin v-if="tender && tender.sid" :tender="tender" />
         </el-tab-pane>
@@ -123,7 +123,7 @@
 </template>
 
 <script>
-import { getTender, updateTender, openTender } from '@/api/system/tender/tender'
+import { getTender, updateTender, openTender, openTenderTwo } from '@/api/system/tender/tender'
 import { getPlan } from '@/api/system/plan'
 import { getMateriel } from "@/api/mast/materiel";
 import { listQuote, UpdateQuote } from '@/api/system/quote'
@@ -216,7 +216,7 @@ export default {
   },
 
   computed: {
-    isOverFirstTime() {
+    isOverFirstTime () {
       const currentTime = moment();
       let kaibiaoTime = moment(this.detail.firstTime);
 
@@ -341,7 +341,7 @@ export default {
           icon: 'el-icon-position',
 
         }]
-        
+
         if (this.checkRole(['purchaser'])) {
           this.activeName4 == 'annWin'
         } else {
@@ -349,7 +349,7 @@ export default {
         }
       }
     },
-    async getListQuote() {
+    async getListQuote () {
       const res = await listQuote({ sid: this.sid })
       this.quoteTableData = res.data.map(item => {
         const filePath = item.filePath
@@ -361,7 +361,7 @@ export default {
         return item
       })
     },
-    
+
     handlePassAudit (row) {
       this.$modal.confirm(`是否审核通过该供应商【${row.hName}】的报价?`).then(() => {
         const formData = {
@@ -411,24 +411,23 @@ export default {
     },
 
     // 重新开标
-    handleReOpenBid() {
+    handleReOpenBid () {
       this.$modal.confirm(`确定开标?`)
-      .then(() => {
-        this.fullscreenLoading = true;
-        const formData = {
-          sid: Number(this.sid),
-          audit: 1
-        }
-        
-        openTender(formData)
-        .then(res => {
-          this.$message.success('操作成功')
-          this.getData()
-          // this.$refs.refCompWinningBid.getList()
-        }).finally(() => {
-          this.fullscreenLoading = false;
+        .then(() => {
+          this.fullscreenLoading = true;
+          const formData = {
+            sid: Number(this.sid)
+          }
+
+          openTenderTwo(formData)
+            .then(res => {
+              this.$message.success('操作成功')
+              this.getData()
+              // this.$refs.refCompWinningBid.getList()
+            }).finally(() => {
+              this.fullscreenLoading = false;
+            })
         })
-      })
     }
   }
 };

+ 13 - 11
ruoyi-ui/src/views/tender/tender1/components/CompDetermineWin.vue

@@ -2,25 +2,27 @@
   <div class="app-container">
     <el-table :data="data" border style="width: 100%">
       <el-table-column prop="hName" align="center" label="供应商名称" />
-      <el-table-column prop="contact" align="center" label="供应商联系人" />
-      <el-table-column prop="contactPhone" align="center" label="供应商联系方式" />
-      <el-table-column prop="quotePrice" align="center" label="报价">
+      <el-table-column prop="ywName" align="center" label="供应商联系人" />
+      <el-table-column prop="ywPhone" align="center" label="供应商联系方式" />
+      <el-table-column prop="scoreInfo" align="center" label="专家评分">
         <template slot-scope="scope">
-          <span>{{scope.row.third ? scope.row.third : (scope.row.second ? scope.row.second : scope.row.first)}}</span>
+          <div v-for="(item, index) in scope.row.scoreInfo.split(';')" :key="index">
+            {{ item.replace(',', ':') }}
+          </div>
         </template>
       </el-table-column>
-      <el-table-column prop="quoteTime" align="center" label="报价时间">
-        <template slot-scope="scope">
-          <span>{{scope.row.quoteTime}}</span>
-        </template>
+      <el-table-column prop="averScore" align="center" label="综合得分" />
+      <el-table-column prop="priceScore" align="center" label="报价得分" />
+      <el-table-column prop="totalScore" align="center" label="总得分" />
+      <el-table-column type="index" label="排序" align="center">
+        <template slot-scope="scope">{{ scope.$index + 1 }}</template>
       </el-table-column>
     </el-table>
   </div>
 </template>
 <script>
 
-import { listQuote } from '@/api/system/quote'
-import { listWinner } from "@/api/system/winner";
+import { getSummary } from '@/api/summary/summary'
 import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
 
 export default {
@@ -48,7 +50,7 @@ export default {
 
     /** 查询列表 */
     async getList () {
-      const res = await listQuote({ sid: this.sid, audit: 1 })
+      const res = await getSummary({ sid: this.sid })
       this.data = res.data
     }
   }

+ 57 - 0
ruoyi-ui/src/views/tender/tender1/components/CompDetermineWin_old.vue

@@ -0,0 +1,57 @@
+<template>
+  <div class="app-container">
+    <el-table :data="data" border style="width: 100%">
+      <el-table-column prop="hName" align="center" label="供应商名称" />
+      <el-table-column prop="contact" align="center" label="供应商联系人" />
+      <el-table-column prop="contactPhone" align="center" label="供应商联系方式" />
+      <el-table-column prop="quotePrice" align="center" label="报价">
+        <template slot-scope="scope">
+          <span>{{scope.row.third ? scope.row.third : (scope.row.second ? scope.row.second : scope.row.first)}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="quoteTime" align="center" label="报价时间">
+        <template slot-scope="scope">
+          <span>{{scope.row.quoteTime}}</span>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+<script>
+
+import { listQuote } from '@/api/system/quote'
+import { listWinner } from "@/api/system/winner";
+import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
+
+export default {
+  name: "DetermineWin",
+  props: {
+    tender: {
+      type: Object,
+      default: () => { }
+    }
+  },
+  data () {
+    return {
+      sid: null,
+      data: [],
+      loading: false,
+      isResult: false,
+    };
+  },
+  created () {
+    this.sid = this.$route.query.sid;
+    this.getList();
+  },
+  methods: {
+    checkRole,
+
+    /** 查询列表 */
+    async getList () {
+      const res = await listQuote({ sid: this.sid, audit: 1 })
+      this.data = res.data
+    }
+  }
+};
+</script>
+<style scoped lang="scss"></style>

+ 84 - 12
ruoyi-ui/src/views/tender/tender1/components/CompEval.vue

@@ -53,10 +53,11 @@
 <script>
 import { updateTender, getTender } from '@/api/system/tender/tender'
 import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
-import { getMarkAll } from '@/api/mark/mark'
+import { getMarkAll, getQuoteScore, getTotal } from '@/api/mark/mark'
 import ExcelJS from 'exceljs'
+import JSZip from 'jszip'
 import { saveAs } from 'file-saver'
-import { genExamineExcel, genRespondExcel, genTechExcel } from '@/utils/markExcel'
+import { genExamineExcel, genRespondExcel, genTechExcel, genBidScoreExcel, genTotalScoreExcel } from '@/utils/markExcel'
 export default {
   name: "Candidate",
   props: {
@@ -88,6 +89,9 @@ export default {
       sName: '',
       uKaiPosition: '',
       uKaiTime: '',
+      quoteScore: [],
+      totalScore: [],
+      ZjNames: []
     };
   },
   created () {
@@ -96,6 +100,8 @@ export default {
     this.form.sSign = tender.sSign;
     this.getData()
     this.getMarks()
+    this.getQuoteScore()
+    this.getTotal()
   },
   methods: {
     checkRole,
@@ -126,7 +132,7 @@ export default {
     },
     async getMarks () {
       const res = await getMarkAll({ sid: this.$route.query.sid })
-      console.log(res);
+
       const data = res.data
       this.sName = data.sName
       this.uKaiPosition = data.uKaiPosition
@@ -220,15 +226,83 @@ export default {
       this.supplier = supplier
 
     },
-    handleDownloadExcel () {
+    async getQuoteScore () {
+      const res = await getQuoteScore({ sid: this.$route.query.sid })
+      if (!res.data) {
+        return
+      }
+      this.quoteScore = res.data
+
+    },
+    async getTotal () {
+      const res = await getTotal({ sid: this.$route.query.sid })
+      if (!res.data) {
+        return
+      }
+      const data = res.data
+      let ZjNames = []
+      for (let i = 0; i < data.length; i++) {
+        const item = data[i]
+        const techList = item.techList
+
+
+        const techListLength = techList.length
+        if (techListLength < 5) {
+          for (let j = 0; j < 5 - techListLength; j++) {
+            techList.push({ score: '', jName: '' })
+          }
+        }
+        if (i == 0) {
+          ZjNames = techList.map(tech => tech.jName)
+        }
+      }
+      this.totalScore = data
+      this.ZjNames = ZjNames
+    },
+    async handleDownloadExcel () {
+      var zip = new JSZip();
+      await this.genPingshenExcel(zip)
+      await this.genScoreExcel(zip)
+      zip.generateAsync({ type: "blob" }).then(function (content) {
+        // see FileSaver.js
+        saveAs(content, "专家评审表.zip");
+      })
+    },
+    async genScoreExcel (zip) {
+      const workbook = new ExcelJS.Workbook()
+      const quoteScore = this.quoteScore
+      const quoteScoreLength = quoteScore.length
+      if (quoteScoreLength < 6) {
+        for (let i = 0; i < 6 - quoteScoreLength; i++) {
+          quoteScore.push({})
+        }
+      }
+
+      genBidScoreExcel(workbook, quoteScore)
+
+      const totalScore = this.totalScore
+      const totalScoreLength = totalScore.length
+      if (totalScore < 6) {
+        for (let i = 0; i < 6 - totalScoreLength; i++) {
+          totalScore.push({})
+        }
+      }
+
+      const zjNames = this.ZjNames
+      genTotalScoreExcel(workbook, totalScore, zjNames)
+
+      const buffer = await workbook.xlsx.writeBuffer();
+
+      //saveAs(new Blob([buffer], { type: 'application/octet-stream' }), "得分表.xlsx");
+      zip.file(`得分表.xlsx`, new Blob([buffer], { type: 'application/octet-stream' }));
+    },
+    async genPingshenExcel (zip) {
       const sName = this.sName
       const uKaiPosition = this.uKaiPosition
       const uKaiTime = this.uKaiTime
       const supplier = this.supplier
       const hNamesKeys = Object.keys(supplier)
-
-      for (let i = 0; i < hNamesKeys.length; i++) {
-        const hNameKey = hNamesKeys[i]
+      for (let hNameKey of hNamesKeys) {
         const workbook = new ExcelJS.Workbook()
         const expertExamines = supplier[hNameKey].bidExpertExamines
         genExamineExcel(workbook, sName, uKaiTime, uKaiPosition, hNameKey, expertExamines)
@@ -240,13 +314,11 @@ export default {
           const tech = expertTeches[jNameKey]
           genTechExcel(workbook, sName, uKaiTime, uKaiPosition, hNameKey, tech, jNameKey + '-技术标')
         }
-        workbook.xlsx.writeBuffer().then(buffer => {
-          saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `专家评审表-${hNameKey}.xlsx`)
-        })
-
-
+        const buffer = await workbook.xlsx.writeBuffer();
+        zip.file(`专家评审表-${hNameKey}.xlsx`, new Blob([buffer], { type: 'application/octet-stream' }));
       }
     },
+
     /** 上传专家签到表 */
     handleUploadSSign (fileList) {
       this.form.sSign = JSON.stringify(fileList);

+ 2 - 2
ruoyi-ui/src/views/tender/tender1/components/CompExpert.vue

@@ -67,8 +67,8 @@
         <el-table-column v-if="checkRole(['operator', 'commander'])" label="操作" align="center"
           class-name="small-padding fixed-width">
           <template slot-scope="scope">
-            <el-button v-if="scope.row.isLeader != 1" size="mini" type="text" icon="el-icon-delete"
-              @click="handleSetLeader(scope.row)">选为组长</el-button>
+            <el-button v-if="scope.row.status == '1' && scope.row.isLeader != 1" size="mini" type="text"
+              icon="el-icon-delete" @click="handleSetLeader(scope.row)">选为组长</el-button>
             <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
           </template>
         </el-table-column>