Преглед на файлове

task-7121 检验过程管理-室内质量控制-室内质控月分析总结报告调整

tianxinyu преди 1 ден
родител
ревизия
b3bd7ac964
променени са 1 файла, в които са добавени 518 реда и са изтрити 0 реда
  1. 518 0
      src/views/component/qualityControl/indexHuaChuang.vue

+ 518 - 0
src/views/component/qualityControl/indexHuaChuang.vue

@@ -0,0 +1,518 @@
+<template>
+  <div class="qualityControl">
+    <div v-if="!readonly && shiFouGuoShen" class="btn">
+      <el-button icon="ibps-icon-edit" @click="onCopy">复制</el-button>
+      <el-button type="success" icon="ibps-icon-plus" @click="onAddClick"
+        >添加</el-button
+      >
+      <el-button type="danger" icon="ibps-icon-close" @click="onRemoveClick"
+        >删除</el-button
+      >
+      <el-button icon="ibps-icon-import" @click="onImportClick">导入</el-button>
+      <el-button icon="ibps-icon-export" @click="onExportClick">导出</el-button>
+    </div>
+    <div class="table">
+      <el-table
+        :data="showPaperList"
+        border
+        @selection-change="handleSelectionChange"
+      >
+        <el-table-column type="selection" />
+        <el-table-column label="序号" width="50">
+          <template slot-scope="{ row, $index }">
+            {{ (currentPage - 1) * pageSize + $index + 1 }}</template
+          >
+        </el-table-column>
+        <el-table-column label="项目名称" prop="xiangMu" width="160" />
+        <el-table-column label="设备编号" prop="sheBeiBianHao" width="160" />
+        <el-table-column label="设备名称" prop="sheBeiMingCheng" width="160" />
+       
+        <!-- <el-table-column label="质控批号" prop="zhiKongPinPiHao" width="100" /> -->
+        <!-- <el-table-column
+          label="批号开始时间"
+          prop="piHaoKaiShiShiJia"
+          width="100"
+        /> -->
+        <el-table-column label="单位" prop="zhiKongTuDanWei" />
+        <el-table-column label="设定质控图数据">
+          <el-table-column label="水平" prop="zhiKongTuShuiPing" />
+          <el-table-column label="均值" prop="zhiKongTuJunZhi" />
+          <el-table-column label="SD" prop="zhiKongTuSd" />
+          <el-table-column label="CV%" prop="zhiKongTuCv" />
+        </el-table-column>
+        <el-table-column label="当月原始测定数据统计">
+          <el-table-column label="均值" prop="yuanShiJunZhi" />
+          <el-table-column label="SD" prop="yuanShiSd" />
+          <el-table-column label="CV%" prop="yuanShiCv" />
+          <el-table-column label="测定数" prop="yuanShiN" />
+          <el-table-column label="失控数" prop="shiKongShu" />
+          <el-table-column label="失控率%" prop="shiKongLv" />
+        </el-table-column>
+        <el-table-column label="当月在控数据统计">
+          <el-table-column label="均值" prop="chuJunZhi" />
+          <el-table-column label="SD" prop="chuSd" />
+          <el-table-column label="CV%" prop="chuCv" />
+        </el-table-column>
+        <el-table-column label="累积质控数据统计">
+          <el-table-column label="均值" prop="leiJunZhi" />
+          <el-table-column label="SD" prop="leiSd" />
+          <el-table-column label="CV%" prop="leiCv" />
+          <el-table-column label="测定数" prop="leiN" />
+          <!-- <el-table-column label="在控率%" prop="zaiKongLv" /> -->
+        </el-table-column>
+        <!-- <el-table-column label="CV%控制范围">
+          <el-table-column label="%" prop="cvKongZhiFanWei" />
+        </el-table-column> -->
+        <el-table-column label="允许不精密度(%)" prop="buJingMiDu" />
+        <el-table-column label="允许总误差(%)" prop="zongWuCha" />
+        <el-table-column label="是否合格" prop="shiFouHeGe" />
+        <el-table-column
+          v-if="!readonly && shiFouGuoShen"
+          label="操作栏位"
+          fixed="right"
+        >
+          <template slot-scope="{ row, $index }">
+            <el-button
+              type="text"
+              icon="ibps-icon-edit"
+              @click="onEditClick(row, $index)"
+              >编辑</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        style="margin-top: 5px; padding-bottom: 10px"
+        :current-page="currentPage"
+        :page-sizes="[10, 15, 20, 30, 50, 100]"
+        :page-size="pageSize"
+        layout="total,sizes,prev,pager,next"
+        :total="tableData.length"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+    <input
+      id=""
+      ref="file1"
+      style="display: none"
+      type="file"
+      name=""
+      accept=".xlsx,.xls"
+      @change="handleUploadChange1"
+    />
+  </div>
+</template>
+
+<script>
+import { cloneDeep } from 'lodash'
+import xlsx from 'xlsx'
+import fs from 'file-saver'
+import dayjs from 'dayjs'
+export default {
+  props: {
+    formData: {
+      type: Object,
+      default: () => {}
+    },
+    params: {
+      type: Object,
+      default: () => {}
+    },
+    readonly: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      tableData: [],
+      multipleSelection: [],
+      pageSize: 10,
+      currentPage: 1,
+      columns: {
+        xiangMu: '项目名称',
+        sheBeiBianHao: '设备编号',
+        sheBeiMingCheng: '设备名称',
+        
+        // zhiKongPinPiHao: '质控批号',
+        // piHaoKaiShiShiJia: '批号开始时间',
+        // zhiKongChangJia: '质控品厂家',
+        // shiKongGuiZe: '失控规则',
+
+        zhiKongTuDanWei: '单位',
+        zhiKongTuShuiPing: '设定质控图数据水平',
+        zhiKongTuJunZhi: '设定质控图数据均值',
+        zhiKongTuSd: '设定质控图数据SD',
+        zhiKongTuCv: '设定质控图数据CV%',
+
+        yuanShiJunZhi: '当月原始测定数据统计均值',
+        yuanShiSd: '当月原始测定数据统计SD',
+        yuanShiCv: '当月原始测定数据统计CV%',
+        yuanShiN: '当月原始测定数据统计测定数',
+        shiKongShu: '当月原始测定数据统计失控数',
+        shiKongLv: '当月原始测定数据统计失控率%',
+
+        chuJunZhi: '当月在控数据统计均值',
+        chuSd: '当月在控数据统计SD',
+        chuCv: '当月在控数据统计CV%',
+
+        leiJunZhi: '累积质控数据统计均值',
+        leiSd: '累积质控数据统计SD',
+        leiCv: '累积质控数据统计CV%',
+        leiN: '累积质控数据统计测定数',
+
+        buJingMiDu: '允许不精密度(%)',
+        zongWuCha: '允许总误差(%)',
+        shiFouHeGe: '是否合格'
+      }
+    }
+  },
+  computed: {
+    // 分页结果
+    showPaperList() {
+      const start = (this.currentPage - 1) * this.pageSize
+      const end = start + this.pageSize
+      return this.tableData.slice(start, end)
+    },
+    shiFouGuoShen() {
+      if (
+        !this.formData.shiFouGuoShen ||
+        this.formData.shiFouGuoShen === '已退回' ||
+        this.formData.shiFouGuoShen === '已暂存' ||
+        this.formData.shiFouGuoShen === '待编制'
+      ) {
+        return true
+      }
+      return false
+    }
+  },
+  watch: {
+    'formData.dlxmsnzkyfxzb': {
+      handler(val) {
+        if (
+          (val && val.length) ||
+          (Array.prototype.isPrototypeOf(val) && val.length === 0)
+        ) {
+          // console.log(this.formData)
+          this.tableData = val
+        }
+      },
+      immediate: true
+    },
+    tableData: {
+      handler(val) {
+        this.$emit('change-data', 'dlxmsnzkyfxzb', val)
+      },
+      deep: true
+    }
+  },
+
+  methods: {
+    onCopy() {
+      if (this.multipleSelection.length > 0) {
+        this.tableData = this.tableData.concat(
+          cloneDeep(this.multipleSelection)
+        )
+      } else {
+        this.$message.warning('请选择数据')
+      }
+    },
+    xlsx(json, fields, filename = '.xlsx') {
+      // 导出xlsx
+      json.forEach((item) => {
+        for (const i in item) {
+          if (fields.hasOwnProperty(i)) {
+            item[fields[i]] = item[i]
+          }
+          delete item[i] // 删除原先的对象属性
+        }
+      })
+      const sheetName = filename // excel的文件名称
+      const wb = xlsx.utils.book_new() // 工作簿对象包含一SheetNames数组,以及一个表对象映射表名称到表对象。XLSX.utils.book_new实用函数创建一个新的工作簿对象。
+      const ws = xlsx.utils.json_to_sheet(json, {
+        header: Object.values(fields)
+      }) // 将JS对象数组转换为工作表。
+      wb.SheetNames.push(sheetName)
+      wb.Sheets[sheetName] = ws
+      const defaultCellStyle = {
+        font: { name: 'Verdana', sz: 13, color: 'FF00FF88' },
+        fill: { fgColor: { rgb: 'FFFFAA00' } }
+      } // 设置表格的样式
+      const wopts = {
+        bookType: 'xlsx',
+        bookSST: false,
+        type: 'binary',
+        cellStyles: true,
+        defaultCellStyle: defaultCellStyle,
+        showGridLines: false
+      } // 写入的样式
+      const wbout = xlsx.write(wb, wopts)
+      const blob = new Blob([this.s2ab(wbout)], {
+        type: 'application/octet-stream'
+      })
+      fs.saveAs(blob, filename + '.xlsx')
+    },
+    s2ab(s) {
+      let buf
+      if (typeof ArrayBuffer !== 'undefined') {
+        buf = new ArrayBuffer(s.length)
+        const view = new Uint8Array(buf)
+        for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
+        return buf
+      } else {
+        buf = new Array(s.length)
+        for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff
+        return buf
+      }
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val
+    },
+    onAddClick() {
+      const btn = document.querySelector('.dynamic-form-table .ibps-icon-add')
+      btn.click()
+    },
+    onImportClick() {
+      // const btn = document.querySelector('.dynamic-form-table .ibps-icon-import')
+      // btn.click()
+      this.$refs.file1.click()
+      console.log('导入')
+    },
+    /* 读取文件 将文件转换为二进制 */
+    readFile(file) {
+      return new Promise((resolve) => {
+        const reader = new FileReader()
+        reader.readAsBinaryString(file)
+        reader.onload = (ev) => {
+          resolve(ev.target.result)
+        }
+      })
+    },
+    // 转换对象的key
+    switchDeviceObj(data, originalObj) {
+      const result = []
+      data.forEach((item) => {
+        const obj = {}
+        for (const key in originalObj) {
+          // 对日期格式的数据做兼容处理
+          if (item[originalObj[key]] instanceof Date) {
+            obj[key] =
+              dayjs(item[originalObj[key]])
+                .add(8, 'hour')
+                .format('YYYY-MM-DD') || ''
+          } else {
+            obj[key] = String(item[originalObj[key]] || '')
+          }
+        }
+        result.push(obj)
+      })
+      return result
+    },
+    async switchSheBeiToName(list) {
+      // const sql = `select id_, jian_yan_xiang_mu, she_bei_ming_cheng_ from t_sbdj where find_in_set('yuan_she_bei_bian', 'list.map(item => item.sheBeiBianHao).join(',')') = `
+      // const sql = `select id_, yuan_she_bei_bian, she_bei_ming_cheng_ from t_sbdj where find_in_set('yuan_she_bei_bian', 'list.map(item => item.sheBeiBianHao).join(',')')`
+      let names = list.map(item => item.sheBeiBianHao).join(',')
+      const { variables: { data = {} } = {} } = await this.$common.request(
+        'query',
+        {
+          key: 'gjsbbhhqdysbxx',
+          params: [names]
+        }
+      )
+      for (let i = 0; i < list.length; i++) {
+        const row = list[i]
+        const t = data.find(
+          (item) => item.yuan_she_bei_bian.trim() === row.sheBeiBianHao.trim()
+        )
+        let newName = t?.she_bei_ming_cheng_ || ''
+        // row.sheBeiMingCheng = t?.she_bei_ming_cheng_ || ''
+        if(!newName || row.sheBeiMingCheng != newName){
+          throw new Error(`第${i + 1}行设备编号与设备名称不对应!`)
+        }
+        
+      }
+    },
+    async switchXmToId(list) {
+      // const sql = `select id_, jian_yan_xiang_mu from t_nlfwb`
+      const { variables: { data = {} } = {} } = await this.$common.request(
+        'query',
+        {
+          key: 'getNlfwbProject',
+          params: [null]
+        }
+      )
+      for (let i = 0; i < list.length; i++) {
+        const row = list[i]
+        const t = data.find(
+          (item) => item.jian_yan_xiang_mu.trim() === row.xiangMu.trim()
+        )
+        row.xuanZeXiangMu = t?.id_ || ''
+      }
+    },
+    checkDate(data) {
+      // 校验日期字段是否符合要求
+      const dateRegex = /^(\d{4})[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12]\d|3[01])$/
+      for (let i = 0; i < data.length; i++) {
+        const row = data[i]
+        if (row.piHaoKaiShiShiJia && !dateRegex.test(row.piHaoKaiShiShiJia)) {
+          throw new Error(`第${i + 1}行时间格式错误!`)
+        }
+      }
+    },
+    async handleUploadChange1(file) {
+      try {
+        const dataBinary = await this.readFile(file.target.files[0])
+        file.target.value = null // 注意上传后要将input的值设为空
+        const workBook = xlsx.read(dataBinary, {
+          type: 'binary',
+          cellDates: true
+        })
+        const workSheet = workBook.Sheets[workBook.SheetNames[0]]
+        const data = xlsx.utils.sheet_to_json(workSheet)
+        const importData = this.switchDeviceObj(data, this.columns)
+        // console.log(JSON.parse(JSON.stringify(importData)))
+        // this.checkDate(importData)
+        // await this.switchXmToId(importData)
+        await this.switchSheBeiToName(importData)
+        this.tableData.push(...importData)
+        // console.log(JSON.parse(JSON.stringify(this.tableData)))
+      } catch (error) {
+        this.$message.warning(error?.message || '导入失败')
+      }
+    },
+    getTimeStamp() {
+      return dayjs().format('YYYYMMDDHHmmss')
+    },
+    onExportClick() {
+      // const btn = document.querySelector('.dynamic-form-table .ibps-icon-export')
+      // btn.click()
+      const copyData = JSON.parse(JSON.stringify(this.tableData))
+      this.xlsx(
+        copyData,
+        this.columns,
+        '定量项目室内质控月分析表' + this.getTimeStamp()
+      )
+      this.$message.success('导出成功!')
+    },
+    onRemoveClick() {
+      if (this.multipleSelection.length === 0) {
+        return this.$message.warning('请先选择需要删除的数据!')
+      }
+      this.$confirm('是否确认删除所选项?', '提示', {
+        confirmButtonText: '确认',
+        cancelButtonText: '取消',
+        type: 'warning'
+      })
+        .then(() => {
+          this.tableData = this.tableData.filter(
+            (item) => !this.multipleSelection.includes(item)
+          )
+          this.currentPage = 1
+        })
+        .catch(() => {})
+    },
+    onEditClick(row, $index) {
+      const btns = document.querySelectorAll(
+        '.dynamic-form-table .ibps-icon-edit'
+      )
+      btns[Math.floor(btns.length / 2) + $index].click()
+    },
+
+    onPageClick(number) {
+      const btns = document.querySelectorAll(
+        '.dynamic-form-table .el-pager .number'
+      )
+      if (btns[0].innerText == this.currentPage) {
+        btns[0].click()
+      }
+      if (btns[1].innerText == this.currentPage) {
+        btns[1].click()
+      }
+      if (btns[2].innerText == this.currentPage) {
+        btns[2].click()
+      }
+      if (btns[3].innerText == this.currentPage) {
+        btns[3].click()
+      }
+      if (btns[4].innerText == this.currentPage) {
+        btns[4].click()
+      }
+      if (btns[5].innerText == this.currentPage) {
+        btns[5].click()
+      }
+      if (btns[6].innerText == this.currentPage) {
+        btns[6].click()
+      }
+
+      const butprev = document.querySelectorAll(
+        '.dynamic-form-table .el-pager .btn-quickprev'
+      )
+      if (
+        this.currentPage < Number(btns[1].innerText) &&
+        this.currentPage !== Number(btns[0].innerText)
+      ) {
+        butprev[0].click()
+      }
+      const butnext = document.querySelectorAll(
+        '.dynamic-form-table .el-pager .btn-quicknext'
+      )
+      if (
+        this.currentPage > Number(btns[5].innerText) &&
+        this.currentPage !== Number(btns[6].innerText)
+      ) {
+        butnext[0].click()
+      }
+    },
+    onSizeClick() {
+      const names = document.querySelectorAll(
+        '.dynamic-form-table .el-popper .el-select-dropdown__item'
+      )
+      if (names[0].innerText == this.pageSize + '条/页') {
+        names[0].click()
+      }
+      if (names[1].innerText == this.pageSize + '条/页') {
+        names[1].click()
+      }
+      if (names[2].innerText == this.pageSize + '条/页') {
+        names[2].click()
+      }
+      if (names[3].innerText == this.pageSize + '条/页') {
+        names[3].click()
+      }
+      if (names[4].innerText == this.pageSize + '条/页') {
+        names[4].click()
+      }
+      if (names[5].innerText == this.pageSize + '条/页') {
+        names[5].click()
+      }
+    },
+    // 当前页码改变
+    handleCurrentChange(val) {
+      this.currentPage = val
+      this.onPageClick()
+    },
+    // 页码选择器改变
+    handleSizeChange(val) {
+      this.pageSize = val
+      this.currentPage = 1
+      this.onSizeClick()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.qualityControl {
+  margin-top: 20px;
+  .btn {
+    padding: 0;
+    margin-bottom: 4px;
+    display: flex;
+    justify-content: flex-end;
+    .el-button + .el-button {
+      margin-left: 6px;
+    }
+  }
+}
+</style>