WXL
3 天以前 4c9fdc87987140e8b2c3f0dfc2f6608cdb6be774
src/views/business/OrganUtilization/OrganUtilizationInfo.vue
@@ -13,18 +13,21 @@
            <el-input
              v-model="form.responsibleusername"
              placeholder="请输入负责人姓名"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="协调员一" prop="coordinatedusernameo" class="col-1-3">
            <el-input
              v-model="form.coordinatedusernameo"
              placeholder="请输入协调员一姓名"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="协调员二" prop="coordinatedusernamet" class="col-1-3">
            <el-input
              v-model="form.coordinatedusernamet"
              placeholder="请输入协调员二姓名"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="完成时间" prop="completetime" class="col-1-3">
@@ -33,6 +36,7 @@
              type="datetime"
              value-format="yyyy-MM-dd HH:mm:ss"
              style="width: 100%"
              :disabled="isReadOnly"
            />
          </el-form-item>
        </div>
@@ -61,7 +65,7 @@
        </div>
        <div class="form-row">
          <el-form-item align="left" label="遗体接收" prop="isbodydonation" class="col-1-3">
            <el-radio-group v-model="form.isbodydonation">
            <el-radio-group v-model="form.isbodydonation" :disabled="isReadOnly">
              <el-radio
                v-for="dict in dict.type.sys_0_1 || []"
                :key="dict.value"
@@ -75,12 +79,14 @@
            <el-input
              v-model="form.relationname"
              placeholder="请输入接收家属"
              :disabled="isReadOnly"
            />
          </el-form-item>
          <el-form-item label="与捐献者关系" prop="signfamilyrelations" class="col-1-3">
            <el-select
              v-model="form.signfamilyrelations"
              placeholder="请选择与捐献者关系"
              :disabled="isReadOnly"
            >
              <el-option
                v-for="dict in dict.type.sys_FamilyRelation || []"
@@ -116,6 +122,7 @@
            <el-form-item label-width="100px" label="移植器官">
              <el-checkbox-group
                v-model="selectedOrgans"
                :disabled="isReadOnly"
                @change="handleOrganSelectionChange"
              >
                <el-checkbox
@@ -181,7 +188,9 @@
                              <el-form-item label="受者姓名">
                                <el-input
                                  v-model="scope.row.name"
                                  :class="{ 'field-error': isFieldError(scope.row, 'name') }"
                                  placeholder="请输入受者姓名"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -193,6 +202,7 @@
                                  value-format="yyyy-MM-dd"
                                  placeholder="选择出生日期"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -202,6 +212,7 @@
                                  v-model="scope.row.sex"
                                  placeholder="请选择性别"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                >
                                  <el-option label="男" :value="0" />
                                  <el-option label="女" :value="1" />
@@ -216,6 +227,7 @@
                                <el-input
                                  v-model="scope.row.age"
                                  placeholder="年龄"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -225,6 +237,7 @@
                                  v-model="scope.row.idcardtype"
                                  placeholder="请选择证件类型"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                >
                                  <el-option label="身份证" :value="1" />
                                  <el-option label="护照" :value="2" />
@@ -238,6 +251,7 @@
                                <el-input
                                  v-model="scope.row.idcardno"
                                  placeholder="证件号码"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -253,6 +267,7 @@
                                <el-input
                                  v-model="scope.row.hospitalname"
                                  placeholder="请输入移植中心名称"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -261,6 +276,7 @@
                                <el-input
                                  v-model="scope.row.phone"
                                  placeholder="联系电话"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -274,6 +290,7 @@
                                  :rows="2"
                                  v-model="scope.row.residenceaddress"
                                  placeholder="请输入详细地址"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -295,6 +312,7 @@
                                  value-format="yyyy-MM-dd HH:mm:ss"
                                  placeholder="选择移植日期"
                                  style="width: 100%"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -303,6 +321,7 @@
                                <el-input
                                  v-model="scope.row.transplantdoct"
                                  placeholder="请输入移植医生"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -321,8 +340,10 @@
                                <el-input
                                  type="textarea"
                                  :rows="3"
                                  :class="{ 'field-error': isFieldError(scope.row, 'abandonreason') }"
                                  v-model="scope.row.abandonreason"
                                  placeholder="请输入未移植原因"
                                  :disabled="isReadOnly"
                                />
                              </el-form-item>
                            </el-col>
@@ -365,10 +386,12 @@
                  <template slot-scope="scope">
                    <el-autocomplete
                      v-model="scope.row.hospitalname"
                      :class="{ 'field-error': isFieldError(scope.row, 'hospitalname') }"
                      :fetch-suggestions="queryHospitalSearch"
                      placeholder="请选择或输入移植医院"
                      style="width: 100%"
                      clearable
                      :disabled="isReadOnly"
                    ></el-autocomplete>
                  </template>
                </el-table-column>
@@ -382,6 +405,7 @@
                      v-model="scope.row.transplantstate"
                      placeholder="请选择移植状态"
                      style="width: 100%"
                      :disabled="isReadOnly"
                      @change="handleTransplantStatusChange(scope.row, $event)"
                    >
                      <el-option
@@ -406,9 +430,11 @@
                      size="small"
                      style="width: 100%"
                      v-model="scope.row.transplanttime"
                      :class="{ 'field-error': isFieldError(scope.row, 'transplanttime') }"
                      type="datetime"
                      value-format="yyyy-MM-dd HH:mm:ss"
                      placeholder="选择移植时间"
                      :disabled="isReadOnly"
                    />
                  </template>
                </el-table-column>
@@ -422,13 +448,18 @@
                    <el-input
                      v-model="scope.row.transplantdoct"
                      placeholder="医师姓名"
                      :disabled="isReadOnly"
                    />
                  </template>
                </el-table-column>
                <el-table-column label="受者姓名" align="center" prop="name">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.name" placeholder="受者姓名" />
                    <el-input
                      v-model="scope.row.name"
                      placeholder="受者姓名"
                      :disabled="isReadOnly"
                    />
                  </template>
                </el-table-column>
              </el-table>
@@ -469,6 +500,7 @@
        >
          <div style="margin-bottom: 10px; text-align: right;">
            <el-button
              v-if="!isReadOnly"
              size="mini"
              type="primary"
              icon="el-icon-plus"
@@ -498,6 +530,7 @@
                <el-select
                  v-model="scope.row.fileType"
                  size="small"
                  :disabled="isReadOnly"
                  @change="updateAttachmentCategory(scope.row, $event)"
                  placeholder="选择分类"
                >
@@ -526,7 +559,12 @@
                <span>{{ formatFileSize(scope.row.fileSize) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="180" fixed="right">
            <el-table-column
              v-if="!isReadOnly"
              label="操作"
              width="180"
              fixed="right"
            >
              <template #default="scope">
                <el-button
                  size="mini"
@@ -553,10 +591,16 @@
      </el-tabs>
    </el-card>
    <div style="text-align: center; margin: 30px 0;">
      <el-button type="primary" @click="handleSave" :loading="saveLoading">
      <el-button
        v-if="!isReadOnly"
        type="primary"
        @click="handleSave"
        :loading="saveLoading"
      >
        保存
      </el-button>
      <el-button
        v-if="!isReadOnly"
        type="success"
        @click="handleComplete"
        :loading="confirmLoading"
@@ -621,6 +665,7 @@
  completionadd,
  completionedit
} from "@/api/businessApi";
import { getDonatebaseinfo } from "@/api/project/donatebaseinfo";
import FilePreviewDialog from "@/components/FilePreviewDialog";
import CaseBasicInfo from "@/components/CaseBasicInfo";
import { getToken } from "@/utils/auth";
@@ -706,7 +751,8 @@
        { value: "1", label: "已移植" },
        { value: "0", label: "未移植" },
        { value: "2", label: "移植中" },
        { value: "3", label: "库存" }
        { value: "3", label: "库存" },
        { value: "4", label: "弃用" }
      ],
      organExpansionMap: {
        C64: { subItems: ["C64L", "C64R"], subNames: ["左肾", "右肾"] },
@@ -724,6 +770,8 @@
      attachments: [],
      // 展开的行keys
      expandedRows: [],
      // 校验失败时高亮的字段(organno -> 缺失字段名数组)
      errorFields: {},
      // 编辑对话框
      editDialogVisible: false,
      currentRecord: {},
@@ -795,6 +843,21 @@
    // 获取器官字典
    organDict() {
      return this.dict.type.sys_Organ || [];
    },
    // 查看模式:只读,禁用表单并隐藏保存按钮
    isReadOnly() {
      return this.$route.query.mode === "view";
    }
  },
  watch: {
    // 用户修改利用记录时,清除字段高亮
    "utilizationData.serviceDonatecomporganList": {
      deep: true,
      handler() {
        if (Object.keys(this.errorFields).length > 0) {
          this.errorFields = {};
        }
      }
    }
  },
  created() {
@@ -1154,7 +1217,7 @@
    getOrganRowClassName({ row }) {
      if (
        row.transplantstate == "1" &&
        (!row.hospitalno || !row.name || !row.transplanttime)
        (!row.hospitalname || !row.name || !row.transplanttime)
      ) {
        return "warning-row";
      }
@@ -1162,6 +1225,11 @@
        return "warning-row";
      }
      return "";
    },
    // 校验失败时字段是否高亮
    isFieldError(row, field) {
      const fields = this.errorFields[row.organno];
      return fields && fields.includes(field);
    },
    // 获取状态标签类型
@@ -1206,10 +1274,19 @@
    // 保存基本信息
    async handleSave() {
      if (this.saveLoading) return;
      this.$refs.form.validate(async valid => {
        if (valid) {
          this.saveLoading = true;
          try {
            // 新增时校验是否已有相同患者
            if (!this.form.id) {
              const exists = await this.checkPatientExists();
              if (exists) {
                this.$message.warning("该患者已存在,请勿重复添加");
                return;
              }
            }
            const saveData = {
              ...this.form,
              assessannex: JSON.stringify(this.attachments),
@@ -1240,6 +1317,33 @@
          }
        }
      });
    },
    // 新增时校验是否已有相同患者(按住院号)
    async checkPatientExists() {
      let inpatientno = this.form.inpatientno;
      if (!inpatientno && this.caseId) {
        try {
          const caseRes = await getDonatebaseinfo(this.caseId);
          inpatientno = (caseRes.data && caseRes.data.inpatientno) || "";
        } catch (e) {
          inpatientno = "";
        }
      }
      if (!inpatientno) return false;
      try {
        const res = await completionList({
          inpatientno,
          pageNum: 1,
          pageSize: 1
        });
        let list = res.data || [];
        if (!Array.isArray(list)) {
          list = list.rows || list.list || [];
        }
        return list.some(item => item && item.id != null && item.id !== "");
      } catch (e) {
        return false;
      }
    },
    // 保存利用记录
@@ -1281,20 +1385,57 @@
    // 确认完成利用
    async handleConfirmUtilization() {
      // 检查利用记录是否完整
      const incompleteRecords = this.utilizationData.serviceDonatecomporganList.filter(
        record => {
          if (record.transplantstate == "1") {
            return !record.hospitalno || !record.name || !record.transplanttime;
          } else if (record.transplantstate == "0") {
            return !record.abandonreason;
          }
          return false;
      if (
        !this.utilizationData.serviceDonatecomporganList ||
        this.utilizationData.serviceDonatecomporganList.length == 0
      ) {
        this.$message.warning("请先添加利用记录");
        return;
      }
      // 检查利用记录是否完整,记录缺失字段
      const errorFields = {};
      const incompleteRecords = [];
      this.utilizationData.serviceDonatecomporganList.forEach(record => {
        const missing = [];
        if (record.transplantstate == "1") {
          if (!record.hospitalname) missing.push("hospitalname");
          if (!record.name) missing.push("name");
          if (!record.transplanttime) missing.push("transplanttime");
        } else if (record.transplantstate == "0") {
          if (!record.abandonreason) missing.push("abandonreason");
        }
      );
        if (missing.length > 0) {
          errorFields[record.organno] = missing;
          incompleteRecords.push(record);
        }
      });
      this.errorFields = errorFields;
      if (incompleteRecords.length > 0) {
        this.$message.warning("请先完善所有利用记录的信息");
        // 仅当缺少「未移植原因」时该字段位于折叠面板内,才自动展开对应面板
        this.expandedRows = incompleteRecords
          .filter(record =>
            (errorFields[record.organno] || []).includes("abandonreason")
          )
          .map(record => record.organno);
        // 缺失字段中文名,用于提示具体是哪个项没填
        const fieldLabels = {
          hospitalname: "移植医院",
          name: "受者姓名",
          transplanttime: "移植时间",
          abandonreason: "未移植原因"
        };
        const details = incompleteRecords
          .map(record => {
            const missingLabels = (errorFields[record.organno] || [])
              .map(field => fieldLabels[field] || field)
              .join("、");
            return `${record.organname || record.organno} ${missingLabels}`;
          })
          .join(";");
        this.$message.warning(`请完善以下器官的利用信息:${details}`);
        return;
      }
@@ -1760,6 +1901,13 @@
  background-color: #fdf6ec;
}
/* 校验失败字段高亮 */
.field-error >>> .el-input__inner,
.field-error >>> .el-textarea__inner {
  border-color: #f56c6c !important;
  box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.15);
}
:deep(.el-table__row.default-row) {
  background-color: #f0f9ff;
}
@@ -2073,8 +2221,6 @@
.paper-form {
  border-left: 1px solid #d0d3db;
  background: #fff;
  /* 超宽屏限制表单最大宽度,右侧留白,避免字段分布过开 */
  max-width: 1400px;
}
.paper-form >>> .form-row {