WXL
5 天以前 475a352a4bfd7ac3a81e8c7c92d3bb64e2e01037
src/views/business/maintain/components/LiverKidneyPanel.vue
@@ -30,7 +30,7 @@
        class-name="leave-alone"
      >
        <template #default="scope">
          <span :class="{'required-item': scope.row.required}">
          <span :class="{ 'required-item': scope.row.required }">
            {{ scope.row.itemName }}
          </span>
        </template>
@@ -54,8 +54,11 @@
              class="value-input"
            />
            <span v-else class="value-display">
              {{ scope.row.values[index] || '-' }}
              <span v-if="scope.row.values[index] && scope.row.unit" class="unit">
              {{ scope.row.values[index] || "-" }}
              <span
                v-if="scope.row.values[index] && scope.row.unit"
                class="unit"
              >
                {{ scope.row.unit }}
              </span>
            </span>
@@ -65,8 +68,6 @@
          </div>
        </template>
      </el-table-column>
    </el-table>
    <!-- 附件上传区域 -->
@@ -95,7 +96,9 @@
        <el-form-item
          label="日期"
          prop="date"
          :rules="[{ required: true, message: '请选择日期', trigger: 'change' }]"
          :rules="[
            { required: true, message: '请选择日期', trigger: 'change' }
          ]"
        >
          <el-date-picker
            v-model="columnForm.date"
@@ -108,7 +111,9 @@
        <el-form-item
          label="时间"
          prop="time"
          :rules="[{ required: true, message: '请选择时间', trigger: 'change' }]"
          :rules="[
            { required: true, message: '请选择时间', trigger: 'change' }
          ]"
        >
          <el-time-picker
            v-model="columnForm.time"
@@ -130,65 +135,58 @@
import UploadAttachment from "@/components/UploadAttachment";
export default {
  name: 'LiverKidneyPanel',
  name: "LiverKidneyPanel",
  components: {
    UploadAttachment,
    UploadAttachment
  },
  props: {
    isEditing: {
      type: Boolean,
      default: false
    },
    // 修改 prop 定义,支持对象格式的初始数据
    initialData: {
      type: Array,
      default: () => []
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      tableData: [],
      dynamicColumns: [
        {
          label: '2024-12-27\n08:00',
          key: 'time1',
          date: '2024-12-27',
          time: '08:00'
        },
        {
          label: '2024-12-27\n14:00',
          key: 'time2',
          date: '2024-12-27',
          time: '14:00'
        }
      ],
      dynamicColumns: [],
      attachments: [],
      columnDialogVisible: false,
      columnForm: {
        date: '',
        time: ''
        date: "",
        time: ""
      },
      tableKey: 0 // 用于强制重新渲染表格
      tableKey: 0,
      // 内部数据状态
      internalData: {}
    };
  },
  watch: {
    // 监听 initialData 变化,确保数据正确接收 [5](@ref)
    initialData: {
      handler(newData) {
        if (newData && Object.keys(newData).length > 0) {
          this.internalData = { ...newData };
          this.initFromExternalData();
        }
      },
      immediate: true,
      deep: true
    },
    isEditing(newVal) {
      if (!newVal) {
        // 保存数据
        this.$emit('data-change', {
          type: 'liver_kidney',
          data: this.tableData,
          columns: this.dynamicColumns,
          attachments: this.attachments
        });
        this.saveData();
      }
      // 编辑模式切换时重新计算列宽
      this.$nextTick(() => {
        this.forceTableLayout();
      });
    },
    dynamicColumns: {
      handler() {
        // 列变化时重新计算布局
        this.$nextTick(() => {
          this.forceTableLayout();
        });
@@ -197,94 +195,99 @@
    }
  },
  methods: {
    // 从外部数据初始化组件 [9](@ref)
    initFromExternalData() {
      if (this.internalData.data && this.internalData.columns) {
        // 使用外部数据初始化表格
        this.tableData = this.internalData.data.map(item => ({
          ...item,
          values:
            item.values || new Array(this.internalData.columns.length).fill("")
        }));
        this.dynamicColumns = [...this.internalData.columns];
      } else {
        // 如果没有外部数据,使用默认初始化
        this.initTableData();
      }
      // 初始化附件
      if (this.internalData.attachments) {
        this.attachments = [...this.internalData.attachments];
      }
    },
    // 初始化默认表格数据
    initTableData() {
      const medicalItems = [
        {
          itemName: '血钠',
          unit: 'mmol/L',
          itemName: "血钠",
          unit: "mmol/L",
          required: true,
          reference: '135-145'
          reference: "135-145"
        },
        {
          itemName: '血钾',
          unit: 'mmol/L',
          itemName: "血钾",
          unit: "mmol/L",
          required: true,
          reference: '3.5-5.5'
          reference: "3.5-5.5"
        },
        { itemName: "BUN", unit: "mg/dL", required: true, reference: "<20" },
        { itemName: "肌酐", unit: "μmol/L", required: true, reference: "<100" },
        {
          itemName: 'BUN',
          unit: 'mg/dL',
          itemName: "总胆红素",
          unit: "μmol/L",
          required: true,
          reference: '<20'
          reference: "<21"
        },
        {
          itemName: '肌酐',
          unit: 'μmol/L',
          required: true,
          reference: '<100'
        },
        {
          itemName: '总胆红素',
          unit: 'μmol/L',
          required: true,
          reference: '<21'
        },
        {
          itemName: 'ALT',
          unit: 'U/L',
          required: true,
          reference: '<50'
        },
        {
          itemName: 'AST',
          unit: 'U/L',
          required: true,
          reference: '<40'
        },
        {
          itemName: 'GGT',
          unit: 'U/L',
          required: true,
          reference: '<57'
        },
        {
          itemName: 'ALP',
          unit: 'U/L',
          required: true,
          reference: '<120'
        },
        {
          itemName: 'PT',
          unit: '秒',
          required: true,
          reference: '9.4-12.5'
        },
        {
          itemName: 'INR',
          unit: '',
          required: true,
          reference: '0.85-1.15'
        }
        { itemName: "ALT", unit: "U/L", required: true, reference: "<50" },
        { itemName: "AST", unit: "U/L", required: true, reference: "<40" },
        { itemName: "GGT", unit: "U/L", required: true, reference: "<57" },
        { itemName: "ALP", unit: "U/L", required: true, reference: "<120" },
        { itemName: "PT", unit: "秒", required: true, reference: "9.4-12.5" },
        { itemName: "INR", unit: "", required: true, reference: "0.85-1.15" }
      ];
      // 如果没有动态列,初始化默认列
      if (this.dynamicColumns.length === 0) {
        this.dynamicColumns = [
          {
            label: `${new Date().toISOString().split("T")[0]}\n08:00`,
            key: "time1",
            date: new Date().toISOString().split("T")[0],
            time: "08:00"
          }
        ];
      }
      this.tableData = medicalItems.map(item => ({
        ...item,
        values: new Array(this.dynamicColumns.length).fill('')
        values: new Array(this.dynamicColumns.length).fill("")
      }));
    },
    // 保存数据到父组件 [2](@ref)
    saveData() {
      const dataToEmit = {
        type: "liver_kidney",
        data: this.tableData,
        columns: this.dynamicColumns,
        attachments: this.attachments
      };
      this.$emit("data-change", dataToEmit);
    },
    addColumn() {
      this.columnForm = {
        date: new Date().toISOString().split('T')[0],
        time: '08:00'
        date: new Date().toISOString().split("T")[0],
        time: "08:00"
      };
      this.columnDialogVisible = true;
    },
    confirmAddColumn() {
      this.$refs.columnForm.validate((valid) => {
      this.$refs.columnForm.validate(valid => {
        if (!valid) {
          this.$message.warning('请完善时间点信息');
          this.$message.warning("请完善时间点信息");
          return;
        }
@@ -295,64 +298,60 @@
          date: this.columnForm.date,
          time: this.columnForm.time
        };
        this.internalData.columns.push(newColumn);
        this.dynamicColumns.push(newColumn);
        // 为所有行新增一个空值
        this.tableData.forEach(row => {
          row.values.push('');
          if (!row.values) {
            row.values = [];
          }
          row.values.push("");
        });
        this.columnDialogVisible = false;
        this.$message.success('时间点添加成功');
        // 强制表格重新渲染
        this.$message.success("时间点添加成功");
        this.tableKey += 1;
      });
    },
    handleDialogClosed() {
      this.columnForm = {
        date: '',
        time: ''
        date: "",
        time: ""
      };
      this.$refs.columnForm && this.$refs.columnForm.clearValidate();
    },
    handleValueChange(row, columnIndex) {
      this.$emit('data-change', {
        type: 'liver_kidney',
        data: this.tableData,
        columns: this.dynamicColumns
      });
      this.saveData();
    },
    handleAttachmentChange(fileList) {
      this.attachments = fileList;
      this.$emit('attachment-change', {
        type: 'liver_kidney',
      this.$emit("attachment-change", {
        type: "liver_kidney",
        attachments: fileList
      });
    },
    // 强制表格重新布局[1,3](@ref)
    forceTableLayout() {
      this.$nextTick(() => {
        const table = this.$el.querySelector('.el-table');
        if (table && table.querySelector('colgroup')) {
          // 触发表格重新计算布局
        const table = this.$el.querySelector(".el-table");
        if (table && table.querySelector("colgroup")) {
          this.$nextTick(() => {
            window.dispatchEvent(new Event('resize'));
            window.dispatchEvent(new Event("resize"));
          });
        }
      });
    },
    handleHeaderDragEnd() {
      // 列宽拖拽结束后重新计算布局
      this.forceTableLayout();
    },
    // 提供数据导出方法供父组件调用
    exportData() {
      return {
        tableData: this.tableData,
@@ -363,9 +362,11 @@
    }
  },
  mounted() {
    this.initTableData();
    // 初始渲染后计算列宽
    // 确保组件正确挂载后初始化数据 [1](@ref)
    this.$nextTick(() => {
      if (Object.keys(this.internalData).length === 0) {
        this.initTableData();
      }
      this.forceTableLayout();
    });
  }
@@ -464,7 +465,6 @@
  font-weight: normal;
}
/* 响应式设计 */
@media (max-width: 768px) {
  .medical-panel {
    padding: 10px;