| | |
| | | |
| | | <!-- 基本信息 --> |
| | | <el-descriptions title="基本信息" :column="2" border> |
| | | <el-descriptions-item label="任务编号">{{ taskDetail.taskCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="任务编号">{{ taskDetail.showTaskCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="任务类型"> |
| | | <dict-tag :options="dict.type.sys_task_type" :value="taskDetail.taskType"/> |
| | | </el-descriptions-item> |
| | |
| | | |
| | | <!-- 急救转运任务扩展信息 --> |
| | | <el-descriptions v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo" title="急救转运信息" :column="2" border style="margin-top: 20px;"> |
| | | <el-descriptions-item label="患者姓名">{{ taskDetail.emergencyInfo.patientName }}</el-descriptions-item> |
| | | <el-descriptions-item label="患者性别"> |
| | | <dict-tag :options="dict.type.sys_user_sex" :value="taskDetail.emergencyInfo.patientGender"/> |
| | | <el-descriptions-item label="联系人"> |
| | | <span v-if="taskDetail.emergencyInfo.patientContact">{{ taskDetail.emergencyInfo.patientContact }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="患者年龄">{{ taskDetail.emergencyInfo.patientAge }}</el-descriptions-item> |
| | | <el-descriptions-item label="联系电话">{{ taskDetail.emergencyInfo.contactPhone }}</el-descriptions-item> |
| | | <el-descriptions-item label="接送医院" :span="2">{{ taskDetail.emergencyInfo.hospitalName }}</el-descriptions-item> |
| | | <el-descriptions-item label="就诊科室" :span="2"> |
| | | <dict-tag v-if="taskDetail.emergencyInfo.hospitalDepartment" :options="dict.type.hospital_department" :value="taskDetail.emergencyInfo.hospitalDepartment"/> |
| | | <el-descriptions-item label="联系电话"> |
| | | <span v-if="taskDetail.emergencyInfo.patientPhone">{{ taskDetail.emergencyInfo.patientPhone }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="患者姓名"> |
| | | <span v-if="taskDetail.emergencyInfo.patientName">{{ taskDetail.emergencyInfo.patientName }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="患者性别"> |
| | | <dict-tag v-if="taskDetail.emergencyInfo.patientGender" :options="dict.type.sys_user_sex" :value="taskDetail.emergencyInfo.patientGender"/> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="身份信息" :span="2"> |
| | | <span v-if="taskDetail.emergencyInfo.patientIdCard">{{ taskDetail.emergencyInfo.patientIdCard }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="病情描述" :span="2"> |
| | | <span v-if="taskDetail.emergencyInfo.illnessDescription">{{ taskDetail.emergencyInfo.illnessDescription }}</span> |
| | | <span v-if="taskDetail.emergencyInfo.patientCondition">{{ taskDetail.emergencyInfo.patientCondition }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="特殊需求" :span="2"> |
| | | <span v-if="taskDetail.emergencyInfo.specialRequirements">{{ taskDetail.emergencyInfo.specialRequirements }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="是否需要担架"> |
| | | <el-tag v-if="taskDetail.emergencyInfo.needsStretcher == 1" type="success" size="small">是</el-tag> |
| | | <el-tag v-else type="info" size="small">否</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="是否需要轮椅"> |
| | | <el-tag v-if="taskDetail.emergencyInfo.needsWheelchair == 1" type="success" size="small">是</el-tag> |
| | | <el-tag v-else type="info" size="small">否</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="是否需要氧气"> |
| | | <el-tag v-if="taskDetail.emergencyInfo.needsOxygen == 1" type="success" size="small">是</el-tag> |
| | | <el-tag v-else type="info" size="small">否</el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="紧急程度"> |
| | | <el-tag v-if="taskDetail.emergencyInfo.urgencyLevel === 'HIGH'" type="danger" size="small">紧急</el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.urgencyLevel === 'MEDIUM'" type="warning" size="small">一般</el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.urgencyLevel === 'LOW'" type="info" size="small">不急</el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="陪同人数">{{ taskDetail.emergencyInfo.companionCount || 0 }} 人</el-descriptions-item> |
| | | <el-descriptions-item label="预估费用">{{ taskDetail.emergencyInfo.estimatedCost || '--' }} 元</el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- 旧系统同步信息(仅急救转运任务显示) --> |
| | | <el-descriptions v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo" title="旧系统同步信息" :column="2" border style="margin-top: 20px;"> |
| | | <el-descriptions-item label="服务单同步状态"> |
| | | <el-tag v-if="taskDetail.emergencyInfo.syncStatus === 0" type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未同步 |
| | | </el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.syncStatus === 1" type="warning" size="small"> |
| | | <i class="el-icon-loading"></i> 同步中 |
| | | </el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.syncStatus === 2" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 同步成功 |
| | | </el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.syncStatus === 3" type="danger" size="small"> |
| | | <i class="el-icon-error"></i> 同步失败 |
| | | </el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | <!-- 未同步或同步失败时显示同步按钮 --> |
| | | <el-button |
| | | v-if="taskDetail.emergencyInfo.syncStatus === 0 || taskDetail.emergencyInfo.syncStatus === 3" |
| | | type="primary" |
| | | size="mini" |
| | | icon="el-icon-refresh" |
| | | :loading="syncingServiceOrder" |
| | | @click="syncServiceOrder" |
| | | style="margin-left: 10px;" |
| | | >同步服务单</el-button> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="服务单号"> |
| | | <span v-if="taskDetail.emergencyInfo.legacyServiceOrdId"> |
| | | <el-tag type="primary" size="small">{{ taskDetail.emergencyInfo.legacyServiceOrdId }}</el-tag> |
| | | </span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="服务单编码"> |
| | | <span v-if="taskDetail.emergencyInfo.serviceCode"> |
| | | <el-tag type="success" size="small">{{ taskDetail.emergencyInfo.serviceCode }}</el-tag> |
| | | </span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="服务单同步时间"> |
| | | <span v-if="taskDetail.emergencyInfo.syncTime">{{ parseTime(taskDetail.emergencyInfo.syncTime) }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="服务单同步错误" :span="1"> |
| | | <span v-if="taskDetail.emergencyInfo.syncErrorMsg" style="color: #F56C6C;">{{ taskDetail.emergencyInfo.syncErrorMsg }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="调度单同步状态"> |
| | | <el-tag v-if="taskDetail.emergencyInfo.dispatchSyncStatus === 0" type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未同步 |
| | | </el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.dispatchSyncStatus === 1" type="warning" size="small"> |
| | | <i class="el-icon-loading"></i> 同步中 |
| | | </el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.dispatchSyncStatus === 2" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 同步成功 |
| | | </el-tag> |
| | | <el-tag v-else-if="taskDetail.emergencyInfo.dispatchSyncStatus === 3" type="danger" size="small"> |
| | | <i class="el-icon-error"></i> 同步失败 |
| | | </el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | <!-- 未同步或同步失败时显示同步按钮 --> |
| | | <el-button |
| | | v-if="taskDetail.emergencyInfo.dispatchSyncStatus === 0 || taskDetail.emergencyInfo.dispatchSyncStatus === 3" |
| | | type="primary" |
| | | size="mini" |
| | | icon="el-icon-refresh" |
| | | :loading="syncingDispatchOrder" |
| | | @click="syncDispatchOrder" |
| | | style="margin-left: 10px;" |
| | | >同步调度单</el-button> |
| | | <!-- 从旧系统同步数据到新系统按钮 --> |
| | | <el-button |
| | | v-if="taskDetail.emergencyInfo.legacyServiceOrdId && taskDetail.emergencyInfo.legacyDispatchOrdId" |
| | | type="success" |
| | | size="mini" |
| | | icon="el-icon-download" |
| | | :loading="syncingFromLegacy" |
| | | @click="syncFromLegacySystem" |
| | | style="margin-left: 10px;" |
| | | >从旧系统同步</el-button> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="调度单号"> |
| | | <span v-if="taskDetail.emergencyInfo.legacyDispatchOrdId"> |
| | | <el-tag type="primary" size="small">{{ taskDetail.emergencyInfo.legacyDispatchOrdId }}</el-tag> |
| | | </span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="调度单编码"> |
| | | <span v-if="taskDetail.emergencyInfo.dispatchCode"> |
| | | <el-tag type="success" size="small">{{ taskDetail.emergencyInfo.dispatchCode }}</el-tag> |
| | | </span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="调度单同步时间"> |
| | | <span v-if="taskDetail.emergencyInfo.dispatchSyncTime">{{ parseTime(taskDetail.emergencyInfo.dispatchSyncTime) }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="调度单同步错误" :span="1"> |
| | | <span v-if="taskDetail.emergencyInfo.dispatchSyncErrorMsg" style="color: #F56C6C;">{{ taskDetail.emergencyInfo.dispatchSyncErrorMsg }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="任务状态同步" :span="2"> |
| | | <el-alert |
| | | title="提示:任务状态会自动同步到旧系统的调度单中,如果因网络等原因未同步,可点击下方按钮手动同步。" |
| | | type="info" |
| | | :closable="false" |
| | | show-icon |
| | | style="margin-bottom: 10px;"> |
| | | </el-alert> |
| | | <el-button |
| | | v-if="taskDetail.emergencyInfo.legacyDispatchOrdId && taskDetail.emergencyInfo.legacyDispatchOrdId > 0" |
| | | type="warning" |
| | | size="small" |
| | | icon="el-icon-refresh" |
| | | :loading="syncingTaskStatus" |
| | | @click="syncTaskStatus" |
| | | >同步任务状态到旧系统</el-button> |
| | | <el-tag v-else type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 请先同步调度单 |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- 支付信息(仅急救转运任务显示) --> |
| | | <el-card v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && paymentInfo" class="box-card" style="margin-top: 20px;"> |
| | | <div slot="header" class="clearfix"> |
| | | <span>支付信息</span> |
| | | <!-- 已完成且未申请发票时显示申请发票按钮 --> |
| | | <el-button |
| | | v-if="canApplyInvoice" |
| | | style="float: right; padding: 3px 0" |
| | | type="text" |
| | | @click="handleApplyInvoice" |
| | | v-hasPermi="['system:invoice:add']" |
| | | > |
| | | <i class="el-icon-document-add"></i> 申请发票 |
| | | </el-button> |
| | | </div> |
| | | |
| | | <!-- 支付概览 --> |
| | | <el-descriptions :column="3" border> |
| | | <el-descriptions-item label="基本价格"> |
| | | <span style="color: #409EFF; font-weight: bold;">¥{{ paymentInfo.transferPrice || '0.00' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="附加费用总额"> |
| | | <span style="color: #E6A23C; font-weight: bold;">¥{{ paymentInfo.additionalAmount || '0.00' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="总金额"> |
| | | <span style="color: #67C23A; font-weight: bold;">¥{{ paymentInfo.totalAmount || '0.00' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="已支付金额"> |
| | | <span style="color: #67C23A; font-weight: bold;">¥{{ paymentInfo.paidAmount || '0.00' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="剩余未付金额"> |
| | | <span style="color: #F56C6C; font-weight: bold;">¥{{ getRemainingAmount() }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="支付状态"> |
| | | <el-tag v-if="getRemainingAmount() <= 0" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 已结清 |
| | | </el-tag> |
| | | <el-tag v-else-if="paymentInfo.paidAmount > 0" type="warning" size="small"> |
| | | <i class="el-icon-warning"></i> 部分支付 |
| | | </el-tag> |
| | | <el-tag v-else type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未支付 |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <!-- 附加费用明细 --> |
| | | <div style="margin-top: 20px;"> |
| | | <h4 style="margin-bottom: 10px;">附加费用明细</h4> |
| | | <el-table :data="paymentInfo.additionalFees" border> |
| | | <el-table-column label="费用类型" align="center" prop="feeType" width="120"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.task_additional_fee_type" :value="scope.row.feeType"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="费用名称" align="center" prop="feeName" /> |
| | | <el-table-column label="单价" align="center" prop="unitAmount" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span>¥{{ scope.row.unitAmount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数量" align="center" prop="quantity" width="80" /> |
| | | <el-table-column label="小计" align="center" prop="totalAmount" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span style="color: #E6A23C; font-weight: bold;">¥{{ scope.row.totalAmount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="同步状态" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.syncStatus === 0" type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未同步 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 1" type="warning" size="small"> |
| | | <i class="el-icon-loading"></i> 同步中 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 2" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 同步成功 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 3" type="danger" size="small"> |
| | | <i class="el-icon-error"></i> 同步失败 |
| | | </el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.remark">{{ scope.row.remark }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 空状态提示 --> |
| | | <div v-if="!paymentInfo.additionalFees || paymentInfo.additionalFees.length === 0" style="text-align: center; padding: 40px 0; color: #909399;"> |
| | | <i class="el-icon-document" style="font-size: 48px; display: block; margin-bottom: 12px;"></i> |
| | | <span>暂无附加费用</span> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 已支付记录 --> |
| | | <div style="margin-top: 20px;"> |
| | | <h4 style="margin-bottom: 10px;">已支付记录</h4> |
| | | <el-table :data="paymentInfo.paidPayments" border> |
| | | <el-table-column label="商户订单号" align="center" prop="outTradeNo" width="200" show-overflow-tooltip /> |
| | | <el-table-column label="支付金额" align="center" prop="settlementAmount" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span style="color: #67C23A; font-weight: bold;">¥{{ scope.row.settlementAmount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="支付方式" align="center" prop="paymentMethod" width="120"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.task_payment_method" :value="scope.row.paymentMethod"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="支付状态" align="center" prop="payStatus" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.payStatus === 'PAID'" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 已支付 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.payStatus === 'PENDING'" type="warning" size="small"> |
| | | <i class="el-icon-time"></i> 待支付 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.payStatus === 'FAILED'" type="danger" size="small"> |
| | | <i class="el-icon-error"></i> 失败 |
| | | </el-tag> |
| | | <el-tag v-else type="info" size="small"> |
| | | {{ scope.row.payStatus }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="交易号" align="center" prop="tradeNo" width="150" show-overflow-tooltip /> |
| | | <el-table-column label="支付时间" align="center" prop="payTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.payTime">{{ parseTime(scope.row.payTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="同步状态" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.syncStatus === 0" type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未同步 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 1" type="warning" size="small"> |
| | | <i class="el-icon-loading"></i> 同步中 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 2" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 同步成功 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 3" type="danger" size="small"> |
| | | <i class="el-icon-error"></i> 同步失败 |
| | | </el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.remark">{{ scope.row.remark }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 空状态提示 --> |
| | | <div v-if="!paymentInfo.paidPayments || paymentInfo.paidPayments.length === 0" style="text-align: center; padding: 40px 0; color: #909399;"> |
| | | <i class="el-icon-document" style="font-size: 48px; display: block; margin-bottom: 12px;"></i> |
| | | <span>暂无支付记录</span> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 福祉车任务扩展信息 --> |
| | | <el-descriptions v-if="taskDetail.taskType === 'WELFARE' && taskDetail.welfareInfo" title="福祉车服务信息" :column="2" border style="margin-top: 20px;"> |
| | |
| | | </el-descriptions> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <div style="margin-top: 20px; text-align: center;"> |
| | | <!-- <div style="margin-top: 20px; text-align: center;"> |
| | | <el-button type="primary" @click="handleEdit" v-hasPermi="['task:general:edit']">编辑任务</el-button> |
| | | <el-button type="success" @click="handleAssign" v-hasPermi="['task:general:assign']">分配任务</el-button> |
| | | <el-button type="warning" @click="handleStatusChange" v-hasPermi="['task:general:status']">状态变更</el-button> |
| | | <el-button type="info" @click="handleVehicleAssign" v-hasPermi="['task:general:assign']">分配车辆</el-button> |
| | | </div> --> |
| | | </el-card> |
| | | |
| | | <!-- 执行人员列表 --> |
| | | <el-card class="box-card" style="margin-top: 20px;"> |
| | | <div slot="header" class="clearfix"> |
| | | <span>执行人员</span> |
| | | </div> |
| | | |
| | | <el-table :data="taskDetail.assignees" v-loading="assigneeLoading"> |
| | | <el-table-column label="序号" align="center" width="60"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.$index + 1 }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="姓名" align="center" prop="userName"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ scope.row.userName }}</span> |
| | | <el-tag v-if="scope.row.isPrimary === '1'" type="warning" size="mini" style="margin-left: 8px;"> |
| | | <i class="el-icon-star-on"></i> 负责人 |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="角色类型" align="center" prop="userType" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.userType === 'driver'" type="primary" size="small">司机</el-tag> |
| | | <el-tag v-else-if="scope.row.userType === 'doctor'" type="success" size="small">医生</el-tag> |
| | | <el-tag v-else-if="scope.row.userType === 'nurse'" type="info" size="small">护士</el-tag> |
| | | <el-tag v-else type="" size="small">{{ scope.row.userType }}</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" align="center" prop="createTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 空状态提示 --> |
| | | <div v-if="!taskDetail.assignees || taskDetail.assignees.length === 0" style="text-align: center; padding: 40px 0; color: #909399;"> |
| | | <i class="el-icon-user" style="font-size: 48px; display: block; margin-bottom: 12px;"></i> |
| | | <span>暂无执行人员</span> |
| | | </div> |
| | | </el-card> |
| | | |
| | |
| | | </div> |
| | | |
| | | <el-table :data="taskDetail.attachments" v-loading="attachmentLoading"> |
| | | <el-table-column label="文件名" align="center" prop="fileName" /> |
| | | <el-table-column label="文件类型" align="center" prop="fileType" /> |
| | | <el-table-column label="文件大小" align="center" prop="fileSize"> |
| | | <el-table-column label="缩略图" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ formatFileSize(scope.row.fileSize) }}</span> |
| | | <el-image |
| | | v-if="isImage(scope.row.fileType)" |
| | | :src="scope.row.fileUrl" |
| | | :preview-src-list="[scope.row.fileUrl]" |
| | | fit="cover" |
| | | style="width: 80px; height: 80px; border-radius: 4px; cursor: pointer;" |
| | | > |
| | | <div slot="error" class="image-slot"> |
| | | <i class="el-icon-picture-outline" style="font-size: 40px; color: #C0C4CC;"></i> |
| | | </div> |
| | | </el-image> |
| | | <div v-else style="text-align: center;"> |
| | | <i class="el-icon-document" style="font-size: 40px; color: #909399;"></i> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="业务分类" align="center" prop="attachmentCategory" width="150"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.sys_attachment_category" :value="scope.row.attachmentCategory"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="同步状态" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.syncedToImageData === 0" type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未同步 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncedToImageData === 1" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 已同步 |
| | | </el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="上传时间" align="center" prop="uploadTime" width="180"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | |
| | | <!-- 附加费用列表 --> |
| | | <el-card class="box-card" style="margin-top: 20px;"> |
| | | <div slot="header" class="clearfix"> |
| | | <span>附加费用列表</span> |
| | | </div> |
| | | |
| | | <el-table :data="additionalFeeList" v-loading="feeLoading"> |
| | | <el-table-column label="费用类型" align="center" prop="feeType" width="120"> |
| | | <template slot-scope="scope"> |
| | | <dict-tag :options="dict.type.task_additional_fee_type" :value="scope.row.feeType"/> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="费用名称" align="center" prop="feeName" /> |
| | | <el-table-column label="单价" align="center" prop="unitAmount" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span>¥{{ scope.row.unitAmount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="数量" align="center" prop="quantity" width="80" /> |
| | | <el-table-column label="总金额" align="center" prop="totalAmount" width="120"> |
| | | <template slot-scope="scope"> |
| | | <span style="color: #E6A23C; font-weight: bold;">¥{{ scope.row.totalAmount }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="同步状态" align="center" width="120"> |
| | | <template slot-scope="scope"> |
| | | <el-tag v-if="scope.row.syncStatus === 0" type="info" size="small"> |
| | | <i class="el-icon-warning"></i> 未同步 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 1" type="warning" size="small"> |
| | | <i class="el-icon-loading"></i> 同步中 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 2" type="success" size="small"> |
| | | <i class="el-icon-success"></i> 同步成功 |
| | | </el-tag> |
| | | <el-tag v-else-if="scope.row.syncStatus === 3" type="danger" size="small"> |
| | | <i class="el-icon-error"></i> 同步失败 |
| | | </el-tag> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="同步时间" align="center" prop="syncTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.syncTime">{{ parseTime(scope.row.syncTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建时间" align="center" prop="createdTime" width="180"> |
| | | <template slot-scope="scope"> |
| | | <span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="创建者" align="center" prop="createdBy" width="100" /> |
| | | <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip> |
| | | <template slot-scope="scope"> |
| | | <span v-if="scope.row.remark">{{ scope.row.remark }}</span> |
| | | <span v-else style="color: #C0C4CC;">--</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <!-- 空状态提示 --> |
| | | <div v-if="!additionalFeeList || additionalFeeList.length === 0" style="text-align: center; padding: 40px 0; color: #909399;"> |
| | | <i class="el-icon-document" style="font-size: 48px; display: block; margin-bottom: 12px;"></i> |
| | | <span>暂无附加费用</span> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 操作日志 --> |
| | |
| | | </el-dialog> |
| | | |
| | | <!-- 上传附件对话框 --> |
| | | <el-dialog title="上传附件" :visible.sync="uploadOpen" width="500px" append-to-body> |
| | | <el-upload |
| | | class="upload-demo" |
| | | drag |
| | | :action="uploadUrl" |
| | | :headers="uploadHeaders" |
| | | :data="uploadData" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | :before-upload="beforeUpload" |
| | | multiple> |
| | | <i class="el-icon-upload"></i> |
| | | <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
| | | <div class="el-upload__tip" slot="tip">只能上传jpg/png/pdf/doc/docx文件,且不超过10MB</div> |
| | | </el-upload> |
| | | <el-dialog title="上传附件" :visible.sync="uploadOpen" width="500px" append-to-body @close="cancelUpload"> |
| | | <el-form ref="uploadForm" :model="uploadForm" :rules="uploadRules" label-width="100px"> |
| | | <el-form-item label="业务分类" prop="category"> |
| | | <el-select v-model="uploadForm.category" placeholder="请选择业务分类" clearable style="width: 100%;"> |
| | | <el-option |
| | | v-for="dict in dict.type.sys_attachment_category" |
| | | :key="dict.value" |
| | | :label="dict.label" |
| | | :value="dict.value" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="附件" prop="files"> |
| | | <el-upload |
| | | ref="upload" |
| | | class="upload-demo" |
| | | :action="uploadUrl" |
| | | :headers="uploadHeaders" |
| | | :data="uploadData" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | :before-upload="beforeUpload" |
| | | :file-list="fileList" |
| | | :auto-upload="false" |
| | | multiple |
| | | drag> |
| | | <i class="el-icon-upload"></i> |
| | | <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> |
| | | <div class="el-upload__tip" slot="tip">只能上传jpg/png/pdf/doc/docx文件,且不超过100MB</div> |
| | | </el-upload> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div slot="footer" class="dialog-footer"> |
| | | <el-button type="primary" @click="submitUpload">确 定</el-button> |
| | | <el-button @click="cancelUpload">取 消</el-button> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getTask, updateTask, assignTask, changeTaskStatus, uploadAttachment, deleteAttachment, getTaskVehicles, getAvailableVehicles, assignVehiclesToTask, unassignVehicleFromTask } from "@/api/task"; |
| | | import { getTask, updateTask, assignTask, changeTaskStatus, uploadAttachment, deleteAttachment, getTaskVehicles, getAvailableVehicles, assignVehiclesToTask, unassignVehicleFromTask, getPaymentInfo, syncServiceOrder, syncDispatchOrder, syncTaskStatus, syncFromLegacySystem, checkTaskInvoice } from "@/api/task"; |
| | | import { listUser } from "@/api/system/user"; |
| | | import { getToken } from "@/utils/auth"; |
| | | |
| | | export default { |
| | | name: "TaskDetail", |
| | | dicts: ['sys_task_type', 'sys_task_status', 'sys_vehicle_type', 'sys_task_vehicle_status', 'sys_user_sex', 'hospital_department'], |
| | | dicts: ['sys_task_type', 'sys_task_status', 'sys_vehicle_type', 'sys_task_vehicle_status', 'sys_user_sex', 'hospital_department', 'sys_attachment_category', 'task_additional_fee_type', 'task_payment_method'], |
| | | data() { |
| | | return { |
| | | // 任务详情 |
| | |
| | | vehicleAssignOpen: false, |
| | | // 是否显示上传对话框 |
| | | uploadOpen: false, |
| | | // 上传表单 |
| | | uploadForm: { |
| | | category: null |
| | | }, |
| | | // 文件列表 |
| | | fileList: [], |
| | | // 编辑表单 |
| | | editForm: {}, |
| | | // 分配表单 |
| | |
| | | // 加载状态 |
| | | vehicleLoading: false, |
| | | attachmentLoading: false, |
| | | feeLoading: false, |
| | | assigneeLoading: false, |
| | | // 附加费用列表 |
| | | additionalFeeList: [], |
| | | // 支付信息 |
| | | paymentInfo: null, |
| | | // 上传相关 |
| | | uploadUrl: process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + this.$route.params.taskId, |
| | | uploadUrl: process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + (new URLSearchParams(window.location.search).get('taskId') || ''), |
| | | uploadHeaders: { |
| | | Authorization: "Bearer " + getToken() |
| | | }, |
| | |
| | | vehicleIds: [ |
| | | { required: true, message: "车辆不能为空", trigger: "change" } |
| | | ] |
| | | } |
| | | }, |
| | | uploadRules: { |
| | | category: [ |
| | | { required: true, message: "业务分类不能为空", trigger: "change" } |
| | | ] |
| | | }, |
| | | // 同步加载状态 |
| | | syncingServiceOrder: false, |
| | | syncingDispatchOrder: false, |
| | | syncingFromLegacy: false, |
| | | syncingTaskStatus: false, |
| | | // 发票申请状态 |
| | | hasInvoiceApplied: false, |
| | | invoiceStatus: null // 0-待审核, 1-已通过, 2-已驳回 |
| | | }; |
| | | }, |
| | | created() { |
| | | this.getTaskDetail(); |
| | | this.getUserList(); |
| | | this.getAdditionalFeeList(); |
| | | // 初始化上传URL |
| | | this.uploadUrl = process.env.VUE_APP_BASE_API + "/task/attachment/upload/" + this.$route.params.taskId; |
| | | // 检查发票申请状态 |
| | | this.checkInvoiceStatus(); |
| | | }, |
| | | computed: { |
| | | /** 是否可以申请发票 */ |
| | | canApplyInvoice() { |
| | | // 只有急救转运任务 |
| | | if (this.taskDetail.taskType !== 'EMERGENCY_TRANSFER') return false; |
| | | // 任务必须已完成 |
| | | if (this.taskDetail.taskStatus !== 'COMPLETED') return false; |
| | | // 未申请过发票,或者曾被驳回 |
| | | return !this.hasInvoiceApplied || this.invoiceStatus === 2; |
| | | } |
| | | }, |
| | | methods: { |
| | | /** 获取任务详情 */ |
| | | getTaskDetail() { |
| | | getTask(this.$route.params.taskId).then(response => { |
| | | this.taskDetail = response.data; |
| | | // 任务详情加载完成后,加载支付信息 |
| | | // console.log("TaskDetail", this.taskDetail); |
| | | this.loadPaymentInfo(); |
| | | }); |
| | | }, |
| | | /** 获取附加费用列表 */ |
| | | getAdditionalFeeList() { |
| | | this.feeLoading = true; |
| | | getPaymentInfo(this.$route.params.taskId).then(response => { |
| | | this.additionalFeeList = response.data.additionalFees || []; |
| | | this.feeLoading = false; |
| | | }).catch(() => { |
| | | this.feeLoading = false; |
| | | }); |
| | | }, |
| | | /** 加载支付信息 */ |
| | | loadPaymentInfo() { |
| | | //EMERGENCY_TRANSFER |
| | | if (this.taskDetail.taskType === 'EMERGENCY_TRANSFER') { |
| | | getPaymentInfo(this.$route.params.taskId).then(response => { |
| | | // console.log("PaymentInfo", response.data); |
| | | this.paymentInfo = response.data; |
| | | }).catch(() => { |
| | | this.paymentInfo = null; |
| | | }); |
| | | } |
| | | }, |
| | | /** 计算剩余未付金额 */ |
| | | getRemainingAmount() { |
| | | if (!this.paymentInfo) return '0.00'; |
| | | const total = parseFloat(this.paymentInfo.totalAmount || 0); |
| | | const paid = parseFloat(this.paymentInfo.paidAmount || 0); |
| | | const remaining = total - paid; |
| | | return remaining > 0 ? remaining.toFixed(2) : '0.00'; |
| | | }, |
| | | /** 获取用户列表 */ |
| | | getUserList() { |
| | |
| | | }, |
| | | /** 上传附件 */ |
| | | handleUpload() { |
| | | this.uploadForm = { |
| | | category: null |
| | | }; |
| | | this.fileList = []; |
| | | this.uploadOpen = true; |
| | | }, |
| | | /** 取消车辆分配 */ |
| | |
| | | }, |
| | | /** 上传前检查 */ |
| | | beforeUpload(file) { |
| | | // 检查是否选择了业务分类 |
| | | if (!this.uploadForm.category) { |
| | | this.$message.error('请先选择业务分类!'); |
| | | return false; |
| | | } |
| | | |
| | | // 更新uploadData,确保每次上传都带有category参数 |
| | | this.uploadData = { |
| | | category: this.uploadForm.category |
| | | }; |
| | | |
| | | const isValidType = ['image/jpeg', 'image/png', 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'].includes(file.type); |
| | | const isLt10M = file.size / 1024 / 1024 < 10; |
| | | const isLt10M = file.size / 1024 / 1024 < 100; |
| | | |
| | | if (!isValidType) { |
| | | this.$message.error('只能上传 JPG/PNG/PDF/DOC/DOCX 格式的文件!'); |
| | | return false; |
| | | } |
| | | if (!isLt10M) { |
| | | this.$message.error('上传文件大小不能超过 10MB!'); |
| | | this.$message.error('上传文件大小不能超过 100MB!'); |
| | | return false; |
| | | } |
| | | return isValidType && isLt10M; |
| | | return true; |
| | | }, |
| | | /** 提交上传 */ |
| | | submitUpload() { |
| | | this.$refs["uploadForm"].validate(valid => { |
| | | if (valid) { |
| | | // 检查是否选择了文件 |
| | | const fileList = this.$refs.upload.uploadFiles; |
| | | if (!fileList || fileList.length === 0) { |
| | | this.$message.warning('请选择要上传的文件'); |
| | | return; |
| | | } |
| | | |
| | | // 触发上传 |
| | | this.$refs.upload.submit(); |
| | | } |
| | | }); |
| | | }, |
| | | /** 取消上传 */ |
| | | cancelUpload() { |
| | | this.uploadOpen = false; |
| | | this.uploadForm = { |
| | | category: null |
| | | }; |
| | | this.fileList = []; |
| | | if (this.$refs.upload) { |
| | | this.$refs.upload.clearFiles(); |
| | | } |
| | | }, |
| | | /** 上传成功 */ |
| | | handleUploadSuccess(response, file, fileList) { |
| | | this.$modal.msgSuccess("上传成功"); |
| | | this.uploadOpen = false; |
| | | this.getTaskDetail(); |
| | | // 检查是否所有文件都上传完成 |
| | | const allDone = fileList.every(f => f.status === 'success' || f.status === 'fail'); |
| | | |
| | | if (allDone) { |
| | | this.$modal.msgSuccess("上传成功"); |
| | | this.cancelUpload(); |
| | | this.getTaskDetail(); |
| | | } |
| | | }, |
| | | /** 上传失败 */ |
| | | handleUploadError(err, file, fileList) { |
| | |
| | | return typeItem ? typeItem.label : vehicleType; |
| | | } |
| | | return vehicleType; |
| | | }, |
| | | /** 判断是否为图片类型 */ |
| | | isImage(fileType) { |
| | | if (!fileType) return false; |
| | | const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']; |
| | | return imageTypes.includes(fileType.toLowerCase()); |
| | | }, |
| | | /** 手动同步服务单 */ |
| | | syncServiceOrder() { |
| | | this.$modal.confirm('是否确认同步服务单到旧系统?').then(() => { |
| | | this.syncingServiceOrder = true; |
| | | return syncServiceOrder(this.taskDetail.taskId); |
| | | }).then(() => { |
| | | this.$modal.msgSuccess("服务单同步成功"); |
| | | // 重新加载任务详情 |
| | | this.getTaskDetail(); |
| | | }).catch(() => { |
| | | // 处理取消和错误 |
| | | }).finally(() => { |
| | | this.syncingServiceOrder = false; |
| | | }); |
| | | }, |
| | | /** 手动同步调度单 */ |
| | | syncDispatchOrder() { |
| | | this.$modal.confirm('是否确认同步调度单到旧系统?').then(() => { |
| | | this.syncingDispatchOrder = true; |
| | | return syncDispatchOrder(this.taskDetail.taskId); |
| | | }).then(() => { |
| | | this.$modal.msgSuccess("调度单同步成功"); |
| | | // 重新加载任务详情 |
| | | this.getTaskDetail(); |
| | | }).catch(() => { |
| | | // 处理取消和错误 |
| | | }).finally(() => { |
| | | this.syncingDispatchOrder = false; |
| | | }); |
| | | }, |
| | | /** 从旧系统同步数据到新系统 */ |
| | | syncFromLegacySystem() { |
| | | // 检查是否同时有serviceOrdID和dispatchOrdID |
| | | if (!this.taskDetail.emergencyInfo.legacyServiceOrdId || !this.taskDetail.emergencyInfo.legacyDispatchOrdId) { |
| | | this.$modal.msgError("缺少必要的旧系统ID信息"); |
| | | return; |
| | | } |
| | | |
| | | this.$modal.confirm('是否确认从旧系统同步数据到新系统?').then(() => { |
| | | this.syncingFromLegacy = true; |
| | | return syncFromLegacySystem( |
| | | this.taskDetail.emergencyInfo.legacyServiceOrdId, |
| | | this.taskDetail.emergencyInfo.legacyDispatchOrdId |
| | | ); |
| | | }).then(() => { |
| | | this.$modal.msgSuccess("从旧系统同步成功"); |
| | | // 重新加载任务详情 |
| | | this.getTaskDetail(); |
| | | }).catch((error) => { |
| | | if (error !== 'cancel') { |
| | | this.$modal.msgError("同步失败: " + (error.message || "未知错误")); |
| | | } |
| | | }).finally(() => { |
| | | this.syncingFromLegacy = false; |
| | | }); |
| | | }, |
| | | /** 手动同步任务状态 */ |
| | | syncTaskStatus() { |
| | | this.$modal.confirm('是否确认同步任务状态到旧系统?').then(() => { |
| | | this.syncingTaskStatus = true; |
| | | return syncTaskStatus(this.taskDetail.taskId); |
| | | }).then(() => { |
| | | this.$modal.msgSuccess("任务状态同步成功"); |
| | | // 重新加载任务详情 |
| | | this.getTaskDetail(); |
| | | }).catch(() => { |
| | | // 处理取消和错误 |
| | | }).finally(() => { |
| | | this.syncingTaskStatus = false; |
| | | }); |
| | | }, |
| | | |
| | | /** 检查发票申请状态 */ |
| | | checkInvoiceStatus() { |
| | | // 调用后端接口检查该任务是否已申请发票 |
| | | checkTaskInvoice(this.$route.params.taskId) |
| | | .then(response => { |
| | | if (response.code === 200 && response.data) { |
| | | this.hasInvoiceApplied = true; |
| | | this.invoiceStatus = response.data.status; |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | // 忽略错误,默认未申请 |
| | | }); |
| | | }, |
| | | |
| | | /** 申请发票 */ |
| | | handleApplyInvoice() { |
| | | // 跳转到发票申请页面,带上任务信息 |
| | | const taskInfo = { |
| | | taskId: this.taskDetail.taskId, |
| | | taskCode: this.taskDetail.taskCode || this.taskDetail.showTaskCode, |
| | | legacyServiceOrderId: this.taskDetail.emergencyInfo?.legacyServiceOrdId, |
| | | serviceCode: this.taskDetail.emergencyInfo?.serviceCode, |
| | | departure: this.taskDetail.departureAddress, |
| | | destination: this.taskDetail.destinationAddress, |
| | | completionTime: this.parseTime(this.taskDetail.actualEndTime), |
| | | transferPrice: this.paymentInfo?.transferPrice || this.paymentInfo?.totalAmount |
| | | }; |
| | | |
| | | // 将任务信息存储到 sessionStorage |
| | | sessionStorage.setItem('invoiceTaskInfo', JSON.stringify(taskInfo)); |
| | | |
| | | // 跳转到发票申请页面 |
| | | this.$router.push({ |
| | | path: '/system/invoice/apply', |
| | | query: { taskId: this.taskDetail.taskId } |
| | | }); |
| | | } |
| | | } |
| | | }; |