zzs 3 months ago
parent
commit
686c602902

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

@@ -35,3 +35,19 @@ export function getTotal(params) {
     params,
   });
 }
+
+export function getIdea(params) {
+  return request({
+    url: "/bidding/idea/selectIdeaBySid",
+    method: "get",
+    params,
+  });
+}
+
+export function getIdeas(params) {
+  return request({
+    url: "/bidding/idea/list",
+    method: "get",
+    params,
+  });
+}

+ 113 - 34
ruoyi-ui/src/utils/markExcel.js

@@ -94,9 +94,9 @@ export const genExamineExcel = (
   for (let i = 0; i < tableData.length; i++) {
     const data = [
       i + 1,
-      tableData[i].content,
-      tableData[i].standard,
-      tableData[i].isOk,
+      tableData[i].content || "",
+      tableData[i].standard || "",
+      tableData[i].isOk || "",
     ];
     for (let j = 0; j < data.length; j++) {
       const td = tbody[j];
@@ -280,9 +280,9 @@ export const genRespondExcel = (
   for (let i = 0; i < tableData.length; i++) {
     const data = [
       i + 1,
-      tableData[i].content,
-      tableData[i].standard,
-      tableData[i].isOk,
+      tableData[i].content || "",
+      tableData[i].standard || "",
+      tableData[i].isOk || "",
     ];
     for (let j = 0; j < data.length; j++) {
       const td = tbody[j];
@@ -479,11 +479,11 @@ export const genTechExcel = (
   for (let i = 0; i < tableData.length; i++) {
     const data = [
       i + 1,
-      tableData[i].content,
-      tableData[i].value,
-      tableData[i].standard,
-      tableData[i].score,
-      tableData[i].reason,
+      tableData[i].content || "",
+      tableData[i].value || "",
+      tableData[i].standard || "",
+      tableData[i].score || "",
+      tableData[i].reason || "",
     ];
     for (let j = 0; j < data.length; j++) {
       const td = tbody[j];
@@ -575,7 +575,7 @@ export const genTechExcel = (
  * @param {*} workbook ExcelJs对象
  * @param {*} tableData 数据
  */
-export const genBidScoreExcel = (workbook, tableData) => {
+export const genBidScoreExcel = (workbook, tableData, materialId) => {
   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++) {
@@ -630,11 +630,11 @@ export const genBidScoreExcel = (workbook, tableData) => {
   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,
+      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];
@@ -666,20 +666,27 @@ export const genBidScoreExcel = (workbook, tableData) => {
     vertical: "middle",
     wrapText: true,
   };
+
+  const materialIds = [39, 40, 41, 42];
+  let text = "";
+  if (materialIds.indexOf(materialId) != -1) {
+    text = `投标报价:
+其中价格分统一采用低价优先法计算,即满足招标文件要求且投标价格
+最低的投标报价为评标基准价,其价格分为满分 10 分,其他投标人的价
+格分统一按下列公式计算:
+投标报价得分=(评标基准价/投标报价)×10%×100`;
+  } else {
+    text = `投标报价:
+其中价格分统一采用低价优先法计算,即满足招标文件要求且投标价格
+最低的投标报价为评标基准价,其价格分为满分 30 分,其他投标人的价
+格分统一按下列公式计算:
+投标报价得分=(评标基准价/投标报价)×30%×100`;
+  }
   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%`,
+        text: text,
       },
     ],
   };
@@ -829,17 +836,17 @@ export const genTotalScoreExcel = (workbook, tableData, zjNames) => {
 
   let zhongbiaoren = "";
   for (let i = 0; i < tableData.length; i++) {
-    const techList = tableData[i].techList;
-    const data = [i + 1, tableData[i].hName];
+    const techList = tableData[i].techList || "";
+    const data = [i + 1, tableData[i].hName] || "";
     if (i == 0) {
-      zhongbiaoren = tableData[i].hName;
+      zhongbiaoren = tableData[i].hName || "";
     }
     for (let j = 0; j < techList.length; j++) {
-      data.push(techList[j].score);
+      data.push(techList[j].score || "");
     }
-    data.push(tableData[i].averScore);
-    data.push(tableData[i].priceScore);
-    data.push(tableData[i].totalScore);
+    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];
@@ -910,3 +917,75 @@ export const genTotalScoreExcel = (workbook, tableData, zjNames) => {
   rowLast.height = 28;
   rowLast.font = { name: "宋体", family: 4, size: 12 };
 };
+
+/**
+ * 得分汇总
+ * @param {*} workbook ExcelJs对象
+ * @param {*} tableData 数据
+ */
+export const genIdeaExcel = (
+  workbook,
+  sName,
+  kaibiaoTime,
+  kaibiaoAddress,
+  idea
+) => {
+  const worksheet = workbook.addWorksheet("评委意见表");
+  const columnWidth = [40.97, 39.63];
+  for (let cw = 1; cw <= columnWidth.length; cw++) {
+    worksheet.getColumn(cw).width = columnWidth[cw - 1] + 0.62;
+  }
+  worksheet.addRow(["评委评价意见表"]);
+  worksheet.mergeCells("A1:B1");
+  worksheet.getCell("A1").alignment = {
+    vertical: "middle",
+    horizontal: "center",
+  };
+  const row1 = worksheet.getRow(1);
+  row1.height = 45;
+  row1.font = { name: "宋体", family: 4, size: 14, bold: true };
+
+  worksheet.addRow([`项目名称:${sName}`]);
+  worksheet.mergeCells("A2:B2");
+  worksheet.getCell("A2").alignment = { vertical: "middle" };
+  const row2 = worksheet.getRow(2);
+  row2.height = 28;
+  row2.font = { name: "宋体", family: 4, size: 10 };
+
+  worksheet.addRow([
+    `开标时间:${dayjs(kaibiaoTime).format("YYYY年MM月DD日HH时mm分")}`,
+  ]);
+
+  worksheet.getCell("A3").alignment = { vertical: "middle" };
+  const row3 = worksheet.getRow(3);
+  row3.height = 28;
+  row3.font = { name: "宋体", family: 4, size: 10 };
+
+  worksheet.addRow([`开标地点:${kaibiaoAddress}`]);
+  worksheet.mergeCells("A4:B4");
+  worksheet.getCell("A4").alignment = { vertical: "middle" };
+  const row4 = worksheet.getRow(4);
+  row4.height = 28;
+  row4.font = { name: "宋体", family: 4, size: 10 };
+
+  let value = "";
+  const alignment = { vertical: "top" };
+  console.log({ idea });
+  if (idea) {
+    value = {
+      richText: [{ font: { name: "宋体", family: 4, size: 10 }, text: idea }],
+    };
+  }
+  worksheet.mergeCells("A5:B5");
+  worksheet.getCell(`A5`).alignment = alignment;
+  worksheet.getCell(`A5`).value = value;
+  const row5 = worksheet.getRow(5);
+  row5.height = 521.3;
+
+  worksheet.addRow(["评审小组成员签字:"]);
+  worksheet.mergeCells(`A6:B6`);
+  worksheet.getCell(`A6`).alignment = { vertical: "middle" };
+  const rowLast = worksheet.getRow(6);
+  rowLast.height = 36.75;
+  rowLast.font = { name: "宋体", family: 4, size: 10 };
+};

+ 28 - 5
ruoyi-ui/src/views/expert/tender/components/excelContent.vue

@@ -34,7 +34,12 @@
         </template>
       </el-descriptions-item>
     </el-descriptions>
-
+    <div class="margin-top">
+      <span class="describe">专家意见</span>
+      <div v-if="!isEdit" class="pre-text">{{ idea }}</div>
+      <el-input v-else type="textarea" :autosize="{ minRows: 2, maxRows: 6 }" placeholder="请输入专家意见" v-model="idea">
+      </el-input>
+    </div>
     <div class="margin-top">
       <span class="describe">资格审查表</span>
 
@@ -149,17 +154,18 @@
         <el-button v-if="isLeader && xiangyingList.length > 0" type="primary" plain
           @click="handleDownloadRespond">下载响应性审查表</el-button>
         <el-button v-if="jishuList.length > 0" type="primary" plain @click="handleDownloadTech">下载技术审查表</el-button>
+        <el-button v-if="jishuList.length > 0" type="primary" plain @click="handleDownloadIdea">下载专家意见表</el-button>
       </div>
     </div>
   </div>
 </template>
 
 <script>
-import { getMark, addMark } from '@/api/mark/mark'
+import { getMark, addMark, getIdea } from '@/api/mark/mark'
 import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
 import ExcelJS from 'exceljs'
 import { saveAs } from 'file-saver'
-import { genExamineExcel, genRespondExcel, genTechExcel } from '@/utils/markExcel'
+import { genExamineExcel, genRespondExcel, genTechExcel, genIdeaExcel } from '@/utils/markExcel'
 import dayjs from 'dayjs'
 export default {
   name: 'excelContent',
@@ -190,6 +196,7 @@ export default {
       isLeader: false,
       isEdit: false,
       // 资格审查表
+      idea: '',
       zigeList: [],
       // 响应审查表
       xiangyingList: [],
@@ -269,10 +276,17 @@ export default {
           this.excelForm.uKaiPosition = response.data.uKaiPosition;
         }
       })
+
+      getIdea({ sid: this.tender.sid, hid: this.hid }).then(response => {
+        this.idea = response?.data?.idea || ''
+      })
     },
 
     handleSave () {
-
+      if (this.isLeader && !this.idea) {
+        this.$message.error('请填写专家意见')
+        return
+      }
       for (let item of this.jishuList) {
         if (item.value != item.score) {
           if (!item.reason) {
@@ -315,7 +329,9 @@ export default {
         }
       })
       const formData = {
-
+        sid: this.tender.sid,
+        idea: this.idea,
+        hid: this.hid,
         bidExpertExamines: bidExpertExamines,
         bidExpertTeches: bidExpertTeches,
         bidExpertResponds: bidExpertResponds
@@ -352,6 +368,13 @@ export default {
       workbook.xlsx.writeBuffer().then(buffer => {
         saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `技术审查表-${this.hName}.xlsx`)
       })
+    },
+    handleDownloadIdea () {
+      const workbook = new ExcelJS.Workbook()
+      genIdeaExcel(workbook, this.tender.sName, this.excelForm.kaibiaoTime, this.excelForm.kaibiaoAddress, this.hName, this.idea)
+      workbook.xlsx.writeBuffer().then(buffer => {
+        saveAs(new Blob([buffer], { type: 'application/octet-stream' }), `专家意见-${this.hName}.xlsx`)
+      })
     }
   }
 }

+ 6 - 5
ruoyi-ui/src/views/tender/tender1/bidding.vue

@@ -94,7 +94,7 @@
     <div v-if="currentName === '评标'" class="div2">
       <el-tabs v-model="activeName3">
         <el-tab-pane label="评标" name="bidEval" style="font-size: 16px">
-          <CompEval v-if="tender && tender.sid" :tender="tender"></CompEval>
+          <CompEval v-if="tender && tender.sid && plan.materielType" :tender="tender" :plan="plan"></CompEval>
         </el-tab-pane>
       </el-tabs>
     </div>
@@ -231,7 +231,7 @@ export default {
     checkPermi,
     changeStep (stepIndex) {
       const sProjectState = this.tender.sProjectState
-      console.log(sProjectState, 'sProjectState');
+
       const currentName = this.step[stepIndex].name
       if (currentName == '招标') {
         this.currentStep = stepIndex;
@@ -280,9 +280,10 @@ export default {
       const caigou = await getPlanProfileByAid(res1.data.aid)
       this.caigou = caigou.data
 
-      getMateriel(this.plan.materialId).then(resMateriel => {
-        this.plan.materialName = resMateriel.data.materielName
-      })
+      const resMateriel = await getMateriel(this.plan.materialId)
+      this.plan.materialName = resMateriel.data.materielName
+      this.plan.materielType = resMateriel.data.materielType
+
 
       if (data2) {
         this.detail.firstTime = data2.uKaiTime

+ 54 - 37
ruoyi-ui/src/views/tender/tender1/components/CompEval.vue

@@ -53,11 +53,11 @@
 <script>
 import { updateTender, getTender } from '@/api/system/tender/tender'
 import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
-import { getMarkAll, getQuoteScore, getTotal } from '@/api/mark/mark'
+import { getMarkAll, getQuoteScore, getTotal, getIdeas } from '@/api/mark/mark'
 import ExcelJS from 'exceljs'
 import JSZip from 'jszip'
 import { saveAs } from 'file-saver'
-import { genExamineExcel, genRespondExcel, genTechExcel, genBidScoreExcel, genTotalScoreExcel } from '@/utils/markExcel'
+import { genExamineExcel, genRespondExcel, genTechExcel, genBidScoreExcel, genTotalScoreExcel, genIdeaExcel } from '@/utils/markExcel'
 export default {
   name: "Candidate",
   props: {
@@ -65,6 +65,10 @@ export default {
       type: Object,
       default: () => { }
     },
+    plan: {
+      type: Object,
+      default: () => { }
+    },
   },
   data () {
     return {
@@ -89,6 +93,7 @@ export default {
       sName: '',
       uKaiPosition: '',
       uKaiTime: '',
+      ideas: [],
       quoteScore: [],
       totalScore: [],
       ZjNames: []
@@ -98,10 +103,12 @@ export default {
     const tender = this.tender
     this.form.sid = tender.sid;
     this.form.sSign = tender.sSign;
+
     this.getData()
     this.getMarks()
     this.getQuoteScore()
     this.getTotal()
+    this.getIdea()
   },
   methods: {
     checkRole,
@@ -181,50 +188,56 @@ export default {
       }
 
 
-
       const supplier = {}
       for (let item of bidExpertExamines) {
-        if (supplier[item.hName]) {
-          if (supplier[item.hName]['bidExpertExamines']) {
-            supplier[item.hName]['bidExpertExamines'].push(item)
-          } else {
-            supplier[item.hName]['bidExpertExamines'] = [item]
+        if (!supplier[item.hid]) {
+          supplier[item.hid] = {
+            hName: item.hName,
           }
+        }
+        if (!supplier[item.hid]['bidExpertExamines']) {
+          supplier[item.hid]['bidExpertExamines'] = [item]
         } else {
-          supplier[item.hName] = {
-            'bidExpertExamines': [item]
-          }
+          supplier[item.hid]['bidExpertExamines'].push(item)
         }
       }
       for (let item of bidExpertResponds) {
-        if (supplier[item.hName]) {
-          if (supplier[item.hName]['bidExpertResponds']) {
-            supplier[item.hName]['bidExpertResponds'].push(item)
-          } else {
-            supplier[item.hName]['bidExpertResponds'] = [item]
+        if (!supplier[item.hid]) {
+          supplier[item.hid] = {
+            hName: item.hName,
           }
+        }
+        if (!supplier[item.hid]['bidExpertResponds']) {
+          supplier[item.hid]['bidExpertResponds'] = [item]
         } else {
-          supplier[item.hName] = {
-            'bidExpertResponds': [item]
-          }
+          supplier[item.hid]['bidExpertResponds'].push(item)
         }
       }
 
       for (let item of bidExpertTeches) {
-        if (!supplier[item.hName]) {
-          supplier[item.hName] = {}
+
+        if (!supplier[item.hid]) {
+          supplier[item.hid] = {
+            hName: item.hName,
+          }
         }
-        if (!supplier[item.hName]['bidExpertTeches']) {
-          supplier[item.hName]['bidExpertTeches'] = {}
+        if (!supplier[item.hid]['bidExpertTeches']) {
+          supplier[item.hid]['bidExpertTeches'] = {}
         }
-        if (!supplier[item.hName]['bidExpertTeches'][item.jName]) {
-          supplier[item.hName]['bidExpertTeches'][item.jName] = [item]
+        if (!supplier[item.hid]['bidExpertTeches'][item.jName]) {
+          supplier[item.hid]['bidExpertTeches'][item.jName] = [item]
         } else {
-          supplier[item.hName]['bidExpertTeches'][item.jName].push(item)
+          supplier[item.hid]['bidExpertTeches'][item.jName].push(item)
         }
+
       }
       this.supplier = supplier
-
+      console.log(supplier);
+    },
+    async getIdea () {
+      const res = await getIdeas({ sid: this.$route.query.sid })
+      this.ideas = res.data || []
+      console.log(res.data);
     },
     async getQuoteScore () {
       const res = await getQuoteScore({ sid: this.$route.query.sid })
@@ -265,6 +278,7 @@ export default {
     },
     async genScoreExcel (zip) {
       const workbook = new ExcelJS.Workbook()
+
       const quoteScore = this.quoteScore
       const quoteScoreLength = quoteScore.length
       if (quoteScoreLength < 6) {
@@ -273,7 +287,7 @@ export default {
         }
       }
 
-      genBidScoreExcel(workbook, quoteScore)
+      genBidScoreExcel(workbook, quoteScore, this.plan.materialId)
 
       const totalScore = this.totalScore
       const totalScoreLength = totalScore.length
@@ -296,21 +310,24 @@ export default {
       const uKaiPosition = this.uKaiPosition
       const uKaiTime = this.uKaiTime
       const supplier = this.supplier
-      const hNamesKeys = Object.keys(supplier)
-      for (let hNameKey of hNamesKeys) {
+      const hHidKeys = Object.keys(supplier)
+      for (let hidKey of hHidKeys) {
+        const hName = supplier[hidKey].hName
         const workbook = new ExcelJS.Workbook()
-        const expertExamines = supplier[hNameKey].bidExpertExamines
-        genExamineExcel(workbook, sName, uKaiTime, uKaiPosition, hNameKey, expertExamines)
-        const expertResponds = supplier[hNameKey].bidExpertResponds
-        genRespondExcel(workbook, sName, uKaiTime, uKaiPosition, hNameKey, expertResponds)
-        const expertTeches = supplier[hNameKey].bidExpertTeches
+        const idea = this.ideas.find(item => item.hid == hidKey)
+        genIdeaExcel(workbook, sName, uKaiTime, uKaiPosition, idea?.idea)
+        const expertExamines = supplier[hidKey].bidExpertExamines
+        genExamineExcel(workbook, sName, uKaiTime, uKaiPosition, hName, expertExamines)
+        const expertResponds = supplier[hidKey].bidExpertResponds
+        genRespondExcel(workbook, sName, uKaiTime, uKaiPosition, hName, expertResponds)
+        const expertTeches = supplier[hidKey].bidExpertTeches
         const jNamesKeys = Object.keys(expertTeches)
         for (let jNameKey of jNamesKeys) {
           const tech = expertTeches[jNameKey]
-          genTechExcel(workbook, sName, uKaiTime, uKaiPosition, hNameKey, tech, jNameKey + '-技术标')
+          genTechExcel(workbook, sName, uKaiTime, uKaiPosition, hName, tech, jNameKey + '-技术标')
         }
         const buffer = await workbook.xlsx.writeBuffer();
-        zip.file(`专家评审表-${hNameKey}.xlsx`, new Blob([buffer], { type: 'application/octet-stream' }));
+        zip.file(`专家评审表-${hName}.xlsx`, new Blob([buffer], { type: 'application/octet-stream' }));
       }
     },