1
lkk
16 小时以前 4b6eabfb56d2b736c5f16796614318770c606fd6
src/views/doctor/inspectCheck/index.vue
@@ -1,35 +1,77 @@
<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px" @submit.native.prevent>
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      label-width="68px"
      @submit.native.prevent
    >
      <el-form-item label="体检号" prop="reportDoctorCode">
        <el-input ref="inputName" v-model="queryParams.tjNum" placeholder="请输入体检号" clearable
          @keyup.enter.native="handleQuery" style="width: 170px" />
        <el-input
          ref="inputName"
          v-model="queryParams.tjNum"
          placeholder="请输入体检号"
          clearable
          @keyup.enter.native="handleQuery"
          style="width: 170px"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery" style="margin-right: 15px">
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
          style="margin-right: 15px"
        >
          查询
        </el-button>
        <el-button icon="el-icon-refresh" type="primary" size="mini" @click="resetQuery">
        <el-button
          icon="el-icon-refresh"
          type="primary"
          size="mini"
          @click="resetQuery"
        >
          重置
        </el-button>
        <el-button icon="el-icon-check" type="primary" size="mini" style="margin-right: 15px" @click="tongbu">
        <el-button
          icon="el-icon-check"
          type="primary"
          size="mini"
          style="margin-right: 15px"
          @click="tongbu"
        >
          同步
        </el-button>
      </el-form-item>
    </el-form>
    <div class="box">
      <div class="table-header">
        检验记录
      </div>
      <div class="table-header">检验记录</div>
      <div>
        <el-table :data="exaLists" border style="width: 100%" @selection-change="handleSelectionChange"
          :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }" height="350" ref="firstTable">
        <el-table
          :data="exaLists"
          border
          style="width: 100%"
          @selection-change="handleSelectionChange"
          :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }"
          height="350"
          ref="firstTable"
        >
          <el-table-column fixed type="selection" align="center" label="选择" width="50" />
          <el-table-column label="姓名" align="center" prop="name" width="80" />
          <el-table-column label="性别" align="center" prop="gender" width="80" />
          <el-table-column label="年龄" align="center" prop="patientAge" width="80" />
          <el-table-column label="送检科室" align="center" prop="deptName" width="100" />
          <el-table-column label="检验项目" align="center" prop="checkParts" width="350" :show-overflow-tooltip="true" />
          <el-table-column
            label="检验项目"
            align="center"
            prop="checkParts"
            width="350"
            :show-overflow-tooltip="true"
          />
          <el-table-column label="项目编号" align="center" prop="jcxmid" width="150" />
          <el-table-column label="审核医师" align="center" prop="shys" width="150" />
          <el-table-column label="报告时间" align="center" prop="examinationDate" width="150" />
@@ -49,19 +91,44 @@
        </el-table>
      </div>
    </div>
    <div class="table-title">
  <h3>
    体检记录:
    <span class="highlight">姓名:{{ infoList.tjCustomerName || "暂无" }}</span>
    <span class="highlight">性别:{{ infoList.tjCustomerSex == 0 ? "男" : infoList.tjCustomerSex == 1 ? "女" : "暂无" }}</span>
    <span class="highlight">年龄:{{ infoList.tjCustomerAge || "暂无" }}</span>
  </h3>
</div>
    <el-table border height="350" ref="tab1" :data="checkList" v-loading="loading" style="width: 100%"
      <h3>
        体检记录:
        <span class="highlight">姓名:{{ infoList.tjCustomerName || "暂无" }}</span>
        <span class="highlight">
          性别:
          {{
            infoList.tjCustomerSex == 0
              ? "男"
              : infoList.tjCustomerSex == 1
              ? "女"
              : "暂无"
          }}
        </span>
        <span class="highlight">年龄:{{ infoList.tjCustomerAge || "暂无" }}</span>
        <span class="highlight">门诊号:{{ infoList.cardId || "暂无" }}</span>
      </h3>
    </div>
    <el-table
      border
      height="350"
      ref="tab1"
      :data="checkList"
      v-loading="loading"
      style="width: 100%"
      @selection-change="handleSelectionChangeSecond"
      :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }">
      :header-cell-style="{ background: '#aad8df', fontSize: '14px', color: '#333' }"
    >
      <el-table-column type="selection" width="60" />
      <el-table-column label="状态" align="center" prop="type" :show-overflow-tooltip="true" min-width="60">
      <el-table-column
        label="状态"
        align="center"
        prop="type"
        :show-overflow-tooltip="true"
        min-width="60"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.type == '0'">未检</span>
          <span v-if="scope.row.type == '1'">已检</span>
@@ -78,298 +145,152 @@
    </el-table>
  </div>
</template>
<script>
import { getlisList, getJyTjList, asyncPacs } from "@/api/doctor/pacsCheck";
import { getOrderList } from "@/api/hosp/order";
import moment from "moment";
export default {
  dicts: ["dict_tj_status"],
  data() {
    return {
        isProcessing: false, // 防止死循环
    isDeselection: false, // 标记是否为取消选中
      infoList: {},
      dis: false,
      code: null,
      createTimeList: "",
      total: 0,
      loading: false,
      isSyncing: false,
      isFetchingRightTableData: false,
      queryParams: {
        name: null,
        start: null,
        end: null,
        tjNum: null,
      },
      checkStatus: "0",
      exaLists: [],
      selectedFirstTable: null,
      selectedSecondTable: [],
      form: {},
      clearTimeSet: null,
      tjNumbers: "",
      multipleSelection: "",
      tjnum: "",
      xiangmuList: [],
      checkList: [],
      tg: true,
      bh: true,
      pickerOptions: {
        shortcuts: [
          {
            text: "最近一周",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近一个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit("pick", [start, end]);
            },
          },
          {
            text: "最近三个月",
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
              picker.$emit("pick", [start, end]);
            },
          },
        ],
      },
      infoList: {},
      selectedFirstTable: [],
      selectedSecondTable: [],
      loading: false,
      isProcessingSelection: false,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.inputName.focus();
    });
  },
  methods: {
    handleDateChange(val) {
      if (val && val.length === 2) {
        this.queryParams.start = val[0];
        this.queryParams.end = val[1];
      } else {
        this.queryParams.start = null;
        this.queryParams.end = null;
      }
      console.log("Query Params:", this.queryParams);
    },
    tableRowClassName({ row }) {
      return !row.brid ? "row-disabled" : "";
    },
handleSelectionChange(val) {
  this.selectedFirstTable = val;
  this.$nextTick(() => {
    if (val.length === 0) {
      console.log('无选中行,清空选择和 checkList');
      this.checkList = [];
      this.exaLists.forEach(row => {
        this.$refs.firstTable && this.$refs.firstTable.toggleRowSelection(row, false);
      });
      return;
    }
    const firstSelectedRow = val[0];
    let filterKey = firstSelectedRow.checkParts ? 'checkParts' : 'brid';
    let filterValue = firstSelectedRow.checkParts || firstSelectedRow.brid;
    console.log(`按 ${filterKey} 筛选: ${filterValue}`);
    const selectedSet = new Set(
      this.exaLists
        .filter(row => row[filterKey] === filterValue)
        .map(item => item.tempId)
    );
    console.log(`选中的 ${filterKey} 集合 (tempId):`, selectedSet);
    this.exaLists.forEach(row => {
      if (!row.brid) {
        console.warn(`名称为 ${row.name} 的行没有申请单号,跳过选择`);
        return;
      }
      const shouldSelect = selectedSet.has(row.tempId);
      console.log(`行 tempId: ${row.tempId}, ${filterKey}: ${row[filterKey]}, 是否选中: ${shouldSelect}`);
      this.$refs.firstTable.toggleRowSelection(row, shouldSelect);
    });
    if (!this.isFetchingRightTableData) {
      this.isFetchingRightTableData = true;
      this.fetchRightTableData().finally(() => {
        this.isFetchingRightTableData = false;
      });
    }
  });
},
    fetchRightTableData() {
      const code = this.queryParams.tjNum;
      if (!code) {
        console.warn('未提供体检号,跳过 fetchRightTableData');
        this.checkList = [];
        this.loading = false;
        return Promise.resolve();
      }
      this.loading = true;
      return getJyTjList(code)
        .then((response) => {
          this.checkList = response.data || [];
          this.loading = false;
        })
        .catch((error) => {
          console.error('获取 checkList 失败:', error);
          this.checkList = [];
          this.loading = false;
          throw error;
        });
    },
    handleSelectionChangeSecond(selectedRows) {
      this.selectedSecondTable = selectedRows;
      if (selectedRows.length > 1) {
        let del_row = selectedRows.shift();
        this.$refs.tab1.toggleRowSelection(del_row, false);
      }
      console.log("当前选中的行数据:", this.selectedSecondTable);
    },
    async handleQuery() {
      if (!this.queryParams.tjNum) {
        this.$message.error("体检号不能为空");
        return;
      }
      this.loading = true;
      try {
        // 并行执行两个查询
        const [orderResponse, lisResponse] = await Promise.all([
          getOrderList(this.queryParams).catch((error) => {
            console.error('获取 orderList 失败:', error);
            return { data: { list: [] } }; // 返回空数据以继续执行
          }),
          getOrderList(this.queryParams).catch(() => ({ data: { list: [] } })),
          getlisList(this.queryParams),
        ]);
        // 处理 getOrderList 结果
        if (orderResponse.data?.list?.length > 0) {
          this.infoList = orderResponse.data.list[0];
        } else {
          this.infoList = {};
          console.warn('getOrderList 返回空列表');
        }
        // 处理 getlisList 结果
        if (lisResponse.code === 200) {
          this.exaLists = lisResponse.data.map((item, index) => ({
            ...item,
            brid: item.brid?.trim(), // 清理空格
            mzh: item.mzh?.trim(),
            tempId: index,
          }));
          console.log('Loaded exaLists:', this.exaLists);
          // 获取右侧表格数据
          await this.fetchRightTableData();
        } else {
          this.exaLists = [];
          this.$message.error(lisResponse.msg || "查询检验记录失败");
        }
      } catch (error) {
        console.error('查询失败:', error);
        this.$message.error(error?.msg || "查询失败,请稍后重试");
        this.exaLists = [];
        this.checkList = [];
        this.infoList = {};
        this.infoList = orderResponse.data.list?.[0] || {};
        this.exaLists = lisResponse.data.map((item, index) => ({
          ...item,
          brid: item.brid?.trim(),
          tempId: index,
        }));
        await this.fetchRightTableData();
      } catch (e) {
        console.error(e);
      } finally {
        this.loading = false;
      }
      // 处理时间范围
      if (this.createTimeList) {
        this.queryParams.start = this.createTimeList[0];
        this.queryParams.end = this.createTimeList[1];
      } else {
        this.queryParams.start = null;
        this.queryParams.end = null;
      }
    },
    resetQuery() {
      this.createTimeList = [];
      this.resetForm("queryForm");
      this.queryParams = {
        name: null,
        start: null,
        end: null,
        tjNum: null,
      };
      this.checkList = [];
      this.queryParams.tjNum = null;
      this.exaLists = [];
      this.checkList = [];
      this.infoList = {};
    },
handleSelectionChange(selected) {
  if (this.isProcessingSelection) return;
  this.isProcessingSelection = true;
    handleCurrentChange(row) {
      this.currentRow = row;
  // 找到用户刚操作的那一条(对比之前和现在的差异)
  const old = this.selectedFirstTable;
  let changedRow = null;
  if (selected.length > old.length) {
    // 新增:找出新增的
    changedRow = selected.find(row => !old.includes(row));
  } else {
    // 删除:找出删除的
    changedRow = old.find(row => !selected.includes(row));
  }
  if (changedRow) {
    const group = this.exaLists.filter(r => r.brid === changedRow.brid);
    const isAdding = selected.length > old.length;
    this.$refs.firstTable.clearSelection();
    if (isAdding) {
      // 添加,整个组选上 + 原有选的 brid 也选上
      const allBrids = new Set();
      selected.forEach(row => allBrids.add(row.brid));
      allBrids.add(changedRow.brid);
      const newSelection = this.exaLists.filter(row => allBrids.has(row.brid));
      newSelection.forEach(row => {
        this.$refs.firstTable.toggleRowSelection(row, true);
      });
      this.selectedFirstTable = newSelection;
    } else {
      // 删除,整个组取消,再把剩下 brid 分组补回去
      const remaining = old.filter(row => row.brid !== changedRow.brid);
      const remainBrids = [...new Set(remaining.map(r => r.brid))];
      const newSelection = this.exaLists.filter(row => remainBrids.includes(row.brid));
      newSelection.forEach(row => {
        this.$refs.firstTable.toggleRowSelection(row, true);
      });
      this.selectedFirstTable = newSelection;
    }
  } else {
    this.selectedFirstTable = selected;
  }
  this.fetchRightTableData();
  this.isProcessingSelection = false;
},
    handleSelectionChangeSecond(selected) {
      this.selectedSecondTable = selected.slice(0, 1);
    },
    setTime() {
      this.clearTimeSet = setInterval(() => {
        this.$modal.closeLoading();
      }, 300000);
    fetchRightTableData() {
      if (!this.queryParams.tjNum) return;
      this.loading = true;
      return getJyTjList(this.queryParams.tjNum)
        .then(res => {
          this.checkList = res.data || [];
        })
        .finally(() => {
          this.loading = false;
        });
    },
    tongbu() {
      this.$modal.loading("正在同步,请稍候...");
      this.setTime();
      const requestData = {
        lis: this.selectedFirstTable ? this.selectedFirstTable.map((item) => ({
          ...item,
          tjNum: this.queryParams.tjNum,
        })) : [],
        jcxmid: this.selectedFirstTable && this.selectedFirstTable.length > 0 ? this.selectedFirstTable[0].jcxmid : null,
        shys: this.selectedFirstTable && this.selectedFirstTable.length > 0 ? this.selectedFirstTable[0].shys : null,
        lis: this.selectedFirstTable,
        tj: this.selectedSecondTable[0],
      };
      asyncPacs(requestData)
        .then((res) => {
          if (res.code === 200) {
            this.fetchRightTableData();
            clearInterval(this.clearTimeSet);
            this.clearTimeSet = null;
            this.$modal.closeLoading();
            this.$modal.msgSuccess("同步成功!");
          } else {
            this.$message.error(res.message || "同步失败,请稍后重试");
          }
        })
        .catch((error) => {
          clearInterval(this.clearTimeSet);
          this.clearTimeSet = null;
          this.$modal.closeLoading();
        });
      asyncPacs(requestData).then(res => {
        if (res.code === 200) {
          this.$message.success("同步成功!");
          this.fetchRightTableData();
        } else {
          this.$message.error(res.message || "同步失败");
        }
      });
    },
  },
};</script>
};
</script>
<style lang="scss" scoped>
.app-container {
  padding: 20px;
  background: #f5f7fa;
}
.table-header {
  text-align: center;
  background-color: #aad8df;
@@ -380,13 +301,11 @@
  margin-top: 10px;
  border-radius: 4px 4px 0 0;
}
.table-title {
  text-align: left;
  margin: 20px 0;
  padding: 10px 0;
}
.table-title h3 {
  font-size: 16px;
  color: #333;
@@ -397,27 +316,12 @@
  flex-wrap: wrap;
  gap: 20px;
}
.table-title .highlight {
  font-weight: bold;
  color: #2c3e50;
}
.el-table {
  border-radius: 4px;
  font-size: 14px;
}
.el-table .warning-row {
  background: #e5f3ff !important;
}
::v-deep .el-table__body tr.current-row > td {
  background: #edf2fa !important;
}
.row-disabled {
  color: #999;
  background-color: #f5f5f5;
}
</style>
</style>