WXL
6 天以前 631c8f37b449b09d19345b76400a39abdb7800f6
src/views/business/transfer/index.vue
@@ -2,16 +2,12 @@
  <div class="app-container">
    <!-- 搜索筛选区域 -->
    <el-card class="filter-card">
      <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="80px">
        <el-form-item label="转运单号" prop="transportNo">
          <el-input
            v-model="queryParams.transportNo"
            placeholder="请输入转运单号"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
      <el-form
        :model="queryParams"
        ref="queryForm"
        :inline="true"
        label-width="80px"
      >
        <el-form-item label="案例编号" prop="caseNo">
          <el-input
            v-model="queryParams.caseNo"
@@ -21,22 +17,28 @@
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="捐献者姓名" prop="donorName">
        <el-form-item label="患者姓名" prop="patName">
          <el-input
            v-model="queryParams.donorName"
            placeholder="请输入捐献者姓名"
            v-model="queryParams.patName"
            placeholder="请输入患者姓名"
            clearable
            style="width: 200px"
            @keyup.enter.native="handleQuery"
          />
        </el-form-item>
        <el-form-item label="转运状态" prop="status">
          <el-select v-model="queryParams.status" placeholder="转运状态" clearable style="width: 200px">
            <el-option label="全部" value=""/>
            <el-option label="待出发" value="pending"/>
            <el-option label="转运中" value="transporting"/>
            <el-option label="已完成" value="completed"/>
            <el-option label="已取消" value="cancelled"/>
        <el-form-item label="转运状态" prop="transitStatus">
          <el-select
            v-model="queryParams.transitStatus"
            placeholder="转运状态"
            clearable
            style="width: 200px"
          >
            <el-option label="全部" value="" />
            <el-option label="待转运" :value="1" />
            <el-option label="转运中" :value="2" />
            <el-option label="转运完成" :value="3" />
            <el-option label="转运取消" :value="4" />
            <el-option label="暂存" :value="5" />
          </el-select>
        </el-form-item>
        <el-form-item label="创建时间">
@@ -51,7 +53,9 @@
          ></el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
          <el-button type="primary" icon="el-icon-search" @click="handleQuery"
            >搜索</el-button
          >
          <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
        </el-form-item>
      </el-form>
@@ -97,71 +101,166 @@
    <!-- 操作按钮区域 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" @click="handleAdd">新建转运单</el-button>
        <el-button type="primary" plain icon="el-icon-plus" @click="handleAdd"
          >新建转运单</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="el-icon-edit" :disabled="single" @click="handleUpdate">修改</el-button>
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          :disabled="single"
          @click="handleUpdate"
          >修改</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="el-icon-delete" :disabled="multiple" @click="handleDelete">删除</el-button>
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          :disabled="multiple"
          @click="handleDelete"
          >删除</el-button
        >
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="el-icon-download" @click="handleExport">导出</el-button>
        <el-button
          type="warning"
          plain
          icon="el-icon-download"
          @click="handleExport"
          >导出</el-button
        >
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
      <right-toolbar
        :showSearch.sync="showSearch"
        @queryTable="getList"
      ></right-toolbar>
    </el-row>
    <!-- 数据表格 -->
    <el-table v-loading="loading" :data="transportList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center"/>
      <el-table-column label="序号" type="index" width="60" align="center"/>
      <el-table-column label="转运单号" align="center" prop="id" width="140"/>
      <el-table-column label="案例编号" align="center" prop="caseNo" width="140"/>
      <el-table-column label="捐献者信息" align="center" width="180">
    <!-- 数据表格 - 直接使用后端返回的数据结构 -->
    <el-table
      v-loading="loading"
      :data="transportList"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="序号" type="index" width="60" align="center" />
      <el-table-column
        label="转运单号"
        align="center"
        prop="reportId"
        width="140"
      />
      <el-table-column
        label="案例编号"
        align="center"
        prop="caseNo"
        width="140"
      />
      <el-table-column label="患者信息" align="center" width="260">
        <template slot-scope="scope">
          <div class="donor-info">
            <div class="donor-name">{{ scope.row.donorName }}</div>
            <div class="donor-details">{{ scope.row.gender }} | {{ scope.row.age }}岁</div>
            <div class="donor-name">{{ scope.row.patName }}</div>
            <div class="donor-details">
              <dict-tag
                :options="dict.type.sys_user_sex"
                :value="parseInt(scope.row.sex)"
              />
              | {{ scope.row.age }}岁
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="疾病诊断" align="center" prop="diagnosis" min-width="200" show-overflow-tooltip/>
      <el-table-column label="医疗机构" align="center" prop="hospitalName" width="150"/>
      <el-table-column label="计划转运时间" align="center" prop="transportTime" width="160"/>
      <el-table-column label="负责协调员" align="center" prop="coordinator" width="100"/>
      <el-table-column label="转运状态" align="center" prop="status" width="100">
      <el-table-column
        label="疾病诊断"
        align="center"
        prop="diagnosisname"
        min-width="200"
        show-overflow-tooltip
      />
      <el-table-column
        label="治疗医院"
        align="center"
        prop="treatmentHospitalName"
        width="150"
      />
      <el-table-column
        label="计划转运时间"
        align="center"
        prop="transportStartTime"
        width="160"
      />
      <el-table-column
        label="负责协调员"
        align="center"
        prop="contactPerson"
        width="100"
      />
      <el-table-column
        label="转运状态"
        align="center"
        prop="transitStatus"
        width="100"
      >
        <template slot-scope="scope">
          <el-tag :type="scope.row.status | statusFilter">
            {{ scope.row.statusText }}
          <el-tag :type="getStatusTagType(scope.row.transitStatus)">
            {{ getStatusText(scope.row.transitStatus) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" align="center" prop="createTime" width="160"/>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
      <el-table-column
        label="创建时间"
        align="center"
        prop="createTime"
        width="160"
      />
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
        width="220"
      >
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-view" @click="handleDetail(scope.row)">详情</el-button>
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">编辑</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleDetail(scope.row)"
            >详情</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            >编辑</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-video-play"
            @click="handleStartTransport(scope.row)"
            v-if="scope.row.status === 'pending'"
          >开始转运</el-button>
            v-if="scope.row.transitStatus === 1"
            >开始转运</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-check"
            @click="handleCompleteTransport(scope.row)"
            v-if="scope.row.status === 'transporting'"
          >完成转运</el-button>
            v-if="scope.row.transitStatus === 2"
            >完成转运</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <pagination
      v-show="total>0"
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
@@ -176,9 +275,20 @@
      append-to-body
      :close-on-click-modal="false"
    >
      <transport-detail :transportData="currentTransport" @close="detailOpen = false"/>
      <transport-detail
        :transportData="currentTransport"
        @close="detailOpen = false"
      />
    </el-dialog>
    <!-- 新增:修改弹框 -->
    <transport-edit
      :edit-open="editOpen"
      :transport-data="currentTransport"
      :is-edit="isEditing"
      @update:edit-open="editOpen = $event"
      @close="handleEditClose"
      @save-success="handleSaveSuccess"
    />
    <!-- 操作确认弹框 -->
    <el-dialog
      :title="actionTitle"
@@ -187,7 +297,11 @@
      append-to-body
    >
      <div class="action-confirm">
        <p>确定要{{ actionText }}转运单 "{{ currentTransport.id }}" 吗?</p>
        <p>
          确定要{{ actionText }}转运单 "{{
            currentTransport.reportId || currentTransport.id
          }}" 吗?
        </p>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="actionOpen = false">取 消</el-button>
@@ -198,12 +312,20 @@
</template>
<script>
import { listTransport, getTransport, delTransport, updateTransportStatus } from "@/api/system/business";
import TransportDetail from './transportDetail';
import {
  transportList,
  transportAdd,
  transportEdit,
  transportDelete,
  transportInfo
} from "@/api/businessApi/index";
import TransportDetail from "./transportDetail";
import TransportEdit from "./TransportEdit";
export default {
  name: "TransportList",
  components: { TransportDetail },
  components: { TransportDetail, TransportEdit },
  dicts: ["sys_user_sex", "sys_BloodType"],
  data() {
    return {
      // 遮罩层
@@ -218,12 +340,15 @@
      showSearch: true,
      // 总条数
      total: 0,
      // 转运单表格数据
      // 转运单表格数据 - 直接使用后端返回的数据结构
      transportList: [],
      // 详情弹框是否显示
      detailOpen: false,
      // 操作确认弹框是否显示
      actionOpen: false,
      // 新增:修改弹框相关数据
      editOpen: false,
      isEditing: false,
      // 详情弹框标题
      detailTitle: "",
      // 操作确认标题
@@ -240,138 +365,101 @@
        pendingTransports: 0,
        completedTransports: 0
      },
      // 查询参数
      // 查询参数(完全适配后端接口)
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        transportNo: undefined,
        caseNo: undefined,
        donorName: undefined,
        status: undefined
        caseNo: undefined, // 案例编号
        patName: undefined, // 患者姓名
        transitStatus: undefined, // 转运状态:1待转运 2转运中 3转运完成 4转运取消 5暂存
        searchValue: undefined, // 搜索值
        params: {} // 其他参数对象
      }
    };
  },
  filters: {
    statusFilter(status) {
      const statusMap = {
        'pending': 'warning',
        'transporting': 'primary',
        'completed': 'success',
        'cancelled': 'danger'
      };
      return statusMap[status];
    }
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询转运单列表 */
    getList() {
    /** 查询转运单列表 - 直接使用后端数据结构 */
    async getList() {
      this.loading = true;
      // 模拟API调用延迟
      setTimeout(() => {
        // 测试数据
        this.transportList = [
          {
            id: 'T20241217001',
            caseNo: 'DON20241216001',
            donorName: '张三',
            gender: '男',
            age: 38,
            diagnosis: '脑外伤导致脑死亡,经抢救无效宣布脑死亡。家属同意器官捐献。',
            hospitalName: '青岛镜湖医院',
            transportTime: '2024-12-17 14:30:00',
            coordinator: '张医生',
            createTime: '2024-12-16 09:30:00',
            status: 'pending',
            statusText: '待出发',
            departureLocation: '青岛市立医院急诊科',
            destinationHospital: '青岛镜湖医院',
            emergencyDoctor: '王医生',
            nurse: '李护士',
            driver: '刘师傅',
            icuDoctor: '赵医生',
            contacts: [
              { role: '协调员电话', phone: '13800138000' },
              { role: '急诊医生电话', phone: '13800138001' },
              { role: '护士电话', phone: '13800138002' },
              { role: '司机电话', phone: '13800138003' },
              { role: 'ICU医生电话', phone: '13800138004' }
            ],
            remarks: '需要准备呼吸机等急救设备'
          },
          {
            id: 'T20241217002',
            caseNo: 'DON20241216002',
            donorName: '李四',
            gender: '女',
            age: 45,
            diagnosis: '脑梗死,脑干功能丧失',
            hospitalName: '青岛大学附属医院',
            transportTime: '2024-12-17 16:00:00',
            coordinator: '李医生',
            createTime: '2024-12-16 11:20:00',
            status: 'transporting',
            statusText: '转运中',
            departureLocation: '青岛大学附属医院ICU',
            destinationHospital: '青岛器官移植中心',
            currentLocation: '青岛市南区香港中路',
            estimatedTime: '30分钟'
          },
          {
            id: 'T20241216003',
            caseNo: 'DON20241215001',
            donorName: '王五',
            gender: '男',
            age: 52,
            diagnosis: '心脏骤停,多器官功能衰竭',
            hospitalName: '青岛市立医院',
            transportTime: '2024-12-16 10:15:00',
            coordinator: '王医生',
            createTime: '2024-12-15 14:45:00',
            status: 'completed',
            statusText: '已完成',
            departureLocation: '青岛市立医院心内科',
            destinationHospital: '青岛器官移植中心',
            completedTime: '2024-12-16 12:30:00',
            distance: '15公里',
            duration: '2小时15分钟'
          },
          {
            id: 'T20241216004',
            caseNo: 'DON20241214001',
            donorName: '赵六',
            gender: '女',
            age: 29,
            diagnosis: '急性肝衰竭',
            hospitalName: '青岛科大医院',
            transportTime: '2024-12-16 08:30:00',
            coordinator: '赵医生',
            createTime: '2024-12-14 16:20:00',
            status: 'cancelled',
            statusText: '已取消',
            cancelReason: '家属临时改变决定'
          }
        ];
        // 更新统计数据
        this.updateStats();
        this.total = this.transportList.length;
      try {
        // 构建符合后端接口的请求参数 [1,2](@ref)
        const requestParams = {
          pageNum: this.queryParams.pageNum,
          pageSize: this.queryParams.pageSize,
          caseNo: this.queryParams.caseNo,
          patName: this.queryParams.patName,
          transitStatus: this.queryParams.transitStatus,
          searchValue: this.queryParams.searchValue
        };
        // 处理时间范围参数 [5](@ref)
        if (this.dateRange && this.dateRange.length === 2) {
          requestParams.transportStartTime = this.dateRange.join(",");
        }
        // 调用正式接口 [3](@ref)
        const response = await transportList(requestParams);
        if (response.code === 200) {
          // 直接使用后端返回的数据结构,不进行转换 [8](@ref)
          this.transportList = response.rows || response.data || [];
          this.total = response.total || 0;
          // 更新统计数据
          this.updateStats();
        } else {
          this.$modal.msgError(response.msg || "获取转运单列表失败");
        }
      } catch (error) {
        console.error("获取转运单列表失败:", error);
        this.$modal.msgError("网络请求失败,请稍后重试");
      } finally {
        this.loading = false;
      }, 500);
      }
    },
    /** 获取状态标签类型 */
    getStatusTagType(transitStatus) {
      const statusMap = {
        1: "warning", // 待转运
        2: "primary", // 转运中
        3: "success", // 转运完成
        4: "danger", // 转运取消
        5: "info" // 暂存
      };
      return statusMap[transitStatus] || "info";
    },
    /** 获取状态文本 */
    getStatusText(transitStatus) {
      const statusMap = {
        1: "待转运",
        2: "转运中",
        3: "转运完成",
        4: "转运取消",
        5: "暂存"
      };
      return statusMap[transitStatus] || "未知状态";
    },
    // 更新统计数据
    updateStats() {
      this.stats.totalTransports = this.transportList.length;
      this.stats.pendingTransports = this.transportList.filter(item => item.status === 'pending').length;
      this.stats.completedTransports = this.transportList.filter(item => item.status === 'completed').length;
      this.stats.pendingTransports = this.transportList.filter(
        item => item.transitStatus === 1
      ).length;
      this.stats.completedTransports = this.transportList.filter(
        item => item.transitStatus === 3
      ).length;
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.ids = selection.map(item => item.reportId || item.id);
      this.single = selection.length !== 1;
      this.multiple = !selection.length;
    },
@@ -385,82 +473,129 @@
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRange = [];
      this.resetForm("queryForm");
      this.handleQuery();
      this.queryParams = {
        pageNum: 1,
        pageSize: 10,
        caseNo: undefined,
        patName: undefined,
        transitStatus: undefined,
        searchValue: undefined
      };
      this.getList();
    },
    /** 详情按钮操作 */
    handleDetail(row) {
      this.currentTransport = row;
      this.detailTitle = `转运单详情 - ${row.id}`;
      this.detailTitle = `转运单详情 - ${row.reportId || row.id}`;
      this.detailOpen = true;
    },
    /** 开始转运操作 */
    handleStartTransport(row) {
      this.currentTransport = row;
      this.actionTitle = '开始转运';
      this.actionText = '开始';
      this.actionOpen = true;
    },
    /** 完成转运操作 */
    handleCompleteTransport(row) {
      this.currentTransport = row;
      this.actionTitle = '完成转运';
      this.actionText = '完成';
      this.actionOpen = true;
    },
    /** 确认操作 */
    confirmAction() {
      const index = this.transportList.findIndex(item => item.id === this.currentTransport.id);
      if (index !== -1) {
        if (this.actionText === '开始') {
          this.transportList[index].status = 'transporting';
          this.transportList[index].statusText = '转运中';
        } else if (this.actionText === '完成') {
          this.transportList[index].status = 'completed';
          this.transportList[index].statusText = '已完成';
          this.transportList[index].completedTime = new Date().toLocaleString();
        }
        // 更新统计数据
        this.updateStats();
        this.$modal.msgSuccess(`${this.actionText}成功`);
      }
      this.actionOpen = false;
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.$router.push('/transport/add');
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      const id = row.id || this.ids[0];
      this.$router.push('/transport/edit/' + id);
      this.currentTransport = row || {};
      this.isEditing = true;
      this.editOpen = true;
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const ids = row.id || this.ids;
      this.$modal.confirm('是否确认删除转运单编号为"' + ids + '"的数据项?').then(() => {
        // 模拟删除操作
        this.transportList = this.transportList.filter(item => !ids.includes(item.id));
        this.total = this.transportList.length;
        this.updateStats();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    /** 新建转运单 */
    handleAdd() {
      this.currentTransport = {};
      this.isEditing = false;
      this.editOpen = true;
    },
    /** 修改弹框关闭处理 */
    handleEditClose() {
      this.editOpen = false;
      this.currentTransport = {};
    },
    /** 保存成功处理 */
    handleSaveSuccess() {
      this.getList(); // 重新加载列表
    },
    /** 开始转运操作 */
    async handleStartTransport(row) {
      this.currentTransport = row;
      this.actionTitle = "开始转运";
      this.actionText = "开始";
      this.actionOpen = true;
    },
    /** 完成转运操作 */
    async handleCompleteTransport(row) {
      this.currentTransport = row;
      this.actionTitle = "完成转运";
      this.actionText = "完成";
      this.actionOpen = true;
    },
    /** 确认操作 - 使用后端原始数据结构 [4](@ref) */
    async confirmAction() {
      try {
        let requestData = {
          id: this.currentTransport.id || this.currentTransport.reportId
        };
        if (this.actionText === "开始") {
          requestData.transitStatus = 2; // 设置为转运中
        } else if (this.actionText === "完成") {
          requestData.transitStatus = 3; // 设置为转运完成
        }
        // 直接传递后端需要的参数 [8](@ref)
        const response = await transportEdit(requestData);
        if (response.code === 200) {
          this.$modal.msgSuccess(`${this.actionText}转运成功`);
          this.getList(); // 刷新列表
        } else {
          this.$modal.msgError(response.msg || `${this.actionText}转运失败`);
        }
      } catch (error) {
        console.error(`${this.actionText}转运失败:`, error);
        this.$modal.msgError("操作失败,请稍后重试");
      }
      this.actionOpen = false;
    },
    /** 删除按钮操作 - 使用后端原始ID [1](@ref) */
    async handleDelete(row) {
      const ids = row.reportId || row.id || this.ids;
      try {
        await this.$modal.confirm(
          '是否确认删除转运单编号为"' + ids + '"的数据项?'
        );
        const response = await transportDelete(ids);
        if (response.code === 200) {
          this.$modal.msgSuccess("删除成功");
          this.getList(); // 刷新列表
        } else {
          this.$modal.msgError(response.msg || "删除失败");
        }
      } catch (error) {
        if (error !== "cancel") {
          console.error("删除失败:", error);
          this.$modal.msgError("删除失败,请稍后重试");
        }
      }
    },
    /** 导出按钮操作 */
    handleExport() {
      this.download('system/transport/export', {
        ...this.queryParams
      }, `transport_${new Date().getTime()}.xlsx`)
      // 直接使用后端参数结构进行导出 [5](@ref)
      this.download(
        "system/transport/export",
        {
          ...this.queryParams
        },
        `transport_${new Date().getTime()}.xlsx`
      );
    }
  }
};
@@ -486,15 +621,15 @@
}
.stats-card.total {
  border-left: 4px solid #409EFF;
  border-left: 4px solid #409eff;
}
.stats-card.pending {
  border-left: 4px solid #E6A23C;
  border-left: 4px solid #e6a23c;
}
.stats-card.completed {
  border-left: 4px solid #67C23A;
  border-left: 4px solid #67c23a;
}
.stat-content {
@@ -525,7 +660,9 @@
}
.donor-info {
  text-align: left;
  text-align: center;
  display: flex;
  justify-content: center
}
.donor-name {
@@ -534,8 +671,10 @@
}
.donor-details {
  font-size: 12px;
  color: #909399;
  margin-left: 5px;
  font-size: 16px;
  color: #093ca4;
  display: flex;
}
.mb8 {