소스 검색

feat: 需求变更修改

sunxiao 5 달 전
부모
커밋
5fa6e22747

+ 8 - 0
src/api/report/lab.js

@@ -51,6 +51,14 @@ export function getContinuousAssayList (params) {
   })
 }
 
+export function getContinuousAssayListNew (params) {
+  return request({
+    url: '/business/continuousAssayCountByDatesNew',
+    method: 'get',
+    params
+  })
+}
+
 // 获取设备列表
 export function getDeviceList(params) {
   return request({

+ 2 - 2
src/views/report/components/RecordDrawer.vue

@@ -166,7 +166,7 @@ const onDrawerClosed = () => {
   <el-drawer
     class="record-drawer_view"
     v-model="drawerVisible"
-    title="实验室化验记录"
+    title="化验记录"
     direction="ltr"
     :size="1100"
     :before-close="handleClose"
@@ -186,7 +186,7 @@ const onDrawerClosed = () => {
             </el-col>
             <el-col :span="6">
               <el-card>
-                <p class="sub-title">设备编号</p>
+                <p class="sub-title">设备名称</p>
                 <p>{{ data.deviceNo }}</p>
               </el-card>
             </el-col>

+ 229 - 0
src/views/report/detection-month/index copy.vue

@@ -0,0 +1,229 @@
+<script setup>
+import { dayjs } from 'element-plus';
+import { getContinuousAssayListNew, getDeviceList } from '@/api/report/lab';
+
+const { proxy } = getCurrentInstance();
+
+const queryParams = ref({
+  pageNum: 1,
+  pageSize: 10,
+  deviceNo: '',
+  activeRadioName: 'daterange'
+});
+
+const tableLoading = ref(false);
+const loading = ref(false);
+
+const datePickerValue = ref([]);
+const tempDataValue = ref({timeBegin: dayjs(new Date()).startOf('week').format('YYYY') + '年'});
+
+const tableData = ref([]);
+const columns = ref([]);
+const options = ref([]);
+
+const dateBeforeSevenDays = computed(() => new Date(dayjs().subtract(7, 'day').format('YYYY-MM-DD')))
+
+const format = computed(() => {
+  return queryParams.value.activeRadioName === 'week' ? tempDataValue.value.timeBegin + ' 第 ww 周'  : 'YYYY-MM'
+})
+
+const label = computed(() => {
+  return queryParams.value.activeRadioName === 'week' ? '选择周' : '选择月'
+})
+
+const onChangeDatePicker = (value) => {
+  const timeBegin = dayjs(value).startOf('week').format('YYYY') + '年';
+  const timeEnd = dayjs(value).endOf('week').format('MM-DD');
+  
+  tempDataValue.value = { timeBegin, timeEnd };
+}
+
+const onRadioChange = () => {
+  datePickerValue.value = new Date();
+}
+
+const getStartTimeAndEndTime = () => {
+  const { activeRadioName } = queryParams.value;
+  const time = datePickerValue.value;
+  let timeBegin = '';
+  let timeEnd = '';
+  
+  if ( activeRadioName === 'daterange' ) {
+    if (time.length) {
+      const [ startTime, endTime ] = time;
+      timeBegin = dayjs(startTime).format('YYYY-MM-DD')
+      timeEnd = dayjs(endTime).format('YYYY-MM-DD')
+    }
+  } else {
+    timeBegin = dayjs(time).startOf('month').format('YYYY-MM-DD');
+    timeEnd = dayjs(time).endOf('month').format('YYYY-MM-DD');
+  }
+ 
+  return {
+    timeBegin,
+    timeEnd
+  }
+}
+
+const initPageData = async() => {
+  tableLoading.value = true;
+  loading.value = true;
+
+  const dateResult = getStartTimeAndEndTime();
+  const { data } = await getContinuousAssayListNew({...dateResult, deviceNo: queryParams.value.deviceNo});
+  console.log("data", data);
+  const whiteTableList = [
+    // { title: '检测指标', key: 'assayName' },
+    { title: '实际检测数量', key: 'assayCounts' },
+    { title: '最小值', key: 'minVal' },
+    { title: '最大值', key: 'maxVal' },
+    { title: '合格率(%)', key: 'passedRates' }, 
+    { title: '标线(%)', key: 'bx' },
+    { title: '合格率偏差', key: 'ratesDeviation' }
+  ]
+
+  const tempBodyObject = {};
+  const middleData = Object.entries(data).map(([key, value]) => {
+    const children = Object.entries(value).map(([k, v]) => {
+      const [child] = v;
+      tempBodyObject[key + '-' + k] = child;
+      return {
+        label: k, 
+        prop: key + '-' + k, 
+        width: 160
+      }
+    });
+    
+    return {
+      label: key === 'total' ? '' : key,
+      children
+    }
+  });
+  
+  if ( middleData.length ) {
+    columns.value = [{ label: '检测点位', fixed: "left", children: [{ label: '检测指标', prop: 'title', width: 150 }]}].concat(middleData);
+    tableData.value = whiteTableList.map(item => {
+      const { key } = item;
+      Object.entries(tempBodyObject).map(([k, v]) => {
+        item = {
+          ...item,
+          [k]: v[key]
+        }
+      })
+      return item;
+    });
+  } else {
+    columns.value = [];
+    tableData.value = []
+  }
+  tableLoading.value = false;
+  loading.value = false;
+}
+
+const handlerQuery = () => {
+  initPageData();
+}
+
+const handlerReset = () => {
+  const [ item ] = options.value;
+  datePickerValue.value = [dateBeforeSevenDays.value, new Date()];
+  queryParams.value.activeRadioName = 'daterange';
+  queryParams.value.deviceNo = item?.deviceNo || '';
+  initPageData();
+}
+
+const handleExport = () => {
+  const dateResult = getStartTimeAndEndTime();
+  proxy.getDownload("/business/exportContinuousAssayCountByDates", {
+    ...dateResult,
+    deviceNo: queryParams.value.deviceNo
+  }, `${new Date().getTime()}.xlsx`);
+}
+
+onMounted(async() => {
+
+  datePickerValue.value = [dateBeforeSevenDays.value, new Date()];
+
+  await getDeviceList({ type: 2 }).then(({ data }) => {
+    const [ item ] = data;
+    queryParams.value.deviceNo = item?.deviceNo || '';
+    options.value = data
+  });
+  
+  await initPageData();
+})
+</script>
+
+<template>
+  <div class="lab-day-viewport space-y-[10px]">
+    <el-card shadow="never" :body-style="{ border: '0px' }">
+      <template #header>
+        <p class="space-x-[10px]">
+          <span class="font-bold">数据筛选</span>
+        </p>
+      </template>
+      <el-row class="pt-[5px]" justify="space-between" :gutter="20">
+        <el-col :span="6">
+          <el-form-item label="设备名称">
+            <el-select v-model="queryParams.deviceNo" placeholder="请选择" filterable clearable>
+              <el-option v-for="item in options" :key="item.deviceNo" :label="item.deviceName" :value="item.deviceNo" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="14">
+          <div class="flex items-center space-x-[20px]">
+            <el-form-item label="统计时段">
+              <el-radio-group v-model="queryParams.activeRadioName" @change="onRadioChange">
+                <el-radio-button label="按周" value="daterange" />
+                <el-radio-button label="按月" value="month" />
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item>
+              <el-date-picker
+                v-model="datePickerValue"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                placeholder="请选择月份"
+                :type="queryParams.activeRadioName"
+                :editable="false"
+                :clearable="false"
+                style="max-width: 280px;"
+                @change="onChangeDatePicker"
+              />
+            </el-form-item>
+          </div>
+        </el-col>
+        <el-col :span="4">
+          <div class="flex justify-end">
+            <el-button type="primary" @click="handlerQuery" :loading="loading">查询</el-button>
+            <el-button @click="handlerReset" :loading="loading">重置</el-button>
+          </div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <el-card shadow="never" :body-style="{ padding: '20px' }">
+      <div class="flex justify-between items-center mb-[10px]">
+        <h4 class="font-bold">统计报表</h4>
+        <el-button
+          type="warning"
+          plain
+          icon="Download"
+          @click="handleExport"
+          :loading="loading"
+        >导出</el-button>
+      </div>
+      <el-table :data="tableData" style="width: 100%" v-loading="tableLoading">
+        <!-- <el-table-column prop="title" label="检测点位" width="160" fixed="left" header-align="center" /> -->
+        <el-table-column  :label="col.label" :width="col.width || 200" :fixed="col.fixed" align="center" v-for="col, index in columns">
+          <el-table-column :prop="child.prop" :label="child.label" :width="child.width" v-for="child in col.children"/>
+        </el-table-column>
+        <!-- <el-table-column prop="totalDeviationRate" label="总质控合格率" width="120" header-align="center" fixed="right" align="center"/> -->
+      </el-table>
+    </el-card>
+
+  </div>
+  
+</template>
+
+<style lang="scss" scoped></style>

+ 135 - 60
src/views/report/detection-month/index.vue

@@ -1,6 +1,7 @@
 <script setup>
-import { dayjs } from 'element-plus';
-import { getContinuousAssayList, getDeviceList } from '@/api/report/lab';
+import { h } from 'vue';
+import {  dayjs } from 'element-plus';
+import { getContinuousAssayListNew, getDeviceList } from '@/api/report/lab';
 
 const { proxy } = getCurrentInstance();
 
@@ -8,19 +9,21 @@ const queryParams = ref({
   pageNum: 1,
   pageSize: 10,
   deviceNo: '',
-  activeRadioName: 'week'
+  activeRadioName: 'daterange'
 });
 
 const tableLoading = ref(false);
 const loading = ref(false);
 
-const datePickerValue = ref(new Date());
+const datePickerValue = ref([]);
 const tempDataValue = ref({timeBegin: dayjs(new Date()).startOf('week').format('YYYY') + '年'});
 
 const tableData = ref([]);
 const columns = ref([]);
 const options = ref([]);
 
+const dateBeforeSevenDays = computed(() => new Date(dayjs().subtract(7, 'day').format('YYYY-MM-DD')))
+
 const format = computed(() => {
   return queryParams.value.activeRadioName === 'week' ? tempDataValue.value.timeBegin + ' 第 ww 周'  : 'YYYY-MM'
 })
@@ -42,65 +45,121 @@ const onRadioChange = () => {
 
 const getStartTimeAndEndTime = () => {
   const { activeRadioName } = queryParams.value;
-  const timeBegin = dayjs(datePickerValue.value).startOf(activeRadioName).format('YYYY-MM-DD');
-  const timeEnd = dayjs(datePickerValue.value).endOf(activeRadioName).format('YYYY-MM-DD');
-
+  const time = datePickerValue.value;
+  let timeBegin = '';
+  let timeEnd = '';
+  
+  if ( activeRadioName === 'daterange' ) {
+    if (time.length) {
+      const [ startTime, endTime ] = time;
+      timeBegin = dayjs(startTime).format('YYYY-MM-DD')
+      timeEnd = dayjs(endTime).format('YYYY-MM-DD')
+    }
+  } else {
+    timeBegin = dayjs(time).startOf('month').format('YYYY-MM-DD');
+    timeEnd = dayjs(time).endOf('month').format('YYYY-MM-DD');
+  }
+ 
   return {
     timeBegin,
     timeEnd
   }
 }
 
+const formatter = (row, column) => {
+    const { title, ratesDeviationNumber }= row;
+    const { no } = column;
+ 
+    if (  title === '合格率偏差' && no != 0 && no != columns.value.length - 1 ) {
+      const val = row[column.property];
+  
+      if (!ratesDeviationNumber && ratesDeviationNumber != 0) return '';
+  
+      return h('span', {
+        style: { color: ratesDeviationNumber != 0 ? 'red' : '#606266' },
+      }, row[column.property])
+    }
+
+    return row[column.property]
+}
+
 const initPageData = async() => {
   tableLoading.value = true;
   loading.value = true;
+
   const dateResult = getStartTimeAndEndTime();
-  const { data } = await getContinuousAssayList({...dateResult, deviceNo: queryParams.value.deviceNo});
+  const { data } = await getContinuousAssayListNew({...dateResult, deviceNo: queryParams.value.deviceNo});
 
   const whiteTableList = [
-    // { title: '检测指标', key: 'assayName' },
     { title: '实际检测数量', key: 'assayCounts' },
-    { title: '最小值', key: 'minVal' },
-    { title: '最大值', key: 'maxVal' },
-    { title: '合格率(%)', key: 'passedRates' }, 
-    { title: '标线(%)', key: 'bx' },
-    { title: '合格率偏差', key: 'ratesDeviation' }
+    { title: '质控样检测数量', key: 'zkCounts' },
+    { title: '质控样合格率(%)', key: 'passedRates' },
+    { title: '合格率偏差', key: 'ratesDeviation' },
   ]
-
-  const tempBodyObject = {};
+  
+  let assayTotal = 0;
+  let zkTotal = 0;
+  
   const middleData = Object.entries(data).map(([key, value]) => {
-    const children = Object.entries(value).map(([k, v]) => {
-      const [child] = v;
-      tempBodyObject[key + '-' + k] = child;
-      return {
-        label: k, 
-        prop: key + '-' + k, 
-        width: 160
-      }
-    });
-    
+    assayTotal += value['assayCounts']
+    zkTotal += value['zkCounts']
     return {
-      label: key === 'total' ? '' : key,
-      children
+      label: key,
+      prop: key,
+      minWidth: 160
     }
   });
   
-  if ( middleData.length ) {
-    columns.value = [{ label: '检测点位', fixed: "left", children: [{ label: '检测指标', prop: 'title', width: 150 }]}].concat(middleData);
-    tableData.value = whiteTableList.map(item => {
-      const { key } = item;
-      Object.entries(tempBodyObject).map(([k, v]) => {
-        item = {
-          ...item,
-          [k]: v[key]
-        }
-      })
-      return item;
+  const tableResultData = whiteTableList.map(item => {
+    const { key } = item;
+    
+    Object.entries(data).forEach(([k, v]) => {
+      let total = '';
+      
+      if ( key === 'assayCounts' ) total = assayTotal;
+      
+      if ( key === 'zkCounts' ) total = zkTotal;
+
+      item = {
+        total: total === '' ? '' : total,
+        ...item,
+        ratesDeviationNumber: v['ratesDeviationNumber'],
+        [k]: v[key]
+      }
     });
+    return item;
+  })
+  console.log(tableResultData)
+  if ( middleData.length ) {
+    columns.value = [
+      { label: '检测指标', width: 200, prop: 'title' },
+      ...middleData,
+      { label: '合计', width: 200, prop: 'total' }
+    ];
+
+    tableData.value = tableResultData;
   } else {
     columns.value = [];
-    tableData.value = []
+    tableData.value = [];
   }
+
+
+  // if ( middleData.length ) {
+  //   columns.value = [{ label: '检测点位', fixed: "left", children: [{ label: '检测指标', prop: 'title', width: 150 }]}].concat(middleData);
+  //   tableData.value = whiteTableList.map(item => {
+  //     const { key } = item;
+  //     Object.entries(tempBodyObject).map(([k, v]) => {
+  //       item = {
+  //         ...item,
+  //         [k]: v[key]
+  //       }
+  //     })
+  //     return item;
+  //   });
+  // } else {
+  //   columns.value = [];
+  //   tableData.value = []
+  // }
   tableLoading.value = false;
   loading.value = false;
 }
@@ -110,33 +169,36 @@ const handlerQuery = () => {
 }
 
 const handlerReset = () => {
-  datePickerValue.value = new Date();
-  queryParams.value.activeRadioName = 'week';
-  queryParams.value.deviceNo = ''
+  const [ item ] = options.value;
+  datePickerValue.value = [dateBeforeSevenDays.value, new Date()];
+  queryParams.value.activeRadioName = 'daterange';
+  queryParams.value.deviceNo = item?.deviceNo || '';
   initPageData();
 }
 
 const handleExport = () => {
   const dateResult = getStartTimeAndEndTime();
-  proxy.getDownload("/business/exportContinuousAssayCountByDates", {
+  proxy.getDownload("/business/exportContinuousAssayCountByDatesNew", {
     ...dateResult,
     deviceNo: queryParams.value.deviceNo
   }, `${new Date().getTime()}.xlsx`);
 }
 
 onMounted(async() => {
-  getDeviceList({ type: 2 }).then(({ data }) => {
-    // const [ item ] = data;
-    // queryParams.value.deviceNo = item?.deviceNo;
+
+  datePickerValue.value = [dateBeforeSevenDays.value, new Date()];
+
+  await getDeviceList({ type: 2 }).then(({ data }) => {
+    const [ item ] = data;
+    queryParams.value.deviceNo = item?.deviceNo || '';
     options.value = data
   });
   
-  initPageData();
+  await initPageData();
 })
 </script>
 
 <template>
-  
   <div class="lab-day-viewport space-y-[10px]">
     <el-card shadow="never" :body-style="{ border: '0px' }">
       <template #header>
@@ -146,28 +208,30 @@ onMounted(async() => {
       </template>
       <el-row class="pt-[5px]" justify="space-between" :gutter="20">
         <el-col :span="6">
-          <el-form-item label="设备编号">
+          <el-form-item label="设备名称">
             <el-select v-model="queryParams.deviceNo" placeholder="请选择" filterable clearable>
               <el-option v-for="item in options" :key="item.deviceNo" :label="item.deviceName" :value="item.deviceNo" />
             </el-select>
           </el-form-item>
         </el-col>
-        <el-col :span="12">
+        <el-col :span="14">
           <div class="flex items-center space-x-[20px]">
             <el-form-item label="统计时段">
               <el-radio-group v-model="queryParams.activeRadioName" @change="onRadioChange">
-                <el-radio-button label="按周" value="week" />
+                <el-radio-button label="按周" value="daterange" />
                 <el-radio-button label="按月" value="month" />
               </el-radio-group>
             </el-form-item>
-            <el-form-item :label="label">
+            <el-form-item>
               <el-date-picker
                 v-model="datePickerValue"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                placeholder="请选择月份"
+                :type="queryParams.activeRadioName"
                 :editable="false"
                 :clearable="false"
-                :type="queryParams.activeRadioName"
-                :format=format
-                :placeholder="'请' + label"
+                style="max-width: 280px;"
                 @change="onChangeDatePicker"
               />
             </el-form-item>
@@ -190,14 +254,25 @@ onMounted(async() => {
           plain
           icon="Download"
           @click="handleExport"
+          :loading="loading"
         >导出</el-button>
       </div>
       <el-table :data="tableData" style="width: 100%" v-loading="tableLoading">
-        <!-- <el-table-column prop="title" label="检测点位" width="160" fixed="left" header-align="center" /> -->
-        <el-table-column  :label="col.label" :width="col.width || 200" :fixed="col.fixed" align="center" v-for="col, index in columns">
-          <el-table-column :prop="child.prop" :label="child.label" :width="child.width" v-for="child in col.children"/>
+        <el-table-column
+          :prop="col.prop"
+          :label="col.label"
+          :width="col.width"
+          :min-width="col.minWidth || 200"
+          :fixed="col.fixed"
+          align="center"
+          v-for="col, index in columns"
+          :formatter="formatter"
+        >
+          <!-- <template #default="scope">
+            {{ scope.row }}
+            {{ scope.row[col.prop] }}
+          </template> -->
         </el-table-column>
-        <!-- <el-table-column prop="totalDeviationRate" label="总质控合格率" width="120" header-align="center" fixed="right" align="center"/> -->
       </el-table>
     </el-card>
 

+ 107 - 37
src/views/report/laboratory-month/index.vue

@@ -1,11 +1,12 @@
 <script setup>
 import { dayjs } from 'element-plus';
 import { getMonthTable, getDeviceList } from '@/api/report/lab';
+import { computed } from 'vue';
 
 const { proxy } = getCurrentInstance();
 
 const queryParams = ref({
-  activeRadioName: 'week',
+  activeRadioName: 'daterange',
   deviceNo: ''
 });
 
@@ -13,10 +14,11 @@ const tableLoading = ref(false);
 const loading = ref(false);
 const options = ref([]);
 
-const datePickerValue = ref(new Date());
+const datePickerValue = ref([]);
 const tempDataValue = ref({timeBegin: dayjs(new Date()).startOf('week').format('YYYY') + '年'});
 
 const tableData = ref([]);
+const finalyColumns = ref([]);
 const columns = [
   {
     label: '高COD',
@@ -84,30 +86,35 @@ const columns = [
   },
 ]
 
-const format = computed(() => {
-  return queryParams.value.activeRadioName === 'week' ? tempDataValue.value.timeBegin + ' 第 ww 周'  : 'YYYY-MM'
-})
-
-const label = computed(() => {
-  return queryParams.value.activeRadioName === 'week' ? '选择周' : '选择月'
-})
+const dateBeforeSevenDays = computed(() => new Date(dayjs().subtract(7, 'day').format('YYYY-MM-DD')))
 
 const onChangeDatePicker = (value) => {
   const timeBegin = dayjs(value).startOf('week').format('YYYY') + '年';
   const timeEnd = dayjs(value).endOf('week').format('MM-DD');
-  
   tempDataValue.value = { timeBegin, timeEnd };
 }
 
 const onRadioChange = () => {
-  datePickerValue.value = new Date();
+  datePickerValue.value = queryParams.value.activeRadioName === 'daterange' ? [dateBeforeSevenDays.value, new Date()] : new Date();
 }
 
 const getStartTimeAndEndTime = () => {
   const { activeRadioName } = queryParams.value;
-  const timeBegin = dayjs(datePickerValue.value).startOf(activeRadioName).format('YYYY-MM-DD');
-  const timeEnd = dayjs(datePickerValue.value).endOf(activeRadioName).format('YYYY-MM-DD');
-
+  const time = datePickerValue.value;
+  let timeBegin = '';
+  let timeEnd = '';
+  
+  if ( activeRadioName === 'daterange' ) {
+    if (time.length) {
+      const [ startTime, endTime ] = time;
+      timeBegin = dayjs(startTime).format('YYYY-MM-DD')
+      timeEnd = dayjs(endTime).format('YYYY-MM-DD')
+    }
+  } else {
+    timeBegin = dayjs(time).startOf('month').format('YYYY-MM-DD');
+    timeEnd = dayjs(time).endOf('month').format('YYYY-MM-DD');
+  }
+ 
   return {
     timeBegin,
     timeEnd
@@ -117,8 +124,35 @@ const getStartTimeAndEndTime = () => {
 const initPageData = async() => {
   tableLoading.value = true;
   loading.value = true;
+
   const dateResult = getStartTimeAndEndTime();
   const { data } = await getMonthTable({...dateResult, ...queryParams.value});
+  // tableData.value = (data || []).concat({worksName: '合计', highCodArrayCounts: 123, lowCodArrayCounts: 456});
+
+  const arr = [];
+
+  for (let index = 0; index < columns.length; index++) {
+    const children = columns[index].children;
+    const tempArr = [];
+    for (let i = 0; i < children.length; i++) {
+      const item = children[i];
+      tempArr.push(item.prop);
+    }
+    arr.push( tempArr );
+  }
+
+  const tempColumns = [];
+
+  arr.forEach((item, index) => {
+    const [k1, k2, k3] = item;
+    const isExits = data.some((val) => val[k1] && val[k2] && val[k3]);
+    if ( isExits ) {
+      tempColumns.push(columns[index]);
+    }
+  })
+
+  finalyColumns.value = data.length ? tempColumns : [];
+
   tableData.value = data || [];
   tableLoading.value = false;
   loading.value = false;
@@ -129,9 +163,10 @@ const handlerQuery = () => {
 }
 
 const handlerReset = () => {
-  datePickerValue.value = new Date();
-  queryParams.value.activeRadioName = 'week';
-  queryParams.value.deviceNo = ''
+  const [ item ] = options.value;
+  datePickerValue.value = [dateBeforeSevenDays.value, new Date()];
+  queryParams.value.activeRadioName = 'daterange';
+  queryParams.value.deviceNo = item?.deviceNo || '';
   initPageData();
 }
 
@@ -145,16 +180,52 @@ const handleExport = () => {
   }, `${new Date().getTime()}.xlsx`);
 }
 
-onMounted(() => {
-  getDeviceList({type: 1}).then(({ data }) => {
+// 合并单元格
+ const arraySpanMethod = (value) => {
+  const {
+    row,
+    column,
+    rowIndex,
+    columnIndex,
+  } = value
+
+  if ( rowIndex === tableData.value.length - 1 ) {
+    if ( columnIndex !== 0 && columnIndex !== columns.length * 3 + 2 - 1 ) {
+      console.log( columnIndex, columnIndex % 3 );
+      if (columnIndex % 3 === 1) {
+        // rowspan: 2,
+        // colspan: 1,
+        return [1, 3] 
+      } else {
+        return [0, 0]
+      }
+    }
+  }
+
+  // if (rowIndex % 2 === 0) {
+  //   if (columnIndex === 0) {
+  //     return [1, 2]
+  //   } else if (columnIndex === 1) {
+  //     return [0, 0]
+  //   }
+  // }
+}
+
+onMounted(async () => {
+
+  datePickerValue.value = [dateBeforeSevenDays.value, new Date()];
+
+  await getDeviceList({type: 1}).then(({ data }) => {
+    const [ item ] = data;
+    queryParams.value.deviceNo = item?.deviceNo || '';
     options.value = data
   });
-  initPageData();
+  
+  await initPageData();
 })
 </script>
 
 <template>
-  
   <div class="lab-day-viewport space-y-[10px]">
     <el-card shadow="never" :body-style="{ border: '0px' }">
       <template #header>
@@ -164,29 +235,30 @@ onMounted(() => {
       </template>
       <el-row class="pt-[5px]" justify="space-between" :gutter="20">
         <el-col :span="6">
-          <el-form-item label="设备编号">
+          <el-form-item label="设备名称">
             <el-select v-model="queryParams.deviceNo" placeholder="请选择" filterable clearable>
               <el-option v-for="item in options" :key="item.deviceNo" :label="item.deviceName" :value="item.deviceNo" />
             </el-select>
           </el-form-item>
         </el-col>
-        <el-col :span="12">
+        <el-col :span="14">
           <div class="flex items-center space-x-[20px]">
-            <el-form-item label="统计时段">
+            <el-form-item label="统计时段" style="flex-shrink: 0;">
               <el-radio-group v-model="queryParams.activeRadioName" @change="onRadioChange">
-                <el-radio-button label="按周" value="week" />
+                <el-radio-button label="按周" value="daterange" />
                 <el-radio-button label="按月" value="month" />
               </el-radio-group>
             </el-form-item>
-            <el-form-item :label="label">
+            <el-form-item label="">
               <el-date-picker
                 v-model="datePickerValue"
-                style="width: 300px"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                placeholder="请选择月份"
+                :type="queryParams.activeRadioName"
                 :editable="false"
                 :clearable="false"
-                :type="queryParams.activeRadioName"
-                :format=format
-                :placeholder="'请' + label"
+                style="max-width: 280px;"
                 @change="onChangeDatePicker"
               />
             </el-form-item>
@@ -209,19 +281,17 @@ onMounted(() => {
           plain
           icon="Download"
           @click="handleExport"
+          :loading="loading"
         >导出</el-button>
       </div>
+      <!-- :span-method="arraySpanMethod" -->
       <el-table :data="tableData" style="width: 100%" v-loading="tableLoading">
         <el-table-column prop="worksName" label="用户" width="200" fixed="left" header-align="center" />
-        <el-table-column :label="col.label" :width="col.width" :fixed="col.fixed" align="center" v-for="col in columns">
-          <el-table-column :prop="child.prop" :label="child.label" :width="child.width" v-for="child in col.children"/>
+        <el-table-column :label="col.label" :min-width="col.width" :fixed="col.fixed" align="center" v-for="col in finalyColumns">
+          <el-table-column :prop="child.prop" :label="child.label" :min-width="child.width" v-for="child in col.children"/>
         </el-table-column>
         <el-table-column prop="totalDeviationRate" label="总质控合格率" width="120" header-align="center" fixed="right" align="center"/>
       </el-table>
     </el-card>
-
   </div>
-  
-</template>
-
-<style lang="scss" scoped></style>
+</template>

+ 64 - 8
src/views/report/record/index.vue

@@ -3,6 +3,7 @@ import { getDeviceList, getDrawerData } from '@/api/report/lab';
 import { dayjs } from 'element-plus';
 
 const { proxy } = getCurrentInstance();
+const route = useRoute();
 
 const queryParams = ref({ 
   deviceNo: '',
@@ -23,10 +24,10 @@ const columns = [
     label: '基本资料',
     children: [
       { label: "化验时间", prop: 'assayTime', width: 180 },
-      { label: "设备名称", prop: 'deviceName', width: 180 },
-      { label: "设备编号", prop: 'deviceNo', width: 180 },
+      // { label: "设备名称", prop: 'deviceName', width: 180 },
+      // { label: "设备名称", prop: 'deviceNo', width: 180 },
       { label: "所属水厂", prop: 'worksName', width: 180 },
-      { label: "样品名称", prop: 'assayTypeName', width: 180 }
+      // { label: "样品名称", prop: 'assayTypeName', width: 180 }
     ]
   },
   {
@@ -95,6 +96,8 @@ const columns = [
   }
 ]
 
+const finalyColumns = ref([]);
+
 const initPageData = async () => {
 
   loading.value = true;
@@ -102,6 +105,30 @@ const initPageData = async () => {
   const [ timeBegin, timeEnd ] = datePieckerValue.value;
   const { total: tableTotal, rows } = await getDrawerData({ ...queryParams.value, timeBegin, timeEnd });
   
+  const arr = [];
+
+  for (let index = 1; index < columns.length; index++) {
+    const children = columns[index].children;
+    const tempArr = [];
+    for (let i = 1; i < children.length; i++) {
+      const item = children[i];
+      tempArr.push(item.prop);
+    }
+    arr.push( tempArr );
+  }
+  
+  const tempColumns = [];
+
+  arr.forEach((item, index) => {
+    const [k1, k2] = item;
+    const isExits = rows.some((val) => val[k1] && val[k2]);
+    if ( isExits ) {
+      tempColumns.push(columns[index + 1]);
+    }
+  })
+
+  finalyColumns.value = rows.length ? [columns[0]].concat(tempColumns) : [];
+
   tableData.value = rows;
   total.value = tableTotal;
   loading.value = false;
@@ -131,8 +158,33 @@ const handleExport = () => {
   }, `${new Date().getTime()}.xlsx`);
 }
 
+const test = (key, item) => {
+  let color = '#606266';
+  
+  const whitelist = [
+    'highCodDeviationRate',
+    'lowCodDeviationRate',
+    'anDanDeviationRate',
+    'tnDeviationRate',
+    'tpDeviationRate',
+    'xsydDeviationRate',
+    'yxsyDeviationRate',
+    'zlsyDeviationRate',
+  ]
+
+  if ( whitelist.includes(key) ) {
+    const n = item[key + 'Number'];
+    if ( (n || n == 0) && Math.abs( n ) > 0.1 ) {
+      color = 'red'
+      console.log( key,  );
+    }
+  }
+
+  return {color};
+}
+
 onMounted(async () => {
-  await getDeviceList({tpye: 1}).then(({ data }) => {
+  await getDeviceList({ type: route.query.t }).then(({ data }) => {
     const [ item ] = data;
     queryParams.value.deviceNo = item?.deviceNo;
     firstDeviceNo = item?.deviceNo;
@@ -152,7 +204,7 @@ onMounted(async () => {
       </template>
       <el-row class="pt-[5px]" justify="space-between" :gutter="20">
         <el-col :span="6">
-          <el-form-item label="设备编号">
+          <el-form-item label="设备名称">
             <el-select v-model="queryParams.deviceNo" placeholder="请选择" filterable clearable>
               <el-option v-for="item in options" :key="item.deviceNo" :label="item.deviceName" :value="item.deviceNo" />
             </el-select>
@@ -175,7 +227,7 @@ onMounted(async () => {
             />
           </el-form-item>
         </el-col>
-        <el-col :span="6">
+        <el-col :span="6" :offset="6">
           <div class="flex justify-end">
             <el-button type="primary" @click="handleQuery" :loading="loading">查询</el-button>
             <el-button @click="handleReset" :loading="loading">重置</el-button>
@@ -190,8 +242,12 @@ onMounted(async () => {
         <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
       </div>
       <el-table :data="tableData" style="width: 100%" v-loading="loading">
-        <el-table-column :label="col.label" :width="col.width" :fixed="col.fixed" align="center" v-for="col in columns">
-          <el-table-column :prop="child.prop" :label="child.label" :width="child.width" v-for="child in col.children" />
+        <el-table-column :label="col.label" :min-width="col.width" :fixed="col.fixed" align="center" v-for="col in finalyColumns">
+          <el-table-column :prop="child.prop" :label="child.label" :min-width="child.width" v-for="child in col.children">
+            <template #default="scope">
+              <span :style="test(child.prop, scope.row)">{{ scope.row[child.prop] }}</span>
+            </template>
+          </el-table-column>
         </el-table-column>
       </el-table>
       <div class="">

+ 58 - 36
src/views/report/report-daily/index.vue

@@ -3,8 +3,6 @@ import { RecordDrawer } from '@/views/report/components';
 import { getHomeCounts, getWaterFactory, getDailyTable, getDeviceList } from '@/api/report/lab';
 import { dayjs } from 'element-plus';
 
-const route = useRoute();
-
 const drawerVisible = ref(false);
 const tableLoading = ref(false);
 const total = ref(0);
@@ -13,6 +11,10 @@ const tableData = ref([]);
 const drawerData = ref({});
 const currentDateTime = ref('');
 
+const categoryOptions = [
+  { label: '化验室设备', value: 1 },
+  { label: '连续检测设备', value: 2 },
+]
 const deviceNameEnum = {
   "0": "待机中",
   "1": "离线中",
@@ -32,8 +34,6 @@ const pageCountNums = ref({
 const queryParams = ref({ 
   assayStatus: '',
   assayDate: dayjs().format("YYYY-MM-DD"),
-  // assayDate: '2024-08-13',
-  // worksId: null,
   deviceNo: '',
   type: 1,
   pageNum: 1,
@@ -52,24 +52,38 @@ const getDeviceClass = ({ assayStatus: key }) => {
 
 const initPageData = async () => {
   tableLoading.value = true;
+  
+  const { data: deviceData } = await getDeviceList({ type: queryParams.value.type });
   const { total: pageTotal, rows } = await getDailyTable(queryParams.value);
   
   total.value = pageTotal;
   tableData.value = rows.map(item => ({
     ...item,
-    // passAssayRates: item.passAssayRates ? item.passAssayRates.toFixed(2) + '%' : '',
     currentTemperature: item.currentTemperature ? item.currentTemperature + '°' : '',
-    // currentHumidity: item.currentHumidity ? item.currentHumidity + '%' : '',
     wasteLiquidAmounts: item.wasteLiquidAmounts ? item.wasteLiquidAmounts + 'L' : '',
   }));
+  
   tableLoading.value = false;
+  selectOptions.value = deviceData;
 }
 
-const handleDatePickerChange = () => initPageData();
+const handleDatePickerChange = () => {
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = 10;
+  initPageData();
+}
 
-const handleSelectChange = () => initPageData();
+const handleSelectChange = () => {
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = 10;
+  initPageData();
+}
 
-const handleRadioChange = () => initPageData();
+const handleRadioChange = () => {
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = 10;
+  initPageData();
+}
 
 // table btn 化验记录
 const handleTableBtnClick = async (row) => {
@@ -83,26 +97,23 @@ const handleTableBtnClick = async (row) => {
   drawerVisible.value = true;
 }
 
-onMounted( async () => {
-  const { type } = route.query;
-
-  queryParams.value.type = type;
-
-  initPageData();
-  
-  const { data } = await getHomeCounts(type);
-  const { data: deviceData } = await getDeviceList({ type });
-
+// 设备类型变化
+const reloadPageData = async (type) => {
+  queryParams.value.type = type || 1;
+  queryParams.value.deviceNo = '';
+  queryParams.value.pageNum = 1;
+  queryParams.value.pageSize = 10;
+  const { data } = await getHomeCounts(queryParams.value.type);
   pageCountNums.value = {
     ...data,
     passAssayRates: Number(data.passAssayRates.slice(0, -1))
   };
-  
-  selectOptions.value = deviceData;
-  
+  initPageData();
+}
 
+onMounted( async () => {
+  reloadPageData();
   currentDateTime.value = dayjs(new Date()).format('YYYY-MM-DD hh:mm:ss');
-
 })
 
 </script>
@@ -123,7 +134,7 @@ onMounted( async () => {
               <template #title>
                 <p class="flex items-center space-x-[4px]">
                   <el-icon :size="14" color="#2454ff"><Management /></el-icon>
-                  <span>全国实验室设备总数(台)</span>
+                  <span>全国设备总数(台)</span>
                 </p>
               </template>
             </el-statistic>
@@ -208,19 +219,21 @@ onMounted( async () => {
             <el-radio-button label="离线中" value="1" />
             <el-radio-button label="化验中" value="2" />
           </el-radio-group>
-          <div class="space-x-[20px]">
-            <el-date-picker
-              type="date"
-              :clearable="false"
-              v-model="queryParams.assayDate"
-              value-format="YYYY-MM-DD"
-              placeholder="选择日期"
-              style="width: 220px"
-              @change="handleDatePickerChange"
-            />
+          <div class="flex space-x-[20px]">
+            <el-select
+              placeholder="选择设备类型"
+              v-model="queryParams.type"
+              @change="reloadPageData"
+            >
+              <el-option
+                v-for="item in categoryOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
             <el-select
               placeholder="选择设备"
-              style="width: 220px"
               clearable
               filterable
               v-model="queryParams.deviceNo"
@@ -233,11 +246,20 @@ onMounted( async () => {
                 :value="item.deviceNo"
               />
             </el-select>
+            <el-date-picker
+              type="date"
+              :clearable="false"
+              v-model="queryParams.assayDate"
+              value-format="YYYY-MM-DD"
+              placeholder="选择日期"
+              @change="handleDatePickerChange"
+              style="width: 400px;"
+            />
           </div>
         </div>
         <el-table :data="tableData" style="width: 100%" v-loading="tableLoading">
           <el-table-column prop="deviceName" label="设备名称" width="180" fixed/>
-          <el-table-column prop="deviceNo" label="设备编号" width="180" />
+          <el-table-column prop="deviceNo" label="设备名称" width="180" />
           <el-table-column prop="worksName" label="所属水厂" width="180"/>
           <el-table-column prop="assayStatus" label="当前设备状态" width="180">
             <template #default="{ row }">