<template>
|
<view class="transport-edit-container">
|
<!-- 表单内容 -->
|
<scroll-view scroll-y class="form-scroll" :show-scrollbar="false">
|
<view class="form-content">
|
<!-- 基础信息卡片 -->
|
<view class="form-section">
|
<view class="section-header">
|
<view class="section-icon">📋</view>
|
<text class="section-title">基础信息</text>
|
</view>
|
|
<view class="form-grid">
|
<view class="form-item">
|
<text class="item-label required">案例选择</text>
|
<u-input
|
v-model="form.caseInfo.donorName"
|
placeholder="选择案例"
|
readonly
|
border="none"
|
@click="showCasePicker = true"
|
:customStyle="inputStyle(!form.caseInfo.caseId)"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label required">捐献医院</text>
|
<u-input
|
v-model="form.hospital"
|
placeholder="请输入捐献医院"
|
border="none"
|
:customStyle="inputStyle(!form.hospital)"
|
/>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label">科室</text>
|
<u-input
|
v-model="form.department"
|
placeholder="请输入科室"
|
border="none"
|
/>
|
</view>
|
</view>
|
</view>
|
|
<!-- 转运信息卡片 -->
|
<view class="form-section">
|
<view class="section-header">
|
<view class="section-icon">🚑</view>
|
<text class="section-title">转运信息</text>
|
</view>
|
|
<view class="form-grid">
|
<view class="form-item">
|
<text class="item-label required">出发时间</text>
|
<u-input
|
v-model="form.departureTime"
|
placeholder="请选择出发时间"
|
readonly
|
border="none"
|
@click="showTimePicker = true"
|
:customStyle="inputStyle(!form.departureTime)"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
|
<view class="form-item full-width">
|
<text class="item-label">出发地点</text>
|
<u-textarea
|
v-model="form.departureLocation"
|
placeholder="请输入出发地点详细地址"
|
count
|
maxlength="200"
|
height="120"
|
/>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label">抵达医院</text>
|
<u-input
|
v-model="form.destinationHospital"
|
placeholder="请输入抵达医院"
|
border="none"
|
/>
|
</view>
|
</view>
|
</view>
|
|
<!-- 团队成员卡片 -->
|
<view class="form-section">
|
<view class="section-header">
|
<view class="section-icon">👥</view>
|
<text class="section-title">团队成员</text>
|
</view>
|
|
<view class="form-grid">
|
<view class="form-item">
|
<text class="item-label">协调员</text>
|
<u-input
|
v-model="form.coordinator.name"
|
placeholder="选择协调员"
|
readonly
|
border="none"
|
@click="showCoordinatorPicker = true"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label">急诊科医生</text>
|
<u-input
|
v-model="form.emergencyDoctor.name"
|
placeholder="选择急诊科医生"
|
readonly
|
border="none"
|
@click="showDoctorPicker = true"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label">护士</text>
|
<u-input
|
v-model="form.nurse.name"
|
placeholder="选择护士"
|
readonly
|
border="none"
|
@click="showNursePicker = true"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label">司机</text>
|
<u-input
|
v-model="form.driver.name"
|
placeholder="选择司机"
|
readonly
|
border="none"
|
@click="showDriverPicker = true"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
|
<view class="form-item">
|
<text class="item-label">ICU评估医生</text>
|
<u-input
|
v-model="form.icuDoctor.name"
|
placeholder="选择ICU评估医生"
|
readonly
|
border="none"
|
@click="showIcuDoctorPicker = true"
|
>
|
<template #suffix>
|
<u-icon name="arrow-down" color="#86868b"></u-icon>
|
</template>
|
</u-input>
|
</view>
|
</view>
|
</view>
|
|
<!-- 联系方式卡片 -->
|
<view class="form-section">
|
<view class="section-header">
|
<view class="section-icon">📞</view>
|
<text class="section-title">联系方式</text>
|
</view>
|
|
<view class="form-grid">
|
<view class="form-item" v-for="(contact, index) in form.contacts" :key="index">
|
<text class="item-label">{{ contact.role }}</text>
|
<u-input
|
v-model="contact.phone"
|
placeholder="请输入联系电话"
|
border="none"
|
type="number"
|
/>
|
</view>
|
</view>
|
</view>
|
|
<!-- 备注信息卡片 -->
|
<view class="form-section">
|
<view class="section-header">
|
<view class="section-icon">📝</view>
|
<text class="section-title">备注信息</text>
|
</view>
|
|
<view class="form-grid">
|
<view class="form-item full-width">
|
<u-textarea
|
v-model="form.remarks"
|
placeholder="请输入特殊要求或备注信息"
|
count
|
maxlength="500"
|
height="200"
|
/>
|
</view>
|
</view>
|
</view>
|
|
<!-- 操作按钮 -->
|
<view class="action-buttons">
|
<u-button class="btn secondary" @click="handleCancel">取消</u-button>
|
<u-button class="btn primary" @click="handleSaveDraft">保存草稿</u-button>
|
<u-button class="btn success" @click="handleSubmit" :disabled="!isFormValid">提交申请</u-button>
|
</view>
|
</view>
|
</scroll-view>
|
|
<!-- 选择器组件 -->
|
<u-picker
|
:show="showCasePicker"
|
:columns="[caseOptions]"
|
keyName="label"
|
@confirm="onCaseConfirm"
|
@cancel="showCasePicker = false"
|
title="选择案例"
|
></u-picker>
|
|
<u-datetime-picker
|
:show="showTimePicker"
|
v-model="departureTimeValue"
|
mode="datetime"
|
@confirm="onTimeConfirm"
|
@cancel="showTimePicker = false"
|
title="选择出发时间"
|
></u-datetime-picker>
|
|
<u-picker
|
:show="showCoordinatorPicker"
|
:columns="[coordinatorOptions]"
|
keyName="label"
|
@confirm="onCoordinatorConfirm"
|
@cancel="showCoordinatorPicker = false"
|
title="选择协调员"
|
></u-picker>
|
|
<u-picker
|
:show="showDoctorPicker"
|
:columns="[doctorOptions]"
|
keyName="label"
|
@confirm="onDoctorConfirm"
|
@cancel="showDoctorPicker = false"
|
title="选择急诊科医生"
|
></u-picker>
|
|
<u-picker
|
:show="showNursePicker"
|
:columns="[nurseOptions]"
|
keyName="label"
|
@confirm="onNurseConfirm"
|
@cancel="showNursePicker = false"
|
title="选择护士"
|
></u-picker>
|
|
<u-picker
|
:show="showDriverPicker"
|
:columns="[driverOptions]"
|
keyName="label"
|
@confirm="onDriverConfirm"
|
@cancel="showDriverPicker = false"
|
title="选择司机"
|
></u-picker>
|
|
<u-picker
|
:show="showIcuDoctorPicker"
|
:columns="[icuDoctorOptions]"
|
keyName="label"
|
@confirm="onIcuDoctorConfirm"
|
@cancel="showIcuDoctorPicker = false"
|
title="选择ICU评估医生"
|
></u-picker>
|
|
<!-- 加载状态 -->
|
<u-loading-icon :show="loading" text="提交中..."></u-loading-icon>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed, onMounted } from 'vue'
|
import { onLoad } from '@dcloudio/uni-app'
|
|
// 表单数据
|
const form = reactive({
|
caseInfo: {
|
caseId: '',
|
donorName: '',
|
gender: '',
|
age: '',
|
diagnosis: ''
|
},
|
hospital: '',
|
department: '',
|
departureTime: '',
|
departureLocation: '',
|
destinationHospital: '',
|
coordinator: { id: '', name: '' },
|
emergencyDoctor: { id: '', name: '' },
|
nurse: { id: '', name: '' },
|
driver: { id: '', name: '' },
|
icuDoctor: { id: '', name: '' },
|
contacts: [
|
{ role: '协调员电话', phone: '' },
|
{ role: '急诊医生电话', phone: '' },
|
{ role: '护士电话', phone: '' },
|
{ role: '司机电话', phone: '' },
|
{ role: 'ICU医生电话', phone: '' }
|
],
|
remarks: ''
|
})
|
|
// 选择器状态
|
const showCasePicker = ref(false)
|
const showTimePicker = ref(false)
|
const showCoordinatorPicker = ref(false)
|
const showDoctorPicker = ref(false)
|
const showNursePicker = ref(false)
|
const showDriverPicker = ref(false)
|
const showIcuDoctorPicker = ref(false)
|
const departureTimeValue = ref(0)
|
|
// 选项数据
|
const caseOptions = ref([
|
{
|
label: '张三 - 脑外伤导致脑死亡 - 青岛镜湖医院',
|
value: 'DON20241216001',
|
data: {
|
donorName: '张三',
|
gender: '男',
|
age: '38',
|
diagnosis: '脑外伤导致脑死亡',
|
hospital: '青岛镜湖医院'
|
}
|
},
|
{
|
label: '李四 - 脑梗死 - 青岛大学附属医院',
|
value: 'DON20241216002',
|
data: {
|
donorName: '李四',
|
gender: '女',
|
age: '45',
|
diagnosis: '脑梗死',
|
hospital: '青岛大学附属医院'
|
}
|
}
|
])
|
|
const coordinatorOptions = ref([
|
{ label: '张医生', value: '1' },
|
{ label: '李医生', value: '2' },
|
{ label: '王医生', value: '3' }
|
])
|
|
const doctorOptions = ref([
|
{ label: '赵医生', value: '1' },
|
{ label: '钱医生', value: '2' },
|
{ label: '孙医生', value: '3' }
|
])
|
|
const nurseOptions = ref([
|
{ label: '周护士', value: '1' },
|
{ label: '吴护士', value: '2' },
|
{ label: '郑护士', value: '3' }
|
])
|
|
const driverOptions = ref([
|
{ label: '刘师傅', value: '1' },
|
{ label: '陈师傅', value: '2' },
|
{ label: '杨师傅', value: '3' }
|
])
|
|
const icuDoctorOptions = ref([
|
{ label: '朱医生', value: '1' },
|
{ label: '秦医生', value: '2' },
|
{ label: '尤医生', value: '3' }
|
])
|
|
// 状态管理
|
const loading = ref(false)
|
const isEdit = ref(false)
|
const transportId = ref('')
|
const disabledColor = ref('#f5f5f7')
|
|
// 计算属性
|
const isFormValid = computed(() => {
|
return form.caseInfo.caseId && form.hospital && form.departureTime
|
})
|
|
// 样式方法
|
const inputStyle = (isError) => {
|
return isError ?
|
'border: 2rpx solid #ff4757 !important; border-radius: 12rpx !important;' :
|
'border: 2rpx solid #e5e5e7 !important; border-radius: 12rpx !important;'
|
}
|
|
// 方法定义
|
const onCaseConfirm = (e) => {
|
if (e.value && e.value[0]) {
|
const selectedCase = e.value[0]
|
form.caseInfo.caseId = selectedCase.value
|
form.caseInfo.donorName = selectedCase.data.donorName
|
form.caseInfo.gender = selectedCase.data.gender
|
form.caseInfo.age = selectedCase.data.age
|
form.caseInfo.diagnosis = selectedCase.data.diagnosis
|
form.hospital = selectedCase.data.hospital
|
}
|
showCasePicker.value = false
|
}
|
|
const onTimeConfirm = (e) => {
|
const date = new Date(e.value)
|
form.departureTime = `${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')}`
|
showTimePicker.value = false
|
}
|
|
const onCoordinatorConfirm = (e) => {
|
if (e.value && e.value[0]) {
|
form.coordinator.name = e.value[0].label
|
form.coordinator.id = e.value[0].value
|
// 自动填充协调员电话
|
const contact = form.contacts.find(item => item.role === '协调员电话')
|
if (contact) {
|
contact.phone = '13800138000' // 模拟数据
|
}
|
}
|
showCoordinatorPicker.value = false
|
}
|
|
const onDoctorConfirm = (e) => {
|
if (e.value && e.value[0]) {
|
form.emergencyDoctor.name = e.value[0].label
|
form.emergencyDoctor.id = e.value[0].value
|
// 自动填充急诊医生电话
|
const contact = form.contacts.find(item => item.role === '急诊医生电话')
|
if (contact) {
|
contact.phone = '13800138001' // 模拟数据
|
}
|
}
|
showDoctorPicker.value = false
|
}
|
|
const onNurseConfirm = (e) => {
|
if (e.value && e.value[0]) {
|
form.nurse.name = e.value[0].label
|
form.nurse.id = e.value[0].value
|
// 自动填充护士电话
|
const contact = form.contacts.find(item => item.role === '护士电话')
|
if (contact) {
|
contact.phone = '13800138002' // 模拟数据
|
}
|
}
|
showNursePicker.value = false
|
}
|
|
const onDriverConfirm = (e) => {
|
if (e.value && e.value[0]) {
|
form.driver.name = e.value[0].label
|
form.driver.id = e.value[0].value
|
// 自动填充司机电话
|
const contact = form.contacts.find(item => item.role === '司机电话')
|
if (contact) {
|
contact.phone = '13800138003' // 模拟数据
|
}
|
}
|
showDriverPicker.value = false
|
}
|
|
const onIcuDoctorConfirm = (e) => {
|
if (e.value && e.value[0]) {
|
form.icuDoctor.name = e.value[0].label
|
form.icuDoctor.id = e.value[0].value
|
// 自动填充ICU医生电话
|
const contact = form.contacts.find(item => item.role === 'ICU医生电话')
|
if (contact) {
|
contact.phone = '13800138004' // 模拟数据
|
}
|
}
|
showIcuDoctorPicker.value = false
|
}
|
|
const handleCancel = () => {
|
uni.navigateBack()
|
}
|
|
const validateForm = () => {
|
if (!form.caseInfo.caseId) {
|
uni.showToast({ title: '请选择案例', icon: 'none' })
|
return false
|
}
|
if (!form.hospital) {
|
uni.showToast({ title: '请输入捐献医院', icon: 'none' })
|
return false
|
}
|
if (!form.departureTime) {
|
uni.showToast({ title: '请选择出发时间', icon: 'none' })
|
return false
|
}
|
return true
|
}
|
|
const handleSaveDraft = async () => {
|
if (!validateForm()) return
|
|
loading.value = true
|
try {
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
await saveTransport('draft')
|
uni.showToast({ title: '保存草稿成功', icon: 'success' })
|
} catch (error) {
|
console.error('保存草稿失败:', error)
|
uni.showToast({ title: '保存失败,请重试', icon: 'none' })
|
} finally {
|
loading.value = false
|
}
|
}
|
|
const handleSubmit = async () => {
|
if (!validateForm()) return
|
|
uni.showModal({
|
title: '确认提交',
|
content: '确定要提交转运单申请吗?',
|
success: async (res) => {
|
if (res.confirm) {
|
loading.value = true
|
try {
|
await new Promise(resolve => setTimeout(resolve, 1500))
|
await saveTransport('pending')
|
uni.showToast({ title: '提交成功', icon: 'success' })
|
setTimeout(() => {
|
uni.navigateBack()
|
}, 1500)
|
} catch (error) {
|
console.error('提交失败:', error)
|
uni.showToast({ title: '提交失败,请重试', icon: 'none' })
|
} finally {
|
loading.value = false
|
}
|
}
|
}
|
})
|
}
|
|
const saveTransport = async (status) => {
|
const submitData = {
|
...form,
|
status: status,
|
id: isEdit.value ? transportId.value : generateTransportId(),
|
createTime: new Date().toISOString()
|
}
|
|
console.log('保存转运单:', submitData)
|
// 实际项目中调用API接口
|
}
|
|
const generateTransportId = () => {
|
const date = new Date()
|
return `T${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, '0')}${date.getDate().toString().padStart(2, '0')}${Math.random().toString().slice(-3)}`
|
}
|
|
const loadTransportData = (id) => {
|
// 模拟加载编辑数据
|
const mockData = {
|
caseInfo: {
|
caseId: 'DON20241216001',
|
donorName: '张三',
|
gender: '男',
|
age: '38',
|
diagnosis: '脑外伤导致脑死亡'
|
},
|
hospital: '青岛镜湖医院',
|
department: '神经外科',
|
departureTime: '2024-12-17 14:30:00',
|
departureLocation: '青岛市立医院急诊科',
|
destinationHospital: '青岛镜湖医院',
|
coordinator: { id: '1', name: '张医生' },
|
emergencyDoctor: { id: '2', name: '王医生' },
|
nurse: { id: '3', name: '李护士' },
|
driver: { id: '4', name: '刘师傅' },
|
icuDoctor: { id: '5', name: '赵医生' },
|
contacts: [
|
{ role: '协调员电话', phone: '13800138000' },
|
{ role: '急诊医生电话', phone: '13800138001' },
|
{ role: '护士电话', phone: '13800138002' },
|
{ role: '司机电话', phone: '13800138003' },
|
{ role: 'ICU医生电话', phone: '13800138004' }
|
],
|
remarks: '需要准备呼吸机等急救设备'
|
}
|
|
Object.assign(form, mockData)
|
}
|
|
// 生命周期
|
onLoad((options) => {
|
if (options.id) {
|
isEdit.value = true
|
transportId.value = options.id
|
loadTransportData(options.id)
|
}
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.transport-edit-container {
|
min-height: 100vh;
|
background: linear-gradient(135deg, #f8fdff 0%, #e8f7f6 100%);
|
}
|
|
.form-scroll {
|
height: 100vh;
|
}
|
|
.form-content {
|
padding: 30rpx;
|
}
|
|
.form-section {
|
background: #fff;
|
border-radius: 20rpx;
|
padding: 30rpx;
|
margin-bottom: 30rpx;
|
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
|
}
|
|
.section-header {
|
display: flex;
|
// align-items: center;
|
margin-bottom: 30rpx;
|
padding-bottom: 20rpx;
|
border-bottom: 2rpx solid #f0f0f0;
|
}
|
|
.section-icon {
|
font-size: 32rpx;
|
margin-right: 16rpx;
|
}
|
|
.section-title {
|
font-size: 32rpx;
|
font-weight: 600;
|
color: #1d1d1f;
|
}
|
|
.form-grid {
|
display: flex;
|
flex-direction: column;
|
gap: 24rpx;
|
}
|
|
.form-item {
|
display: flex;
|
flex-direction: column;
|
|
&.full-width {
|
grid-column: 1 / -1;
|
}
|
}
|
|
.item-label {
|
font-size: 28rpx;
|
color: #1d1d1f;
|
font-weight: 500;
|
margin-bottom: 12rpx;
|
|
&.required::after {
|
content: '*';
|
color: #ff4757;
|
margin-left: 4rpx;
|
}
|
}
|
|
// 自定义u-input样式
|
:deep(.u-input) {
|
border: 2rpx solid #e5e5e7 !important;
|
border-radius: 12rpx !important;
|
padding: 20rpx 24rpx !important;
|
background: #fff !important;
|
}
|
|
:deep(.u-textarea) {
|
border: 2rpx solid #e5e5e7 !important;
|
border-radius: 12rpx !important;
|
padding: 20rpx 24rpx !important;
|
background: #fff !important;
|
}
|
|
.action-buttons {
|
display: flex;
|
gap: 20rpx;
|
margin-top: 40rpx;
|
}
|
|
.btn {
|
flex: 1;
|
height: 80rpx;
|
border-radius: 16rpx;
|
font-size: 32rpx;
|
font-weight: 500;
|
|
&.secondary {
|
background: #f5f5f7 !important;
|
color: #1d1d1f !important;
|
}
|
|
&.primary {
|
background: #2979ff !important;
|
color: #fff !important;
|
}
|
|
&.success {
|
background: linear-gradient(135deg, #0f95b0, #89C4C1) !important;
|
color: #fff !important;
|
|
&:disabled {
|
background: #c0c0c0 !important;
|
opacity: 0.6;
|
}
|
}
|
}
|
</style>
|