WXL
6 天以前 475a352a4bfd7ac3a81e8c7c92d3bb64e2e01037
青岛维护提交
已修改15个文件
已添加2个文件
8153 ■■■■ 文件已修改
src/api/businessApi/affirm.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/businessApi/assess.js 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/project/donatebaseinfo.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/TerminateRestoreModal/index.vue 408 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/affirm/affirmInfo.vue 820 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/affirm/index.vue 278 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/assessInfo.vue 933 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/components/OrganAssessmentForm.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/assess/index.vue 367 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/components/BloodRoutinePanel.vue 281 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/components/LiverKidneyPanel.vue 236 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/components/UrineRoutinePanel.vue 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/index.vue 378 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/maintain/maintainInfo.vue 937 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/DonationProcess/index.vue 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatebaseinfo/EditCaseModal.vue 911 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/project/donatebaseinfo/index.vue 1934 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/businessApi/affirm.js
@@ -0,0 +1,44 @@
import request from '@/utils/request'
// ä¸ŠæŠ¥æ¡ˆä¾‹æ–°å¢ž
export function relativesAdd(data) {
  return request({
    url: '/project/relativesconfirmation/add',
    method: 'post',
    data: data
  })
}
// ä¸ŠæŠ¥æ¡ˆä¾‹ä¿®æ”¹
export function relativesEdit(data) {
  return request({
    url: '/project/relativesconfirmation/edit',
    method: 'post',
    data: data
  })
}
// ä¸ŠæŠ¥æ¡ˆä¾‹åˆ—表
export function relativesList(data) {
  return request({
    url: '/project/relativesconfirmation/confirmationBaseInfoList',
    method: 'post',
    data: data
  })
}
// æ¡ˆä¾‹è¯¦æƒ…
export function relativesInfo(id) {
  return request({
    url: '/project/relativesconfirmation/getInfo/' + id,
    method: 'get'
  })
}
// åˆ é™¤
export function relativesDel(id) {
  return request({
    url: '/project/relativesconfirmation/remove/' + id,
    method: 'get'
  })
}
src/api/businessApi/assess.js
@@ -3,7 +3,15 @@
// ä¸ŠæŠ¥æ¡ˆä¾‹æ–°å¢ž
export function assessAdd(data) {
  return request({
    url: '/project/assessbaseinforeport/add',
    url: '/project/medicalevaluation/add',
    method: 'post',
    data: data
  })
}
// ä¸ŠæŠ¥æ¡ˆä¾‹æ–°å¢ž
export function assessedit(data) {
  return request({
    url: '/project/medicalevaluation/edit',
    method: 'post',
    data: data
  })
@@ -12,7 +20,7 @@
// æ¡ˆä¾‹åˆ—表及详情
export function evaluateBaseInfolist(data) {
  return request({
    url: '/project/medicalevaluation/evaluateBaseInfolist',
    url: '/project/medicalevaluation/medevaluateBaseInfolist',
    method: 'post',
    data: data
  })
src/api/project/donatebaseinfo.js
@@ -1,11 +1,11 @@
import request from '@/utils/request'
// æŸ¥è¯¢æçŒ®åŸºç¡€åˆ—表
export function listDonatebaseinfo(query) {
export function listDonatebaseinfo(data) {
  return request({
    url: '/project/donatebaseinfo/list',
    method: 'get',
    params: query
    method: 'post',
    data: data
  })
}
export function listDonationProcess(query) {
src/components/TerminateRestoreModal/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,408 @@
<template>
  <div>
    <!-- ç»ˆæ­¢ç¡®è®¤å¼¹æ¡† -->
    <el-dialog
      :title="terminateTitle"
      :visible.sync="terminateVisible"
      width="800px"
      append-to-body
      :close-on-click-modal="false"
      @close="handleTerminateClose"
    >
      <div class="patient-info">
        <el-alert
          :title="
            `当前操作患者:${currentRecord.name} (${currentRecord.idcardno ||
              '无证件号'})`
          "
          type="info"
          :closable="false"
          show-icon
        />
      </div>
      <el-form
        :model="terminateForm"
        :rules="terminateRules"
        ref="terminateFormRef"
        label-width="100px"
        class="terminate-form"
      >
        <el-form-item label="终止类型" prop="terminationType">
          <el-select
            v-model="terminateForm.terminationType"
            placeholder="请选择终止类型"
            style="width: 100%;"
          >
            <el-option
              v-for="item in terminationTypes"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="详细原因" prop="terminationResult">
          <el-input
            v-model="terminateForm.terminationResult"
            type="textarea"
            :rows="3"
            placeholder="请输入终止的详细原因"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="二次确认" prop="confirmText">
          <el-input
            v-model="terminateForm.confirmText"
            placeholder="请输入'确认终止'以完成操作"
            @input="handleConfirmTextChange"
          />
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="handleTerminateClose" :disabled="terminateLoading"
          >取消</el-button
        >
        <el-button
          type="danger"
          :disabled="!canSubmitTerminate"
          @click="handleTerminateSubmit"
          :loading="terminateLoading"
        >
          ç¡®è®¤ç»ˆæ­¢
        </el-button>
      </div>
    </el-dialog>
    <!-- æ¢å¤ç¡®è®¤å¼¹æ¡† -->
    <el-dialog
      :title="restoreTitle"
      :visible.sync="restoreVisible"
      width="600px"
      append-to-body
      :close-on-click-modal="false"
    >
      <div class="patient-info">
        <el-alert
          :title="
            `当前操作患者:${currentRecord.name} (${currentRecord.idcardno ||
              '无证件号'})`
          "
          type="info"
          :closable="false"
          show-icon
        />
      </div>
      <div style="margin: 20px 0;">
        <p>
          ç¡®å®šè¦æ¢å¤æçŒ®è€…
          <strong>{{ currentRecord.name }}</strong> çš„æçŒ®è¿›ç¨‹å—?
        </p>
        <p style="color: #67c23a; font-size: 12px; margin-top: 10px;">
          æ¢å¤åŽï¼Œè¯¥æ¡ˆä¾‹å°†é‡æ–°è¿›å…¥æçŒ®æµç¨‹
        </p>
      </div>
      <div slot="footer">
        <el-button @click="restoreVisible = false" :disabled="restoreLoading"
          >取消</el-button
        >
        <el-button
          type="success"
          @click="handleRestoreSubmit"
          :loading="restoreLoading"
        >
          ç¡®è®¤æ¢å¤
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { updateDonatebaseinfo } from "@/api/project/donatebaseinfo";
export default {
  name: "TerminateRestoreModal",
  props: {
    // å½“前操作记录
    currentRecord: {
      type: Object,
      default: () => ({})
    },
    // å¼¹æ¡†æ˜¾ç¤ºçŠ¶æ€
    visible: {
      type: Object,
      default: () => ({
        terminate: false,
        restore: false
      })
    },
    // è‡ªå®šä¹‰æ ‡é¢˜
    titles: {
      type: Object,
      default: () => ({
        terminate: "终止捐献进程",
        restore: "恢复捐献进程"
      })
    }
  },
  data() {
    return {
      // ç»ˆæ­¢è¡¨å•
      terminateForm: {
        terminationType: "",
        terminationResult: "",
        confirmText: ""
      },
      // ç»ˆæ­¢ç±»åž‹é€‰é¡¹
      terminationTypes: [
        { label: "好转", value: "1" },
        { label: "死亡", value: "2" },
        { label: "不符合捐献进程", value: "3" },
        { label: "家属放弃捐献", value: "4" },
        { label: "其他", value: "5" }
      ],
      // éªŒè¯è§„则
      terminateRules: {
        terminationType: [
          { required: true, message: "请选择终止类型", trigger: "change" }
        ],
        terminationResult: [
          { required: true, message: "请输入终止原因", trigger: "blur" },
          { min: 5, message: "终止原因至少5个字符", trigger: "blur" }
        ]
      },
      // åŠ è½½çŠ¶æ€
      terminateLoading: false,
      restoreLoading: false,
      // æŽ§åˆ¶æäº¤
      canSubmitTerminate: false
    };
  },
  computed: {
    terminateVisible: {
      get() {
        return this.visible.terminate;
      },
      set(value) {
        this.$emit("update:visible", { ...this.visible, terminate: value });
      }
    },
    restoreVisible: {
      get() {
        return this.visible.restore;
      },
      set(value) {
        this.$emit("update:visible", { ...this.visible, restore: value });
      }
    },
    terminateTitle() {
      return this.titles.terminate;
    },
    restoreTitle() {
      return this.titles.restore;
    },
    // æ‚£è€…信息显示
    patientInfo() {
      return `${this.currentRecord.name} (${this.currentRecord.idcardno ||
        "无证件号"})`;
    }
  },
  watch: {
    "visible.terminate": {
      handler(newVal) {
        if (newVal) {
          this.resetTerminateForm();
        }
      },
      immediate: true
    }
  },
  methods: {
    /** é‡ç½®ç»ˆæ­¢è¡¨å• */
    resetTerminateForm() {
      this.terminateForm = {
        terminationType: "",
        terminationResult: "",
        confirmText: ""
      };
      this.canSubmitTerminate = false;
      this.terminateLoading = false;
      // é‡ç½®è¡¨å•验证
      this.$nextTick(() => {
        if (this.$refs.terminateFormRef) {
          this.$refs.terminateFormRef.clearValidate();
        }
      });
    },
    /** ç¡®è®¤æ–‡æœ¬å˜åŒ–处理 */
    handleConfirmTextChange(value) {
      this.canSubmitTerminate = value === "确认终止";
    },
    /** ç»ˆæ­¢å¼¹æ¡†å…³é—­å¤„理 */
    handleTerminateClose() {
      this.terminateVisible = false;
      this.resetTerminateForm();
    },
    /** ç»ˆæ­¢å‰çš„二次确认 */
    async confirmTermination() {
      try {
        await this.$confirm(
          `是否确认终止患者 ${this.patientInfo} çš„æçŒ®æ¡ˆä¾‹ï¼Ÿæ­¤æ“ä½œå°†ç»ˆæ­¢è¯¥æ‚£è€…的捐献进程。`,
          "警告",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
            closeOnClickModal: false,
            closeOnPressEscape: false
          }
        );
        return true;
      } catch (error) {
        console.log("用户取消终止操作");
        return false;
      }
    },
    /** æ¢å¤å‰çš„二次确认 */
    async confirmRestoration() {
      try {
        await this.$confirm(
          `是否确认恢复患者 ${this.patientInfo} çš„æçŒ®æ¡ˆä¾‹ï¼Ÿæ¢å¤åŽè¯¥æ¡ˆä¾‹å°†é‡æ–°è¿›å…¥æçŒ®æµç¨‹ã€‚`,
          "确认恢复",
          {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "info",
            closeOnClickModal: false,
            closeOnPressEscape: false
          }
        );
        return true;
      } catch (error) {
        console.log("用户取消恢复操作");
        return false;
      }
    },
    /** æäº¤ç»ˆæ­¢ */
    async handleTerminateSubmit() {
      try {
        // è¡¨å•验证
        await this.$refs.terminateFormRef.validate();
        if (!this.canSubmitTerminate) {
          this.$message.warning('请输入"确认终止"完成验证');
          return;
        }
        console.log(66);
        // äºŒæ¬¡ç¡®è®¤
        const userConfirmed = await this.confirmTermination();
        if (!userConfirmed) {
          return;
        }
        this.terminateLoading = true;
        // è°ƒç”¨ç»ˆæ­¢æŽ¥å£
        await updateDonatebaseinfo({
          id: this.currentRecord.id,
          caseNo: this.currentRecord.caseNo,
          terminationType: this.terminateForm.terminationType,
          terminationResult: this.terminateForm.terminationResult,
          terminationCase: 1
        });
        this.$message.success("终止成功");
        this.terminateVisible = false;
        // é€šçŸ¥çˆ¶ç»„件操作完成,需要刷新数据
        this.$emit("operation-success", {
          type: "terminate",
          record: this.currentRecord,
          terminationType: this.terminateForm.terminationType
        });
      } catch (error) {
        if (error instanceof Error) {
          this.$message.error("终止失败");
          console.error("终止错误:", error);
        }
        // éªŒè¯å¤±è´¥ä¸æ˜¾ç¤ºé”™è¯¯æ¶ˆæ¯
      } finally {
        this.terminateLoading = false;
      }
    },
    /** æäº¤æ¢å¤ */
    async handleRestoreSubmit() {
      try {
        // äºŒæ¬¡ç¡®è®¤
        const userConfirmed = await this.confirmRestoration();
        if (!userConfirmed) {
          return;
        }
        this.restoreLoading = true;
        // è°ƒç”¨æ¢å¤æŽ¥å£
        await updateDonatebaseinfo({
          id: this.currentRecord.id,
          caseNo: this.currentRecord.caseNo,
          terminationCase: 0
        });
        this.$message.success("恢复成功");
        this.restoreVisible = false;
        // é€šçŸ¥çˆ¶ç»„件操作完成,需要刷新数据
        this.$emit("operation-success", {
          type: "restore",
          record: this.currentRecord
        });
      } catch (error) {
        this.$message.error("恢复失败");
        console.error("恢复错误:", error);
      } finally {
        this.restoreLoading = false;
      }
    }
  }
};
</script>
<style scoped>
.patient-info {
  margin-bottom: 20px;
  font-size: 18px;
}
.terminate-form {
  margin-top: 15px;
}
/* å“åº”式调整 */
@media (max-width: 768px) {
  .patient-info ::v-deep .el-alert {
    padding: 8px 16px;
  }
  .terminate-form ::v-deep .el-form-item__label {
    width: 80px !important;
  }
  .terminate-form ::v-deep .el-form-item__content {
    margin-left: 80px !important;
  }
}
</style>
src/views/business/affirm/affirmInfo.vue
@@ -5,10 +5,10 @@
      <div slot="header" class="clearfix">
        <span class="detail-title">捐献确认基本信息</span>
        <el-button
          v-if="$route.query.confirm"
          type="primary"
          style="float: right; padding: 3px 0"
          type="success"
          style="float: right;"
          @click="handleSave"
          :loading="saveLoading"
        >
          ä¿å­˜ç¡®è®¤ä¿¡æ¯
        </el-button>
@@ -18,23 +18,19 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="住院号" prop="caseNo">
              <el-input v-model="form.caseNo" :readonly="!isEdit" />
              <el-input v-model="form.caseNo" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="捐献者姓名" prop="donorName">
              <el-input v-model="form.donorName" :readonly="!isEdit" />
            <el-form-item label="捐献者姓名" prop="name">
              <el-input v-model="form.name" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="性别" prop="gender">
              <el-select
                v-model="form.gender"
                :disabled="!isEdit"
                style="width: 100%"
              >
                <el-option label="男" value="0" />
                <el-option label="女" value="1" />
            <el-form-item label="性别" prop="sex">
              <el-select v-model="form.sex" style="width: 100%">
                <el-option label="男" value="1" />
                <el-option label="女" value="2" />
              </el-select>
            </el-form-item>
          </el-col>
@@ -43,91 +39,158 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="年龄" prop="age">
              <el-input v-model="form.age" :readonly="!isEdit" />
              <el-input v-model="form.age" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="疾病诊断" prop="diagnosis">
              <el-input v-model="form.diagnosis" :readonly="!isEdit" />
            <el-form-item label="疾病诊断" prop="diagnosisname">
              <el-input v-model="form.diagnosisname" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="所在医疗机构" prop="hospitalName">
              <el-input v-model="form.hospitalName" :readonly="!isEdit" />
            <el-form-item label="所在医疗机构" prop="treatmenthospitalname">
              <el-input v-model="form.treatmenthospitalname" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="协调员1" prop="coordinator1">
              <el-input v-model="form.coordinator1" :readonly="!isEdit" />
            <el-form-item label="协调员1" prop="coordinatedusernameo">
              <el-input v-model="form.coordinatedusernameo" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="协调员2" prop="coordinator2">
              <el-input v-model="form.coordinator2" :readonly="!isEdit" />
            <el-form-item label="协调员2" prop="coordinatedusernamet">
              <el-input v-model="form.coordinatedusernamet" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="业务人员" prop="assignee">
              <el-input v-model="form.assignee" :readonly="!isEdit" />
            <el-form-item label="业务人员" prop="responsibleusername">
              <el-input v-model="form.responsibleusername" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="确认状态" prop="confirmationStatus">
          <!-- <el-col :span="8">
            <el-form-item label="确认状态" prop="relativeconfirmationsign">
              <el-select
                v-model="form.confirmationStatus"
                v-model="form.relativeconfirmationsign"
                style="width: 100%"
              >
                <el-option label="未确认" value="0" />
                <el-option label="家属确认" value="1" />
                <el-option label="不同意捐献" value="2" />
              </el-select>
            </el-form-item>
          </el-col>
          </el-col> -->
          <el-col :span="8">
            <el-form-item label="确认时间" prop="confirmationTime">
            <el-form-item label="签字时间" prop="signdate">
              <el-date-picker
                v-model="form.confirmationTime"
                v-model="form.signdate"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                value-format="yyyy-MM-dd"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <!-- <el-col :span="8">
            <el-form-item label="血型" prop="bloodtype">
              <el-input v-model="form.bloodtype"  />
            </el-form-item>
          </el-col> -->
        </el-row>
        <!-- <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="证件号码" prop="idcardno">
              <el-input v-model="form.idcardno"  />
            </el-form-item>
          </el-col>
        </el-row> -->
        <!-- äº²å±žä¿¡æ¯ -->
        <!-- äº²å±žä¿¡æ¯ -->
        <el-divider content-position="left">亲属确认信息</el-divider>
        <el-row :gutter="20">
          <el-col :span="6">
            <el-form-item label="亲属姓名" prop="relativeconfirmationsignname">
              <el-input
                v-model="form.relativeconfirmationsignname"
                placeholder="请输入亲属姓名"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="与捐赠者关系" prop="familyrelations">
              <el-select
                v-model="form.familyrelations"
                placeholder="请选择与捐赠者关系"
              >
                <el-option
                  v-for="dict in dict.type.sys_FamilyRelation || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="亲属身份证" prop="relativeidcardno">
              <el-input
                v-model="form.relativeidcardno"
                placeholder="请输入亲属证件号码"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="亲属电话" prop="relativephone">
              <el-input
                v-model="form.relativephone"
                placeholder="请输入亲属联系电话"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="家属意见备注" prop="familyRemark">
        <el-row>
          <el-form-item label-width="100px" label="捐献决定">
            <el-checkbox-group v-model="organdecision">
              <el-checkbox
                v-for="item in organselection"
                :key="item"
                :label="item"
                >{{ item }}
              </el-checkbox>
            </el-checkbox-group>
            <el-input
              v-if="organdecision.includes('其他')"
              v-model="organdecisionOther"
              placeholder="请输入其他捐献决定的具体内容"
              style="margin-top: 10px; width: 300px;"
            ></el-input>
          </el-form-item>
        </el-row>
        <el-form-item label="家属意见备注" prop="relativeRemark">
          <el-input
            type="textarea"
            :rows="3"
            v-model="form.familyRemark"
            :readonly="!isEdit"
            v-model="form.relativeRemark"
            placeholder="记录家属的意见和沟通情况"
          />
        </el-form-item>
      </el-form>
    </el-card>
    <!-- é™„件列表 -->
    <!-- é™„件信息 - æŒ‰ç±»åž‹åˆ†ç±» -->
    <el-card class="attachment-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">相关附件上传</span>
        <el-button
          v-if="isEdit"
          type="primary"
          size="mini"
          @click="handleSaveAll"
          :loading="saveLoading"
        >
          ä¿å­˜æ‰€æœ‰é™„ä»¶
        </el-button>
      </div>
      <!-- é™„件类型选项卡 -->
@@ -138,8 +201,8 @@
          :label="type.label"
          :name="type.value"
        >
          <div class="attachment-upload-section">
            <div class="upload-header">
          <div class="attachment-section">
            <div class="attachment-header">
              <span class="upload-title">{{ type.label }}</span>
              <el-tooltip content="点击上传该类型附件" placement="top">
                <el-button
@@ -147,28 +210,35 @@
                  type="primary"
                  icon="el-icon-plus"
                  @click="openUploadDialog(type.value)"
                  :disabled="!isEdit"
                >
                  æ·»åР附件
                </el-button>
              </el-tooltip>
            </div>
            <!-- é™„件列表 -->
            <!-- å½“前类型的附件列表 -->
            <div class="attachment-list">
            <el-table
              :data="getAttachmentsByType(type.value)"
                size="small"
              v-loading="attachmentLoading"
              style="width: 100%; margin-top: 15px;"
                style="width: 100%;"
            >
              <el-table-column label="文件名称" min-width="200">
                <el-table-column label="文件名" min-width="200">
                <template slot-scope="scope">
                  <div class="file-info">
                    <i
                      class="el-icon-document"
                      style="margin-right: 8px; color: #409EFF;"
                      style="color: #409EFF; margin-right: 8px;"
                    ></i>
                    <span>{{ scope.row.fileName }}</span>
                  </div>
                    <span class="file-name">{{ scope.row.fileName }}</span>
                  </template>
                </el-table-column>
                <el-table-column label="文件类型" width="100" align="center">
                  <template slot-scope="scope">
                    <el-tag size="small">{{
                      getFileType(scope.row.fileName)
                    }}</el-tag>
                </template>
              </el-table-column>
@@ -180,64 +250,47 @@
              <el-table-column label="上传时间" width="160" align="center">
                <template slot-scope="scope">
                  <span>{{ parseTime(scope.row.uploadTime) }}</span>
                    <span>{{ formatDateTime(scope.row.uploadTime) }}</span>
                </template>
              </el-table-column>
              <el-table-column label="上传人" width="100" align="center">
                <template slot-scope="scope">
                  <span>{{ scope.row.uploader }}</span>
                </template>
              </el-table-column>
              <el-table-column
                label="操作"
                width="120"
                align="center"
                v-if="isEdit"
              >
                <el-table-column label="操作" width="150" align="center">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-view"
                      type="primary"
                    @click="handlePreview(scope.row)"
                    >预览</el-button
                  >
                      é¢„览
                    </el-button>
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-delete"
                    style="color: #F56C6C;"
                    @click="handleRemoveAttachment(scope.row, type.value)"
                    >删除</el-button
                      type="danger"
                      @click="handleRemoveAttachment(type.value, scope.$index)"
                  >
                </template>
              </el-table-column>
              <el-table-column label="操作" width="80" align="center" v-else>
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    type="text"
                    icon="el-icon-view"
                    @click="handlePreview(scope.row)"
                    >预览</el-button
                  >
                      åˆ é™¤
                    </el-button>
                </template>
              </el-table-column>
            </el-table>
              <!-- ç©ºçŠ¶æ€æç¤º -->
            <div
              v-if="getAttachmentsByType(type.value).length === 0"
              class="empty-attachment"
            >
              <el-empty description="暂无附件" :image-size="80"></el-empty>
                <el-empty
                  :description="`暂无${type.label}附件`"
                  :image-size="80"
                ></el-empty>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <!-- ä¸Šä¼ å¯¹è¯æ¡† -->
    <el-dialog
      :title="`上传${getCurrentTypeLabel}附件`"
      :visible.sync="uploadDialogVisible"
@@ -276,17 +329,27 @@
        </el-button>
      </span>
    </el-dialog>
    <!-- æ–‡ä»¶é¢„览弹窗 -->
    <FilePreviewDialog
      :visible="previewVisible"
      :file="currentPreviewFile"
      @close="previewVisible = false"
      @download="handleDownload"
    />
  </div>
</template>
<script>
import {
  getConfirmationDetail,
  updateConfirmation
} from "./mockConfirmationApi";
import { relativesList, relativesEdit } from "@/api/businessApi";
import FilePreviewDialog from "@/components/FilePreviewDialog";
export default {
  name: "ConfirmationDetail",
  components: {
    FilePreviewDialog
  },
  dicts: ["sys_FamilyRelation"],
  data() {
    return {
      // æ˜¯å¦ç¼–辑模式
@@ -294,28 +357,53 @@
      // è¡¨å•数据
      form: {
        id: undefined,
        infoid: undefined,
        caseNo: "",
        donorName: "",
        gender: "",
        name: "",
        sex: "",
        age: "",
        diagnosis: "",
        hospitalName: "",
        coordinator1: "",
        coordinator2: "",
        assignee: "",
        confirmationStatus: "0",
        confirmationTime: "",
        familyRemark: ""
        diagnosisname: "",
        treatmenthospitalname: "",
        coordinatedusernameo: "",
        coordinatedusernamet: "",
        responsibleusername: "",
        relativeconfirmationsign: "0",
        signdate: "",
        relativeconfirmationsignname: "",
        familyrelations: "",
        relativeidcardno: "",
        relativephone: "",
        relativeRemark: "",
        assessannex: "" // JSON字符串存储所有附件
      },
      // é™„件列表
      organdecision: [],
      organdecisionOther: "",
      organselection: [
        "肝脏",
        "双肾",
        "左肾",
        "右肾",
        "心脏",
        "肺脏",
        "胰腺",
        "小肠",
        "双眼组织",
        "遗体",
        "其他"
      ],
      // åŠ è½½çŠ¶æ€
      loading: false,
      saveLoading: false,
      // é™„件相关数据
      activeAttachmentType: "1",
      attachmentLoading: false,
      uploadDialogVisible: false,
      uploadLoading: false,
      saveLoading: false,
      tempFileList: [],
      currentUploadType: "",
      // é¢„览相关
      previewVisible: false,
      currentPreviewFile: null,
      // é™„件类型定义
      attachmentTypes: [
@@ -327,36 +415,18 @@
        { value: "6", label: "心死亡判定知情同意书" }
      ],
      // é™„件列表数据
      attachmentList: [
        // æ¨¡æ‹Ÿæ•°æ® - å®žé™…项目中从接口获取
        {
          id: 1,
          type: "1",
          typeName: "人体器官潜在捐献者登记表",
          fileName: "潜在捐献者登记表_202512001.pdf",
          fileSize: 2548321,
          uploadTime: "2025-12-01 10:30:00",
          uploader: "张三",
          fileUrl: "/attachments/1.pdf"
        },
        {
          id: 2,
          type: "1",
          typeName: "人体器官潜在捐献者登记表",
          fileName: "补充说明.docx",
          fileSize: 512345,
          uploadTime: "2025-12-01 14:20:00",
          uploader: "李四",
          fileUrl: "/attachments/2.docx"
      // é™„件数据结构 - æŒ‰ç±»åž‹åˆ†å¼€å­˜å‚¨
      attachmentData: {
        "1": [], // ç±»åž‹1的附件列表
        "2": [],
        "3": [],
        "4": [],
        "5": [],
        "6": []
        }
      ]
    };
  },
  computed: {
    isEdit() {
      return this.$route.query.confirm === "true";
    },
    getCurrentTypeLabel() {
      const type = this.attachmentTypes.find(
        t => t.value === this.currentUploadType
@@ -365,113 +435,119 @@
    }
  },
  created() {
    const id = this.$route.query.id;
    const infoid = this.$route.query.infoid;
    this.isEdit = this.$route.query.confirm === "true";
    if (id) {
      this.getDetail(id);
    if (infoid) {
      this.getDetail(infoid);
    }
    this.getAttachmentList();
  },
  methods: {
    // èŽ·å–è¯¦æƒ…
    getDetail(id) {
      getConfirmationDetail(id).then(response => {
    async getDetail(infoid) {
      this.loading = true;
      try {
        const response = await relativesList({ infoid });
        if (response.code === 200) {
          this.form = response.data;
          this.handleDetailData(response);
        } else {
          this.$message.error("获取详情失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        console.error("获取捐献确认详情失败:", error);
        this.$message.error("获取详情失败");
      } finally {
        this.loading = false;
      }
    },
    // å¤„理详情数据
    handleDetailData(response) {
      let detailData = null;
      // æ ¹æ®æŽ¥å£å®žé™…返回的数据结构进行调整
      if (response.data) {
        if (Array.isArray(response.data)) {
          detailData = response.data[0] || {};
        } else if (response.data.rows && Array.isArray(response.data.rows)) {
          detailData = response.data.rows[0] || {};
        } else if (Array.isArray(response.data.list)) {
          detailData = response.data.list[0] || {};
        } else {
          detailData = response.data;
        }
      } else {
        detailData = response;
      }
      // æ˜ å°„字段到表单
      this.form = {
        ...this.form,
        id: detailData.id || this.$route.query.id,
        infoid: detailData.infoid || infoid,
        caseNo: detailData.caseNo || "",
        name: detailData.name || "",
        sex: detailData.sex || "",
        age: detailData.age || "",
        diagnosisname: detailData.diagnosisname || "",
        treatmenthospitalname: detailData.treatmenthospitalname || "",
        coordinatedusernameo: detailData.coordinatedusernameo || "",
        coordinatedusernamet: detailData.coordinatedusernamet || "",
        responsibleusername: detailData.responsibleusername || "",
        relativeconfirmationsign: detailData.relativeconfirmationsign || "0",
        signdate: detailData.signdate,
        relativeconfirmationsignname:
          detailData.relativeconfirmationsignname || "",
        familyrelations: detailData.familyrelations || "",
        relativeidcardno: detailData.relativeidcardno || "",
        relativephone: detailData.relativephone || "",
        relativeRemark: detailData.relativeRemark || "",
        assessannex: detailData.assessannex || ""
      };
      // å¤„理捐献决定数据
      if (detailData.organdecision) {
        this.organdecision = Array.isArray(detailData.organdecision)
          ? detailData.organdecision
          : detailData.organdecision.split(",");
      }
      // å¤„理附件数据 - ä»Žassessannex字段解析JSON并按类型分类
      this.processAssessannexData();
    },
    // å¤„理assessannex字段数据并按类型分类
    processAssessannexData() {
      if (this.form.assessannex) {
        try {
          const annexData =
            typeof this.form.assessannex === "string"
              ? JSON.parse(this.form.assessannex)
              : this.form.assessannex;
          // æ¸…空现有数据
          Object.keys(this.attachmentData).forEach(key => {
            this.attachmentData[key] = [];
      });
    },
    // èŽ·å–é™„ä»¶åˆ—è¡¨
    getAttachmentList() {
      this.attachmentLoading = true;
      // æ¨¡æ‹Ÿé™„件数据
      this.attachmentList = [
        {
          id: 1,
          type: "1",
          typeName: "人体器官潜在捐献者登记表",
          fileName: "潜在捐献者登记表_202512001.pdf",
          uploadTime: "2025-12-01 10:30:00",
          uploader: "张三",
          fileSize: "2.5MB",
          fileUrl: "/attachments/1.pdf"
        },
        {
          id: 2,
          type: "2",
          typeName: "人体器官捐献亲属确认登记表",
          fileName: "亲属确认登记表_202512001.pdf",
          uploadTime: "2025-12-01 14:20:00",
          uploader: "李四",
          fileSize: "1.8MB",
          fileUrl: "/attachments/2.pdf"
        },
        {
          id: 3,
          type: "3",
          typeName: "捐献者及直系亲属身份证、户口簿相关证明",
          fileName: "身份证明_202512001.zip",
          uploadTime: "2025-12-01 16:45:00",
          uploader: "王五",
          fileSize: "5.2MB",
          fileUrl: "/attachments/3.zip"
        },
        {
          id: 4,
          type: "4",
          typeName: "公民身故后人体器官(角膜)遗体捐献告知书",
          fileName: "捐献告知书_202512001.pdf",
          uploadTime: "2025-12-02 09:15:00",
          uploader: "张三",
          fileSize: "1.2MB",
          fileUrl: "/attachments/4.pdf"
        },
        {
          id: 5,
          type: "5",
          typeName: "脑死亡判定知情同意书",
          fileName: "脑死亡判定同意书_202512001.pdf",
          uploadTime: "2025-12-02 11:30:00",
          uploader: "李四",
          fileSize: "0.8MB",
          fileUrl: "/attachments/5.pdf"
        },
        {
          id: 6,
          type: "6",
          typeName: "心死亡判定知情同意书",
          fileName: "心死亡判定同意书_202512001.pdf",
          uploadTime: "2025-12-02 13:20:00",
          uploader: "王五",
          fileSize: "0.9MB",
          fileUrl: "/attachments/6.pdf"
        }
      ];
      this.attachmentLoading = false;
    },
    // ä¸‹è½½é™„ä»¶
    handleDownload(row) {
      // å®žé™…项目中这里调用文件下载接口
      this.$message.success(`下载文件: ${row.fileName}`);
      console.log("下载文件:", row.fileUrl);
    },
    // ä¿å­˜ç¡®è®¤ä¿¡æ¯
    handleSave() {
      this.$refs.form.validate(valid => {
        if (valid) {
          updateConfirmation(this.form).then(response => {
            if (response.code === 200) {
              this.$message.success("保存成功");
              this.isEdit = false;
              this.$router.push("/case/confirmation");
          // æŒ‰ç±»åž‹åˆ†ç±»å­˜å‚¨
          if (Array.isArray(annexData)) {
            annexData.forEach(attachment => {
              const type = attachment.type || "1"; // é»˜è®¤åˆ°ç¬¬ä¸€ç§ç±»åž‹
              if (this.attachmentData[type]) {
                this.attachmentData[type].push(attachment);
            }
          });
        }
      });
        } catch (error) {
          console.warn("assessannex数据解析失败:", error);
        }
      }
    },
 // æ ¹æ®ç±»åž‹èŽ·å–é™„ä»¶
    // æ ¹æ®ç±»åž‹èŽ·å–é™„ä»¶åˆ—è¡¨
    getAttachmentsByType(type) {
      return this.attachmentList.filter(item => item.type === type);
      return this.attachmentData[type] || [];
    },
    // æ‰“开上传对话框
@@ -486,35 +562,38 @@
      });
    },
    // ä¸Šä¼ å‰æ ¡éªŒ
    // ä¸Šä¼ å‰æ ¡éªŒ[7](@ref)
    beforeUpload(file) {
      const allowedTypes = [
        'application/pdf',
        'image/jpeg',
        'image/png',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
        "application/pdf",
        "image/jpeg",
        "image/png",
        "application/msword",
        "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
      ];
      const maxSize = 10 * 1024 * 1024; // 10MB
      // æ ¡éªŒæ–‡ä»¶ç±»åž‹
      const isTypeOk = allowedTypes.includes(file.type) ||
                      file.name.endsWith('.pdf') ||
                      file.name.endsWith('.jpg') ||
                      file.name.endsWith('.jpeg') ||
                      file.name.endsWith('.png') ||
                      file.name.endsWith('.doc') ||
                      file.name.endsWith('.docx');
      const isTypeOk =
        allowedTypes.includes(file.type) ||
        file.name.endsWith(".pdf") ||
        file.name.endsWith(".jpg") ||
        file.name.endsWith(".jpeg") ||
        file.name.endsWith(".png") ||
        file.name.endsWith(".doc") ||
        file.name.endsWith(".docx");
      if (!isTypeOk) {
        this.$message.error('文件格式不支持,请上传pdf、jpg、png、doc或docx格式文件');
        this.$message.error(
          "文件格式不支持,请上传pdf、jpg、png、doc或docx格式文件"
        );
        return false;
      }
      // æ ¡éªŒæ–‡ä»¶å¤§å°
      if (file.size > maxSize) {
        this.$message.error('文件大小不能超过10MB');
        this.$message.error("文件大小不能超过10MB");
        return false;
      }
@@ -533,25 +612,29 @@
    // è‡ªå®šä¹‰ä¸Šä¼ è¯·æ±‚
    handleHttpRequest(options) {
      // æ¨¡æ‹Ÿä¸Šä¼ è¿‡ç¨‹
      return new Promise((resolve, reject) => {
        this.uploadLoading = true;
        // æ¨¡æ‹Ÿä¸Šä¼ å»¶è¿Ÿ
        // æ¨¡æ‹Ÿä¸Šä¼ è¿‡ç¨‹
        setTimeout(() => {
          const newAttachment = {
            id: Date.now(),
            type: this.currentUploadType,
            typeName: this.getCurrentTypeLabel,
            fileName: options.file.name,
            fileUrl: URL.createObjectURL(options.file),
            fileSize: options.file.size,
            fileType: this.getFileExtension(options.file.name),
            type: this.currentUploadType, // è®°å½•附件类型
            uploadTime: new Date().toISOString(),
            uploader: '当前用户', // å®žé™…项目中从用户信息获取
            fileUrl: URL.createObjectURL(options.file) // ä¸´æ—¶URL,实际项目中为服务器返回的URL
            uploader: "当前用户"
          };
          this.attachmentList.push(newAttachment);
          // æ·»åŠ åˆ°å¯¹åº”ç±»åž‹çš„é™„ä»¶åˆ—è¡¨
          if (this.attachmentData[this.currentUploadType]) {
            this.attachmentData[this.currentUploadType].push(newAttachment);
          }
          this.uploadLoading = false;
          this.updateAssessannexField(); // æ›´æ–°å­˜å‚¨å­—段
          resolve({ code: 200, data: newAttachment });
        }, 1500);
      });
@@ -560,90 +643,184 @@
    // æäº¤ä¸Šä¼ 
    async submitUpload() {
      if (this.tempFileList.length === 0) {
        this.$message.warning('请先选择要上传的文件');
        this.$message.warning("请先选择要上传的文件");
        return;
      }
      try {
        // ä¾æ¬¡ä¸Šä¼ æ‰€æœ‰æ–‡ä»¶
        for (const file of this.tempFileList) {
          await this.$refs.uploadRef.submit();
        }
        this.$message.success('文件上传成功');
        this.$message.success("文件上传成功");
        this.uploadDialogVisible = false;
        this.tempFileList = [];
      } catch (error) {
        this.$message.error('文件上传失败');
        console.error('上传失败:', error);
        this.$message.error("文件上传失败");
        console.error("上传失败:", error);
      }
    },
    // åˆ é™¤é™„ä»¶
    handleRemoveAttachment(attachment, type) {
      this.$confirm('确定要删除这个附件吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const index = this.attachmentList.findIndex(item => item.id === attachment.id);
        if (index !== -1) {
          this.attachmentList.splice(index, 1);
          this.$message.success('附件删除成功');
          // å®žé™…项目中调用删除接口
          // this.deleteAttachment(attachment.id);
    handleRemoveAttachment(type, index) {
      this.$confirm("确定要删除这个附件吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          if (this.attachmentData[type] && this.attachmentData[type][index]) {
            this.attachmentData[type].splice(index, 1);
            this.$message.success("附件删除成功");
            this.updateAssessannexField(); // æ›´æ–°å­˜å‚¨å­—段
        }
      }).catch(() => {});
        })
        .catch(() => {});
    },
    // é¢„览附件
    handlePreview(attachment) {
      // å®žé™…项目中根据文件类型调用不同的预览方式
      if (attachment.fileName.endsWith('.pdf')) {
        // PDF预览
        window.open(attachment.fileUrl, '_blank');
      } else if (attachment.fileName.match(/\.(jpg|jpeg|png)$/i)) {
        // å›¾ç‰‡é¢„览
        this.$alert(`<img src="${attachment.fileUrl}" style="max-width: 100%;" alt="${attachment.fileName}">`,
          '图片预览', {
            dangerouslyUseHTMLString: true,
            customClass: 'image-preview-dialog'
    // æ›´æ–°assessannex存储字段
    updateAssessannexField() {
      // å°†æ‰€æœ‰ç±»åž‹çš„附件合并为一个数组
      const allAttachments = [];
      Object.values(this.attachmentData).forEach(attachments => {
        allAttachments.push(...attachments);
          });
      // æ›´æ–°åˆ°è¡¨å•字段
      this.form.assessannex = JSON.stringify(allAttachments);
    },
    // æ–‡ä»¶é¢„览
    handlePreview(file) {
      this.currentPreviewFile = {
        fileName: file.fileName,
        fileUrl: file.fileUrl,
        fileType: this.getFileType(file.fileName)
      };
      this.previewVisible = true;
    },
    // æ–‡ä»¶ä¸‹è½½
    handleDownload(file) {
      const fileUrl = file.fileUrl;
      const fileName = file.fileName;
      if (fileUrl) {
        const link = document.createElement("a");
        link.href = fileUrl;
        link.download = fileName;
        link.style.display = "none";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        this.$message.success("开始下载文件");
      } else {
        // å…¶ä»–文件类型提示下载
        this.$message.info('该文件类型暂不支持在线预览,请下载后查看');
        this.$message.warning("文件路径不存在,无法下载");
      }
    },
    // ä¿å­˜æ‰€æœ‰é™„件信息
    handleSaveAll() {
      this.saveLoading = true;
    // èŽ·å–æ–‡ä»¶ç±»åž‹
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = this.getFileExtension(fileName);
      const imageTypes = ["jpg", "jpeg", "png"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx"];
      // æ¨¡æ‹Ÿä¿å­˜è¿‡ç¨‹
      setTimeout(() => {
        this.$message.success('附件信息保存成功');
        this.saveLoading = false;
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      if (officeTypes.includes(extension)) return "office";
      return "other";
    },
        // å®žé™…项目中调用保存接口
        // this.saveAttachments();
      }, 1000);
    // èŽ·å–æ–‡ä»¶æ‰©å±•å
    getFileExtension(filename) {
      return filename
        .split(".")
        .pop()
        .toLowerCase();
    },
    // æ–‡ä»¶å¤§å°æ ¼å¼åŒ–
    formatFileSize(size) {
      if (size === 0) return '0 B';
      if (!size) return "0 B";
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const sizes = ["B", "KB", "MB", "GB"];
      const i = Math.floor(Math.log(size) / Math.log(k));
      return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
      return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
    },
    // æ—¶é—´æ ¼å¼åŒ–
    parseTime(time) {
      if (!time) return '';
      const date = new Date(time);
      return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
    // æ—¥æœŸæ—¶é—´æ ¼å¼åŒ–
    formatDateTime(dateTime) {
      if (!dateTime) return "";
      try {
        const date = new Date(dateTime);
        if (isNaN(date.getTime())) return dateTime;
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, "0");
        const day = String(date.getDate()).padStart(2, "0");
        const hours = String(date.getHours()).padStart(2, "0");
        const minutes = String(date.getMinutes()).padStart(2, "0");
        return `${year}-${month}-${day} ${hours}:${minutes}`;
      } catch (error) {
        return dateTime;
      }
    },
    // èŽ·å–å½“å‰æ—¶é—´
    getCurrentTime() {
      const now = new Date();
      return `${now.getFullYear()}-${(now.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${now
        .getDate()
        .toString()
        .padStart(2, "0")} ${now
        .getHours()
        .toString()
        .padStart(2, "0")}:${now
        .getMinutes()
        .toString()
        .padStart(2, "0")}:${now
        .getSeconds()
        .toString()
        .padStart(2, "0")}`;
    },
    // ä¿å­˜ç¡®è®¤ä¿¡æ¯
    async handleSave() {
      try {
        await this.$refs.form.validate();
        this.saveLoading = true;
        // ç¡®ä¿é™„件数据是最新的
        this.updateAssessannexField();
        const saveData = {
          ...this.form,
          organdecision: this.organdecision.join(","),
          organdecisionOther: this.organdecisionOther
          // assessannex字段已在updateAssessannexField中更新
        };
        const response = await relativesEdit(saveData);
        if (response.code === 200) {
          this.$message.success("保存成功");
          this.$router.push("/case/confirmation");
        } else {
          this.$message.error("保存失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        if (error !== "cancel") {
          console.error("保存失败:", error);
          this.$message.error("保存失败");
        }
      } finally {
        this.saveLoading = false;
      }
    }
  }
};
@@ -665,37 +842,20 @@
.detail-title {
  font-size: 16px;
  font-weight: bold;
  margin-right: 20px;
}
.fixed-width .el-button {
  margin: 0 5px;
}
.confirmation-detail {
  padding: 20px;
.attachment-section {
  padding: 15px;
}
.detail-card {
  margin-bottom: 20px;
}
.attachment-card {
  margin-bottom: 20px;
}
.detail-title {
  font-size: 16px;
  font-weight: bold;
}
.attachment-upload-section {
  padding: 10px;
}
.upload-header {
.attachment-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}
.upload-title {
@@ -704,9 +864,8 @@
  color: #303133;
}
.file-info {
  display: flex;
  align-items: center;
.attachment-list {
  margin-top: 15px;
}
.empty-attachment {
@@ -715,13 +874,8 @@
  color: #909399;
}
/* å›¾ç‰‡é¢„览对话框样式 */
:deep(.image-preview-dialog) {
  width: auto;
  max-width: 90vw;
}
:deep(.image-preview-dialog .el-message-box__content) {
  text-align: center;
.file-name {
  font-size: 13px;
  color: #606266;
}
</style>
src/views/business/affirm/index.vue
@@ -35,7 +35,7 @@
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="确认状态" prop="confirmationStatus">
        <!-- <el-form-item label="确认状态" prop="confirmationStatus">
          <el-select
            v-model="queryParams.confirmationStatus"
            placeholder="请选择确认状态"
@@ -46,7 +46,7 @@
            <el-option label="家属确认" value="1" />
            <el-option label="不同意捐献" value="2" />
          </el-select>
        </el-form-item>
        </el-form-item> -->
        <el-form-item label="确认时间" prop="confirmationTimeRange">
          <el-date-picker
            v-model="queryParams.confirmationTimeRange"
@@ -121,14 +121,14 @@
        <el-table-column
          label="潜在捐献者姓名"
          align="center"
          prop="donorName"
          prop="name"
          width="120"
        />
        <el-table-column label="性别" align="center" prop="gender" width="80">
        <el-table-column label="性别" align="center" prop="sex" width="80">
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_user_sex"
              :value="parseInt(scope.row.gender)"
              :value="scope.row.sex"
            />
          </template>
        </el-table-column>
@@ -136,39 +136,47 @@
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosis"
          prop="diagnosisname"
          min-width="180"
          show-overflow-tooltip
        />
        <el-table-column
          label="所在医疗机构"
          align="center"
          prop="hospitalName"
          prop="treatmenthospitalname"
          width="150"
          show-overflow-tooltip
        />
        <!-- <el-table-column
          label="确认状态"
          align="center"
          prop="relativeconfirmationsign"
          width="120"
        >
          <template slot-scope="scope">
            <el-tag :type="statusFilter(scope.row.relativeconfirmationsign)">
              {{ statusTextFilter(scope.row.relativeconfirmationsign) }}
            </el-tag>
          </template>
        </el-table-column> -->
        <el-table-column
          label="家属意见"
          align="center"
          prop="relativeRemark"
          width="150"
          show-overflow-tooltip
        />
        <el-table-column
          label="确认状态"
          align="center"
          prop="confirmationStatus"
          width="120"
        >
          <template slot-scope="scope">
            <el-tag :type="statusFilter(scope.row.confirmationStatus)">
              {{ statusTextFilter(scope.row.confirmationStatus) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          label="确认时间"
          align="center"
          prop="confirmationTime"
          prop="signdate"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.confirmationTime
                ? parseTime(scope.row.confirmationTime, "{y}-{m}-{d}")
              scope.row.signdate
                ? parseTime(scope.row.signdate, "{y}-{m}-{d}")
                : "-"
            }}</span>
          </template>
@@ -176,19 +184,19 @@
        <el-table-column
          label="业务人员"
          align="center"
          prop="assignee"
          prop="responsibleusername"
          width="100"
        />
        <el-table-column
          label="协调员1"
          align="center"
          prop="coordinator1"
          prop="coordinatedusernameo"
          width="100"
        />
        <el-table-column
          label="协调员2"
          align="center"
          prop="coordinator2"
          prop="coordinatedusernamet"
          width="100"
        />
        <el-table-column
@@ -205,14 +213,14 @@
              @click.stop="handleView(scope.row)"
              >详情</el-button
            >
            <el-button
              v-if="scope.row.confirmationStatus === '0'"
            <!-- <el-button
              v-if="scope.row.relativeconfirmationsign === '0'"
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleConfirm(scope.row)"
              >确认</el-button
            >
            > -->
          </template>
        </el-table-column>
      </el-table>
@@ -230,7 +238,7 @@
</template>
<script>
import { listConfirmation, delConfirmation, exportConfirmation } from "./mockConfirmationApi";
import { relativesList } from "@/api/businessApi";
import Pagination from "@/components/Pagination";
export default {
@@ -285,23 +293,102 @@
      return statusMap[status] || "未知";
    },
    // æŸ¥è¯¢æçŒ®ç¡®è®¤åˆ—表
    getList() {
    async getList() {
      this.loading = true;
      listConfirmation(this.queryParams)
        .then(response => {
      try {
        // æž„建查询参数,映射到接口字段
        const requestParams = this.buildRequestParams();
        const response = await relativesList(requestParams);
          if (response.code === 200) {
          // å¤„理接口返回的数据结构
          this.handleResponseData(response);
        } else {
          this.$message.error("获取数据失败:" + (response.msg || "未知错误"));
          this.confirmationList = [];
          this.total = 0;
        }
      } catch (error) {
        console.error("获取捐献确认列表失败:", error);
        this.$message.error("获取数据失败");
        this.confirmationList = [];
        this.total = 0;
      } finally {
        this.loading = false;
      }
    },
    // æž„建请求参数
    buildRequestParams() {
      const params = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize
      };
      // æ˜ å°„查询条件到接口字段
      if (this.queryParams.donorName) {
        params.name = this.queryParams.donorName;
      }
      if (this.queryParams.hospitalName) {
        params.treatmenthospitalname = this.queryParams.hospitalName;
      }
      if (this.queryParams.assignee) {
        params.responsibleusername = this.queryParams.assignee;
      }
      // if (this.queryParams.confirmationStatus) {
      //   params.relativeconfirmationsign = this.queryParams.confirmationStatus;
      // }
      // å¤„理时间范围查询
      if (
        this.queryParams.confirmationTimeRange &&
        this.queryParams.confirmationTimeRange.length === 2
      ) {
        params.startSignDate = this.queryParams.confirmationTimeRange[0];
        params.endSignDate = this.queryParams.confirmationTimeRange[1];
      }
      return params;
    },
    // å¤„理接口响应数据
    handleResponseData(response) {
      // æ ¹æ®æŽ¥å£å®žé™…返回的数据结构进行调整
      if (response.data) {
        if (Array.isArray(response.data)) {
          // å¦‚果返回的是数组
          this.confirmationList = response.data;
          this.total = response.data.length;
        } else if (response.data.rows) {
          // å¦‚果返回的是分页数据结构
            this.confirmationList = response.data.rows;
            this.total = response.data.total;
        } else if (Array.isArray(response.data.list)) {
          // å¦‚果返回的是list字段
          this.confirmationList = response.data.list;
          this.total = response.data.total || response.data.list.length;
          } else {
            this.$message.error("获取数据失败");
          // å…¶ä»–数据结构,尝试直接使用data
          this.confirmationList = response.data;
          this.total = response.total || response.data.length;
          }
          this.loading = false;
        })
        .catch(error => {
          console.error("获取捐献确认列表失败:", error);
          this.loading = false;
          this.$message.error("获取数据失败");
        });
      } else {
        // å¦‚æžœdata为空,使用根级别的rows或list
        if (Array.isArray(response.rows)) {
          this.confirmationList = response.rows;
          this.total = response.total;
        } else if (Array.isArray(response.list)) {
          this.confirmationList = response.list;
          this.total = response.total;
        } else {
          this.confirmationList = [];
          this.total = 0;
        }
      }
      // ç¡®ä¿confirmationList是数组
      if (!Array.isArray(this.confirmationList)) {
        this.confirmationList = [];
      }
    },
    // æœç´¢æŒ‰é’®æ“ä½œ
    handleQuery() {
@@ -311,7 +398,8 @@
    // é‡ç½®æŒ‰é’®æ“ä½œ
    resetQuery() {
      this.$refs.queryForm.resetFields();
      this.handleQuery();
      this.queryParams.pageNum = 1;
      this.getList();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
@@ -323,14 +411,14 @@
    handleRowClick(row) {
      this.$router.push({
        path: "/case/affirmInfo",
        query: { id: row.id }
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // æŸ¥çœ‹è¯¦æƒ…
    handleView(row) {
      this.$router.push({
        path: "/case/affirmInfo",
        query: { id: row.id }
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // ç¡®è®¤æ“ä½œ
@@ -346,6 +434,8 @@
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate() {
      if (this.ids.length === 0) return;
      const id = this.ids[0];
      this.$router.push({
        path: "/case/confirmation/edit",
@@ -353,51 +443,78 @@
      });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ
    handleDelete() {
      const ids = this.ids;
      this.$confirm("是否确认删除选中的数据项?", "警告", {
    async handleDelete() {
      if (this.ids.length === 0) return;
      try {
        await this.$confirm("是否确认删除选中的数据项?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          return delConfirmation(ids);
        })
        .then(response => {
          if (response.code === 200) {
        });
        // è¿™é‡Œéœ€è¦è°ƒç”¨åˆ é™¤æŽ¥å£ï¼Œç”±äºŽæ‚¨åªæä¾›äº†relativesList接口,这里暂时注释
        // å®žé™…使用时需要调用对应的删除接口
        // const response = await delConfirmation(this.ids);
        // æ¨¡æ‹Ÿåˆ é™¤æˆåŠŸ
            this.$message.success("删除成功");
            this.getList();
        this.getList(); // é‡æ–°åŠ è½½æ•°æ®
      } catch (error) {
        if (error !== "cancel") {
          console.error("删除失败:", error);
          this.$message.error("删除失败");
          }
        })
        .catch(() => {});
      }
    },
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm("是否确认导出所有确认数据?", "警告", {
    async handleExport() {
      try {
        await this.$confirm("是否确认导出所有确认数据?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          this.loading = true;
          return exportConfirmation(queryParams);
        })
        .then(response => {
          if (response.code === 200) {
            this.$message.success("导出成功");
            // å®žé™…项目中这里处理文件下载
          }
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
        this.loading = true;
        // æž„建导出参数
        const exportParams = this.buildRequestParams();
        exportParams.pageSize = 10000; // å¯¼å‡ºæ‰€æœ‰æ•°æ®
        // èŽ·å–å¯¼å‡ºæ•°æ®
        const response = await relativesList(exportParams);
        if (response.code === 200) {
          // å¤„理导出数据
          this.exportDataToExcel(response.data);
          this.$message.success("导出成功");
        } else {
          this.$message.error("导出失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        if (error !== "cancel") {
          console.error("导出失败:", error);
          this.$message.error("导出失败");
        }
      } finally {
        this.loading = false;
      }
    },
    // å¯¼å‡ºæ•°æ®åˆ°Excel
    exportDataToExcel(data) {
      // è¿™é‡Œå®žçŽ°å¯¼å‡ºé€»è¾‘ï¼Œå¯ä»¥ä½¿ç”¨xlsx等库
      // ç”±äºŽæ˜¯å‰ç«¯å¯¼å‡ºï¼Œè¿™é‡Œç®€å•演示
      console.log("导出数据:", data);
      // å®žé™…项目中需要实现完整的Excel导出功能
    },
    // æ—¶é—´æ ¼å¼åŒ–
    parseTime(time, pattern) {
      if (!time) return "";
      const date = new Date(time);
      if (pattern) {
        // ç®€å•的模式匹配
        if (pattern === "{y}-{m}-{d}") {
      return `${date.getFullYear()}-${(date.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${date
@@ -406,6 +523,23 @@
        .padStart(2, "0")}`;
    }
  }
      return `${date.getFullYear()}-${(date.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${date
        .getDate()
        .toString()
        .padStart(2, "0")} ${date
        .getHours()
        .toString()
        .padStart(2, "0")}:${date
        .getMinutes()
        .toString()
        .padStart(2, "0")}:${date
        .getSeconds()
        .toString()
        .padStart(2, "0")}`;
    }
  }
};
</script>
src/views/business/assess/assessInfo.vue
@@ -17,44 +17,38 @@
          assessmentData.caseNo
        }}</el-descriptions-item>
        <el-descriptions-item label="潜在捐献者姓名">{{
          assessmentData.donorName
          assessmentData.name || assessmentData.donorName
        }}</el-descriptions-item>
        <el-descriptions-item label="性别">
          <dict-tag :options="genderOptions" :value="assessmentData.gender" />
          <dict-tag
            :options="dict.type.sys_user_sex"
            :value="assessmentData.sex"
          />
        </el-descriptions-item>
        <el-descriptions-item label="年龄"
          >{{ assessmentData.age }}岁</el-descriptions-item
        >
        <el-descriptions-item label="血型">
          <dict-tag
            :options="bloodTypeOptions"
            :value="assessmentData.bloodType"
          />
          {{ assessmentData.bloodtype }}
        </el-descriptions-item>
        <el-descriptions-item label="证件号码">{{
          assessmentData.idCardNo
          assessmentData.idcardno
        }}</el-descriptions-item>
        <el-descriptions-item label="疾病诊断">{{
          assessmentData.diagnosis
          assessmentData.diagnosisname
        }}</el-descriptions-item>
        <el-descriptions-item label="所在医疗机构">{{
          assessmentData.hospitalName
          assessmentData.treatmenthospitalname
        }}</el-descriptions-item>
        <el-descriptions-item label="主治医生">{{
          assessmentData.doctorName
        <el-descriptions-item label="协调员">{{
          assessmentData.coordinatorName
        }}</el-descriptions-item>
        <el-descriptions-item label="申请评估时间">{{
          assessmentData.applyTime
        <el-descriptions-item label="评估时间">{{
          assessmentData.assessTime
        }}</el-descriptions-item>
        <el-descriptions-item label="评估类型">
          <dict-tag
            :options="assessmentTypeOptions"
            :value="assessmentData.assessmentType"
          />
        </el-descriptions-item>
        <el-descriptions-item label="评估状态">
          <el-tag :type="statusFilter(assessmentData.assessmentStatus)">
            {{ statusTextFilter(assessmentData.assessmentStatus) }}
          <el-tag :type="statusFilter(assessmentData.assessState)">
            {{ statusTextFilter(assessmentData.assessState) }}
          </el-tag>
        </el-descriptions-item>
      </el-descriptions>
@@ -69,6 +63,7 @@
          type="primary"
          size="mini"
          @click="handleCompleteAssessment"
          :loading="saveLoading"
        >
          ç¡®è®¤å®Œæˆè¯„ä¼°
        </el-button>
@@ -76,9 +71,15 @@
          å½“前角色:{{ currentDepartment }}评估人员
        </span>
      </div>
      <el-row>
        <el-form-item label-width="100px" label="评估器官">
          <el-checkbox-group v-model="organdecision">
      <!-- æçŒ®å†³å®šè¡¨å• -->
      <el-form>
        <el-form-item label-width="100px" label="捐献决定">
          <el-checkbox-group
            v-model="organdecision"
            @change="handleOrganDecisionChange"
            :disabled="!isEdit"
          >
            <el-checkbox
              v-for="item in organselection"
              :key="item"
@@ -88,22 +89,27 @@
          </el-checkbox-group>
          <el-input
            v-if="organdecision.includes('其他')"
            v-model="assessmentData.organdecisionOther"
            v-model="organdecisionOther"
            placeholder="请输入其他捐献决定的具体内容"
            style="margin-top: 10px; width: 300px;"
            :readonly="!isEdit"
            @input="handleOtherDecisionInput"
          ></el-input>
        </el-form-item>
      </el-row>
      </el-form>
      <!-- å™¨å®˜è¯„估表格 -->
      <el-table
        :data="organAssessmentList"
        :data="filteredOrganAssessmentList"
        v-loading="assessmentLoading"
        style="width: 100%"
        :row-class-name="getRowClassName"
        :expand-row-keys="expandedRowKeys"
        @expand-change="handleExpandChange"
        row-key="organType"
        row-key="organno"
        empty-text="当前捐献决定下暂无需要评估的器官"
      >
        <el-table-column type="expand" width="60">
        <el-table-column type="expand">
          <template slot-scope="scope">
            <div class="organ-expand-content" v-if="scope.row.expanded">
              <el-tabs
@@ -123,13 +129,15 @@
                    :assessment-data="assessment"
                    :assessment-index="index"
                    :readonly="!canAssessOrgan(scope.row)"
                    @save="handleSaveOrganAssessment"
                    @add-assessment="handleAddAssessment"
                  />
                </el-tab-pane>
                <!-- æ·»åŠ è¯„ä¼°æŒ‰é’® -->
                <el-tab-pane name="add" v-if="canAssessOrgan(scope.row)">
                <el-tab-pane
                  name="add"
                  v-if="canAssessOrgan(scope.row) && isEdit"
                >
                  <template slot="label">
                    <el-button
                      type="text"
@@ -150,10 +158,10 @@
                  <div class="assessment-summary">
                    <el-descriptions title="评估结果汇总" :column="2" border>
                      <el-descriptions-item label="器官类型">{{
                        scope.row.organName
                        scope.row.organname
                      }}</el-descriptions-item>
                      <el-descriptions-item label="评估科室">{{
                        scope.row.department
                      <el-descriptions-item label="获取机构">{{
                        scope.row.gainhospitalname
                      }}</el-descriptions-item>
                      <el-descriptions-item label="评估次数" :span="2">
                        <el-tag type="info"
@@ -165,34 +173,58 @@
                      </el-descriptions-item>
                    </el-descriptions>
                    <!-- é™„件汇总 -->
                    <el-card header="所有评估附件" style="margin-top: 20px;">
                      <el-table
                        :data="getAllAttachments(scope.row)"
                        size="small"
                        empty-text="暂无附件"
                    <!-- è¯„估详情汇总 -->
                    <el-card header="评估详情" style="margin-top: 20px;">
                      <el-descriptions :column="1" border>
                        <el-descriptions-item label="获取前活检">
                          <el-tag
                            :type="
                              scope.row.isbiopsybefore === '1'
                                ? 'success'
                                : 'info'
                            "
                      >
                        <el-table-column label="附件名称" prop="fileName" />
                        <el-table-column label="评估阶段" width="120">
                          <template slot-scope="{ row }">
                            ç¬¬{{ row.assessmentIndex + 1 }}次评估
                          </template>
                        </el-table-column>
                        <el-table-column
                          label="上传时间"
                          prop="uploadTime"
                          width="180"
                        />
                        <el-table-column label="操作" width="120">
                          <template slot-scope="{ row }">
                            <el-button
                              type="text"
                              @click="handlePreviewAttachment(row)"
                              >预览</el-button
                            {{ scope.row.isbiopsybefore === "1" ? "是" : "否" }}
                          </el-tag>
                        </el-descriptions-item>
                        <el-descriptions-item label="获取后活检">
                          <el-tag
                            :type="
                              scope.row.isbiopsyafter === '1'
                                ? 'success'
                                : 'info'
                            "
                            >
                          </template>
                        </el-table-column>
                      </el-table>
                            {{ scope.row.isbiopsyafter === "1" ? "是" : "否" }}
                          </el-tag>
                        </el-descriptions-item>
                        <el-descriptions-item label="边缘器官">
                          <el-tag
                            :type="
                              scope.row.ismarginalorgan === '1'
                                ? 'warning'
                                : 'info'
                            "
                          >
                            {{
                              scope.row.ismarginalorgan === "1" ? "是" : "否"
                            }}
                          </el-tag>
                        </el-descriptions-item>
                        <el-descriptions-item label="病原菌阳性">
                          <el-tag
                            :type="
                              scope.row.ispathogenpositive === '1'
                                ? 'danger'
                                : 'info'
                            "
                          >
                            {{
                              scope.row.ispathogenpositive === "1" ? "是" : "否"
                            }}
                          </el-tag>
                        </el-descriptions-item>
                      </el-descriptions>
                    </el-card>
                  </div>
                </el-tab-pane>
@@ -201,28 +233,16 @@
          </template>
        </el-table-column>
        <el-table-column
          label="器官类型"
          align="center"
          prop="organType"
          width="120"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="organTypeOptions"
              :value="scope.row.organType"
            />
          </template>
        </el-table-column>
        <el-table-column label="器官类型" align="center" prop="organname" />
        <el-table-column label="器官编号" align="center" prop="organnumber" />
        <el-table-column
          label="评估科室"
          label="获取机构"
          align="center"
          prop="department"
          width="120"
          prop="gainhospitalname"
          show-overflow-tooltip
        />
        <el-table-column label="评估人员" align="center" prop="assessor" />
        <!-- åŠ¨æ€æ˜¾ç¤ºè¯„ä¼°çŠ¶æ€åˆ— -->
        <el-table-column
@@ -247,10 +267,16 @@
        <el-table-column label="整体状态" align="center" width="100">
          <template slot-scope="scope">
            <el-tag
              :type="scope.row.assessmentStatus === '1' ? 'success' : 'primary'"
              :type="
                getOrganOverallStatus(scope.row) === 'completed'
                  ? 'success'
                  : getOrganOverallStatus(scope.row) === 'assessing'
                  ? 'primary'
                  : 'warning'
              "
              size="small"
            >
              {{ scope.row.assessmentStatus === "1" ? "已完成" : "评估中" }}
              {{ getOrganOverallStatusText(scope.row) }}
            </el-tag>
          </template>
        </el-table-column>
@@ -263,13 +289,23 @@
        >
          <template slot-scope="scope">
            <el-button
              v-if="canAssessOrgan(scope.row)"
              v-if="canAssessOrgan(scope.row) && isEdit"
              size="mini"
              type="text"
              @click="handleToggleExpand(scope.row)"
            >
              {{
                expandedRowKeys.includes(scope.row.organType) ? "收起" : "详情"
                expandedRowKeys.includes(scope.row.organno) ? "收起" : "详情"
              }}
            </el-button>
            <el-button
              v-else-if="!isEdit"
              size="mini"
              type="text"
              @click="handleToggleExpand(scope.row)"
            >
              {{
                expandedRowKeys.includes(scope.row.organno) ? "收起" : "查看"
              }}
            </el-button>
            <el-button v-else size="mini" type="text" disabled
@@ -279,6 +315,12 @@
        </el-table-column>
      </el-table>
    </el-card>
    <!-- æ•´ä½“保存按钮 -->
    <div class="footer-actions" v-if="isEdit">
      <el-button type="primary" @click="handleSaveAll" :loading="saveLoading">保存评估表</el-button>
      <el-button @click="handleCancel">取消</el-button>
    </div>
    <!-- æ–‡ä»¶é¢„览弹窗 -->
    <FilePreviewDialog
@@ -291,61 +333,38 @@
<script>
import {
  getAssessment,
  updateOrganAssessment,
  completeAssessment
} from "./mockAssessmentApi";
  evaluateBaseInfolist,
  assessedit,
  assessAdd
} from "@/api/businessApi/index";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import OrganAssessmentForm from "./components/OrganAssessmentForm.vue";
export default {
  name: "AssessmentDetail",
  components: { OrganAssessmentForm, FilePreviewDialog },
  dicts: ["sys_user_sex", "sys_Organ", "sys_0_1"],
  data() {
    return {
      assessmentId: undefined,
      assessmentData: {},
      organAssessmentList: [],
      attachmentList: [],
      // æ˜¯å¦ç¼–辑模式
      isEdit: false,
      // åŠ è½½çŠ¶æ€
      assessmentLoading: false,
      organdecision: [],
      saveLoading: false,
      // æ•°æ®ID
      infoid: undefined,
      assessmentId: undefined,
      // ä¸»è¦æ•°æ®
      assessmentData: {},
      organAssessmentList: [], // æ‰€æœ‰å™¨å®˜æ•°æ®
      // å±•开行相关
      expandedRowKeys: [],
      // é™„件相关
      currentPreviewFile: null,
      attachmentVisible: false,
      currentUser: {
        id: "001",
        name: "张医生",
        department: "协调员",
        role: "coordinator"
      },
      //department:心脏、coordinator:协调员
      // å­—典选项
      genderOptions: [
        { value: "0", label: "男" },
        { value: "1", label: "女" }
      ],
      bloodTypeOptions: [
        { value: "A", label: "A型" },
        { value: "B", label: "B型" },
        { value: "O", label: "O型" },
        { value: "AB", label: "AB型" }
      ],
      assessmentTypeOptions: [
        { value: "1", label: "初次评估" },
        { value: "2", label: "最终评估" }
      ],
      organTypeOptions: [
        { value: "heart", label: "心脏" },
        { value: "liver", label: "肝脏" },
        { value: "kidney", label: "肾脏" },
        { value: "lung", label: "肺脏" },
        { value: "pancreas", label: "胰腺" },
        { value: "intestine", label: "肠道" },
        { value: "cornea", label: "角膜" },
        { value: "skin", label: "皮肤" }
      ],
      // æçŒ®å†³å®šç›¸å…³
      organdecision: [],
      organdecisionOther: "",
      organselection: [
        "肝脏",
        "双肾",
@@ -358,7 +377,28 @@
        "双眼组织",
        "遗体",
        "其他"
      ]
      ],
      // å™¨å®˜ç±»åž‹æ˜ å°„关系
      organDecisionMapping: {
        è‚è„: ["肝脏"],
        åŒè‚¾: ["左肾", "右肾"],
        å·¦è‚¾: ["左肾"],
        å³è‚¾: ["右肾"],
        å¿ƒè„: ["心脏"],
        è‚ºè„: ["肺脏"],
        èƒ°è…º: ["胰腺"],
        å°è‚ : ["小肠"],
        åŒçœ¼ç»„织: ["角膜"],
        é—体: ["皮肤", "骨骼", "其他组织"],
        å…¶ä»–: [] // å…¶ä»–类型不映射具体器官
      },
      // ç”¨æˆ·ä¿¡æ¯
      currentUser: {
        id: "001",
        name: "张医生",
        department: "心脏科",
        role: "doctor" // coordinator, doctor
      }
    };
  },
  computed: {
@@ -368,8 +408,27 @@
    currentDepartment() {
      return this.currentUser.department;
    },
    // æ ¹æ®æçŒ®å†³å®šè¿‡æ»¤åŽçš„器官列表
    filteredOrganAssessmentList() {
      if (!this.organdecision || this.organdecision.length === 0) {
        return [];
      }
      // èŽ·å–æ‰€æœ‰é€‰ä¸­çš„å™¨å®˜ç±»åž‹
      const selectedOrgans = new Set();
      this.organdecision.forEach(decision => {
        const organs = this.organDecisionMapping[decision] || [];
        organs.forEach(organ => selectedOrgans.add(organ));
      });
      // è¿‡æ»¤å™¨å®˜è¯„估列表
      return this.organAssessmentList.filter(organ =>
        selectedOrgans.has(organ.organname)
      );
    },
    // æ£€æŸ¥æ‰€æœ‰è¿‡æ»¤åŽçš„器官是否都已评估
    allOrgansAssessed() {
      return this.organAssessmentList.every(
      return this.filteredOrganAssessmentList.every(
        organ =>
          organ.assessments &&
          organ.assessments.length > 0 &&
@@ -379,86 +438,364 @@
      );
    }
  },
  watch: {
    // ç›‘听捐献决定变化,用于复杂逻辑处理
    organdecision: {
      handler(newVal, oldVal) {
        this.handleComplexDecisionChange(newVal, oldVal);
      },
      deep: true
    }
  },
  created() {
    this.infoid = this.$route.query.infoid;
    this.assessmentId = this.$route.query.id;
    this.isEdit = this.$route.query.assess === "true";
    this.getAssessmentDetail();
  },
  methods: {
    // èŽ·å–é»˜è®¤è¯„ä¼°æ•°æ®ç»“æž„
    getDefaultAssessment() {
    // æ•´ä½“保存方法
    async handleSaveAll() {
      this.saveLoading = true;
      try {
        // 1. å‡†å¤‡ä¸»è¯„估表数据
        const saveData = {
          // æ ¹æ® id æ˜¯å¦å­˜åœ¨å†³å®šæ˜¯æ›´æ–°è¿˜æ˜¯æ–°å¢ž
          id: this.assessmentData.id || undefined,
          infoid: this.infoid,
          caseNo: this.assessmentData.caseNo,
          donorno: this.assessmentData.donorno,
          treatmenthospitalname: this.assessmentData.treatmenthospitalname,
          treatmenthospitalno: this.assessmentData.treatmenthospitalno,
          sex: this.assessmentData.sex,
          age: this.assessmentData.age,
          bloodtype: this.assessmentData.bloodtype,
          idcardno: this.assessmentData.idcardno,
          diagnosisname: this.assessmentData.diagnosisname,
          coordinatorName: this.assessmentData.coordinatorName,
          assessTime: this.assessmentData.assessTime || new Date().toISOString(),
          assessState: this.assessmentData.assessState,
          assessannex: this.assessmentData.assessannex,
          // æçŒ®å†³å®šä¿¡æ¯
          organdecision: this.organdecision.join(','),
          organdecisionOther: this.organdecisionOther,
          // å™¨å®˜è¯„估列表
          serviceMedicalevaluationorgans: this.organAssessmentList.map(organ => ({
            id: organ.id,
            infoid: organ.infoid,
            donorno: organ.donorno,
            organno: organ.organno,
            organname: organ.organname,
            organnumber: organ.organnumber,
            gainhospitalno: organ.gainhospitalno,
            gainhospitalname: organ.gainhospitalname,
            isbiopsybefore: organ.isbiopsybefore,
            isbiopsyafter: organ.isbiopsyafter,
            ismarginalorgan: organ.ismarginalorgan,
            ispathogenpositive: organ.ispathogenpositive,
            ispnf: organ.ispnf,
            isdgf: organ.isdgf,
            // å°† assessments æ•°ç»„序列化到 assesscontent å­—段
            assesscontent: JSON.stringify(organ.assessments)
          }))
        };
        // 2. æ ¹æ® id åˆ¤æ–­è°ƒç”¨å“ªä¸ª API
        const saveMethod = this.assessmentData.id ? assessedit : assessAdd;
        const response = await saveMethod(saveData);
        if (response.code === 200) {
          this.$message.success('评估表保存成功!');
          // ä¿å­˜æˆåŠŸåŽï¼Œæ›´æ–°æœ¬åœ°çš„ assessmentData.id(对于新增情况)
          if (!this.assessmentData.id && response.data && response.data.id) {
            this.assessmentData.id = response.data.id;
          }
        } else {
          this.$message.error('保存失败:' + (response.msg || '未知错误'));
        }
      } catch (error) {
        console.error('保存评估表失败:', error);
        this.$message.error('保存失败,请重试');
      } finally {
        this.saveLoading = false;
      }
    },
    // å–消按钮事件
    handleCancel() {
      this.$router.go(-1);
    },
    // æçŒ®å†³å®šå˜æ›´å¤„理
    handleOrganDecisionChange(newDecision) {
      // è‡ªåŠ¨å¤„ç†ç›¸å…³é€»è¾‘
      this.autoHandleDecisionChange(newDecision);
      // å¼ºåˆ¶é‡æ–°æ¸²æŸ“
      this.$forceUpdate();
      // å¦‚果从有选择变为无选择,清空展开状态
      if (newDecision.length === 0) {
        this.expandedRowKeys = [];
      }
    },
    // å…¶ä»–捐献决定输入处理
    handleOtherDecisionInput(value) {
      // è¾“入时不做单独保存,等待整体保存
    },
    // è‡ªåŠ¨å¤„ç†å†³å®šå˜æ›´é€»è¾‘
    autoHandleDecisionChange(newDecision) {
      // å¦‚果选择了"双肾",自动取消单独的"左肾"和"右肾"选择
      if (newDecision.includes("双肾")) {
        this.organdecision = newDecision.filter(
          item => item !== "左肾" && item !== "右肾"
        );
      }
      // å¦‚果选择了"左肾"或"右肾",取消"双肾"选择
      else if (newDecision.includes("左肾") || newDecision.includes("右肾")) {
        this.organdecision = newDecision.filter(item => item !== "双肾");
      }
      // å¤„理互斥逻辑
      this.handleExclusiveDecisions();
    },
    // å¤„理互斥的捐献决定
    handleExclusiveDecisions() {
      // é—体捐献与其他器官捐献互斥(根据业务需求调整)
      if (this.organdecision.includes("遗体")) {
        // å¯ä»¥è®¾ç½®åªä¿ç•™é—体捐献,或者根据业务需求处理
      }
    },
    // å¤æ‚决策变化处理
    handleComplexDecisionChange(newVal, oldVal) {
      // å¤„理新增的选择
      const addedDecisions = newVal.filter(item => !oldVal.includes(item));
      const removedDecisions = oldVal.filter(item => !newVal.includes(item));
      // å¯¹æ–°å¢žåŠ çš„é€‰æ‹©è¿›è¡Œç‰¹æ®Šå¤„ç†
      addedDecisions.forEach(decision => {
        this.handleNewDecision(decision);
      });
      // å¯¹ç§»é™¤çš„选择进行清理
      removedDecisions.forEach(decision => {
        this.handleRemovedDecision(decision);
      });
    },
    // å¤„理新增的捐献决定
    handleNewDecision(decision) {
      // æ ¹æ®æ˜ å°„关系自动创建对应的器官评估项
      this.autoCreateOrganAssessments(decision);
    },
    // è‡ªåŠ¨åˆ›å»ºå™¨å®˜è¯„ä¼°é¡¹
    autoCreateOrganAssessments(decision) {
      const organsToCreate = this.organDecisionMapping[decision];
      if (organsToCreate && organsToCreate.length > 0) {
        organsToCreate.forEach(organName => {
          this.ensureOrganExists(organName);
        });
        // æ˜¾ç¤ºåˆ›å»ºæç¤º
        if (organsToCreate.length > 0) {
          this.$message.success(
            `已为【${decision}】创建${organsToCreate.length}个评估项`
          );
        }
      } else {
        console.warn(`捐献决定【${decision}】没有配置器官映射关系`);
      }
    },
    // å¤„理移除的捐献决定
    handleRemovedDecision(decision) {
      // æ ¹æ®ä¸šåŠ¡éœ€æ±‚æ·»åŠ æ¸…ç†é€»è¾‘
      const relatedOrgans = this.organDecisionMapping[decision] || [];
      relatedOrgans.forEach(organ => {
        // å¯ä»¥åœ¨è¿™é‡Œæ·»åŠ æ¸…ç†ç›¸å…³å™¨å®˜è¯„ä¼°çš„é€»è¾‘
      });
    },
    // ç¡®ä¿å™¨å®˜å­˜åœ¨ï¼ˆå¸¦é‡å¤æ£€æŸ¥ï¼‰
    ensureOrganExists(organName) {
      // æ£€æŸ¥æ˜¯å¦å·²å­˜åœ¨åŒåå™¨å®˜è¯„估项
      const exists = this.organAssessmentList.some(
        organ => organ.organname === organName
      );
      if (!exists) {
        // åˆ›å»ºæ–°çš„器官评估项
        const newOrgan = {
          id: `organ_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
          organno: `ORG${Date.now()}`,
          organname: organName,
          gainhospitalname: "待分配机构",
          isbiopsybefore: "0",
          isbiopsyafter: "0",
          ismarginalorgan: "0",
          ispathogenpositive: "0",
          assessments: [this.getDefaultAssessment(0)],
          activeAssessmentTab: "assessment_0",
          expanded: false,
          createTime: new Date().toISOString()
        };
        this.organAssessmentList = [...this.organAssessmentList, newOrgan];
        return true;
      }
      return false;
    },
    // èŽ·å–è¯„ä¼°è¯¦æƒ…
    async getAssessmentDetail() {
      this.assessmentLoading = true;
      try {
        const response = await evaluateBaseInfolist({ infoid: this.infoid });
        if (response.code === 200) {
          this.handleResponseData(response);
        } else {
          this.$message.error("获取详情失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        console.error("获取评估详情失败:", error);
        this.$message.error("获取详情失败");
      } finally {
        this.assessmentLoading = false;
      }
    },
    // å¤„理接口响应数据
    handleResponseData(response) {
      let detailData = null;
      // æ ¹æ®æŽ¥å£å®žé™…返回的数据结构进行调整
      if (response.data) {
        if (Array.isArray(response.data)) {
          detailData = response.data[0] || {};
        } else if (response.data.rows && Array.isArray(response.data.rows)) {
          detailData = response.data.rows[0] || {};
        } else if (Array.isArray(response.data.list)) {
          detailData = response.data.list[0] || {};
        } else {
          detailData = response.data;
        }
      } else {
        detailData = response;
      }
      // æ˜ å°„字段到评估数据
      this.assessmentData = {
        id: detailData.id || this.assessmentId,
        infoid: detailData.infoid || this.infoid,
        caseNo: detailData.caseNo || "",
        name: detailData.name || detailData.donorName || "",
        sex: detailData.sex || "",
        age: detailData.age || "",
        bloodtype: detailData.bloodtype || "",
        idcardno: detailData.idcardno || "",
        diagnosisname: detailData.diagnosisname || "",
        treatmenthospitalname: detailData.treatmenthospitalname || "",
        coordinatorName: detailData.coordinatorName || "",
        assessTime: detailData.assessTime || "",
        assessState: detailData.assessState || "1",
        assessannex: detailData.assessannex || ""
      };
      // å¤„理捐献决定数据
      if (detailData.organdecision) {
        this.organdecision = Array.isArray(detailData.organdecision)
          ? detailData.organdecision
          : (detailData.organdecision || "").split(",");
        this.organdecisionOther = detailData.organdecisionOther || "";
      }
      // å¤„理器官评估数据
      this.processOrganAssessmentData(detailData);
    },
    // å¤„理器官评估数据
    processOrganAssessmentData(detailData) {
      let organList = [];
      // ä»ŽæŽ¥å£æ•°æ®ä¸­èŽ·å–å™¨å®˜è¯„ä¼°åˆ—è¡¨
      if (detailData.serviceMedicalevaluationorgans) {
        if (Array.isArray(detailData.serviceMedicalevaluationorgans)) {
          organList = detailData.serviceMedicalevaluationorgans;
        }
      }
      // è½¬æ¢å™¨å®˜æ•°æ®æ ¼å¼ï¼Œæ”¯æŒå¤šæ¬¡è¯„ä¼°
      this.organAssessmentList = organList.map(organ => {
        const assessments = [];
        // è§£æžassesscontent字段中的多次评估数据
        if (organ.assesscontent) {
          try {
            const assessData = typeof organ.assesscontent === "string"
              ? JSON.parse(organ.assesscontent)
              : organ.assesscontent;
            if (Array.isArray(assessData)) {
              assessments.push(
                ...assessData.map((item, index) => ({
                  ...item,
                  index: index,
                  status: item.status || "assessed"
                }))
              );
            }
          } catch (error) {
            console.warn("解析评估内容失败:", error);
            assessments.push(this.getDefaultAssessment(0));
          }
        } else {
          assessments.push(this.getDefaultAssessment(0));
        }
      return {
          ...organ,
          assessments: assessments,
          activeAssessmentTab: assessments.length > 0 ? "assessment_0" : "summary",
          expanded: false
        };
      });
    },
    // èŽ·å–é»˜è®¤è¯„ä¼°æ•°æ®ç»“æž„
    getDefaultAssessment(index) {
      return {
        index: index,
        status: "pending",
        assessmentTime: "",
        assessor: "",
        functionStatus: "",
        assessmentOpinion: "",
        attachments: [],
        clinicalData: {},
        labResults: {}
        labResults: {},
        createTime: new Date().toISOString()
      };
    },
    // èŽ·å–è¯„ä¼°è¯¦æƒ…
    getAssessmentDetail() {
      this.assessmentLoading = true;
      getAssessment(this.assessmentId)
        .then(response => {
          if (response.code === 200) {
            this.assessmentData = response.data.caseInfo;
            this.organAssessmentList = this.transformOrganData(
              response.data.organAssessments || []
            );
          }
          this.assessmentLoading = false;
        })
        .catch(error => {
          console.error("获取评估详情失败:", error);
          this.assessmentLoading = false;
        });
    },
    // è½¬æ¢å™¨å®˜æ•°æ®æ ¼å¼ï¼Œæ”¯æŒå¤šæ¬¡è¯„ä¼°
    transformOrganData(organList) {
      return organList.map(organ => {
        const organName = this.getOrganName(organ.organType);
        // è½¬æ¢ä¸ºå¤šæ¬¡è¯„估的数据结构
        const assessments = [];
        if (organ.firstAssessment) {
          assessments.push({ ...organ.firstAssessment, index: 0 });
        }
        if (organ.secondAssessment) {
          assessments.push({ ...organ.secondAssessment, index: 1 });
        }
        // å¯ä»¥ç»§ç»­æ·»åŠ æ›´å¤šè¯„ä¼°...
        // è®¾ç½®å™¨å®˜åç§°å’Œè¯„估数据
        organ.organName = organName;
        organ.assessments = assessments;
        organ.activeAssessmentTab =
          assessments.length > 0 ? "assessment_0" : "summary";
        organ.expanded = false;
        // è®¡ç®—整体评估状态
        organ.assessmentStatus = this.calculateOverallStatus(organ);
        return organ;
      });
    },
    // è®¡ç®—最大评估次数(用于表头显示)
    // è®¡ç®—最大评估次数
    getMaxAssessmentCount() {
      const maxCount = Math.max(
        ...this.organAssessmentList.map(organ =>
          organ.assessments ? organ.assessments.length : 0
        )
      );
      return Math.max(maxCount, 2); // è‡³å°‘显示2列
      return Math.max(maxCount, 1);
    },
    // è®¡ç®—整体评估状态
    calculateOverallStatus(organ) {
      if (!organ.assessments || organ.assessments.length === 0) return "0";
    // èŽ·å–å™¨å®˜æ•´ä½“çŠ¶æ€
    getOrganOverallStatus(organ) {
      if (!organ.assessments || organ.assessments.length === 0) {
        return "pending";
      }
      const allAssessed = organ.assessments.every(
        assessment => assessment.status === "assessed"
@@ -467,14 +804,24 @@
        assessment => assessment.status === "assessed"
      );
      if (allAssessed) return "1";
      if (someAssessed) return "2";
      return "0";
      if (allAssessed) return "completed";
      if (someAssessed) return "assessing";
      return "pending";
    },
    getOrganOverallStatusText(organ) {
      const status = this.getOrganOverallStatus(organ);
      const statusMap = {
        pending: "待评估",
        assessing: "评估中",
        completed: "已完成"
      };
      return statusMap[status] || "未知";
    },
    // åˆ‡æ¢å±•开行
    handleToggleExpand(row) {
      const key = row.organType;
      const key = row.organno;
      const index = this.expandedRowKeys.indexOf(key);
      if (index > -1) {
@@ -483,83 +830,36 @@
      } else {
        this.expandedRowKeys = [key];
        this.organAssessmentList.forEach(item => {
          item.expanded = item.organType === key;
          item.expanded = item.organno === key;
        });
      }
    },
    // å±•开行变化
    handleExpandChange(row, expandedRows) {
      this.expandedRowKeys = expandedRows.map(item => item.organType);
      this.expandedRowKeys = expandedRows.map(item => item.organno);
      this.organAssessmentList.forEach(item => {
        item.expanded = this.expandedRowKeys.includes(item.organType);
        item.expanded = this.expandedRowKeys.includes(item.organno);
      });
    },
    // æ·»åŠ æ–°è¯„ä¼°
    handleAddNewAssessment(organ) {
      const newAssessment = {
        ...this.getDefaultAssessment(),
        index: organ.assessments.length
        ...this.getDefaultAssessment(organ.assessments.length),
        assessor: this.currentUser.name
      };
      organ.assessments.push(newAssessment);
      organ.activeAssessmentTab = `assessment_${organ.assessments.length - 1}`;
      // æ›´æ–°æ•´ä½“状态
      organ.assessmentStatus = this.calculateOverallStatus(organ);
      this.$message.success("已添加新的评估");
    },
    // å¤„理添加评估事件
    handleAddAssessment(data) {
      const { organData, currentIndex } = data;
      const { organData } = data;
      this.handleAddNewAssessment(organData);
    },
    // ä¿å­˜è¯„ä¼°
    handleSaveOrganAssessment(saveData) {
      const { organData, assessmentData, assessmentIndex } = saveData;
      const organToUpdate = {
        ...organData,
        assessments: organData.assessments.map((assessment, index) =>
          index === assessmentIndex
            ? {
                ...assessmentData,
                status: "assessed",
                assessmentTime: new Date().toISOString(),
                assessor: this.currentUser.name
              }
            : assessment
        )
      };
      // æ›´æ–°æ•´ä½“状态
      organToUpdate.assessmentStatus = this.calculateOverallStatus(
        organToUpdate
      );
      updateOrganAssessment(organToUpdate)
        .then(response => {
          if (response.code === 200) {
            this.$message.success(`第${assessmentIndex + 1}次评估保存成功`);
            this.getAssessmentDetail();
            // æ›´æ–°å½“前展开行的数据
            const index = this.organAssessmentList.findIndex(
              item => item.organType === organData.organType
            );
            if (index !== -1) {
              this.organAssessmentList.splice(index, 1, organToUpdate);
            }
          }
        })
        .catch(error => {
          console.error("保存评估失败:", error);
          this.$message.error("保存失败");
        });
    },
    // èŽ·å–æœ€æ–°è¯„ä¼°æ—¶é—´
@@ -572,55 +872,6 @@
      return assessed.sort(
        (a, b) => new Date(b.assessmentTime) - new Date(a.assessmentTime)
      )[0].assessmentTime;
    },
    // èŽ·å–æ‰€æœ‰é™„ä»¶
    getAllAttachments(organ) {
      const attachments = [];
      if (organ.assessments) {
        organ.assessments.forEach((assessment, index) => {
          if (assessment.attachments) {
            assessment.attachments.forEach(att => {
              attachments.push({
                ...att,
                assessmentIndex: index,
                assessmentNumber: index + 1
              });
            });
          }
        });
      }
      return attachments;
    },
    // é¢„览附件
    handlePreviewAttachment(attachment) {
      this.currentPreviewFile = {
        fileName: attachment.fileName,
        fileUrl: attachment.path || attachment.fileUrl,
        fileType: this.getFileType(attachment.fileName)
      };
      this.attachmentVisible = true;
    },
    // èŽ·å–æ–‡ä»¶ç±»åž‹
    getFileType(fileName) {
      if (!fileName) return "other";
      const extension = fileName
        .split(".")
        .pop()
        .toLowerCase();
      const imageTypes = ["jpg", "jpeg", "png", "gif", "bmp", "webp"];
      const pdfTypes = ["pdf"];
      const officeTypes = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"];
      if (imageTypes.includes(extension)) return "image";
      if (pdfTypes.includes(extension)) return "pdf";
      if (officeTypes.includes(extension)) return "office";
      return "other";
    },
    // èŽ·å–è¯„ä¼°çŠ¶æ€æ ‡ç­¾ç±»åž‹
@@ -643,16 +894,16 @@
      return textMap[status] || "未知";
    },
    // èŽ·å–å™¨å®˜åç§°
    getOrganName(organType) {
      const organ = this.organTypeOptions.find(opt => opt.value === organType);
      return organ ? organ.label : organType;
    },
    // æ£€æŸ¥è¯„估权限
    canAssessOrgan(organ) {
      console.log(organ,'organ');
      if (this.isCoordinator) return true;
      return organ.department === this.currentDepartment;
      if (!this.isEdit) return false;
      return (
        organ.gainhospitalname &&
        organ.gainhospitalname.includes(this.currentDepartment)
      );
    },
    // èŽ·å–è¡Œç±»å
@@ -663,46 +914,79 @@
    // çŠ¶æ€è¿‡æ»¤å™¨
    statusFilter(status) {
      const statusMap = {
        "0": "warning",
        "1": "primary",
        "2": "success",
        "3": "danger"
        "1": "warning",
        "2": "primary",
        "3": "success"
      };
      return statusMap[status] || "info";
    },
    statusTextFilter(status) {
      const statusMap = {
        "0": "待评估",
        "1": "评估中",
        "2": "已完成",
        "3": "已关闭"
        "1": "待评估",
        "2": "评估中",
        "3": "已完成"
      };
      return statusMap[status] || "未知";
    },
    // æŸ¥çœ‹é™„ä»¶
    handleAttachmentPreview() {
      if (this.assessmentData.assessannex) {
        try {
          const annexData = typeof this.assessmentData.assessannex === "string"
            ? JSON.parse(this.assessmentData.assessannex)
            : this.assessmentData.assessannex;
          if (Array.isArray(annexData) && annexData.length > 0) {
            this.currentPreviewFile = annexData[0];
      this.attachmentVisible = true;
          } else {
            this.$message.info("暂无附件可预览");
          }
        } catch (error) {
          this.$message.info("附件数据格式错误");
        }
      } else {
        this.$message.info("暂无附件");
      }
    },
    handleCompleteAssessment() {
      this.$confirm("确认完成所有器官评估吗?完成后将无法修改", "确认操作", {
    // å®Œæˆè¯„ä¼°
    async handleCompleteAssessment() {
      try {
        await this.$confirm(
          "确认完成所有器官评估吗?完成后将无法修改",
          "确认操作",
          {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        completeAssessment(this.assessmentId)
          .then(response => {
          }
        );
        // æ›´æ–°è¯„估状态为已完成
        const updateData = {
          ...this.assessmentData,
          assessState: "3",
          assessTime: new Date().toISOString()
        };
        const response = await assessedit(updateData);
            if (response.code === 200) {
              this.$message.success("评估完成确认成功");
              this.getAssessmentDetail();
          this.assessmentData.assessState = "3";
          this.isEdit = false;
        } else {
          this.$message.error("操作失败:" + (response.msg || "未知错误"));
            }
          })
          .catch(error => {
      } catch (error) {
        if (error !== "cancel") {
            console.error("完成评估失败:", error);
            this.$message.error("操作失败");
          });
      });
        }
      }
    }
  }
};
@@ -742,6 +1026,14 @@
.assessment-summary {
  padding: 10px;
}
/* åº•部保存按钮样式 */
.footer-actions {
  margin-top: 20px;
  text-align: center;
  padding: 20px;
  border-top: 1px solid #eaeaea;
}
/* å“åº”式设计 */
@@ -790,4 +1082,17 @@
.fixed-width .el-button {
  margin: 0 2px;
}
/* æçŒ®å†³å®šæ ·å¼ä¼˜åŒ– */
.organ-decision-info {
  margin: 10px 0;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border-left: 4px solid #409eff;
}
.decision-tag {
  margin: 2px 5px;
}
</style>
src/views/business/assess/components/OrganAssessmentForm.vue
@@ -2,7 +2,7 @@
  <div class="organ-assessment-form">
    <el-form :model="assessmentData" label-width="120px">
      <el-form-item label="功能状态">
        <el-select v-model="assessmentData.functionStatus" :disabled="readonly">
        <el-select v-model="assessmentData.functionStatus">
          <el-option label="正常" value="1" />
          <el-option label="轻度异常" value="2" />
          <el-option label="重度异常" value="3" />
@@ -15,7 +15,6 @@
          type="textarea"
          v-model="assessmentData.assessmentOpinion"
          :rows="4"
          :disabled="readonly"
          placeholder="请输入评估意见"
        />
      </el-form-item>
@@ -268,13 +267,17 @@
    /** ä¸Šä¼ æˆåŠŸå¤„ç† */
    handleUploadSuccess({ file, fileList, response }) {
      if (response.code === 200) {
      console.log(response);
      if (response.code == 200) {
        console.log(1);
        const attachmentObj = {
          id:
            response.data.fileId ||
            Math.random()
              .toString(36)
              .substr(2),
          // id:
          //   response.data.fileId ||
          //   Math.random()
          //     .toString(36)
          //     .substr(2),
          fileName: file.name,
          path: response.data.fileUrl || file.url,
          fileUrl: response.data.fileUrl || file.url,
@@ -284,6 +287,7 @@
          assessmentType: this.assessmentType,
          organType: this.organData.organType
        };
        console.log(2,attachmentObj);
        this.assessmentData.attachments.push(attachmentObj);
        this.$message.success("文件上传成功");
src/views/business/assess/index.vue
@@ -8,9 +8,9 @@
        :inline="true"
        label-width="100px"
      >
        <el-form-item label="捐献者姓名" prop="donorName">
        <el-form-item label="捐献者姓名" prop="name">
          <el-input
            v-model="queryParams.donorName"
            v-model="queryParams.name"
            placeholder="请输入捐献者姓名"
            clearable
            style="width: 200px"
@@ -35,22 +35,22 @@
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="评估状态" prop="firstAssessState">
        <el-form-item label="评估状态" prop="assessState">
          <el-select
            v-model="queryParams.firstAssessState"
            v-model="queryParams.assessState"
            placeholder="请选择评估状态"
            clearable
            style="width: 200px"
          >
            <el-option label="待评估" value="0" />
            <el-option label="评估中" value="1" />
            <el-option label="已完成" value="2" />
            <el-option label="已关闭" value="3" />
            <el-option label="待评估" value="1" />
            <el-option label="评估中" value="2" />
            <el-option label="已完成" value="3" />
            <el-option label="已关闭" value="4" />
          </el-select>
        </el-form-item>
        <el-form-item label="申请时间" prop="applyTimeRange">
          <el-date-picker
            v-model="applyTimeRange"
            v-model="queryParams.applyTimeRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
@@ -59,9 +59,9 @@
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item label="评估时间" prop="assessmentTimeRange">
        <el-form-item label="评估时间" prop="assessTimeRange">
          <el-date-picker
            v-model="assessmentTimeRange"
            v-model="queryParams.assessTimeRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
@@ -133,15 +133,14 @@
        <el-table-column
          label="潜在捐献者姓名"
          align="center"
          prop="donorName"
          prop="name"
          width="120"
        />
        <el-table-column label="性别" align="center" prop="gender" width="80">
        <el-table-column label="性别" align="center" prop="sex" width="80">
          <template slot-scope="scope">
            <!-- <dict-tag :options="genderOptions" :value="scope.row.gender" /> -->
            <dict-tag
              :options="dict.type.sys_user_sex"
              :value="parseInt(scope.row.gender)"
              :value="scope.row.sex"
            />
          </template>
        </el-table-column>
@@ -149,14 +148,14 @@
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosis"
          prop="diagnosisname"
          min-width="180"
          show-overflow-tooltip
        />
        <el-table-column
          label="所在医疗机构"
          align="center"
          prop="hospitalName"
          prop="treatmenthospitalname"
          width="150"
          show-overflow-tooltip
        />
@@ -173,13 +172,13 @@
        <el-table-column
          label="评估时间"
          align="center"
          prop="assessmentTime"
          prop="assessTime"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.assessmentTime
                ? parseTime(scope.row.assessmentTime, "{y}-{m}-{d}")
              scope.row.assessTime
                ? parseTime(scope.row.assessTime, "{y}-{m}-{d}")
                : "-"
            }}</span>
          </template>
@@ -187,12 +186,12 @@
        <el-table-column
          label="评估状态"
          align="center"
          prop="firstAssessState"
          prop="assessState"
          width="100"
        >
          <template slot-scope="scope">
            <el-tag :type="statusFilter(scope.row.firstAssessState)">
              {{ statusTextFilter(scope.row.firstAssessState) }}
            <el-tag :type="statusFilter(scope.row.assessState)">
              {{ statusTextFilter(scope.row.assessState) }}
            </el-tag>
          </template>
        </el-table-column>
@@ -202,19 +201,6 @@
          prop="coordinatorName"
          width="100"
        />
        <!-- <el-table-column
          label="评估类型"
          align="center"
          prop="assessmentType"
          width="100"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.assessment_Type"
              :value="parseInt(scope.row.assessmentType)"
            />
          </template>
        </el-table-column> -->
        <el-table-column
          label="操作"
          align="center"
@@ -231,8 +217,8 @@
            >
            <el-button
              v-if="
                scope.row.firstAssessState === '0' ||
                  scope.row.firstAssessState === '1'
                scope.row.assessState === '1' ||
                  scope.row.assessState === '2'
              "
              size="mini"
              type="text"
@@ -241,7 +227,7 @@
              >评估</el-button
            >
            <el-button
              v-if="scope.row.firstAssessState === '2'"
              v-if="scope.row.assessState === '3'"
              size="mini"
              type="text"
              icon="el-icon-check"
@@ -265,19 +251,13 @@
</template>
<script>
// import { listAssessment, delAssessment, exportAssessment } from "@/api/case/assessment";
import {
  listAssessment,
  delAssessment,
  exportAssessment
} from "./mockAssessmentApi";
import { evaluateBaseInfolist } from "@/api/businessApi/index";
import Pagination from "@/components/Pagination";
export default {
  name: "AssessmentList",
  components: { Pagination },
  dicts: ["sys_user_sex", "assessment_Type"],
  dicts: ["sys_user_sex"],
  data() {
    return {
      // é®ç½©å±‚
@@ -296,24 +276,13 @@
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        donorName: undefined,
        name: undefined,
        hospitalName: undefined,
        coordinatorName: undefined,
        firstAssessState: undefined,
      },
        assessState: undefined,
      applyTimeRange: [],
        assessmentTimeRange: [],
      // æ€§åˆ«é€‰é¡¹
      genderOptions: [
        { value: "0", label: "男" },
        { value: "1", label: "女" }
      ],
      // è¯„估类型选项
      assessmentTypeOptions: [
        { value: "1", label: "初次评估" },
        { value: "2", label: "最终评估" }
      ]
        assessTimeRange: []
      }
    };
  },
  created() {
@@ -323,41 +292,121 @@
    // çŠ¶æ€è¿‡æ»¤å™¨
    statusFilter(status) {
      const statusMap = {
        "0": "warning", // å¾…评估
        "1": "primary", // è¯„估中
        "2": "success", // å·²å®Œæˆ
        "3": "danger" // å·²å…³é—­
        "1": "warning", // å¾…评估
        "2": "primary", // è¯„估中
        "3": "success", // å·²å®Œæˆ
        "4": "danger" // å·²å…³é—­
      };
      return statusMap[status] || "info";
    },
    statusTextFilter(status) {
      const statusMap = {
        "0": "待评估",
        "1": "评估中",
        "2": "已完成",
        "3": "已关闭"
        "1": "待评估",
        "2": "评估中",
        "3": "已完成",
        "4": "已关闭"
      };
      return statusMap[status] || "未知";
    },
    // æŸ¥è¯¢è¯„估列表
    getList() {
    async getList() {
      this.loading = true;
      evaluateBaseInfolist(this.queryParams);
      listAssessment(this.queryParams)
        .then(response => {
      try {
        // æž„建查询参数,映射到接口字段
        const requestParams = this.buildRequestParams();
        const response = await evaluateBaseInfolist(requestParams);
          if (response.code === 200) {
          // å¤„理接口返回的数据结构
          this.handleResponseData(response);
        } else {
          this.$message.error("获取数据失败:" + (response.msg || "未知错误"));
          this.assessmentList = [];
          this.total = 0;
        }
      } catch (error) {
        console.error("获取评估列表失败:", error);
        this.$message.error("获取数据失败");
        this.assessmentList = [];
        this.total = 0;
      } finally {
        this.loading = false;
      }
    },
    // æž„建请求参数
    buildRequestParams() {
      const params = {
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize
      };
      // æ˜ å°„查询条件到接口字段
      if (this.queryParams.name) {
        params.name = this.queryParams.name;
      }
      if (this.queryParams.hospitalName) {
        params.treatmenthospitalname = this.queryParams.hospitalName;
      }
      if (this.queryParams.coordinatorName) {
        params.coordinatorName = this.queryParams.coordinatorName;
      }
      if (this.queryParams.assessState) {
        params.assessState = this.queryParams.assessState;
      }
      // å¤„理时间范围查询
      if (this.queryParams.applyTimeRange && this.queryParams.applyTimeRange.length === 2) {
        params.startApplyTime = this.queryParams.applyTimeRange[0];
        params.endApplyTime = this.queryParams.applyTimeRange[1];
      }
      if (this.queryParams.assessTimeRange && this.queryParams.assessTimeRange.length === 2) {
        params.startAssessTime = this.queryParams.assessTimeRange[0];
        params.endAssessTime = this.queryParams.assessTimeRange[1];
      }
      return params;
    },
    // å¤„理接口响应数据
    handleResponseData(response) {
      // æ ¹æ®æŽ¥å£å®žé™…返回的数据结构进行调整
      if (response.data) {
        if (Array.isArray(response.data)) {
          // å¦‚果返回的是数组
          this.assessmentList = response.data;
          this.total = response.data.length;
        } else if (response.data.rows) {
          // å¦‚果返回的是分页数据结构
            this.assessmentList = response.data.rows;
            this.total = response.data.total;
        } else if (Array.isArray(response.data.list)) {
          // å¦‚果返回的是list字段
          this.assessmentList = response.data.list;
          this.total = response.data.total || response.data.list.length;
          } else {
            this.$message.error("获取数据失败");
          // å…¶ä»–数据结构,尝试直接使用data
          this.assessmentList = response.data;
          this.total = response.total || response.data.length;
          }
          this.loading = false;
        })
        .catch(error => {
          console.error("获取评估列表失败:", error);
          this.loading = false;
          this.$message.error("获取数据失败");
        });
      } else {
        // å¦‚æžœdata为空,使用根级别的rows或list
        if (Array.isArray(response.rows)) {
          this.assessmentList = response.rows;
          this.total = response.total;
        } else if (Array.isArray(response.list)) {
          this.assessmentList = response.list;
          this.total = response.total;
        } else {
          this.assessmentList = [];
          this.total = 0;
        }
      }
      // ç¡®ä¿assessmentList是数组
      if (!Array.isArray(this.assessmentList)) {
        this.assessmentList = [];
      }
    },
    // æœç´¢æŒ‰é’®æ“ä½œ
    handleQuery() {
@@ -367,7 +416,8 @@
    // é‡ç½®æŒ‰é’®æ“ä½œ
    resetQuery() {
      this.$refs.queryForm.resetFields();
      this.handleQuery();
      this.queryParams.pageNum = 1;
      this.getList();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
@@ -379,34 +429,41 @@
    handleRowClick(row) {
      this.$router.push({
        path: "/case/assessInfo",
        query: { id: row.id }
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // æŸ¥çœ‹è¯¦æƒ…
    handleView(row) {
      this.$router.push({ path: "/case/assessInfo", query: { id: row.id } });
      this.$router.push({
        path: "/case/assessInfo",
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // è¿›è¡Œè¯„ä¼°
    handleAssess(row) {
      this.$router.push({
        path: "/case/assessInfo",
        query: { id: row.id, assess: true }
        query: { id: row.id, infoid: row.infoid, assess: true }
      });
    },
    // ç¡®è®¤è¯„ä¼°
    handleConfirm(row) {
      this.$confirm("确认完成该案例的评估吗?", "警告", {
    async handleConfirm(row) {
      try {
        await this.$confirm("确认完成该案例的评估吗?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          // è°ƒç”¨Mock确认API
        });
        // è¿™é‡Œéœ€è¦è°ƒç”¨ç¡®è®¤è¯„估接口,暂时模拟成功
          this.$message.success("确认成功");
          // åˆ·æ–°åˆ—表
          this.getList();
        })
        .catch(() => {});
      } catch (error) {
        if (error !== 'cancel') {
          console.error("确认失败:", error);
        }
      }
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
    handleCreate() {
@@ -414,64 +471,94 @@
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate() {
      if (this.ids.length === 0) return;
      const id = this.ids[0];
      this.$router.push({ path: "/case/assessment/edit", query: { id: id } });
      this.$router.push({
        path: "/case/assessment/edit",
        query: { id: id }
      });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ - ä½¿ç”¨Mock API
    handleDelete() {
      const ids = this.ids;
      this.$confirm("是否确认删除选中的数据项?", "警告", {
    // åˆ é™¤æŒ‰é’®æ“ä½œ
    async handleDelete() {
      if (this.ids.length === 0) return;
      try {
        await this.$confirm("是否确认删除选中的数据项?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          return delAssessment(ids);
        })
        .then(response => {
          if (response.code === 200) {
        });
        // è¿™é‡Œéœ€è¦è°ƒç”¨åˆ é™¤æŽ¥å£ï¼Œæš‚时模拟成功
            this.$message.success("删除成功");
            this.getList();
      } catch (error) {
        if (error !== "cancel") {
          console.error("删除失败:", error);
          this.$message.error("删除失败");
          }
        })
        .catch(() => {});
      }
    },
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ - ä½¿ç”¨Mock API
    handleExport() {
      const queryParams = this.queryParams;
      this.$confirm("是否确认导出所有评估数据?", "警告", {
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ
    async handleExport() {
      try {
        await this.$confirm("是否确认导出所有评估数据?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          this.loading = true;
          return exportAssessment(queryParams);
        })
        .then(response => {
          if (response.code === 200) {
            this.$message.success("导出成功,开始下载文件");
            // æ¨¡æ‹Ÿæ–‡ä»¶ä¸‹è½½
            const link = document.createElement("a");
            link.href = response.data.downloadUrl;
            link.download = "案例评估数据.xlsx";
            link.click();
          }
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
        this.loading = true;
        // æž„建导出参数
        const exportParams = this.buildRequestParams();
        exportParams.pageSize = 10000; // å¯¼å‡ºæ‰€æœ‰æ•°æ®
        // èŽ·å–å¯¼å‡ºæ•°æ®
        const response = await evaluateBaseInfolist(exportParams);
        if (response.code === 200) {
          // å¤„理导出数据
          this.exportDataToExcel(response.data);
          this.$message.success("导出成功");
        } else {
          this.$message.error("导出失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        if (error !== "cancel") {
          console.error("导出失败:", error);
          this.$message.error("导出失败");
        }
      } finally {
        this.loading = false;
      }
    },
    // å¯¼å‡ºæ•°æ®åˆ°Excel
    exportDataToExcel(data) {
      // è¿™é‡Œå®žçŽ°å¯¼å‡ºé€»è¾‘ï¼Œå¯ä»¥ä½¿ç”¨xlsx等库
      // ç”±äºŽæ˜¯å‰ç«¯å¯¼å‡ºï¼Œè¿™é‡Œç®€å•演示
      console.log("导出数据:", data);
      // å®žé™…项目中需要实现完整的Excel导出功能
      // æ¨¡æ‹Ÿæ–‡ä»¶ä¸‹è½½
      const blob = new Blob([JSON.stringify(data, null, 2)], {
        type: 'application/vnd.ms-excel'
      });
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = '医学评估数据.xlsx';
      link.click();
    },
    // æ—¶é—´æ ¼å¼åŒ–
    parseTime(time, pattern) {
      if (!time) return "";
      // ä½¿ç”¨moment.js或简单格式化
      if (this.$moment) {
        return this.$moment(time).format(pattern || "{y}-{m}-{d} {h}:{i}:{s}");
      } else {
        // ç®€å•格式化
        const date = new Date(time);
      if (pattern) {
        // ç®€å•的模式匹配
        if (pattern === "{y}-{m}-{d}") {
        return `${date.getFullYear()}-${(date.getMonth() + 1)
          .toString()
          .padStart(2, "0")}-${date
@@ -480,6 +567,22 @@
          .padStart(2, "0")}`;
      }
    }
      return `${date.getFullYear()}-${(date.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${date
        .getDate()
        .toString()
        .padStart(2, "0")} ${date
        .getHours()
        .toString()
        .padStart(2, "0")}:${date
        .getMinutes()
        .toString()
        .padStart(2, "0")}:${date
        .getSeconds()
        .toString()
        .padStart(2, "0")}`;
    }
  }
};
</script>
src/views/business/maintain/components/BloodRoutinePanel.vue
@@ -79,13 +79,19 @@
            />
            <div v-else class="value-display-container">
              <span class="value-text" :title="scope.row.values[index]">
                {{ scope.row.values[index] || '-' }}
                {{ scope.row.values[index] || "-" }}
              </span>
              <span v-if="scope.row.values[index] && scope.row.unit" class="unit-text">
              <span
                v-if="scope.row.values[index] && scope.row.unit"
                class="unit-text"
              >
                {{ scope.row.unit }}
              </span>
            </div>
            <div v-if="scope.row.reference && scope.row.values[index]" class="validation-indicator">
            <div
              v-if="scope.row.reference && scope.row.values[index]"
              class="validation-indicator"
            >
              <i
                v-if="isValueValid(scope.row, scope.row.values[index])"
                class="el-icon-success valid-icon"
@@ -100,20 +106,6 @@
          </div>
        </template>
      </el-table-column>
      <!-- <el-table-column
        v-if="isEditing"
        label="操作"
        width="120"
        fixed="right"
        class-name="leave-alone"
      >
        <template #default>
          <el-button link type="primary" @click="addColumn" size="small">
            æ–°å¢žåˆ—
          </el-button>
        </template>
      </el-table-column> -->
    </el-table>
    <!-- ç»Ÿè®¡ä¿¡æ¯ -->
@@ -121,7 +113,9 @@
      <el-card shadow="never">
        <div class="stats-content">
          <span class="stats-title">数据统计:</span>
          <span class="stats-item">总记录数: {{ dynamicColumns.length }} ä¸ªæ—¶é—´ç‚¹</span>
          <span class="stats-item"
            >总记录数: {{ dynamicColumns.length }} ä¸ªæ—¶é—´ç‚¹</span
          >
          <span class="stats-item">已填写: {{ filledCount }} é¡¹</span>
          <span class="stats-item">完成度: {{ completionRate }}%</span>
        </div>
@@ -194,7 +188,11 @@
        >
          åˆ é™¤
        </el-button>
        <el-button type="primary" @click="confirmAddColumn" :loading="saveLoading">
        <el-button
          type="primary"
          @click="confirmAddColumn"
          :loading="saveLoading"
        >
          ç¡®å®š
        </el-button>
      </span>
@@ -206,18 +204,19 @@
import UploadAttachment from "@/components/UploadAttachment";
export default {
  name: 'BloodRoutinePanel',
  name: "BloodRoutinePanel",
  components: {
    UploadAttachment,
    UploadAttachment
  },
  props: {
    isEditing: {
      type: Boolean,
      default: false
    },
    // ä¿®æ”¹ä¸º Object ç±»åž‹ï¼Œæ”¯æŒå¤æ‚数据结构
    initialData: {
      type: Array,
      default: () => []
      type: Object,
      default: () => ({})
    },
    showStatistics: {
      type: Boolean,
@@ -227,33 +226,23 @@
  data() {
    return {
      tableData: [],
      dynamicColumns: [
        {
          label: '2024-12-27\n08:00',
          key: 'time1',
          date: '2024-12-27',
          time: '08:00',
          remark: '晨起检测'
        }
      ],
      dynamicColumns: [],
      attachments: [],
      columnDialogVisible: false,
      columnForm: {
        date: '',
        time: '',
        remark: ''
        date: "",
        time: "",
        remark: ""
      },
      editingColumnIndex: null,
      tableKey: 0,
      tableLoading: false,
      saveLoading: false,
      // å†…部数据状态
      internalData: {},
      columnRules: {
        date: [
          { required: true, message: '请选择日期', trigger: 'change' }
        ],
        time: [
          { required: true, message: '请选择时间', trigger: 'change' }
        ]
        date: [{ required: true, message: "请选择日期", trigger: "change" }],
        time: [{ required: true, message: "请选择时间", trigger: "change" }]
      }
    };
  },
@@ -262,7 +251,7 @@
      let count = 0;
      this.tableData.forEach(row => {
        row.values.forEach(value => {
          if (value && value.toString().trim() !== '') {
          if (value && value.toString().trim() !== "") {
            count++;
          }
        });
@@ -275,14 +264,20 @@
    }
  },
  watch: {
    // ç›‘听 initialData å˜åŒ–,确保数据正确接收
    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: 'blood_routine',
          data: this.tableData,
          columns: this.dynamicColumns,
          attachments: this.attachments
        });
        this.saveData();
      }
      this.$nextTick(() => {
        this.forceTableLayout();
@@ -299,54 +294,105 @@
    }
  },
  methods: {
    // ä»Žå¤–部数据初始化组件
    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 = [
      const medicalItems = this.getMedicalItems();
      // å¦‚果没有动态列,初始化默认列
      if (this.dynamicColumns.length === 0) {
        this.dynamicColumns = [
        {
          itemName: 'WBC',
          unit: '×10⁹/L',
          required: true,
          reference: '3.5-9.5',
          min: 3.5,
          max: 9.5,
          type: 'number'
        },
        {
          itemName: 'NEUT%',
          unit: '%',
          required: true,
          reference: '40-75',
          min: 40,
          max: 75,
          type: 'number'
        },
        {
          itemName: 'Hb',
          unit: 'g/L',
          required: true,
          reference: '130-175',
          min: 130,
          max: 175,
          type: 'number'
        },
        {
          itemName: '血小板',
          unit: '×10⁹/L',
          required: true,
          reference: '125-350',
          min: 125,
          max: 350,
          type: 'number'
            label: `${new Date().toISOString().split("T")[0]}\n08:00`,
            key: "time1",
            date: new Date().toISOString().split("T")[0],
            time: "08:00",
            remark: "晨起检测"
        }
      ];
      }
      this.tableData = medicalItems.map(item => ({
        ...item,
        values: new Array(this.dynamicColumns.length).fill('')
        values: new Array(this.dynamicColumns.length).fill("")
      }));
    },
    // è¡€å¸¸è§„检测项目定义
    getMedicalItems() {
      return [
        {
          itemName: "WBC",
          unit: "×10⁹/L",
          required: true,
          reference: "3.5-9.5",
          min: 3.5,
          max: 9.5,
          type: "number"
        },
        {
          itemName: "NEUT%",
          unit: "%",
          required: true,
          reference: "40-75",
          min: 40,
          max: 75,
          type: "number"
        },
        {
          itemName: "Hb",
          unit: "g/L",
          required: true,
          reference: "130-175",
          min: 130,
          max: 175,
          type: "number"
        },
        {
          itemName: "血小板",
          unit: "×10⁹/L",
          required: true,
          reference: "125-350",
          min: 125,
          max: 350,
          type: "number"
        }
      ];
    },
    // ä¿å­˜æ•°æ®åˆ°çˆ¶ç»„ä»¶
    saveData() {
      const dataToEmit = {
        type: "blood_routine",
        data: this.tableData,
        columns: this.dynamicColumns,
        attachments: this.attachments
      };
      this.$emit("data-change", dataToEmit);
    },
    getPlaceholder(row) {
      return row.reference ? `参考: ${row.reference}` : '请输入数值';
      return row.reference ? `参考: ${row.reference}` : "请输入数值";
    },
    isValueValid(row, value) {
@@ -358,9 +404,9 @@
    addColumn() {
      this.editingColumnIndex = null;
      this.columnForm = {
        date: new Date().toISOString().split('T')[0],
        time: '08:00',
        remark: ''
        date: new Date().toISOString().split("T")[0],
        time: "08:00",
        remark: ""
      };
      this.columnDialogVisible = true;
      this.$nextTick(() => {
@@ -374,15 +420,15 @@
      this.columnForm = {
        date: column.date,
        time: column.time,
        remark: column.remark || ''
        remark: column.remark || ""
      };
      this.columnDialogVisible = true;
    },
    confirmAddColumn() {
      this.$refs.columnFormB.validate((valid) => {
      this.$refs.columnFormB.validate(valid => {
        if (!valid) {
          this.$message.warning('请完善时间点信息');
          this.$message.warning("请完善时间点信息");
          return;
        }
@@ -395,10 +441,9 @@
          column.date = this.columnForm.date;
          column.time = this.columnForm.time;
          column.remark = this.columnForm.remark;
          this.$message.success('时间点修改成功');
          this.$message.success("时间点修改成功");
        } else {
          // æ–°å¢žåˆ—
          const newIndex = this.dynamicColumns.length + 1;
          const newColumn = {
            label: `${this.columnForm.date}\n${this.columnForm.time}`,
            key: `time${Date.now()}`,
@@ -407,11 +452,13 @@
            remark: this.columnForm.remark
          };
          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.$message.success('时间点添加成功');
          this.$message.success("时间点添加成功");
        }
        this.columnDialogVisible = false;
@@ -422,10 +469,10 @@
    handleDeleteColumn() {
      if (this.editingColumnIndex !== null) {
        this.$confirm('确定要删除这个时间点吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        this.$confirm("确定要删除这个时间点吗?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          this.dynamicColumns.splice(this.editingColumnIndex, 1);
          this.tableData.forEach(row => {
@@ -433,7 +480,7 @@
          });
          this.columnDialogVisible = false;
          this.tableKey += 1;
          this.$message.success('时间点删除成功');
          this.$message.success("时间点删除成功");
        });
      }
    },
@@ -441,9 +488,9 @@
    handleDialogClosed() {
      this.editingColumnIndex = null;
      this.columnForm = {
        date: '',
        time: '',
        remark: ''
        date: "",
        time: "",
        remark: ""
      };
      this.$refs.columnFormB && this.$refs.columnFormB.clearValidate();
    },
@@ -453,26 +500,22 @@
    },
    handleValueChange(row, columnIndex) {
      this.$emit('data-change', {
        type: 'blood_routine',
        data: this.tableData,
        columns: this.dynamicColumns
      });
      this.saveData();
    },
    handleAttachmentChange(fileList) {
      this.attachments = fileList;
      this.$emit('attachment-change', {
        type: 'blood_routine',
      this.$emit("attachment-change", {
        type: "blood_routine",
        attachments: fileList
      });
    },
    forceTableLayout() {
      this.$nextTick(() => {
        const table = this.$el.querySelector('.el-table');
        const table = this.$el.querySelector(".el-table");
        if (table) {
          window.dispatchEvent(new Event('resize'));
          window.dispatchEvent(new Event("resize"));
        }
      });
    },
@@ -496,7 +539,13 @@
    }
  },
  mounted() {
    // ç¡®ä¿ç»„件正确挂载后初始化数据
    this.$nextTick(() => {
      if (Object.keys(this.internalData).length === 0) {
    this.initTableData();
      }
      this.forceTableLayout();
    });
  }
};
</script>
@@ -681,13 +730,5 @@
    flex-direction: column;
    gap: 4px;
  }
}
/* åŠ¨ç”»æ•ˆæžœ */
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>
src/views/business/maintain/components/LiverKidneyPanel.vue
@@ -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: "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 = [
        {
          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'
            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;
src/views/business/maintain/components/UrineRoutinePanel.vue
@@ -85,8 +85,12 @@
                  :value="option.value"
                />
              </el-select>
              <span v-else class="value-text" :title="getSelectLabel(scope.row, index)">
                {{ getSelectLabel(scope.row, index) || '-' }}
              <span
                v-else
                class="value-text"
                :title="getSelectLabel(scope.row, index)"
              >
                {{ getSelectLabel(scope.row, index) || "-" }}
              </span>
            </template>
@@ -102,9 +106,12 @@
              />
              <div v-else class="value-display-container">
                <span class="value-text" :title="scope.row.values[index]">
                  {{ scope.row.values[index] || '-' }}
                  {{ scope.row.values[index] || "-" }}
                </span>
                <span v-if="scope.row.values[index] && scope.row.unit" class="unit-text">
                <span
                  v-if="scope.row.values[index] && scope.row.unit"
                  class="unit-text"
                >
                  {{ scope.row.unit }}
                </span>
              </div>
@@ -112,20 +119,6 @@
          </div>
        </template>
      </el-table-column>
      <!-- <el-table-column
        v-if="isEditing"
        label="操作"
        width="120"
        fixed="right"
        class-name="leave-alone"
      >
        <template #default>
          <el-button link type="primary" @click="addColumn" size="small">
            æ–°å¢žåˆ—
          </el-button>
        </template>
      </el-table-column> -->
    </el-table>
    <!-- ç»Ÿè®¡ä¿¡æ¯ -->
@@ -133,7 +126,9 @@
      <el-card shadow="never">
        <div class="stats-content">
          <span class="stats-title">数据统计:</span>
          <span class="stats-item">总记录数: {{ dynamicColumns.length }} ä¸ªæ—¶é—´ç‚¹</span>
          <span class="stats-item"
            >总记录数: {{ dynamicColumns.length }} ä¸ªæ—¶é—´ç‚¹</span
          >
          <span class="stats-item">已填写: {{ filledCount }} é¡¹</span>
          <span class="stats-item">完成度: {{ completionRate }}%</span>
        </div>
@@ -145,7 +140,9 @@
      <div class="attachment-header">
        <i class="el-icon-paperclip"></i>
        <span class="attachment-title">附件上传</span>
        <span class="attachment-tip">支持上传尿常规检验报告单等文件 (最多10个)</span>
        <span class="attachment-tip"
          >支持上传尿常规检验报告单等文件 (最多10个)</span
        >
      </div>
      <upload-attachment
        :file-list="attachments"
@@ -206,7 +203,11 @@
        >
          åˆ é™¤
        </el-button>
        <el-button type="primary" @click="confirmAddColumn" :loading="saveLoading">
        <el-button
          type="primary"
          @click="confirmAddColumn"
          :loading="saveLoading"
        >
          ç¡®å®š
        </el-button>
      </span>
@@ -218,18 +219,19 @@
import UploadAttachment from "@/components/UploadAttachment";
export default {
  name: 'UrineRoutinePanel',
  name: "UrineRoutinePanel",
  components: {
    UploadAttachment,
    UploadAttachment
  },
  props: {
    isEditing: {
      type: Boolean,
      default: false
    },
    // ä¿®æ”¹ä¸º Object ç±»åž‹ï¼Œæ”¯æŒå¤æ‚数据结构
    initialData: {
      type: Array,
      default: () => []
      type: Object,
      default: () => ({})
    },
    showStatistics: {
      type: Boolean,
@@ -239,33 +241,23 @@
  data() {
    return {
      tableData: [],
      dynamicColumns: [
        {
          label: '2024-12-27\n08:00',
          key: 'time1',
          date: '2024-12-27',
          time: '08:00',
          remark: '晨尿检测'
        }
      ],
      dynamicColumns: [],
      attachments: [],
      columnDialogVisible: false,
      columnForm: {
        date: '',
        time: '',
        remark: ''
        date: "",
        time: "",
        remark: ""
      },
      editingColumnIndex: null,
      tableKey: 0,
      tableLoading: false,
      saveLoading: false,
      // å†…部数据状态
      internalData: {},
      columnRules: {
        date: [
          { required: true, message: '请选择日期', trigger: 'change' }
        ],
        time: [
          { required: true, message: '请选择时间', trigger: 'change' }
        ]
        date: [{ required: true, message: "请选择日期", trigger: "change" }],
        time: [{ required: true, message: "请选择时间", trigger: "change" }]
      }
    };
  },
@@ -274,7 +266,7 @@
      let count = 0;
      this.tableData.forEach(row => {
        row.values.forEach(value => {
          if (value && value.toString().trim() !== '') {
          if (value && value.toString().trim() !== "") {
            count++;
          }
        });
@@ -287,14 +279,22 @@
    }
  },
  watch: {
    // ç›‘听 initialData å˜åŒ–,确保数据正确接收
    initialData: {
      handler(newData) {
        console.log(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: 'urine_routine',
          data: this.tableData,
          columns: this.dynamicColumns,
          attachments: this.attachments
        });
        this.saveData();
      }
      this.$nextTick(() => {
        this.forceTableLayout();
@@ -311,114 +311,168 @@
    }
  },
  methods: {
    initTableData() {
      const medicalItems = [
    // ä»Žå¤–部数据初始化组件
    initFromExternalData() {
      console.log(this.internalData,'this.internalData');
      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 = this.getMedicalItems();
      // å¦‚果没有动态列,初始化默认列
      if (this.dynamicColumns.length === 0) {
        this.dynamicColumns = [
        {
          itemName: '尿量',
          type: 'number',
            label: `${new Date().toISOString().split("T")[0]}\n08:00`,
            key: "time1",
            date: new Date().toISOString().split("T")[0],
            time: "08:00",
            remark: "晨尿检测"
          }
        ];
      }
      this.tableData = medicalItems.map(item => ({
        ...item,
        values: new Array(this.dynamicColumns.length).fill("")
      }));
    },
    // å°¿å¸¸è§„检测项目定义
    getMedicalItems() {
      return [
        {
          itemName: "尿量",
          type: "number",
          required: true,
          unit: 'ml/h',
          reference: '正常范围视情况而定'
          unit: "ml/h",
          reference: "正常范围视情况而定"
        },
        {
          itemName: '颜色',
          type: 'select',
          itemName: "颜色",
          type: "select",
          required: true,
          options: [
            { value: '淡黄色', label: '淡黄色' },
            { value: '黄色', label: '黄色' },
            { value: '深黄色', label: '深黄色' },
            { value: '红色', label: '红色' },
            { value: '白色', label: '白色' },
            { value: '其他', label: '其他' }
            { value: "淡黄色", label: "淡黄色" },
            { value: "黄色", label: "黄色" },
            { value: "深黄色", label: "深黄色" },
            { value: "红色", label: "红色" },
            { value: "白色", label: "白色" },
            { value: "其他", label: "其他" }
          ]
        },
        {
          itemName: '外观',
          type: 'select',
          itemName: "外观",
          type: "select",
          required: false,
          options: [
            { value: '清亮', label: '清亮' },
            { value: '微浊', label: '微浊' },
            { value: '浑浊', label: '浑浊' },
            { value: '沉淀', label: '沉淀' },
            { value: '其他', label: '其他' }
            { value: "清亮", label: "清亮" },
            { value: "微浊", label: "微浊" },
            { value: "浑浊", label: "浑浊" },
            { value: "沉淀", label: "沉淀" },
            { value: "其他", label: "其他" }
          ]
        },
        {
          itemName: '尿蛋白',
          type: 'select',
          itemName: "尿蛋白",
          type: "select",
          required: true,
          options: [
            { value: '-', label: '阴性(-)' },
            { value: '±', label: '微量(±)' },
            { value: '+', label: '阳性(+)' },
            { value: '++', label: '阳性(++)' },
            { value: '+++', label: '阳性(+++)' }
            { value: "-", label: "阴性(-)" },
            { value: "±", label: "微量(±)" },
            { value: "+", label: "阳性(+)" },
            { value: "++", label: "阳性(++)" },
            { value: "+++", label: "阳性(+++)" }
          ],
          reference: '正常为阴性(-)'
          reference: "正常为阴性(-)"
        },
        {
          itemName: 'pH值',
          type: 'number',
          itemName: "pH值",
          type: "number",
          required: true,
          placeholder: '4.5-8.0',
          unit: '',
          reference: '4.5-8.0',
          placeholder: "4.5-8.0",
          unit: "",
          reference: "4.5-8.0",
          min: 4.5,
          max: 8.0
        },
        {
          itemName: '白细胞',
          type: 'select',
          itemName: "白细胞",
          type: "select",
          required: true,
          options: [
            { value: '-', label: '阴性(-)' },
            { value: '+', label: '阳性(+)' },
            { value: '++', label: '阳性(++)' },
            { value: '+++', label: '阳性(+++)' }
            { value: "-", label: "阴性(-)" },
            { value: "+", label: "阳性(+)" },
            { value: "++", label: "阳性(++)" },
            { value: "+++", label: "阳性(+++)" }
          ],
          reference: '正常为阴性(-)'
          reference: "正常为阴性(-)"
        },
        {
          itemName: '红细胞',
          type: 'number',
          itemName: "红细胞",
          type: "number",
          required: true,
          unit: '/μL',
          reference: '0-9.2',
          unit: "/μL",
          reference: "0-9.2",
          min: 0,
          max: 9.2
        },
        {
          itemName: '细菌',
          type: 'number',
          itemName: "细菌",
          type: "number",
          required: true,
          unit: '/μL',
          reference: '0-385',
          unit: "/μL",
          reference: "0-385",
          min: 0,
          max: 385
        }
      ];
    },
      this.tableData = medicalItems.map(item => ({
        ...item,
        values: new Array(this.dynamicColumns.length).fill('')
      }));
    // ä¿å­˜æ•°æ®åˆ°çˆ¶ç»„ä»¶
    saveData() {
      const dataToEmit = {
        type: "urine_routine",
        data: this.tableData,
        columns: this.dynamicColumns,
        attachments: this.attachments
      };
      this.$emit("data-change", dataToEmit);
    },
    getSelectLabel(row, columnIndex) {
      if (!row.options || !row.values[columnIndex]) return row.values[columnIndex];
      const option = row.options.find(opt => opt.value === row.values[columnIndex]);
      if (!row.options || !row.values[columnIndex])
        return row.values[columnIndex];
      const option = row.options.find(
        opt => opt.value === row.values[columnIndex]
      );
      return option ? option.label : row.values[columnIndex];
    },
    addColumn() {
      this.editingColumnIndex = null;
      this.columnForm = {
        date: new Date().toISOString().split('T')[0],
        time: '08:00',
        remark: ''
        date: new Date().toISOString().split("T")[0],
        time: "08:00",
        remark: ""
      };
      this.columnDialogVisible = true;
      this.$nextTick(() => {
@@ -432,15 +486,15 @@
      this.columnForm = {
        date: column.date,
        time: column.time,
        remark: column.remark || ''
        remark: column.remark || ""
      };
      this.columnDialogVisible = true;
    },
    confirmAddColumn() {
      this.$refs.columnFormU.validate((valid) => {
      this.$refs.columnFormU.validate(valid => {
        if (!valid) {
          this.$message.warning('请完善时间点信息');
          this.$message.warning("请完善时间点信息");
          return;
        }
@@ -453,10 +507,9 @@
          column.date = this.columnForm.date;
          column.time = this.columnForm.time;
          column.remark = this.columnForm.remark;
          this.$message.success('时间点修改成功');
          this.$message.success("时间点修改成功");
        } else {
          // æ–°å¢žåˆ—
          const newIndex = this.dynamicColumns.length + 1;
          const newColumn = {
            label: `${this.columnForm.date}\n${this.columnForm.time}`,
            key: `time${Date.now()}`,
@@ -464,12 +517,14 @@
            time: this.columnForm.time,
            remark: this.columnForm.remark
          };
          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.$message.success('时间点添加成功');
          this.$message.success("时间点添加成功");
        }
        this.columnDialogVisible = false;
@@ -480,10 +535,10 @@
    handleDeleteColumn() {
      if (this.editingColumnIndex !== null) {
        this.$confirm('确定要删除这个时间点吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        this.$confirm("确定要删除这个时间点吗?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }).then(() => {
          this.dynamicColumns.splice(this.editingColumnIndex, 1);
          this.tableData.forEach(row => {
@@ -491,7 +546,7 @@
          });
          this.columnDialogVisible = false;
          this.tableKey += 1;
          this.$message.success('时间点删除成功');
          this.$message.success("时间点删除成功");
        });
      }
    },
@@ -499,9 +554,9 @@
    handleDialogClosed() {
      this.editingColumnIndex = null;
      this.columnForm = {
        date: '',
        time: '',
        remark: ''
        date: "",
        time: "",
        remark: ""
      };
      this.$refs.columnFormU && this.$refs.columnFormU.clearValidate();
    },
@@ -511,26 +566,22 @@
    },
    handleValueChange(row, columnIndex) {
      this.$emit('data-change', {
        type: 'urine_routine',
        data: this.tableData,
        columns: this.dynamicColumns
      });
      this.saveData();
    },
    handleAttachmentChange(fileList) {
      this.attachments = fileList;
      this.$emit('attachment-change', {
        type: 'urine_routine',
      this.$emit("attachment-change", {
        type: "urine_routine",
        attachments: fileList
      });
    },
    forceTableLayout() {
      this.$nextTick(() => {
        const table = this.$el.querySelector('.el-table');
        const table = this.$el.querySelector(".el-table");
        if (table) {
          window.dispatchEvent(new Event('resize'));
          window.dispatchEvent(new Event("resize"));
        }
      });
    },
@@ -554,7 +605,13 @@
    }
  },
  mounted() {
    // ç¡®ä¿ç»„件正确挂载后初始化数据
    this.$nextTick(() => {
      if (Object.keys(this.internalData).length === 0) {
    this.initTableData();
      }
      this.forceTableLayout();
    });
  }
};
</script>
@@ -739,13 +796,5 @@
    flex-direction: column;
    gap: 4px;
  }
}
/* åŠ¨ç”»æ•ˆæžœ */
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>
src/views/business/maintain/index.vue
@@ -8,37 +8,37 @@
        :inline="true"
        label-width="100px"
      >
        <el-form-item label="捐献者姓名" prop="donorName">
        <el-form-item label="捐献者姓名" prop="name">
          <el-input
            v-model="queryParams.donorName"
            v-model="queryParams.name"
            placeholder="请输入捐献者姓名"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="所在医疗机构" prop="hospitalName">
        <el-form-item label="所在医疗机构" prop="treatmenthospitalname">
          <el-input
            v-model="queryParams.hospitalName"
            v-model="queryParams.treatmenthospitalname"
            placeholder="请输入医疗机构"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="医疗组人员" prop="medicalStaff">
        <el-form-item label="协调员" prop="coordinatorName">
          <el-input
            v-model="queryParams.medicalStaff"
            placeholder="请输入医疗组人员"
            v-model="queryParams.coordinatorName"
            placeholder="请输入协调员姓名"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="患者状态" prop="patientStatus">
        <el-form-item label="患者状态" prop="recordstate">
          <el-select
            v-model="queryParams.patientStatus"
            placeholder="请选择患者状态"
            v-model="queryParams.recordstate"
            placeholder="请选择记录状态"
            clearable
            style="width: 200px"
          >
@@ -48,6 +48,23 @@
            <el-option label="已完成捐献" value="4" />
            <el-option label="未完成捐献" value="5" />
          </el-select>
        </el-form-item>
        <el-form-item label="年龄范围" prop="ageRange">
          <el-input
            v-model="queryParams.startAge"
            placeholder="最小年龄"
            clearable
            style="width: 95px"
            @keyup.enter.native="handleQuery"
          />
          <span style="margin: 0 5px">-</span>
          <el-input
            v-model="queryParams.endAge"
            placeholder="最大年龄"
            clearable
            style="width: 95px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="档案录入时间" prop="recordTimeRange">
          <el-date-picker
@@ -73,23 +90,6 @@
    <el-card class="tool-card">
      <el-row :gutter="10">
        <el-col :span="16">
          <!-- <el-button type="primary" icon="el-icon-plus" @click="handleCreate"
            >新增维护</el-button
          > -->
          <el-button
            type="success"
            icon="el-icon-edit"
            :disabled="single"
            @click="handleUpdate"
            >修改</el-button
          >
          <el-button
            type="danger"
            icon="el-icon-delete"
            :disabled="multiple"
            @click="handleDelete"
            >删除</el-button
          >
          <el-button
            type="warning"
            icon="el-icon-download"
@@ -121,113 +121,101 @@
          width="120"
        />
        <el-table-column
          label="潜在捐献者姓名"
          label="捐献者编号"
          align="center"
          prop="donorName"
          prop="donorno"
          width="120"
        />
        <el-table-column label="性别" align="center" prop="gender" width="80">
        <el-table-column
          label="潜在捐献者姓名"
          align="center"
          prop="name"
          width="120"
        />
        <el-table-column label="性别" align="center" prop="sex" width="80">
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_user_sex"
              :value="parseInt(scope.row.gender)"
              :value="scope.row.sex"
            />
          </template>
        </el-table-column>
        <el-table-column label="年龄" align="center" prop="age" width="80" />
        <el-table-column
          label="血型"
          align="center"
          prop="bloodtype"
          width="80"
        >
          <template slot-scope="scope">
            <dict-tag
              :options="dict.type.sys_BloodType"
              :value="scope.row.bloodtype"
            /> </template
        ></el-table-column>
        <el-table-column
          label="疾病诊断"
          align="center"
          prop="diagnosis"
          prop="diagnosisname"
          min-width="180"
          show-overflow-tooltip
        />
        <el-table-column
          label="所在医疗机构"
          label="首诊医疗机构"
          align="center"
          prop="hospitalName"
          prop="treatmenthospitalname"
          width="150"
          show-overflow-tooltip
        />
        <el-table-column
          label="患者状态"
          label="住院号"
          align="center"
          prop="patientStatus"
          prop="inpatientno"
          width="120"
        >
          <template slot-scope="scope">
            <el-tag :type="statusFilter(scope.row.patientStatus)">
              {{ statusTextFilter(scope.row.patientStatus) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          label="入院时间"
          align="center"
          prop="admissionTime"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.admissionTime
                ? parseTime(scope.row.admissionTime, "{y}-{m}-{d}")
                : "-"
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="出院时间"
          align="center"
          prop="dischargeTime"
          width="120"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.dischargeTime
                ? parseTime(scope.row.dischargeTime, "{y}-{m}-{d}")
                : "-"
            }}</span>
          </template>
        </el-table-column>
        />
        <!-- <el-table-column
          label="最新培养结果"
          label="记录状态"
          align="center"
          prop="latestCultureResult"
          prop="recordstate"
          width="120"
        >
          <template slot-scope="scope">
            <el-tag
              :type="scope.row.latestCultureResult === '阴性' ? 'success' : 'danger'"
              effect="plain"
            >
              {{ scope.row.latestCultureResult || '未检测' }}
            <el-tag :type="statusFilter(scope.row.recordstate)">
              {{ statusTextFilter(scope.row.recordstate) }}
            </el-tag>
          </template>
        </el-table-column> -->
        <!-- <el-table-column
          label="护理核查表录入时间"
          align="center"
          prop="lastRecordTime"
          width="140"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.lastRecordTime
                ? parseTime(scope.row.lastRecordTime, "{y}-{m}-{d} {h}:{i}")
                : "-"
            }}</span>
          </template>
        </el-table-column> -->
        <el-table-column
          label="协调员"
          align="center"
          prop="coordinator"
          prop="coordinatorName"
          width="100"
        />
        <el-table-column
          label="维护项目"
          align="center"
          prop="itemName"
          width="120"
          show-overflow-tooltip
        />
        <el-table-column
          label="维护时间"
          align="center"
          prop="itemTime"
          width="140"
        >
          <template slot-scope="scope">
            <span>{{
              scope.row.itemTime
                ? parseTime(scope.row.itemTime, "{y}-{m}-{d} {h}:{i}")
                : "-"
            }}</span>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          align="center"
          width="180"
          width="120"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
@@ -238,20 +226,6 @@
              @click.stop="handleView(scope.row)"
              >详情</el-button
            >
            <!-- <el-button
              size="mini"
              type="text"
              icon="el-icon-edit"
              @click.stop="handleRecord(scope.row)"
              >录入核查</el-button
            >
            <el-button
              size="mini"
              type="text"
              icon="el-icon-document"
              @click.stop="handleRecordList(scope.row)"
              >记录查询</el-button
            > -->
          </template>
        </el-table-column>
      </el-table>
@@ -269,13 +243,13 @@
</template>
<script>
import { listMaintenance, delMaintenance, exportMaintenance } from "./mockMaintenanceApi";
import { maintainList } from "@/api/businessApi";
import Pagination from "@/components/Pagination";
export default {
  name: "MaintenanceList",
  components: { Pagination },
  dicts: ["sys_user_sex"],
  dicts: ["sys_user_sex",'sys_BloodType'],
  data() {
    return {
      // é®ç½©å±‚
@@ -294,11 +268,19 @@
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        donorName: undefined,
        hospitalName: undefined,
        medicalStaff: undefined,
        patientStatus: undefined,
        recordTimeRange: []
        name: undefined, // æçŒ®è€…姓名
        treatmenthospitalname: undefined, // åŒ»ç–—机构名称
        coordinatorName: undefined, // åè°ƒå‘˜å§“名
        recordstate: undefined, // è®°å½•状态
        startAge: undefined, // å¼€å§‹å¹´é¾„
        endAge: undefined, // ç»“束年龄
        caseNo: undefined, // æ¡ˆä¾‹ç¼–号
        donorno: undefined, // æçŒ®è€…编号
        sex: undefined, // æ€§åˆ«
        bloodtype: undefined, // è¡€åž‹
        diagnosisname: undefined, // ç–¾ç—…诊断名称
        inpatientno: undefined, // ä½é™¢å·
        recordTimeRange: [] // æ—¶é—´èŒƒå›´
      }
    };
  },
@@ -330,13 +312,45 @@
    // æŸ¥è¯¢ä¾›è€…维护列表
    getList() {
      this.loading = true;
      listMaintenance(this.queryParams)
      // å¤„理查询参数,过滤掉空值
      const params = this.cleanObject(this.queryParams);
      // å¤„理时间范围参数
      if (params.recordTimeRange && params.recordTimeRange.length === 2) {
        params.startTime = params.recordTimeRange[0] + " 00:00:00";
        params.endTime = params.recordTimeRange[1] + " 23:59:59";
        delete params.recordTimeRange;
      }
      // åˆ é™¤åˆ†é¡µå‚数中的空值
      delete params.pageNum;
      delete params.pageSize;
      maintainList({
        pageNum: this.queryParams.pageNum,
        pageSize: this.queryParams.pageSize,
        ...params
      })
        .then(response => {
          if (response.code === 200) {
            this.maintenanceList = response.data.rows;
            this.total = response.data.total;
            this.maintenanceList = response.data;
            this.total = response.total || 0;
            // å¤„理年龄显示
            this.maintenanceList.forEach(item => {
              if (item.startAge !== undefined && item.endAge !== undefined) {
                item.age = `${item.startAge}-${item.endAge}`;
              } else if (item.startAge !== undefined) {
                item.age = `${item.startAge}+`;
              } else if (item.endAge !== undefined) {
                item.age = `0-${item.endAge}`;
          } else {
            this.$message.error("获取数据失败");
                item.age = "-";
              }
            });
          } else {
            this.$message.error(response.msg || "获取数据失败");
          }
          this.loading = false;
        })
@@ -346,6 +360,16 @@
          this.$message.error("获取数据失败");
        });
    },
    // æ¸…理对象中的空值
    cleanObject(obj) {
      const cleaned = {};
      Object.keys(obj).forEach(key => {
        if (obj[key] !== undefined && obj[key] !== null && obj[key] !== "") {
          cleaned[key] = obj[key];
        }
      });
      return cleaned;
    },
    // æœç´¢æŒ‰é’®æ“ä½œ
    handleQuery() {
      this.queryParams.pageNum = 1;
@@ -353,8 +377,26 @@
    },
    // é‡ç½®æŒ‰é’®æ“ä½œ
    resetQuery() {
      this.$refs.queryForm.resetFields();
      this.handleQuery();
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        name: undefined,
        treatmenthospitalname: undefined,
        coordinatorName: undefined,
        recordstate: undefined,
        startAge: undefined,
        endAge: undefined,
        caseNo: undefined,
        donorno: undefined,
        sex: undefined,
        bloodtype: undefined,
        diagnosisname: undefined,
        inpatientno: undefined,
        recordTimeRange: []
      };
      this.$nextTick(() => {
        this.getList();
      });
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
@@ -366,64 +408,20 @@
    handleRowClick(row) {
      this.$router.push({
        path: "/case/maintainInfo",
        query: { id: row.id }
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // æŸ¥çœ‹è¯¦æƒ…
    handleView(row) {
      this.$router.push({
        path: "/case/maintainInfo",
        query: { id: row.id }
        query: { id: row.id, infoid: row.infoid }
      });
    },
    // å½•入护理核查
    handleRecord(row) {
      this.$router.push({
        path: "/case/maintenance/record",
        query: { id: row.id, maintenanceId: row.maintenanceId }
      });
    },
    // æŸ¥çœ‹è®°å½•列表
    handleRecordList(row) {
      this.$router.push({
        path: "/case/maintenance/records",
        query: { id: row.id, maintenanceId: row.maintenanceId }
      });
    },
    // æ–°å¢žæŒ‰é’®æ“ä½œ
    handleCreate() {
      this.$router.push("/case/maintenance/add");
    },
    // ä¿®æ”¹æŒ‰é’®æ“ä½œ
    handleUpdate() {
      const id = this.ids[0];
      this.$router.push({
        path: "/case/maintenance/edit",
        query: { id: id }
      });
    },
    // åˆ é™¤æŒ‰é’®æ“ä½œ
    handleDelete() {
      const ids = this.ids;
      this.$confirm("是否确认删除选中的数据项?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          return delMaintenance(ids);
        })
        .then(response => {
          if (response.code === 200) {
            this.$message.success("删除成功");
            this.getList();
          }
        })
        .catch(() => {});
    },
    // å¯¼å‡ºæŒ‰é’®æ“ä½œ
    handleExport() {
      const queryParams = this.queryParams;
      const queryParams = this.cleanObject(this.queryParams);
      this.$confirm("是否确认导出所有维护数据?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
@@ -431,13 +429,11 @@
      })
        .then(() => {
          this.loading = true;
          return exportMaintenance(queryParams);
        })
        .then(response => {
          if (response.code === 200) {
          // è¿™é‡Œéœ€è¦è°ƒç”¨å¯¼å‡ºæŽ¥å£ï¼Œæš‚时用模拟成功
          setTimeout(() => {
            this.$message.success("导出成功");
          }
          this.loading = false;
          }, 1000);
        })
        .catch(() => {
          this.loading = false;
@@ -450,16 +446,36 @@
      if (pattern) {
        return pattern.replace(/{(\w+)}/g, (match, p) => {
          switch(p) {
            case 'y': return date.getFullYear();
            case 'm': return (date.getMonth() + 1).toString().padStart(2, '0');
            case 'd': return date.getDate().toString().padStart(2, '0');
            case 'h': return date.getHours().toString().padStart(2, '0');
            case 'i': return date.getMinutes().toString().padStart(2, '0');
            default: return match;
            case "y":
              return date.getFullYear();
            case "m":
              return (date.getMonth() + 1).toString().padStart(2, "0");
            case "d":
              return date
                .getDate()
                .toString()
                .padStart(2, "0");
            case "h":
              return date
                .getHours()
                .toString()
                .padStart(2, "0");
            case "i":
              return date
                .getMinutes()
                .toString()
                .padStart(2, "0");
            default:
              return match;
          }
        });
      }
      return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`;
      return `${date.getFullYear()}-${(date.getMonth() + 1)
        .toString()
        .padStart(2, "0")}-${date
        .getDate()
        .toString()
        .padStart(2, "0")}`;
    }
  }
};
src/views/business/maintain/maintainInfo.vue
@@ -4,12 +4,7 @@
    <el-card class="detail-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">供者基本信息</span>
        <el-button
          v-if="isEdit"
          type="primary"
          style="float: right; padding: 3px 0"
          @click="handleSave"
        >
        <el-button type="success" style="float: right;" @click="handleSave">
          ä¿å­˜ä¿¡æ¯
        </el-button>
      </div>
@@ -18,21 +13,17 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="住院号" prop="caseNo">
              <el-input v-model="form.caseNo" :readonly="!isEdit" />
              <el-input v-model="form.caseNo" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="捐献者姓名" prop="donorName">
              <el-input v-model="form.donorName" :readonly="!isEdit" />
            <el-form-item label="捐献者姓名" prop="name">
              <el-input v-model="form.name" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="性别" prop="gender">
              <el-select
                v-model="form.gender"
                :disabled="!isEdit"
                style="width: 100%"
              >
              <el-select v-model="form.sex" style="width: 100%">
                <el-option label="男" value="0" />
                <el-option label="女" value="1" />
              </el-select>
@@ -43,46 +34,61 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="年龄" prop="age">
              <el-input v-model="form.age" :readonly="!isEdit" />
              <el-input v-model="form.age" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="疾病诊断" prop="diagnosis">
              <el-input v-model="form.diagnosis" :readonly="!isEdit" />
            <el-form-item label="疾病诊断" prop="diagnosisname">
              <el-input v-model="form.diagnosisname" />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="所在医疗机构" prop="hospitalName">
              <el-input v-model="form.hospitalName" :readonly="!isEdit" />
            <el-form-item label="首诊医疗机构" prop="treatmenthospitalname">
              <el-input v-model="form.treatmenthospitalname" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="患者状态" prop="patientStatus">
              <el-select
                v-model="form.patientStatus"
                :disabled="!isEdit"
                style="width: 100%"
              >
                <el-option label="DCD" value="1" />
            <el-form-item label="患者状态" prop="recordstate">
              <el-select v-model="form.recordstate" style="width: 100%">
                <!-- <el-option label="DCD" value="1" />
                <el-option label="DBD" value="2" />
                <el-option label="DBCD" value="3" />
                <el-option label="已完成捐献" value="4" />
                <el-option label="未完成捐献" value="5" />
                <el-option label="未完成捐献" value="5" /> -->
                <el-option
                  v-for="dict in dict.type.sys_DonationCategory || []"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
            <!-- <el-form-item
              align="left"
              label="患者捐献状态"
              prop="donationcategory"
            >
              <el-radio-group v-model="form.recordstate">
                <el-radio
                  v-for="dict in dict.type.sys_DonationCategory || []"
                  :key="dict.value"
                  :label="dict.value"
                  >{{ dict.label }}</el-radio
                >
              </el-radio-group>
            </el-form-item> -->
          </el-col>
          <el-col :span="8">
            <el-form-item
              label="未完成原因"
              prop="incompleteReason"
              v-if="form.patientStatus === '5'"
              v-if="form.recordstate === '5'"
            >
              <el-input
                v-model="form.incompleteReason"
                :readonly="!isEdit"
                placeholder="请输入未完成捐献的原因"
              />
            </el-form-item>
@@ -91,59 +97,59 @@
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="入院时间" prop="admissionTime">
            <el-form-item label="上报时间" prop="reporttime">
              <el-date-picker
                v-model="form.admissionTime"
                v-model="form.reporttime"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
                :disabled="!isEdit"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="出院时间" prop="dischargeTime">
            <el-form-item label="死亡时间" prop="deathTime">
              <el-date-picker
                v-model="form.dischargeTime"
                v-model="form.deathTime"
                type="datetime"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
                :disabled="!isEdit"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="协调员" prop="coordinator">
              <el-input v-model="form.coordinator" :readonly="!isEdit" />
            <el-form-item label="协调员" prop="coordinatorName">
              <el-input v-model="form.coordinatorName" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="血型" prop="bloodType">
              <el-select
                v-model="form.bloodType"
                :disabled="!isEdit"
                style="width: 100%"
              >
                <el-option label="A型" value="A" />
            <el-form-item label="血型" prop="bloodtype">
              <el-select v-model="form.bloodtype" style="width: 100%">
                <!-- <el-option label="A型" value="A" />
                <el-option label="B型" value="B" />
                <el-option label="O型" value="O" />
                <el-option label="AB型" value="AB" />
                <el-option label="AB型" value="AB" /> -->
                <el-option
                  v-for="dict in dict.type.sys_BloodType"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="RH因子" prop="rhFactor">
              <el-select
                v-model="form.rhFactor"
                :disabled="!isEdit"
                style="width: 100%"
            <el-form-item label="Rh(D)" prop="rhYin">
              <el-radio-group v-model="form.rhYin">
                <el-radio
                  v-for="dict in dict.type.sys_bloodtype_rhd || []"
                  :key="dict.value"
                  :label="dict.value"
                  >{{ dict.label }}</el-radio
              >
                <el-option label="阳性" value="positive" />
                <el-option label="阴性" value="negative" />
              </el-select>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
@@ -153,12 +159,12 @@
            type="textarea"
            :rows="3"
            v-model="form.specialMedicalHistory"
            :readonly="!isEdit"
            placeholder="记录特殊病史信息"
          />
        </el-form-item>
      </el-form>
    </el-card>
    <el-card class="assessment-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">供者评估各项记录</span>
@@ -193,14 +199,7 @@
                label="培养类型"
                align="center"
                prop="cultureType"
              >
                <!-- <template slot-scope="scope">
            <dict-tag
              :options="cultureTypeOptions"
              :value="scope.row.cultureType"
            />
          </template> -->
              </el-table-column>
              <el-table-column
                label="采样时间"
                align="center"
@@ -216,7 +215,6 @@
                  </el-tag>
                </template>
              </el-table-column>
              <!-- é™„件列 -->
              <el-table-column label="附件" align="center">
                <template slot-scope="scope">
                  <el-button
@@ -257,14 +255,6 @@
                </template>
              </el-table-column>
            </el-table>
            <pagination
              v-show="cultureTotal > 0"
              :total="cultureTotal"
              :page.sync="cultureQueryParams.pageNum"
              :limit.sync="cultureQueryParams.pageSize"
              @pagination="getCultureList"
            />
          </el-card>
        </el-tab-pane>
@@ -272,6 +262,7 @@
        <el-tab-pane label="肝功能肾功能" name="liverKidney">
          <liver-kidney-panel
            ref="liverKidney"
            :initial-data="assessmentData.liverKidney"
            :is-editing="isEdit && activeTab === 'liverKidney'"
            @data-change="handleLiverKidneyDataChange"
          />
@@ -281,6 +272,7 @@
        <el-tab-pane label="血常规" name="bloodRoutine">
          <blood-routine-panel
            ref="bloodRoutine"
            :initial-data="assessmentData.bloodRoutine"
            :is-editing="isEdit && activeTab === 'bloodRoutine'"
            @data-change="handleBloodRoutineDataChange"
          />
@@ -290,15 +282,15 @@
        <el-tab-pane label="尿常规" name="urineRoutine">
          <urine-routine-panel
            ref="urineRoutine"
            :initial-data="assessmentData.urineRoutine"
            :is-editing="isEdit && activeTab === 'urineRoutine'"
            @data-change="handleUrineRoutineDataChange"
          />
        </el-tab-pane>
      </el-tabs>
    </el-card>
    <!-- åŸ¹å…»ç»“果记录 -->
    <!-- ç®€åŒ–后的护理核查记录 -->
    <!-- æŠ¤ç†æ ¸æŸ¥è®°å½• -->
    <el-card class="record-card">
      <div slot="header" class="clearfix">
        <span class="detail-title">护理核查记录</span>
@@ -332,7 +324,6 @@
          min-width="200"
          show-overflow-tooltip
        />
        <!-- é™„件列 -->
        <el-table-column label="附件" align="center" width="120">
          <template slot-scope="scope">
            <el-button
@@ -352,6 +343,7 @@
          width="180"
          class-name="small-padding fixed-width"
        >
          <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
@@ -367,17 +359,11 @@
            @click="handleDeleteRecord(scope.row)"
            >删除</el-button
          >
          </template>
        </el-table-column>
      </el-table>
      <pagination
        v-show="recordTotal > 0"
        :total="recordTotal"
        :page.sync="recordQueryParams.pageNum"
        :limit.sync="recordQueryParams.pageSize"
        @pagination="getRecordList"
      />
    </el-card>
    <!-- åŸ¹å…»è®°å½•编辑对话框 -->
    <el-dialog
      :title="cultureDialogTitle"
@@ -436,7 +422,6 @@
          </el-col>
        </el-row>
        <!-- é™„件上传 -->
        <el-form-item label="附件">
          <upload-attachment
            :file-list="cultureForm.attachments"
@@ -500,7 +485,6 @@
          />
        </el-form-item>
        <!-- é™„件上传 -->
        <el-form-item label="附件">
          <upload-attachment
            :file-list="recordForm.attachments"
@@ -531,19 +515,7 @@
</template>
<script>
import { getMaintenanceDetail, updateMaintenance } from "./mockMaintenanceApi";
import {
  listCultureResults,
  addCultureResult,
  updateCultureResult,
  deleteCultureResult
} from "./mockMaintenanceApi";
import {
  listNursingRecords,
  addNursingRecord,
  updateNursingRecord,
  deleteNursingRecord
} from "./mockMaintenanceApi";
import { maintainList, maintainedit, maintainAdd } from "@/api/businessApi";
import Pagination from "@/components/Pagination";
import UploadAttachment from "@/components/UploadAttachment";
import AttachmentPreview from "@/components/AttachmentPreview";
@@ -561,120 +533,44 @@
    BloodRoutinePanel,
    UrineRoutinePanel
  },
  dicts: [
    "sys_donornode",
    "sys_BloodType",
    "sys_EthicalReview",
    "sys_BaseAssessConclusion",
    "sys_bloodtype_rhd",
    "sys_DonationCategory"
  ],
  data() {
    return {
      isEdit: true,
      isEdit: false,
      currentMaintenanceId: null,
      isEditMode: false,
      form: {
        id: undefined,
        caseNo: "",
        donorName: "",
        name: "",
        gender: "",
        age: "",
        diagnosis: "",
        hospitalName: "",
        patientStatus: "1",
        admissionTime: "",
        dischargeTime: "",
        coordinator: "",
        bloodType: "",
        diagnosisname: "",
        treatmenthospitalname: "",
        recordstate: "1",
        reporttime: "",
        deathTime: "",
        coordinatorName: "",
        bloodtype: "",
        rhFactor: "",
        specialMedicalHistory: "",
        incompleteReason: ""
      },
      activeTab: "culture",
      liverKidneyData: {}, // ä»Ž maintainList æŽ¥å£èŽ·å–çš„æ•°æ®
      bloodRoutineData: {}, // ä»Ž maintainList æŽ¥å£èŽ·å–çš„æ•°æ®
      liverKidneyData: {}, // ä»Ž maintainList æŽ¥å£èŽ·å–çš„æ•°æ®
      // åŸ¹å…»ç»“果相关数据
      // åŸ¹å…»ç»“果相关数据
      cultureList: [
        {
          id: 1,
          cultureType: "血培养",
          sampleTime: "2024-12-19 10:30:00",
          result: "阴性",
          bacteria: "",
          drugSensitivity: "",
          testingInstitution: "青岛大学附属医院",
          specimenType: "血液",
          remarks: "常规检测",
          attachments: [
            {
              id: 1,
              fileName: "血培养报告.pdf",
              fileUrl:
                "http://localhost:8080/profile/upload/2025/12/27/1.COPO供体评估表.pdf",
              fileSize: 1024000,
              uploadTime: "2024-12-19 11:00:00"
            }
          ]
        },
        {
          id: 3,
          cultureType: "血培养",
          sampleTime: "2024-12-20 09:15:00",
          result: "阴性",
          bacteria: "",
          drugSensitivity: "",
          testingInstitution: "广州检测中心",
          specimenType: "å°¿æ¶²",
          remarks: "清洁中段尿标本",
          attachments: []
        },
        {
          id: 2,
          cultureType: "痰培养结果",
          sampleTime: "2024-12-19 14:20:00",
          result: "阳性",
          bacteria: "金黄色葡萄球菌",
          drugSensitivity: "对青霉素敏感,对头孢类中介",
          testingInstitution: "上海医学检验所",
          specimenType: "痰液",
          remarks: "药敏试验完成",
          attachments: [
            {
              id: 2,
              fileName: "痰培养结果.jpg",
              fileUrl:
                "https://img95.699pic.com/photo/40142/8262.jpg_wh860.jpg",
              fileSize: 512000,
              uploadTime: "2024-12-19 15:30:00"
            },
            {
              id: 3,
              fileName: "药敏报告.pdf",
              fileUrl:
                "http://localhost:8080/profile/upload/2025/12/27/(吴龙8.7)每日工作总结.pdf",
              fileSize: 768000,
              uploadTime: "2024-12-19 16:00:00"
            }
          ]
        },
        {
          id: 4,
          cultureType: "真菌培养",
          sampleTime: "2024-12-20 11:45:00",
          result: "阳性",
          bacteria: "大肠杆菌",
          drugSensitivity: "对左氧氟沙星敏感",
          testingInstitution: "深圳人民医院",
          specimenType: "伤口分泌物",
          remarks: "术后伤口感染监测",
          attachments: [
            {
              id: 4,
              fileName: "真菌培养.pdf",
              fileUrl: "/reports/culture4.pdf",
              fileSize: 890000,
              uploadTime: "2024-12-20 13:20:00"
            }
          ]
        }
      ],
      cultureList: [],
      cultureLoading: false,
      cultureTotal: 5,
      cultureQueryParams: {
        pageNum: 1,
        pageSize: 10
      },
      cultureDialogVisible: false,
      cultureDialogTitle: "",
      cultureSaveLoading: false,
@@ -683,7 +579,7 @@
        cultureType: "",
        sampleTime: "",
        result: "阴性",
        attachments: [] // æ–°å¢žé™„件字段
        attachments: []
      },
      cultureRules: {
        cultureType: [
@@ -706,120 +602,8 @@
      ],
      // æŠ¤ç†æ ¸æŸ¥è®°å½•相关数据
      recordList: [
        {
          id: 1,
          recordTime: "2024-12-19 08:30:00",
          recorder: "张护士",
          temperature: 36.8,
          heartRate: 78,
          bloodPressure: "120/80",
          respirationRate: 18,
          oxygenSaturation: 98,
          urineOutput: 60,
          cvp: 8,
          checkRecord: "患者生命体征平稳,意识清楚,配合治疗",
          remarks: "夜间睡眠良好",
          attachments: [
            {
              id: 1,
              fileName: "早班护理记录.jpg",
              fileUrl: "/records/nursing1.jpg",
              fileSize: 1024000,
              uploadTime: "2024-12-19 09:00:00"
            }
          ]
        },
        {
          id: 2,
          recordTime: "2024-12-19 14:30:00",
          recorder: "李护士",
          temperature: 37.2,
          heartRate: 82,
          bloodPressure: "118/76",
          respirationRate: 16,
          oxygenSaturation: 97,
          urineOutput: 45,
          cvp: 7.5,
          checkRecord: "患者午后体温略有升高,观察中",
          remarks: "建议增加水分摄入",
          attachments: []
        },
        {
          id: 3,
          recordTime: "2024-12-19 20:30:00",
          recorder: "王护士",
          temperature: 36.9,
          heartRate: 75,
          bloodPressure: "122/78",
          respirationRate: 17,
          oxygenSaturation: 98,
          urineOutput: 55,
          cvp: 8.2,
          checkRecord: "晚间生命体征稳定,患者休息良好",
          remarks: "夜间监测无异常",
          attachments: [
            {
              id: 2,
              fileName: "晚班护理记录.pdf",
              fileUrl: "/records/nursing3.pdf",
              fileSize: 890000,
              uploadTime: "2024-12-19 21:00:00"
            },
            {
              id: 3,
              fileName: "体征监测表.xlsx",
              fileUrl: "/records/monitoring3.xlsx",
              fileSize: 256000,
              uploadTime: "2024-12-19 21:15:00"
            }
          ]
        },
        {
          id: 4,
          recordTime: "2024-12-20 08:30:00",
          recorder: "赵护士",
          temperature: 36.7,
          heartRate: 80,
          bloodPressure: "119/77",
          respirationRate: 18,
          oxygenSaturation: 99,
          urineOutput: 65,
          cvp: 7.8,
          checkRecord: "晨间生命体征正常,患者精神状态良好",
          remarks: "准备今日检查",
          attachments: []
        },
        {
          id: 5,
          recordTime: "2024-12-20 12:30:00",
          recorder: "刘护士",
          temperature: 37.1,
          heartRate: 85,
          bloodPressure: "121/79",
          respirationRate: 19,
          oxygenSaturation: 96,
          urineOutput: 40,
          cvp: 8.5,
          checkRecord: "午间体温略有波动,继续观察",
          remarks: "已通知医生",
          attachments: [
            {
              id: 4,
              fileName: "午间护理记录.jpg",
              fileUrl: "/records/nursing5.jpg",
              fileSize: 765000,
              uploadTime: "2024-12-20 13:00:00"
            }
          ]
        }
      ],
      recordList: [],
      recordLoading: false,
      recordTotal: 4,
      recordQueryParams: {
        pageNum: 1,
        pageSize: 10
      },
      recordDialogVisible: false,
      recordDialogTitle: "",
      recordSaveLoading: false,
@@ -827,8 +611,8 @@
        id: undefined,
        recordTime: "",
        recorder: "",
        checkRecord: "", // æ”¹ä¸ºå•字段记录
        attachments: [] // æ–°å¢žé™„件字段
        checkRecord: "",
        attachments: []
      },
      recordRules: {
        recordTime: [
@@ -845,87 +629,152 @@
      // é™„件预览相关
      attachmentPreviewVisible: false,
      currentAttachmentList: [],
      attachmentPreviewTitle: ""
      attachmentPreviewTitle: "",
      // è¯„估数据存储
      assessmentData: {
        liverKidney: {},
        bloodRoutine: {},
        urineRoutine: {},
        cultureResults: [],
        nursingRecords: []
      }
    };
  },
  created() {
    const id = this.$route.query.id;
    // this.isEdit = this.$route.query.edit === "true";
    if (id) {
      this.getDetail(id);
      this.getCultureList();
      this.getRecordList();
    this.loadMaintenanceData();
  },
  watch: {
    $route(to, from) {
      this.loadMaintenanceData();
    }
  },
  methods: {
    // èŽ·å–è¯¦æƒ…
    getDetail(id) {
      getMaintenanceDetail(id).then(response => {
        if (response.code === 200) {
          this.form = response.data;
        }
      });
    },
    // åŸ¹å…»è®°å½•附件变更
    handleCultureAttachmentChange(fileList) {
      this.cultureForm.attachments = fileList;
    },
    // æŠ¤ç†è®°å½•附件变更
    handleRecordAttachmentChange(fileList) {
      this.recordForm.attachments = fileList;
    },
    // æŸ¥çœ‹åŸ¹å…»è®°å½•附件
    handleViewCultureAttachments(row) {
      console.log(22, row.attachments);
      this.currentAttachmentList = row.attachments || [];
      this.attachmentPreviewTitle = `培养记录附件 - ${row.cultureType}`;
      this.attachmentPreviewVisible = true;
    },
    handleTabClick(tab) {
      this.$nextTick(() => {
        console.log(tab.name, 88);
        const tableRef=null;
        if (tab.name == "liverKidney") {
           tableRef = this.$refs.liverKidney; // è¯·æ›¿æ¢ä¸ºæ‚¨çš„表格 ref
        } else if (tab.name == "bloodRoutine") {
           tableRef = this.$refs.bloodRoutine; // è¯·æ›¿æ¢ä¸ºæ‚¨çš„表格 ref
        } else if (tab.name == "bloodRoutine") {
           tableRef = this.$refs.bloodRoutine; // è¯·æ›¿æ¢ä¸ºæ‚¨çš„表格 ref
        }
        // å¦‚果是 el-table,尝试调用其 doLayout æ–¹æ³•
        if (tableRef && tableRef.doLayout) {
          tableRef.doLayout();
        }
        // æˆ–者,更通用的强制重新渲染方式
        this.$forceUpdate(); // æ…Žç”¨ï¼Œå¯èƒ½å¼•发其他问题[1](@ref)
      });
    },
    // æŸ¥çœ‹æŠ¤ç†è®°å½•附件
    handleViewRecordAttachments(row) {
      this.currentAttachmentList = row.attachments || [];
      this.attachmentPreviewTitle = `护理核查记录附件 - ${row.recorder}`;
      this.attachmentPreviewVisible = true;
    },
    // åŸ¹å…»è®°å½•相关方法
    getCultureList() {
    // åŠ è½½ç»´æŠ¤æ•°æ®[1,3](@ref)
    async loadMaintenanceData() {
      try {
      this.cultureLoading = true;
      listCultureResults(this.form.id, this.cultureQueryParams)
        .then(response => {
          if (response.code === 200) {
            // this.cultureList = response.data.rows;
            // this.cultureTotal = response.data.total;
        this.recordLoading = true;
        const { id, infoid } = this.$route.query;
        const queryParams = {};
        if (id) {
          queryParams.id = id;
          this.currentMaintenanceId = id;
          this.isEditMode = true;
        } else if (infoid) {
          queryParams.infoid = infoid;
          this.currentMaintenanceId = null;
          this.isEditMode = false;
        } else {
          this.$message.error("缺少必要的路由参数");
          return;
          }
        const response = await maintainList(queryParams);
        if (response.code === 200) {
          let maintenanceData = response.data[0];
          // å¤„理数组响应
          if (Array.isArray(maintenanceData)) {
            maintenanceData = maintenanceData[0] || {};
          }
          // è§£æžitemDesc字段中的JSON数据[6,8](@ref)
          if (maintenanceData.itemDesc) {
            try {
              const itemDescData = JSON.parse(maintenanceData.itemDesc);
              this.assessmentData = { ...this.assessmentData, ...itemDescData };
              // å¡«å……各个模块的数据
              if (itemDescData.cultureResults) {
                this.cultureList = itemDescData.cultureResults;
              }
              if (itemDescData.nursingRecords) {
                this.recordList = itemDescData.nursingRecords;
              }
              if (itemDescData.liverKidney) {
                this.assessmentData.liverKidney = itemDescData.liverKidney;
              }
              if (itemDescData.bloodRoutine) {
                this.assessmentData.bloodRoutine = itemDescData.bloodRoutine;
              }
              if (itemDescData.urineRoutine) {
                this.assessmentData.urineRoutine = itemDescData.urineRoutine;
              }
            } catch (error) {
              console.error("解析itemDesc JSON失败:", error);
            }
          }
          // å¡«å……基础表单数据
          this.form = { ...this.form, ...maintenanceData };
          this.$message.success("数据加载成功");
        } else {
          this.$message.error("数据加载失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        console.error("加载维护数据失败:", error);
        this.$message.error("数据加载失败");
      } finally {
          this.cultureLoading = false;
        })
        .catch(() => {
          this.cultureLoading = false;
        });
        this.recordLoading = false;
      }
    },
    // ä¿å­˜æ‰€æœ‰æ•°æ®[1,2](@ref)
    async handleSave() {
      try {
        // æž„建保存数据
        const saveData = {
          ...this.form,
          itemDesc: JSON.stringify({
            liverKidney: this.assessmentData.liverKidney,
            bloodRoutine: this.assessmentData.bloodRoutine,
            urineRoutine: this.assessmentData.urineRoutine,
            cultureResults: this.cultureList,
            nursingRecords: this.recordList
          })
        };
        let response;
        if (this.isEditMode && this.currentMaintenanceId) {
          // ç¼–辑模式,调用maintainedit接口[1](@ref)
          saveData.id = this.currentMaintenanceId;
          response = await maintainedit(saveData);
        } else {
          // æ–°å¢žæ¨¡å¼ï¼Œè°ƒç”¨maintainAdd接口[2](@ref)
          response = await maintainAdd(saveData);
        }
        if (response.code === 200) {
          this.$message.success("保存成功");
          this.isEdit = false;
          // å¦‚果是新增保存,更新当前ID
          if (!this.isEditMode && response.data && response.data.id) {
            this.currentMaintenanceId = response.data.id;
            this.isEditMode = true;
          }
        } else {
          this.$message.error("保存失败:" + (response.msg || "未知错误"));
        }
      } catch (error) {
        console.error("保存数据失败:", error);
        this.$message.error("保存失败");
      }
    },
    // åˆ‡æ¢ç¼–辑模式
    toggleEditMode() {
      this.isEdit = !this.isEdit;
      if (!this.isEdit) {
        this.handleSave();
      }
    },
    // åŸ¹å…»è®°å½•相关方法
    handleAddCulture() {
      this.cultureDialogTitle = "新增培养记录";
      this.cultureForm = {
@@ -933,11 +782,7 @@
        cultureType: "",
        sampleTime: "",
        result: "阴性",
        bacteria: "",
        drugSensitivity: "",
        testingInstitution: "",
        specimenType: "",
        remarks: ""
        attachments: []
      };
      this.cultureDialogVisible = true;
      this.$nextTick(() => {
@@ -954,70 +799,28 @@
      });
    },
    handleViewCulture(row) {
      this.$alert(
        `
        <div>
          <p><strong>培养类型:</strong>${this.getCultureTypeLabel(
            row.cultureType
          )}</p>
          <p><strong>采样时间:</strong>${row.sampleTime}</p>
          <p><strong>培养结果:</strong>${row.result}</p>
          <p><strong>检测机构:</strong>${row.testingInstitution}</p>
        </div>
      `,
        "培养记录详情",
        {
          dangerouslyUseHTMLString: true,
          customClass: "detail-dialog"
        }
      );
    },
    toggleEditMode() {
      this.isEdit = !this.isEdit;
      // if (!this.isEdit) {
      //   this.saveAllData();
      // }
    },
    handleLiverKidneyDataChange(data) {
      console.log("肝功能肾功能数据变更:", data);
      // å¤„理数据保存或临时存储
    },
    handleBloodRoutineDataChange(data) {
      console.log("血常规功能数据变更:", data);
      // å¤„理数据保存或临时存储
    },
    handleUrineRoutineDataChange(data) {
      console.log("尿常规功能数据变更:", data);
      // å¤„理数据保存或临时存储
    },
    // ä¿å­˜åŸ¹å…»è®°å½•
    handleSaveCulture() {
      this.$refs.cultureForm.validate(valid => {
        if (valid) {
          this.cultureSaveLoading = true;
          const api = this.cultureForm.id
            ? updateCultureResult
            : addCultureResult;
          const requestData = {
            ...this.cultureForm,
            maintenanceId: this.form.id
          };
          api(requestData)
            .then(response => {
              if (response.code === 200) {
                this.$message.success(
                  this.cultureForm.id ? "修改成功" : "新增成功"
          if (this.cultureForm.id) {
            // ç¼–辑现有记录
            const index = this.cultureList.findIndex(
              item => item.id === this.cultureForm.id
                );
                this.cultureDialogVisible = false;
                this.getCultureList();
            if (index !== -1) {
              this.cultureList.splice(index, 1, { ...this.cultureForm });
              }
          } else {
            // æ–°å¢žè®°å½•
            this.cultureForm.id = Date.now();
            this.cultureList.push({ ...this.cultureForm });
          }
          this.$message.success(this.cultureForm.id ? "修改成功" : "新增成功");
          this.cultureDialogVisible = false;
              this.cultureSaveLoading = false;
            })
            .catch(() => {
              this.cultureSaveLoading = false;
            });
        }
      });
    },
@@ -1029,37 +832,15 @@
        type: "warning"
      })
        .then(() => {
          deleteCultureResult(row.id).then(response => {
            if (response.code === 200) {
          this.cultureList = this.cultureList.filter(
            item => item.id !== row.id
          );
              this.$message.success("删除成功");
              this.getCultureList();
            }
          });
        })
        .catch(() => {});
    },
    getCultureTypeLabel(value) {
      const type = this.cultureTypeOptions.find(item => item.value === value);
      return type ? type.label : "未知";
    },
    // æŠ¤ç†æ ¸æŸ¥è®°å½•相关方法
    getRecordList() {
      this.recordLoading = true;
      listNursingRecords(this.form.id, this.recordQueryParams)
        .then(response => {
          if (response.code === 200) {
            // this.recordList = response.data.rows;
            // this.recordTotal = response.data.total;
          }
          this.recordLoading = false;
        })
        .catch(() => {
          this.recordLoading = false;
        });
    },
    // æŠ¤ç†è®°å½•相关方法
    handleAddRecord() {
      this.recordDialogTitle = "新增护理核查记录";
      this.recordForm = {
@@ -1068,15 +849,9 @@
          .toISOString()
          .replace("T", " ")
          .substring(0, 19),
        recorder: "当前用户", // å®žé™…项目中从用户信息获取
        temperature: 36.5,
        heartRate: 80,
        bloodPressure: "120/80",
        respirationRate: 18,
        oxygenSaturation: 98,
        urineOutput: 50,
        cvp: 8,
        remarks: ""
        recorder: "当前用户",
        checkRecord: "",
        attachments: []
      };
      this.recordDialogVisible = true;
      this.$nextTick(() => {
@@ -1093,58 +868,28 @@
      });
    },
    handleViewRecord(row) {
      this.$alert(
        `
        <div>
          <p><strong>核查时间:</strong>${row.recordTime}</p>
          <p><strong>核查人:</strong>${row.recorder}</p>
          <p><strong>生命体征:</strong></p>
          <ul>
            <li>体温:${row.temperature}℃</li>
            <li>心率:${row.heartRate}次/分</li>
            <li>血压:${row.bloodPressure}mmHg</li>
            <li>呼吸:${row.respirationRate}次/分</li>
            <li>血氧饱和度:${row.oxygenSaturation}%</li>
            <li>尿量:${row.urineOutput}ml/h</li>
          </ul>
          <p><strong>备注:</strong>${row.remarks || "无"}</p>
        </div>
      `,
        "护理核查记录详情",
        {
          dangerouslyUseHTMLString: true,
          customClass: "detail-dialog"
        }
      );
    },
    handleSaveRecord() {
      this.$refs.recordForm.validate(valid => {
        if (valid) {
          this.recordSaveLoading = true;
          const api = this.recordForm.id
            ? updateNursingRecord
            : addNursingRecord;
          const requestData = {
            ...this.recordForm,
            maintenanceId: this.form.id
          };
          api(requestData)
            .then(response => {
              if (response.code === 200) {
                this.$message.success(
                  this.recordForm.id ? "修改成功" : "新增成功"
          if (this.recordForm.id) {
            // ç¼–辑现有记录
            const index = this.recordList.findIndex(
              item => item.id === this.recordForm.id
                );
                this.recordDialogVisible = false;
                this.getRecordList();
            if (index !== -1) {
              this.recordList.splice(index, 1, { ...this.recordForm });
              }
          } else {
            // æ–°å¢žè®°å½•
            this.recordForm.id = Date.now();
            this.recordList.push({ ...this.recordForm });
          }
          this.$message.success(this.recordForm.id ? "修改成功" : "新增成功");
          this.recordDialogVisible = false;
              this.recordSaveLoading = false;
            })
            .catch(() => {
              this.recordSaveLoading = false;
            });
        }
      });
    },
@@ -1156,26 +901,59 @@
        type: "warning"
      })
        .then(() => {
          deleteNursingRecord(row.id).then(response => {
            if (response.code === 200) {
          this.recordList = this.recordList.filter(item => item.id !== row.id);
              this.$message.success("删除成功");
              this.getRecordList();
            }
          });
        })
        .catch(() => {});
    },
    // ä¿å­˜åŸºæœ¬ä¿¡æ¯
    handleSave() {
      this.$refs.form.validate(valid => {
        if (valid) {
          updateMaintenance(this.form).then(response => {
            if (response.code === 200) {
              this.$message.success("保存成功");
              this.isEdit = false;
    // é™„件相关方法
    handleCultureAttachmentChange(fileList) {
      this.cultureForm.attachments = fileList;
    },
    handleRecordAttachmentChange(fileList) {
      this.recordForm.attachments = fileList;
    },
    handleViewCultureAttachments(row) {
      this.currentAttachmentList = row.attachments || [];
      this.attachmentPreviewTitle = `培养记录附件 - ${row.cultureType}`;
      this.attachmentPreviewVisible = true;
    },
    handleViewRecordAttachments(row) {
      this.currentAttachmentList = row.attachments || [];
      this.attachmentPreviewTitle = `护理核查记录附件 - ${row.recorder}`;
      this.attachmentPreviewVisible = true;
    },
    // è¯„估数据变更处理
    handleLiverKidneyDataChange(data) {
      this.assessmentData.liverKidney = data;
    },
    handleBloodRoutineDataChange(data) {
      this.assessmentData.bloodRoutine = data;
    },
    handleUrineRoutineDataChange(data) {
      this.assessmentData.urineRoutine = data;
    },
    handleTabClick(tab) {
      this.$nextTick(() => {
        let tableRef = null;
        if (tab.name === "liverKidney") {
          tableRef = this.$refs.liverKidney;
        } else if (tab.name === "bloodRoutine") {
          tableRef = this.$refs.bloodRoutine;
        } else if (tab.name === "urineRoutine") {
          tableRef = this.$refs.urineRoutine;
            }
          });
        if (tableRef && tableRef.doLayout) {
          tableRef.doLayout();
        }
      });
    }
@@ -1192,92 +970,25 @@
  margin-bottom: 20px;
}
.culture-card {
  margin-bottom: 20px;
}
.record-card {
  margin-bottom: 20px;
}
.detail-title {
  font-size: 16px;
  font-weight: bold;
}
.maintenance-detail {
  padding: 20px;
}
.detail-card {
  margin-bottom: 20px;
}
.culture-card {
  margin-bottom: 20px;
}
.record-card {
  margin-bottom: 20px;
}
.detail-title {
  font-size: 16px;
  font-weight: bold;
}
.medical-panel {
  padding: 20px;
}
.attachment-section {
  margin-top: 20px;
  padding: 15px;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}
.attachment-title {
  font-weight: bold;
  margin-bottom: 10px;
  color: #409eff;
}
.required-item::before {
  content: "*";
  color: #f56c6c;
  margin-right: 4px;
}
.assessment-card {
  margin-bottom: 20px;
}
.medical-table {
  width: 100%;
.record-card {
  margin-bottom: 20px;
}
.dynamic-column {
  min-width: 120px;
.detail-title {
  font-size: 16px;
  font-weight: bold;
  margin-right: 20px;
}
.culture-card {
  margin-bottom: 20px;
}
.fixed-width .el-button {
  margin: 0 2px;
}
/* è¯¦æƒ…对话框样式 */
:deep(.detail-dialog) {
  width: 500px;
}
:deep(.detail-dialog .el-message-box__content) {
  line-height: 1.8;
}
:deep(.detail-dialog ul) {
  margin: 10px 0;
  padding-left: 20px;
}
:deep(.detail-dialog li) {
  margin-bottom: 5px;
}
</style>
src/views/project/DonationProcess/index.vue
@@ -40,6 +40,41 @@
            <el-option label="已终止" value="99" />
          </el-select>
        </el-form-item>
        <!-- æ–°å¢žæœç´¢å­—段 -->
        <el-form-item label="上报时间" prop="reportTimeRange">
          <el-date-picker
            v-model="queryParams.reportTimeRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="yyyy-MM-dd"
            size="small"
            style="width: 240px;"
          />
        </el-form-item>
        <el-form-item label="首诊医院" prop="treatmenthospitalname">
          <el-input
            v-model="queryParams.treatmenthospitalname"
            placeholder="请输入首诊医院"
            clearable
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="住院号" prop="hospitalNo">
          <el-input
            v-model="queryParams.hospitalNo"
            placeholder="请输入住院号"
            clearable
            size="small"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item>
          <el-button
            type="primary"
@@ -147,15 +182,23 @@
      <el-table-column label="年龄" align="center" prop="age" width="80" />
      <el-table-column label="血型" align="center" prop="bloodtype" width="80">
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.sys_BloodType"
            :value="scope.row.bloodtype"
          />
        </template>
      </el-table-column>
      <el-table-column
        label="证件号码"
        label="传染病"
        align="center"
        prop="idcardno"
        prop="infectious"
        width="180"
      />
      <el-table-column
        label="治疗医院"
        label="首诊医院"
        align="center"
        prop="treatmenthospitalname"
        width="150"
@@ -169,75 +212,46 @@
      />
      <el-table-column
        label="案例编号"
        label="住院号"
        align="center"
        prop="caseNo"
        prop="hospitalNo"
        width="120"
      />
      <!-- ç¬¬ä¸€æ¬¡åŒ»å­¦è¯„ä¼° -->
      <el-table-column
        label="第一次评估结论"
        label="评估状态"
        align="center"
        prop="firstAssessState"
        prop="assessState"
        width="120"
      >
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.sys_BaseAssessConclusion"
            :value="scope.row.firstAssessState"
            :value="scope.row.assessState"
          />
        </template>
      </el-table-column>
      <el-table-column
        label="第一次评估时间"
        label="评估时间"
        align="center"
        prop="assessFirstTime"
        prop="assessTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.assessFirstTime, "{y}-{m}-{d}") }}</span>
        </template>
        <!-- <template slot-scope="scope">
          <span>{{ parseTime(scope.row.assessTime, "{y}-{m}-{d}") }}</span>
        </template> -->
      </el-table-column>
      <!-- ç¬¬äºŒæ¬¡åŒ»å­¦è¯„ä¼° -->
      <el-table-column
        label="第二次评估结论"
        align="center"
        prop="secondAssessState"
        width="120"
      >
        <template slot-scope="scope">
          <dict-tag
            :options="dict.type.sys_BaseAssessConclusion"
            :value="scope.row.secondAssessState"
          />
        </template>
      </el-table-column>
      <el-table-column
        label="第二次评估时间"
        align="center"
        prop="assessSecondTime"
        width="110"
      >
        <template slot-scope="scope">
          <span>{{
            parseTime(scope.row.assessSecondTime, "{y}-{m}-{d}")
          }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="亲属确认时间"
        align="center"
        prop="signDate"
        width="110"
      >
        <template slot-scope="scope">
        <!-- <template slot-scope="scope">
          <span>{{ parseTime(scope.row.signDate, "{y}-{m}-{d}") }}</span>
        </template>
        </template> -->
      </el-table-column>
      <el-table-column
@@ -317,7 +331,7 @@
      </el-table-column>
      <!-- æ“ä½œåˆ—:只保留终止和查看详情 -->
      <el-table-column label="操作" align="center" width="150" fixed="right">
      <el-table-column label="操作" align="center" width="200" fixed="right">
        <template slot-scope="scope">
          <el-button size="mini" type="text" @click="handleDetail(scope.row)"
            >查看详情</el-button
@@ -331,6 +345,14 @@
              scope.row.terminationCase === 0 && scope.row.recordstate !== '99'
            "
            >终止</el-button
          >
          <el-button
            size="mini"
            type="text"
            style="color: #67c23a;"
            @click="handleRestore(scope.row)"
            v-if="scope.row.terminationCase === 1"
            >恢复</el-button
          >
        </template>
      </el-table-column>
@@ -354,39 +376,29 @@
      <donor-detail :donorData="currentRecord" @close="detailVisible = false" />
    </el-dialog>
    <!-- ç»ˆæ­¢ç¡®è®¤å¼¹æ¡† -->
    <el-dialog
      title="终止确认"
      :visible.sync="terminateVisible"
      width="400px"
      append-to-body
    >
      <div style="margin-bottom: 20px;">
        <p>
          ç¡®å®šè¦ç»ˆæ­¢æçŒ®è€…
          <strong>{{ currentRecord.name }}</strong> çš„æçŒ®è¿›ç¨‹å—?
        </p>
        <p style="color: #f56c6c; font-size: 12px;">
          æ­¤æ“ä½œä¸å¯é€†ï¼Œè¯·è°¨æ…Žæ“ä½œï¼
        </p>
      </div>
      <div slot="footer">
        <el-button @click="terminateVisible = false">取消</el-button>
        <el-button type="danger" @click="submitTerminate">确认终止</el-button>
      </div>
    </el-dialog>
    <!-- ç»ˆæ­¢/恢复弹框组件 -->
    <terminate-restore-modal
      :current-record="currentRecord"
      :visible="modalVisible"
      :titles="modalTitles"
      @update:visible="handleModalVisibleChange"
      @operation-success="handleOperationSuccess"
    />
  </div>
</template>
<script>
import { courselist, terminateDonor } from "@/api/businessApi";
import TerminateRestoreModal from "@/components/TerminateRestoreModal";
export default {
  name: "Donatebaseinfo",
  dicts: ["sys_donornode", "sys_EthicalReview", "sys_BaseAssessConclusion"],
  components: {
    TerminateRestoreModal
  },
  dicts: ["sys_donornode",'sys_BloodType', "sys_EthicalReview", "sys_BaseAssessConclusion"],
  data() {
    return {
      // é®ç½©å±‚
      loading: false,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
@@ -396,8 +408,6 @@
      donatebaseinfoList: [],
      // è¯¦æƒ…弹框显示
      detailVisible: false,
      // ç»ˆæ­¢ç¡®è®¤å¼¹æ¡†æ˜¾ç¤º
      terminateVisible: false,
      // å½“前操作记录
      currentRecord: {},
      // ç»Ÿè®¡æ•°æ®
@@ -413,7 +423,21 @@
        pageSize: 10,
        name: undefined,
        idcardno: undefined,
        recordstate: undefined
        recordstate: undefined,
        // æ–°å¢žçš„æœç´¢å­—段
        reportTimeRange: [],
        treatmenthospitalname: undefined,
        hospitalNo: undefined
      },
      // å¼¹æ¡†æ˜¾ç¤ºçŠ¶æ€
      modalVisible: {
        terminate: false,
        restore: false
      },
      // å¼¹æ¡†æ ‡é¢˜
      modalTitles: {
        terminate: "终止捐献进程",
        restore: "恢复捐献进程"
      }
    };
  },
@@ -422,26 +446,24 @@
  },
  methods: {
    /** æŸ¥è¯¢æçŒ®åŸºç¡€åˆ—表 */
    /** æŸ¥è¯¢æçŒ®åŸºç¡€åˆ—表 */
    async getList() {
      this.loading = true;
      try {
        const response = await courselist(this.queryParams);
        // æ ¹æ®å®žé™…接口返回结构调整
        let realData = [];
        realData = response.data.donatebaseinfoProgressDTOS;
        this.total = response.total;
        this.stats.pendingCount = response.data.terminationCase[0];
        this.stats.approvedCount = response.data.terminationCase[1];
        this.stats.terminatedCount = response.data.terminationCase[2];
        this.stats.totalCount = response.total;
        // å­˜å‚¨æ‰€æœ‰æ•°æ®ç”¨äºŽå‰ç«¯ç­›é€‰å’Œåˆ†é¡µ
        this.allTableData = realData;
        this.stats.totalCount =
          response.total - response.data.terminationCase[2];
        // åº”用前端筛选条件(如果接口不支持后端筛选)
        this.allTableData = realData;
        let filteredData = this.applyFrontendFilter(realData);
        // å‰ç«¯åˆ†é¡µå¤„理(如果接口不支持后端分页)
        if (!response.total && !response.data) {
          const startIndex =
            (this.queryParams.pageNum - 1) * this.queryParams.pageSize;
@@ -449,18 +471,13 @@
          this.donatebaseinfoList = filteredData.slice(startIndex, endIndex);
          this.total = filteredData.length;
        } else {
          // æŽ¥å£å·²åˆ†é¡µï¼Œç›´æŽ¥ä½¿ç”¨è¿”回数据
          this.donatebaseinfoList = filteredData;
        }
        // æ›´æ–°ç»Ÿè®¡æ•°æ®
        // this.updateStats(realData);
      } catch (error) {
        console.error("获取数据失败:", error);
        this.$message.error("数据加载失败");
        this.donatebaseinfoList = [];
        this.total = 0;
        // this.updateStats([]);
      } finally {
        this.loading = false;
      }
@@ -489,21 +506,37 @@
        );
      }
      return filteredData;
    },
      if (this.queryParams.treatmenthospitalname) {
        filteredData = filteredData.filter(
          item =>
            item.treatmenthospitalname &&
            item.treatmenthospitalname.includes(
              this.queryParams.treatmenthospitalname
            )
        );
      }
    /** æ›´æ–°ç»Ÿè®¡æ•°æ® */
    updateStats(data) {
      this.stats.totalCount = data.length;
      this.stats.pendingCount = data.filter(
        item => item.recordstate === "0" || item.recordstate === 0
      ).length;
      this.stats.approvedCount = data.filter(
        item => item.recordstate === "1" || item.recordstate === 1
      ).length;
      this.stats.terminatedCount = data.filter(
        item => item.recordstate === "99" || item.recordstate === 99
      ).length;
      if (this.queryParams.hospitalNo) {
        filteredData = filteredData.filter(
          item =>
            item.hospitalNo &&
            item.hospitalNo.includes(this.queryParams.hospitalNo)
        );
      }
      if (
        this.queryParams.reportTimeRange &&
        this.queryParams.reportTimeRange.length === 2
      ) {
        const [startTime, endTime] = this.queryParams.reportTimeRange;
        filteredData = filteredData.filter(item => {
          if (!item.reporttime) return false;
          const reportDate = this.parseTime(item.reporttime, "{y}-{m}-{d}");
          return reportDate >= startTime && reportDate <= endTime;
        });
      }
      return filteredData;
    },
    /** èŽ·å–çŠ¶æ€æ ‡ç­¾æ ·å¼ */
@@ -529,8 +562,6 @@
    /** æ—¶é—´æ ¼å¼åŒ– */
    parseTime(time, format) {
      if (!time) return "-";
      // å¤„理时间戳和日期字符串
      const date = new Date(time);
      if (isNaN(date.getTime())) return time;
@@ -569,26 +600,24 @@
    /** ç»ˆæ­¢æ“ä½œ */
    handleTerminate(row) {
      this.currentRecord = { ...row };
      this.terminateVisible = true;
      this.modalVisible = { ...this.modalVisible, terminate: true };
    },
    /** æäº¤ç»ˆæ­¢ */
    async submitTerminate() {
      try {
        // è°ƒç”¨ç»ˆæ­¢æŽ¥å£
        await terminateDonor({
          id: this.currentRecord.id,
          caseNo: this.currentRecord.caseNo,
          terminationReason: "管理员手动终止"
        });
    /** æ¢å¤æ“ä½œ */
    handleRestore(row) {
      this.currentRecord = { ...row };
      this.modalVisible = { ...this.modalVisible, restore: true };
    },
        this.$message.success("终止成功");
        this.terminateVisible = false;
        this.getList(); // é‡æ–°åŠ è½½æ›´æ–°æ•°æ®
      } catch (error) {
        this.$message.error("终止失败");
        console.error("终止错误:", error);
      }
    /** å¤„理弹框显示状态变化 */
    handleModalVisibleChange(newVisible) {
      this.modalVisible = { ...newVisible };
    },
    /** å¤„理操作成功 */
    handleOperationSuccess({ type, record }) {
      console.log(`${type}操作成功:`, record);
      this.getList(); // é‡æ–°åŠ è½½æ•°æ®
    }
  }
};
src/views/project/donatebaseinfo/EditCaseModal.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,911 @@
<template>
  <el-dialog
    :title="title"
    :visible.sync="localVisible"
    width="1200px"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-width="130px"
      label-position="right"
    >
      <!-- åŸºç¡€ä¿¡æ¯éƒ¨åˆ† -->
      <el-card header="基础信息" class="form-section">
        <el-row :gutter="20">
          <el-col :span="11">
            <el-form-item label="案例编号" prop="caseNo">
              <el-input
                v-model="formData.caseNo"
                :disabled="isEdit"
                placeholder="系统自动生成"
              />
            </el-form-item>
          </el-col>
          <el-col :span="11">
            <el-form-item label="捐献者编号" prop="donorno">
              <el-input
                v-model="formData.donorno"
                placeholder="请输入捐献者编号"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="6">
            <el-form-item label="姓名" prop="name">
              <el-input v-model="formData.name" placeholder="必填项" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="性别" prop="sex">
              <el-select v-model="formData.sex" placeholder="请选择性别">
                <el-option label="未知" value="0" />
                <el-option label="男" value="1" />
                <el-option label="女" value="2" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="证件类型" prop="idcardtype">
              <el-select
                v-model="formData.idcardtype"
                placeholder="请选择证件类型"
              >
                <el-option label="身份证" value="1" />
                <el-option label="军人证" value="2" />
                <el-option label="护照" value="3" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="证件号码" prop="idcardno">
              <el-input
                v-model="formData.idcardno"
                placeholder="请输入证件号码"
                @blur="handleIdCardBlur"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="6">
            <el-form-item label="出生日期" prop="birthday">
              <el-date-picker
                v-model="formData.birthday"
                type="date"
                placeholder="选择出生日期"
                value-format="yyyy-MM-dd"
                style="width: 100%"
                @change="calculateAge"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="年龄" prop="andAge">
              <el-input v-model="formData.andAge" disabled />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="民族" prop="nation">
              <el-select v-model="formData.nation" placeholder="请选择民族">
                <el-option
                  v-for="dict in dictOptions.sys_nation"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="国籍" prop="nationality">
              <el-input
                v-model="formData.nationality"
                placeholder="请输入国籍"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="6">
            <el-form-item label="联系电话" prop="phone">
              <el-input v-model="formData.phone" placeholder="请输入联系电话" />
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="学历" prop="education">
              <el-select v-model="formData.education" placeholder="请选择学历">
                <el-option
                  v-for="dict in dictOptions.sys_education"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="职业" prop="occupation">
              <el-select v-model="formData.occupation" placeholder="请选择职业">
                <el-option
                  v-for="dict in dictOptions.sys_occupation"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="籍贯" prop="nativeplace">
              <el-input
                v-model="formData.nativeplace"
                placeholder="请输入籍贯"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>
      <!-- åŒ»ç–—信息部分 -->
      <el-card header="医疗信息" class="form-section">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="首诊医院" prop="treatmenthospitalno">
              <org-selecter
                :org-type="'3'"
                v-model="formData.treatmenthospitalno"
                @change="handleHospitalChange"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="科室" prop="treatmentdeptname">
              <el-input
                v-model="formData.treatmentdeptname"
                placeholder="请输入科室"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="住院号" prop="inpatientno">
              <el-input
                v-model="formData.inpatientno"
                placeholder="请输入住院号"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="疾病诊断" prop="diagnosisname">
              <el-input
                v-model="formData.diagnosisname"
                placeholder="请输入疾病诊断名称"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="血型" prop="bloodtype">
              <el-radio-group v-model="formData.bloodtype">
                <el-radio label="1">A型</el-radio>
                <el-radio label="2">B型</el-radio>
                <el-radio label="3">O型</el-radio>
                <el-radio label="4">AB型</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="Rh(D)" prop="rhyin">
              <el-radio-group v-model="form.rhyin">
                <el-radio
                  v-for="dict in dict.type.sys_bloodtype_rhd || []"
                  :key="dict.value"
                  :label="dict.value"
                  >{{ dict.label }}</el-radio
                >
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="当前医疗机构" prop="currentMedicalInstitution">
              <el-input
                v-model="formData.currentMedicalInstitution"
                placeholder="请输入当前医疗机构"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="当前医疗机构科室" prop="currentDept">
              <el-input
                v-model="formData.currentDept"
                placeholder="请输入当前医疗机构科室"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="首次医疗机构" prop="firstMedicalInstitution">
              <el-input
                v-model="formData.firstMedicalInstitution"
                placeholder="请输入首次医疗机构"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="首次医疗机构科室" prop="firstDept">
              <el-input
                v-model="formData.firstDept"
                placeholder="请输入首次医疗机构科室"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="GSC评分" prop="gcsScore">
              <el-input
                v-model="formData.gcsScore"
                placeholder="请输入GSC评分"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="协调员编号" prop="coordinatorNo">
              <el-input
                v-model="formData.coordinatorNo"
                placeholder="请输入协调员编号"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="协调员姓名" prop="coordinatorName">
              <el-input
                v-model="formData.coordinatorName"
                placeholder="请输入协调员姓名"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="病情概况" prop="illnessoverview">
              <el-input
                v-model="formData.illnessoverview"
                type="textarea"
                :rows="3"
                placeholder="请输入病情概况"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>
      <!-- åœ°å€ä¿¡æ¯éƒ¨åˆ† -->
      <el-card header="地址信息" class="form-section">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="现住地址" prop="residenceaddress">
              <li-area-select
                ref="residenceSelect"
                v-model="residenceAddress"
                @change="handleResidenceAddressChange"
              />
              <el-input
                v-model="formData.residenceaddress"
                placeholder="请输入详细地址"
                style="margin-top: 8px"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="户籍地址" prop="registeraddress">
              <li-area-select
                ref="registerSelect"
                v-model="registerAddress"
                @change="handleRegisterAddressChange"
              />
              <el-input
                v-model="formData.registeraddress"
                placeholder="请输入详细地址"
                style="margin-top: 8px"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>
      <!-- æçŒ®ä¿¡æ¯éƒ¨åˆ† -->
      <el-card header="捐献信息" class="form-section">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="捐献类别" prop="donationcategory">
              <el-select
                v-model="formData.donationcategory"
                placeholder="请选择捐献类别"
              >
                <el-option
                  v-for="dict in dictOptions.sys_DonationCategory"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="案例时间" prop="donatetime">
              <el-date-picker
                v-model="formData.donatetime"
                type="datetime"
                placeholder="选择案例时间"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="记录状态" prop="recordstate">
              <el-select v-model="formData.recordstate" :disabled="isEdit">
                <el-option label="新建" value="0" />
                <el-option label="已上报" value="1" />
                <el-option label="审核中" value="2" />
                <el-option label="已完成" value="3" />
                <el-option label="已终止" value="99" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="获取组织编号" prop="acquisitiontissueno">
              <el-input
                v-model="formData.acquisitiontissueno"
                placeholder="请输入获取组织编号"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="获取组织名称" prop="acquisitiontissuename">
              <el-input
                v-model="formData.acquisitiontissuename"
                placeholder="请输入获取组织名称"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>
      <!-- æŠ¥å‘Šä¿¡æ¯éƒ¨åˆ† -->
      <el-card header="报告信息" class="form-section">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item label="报告人编号" prop="reporterno">
              <el-select
                v-model="formData.reporterno"
                @change="handleReporterChange"
              >
                <el-option
                  v-for="reporter in reporters"
                  :key="reporter.reportNo"
                  :label="reporter.reportName"
                  :value="reporter.reportNo"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="报告人姓名" prop="reportername">
              <el-input
                v-model="formData.reportername"
                placeholder="报告人姓名"
                :disabled="true"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="报告人电话" prop="reporterphone">
              <el-input
                v-model="formData.reporterphone"
                placeholder="报告人联系电话"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="报告时间" prop="reporttime">
              <el-date-picker
                v-model="formData.reporttime"
                type="datetime"
                placeholder="选择报告时间"
                value-format="yyyy-MM-dd HH:mm:ss"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="部门ID" prop="deptid">
              <el-input v-model="formData.deptid" placeholder="请输入部门ID" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-card>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="handleSubmit" :loading="submitLoading">
        {{ isEdit ? "更新" : "保存" }}
      </el-button>
    </div>
  </el-dialog>
</template>
<script>
import {
  getDonatebaseinfo,
  updateDonatebaseinfo
} from "@/api/project/donatebaseinfo";
import OrgSelecter from "@/views/project/components/orgselect";
import LiAreaSelect from "@/components/Address";
export default {
  name: "EditCaseModal",
  components: {
    OrgSelecter,
    LiAreaSelect
  },
  dicts: ["sys_bloodtype_rhd", "sys_BloodType"],
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    editData: {
      type: Object,
      default: () => ({})
    },
    dictOptions: {
      type: Object,
      default: () => ({})
    },
    reporters: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      localVisible: this.visible,
      isEdit: false,
      submitLoading: false,
      residenceAddress: {},
      registerAddress: {},
      formData: this.getDefaultFormData(),
      rules: {
        name: [
          { required: true, message: "请输入捐献者姓名", trigger: "blur" }
        ],
        sex: [{ required: true, message: "请选择性别", trigger: "change" }],
        idcardtype: [
          { required: true, message: "请选择证件类型", trigger: "change" }
        ],
        idcardno: [
          { required: true, message: "请输入证件号码", trigger: "blur" }
        ],
        birthday: [
          { required: true, message: "请选择出生日期", trigger: "change" }
        ],
        treatmenthospitalno: [
          { required: true, message: "请选择首诊医院", trigger: "change" }
        ],
        diagnosisname: [
          { required: true, message: "请输入疾病诊断", trigger: "blur" }
        ],
        bloodtype: [
          { required: true, message: "请选择血型", trigger: "change" }
        ],
        donatetime: [
          { required: true, message: "请选择案例时间", trigger: "change" }
        ],
        reporttime: [
          { required: true, message: "请选择报告时间", trigger: "change" }
        ]
      }
    };
  },
  computed: {
    title() {
      return this.isEdit ? "编辑案例信息" : "新增捐献案例";
    }
  },
  watch: {
    visible(newVal) {
      this.localVisible = newVal;
      if (newVal) {
        this.initForm();
      }
    },
    localVisible(newVal) {
      this.$emit("update:visible", newVal);
    },
    editData: {
      handler(newVal) {
        if (newVal && newVal.id) {
          this.isEdit = true;
          this.$nextTick(() => {
            // ç¡®ä¿ DOM å·²ç»æ›´æ–°åŽå†è¿›è¡Œè¡¨å•操作
            this.initForm(newVal);
          });
        }
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    getDefaultFormData() {
      return {
        // åŸºç¡€ä¿¡æ¯
        caseNo: null,
        donorno: null,
        donateno: null,
        name: null,
        sex: null,
        idcardtype: null,
        idcardno: null,
        birthday: null,
        andAge: "",
        age: null,
        ageunit: "å¹´",
        age2: null,
        ageunit2: "月",
        nation: null,
        nationality: "中国",
        nativeplace: null,
        phone: null,
        education: null,
        occupation: null,
        // åŒ»ç–—信息
        treatmenthospitalno: null,
        treatmenthospitalname: null,
        treatmentdeptname: null,
        inpatientno: null,
        diagnosisname: null,
        bloodtype: "0",
        rhyin: "0",
        currentMedicalInstitution: null,
        currentDept: null,
        firstMedicalInstitution: null,
        firstDept: null,
        gcsScore: null,
        illnessoverview: null,
        coordinatorNo: null,
        coordinatorName: null,
        // åœ°å€ä¿¡æ¯
        residenceaddress: null,
        residenceprovince: null,
        residencecity: null,
        registeraddress: null,
        registerprovince: null,
        registercity: null,
        // æçŒ®ä¿¡æ¯
        donationcategory: null,
        donatetime: null,
        recordstate: "0",
        acquisitiontissueno: "ZJOPO",
        acquisitiontissuename: "浙江省人体器官获取组织",
        // æŠ¥å‘Šä¿¡æ¯
        reporterno: null,
        reportername: null,
        reporterphone: null,
        reporttime: null,
        deptid: null,
        // æ•°ç»„字段
        diseasetype: [],
        infectious: [],
        selfwill: [],
        othercases: [],
        infosources: [],
        kinship: [],
        patientstate: []
      };
    },
    async initForm() {
      console.log(this.isEdit);
      if (this.isEdit) {
        await this.loadEditData();
      } else {
        this.formData = this.getDefaultFormData();
        // è®¾ç½®é»˜è®¤å€¼
        this.formData.nationality = "中国";
        this.formData.bloodtype = "0";
        this.formData.rhyin = "0";
        this.formData.recordstate = "0";
        this.formData.acquisitiontissueno = "ZJOPO";
        this.formData.acquisitiontissuename = "浙江省人体器官获取组织";
      }
      this.$nextTick(() => {
        this.$refs.formRef?.clearValidate();
      });
    },
    async loadEditData() {
      try {
        const response = await getDonatebaseinfo(this.editData.id);
        const data = response.data;
        // å¤„理数组字段
        const arrayFields = [
          "diseasetype",
          "infectious",
          "selfwill",
          "othercases",
          "infosources",
          "kinship",
          "patientstate"
        ];
        arrayFields.forEach(field => {
          if (data[field]) {
            data[field] = data[field].split(",");
          } else {
            data[field] = [];
          }
        });
        this.formData = { ...this.getDefaultFormData(), ...data };
        // è®¾ç½®åœ°å€ä¿¡æ¯
        if (data.residenceprovince) {
          this.residenceAddress = {
            sheng: data.residenceprovincename,
            shi: data.residencecityname,
            qu: data.residencetownname
          };
        }
        if (data.registerprovince) {
          this.registerAddress = {
            sheng: data.registerprovincename,
            shi: data.registercityname,
            qu: data.registertownname
          };
        }
        this.calculateAge(data.birthday);
      } catch (error) {
        this.$message.error("获取案例数据失败");
        this.handleClose();
      }
    },
    handleIdCardBlur() {
      // èº«ä»½è¯è‡ªåŠ¨å¡«å……é€»è¾‘
      this.updateMessage();
    },
    updateMessage() {
      const idCardReg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
      if (idCardReg.test(this.formData.idcardno)) {
        const orgBirthday = this.formData.idcardno.substring(6, 14);
        const orgGender = this.formData.idcardno.substring(16, 17);
        const sex = orgGender % 2 == 1 ? "1" : "2";
        const birthday = `${orgBirthday.substring(
          0,
          4
        )}-${orgBirthday.substring(4, 6)}-${orgBirthday.substring(6, 8)}`;
        this.formData.sex = sex;
        this.formData.birthday = birthday;
        this.calculateAge(birthday);
      }
    },
    calculateAge(birthday) {
      if (!birthday) {
        this.formData.age = this.formData.age2 = null;
        this.formData.andAge = "";
        return;
      }
      const birthDate = new Date(birthday);
      const today = new Date();
      let yearDiff = today.getFullYear() - birthDate.getFullYear();
      let monthDiff = today.getMonth() - birthDate.getMonth();
      let dayDiff = today.getDate() - birthDate.getDate();
      if (dayDiff < 0) {
        monthDiff--;
        const lastDayOfMonth = new Date(
          today.getFullYear(),
          today.getMonth(),
          0
        ).getDate();
        dayDiff += lastDayOfMonth;
      }
      if (monthDiff < 0) {
        yearDiff--;
        monthDiff += 12;
      }
      this.formData.age = yearDiff;
      this.formData.ageunit = "岁";
      this.formData.age2 = monthDiff;
      this.formData.ageunit2 = "月";
      if (yearDiff === 0) {
        if (monthDiff === 0) {
          this.formData.age = dayDiff;
          this.formData.ageunit = "天";
          this.formData.age2 = null;
        } else {
          this.formData.age = monthDiff;
          this.formData.ageunit = "月";
          this.formData.age2 = dayDiff;
          this.formData.ageunit2 = "天";
        }
      }
      this.formData.andAge = [
        this.formData.age && this.formData.age !== 0
          ? `${this.formData.age}${this.formData.ageunit}`
          : "",
        this.formData.age2 && this.formData.age2 !== 0
          ? `${this.formData.age2}${this.formData.ageunit2}`
          : ""
      ]
        .filter(Boolean)
        .join(" ");
    },
    handleHospitalChange(hospitalInfo) {
      if (hospitalInfo && hospitalInfo.organizationname) {
        this.formData.treatmenthospitalname = hospitalInfo.organizationname;
      }
    },
    handleReporterChange(reporterNo) {
      const reporter = this.reporters.find(r => r.reportNo === reporterNo);
      if (reporter) {
        this.formData.reportername = reporter.reportName;
      }
    },
    handleResidenceAddressChange(address) {
      this.formData.residenceprovince = address.sheng;
      this.formData.residencecity = address.shi;
      this.formData.residencetown = address.qu;
    },
    handleRegisterAddressChange(address) {
      this.formData.registerprovince = address.sheng;
      this.formData.registercity = address.shi;
      this.formData.registertown = address.qu;
    },
    handleClose() {
      this.localVisible = false;
      this.isEdit = false;
      this.submitLoading = false;
      this.formData = this.getDefaultFormData();
      this.residenceAddress = {};
      this.registerAddress = {};
      this.$emit("closed");
    },
    async handleSubmit() {
      const valid = await this.$refs.formRef.validate().catch(() => false);
      if (!valid) return;
      this.submitLoading = true;
      try {
        const submitData = this.processSubmitData();
        const result = await updateDonatebaseinfo(submitData);
        if (result.code === 200) {
          this.$message.success(this.isEdit ? "更新成功" : "新增成功");
          this.$emit("success", result.data);
          this.handleClose();
        } else {
          this.$message.error(result.msg || "操作失败");
        }
      } catch (error) {
        this.$message.error("操作失败");
      } finally {
        this.submitLoading = false;
      }
    },
    processSubmitData() {
      const data = { ...this.formData };
      // å¤„理数组字段为字符串
      const arrayFields = [
        "diseasetype",
        "infectious",
        "selfwill",
        "othercases",
        "infosources",
        "kinship",
        "patientstate"
      ];
      arrayFields.forEach(field => {
        if (Array.isArray(data[field])) {
          data[field] = data[field].join(",");
        } else if (!data[field]) {
          data[field] = "";
        }
      });
      // å¤„理日期字段
      if (data.birthday) {
        data.birthday = this.$moment(data.birthday).format(
          "YYYY-MM-DD HH:mm:ss"
        );
      }
      if (data.reporttime) {
        data.reporttime = this.$moment(data.reporttime).format(
          "YYYY-MM-DD HH:mm:ss"
        );
      }
      if (data.donatetime) {
        data.donatetime = this.$moment(data.donatetime).format(
          "YYYY-MM-DD HH:mm:ss"
        );
      }
      // è®¾ç½®é»˜è®¤å€¼
      if (!data.recordstate) {
        data.recordstate = "0";
      }
      if (!data.workflow) {
        data.workflow = 0;
      }
      return data;
    }
  }
};
</script>
<style scoped>
.form-section {
  margin-bottom: 20px;
}
.form-section:last-child {
  margin-bottom: 0;
}
</style>
src/views/project/donatebaseinfo/index.vue
@@ -1,5 +1,6 @@
<template>
  <div class="app-container">
    <!-- æœç´¢è¡¨å• -->
    <el-form
      :model="queryParams"
      ref="queryForm"
@@ -9,7 +10,7 @@
    >
      <el-row :gutter="8">
        <el-col :span="5">
          <el-form-item label="姓名" prop="name">
          <el-form-item label="患者姓名" prop="name">
            <el-input
              v-model="queryParams.name"
              placeholder="请输入姓名"
@@ -20,34 +21,16 @@
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item
            align="left"
            label="医疗机构"
            prop="treatmenthospitalname"
          >
          <el-form-item label="首诊医院" prop="treatmenthospitalname">
            <org-selecter
              ref="orgSelecter"
              :org-type="'3'"
              v-model="queryParams.treatmenthospitalno"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="捐献地市">
            <el-select v-model="queryParams.city" placeholder="请选择地市">
              <el-option
                v-for="item in provinceData"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="9">
          <el-form-item label="案例时间">
          <el-form-item label="上报时间">
            <el-date-picker
              style="width: 100%"
              v-model="selecttime"
@@ -57,69 +40,7 @@
              end-placeholder="结束月份"
              value-format="yyyy-MM-dd"
              @change="getTimeList"
            >
            </el-date-picker>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="8">
        <el-col :span="5">
          <el-form-item label="捐献进度" prop="workflow">
            <el-select
              v-model="queryParams.workflow"
              placeholder="请选择当前进度"
              clearable
              size="small"
            >
              <el-option
                v-for="dict in dict.type.sys_donornode"
                :key="dict.value"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="报告人">
            <el-select
              v-model="queryParams.reporterno"
              placeholder="请选择报告人"
            >
              <el-option
                v-for="item in reportlist"
                :key="item.index"
                :label="item.reportername"
                :value="item.reporterno"
              >
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="是否终止">
            <el-select
              v-model="queryParams.terminationCase"
              placeholder="请选择状态"
            >
              <el-option
                v-for="item in terminationCaselist"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              >
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="9">
          <el-form-item label="籍贯">
            <div>
              <li_area_select
                ref="areaSelect"
                v-model="searchAddress"
              ></li_area_select>
            </div>
          </el-form-item>
        </el-col>
      </el-row>
@@ -131,39 +52,19 @@
              icon="el-icon-search"
              size="mini"
              @click="handleQuery"
              >搜索</el-button
            >
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
              >重置</el-button
            >
              æœç´¢
            </el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">
              é‡ç½®
            </el-button>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <!-- æ“ä½œæŒ‰é’® -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['project:donatebaseinfo:add']"
          >新增</el-button
        >
      </el-col>
      <!-- <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['project:donatebaseinfo:edit']"
          >修改</el-button
        >
      </el-col> -->
      <el-col :span="1.5">
        <el-button
@@ -174,15 +75,14 @@
          :loading="exportLoading"
          @click="handleExport"
          v-hasPermi="['project:donatebaseinfo:export']"
          >导出</el-button
        >
          å¯¼å‡º
        </el-button>
      </el-col>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
    </el-row>
    <!-- æ•°æ®è¡¨æ ¼ -->
    <el-table
      v-loading="loading"
      :data="donatebaseinfoList"
@@ -190,8 +90,6 @@
      border
      :default-sort="{ prop: 'donatetime', order: 'descending' }"
    >
      <!-- <el-table-column label="报告时间" align="center" prop="id" /> -->
      <!-- <el-table-column type="selection" width="55" align="center" /> -->
      <el-table-column
        label="案例时间"
        align="center"
@@ -221,7 +119,9 @@
        <template slot-scope="scope">
           {{
            `${
              scope.row.age && scope.row.age !== 0 ? `${scope.row.age}${scope.row.ageunit?scope.row.ageunit:''}` : ""
              scope.row.age && scope.row.age !== 0
                ? `${scope.row.age}${scope.row.ageunit || ""}`
                : ""
            } ${
              scope.row.age2 && scope.row.age2 !== 0
                ? `${scope.row.age2}${scope.row.ageunit2}`
@@ -231,15 +131,11 @@
        </template>
      </el-table-column>
      <el-table-column
        label="医疗机构"
        label="首诊医院"
        align="center"
        prop="treatmenthospitalname"
      />
      <el-table-column
        label="GSC评分"
        align="center"
        prop="gcsScore"
      />
      <el-table-column label="GSC评分" align="center" prop="gcsScore" />
      <el-table-column label="血型" align="center" prop="bloodtype" width="100">
        <template slot-scope="scope">
          <dict-tag
@@ -248,7 +144,6 @@
          />
        </template>
      </el-table-column>
      <el-table-column
        label="捐献类别"
        align="center"
@@ -268,27 +163,6 @@
        prop="reportername"
        width="100"
      />
      <!--
         <el-table-column
        label="现所在地市"
        align="center"
        prop="registercityname"
        width="150"
      />
      <el-table-column
        label="捐献进度"
        align="center"
        prop="recordstate"
        width="120"
      >
        <template slot-scope="scope">
         <dict-tag
            :options="dict.type.sys_DonationStatus"
            :value="scope.row.recordstate"
          />
        </template>
      </el-table-column>
      -->
      <el-table-column
        label="捐献进度"
        align="center"
@@ -302,11 +176,12 @@
              :value="scope.row.workflow"
            />
          </div>
          <div v-else>任务终止</div>
          <div v-else><el-button type="danger" plain>任务终止</el-button></div>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        width="190"
        align="center"
        class-name="small-padding fixed-width"
        fixed="right"
@@ -318,35 +193,42 @@
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
            >详情</el-button
          >
          <el-button
            v-if="scope.row.recordstate == 0"
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['project:donatebaseinfo:remove']"
            >删除</el-button
          >
          <!--
            <el-button v-if="scope.row.recordstate == 0 || scope.row.recordstate == 3" size="mini" type="text"
            icon="el-icon-thumb" @click="handleapproval(scope.row)">提交</el-button>
           -->
            è¯¦æƒ…
          </el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-refrigerator"
            @click="handledownload(scope.row)"
            >下载</el-button
            icon="el-icon-edit"
            @click="handleOpenEdit(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']"
            >编辑</el-button
          >
          <!--
            <el-button size="mini" type="text" icon="el-icon-edit" @click="handletermination(scope.row)"
            v-hasPermi="['project:donatebaseinfo:edit']">{{ scope.row.recordstate == 99 ? "恢复": "终止"  }}</el-button>
          -->
          <el-button
            size="mini"
            type="text"
            style="color: #f56c6c;"
            @click="handleTerminate(scope.row)"
            v-if="
              scope.row.terminationCase === 0 && scope.row.recordstate !== '99'
            "
          >
            ç»ˆæ­¢
          </el-button>
          <el-button
            size="mini"
            type="text"
            style="color: #67c23a;"
            @click="handleRestore(scope.row)"
            v-if="scope.row.terminationCase === 1"
          >
            æ¢å¤
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- åˆ†é¡µ -->
    <pagination
      v-show="total > 0"
      :total="total"
@@ -354,1051 +236,165 @@
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />
    <!-- æ·»åŠ æˆ–ä¿®æ”¹æçŒ®åŸºç¡€å¯¹è¯æ¡† -->
    <el-dialog
      :title="title"
      align="center"
      :visible.sync="open"
      :close-on-click-modal="false"
      width="1100px"
    >
      <el-form
        ref="form"
        :model="form"
        :rules="rules"
        label-width="130px"
        label-position="right"
      >
        <div
          style="
                border-bottom: 1px solid #ddd;
                border-top: 1px solid #ddd;
                padding-right: 60px;
              "
        >
          <el-row style="margin-top: 40px">
            <el-col :span="8">
              <el-form-item label="案例编号" prop="caseNo">
                <el-input v-model="form.caseNo" disabled />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item
                align="left"
                label="医疗机构"
                prop="treatmenthospitalno"
              >
                <org-selecter
                  ref="addOrgSelect"
                  :org-type="'3'"
                  v-model="form.treatmenthospitalno"
    <!-- æ¡ˆä¾‹ç¼–辑弹窗 -->
    <edit-case-modal
      :visible="editModalVisible"
      :editData="currentEditData"
      :dict-options="dict.type"
      @update:visible="editModalVisible = $event"
      @success="handleEditSuccess"
      @closed="handleEditClosed"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="科室" prop="treatmentdeptno">
                <el-input
                  v-model="form.treatmentdeptname"
                  placeholder="请输入科室"
    <!-- ç»ˆæ­¢/恢复弹框 -->
    <terminate-restore-modal
      :current-record="currentRecord"
      :visible="modalVisible"
      :titles="modalTitles"
      @update:visible="handleModalVisibleChange"
      @operation-success="handleOperationSuccess"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="6">
              <el-form-item align="left" label="姓名" prop="name">
                <el-input v-model="form.name" placeholder="必填项" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="民族" prop="nation">
                <el-select v-model="form.nation" placeholder="请选择民族">
                  <el-option
                    v-for="dict in dict.type.sys_nation"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="籍贯" prop="nativeplace">
                <el-input v-model="form.nativeplace" placeholder="请输入国籍" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="国籍" prop="nationality">
                <el-input v-model="form.nationality" placeholder="请输入国籍" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="6">
              <el-form-item label="证件类型" prop="idcardtype">
                <el-select
                  v-model="form.idcardtype"
                  placeholder="请选择证件类型"
                >
                  <el-option
                    v-for="dict in dict.type.sys_IDType"
                    :key="dict.value"
                    :label="dict.label"
                    :value="parseInt(dict.value)"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="证件号码" prop="idcardno">
                <el-input
                  style="width: 174px"
                  ref="updateBSvalue"
                  class="sfzcode"
                  v-model="form.idcardno"
                  placeholder="请输入证件号码"
                  @blur="updateMessage"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="性别" prop="sex">
                <el-select v-model="form.sex" placeholder="请输入性别">
                  <el-option
                    v-for="dict in dict.type.sys_user_sex"
                    :key="dict.label"
                    :label="dict.label"
                    :value="parseInt(dict.value)"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="学历" prop="education">
                <el-select v-model="form.education" placeholder="请选择学历">
                  <el-option
                    v-for="dict in dict.type.sys_education"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="6">
              <el-form-item label="出生日期" prop="birthday">
                <el-date-picker
                  clearable
                  size="small"
                  v-model="form.birthday"
                  type="date"
                  style="width: 174px"
                  @change="calculateAge"
                  value-format="yyyy-MM-dd"
                  placeholder="选择出生日期"
                >
                </el-date-picker>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <!-- <el-form-item label="年龄" prop="age">
                <el-input v-model="form.age" placeholder="请输入年龄" />
              </el-form-item> -->
              <el-form-item label="年龄" prop="age">
                <el-input v-model="form.andAge" disabled> </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="职业" prop="occupation">
                <el-select v-model="form.occupation" placeholder="请选择职业">
                  <el-option
                    v-for="dict in dict.type.sys_occupation"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
                    <el-row>
            <el-col :span="12">
              <el-form-item
                label="所在医疗机构"
                prop="currentMedicalInstitution"
              >
                <el-input
                  v-model="form.currentMedicalInstitution"
                  placeholder="请输入"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                label-width="150px"
                label="所在医疗机构科室"
                prop="currentDept"
              >
                <el-input v-model="form.currentDept" placeholder="请输入" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="首次医疗机构" prop="firstMedicalInstitution">
                <el-input
                  v-model="form.firstMedicalInstitution"
                  placeholder="请输入"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                label-width="150px"
                label="首次医疗机构科室"
                prop="firstDept"
              >
                <el-input v-model="form.firstDept" placeholder="请输入" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="住址" prop="residenceaddress">
                <div>
                  <li_area_select
                    ref="residenceSelect"
                    v-model="residenceAddresss"
                  ></li_area_select>
                  <!-- <div>{{defultAddress}}</div> -->
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="11" :push="1">
              <el-input
                v-model="form.residenceaddress"
                placeholder="请输入内容"
              />
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="现所在地" prop="registeraddress">
                <div>
                  <li_area_select
                    ref="registerSelect"
                    v-model="registerAddresss"
                  ></li_area_select>
                  <!-- <div>{{defultAddress}}</div> -->
                </div>
              </el-form-item>
            </el-col>
            <el-col :span="11" :push="1">
              <el-input
                v-model="form.registeraddress"
                placeholder="请输入内容"
              />
            </el-col>
          </el-row>
        </div>
        <div
          style="
                border-bottom: 1px solid #ddd;
                margin-top: 20px;
                padding-right: 60px;
              "
        >
          <el-row>
            <el-col :span="8">
              <el-form-item label="案例编号" prop="inpatientno">
                <el-input v-model="form.inpatientno" placeholder="案例编号" />
              </el-form-item>
            </el-col>
            <el-col :span="16">
              <el-form-item label="疾病诊断" prop="diagnosisname">
                <el-input
                  v-model="form.diagnosisname"
                  placeholder="请输入疾病诊断名称"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item align="left" label="血型" prop="bloodtype">
                <el-radio-group v-model="form.bloodtype">
                  <el-radio
                    v-for="dict in dict.type.sys_BloodType"
                    :key="dict.value"
                    :label="dict.value"
                    >{{ dict.label }}</el-radio
                  >
                </el-radio-group>
              </el-form-item>
            </el-col>
            <el-col :span="12" :pull="1">
              <el-form-item label="Rh(D)" align="left" prop="rhyin">
                <el-radio-group v-model="form.rhyin">
                  <el-radio
                    v-for="dict in dict.type.sys_bloodtype_rhd"
                    :key="dict.value"
                    :label="dict.value"
                    >{{ dict.label }}</el-radio
                  >
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-form-item label="疾病类型" align="left">
              <el-checkbox-group v-model="form.diseasetype">
                <el-checkbox
                  v-for="dict in dict.type.sys_DiseaseType"
                  :key="dict.value"
                  :label="dict.value"
                >
                  {{ dict.label }}
                </el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item label="其他" prop="diseasetypeOther">
              <el-input
                v-model="form.diseasetypeOther"
                placeholder="请输入其他"
              />
            </el-form-item>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item align="left" label="传染病">
                <el-checkbox-group v-model="form.infectious">
                  <el-checkbox
                    v-for="dict in dict.type.sys_Infectious"
                    :key="dict.value"
                    :label="dict.value"
                  >
                    {{ dict.label }}
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item align="left" label="其他" prop="infectiousOther">
                <el-input
                  v-model="form.infectiousOther"
                  placeholder="请输入其他"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="9">
              <el-form-item align="left" label="病人状况">
                <el-checkbox-group v-model="form.patientstate">
                  <el-checkbox
                    v-for="dict in dict.type.sys_patientstate"
                    :key="dict.value"
                    :label="dict.value"
                  >
                    {{ dict.label }}
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
            <el-col :span="15" align="left">
              <el-form-item label="其他情况">
                <el-checkbox-group v-model="form.othercases">
                  <el-checkbox
                    v-for="dict in dict.type.sys_OtherCases"
                    :key="dict.value"
                    :label="dict.value"
                  >
                    {{ dict.label }}
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <div
          style="
                border-bottom: 1px solid #ddd;
                padding-right: 60px;
                margin-top: 20px;
              "
        >
          <el-row>
            <div display="flex">
              <el-row>
                <el-col :span="12">
                  <el-form-item
                    label="亲属状况"
                    prop="kinship"
                    class="relation"
                    align="left"
                  >
                    <el-checkbox-group v-model="form.kinship">
                      <el-checkbox
                        v-for="dict in dict.type.sys_Kinship"
                        :key="dict.value"
                        :label="dict.value"
                      >
                        {{ dict.label }}
                      </el-checkbox>
                    </el-checkbox-group>
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="其他" prop="kinshipOther">
                    <el-input
                      v-model="form.kinshipOther"
                      placeholder="请输入其他"
                    />
                  </el-form-item>
                </el-col>
              </el-row>
            </div>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item align="left" label="本人意愿 ">
                <el-checkbox-group v-model="form.selfwill">
                  <el-checkbox
                    v-for="dict in dict.type.sys_SelfWill"
                    :key="dict.value"
                    :label="dict.value"
                  >
                    {{ dict.label }}
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="主要亲属" prop="majorrelatives">
                <el-input
                  v-model="form.majorrelatives"
                  placeholder="请输入主要亲属"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="与捐赠者关系" prop="familyrelations">
                <el-select
                  v-model="form.familyrelations"
                  placeholder="请选择与捐赠者关系"
                >
                  <el-option
                    v-for="dict in dict.type.sys_FamilyRelation"
                    :key="dict.value"
                    :label="dict.label"
                    :value="dict.value"
                  ></el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item align="left" label="信息来源">
                <el-checkbox-group v-model="form.infosources">
                  <el-checkbox
                    v-for="dict in dict.type.sys_InfoSources"
                    :key="dict.value"
                    :label="dict.value"
                  >
                    {{ dict.label }}
                  </el-checkbox>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="其他" prop="infosourcesOther">
                <el-input
                  v-model="form.infosourcesOther"
                  placeholder="请输入信息来源其他"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="信息员" prop="infoname">
                <el-input v-model="form.infoname" placeholder="请输入信息员" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="联系电话" prop="infophone">
                <el-input
                  v-model="form.infophone"
                  placeholder="请输入信息员联系电话"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item align="left" label="红十字会" prop="redorganno">
                <org-selecter
                  ref="addCrossOrgSelect"
                  :org-type="'2'"
                  v-model="form.redorganno"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="联系人" prop="contactperson">
                <el-input
                  v-model="form.contactperson"
                  placeholder="请输入联系人"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="联系时间" prop="contacttime">
                <el-date-picker
                  clearable
                  size="small"
                  style="width: 190px"
                  v-model="form.contacttime"
                  type="datetime"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  placeholder="选择报告时间"
                >
                </el-date-picker>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item
                align="left"
                label="获取组织"
                prop="acquisitiontissuename"
              >
                <org-selecter
                  style="width: 260px"
                  ref="orgSelecter"
                  :org-type="'1'"
                  v-model="form.acquisitiontissueno"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="报告人" prop="reporterno">
                <el-select
                  ref="getReportname"
                  v-model="form.reporterno"
                  placeholder="请选择"
                >
                  <el-option
                    v-for="item in reporters"
                    :key="item.reportNo"
                    :label="item.reportName"
                    :value="item.reportNo"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="联系电话" prop="reporterphone">
                <el-input
                  v-model="form.reporterphone"
                  placeholder="请输入联系电话"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="报告时间" align="left" prop="reporttime">
                <el-date-picker
                  clearable
                  size="small"
                  style="width: 190px"
                  v-model="form.reporttime"
                  type="datetime"
                  value-format="yyyy-MM-dd HH:mm:ss"
                  placeholder="选择报告时间"
                >
                </el-date-picker>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
        <!-- <div style="padding-right: 60px; margin-top: 20px">
          <el-row>
            <el-form-item label="附件" align="left" prop="annexfile">
              <annex-upload ref="annex" :infoid="form.id" :caseNo="form.caseNo" :flowname="flowname"
                :annexno="annexno" />
            </el-form-item>
          </el-row>
        </div> -->
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button v-show="showSaveBtn" type="primary" @click="submitForm"
          >保存并前往案例工作台</el-button
        >
        <el-button
          v-show="showTerminationBtn"
          type="primary"
          @click="submitForm"
          >终止案例</el-button
        >
        <el-button @click="cancel">取 æ¶ˆ</el-button>
        <!-- <el-button @click="handleapproval">提交审核</el-button> -->
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { getUserProfile } from "@/api/system/user";
import TerminateRestoreModal from "@/components/TerminateRestoreModal";
import EditCaseModal from "./EditCaseModal";
import {
  listDonatebaseinfo,
  getDonatebaseinfo,
  delDonatebaseinfo,
  addDonatebaseinfo,
  updateDonatebaseinfo,
  exportDonatebaseinfo,
  downloadbaseinfo,
  getDonationNumber,
  getdonatorno
  exportDonatebaseinfo
} from "@/api/project/donatebaseinfo";
import Li_area_select from "@/components/Address";
import OrgSelecter from "@/views/project/components/orgselect";
import AnnexUpload from "@/views/project/components/annexupload";
import ReportName from "@/views/project/components/organizationUser";
import { getToken } from "@/utils/auth";
import {
  listOrganization,
  getOrganization,
  listReportname,
  listUser
} from "@/api/project/organization";
import { listReportname, listUser } from "@/api/project/organization";
export default {
  name: "Donatebaseinfo",
  components: {
    Li_area_select,
    OrgSelecter,
    AnnexUpload,
    ReportName
    TerminateRestoreModal,
    EditCaseModal
  },
  name: "Donatebaseinfo",
  dicts: [
    "sys_Reporter",
    "sys_redcrossagency",
    "sys_nation",
    "sys_occupation",
    "sys_education",
    "sys_OrganizationType",
    "sys_HospitalNature",
    "sys_RegionalLevel",
    "country",
    "sys_user_sex",
    "sys_IDType",
    "sys_AgeUnit",
    "sys_BloodType",
    "sys_0_1",
    "sys_patientstate",
    "sys_DonationCategory",
    "sys_Kinship",
    "sys_Infectious",
    "sys_bloodtype_rhd",
    "sys_InfoSources",
    "sys_OtherCases",
    "sys_DonationStatus",
    "sys_DiseaseType",
    "sys_SelfWill",
    "sys_FamilyRelation",
    "sys_donornode"
  ],
  data() {
    return {
      tempRecordState: null,
      approvalState: false,
      countyname: "",
      cuuntry: "",
      organizationname: "",
      selecttime: "",
      //省市区
      //默认值设置,可为空
      searchAddress: {
        sheng: "",
        shi: "",
        qu: "",
        organizationname: null
      residenceAddresss: { sheng: "山东省", shi: "", qu: "" },
      registerAddresss: { sheng: "山东省", shi: "", qu: "" },
      modalTitles: {
        terminate: "终止捐献进程",
        restore: "恢复捐献进程"
      },
      residenceAddresss: {
        sheng: "浙江省",
        shi: "",
        qu: ""
      },
      registerAddresss: {
        sheng: "浙江省",
        shi: "",
        qu: ""
      },
      terminationCaselist: [
        { name: "终止状态", value: 1 },
        { name: "正常状态", value: 0 }
      ],
      // é®ç½©å±‚
      loading: true,
      // å¯¼å‡ºé®ç½©å±‚
      exportLoading: false,
      // é€‰ä¸­æ•°ç»„
      editModalVisible: false,
      currentEditData: {},
      ids: [],
      // éžå•个禁用
      single: true,
      // éžå¤šä¸ªç¦ç”¨
      multiple: true,
      // æ˜¾ç¤ºæœç´¢æ¡ä»¶
      showSearch: true,
      // æ€»æ¡æ•°
      total: 0,
      // æçŒ®åŸºç¡€è¡¨æ ¼æ•°æ®
      donatebaseinfoList: [],
      // å¼¹å‡ºå±‚标题
      title: "",
      // æ˜¯å¦æ˜¾ç¤ºå¼¹å‡ºå±‚
      open: false,
      // èŽ·å–ç»„ç»‡åç§°æ—¶é—´èŒƒå›´
      daterangeReporttime: [],
      //用户信息
      currentuser: {},
      // æŸ¥è¯¢å‚æ•°
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        caseNo: null,
        recordstate: null,
        // treatmenthospitalno: null,
        treatmenthospitalname: null,
        name: null,
        residenceprovince: null,
        residencecity: null,
        residencetown: null,
        treatmenthospitalno: null,
        starttime: null,
        endtime: null,
        city: null,
        reportno: null
        // organizationname: null,
        // organizationtype: null,
        // idcardno: null,
        // reporterno: null,
        // reporttime: null,
        endtime: null
      },
      // è¡¨å•参数
      form: {
        id: null,
        name: null,
        sex: null,
        idcardtype: null,
        idcardno: null,
        age: null, // å¹´é¾„(年)
        age: null,
        andAge: "",
        ageunit: "å¹´", // å•位,通常固定为“年”
        age2: null, // å¹´é¾„(月或天)
        ageunit2: "月", // å•位,根据计算决定是“月”还是“天”
        ageunit: null,
        ageunit: "å¹´",
        age2: null,
        ageunit2: "月",
        birthday: null,
        phone: null,
        residenceaddress: null,
        nationality: "中国",
        nativeplace: null,
        residenceprovince: null,
        nation: null,
        residenceprovincename: null,
        occupation: null,
        residencecity: null,
        education: null,
        residencecityname: null,
        residencetown: null,
        residencetownname: null,
        residencecommunity: null,
        residencecommunityname: null,
        residencecountycode: null,
        residencecountyname: null,
        registeraddress: null,
        registerprovince: null,
        registerprovincename: null,
        registercity: null,
        registercityname: null,
        registertown: null,
        registertownname: null,
        registercommunity: null,
        registercommunityname: null,
        registercountycode: null,
        registercountyname: null,
        recordstate: null,
        treatmenthospitalno: null,
        treatmenthospitalname: null,
        treatmentdeptname: null,
        diagnosisno: null,
        diagnosisname: null,
        bloodtype: "0",
        inpatientno: null,
        rhyin: "0",
        caseNo: null,
        donationcategory: null,
        illnessoverview: null,
        diseasetype: [],
        infectious: [],
        selfwill: [],
        diseasetypeOther: null,
        othercases: [],
        kinshipwill: 0,
        infosources: [],
        kinship: [],
        redorganno: null,
        redorganname: null,
        contactperson: null,
        infectiousOther: null,
        contactnumber: null,
        contacttime: null,
        reporterno: null,
        reportername: null,
        patientstate: [],
        reporterphone: null,
        infosourcesOther: null,
        reporttime: null,
        delFlag: null,
        createBy: null,
        createTime: null,
        updateBy: null,
        updateTime: null,
        kinshipOther: null,
        majorrelatives: null,
        familyrelations: null,
        acquisitiontissueno: "ZJOPO",
        acquisitiontissuename: "浙江省人体器官获取组织"
        acquisitiontissuename: "青岛人体器官获取组织"
      },
      //ads
      reporters: [],
      users: [],
      // è¡¨å•校验
     rules: {
        name: [
          { required: true, message: "请输入捐献者姓名", trigger: "blur" }
        ],
        nationality: [
          { required: true, message: "请输入国籍", trigger: "blur" }
        ],
        currentMedicalInstitution: [
          { required: true, message: "请输入所在医疗机构", trigger: "blur" }
        ],
        currentDept: [
          { required: true, message: "所在医疗机构科室", trigger: "blur" }
        ],
        firstMedicalInstitution: [
          { required: true, message: "请输入首次医疗机构", trigger: "blur" }
        ],
        firstDept: [
          { required: true, message: "请输入首次医疗机构科室", trigger: "blur" }
        ],
        birthday: [
          { required: true, message: "请选择出生日期", trigger: "blur" }
        ],
        idcardtype: [
          { required: true, message: "请选择证件类型", trigger: "blur" }
        ],
        residenceaddress: [
          { required: true, message: "请输入住址", trigger: "blur" }
        ],
        registerAddresss: [
          { required: true, message: "请输入现居住地址", trigger: "blur" }
        ],
        diseasetype: [
          { required: true, message: "请选择疾病类型", trigger: "blur" }
        ],
        infectious: [
          { required: true, message: "请选择传染病类型", trigger: "blur" }
        ],
        patientstate: [
          { required: true, message: "请选择病人状况", trigger: "blur" }
        ],
        kinship: [
          { required: true, message: "请选择亲属情况", trigger: "blur" }
        ],
        majorrelatives: [
          { required: true, message: "请输入主要亲属", trigger: "blur" }
        ],
        selfwill: [
          { required: true, message: "请选择本人意愿", trigger: "blur" }
        ],
        registerAddresss: [
          { required: true, message: "请输入现所在地", trigger: "blur" }
        ],
        familyrelations: [
          { required: true, message: "请选择亲属与捐献者关系", trigger: "blur" }
        ],
        infosources: [
          { required: true, message: "请选择信息来源", trigger: "blur" }
        ],
        idcardno: [
          { required: true, message: "请正确输入证件号码", trigger: "blur" }
        ],
        sex: [{ required: true, message: "性别不能为空", trigger: "blur" }],
        age: [{ required: true, message: "请输入年龄", trigger: "blur" }],
        treatmenthospitalno: [
          { required: true, message: "请选择医疗机构", trigger: "blur" }
          { required: true, message: "请选择首诊医院", trigger: "blur" }
        ],
        bloodtype: [
          { required: true, message: "请选择ABO血型", trigger: "blur" }
        ],
        rhyin: [{ required: true, message: "请选择RHD血型", trigger: "blur" }],
        diseasetype: [
          { required: true, message: "请选择RHD血型", trigger: "blur" }
        ],
        inpatientno: [
          { required: true, message: "输入案例编号", trigger: "blur" }
        ],
        diagnosisname: [
          { required: true, message: "疾病诊断不能为空", trigger: "blur" }
        ],
        infoname: [
          { required: true, message: "请输入信息员姓名", trigger: "blur" }
        ],
        infophone: [
          { required: true, message: "请输入信息员联系电话", trigger: "blur" }
        ],
        acquisitiontissueno: [
          { required: true, message: "器官获取组织不能为空", trigger: "blur" }
        ],
        reporterno: [
          { required: true, message: "请选择报告人", trigger: "blur" }
        ],
        reporttime: [
          { required: true, message: "请输入报告时间", trigger: "blur" }
        ],
        reporterphone: [
          { required: true, message: "请输入报告人联系电话", trigger: "blur" }
        ]
      },
      //是否显示保存按钮
      showSaveBtn: true,
      showTerminationBtn: false,
      //流程名称
      flowname: "潜在捐献登记",
      annexno: "PotentialDonationRegistration",
      starttime: "",
      endtime: "",
      reportlist: [],
      reportervalue: "",
      headers: {
        Authorization: "Bearer " + getToken()
      },
      provinceData: [
        { label: "全部", value: "" },
        { label: "杭州市", value: "1" },
        { label: "宁波市", value: "2" },
        { label: "温州市", value: "3" },
        { label: "嘉兴市", value: "4" },
        { label: "湖州市", value: "5" },
        { label: "绍兴市", value: "6" },
        { label: "金华市", value: "7" },
        { label: "衢州市", value: "8" },
        { label: "舟山市", value: "9" },
        { label: "台州市", value: "A" },
        { label: "丽水市", value: "B" }
      ]
      currentRecord: {},
      modalVisible: {}
    };
  },
  created() {
    if (sessionStorage.getItem("donatebaseinfo")) {
      this.queryParams = JSON.parse(sessionStorage.getItem("donatebaseinfo"));
      console.log(this.queryParams, "queryParams");
    const savedParams = sessionStorage.getItem("donatebaseinfo");
    if (savedParams) {
      this.queryParams = { ...this.queryParams, ...JSON.parse(savedParams) };
    }
  },
  async mounted() {
    await Promise.all([
      this.getCurrentUser(),
      this.getuserlist(),
      this.selectReporters()
    ]);
  mounted(e) {
    // let idd = this.$route.query.userid
    // console.log('chuanzhi',idd);
    this.getCurrentUser();
    this.getuserlist();
    this.selectReporters();
    this.LoadReportList();
    if (this.$route.params.starttime != null && this.$route.params.endtime) {
      this.selecttime = [
        this.$moment(this.$route.params.starttime).format("YYYY-MM-DD"),
        this.$moment(this.$route.params.endtime).format("YYYY-MM-DD")
      ];
    }
    if (this.$route.params.reporterno != "") {
      this.reporterno = this.$route.params.reporterno;
    }
    this.queryParams.terminationcase = this.$route.params.terminationcase;
    if (
      this.$route.params.tempRecordState != "" &&
      this.$route.params.tempRecordState != undefined
    ) {
      this.queryParams.recordstate = "" + this.$route.params.tempRecordState;
    }
    if (this.$route.params.reporterno != "") {
      this.reportervalue = this.$route.params.reporterno;
    }
    if (!this.$route.params.shen != "") {
      this.searchAddress.sheng = this.$route.params.shen;
      if (!this.$route.params.shi != "") {
        this.searchAddress.shi = this.$route.params.shi;
      }
      if (!this.$route.params.qu) {
        this.searchAddress.qu = this.$route.params.qu;
      }
    }
    if (this.$route.params.city != "") {
      this.queryParams.city = this.$route.params.city;
    } else {
      this.queryParams.city = "";
    }
    this.initializeRouteParams();
    this.getTimeList();
    this.getList();
  },
  methods: {
    getCurrentUser() {
      getUserProfile().then(response => {
    async getCurrentUser() {
      const response = await getUserProfile();
        this.currentuser = response.data;
      });
    },
    calculateAge(birthday) {
      if (!birthday) {
        // æ¸…空年龄字段
        this.form.age = null;
        this.form.age2 = null;
        // this.form.age3 = null;
        this.form.age = this.form.age2 = null;
        return;
      }
      const birthDate = new Date(birthday);
      const today = new Date();
      // è®¡ç®—总月份差异
      let yearDiff = today.getFullYear() - birthDate.getFullYear();
      let monthDiff = today.getMonth() - birthDate.getMonth();
      let dayDiff = today.getDate() - birthDate.getDate();
      // å¦‚果当前日期的天数小于出生日期的天数,则借月
      if (dayDiff < 0) {
        monthDiff--;
        // èŽ·å–ä¸Šä¸ªæœˆçš„æœ€åŽä¸€å¤©
        const lastDayOfMonth = new Date(
          today.getFullYear(),
          today.getMonth(),
@@ -1407,683 +403,291 @@
        dayDiff += lastDayOfMonth;
      }
      // å¦‚果月份差为负,则借年
      if (monthDiff < 0) {
        yearDiff--;
        monthDiff += 12;
      }
      // èµ‹å€¼å¹´éƒ¨åˆ†
      this.form.age = yearDiff;
      this.form.ageunit = "岁";
      // èµ‹å€¼æœˆéƒ¨åˆ†ï¼ˆæˆ–者您也可以选择显示剩余的天数)
      this.form.age2 = monthDiff;
      this.form.ageunit2 = "月";
      // å¦‚果您还想显示天数
      // this.form.age3 = dayDiff;
      // this.form.ageunit3 = '天';
      // å¦‚果年龄小于1岁,可能您希望用月或天来表示主年龄
      // è¿™é‡Œæ˜¯ä¸€ä¸ªç®€å•的逻辑,您可以根据需求调整
      if (yearDiff === 0) {
        if (monthDiff === 0) {
          // å°äºŽ1个月,用天表示
          this.form.age = dayDiff;
          this.form.ageunit = "天";
          this.form.age2 = null; // æ¸…空第二字段
          // this.form.age3 = null;
          this.form.age2 = null;
        } else {
          // å°äºŽ1年,用月表示
          this.form.age = monthDiff;
          this.form.ageunit = "月";
          this.form.age2 = dayDiff; // ç¬¬äºŒå­—段显示天
          this.form.age2 = dayDiff;
          this.form.ageunit2 = "天";
        }
      }
      this.form.andAge = `${
      this.form.andAge = [
        this.form.age && this.form.age !== 0
          ? `${this.form.age}${this.form.ageunit}`
          : ""
      } ${
          : "",
        this.form.age2 && this.form.age2 !== 0
          ? `${this.form.age2}${this.form.ageunit2}`
          : ""
      }`.trim();
      this.$forceUpdate(); // å¼ºåˆ¶æ›´æ–°
      console.log(this.form.andAge);
    },
    LoadReportList() {
      listDonatebaseinfo().then(res => {
        let list = res.rows;
        let reportlist = [];
        reportlist.push({ reporterno: "", reportername: "全部" });
        list.forEach(element => {
          reportlist.push({
            reporterno: element.reporterno,
            reportername: element.reportername
          });
        });
        if (reportlist != 0) {
          reportlist = this.resetArr(reportlist);
          this.reportlist = reportlist;
        }
      });
      ]
        .filter(Boolean)
        .join(" ");
    },
    resetArr(Arr) {
      var hash = {};
      Arr = Arr.reduce(function(arr, current) {
        hash[current.reporterno]
          ? ""
          : (hash[current.reporterno] = true && arr.push(current));
        return arr;
      }, []);
      return Arr;
    handleTerminate(row) {
      this.currentRecord = { ...row };
      this.modalVisible = { ...this.modalVisible, terminate: true };
    },
    getTimeList(e) {
      console.log(this.selecttime);
      if (this.selecttime != null) {
        if (this.selecttime != 0) {
          this.endtime = this.selecttime[1];
          this.starttime = this.selecttime[0];
          // if (this.endtime == this.starttime) {
          let num = Number(this.endtime.slice(5, 7));
          if (num < 9) {
            let mon = Number(this.endtime.slice(6, 7));
            this.endtime =
              this.endtime.slice(0, 5) +
              "0" +
              (mon + 1) +
              "-" +
              "01" +
              " " +
              "00" +
              ":" +
              "00" +
              ":" +
              "00";
          }
          // this.endtime=this.endtime.slice(0,5)å¹´
          else if (num >= 10) {
            this.endtime =
              this.endtime.slice(0, 5) +
              (num + 1) +
              "-" +
              "01" +
              " " +
              "00" +
              ":" +
              "00" +
              ":" +
              "00";
          } else {
            this.endtime =
              this.endtime.slice(0, 5) +
              "10" +
              "-" +
              "01" +
              " " +
              "00" +
              ":" +
              "00" +
              ":" +
              "00";
          }
          this.starttime =
            this.starttime + " " + "00" + ":" + "00" + ":" + "00";
          // }
        } else {
          this.starttime = "1998-01-01 00:00:00";
          this.endtime = "2998-01-01 00:00:00";
        }
      } else {
        this.starttime = "1998-01-01 00:00:00";
        this.endtime = "2998-01-01 00:00:00";
      }
    handleRestore(row) {
      this.currentRecord = { ...row };
      this.modalVisible = { ...this.modalVisible, restore: true };
    },
    selectReporters() {
      //专职人员
      listReportname("zzry").then(res => {
    getTimeList() {
      if (!this.selecttime) {
        // this.queryParams.starttime = "1998-01-01 00:00:00";
        // this.queryParams.endtime = "2998-01-01 00:00:00";
        return;
      }
      const [start, end] = this.selecttime;
      this.queryParams.starttime = `${start} 00:00:00`;
      const monthNum = Number(end.slice(5, 7));
      const nextMonth = monthNum < 9 ? `0${monthNum + 1}` : monthNum + 1;
      this.queryParams.endtime = `${end.slice(0, 5)}${nextMonth}-01 00:00:00`;
    },
    async selectReporters() {
      const res = await listReportname("zzry");
        this.reporters = res.data;
      });
    },
    getuserlist() {
      //用户列表
      listUser().then(res => {
    async getuserlist() {
      const res = await listUser();
        this.users = res.data;
      });
    },
    handleapproval(row) {
      this.$confirm("是否确认将案例上报审核?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          row.recordstate = 1;
          updateDonatebaseinfo(row).then(response => {
            this.$modal.msgSuccess("上报审核成功");
            this.getList();
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消上报"
          });
        });
    },
    resetapproval(row) {
      this.approvalState = false;
      //  this.reset();
      // const id = row.id || this.ids;
      updateDonatebaseinfo(row).then(response => {
        row.recordstate = 0;
      });
    },
    updateMessage() {
      try {
        const reg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
        if (reg.test(this.form.idcardno)) {
          // èº«ä»½è¯å·ç æ˜¯å¦åˆæ³•
          var org_birthday = this.form.idcardno.substring(6, 14);
          var org_gender = this.form.idcardno.substring(16, 17);
          var sex = org_gender % 2 == 1 ? 1 : 2;
          var birthday =
            org_birthday.substring(0, 4) +
            "-" +
            org_birthday.substring(4, 6) +
            "-" +
            org_birthday.substring(6, 8);
          var birthdays = new Date(birthday.replace(/-/g, "/"));
          let d = new Date();
          let age =
            d.getFullYear() -
            birthdays.getFullYear() -
            (d.getMonth() < birthdays.getMonth() ||
            (d.getMonth() == birthdays.getMonth() &&
              d.getDate() < birthdays.getDate())
              ? 1
              : 0);
          // èµ‹å€¼ç»™è¡¨æ ¼
      const idCardReg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
      if (idCardReg.test(this.form.idcardno)) {
        const orgBirthday = this.form.idcardno.substring(6, 14);
        const orgGender = this.form.idcardno.substring(16, 17);
        const sex = orgGender % 2 == 1 ? 1 : 2;
        const birthday = `${orgBirthday.substring(
          0,
          4
        )}-${orgBirthday.substring(4, 6)}-${orgBirthday.substring(6, 8)}`;
          this.form.sex = sex;
          this.form.birthday = birthday;
          this.calculateAge(birthday);
          // this.form.age = age;
        } else {
        }
      } catch {}
    },
    // sheng: '浙江省',
    //   shi: '',
    //   qu: '',
    // èº«ä»½è¯éªŒè¯
    //根据身份证号自动生成性别、出生日期和年龄
    inputChange() {
      const idCard = this.props.form.getFieldValue("idCard");
      let birthday = "";
      let sex = "0";
      if (idCard.length === 15) {
        birthday = `19${idCard.substring(6, 8)}-${idCard.substring(
          9,
          10
        )}-${idCard.substring(11, 12)}`;
        sex = idCard[14] % 2 === 0 ? "0" : "1";
      } else {
        birthday = `${idCard.substring(6, 10)}-${idCard.substring(
          11,
          12
        )}-${idCard.substring(13, 14)}`;
        sex = idCard[16] % 2 === 0 ? "0" : "1";
      }
      this.setState({
        birthday,
        sex
    initializeRouteParams() {
      const { params } = this.$route;
      const routeParams = {
        starttime: params.starttime,
        endtime: params.endtime,
        reporterno: params.reporterno,
        terminationcase: params.terminationcase,
        tempRecordState: params.tempRecordState,
        city: params.city
      };
      Object.entries(routeParams).forEach(([key, value]) => {
        if (value) this.queryParams[key] = value;
      });
      if (params.starttime && params.endtime) {
        this.selecttime = [
          this.$moment(params.starttime).format("YYYY-MM-DD"),
          this.$moment(params.endtime).format("YYYY-MM-DD")
        ];
      }
    },
    /** æŸ¥è¯¢æçŒ®åŸºç¡€åˆ—表 */
    getList() {
    async getList() {
      this.loading = true;
      this.queryParams.params = {};
      sessionStorage.removeItem("donatebaseinfo");
      sessionStorage.setItem(
        "donatebaseinfo",
        JSON.stringify(this.queryParams)
      );
      // è·³è½¬æ—¶çš„默认进度
      if (this.reportervalue != "") {
        this.queryParams.reportno = this.reportervalue;
      }
      if (this.starttime != "") {
        this.queryParams.starttime = this.starttime;
      } else {
        this.queryParams.starttime = "";
      }
      if (this.endtime != "") {
        this.queryParams.endtime = this.endtime;
      } else {
        this.queryParams.endtime = "";
      }
      this.queryParams.residenceprovince = this.$refs.areaSelect.getSheng();
      this.queryParams.residencecity = this.$refs.areaSelect.getShi();
      this.queryParams.residencetown = this.$refs.areaSelect.getQu();
      console.log(this.queryParams);
      listDonatebaseinfo(this.queryParams).then(response => {
        this.donatebaseinfoList = response.rows;
        //console.log("listDonatebaseinfo", response.rows);
      try {
        const response = await listDonatebaseinfo(this.queryParams);
        this.donatebaseinfoList = response.data;
        this.total = response.total;
      } catch (error) {
        console.error("获取列表失败:", error);
      } finally {
        this.loading = false;
      });
      }
    },
    // å–消按钮
    /** æ‰“开编辑弹窗 */
    handleOpenEdit(row) {
      this.currentEditData = { ...row };
      console.log(this.currentEditData, "this.currentEditData");
      this.editModalVisible = true;
    },
    /** å¤„理编辑成功 */
    handleEditSuccess(updatedData) {
      this.$modal.msgSuccess("编辑成功");
      this.getList(); // åˆ·æ–°åˆ—表
    },
    /** å¤„理编辑弹窗关闭 */
    handleEditClosed() {
      this.currentEditData = {};
    },
    handleModalVisibleChange(newVisible) {
      this.modalVisible = { ...newVisible };
    },
    handleOperationSuccess({ type, record }) {
      console.log(`${type}操作成功:`, record);
      this.getList();
    },
    cancel() {
      this.open = false;
      this.reset();
    },
    // è¡¨å•重置
    reset() {
      this.form = {
        id: null,
        name: null,
        sex: null,
        idcardtype: null,
        idcardno: null,
        age: null,
        ageunit: null,
        birthday: null,
        phone: null,
        residenceaddress: null,
        nationality: "中国",
        nativeplace: null,
        residenceprovince: null,
        nation: null,
        residenceprovincename: null,
        occupation: null,
        residencecity: null,
        education: null,
        residencecityname: null,
        residencetown: null,
        residencetownname: null,
        residencecommunity: null,
        residencecommunityname: null,
        residencecountycode: null,
        residencecountyname: null,
        registeraddress: null,
        registerprovince: null,
        registerprovincename: null,
        registercity: null,
        registercityname: null,
        registertown: null,
        registertownname: null,
        registercommunity: null,
        registercommunityname: null,
        registercountycode: null,
        registercountyname: null,
        recordstate: null,
        treatmenthospitalno: null,
        treatmenthospitalname: null,
        treatmentdeptname: null,
        diagnosisno: null,
        diagnosisname: null,
        bloodtype: "0",
        inpatientno: null,
        rhyin: 0,
        caseNo: null,
        donationcategory: null,
        illnessoverview: null,
        diseasetype: [],
        infectious: [],
        selfwill: [],
        diseasetypeOther: null,
        othercases: [],
        kinshipwill: 0,
        infosources: [],
        kinship: [],
        redorganno: null,
        redorganname: null,
        contactperson: null,
        infectiousOther: null,
        contactnumber: null,
        contacttime: null,
        reporterno: null,
        reportername: null,
        patientstate: [],
        reporterphone: null,
        infosourcesOther: null,
        reporttime: null,
        delFlag: null,
        createBy: null,
        createTime: null,
        updateBy: null,
        updateTime: null,
        kinshipOther: null,
        majorrelatives: null,
        familyrelations: null,
        acquisitiontissueno: "ZJOPO",
        acquisitiontissuename: "浙江省人体器官获取组织"
        sex: null
        // ... ä¿ç•™å¿…要的字段初始值
      };
      this.resetForm("form");
    },
    /** æœç´¢æŒ‰é’®æ“ä½œ */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** é‡ç½®æŒ‰é’®æ“ä½œ */
    resetQuery() {
      this.daterangeReporttime = [];
      this.reportervalue = "";
      this.queryParams = {
        doname: null,
        pageNum: 1,
        pageSize: 10,
        name: null,
        idcardno: null,
        residenceprovince: null,
        residencecity: null,
        residencetown: null,
        // "2"
        recordstate: null,
        treatmenthospitalname: null,
        caseNo: null,
        acquisitiontissueno: null,
        reportername: null,
        reporttime: null,
        city: null,
        treatmenthospitalno: null
        treatmenthospitalno: null,
        starttime: null,
        endtime: null
      };
      this.selecttime = [];
      this.getTimeList();
      this.searchAddress = {
        sheng: "",
        shi: "",
        qu: "",
        organizationname: null
      };
      //this.$refs.areaSelect.clean();
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // å¤šé€‰æ¡†é€‰ä¸­æ•°æ®
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
    /** æ–°å¢žæŒ‰é’®æ“ä½œ */
    handleAdd() {
      // this.$router.push({
      //   path: "/organ/donationdetails/",
      //   query: {
      //     organType: "add",
      //   }
      // });
      this.reset();
      //设置报告人和部门/组
      this.form.reporterno = this.currentuser.userName;
      this.form.reportername = this.currentuser.nickName;
      this.form.deptid = this.currentuser.deptid;
      this.showSaveBtn = true;
      //this.$refs.annex.getAnnexList();
      this.open = true;
      // this.$nextTick(function() {
      //   this.$refs.annex.getAnnexList();
      // });
      this.title = "人体器官潜在捐献者登记表";
    },
    /** ä¿®æ”¹æŒ‰é’®æ“ä½œ */
    handleUpdate(row) {
      this.$router.push({
        path: "/case/course",
        query: {
          id: row.id,
          organType: "edit"
        }
      });
      // this.showSaveBtn = true;
      // const id = row.id || this.ids;
      // //this.$refs.annex.getAnnexList();
      // getDonatebaseinfo(id).then((response) => {
      //   this.reset();
      //   this.$nextTick(function () {
      //     this.$refs.annex.getAnnexList();
      //   });
      //   this.form = response.data;
      //   response.data.sex = parseInt(response.data.sex);
      //   this.form.id = response.data.id;
      //   this.form.diseasetype = this.form.diseasetype.split(",");
      //   this.form.infectious = this.form.infectious.split(",");
      //   this.form.selfwill = this.form.selfwill.split(",");
      //   this.form.othercases = this.form.othercases.split(",");
      //   this.form.infosources = this.form.infosources.split(",");
      //   this.form.kinship = this.form.kinship.split(",");
      //   this.form.patientstate = this.form.patientstate.split(",");
      //   this.open = true;
      //   this.title = "人体器官潜在捐献者登记表";
      //   this.registerAddresss.sheng = response.data.registerprovincename;
      //   this.residenceAddresss.sheng = response.data.residenceprovincename;
      //   this.registerAddresss.shi = response.data.registercityname;
      //   this.residenceAddresss.shi = response.data.residencecityname;
      //   this.residenceAddresss.qu = response.data.residencetownname;
      //   this.registerAddresss.qu = response.data.registertownname;
      // });
    },
    // ç»ˆæ­¢æ¡ˆä¾‹
    handletermination(row) {
      this.reset();
      this.showSaveBtn = false;
      this.showTerminationBtn = true;
      const id = row.id || this.ids;
      getDonatebaseinfo(id).then(response => {
        this.form = response.data;
        this.form.diseasetype = this.form.diseasetype.split(",");
        this.form.infectious = this.form.infectious.split(",");
        this.form.selfwill = this.form.selfwill.split(",");
        this.form.othercases = this.form.othercases.split(",");
        this.form.infosources = this.form.infosources.split(",");
        this.form.kinship = this.form.kinship.split(",");
        this.form.patientstate = this.form.patientstate.split(",");
        this.registerAddresss.sheng = response.data.registerprovincename;
        this.residenceAddresss.sheng = response.data.residenceprovincename;
        this.registerAddresss.shi = response.data.registercityname;
        this.residenceAddresss.shi = response.data.residencecityname;
        this.residenceAddresss.qu = response.data.residencetownname;
        this.registerAddresss.qu = response.data.registertownname;
        this.open = true;
        this.title = "人体器官潜在捐献者登记表";
        this.form.recordstate = 99;
        // this.$nextTick(function() {
        //   this.$refs.annex.getAnnexList();
        // });
        query: { id: row.id, organType: "edit" }
      });
    },
    /** æäº¤æŒ‰é’® */
    submitForm() {
      console.log(this.form);
      this.$refs["form"].validate(valid => {
        if (valid) {
          const date = { ...this.form };
          console.log(date, "date");
          this.form.birthday = this.$moment(this.form.birthday).format(
            "YYYY-MM-DD HH:mm:ss"
          );
          this.form.diseasetype = this.form.diseasetype.join(",");
          this.form.infectious = this.form.infectious.join(",");
          this.form.selfwill = this.form.selfwill.join(",");
          this.form.othercases = this.form.othercases.join(",");
          this.form.infosources = this.form.infosources.join(",");
          this.form.kinship = this.form.kinship.join(",");
          this.form.patientstate = this.form.patientstate.join(",");
          this.form.registerprovince = this.$refs.registerSelect.getSheng();
          this.form.registerprovincename = this.registerAddresss.sheng;
          this.form.residenceprovince = this.$refs.residenceSelect.getSheng();
          this.form.residenceprovincename = this.residenceAddresss.sheng;
    async submitForm() {
      const valid = await this.$refs.form.validate();
      if (!valid) return;
          this.form.registercity = this.$refs.registerSelect.getShi();
          this.form.registercityname = this.registerAddresss.shi;
      const formData = { ...this.form };
          this.form.residencecity = this.$refs.residenceSelect.getShi();
          this.form.residencecityname = this.residenceAddresss.shi;
          this.form.residencetown = this.$refs.residenceSelect.getQu();
          this.form.residencetownname = this.residenceAddresss.qu;
          this.form.registertown = this.$refs.registerSelect.getQu();
          this.form.registertownname = this.registerAddresss.qu;
          this.form.reportername = this.$refs.getReportname.$data.selectedLabel;
          this.form.donatetime = this.form.reporttime;
      // å¤„理表单数据
      const processedData = this.processFormData(formData);
          try {
            this.form.treatmenthospitalname = this.$refs.addOrgSelect.getOptionByValue(
              this.form.treatmenthospitalno
            ).organizationname;
          } catch {
            this.form.treatmenthospitalname = this.form.treatmenthospitalno;
          }
          try {
            this.form.redorganname = this.$refs.addCrossOrgSelect.getOptionByValue(
              this.form.redorganno
            ).organizationname;
          } catch {
            this.form.redorganname = this.form.redorganno;
          }
          this.form.workflow = 0;
          this.form.recordstate = 0;
          addDonatebaseinfo(this.form).then(res => {
            console.log("22");
            console.log(res.code);
            if (res.code == 200) {
        const res = await addDonatebaseinfo(processedData);
        if (res.code === 200) {
              this.$modal.msgSuccess("新增成功");
              this.$router.push({
                path: "/organ/donationdetails/",
                query: {
                  id: res.data.id,
                  organType: "edit"
                }
            query: { id: res.data.id, organType: "edit" }
              });
              this.open = false;
            } else {
              console.log("1");
              this.form = date;
              console.log(this.form, "form");
              this.$modal.msgError("新增失败:" + res.msg);
            }
          });
      } catch (error) {
        this.$modal.msgError("操作失败");
        }
      });
    },
    /** åˆ é™¤æŒ‰é’®æ“ä½œ */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal
        .confirm('是否确认删除捐献基础编号为"' + ids + '"的数据项?')
        .then(function() {
          return delDonatebaseinfo(ids);
        })
        .then(() => {
          this.getList();
          this.$modal.msgSuccess("删除成功");
        })
        .catch(() => {});
    },
    /** å¯¼å‡ºæŒ‰é’®æ“ä½œ */
    handleExport() {
      const queryParams = this.queryParams;
      this.$modal
        .confirm("是否确认导出所有捐献基础数据项?")
        .then(() => {
    processFormData(data) {
      const processed = { ...data };
      // å¤„理数组字段
      const arrayFields = [
        "diseasetype",
        "infectious",
        "selfwill",
        "othercases",
        "infosources",
        "kinship",
        "patientstate"
      ];
      arrayFields.forEach(field => {
        if (Array.isArray(processed[field])) {
          processed[field] = processed[field].join(",");
        }
      });
      // å¤„理日期字段
      if (processed.birthday) {
        processed.birthday = this.$moment(processed.birthday).format(
          "YYYY-MM-DD HH:mm:ss"
        );
      }
      processed.donatetime = processed.reporttime;
      processed.workflow = 0;
      processed.recordstate = 0;
      return processed;
    },
    async handleExport() {
      try {
        await this.$modal.confirm("是否确认导出所有捐献基础数据项?");
          this.exportLoading = true;
          return exportDonatebaseinfo(queryParams);
        })
        .then(response => {
        const response = await exportDonatebaseinfo(this.queryParams);
          this.$download.name(response.msg);
      } catch (error) {
        if (error !== "cancel") {
          this.$modal.msgError("导出失败");
        }
      } finally {
          this.exportLoading = false;
        })
        .catch(() => {});
    },
    // å¯¹è±¡è½¬æˆæŒ‡å®šå­—符串分隔
    listToString(list, separator) {
      let strs = "";
      separator = separator || ",";
      for (let i in list) {
        strs += list[i] + separator;
      }
      return strs != "" ? strs.substr(0, strs.length - 1) : "";
    },
    //字符串根据指定字符串分隔
    stringToList(str, separator) {
      separator = separator || ",";
      let tempList = [];
      if (str != null && str != undefined && str != "") {
        tempList = str.split(separator);
      }
      return tempList;
    },
    //下载潜在登记表
    handledownload(row) {
      const id = row.id || this.ids;
      downloadbaseinfo(id).then(res => {
        var fileUrl = res;
        //获取当前网址
        var urlBase = process.env.VUE_APP_BASE_API;
        var curWWWPath = window.document.location.href;
        var pos = curWWWPath.indexOf(window.document.location.pathname);
        // åˆ›å»ºa标签
        var aEle = document.createElement("a");
        aEle.href =
          curWWWPath.substring(0, pos) + urlBase + fileUrl["downloadUrl"];
        console.log(aEle.href);
        // æ·»åŠ Authorization头部
        fetch(aEle.href, {
          headers: this.headers
        })
          .then(response => {
            // å°†æ–‡ä»¶ä¸‹è½½é“¾æŽ¥ä½œä¸ºblob对象进行下载
            return response.blob();
          })
          .then(blob => {
            const url = window.URL.createObjectURL(new Blob([blob]));
            console.log(url);
            const link = document.createElement("a");
            link.href = url;
            const name = fileUrl["downloadName"];
            link.setAttribute("download", name); // æ›¿æ¢file.pdf为实际的文件名
            document.body.appendChild(link);
            link.click();
            link.parentNode.removeChild(link);
          });
      });
    }
  }
};