医废收集纯手动上传,接口调试,并且添加 科室、人员搜索功能

This commit is contained in:
2026-03-16 14:31:41 +08:00
parent 95d75f76a8
commit f38b51b7e6
+252 -21
View File
@@ -19,13 +19,33 @@
<!-- 科室 -->
<view class="form-item">
<view class="form-label">科室</view>
<picker mode="selector" :range="departmentList" @change="onDepartmentChange">
<view class="form-value-picker">
<text v-if="selectedDepartment">{{selectedDepartment}}</text>
<view class="searchable-picker-wrapper">
<view class="searchable-picker" @click="showDepartmentPicker = true">
<text v-if="selectedDepartment" class="picker-text">{{selectedDepartment}}</text>
<text v-else class="placeholder">请选择科室</text>
<text class="picker-icon"></text>
</view>
</picker>
<!-- 科室搜索弹窗 -->
<view class="picker-modal" v-if="showDepartmentPicker" @click.self="showDepartmentPicker = false">
<view class="picker-modal-content">
<view class="modal-header">
<text class="modal-title">选择科室</text>
<text class="modal-close" @click="showDepartmentPicker = false"></text>
</view>
<view class="search-input-wrapper">
<input class="search-input" v-model="departmentSearchKeyword" placeholder="搜索科室" placeholder-class="search-placeholder" />
<text class="search-icon" v-if="!departmentSearchKeyword">🔍</text>
<text class="clear-icon" v-else @click="departmentSearchKeyword = ''"></text>
</view>
<scroll-view class="picker-list" scroll-y>
<view class="picker-item" v-for="(item, index) in filteredDepartmentList" :key="index" @click="selectDepartment(item)">
<text :class="{'item-active': item === selectedDepartment}">{{item}}</text>
</view>
<view v-if="filteredDepartmentList.length === 0" class="picker-empty">未找到匹配的科室</view>
</scroll-view>
</view>
</view>
</view>
</view>
<!-- 医废编码 -->
@@ -67,13 +87,33 @@
<!-- 交接人员 -->
<view class="form-item">
<view class="form-label">交接人员</view>
<picker mode="selector" :range="handoverList" @change="onHandoverChange">
<view class="form-value-picker">
<text v-if="selectedHandover">{{selectedHandover}}</text>
<view class="searchable-picker-wrapper">
<view class="searchable-picker" @click="showHandoverPicker = true">
<text v-if="selectedHandover" class="picker-text">{{selectedHandover}}</text>
<text v-else class="placeholder">请选择交接人员</text>
<text class="picker-icon"></text>
</view>
</picker>
<!-- 交接人员搜索弹窗 -->
<view class="picker-modal" v-if="showHandoverPicker" @click.self="showHandoverPicker = false">
<view class="picker-modal-content">
<view class="modal-header">
<text class="modal-title">选择交接人员</text>
<text class="modal-close" @click="showHandoverPicker = false"></text>
</view>
<view class="search-input-wrapper">
<input class="search-input" v-model="handoverSearchKeyword" placeholder="搜索交接人员" placeholder-class="search-placeholder" />
<text class="search-icon" v-if="!handoverSearchKeyword">🔍</text>
<text class="clear-icon" v-else @click="handoverSearchKeyword = ''"></text>
</view>
<scroll-view class="picker-list" scroll-y>
<view class="picker-item" v-for="(item, index) in filteredHandoverList" :key="index" @click="selectHandover(item)">
<text :class="{'item-active': item === selectedHandover}">{{item}}</text>
</view>
<view v-if="filteredHandoverList.length === 0" class="picker-empty">未找到匹配的交接人员</view>
</scroll-view>
</view>
</view>
</view>
</view>
<!-- 收集时间 -->
@@ -82,7 +122,6 @@
<view class="datetime-picker">
<picker mode="date" :value="collectionDate" @change="onDateChange" :end="endDate">
<view class="picker-box">
<text class="picker-icon">📅</text>
<text class="picker-text">{{collectionDate || '选择日期'}}</text>
<text class="picker-arrow"></text>
</view>
@@ -90,7 +129,6 @@
<view class="picker-separator">·</view>
<picker mode="time" :value="collectionTime" @change="onTimeChange">
<view class="picker-box">
<text class="picker-icon">🕐</text>
<text class="picker-text">{{collectionTime}}</text>
<text class="picker-arrow"></text>
</view>
@@ -129,7 +167,13 @@
departmentList: [],
typeList: [],
collectorList: [],
handoverList: []
handoverList: [],
// 搜索弹窗显示状态
showDepartmentPicker: false,
showHandoverPicker: false,
// 搜索关键词
departmentSearchKeyword: '',
handoverSearchKeyword: ''
}
},
mounted() {
@@ -152,6 +196,26 @@
this.getCollectorOptions()
this.getHandoverOptions()
},
computed: {
// 过滤后的科室列表
filteredDepartmentList() {
if (!this.departmentSearchKeyword) {
return this.departmentList;
}
return this.departmentList.filter(dept => {
return dept && dept.includes(this.departmentSearchKeyword);
});
},
// 过滤后的交接人员列表
filteredHandoverList() {
if (!this.handoverSearchKeyword) {
return this.handoverList;
}
return this.handoverList.filter(person => {
return person && person.includes(this.handoverSearchKeyword);
});
}
},
methods: {
// 生成随机医废编码
generateMedicalCode() {
@@ -187,14 +251,21 @@
'Content-type': 'application/json'
},
success: function(res) {
that.departmentList = res.data.data || []
const data = res.data.data || []
// 将对象数组转换为字符串数组,提取 dept_name 字段
that.departmentList = data.map(item => {
if (typeof item === 'object' && item !== null) {
return item.dept_name || item.name || item.department_name || item.text || JSON.stringify(item)
}
return item
})
},
fail: () => {
console.info('获取科室选项失败')
}
})
},
// 获取类型选项(预留接口)
getTypeOptions() {
let that = this
@@ -205,14 +276,21 @@
'Content-type': 'application/json'
},
success: function(res) {
that.typeList = res.data.data || []
const data = res.data.data || []
// 将对象数组转换为字符串数组,假设对象中有 name 或 type_name 字段
that.typeList = data.map(item => {
if (typeof item === 'object' && item !== null) {
return item.name || item.type_name || item.text || JSON.stringify(item)
}
return item
})
},
fail: () => {
console.info('获取类型选项失败')
}
})
},
// 获取收集人员选项(预留接口)
getCollectorOptions() {
let that = this
@@ -223,14 +301,21 @@
'Content-type': 'application/json'
},
success: function(res) {
that.collectorList = res.data.data || []
const data = res.data.data || []
// 将对象数组转换为字符串数组,假设对象中有 name 字段
that.collectorList = data.map(item => {
if (typeof item === 'object' && item !== null) {
return item.name || item.text || JSON.stringify(item)
}
return item
})
},
fail: () => {
console.info('获取收集人员选项失败')
}
})
},
// 获取交接人员选项(预留接口)
getHandoverOptions() {
let that = this
@@ -241,7 +326,14 @@
'Content-type': 'application/json'
},
success: function(res) {
that.handoverList = res.data.data || []
const data = res.data.data || []
// 将对象数组转换为字符串数组,假设对象中有 name 字段
that.handoverList = data.map(item => {
if (typeof item === 'object' && item !== null) {
return item.name || item.text || JSON.stringify(item)
}
return item
})
},
fail: () => {
console.info('获取交接人员选项失败')
@@ -249,9 +341,18 @@
})
},
// 科室选择变化
onDepartmentChange(e) {
this.selectedDepartment = this.departmentList[e.detail.value]
// 选择科室
selectDepartment(item) {
this.selectedDepartment = item;
this.showDepartmentPicker = false;
this.departmentSearchKeyword = '';
},
// 选择交接人员
selectHandover(item) {
this.selectedHandover = item;
this.showHandoverPicker = false;
this.handoverSearchKeyword = '';
},
// 类型选择变化
@@ -510,4 +611,134 @@
.cancel-btn::after, .confirm-btn::after {
border: none;
}
/* 可搜索选择器 */
.searchable-picker-wrapper {
flex: 1;
position: relative;
}
.searchable-picker {
display: flex;
align-items: center;
justify-content: flex-end;
color: #666;
font-size: 28rpx;
}
/* 搜索弹窗 */
.picker-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
justify-content: center;
z-index: 1000;
}
.picker-modal-content {
width: 100%;
background: #fff;
border-radius: 30rpx 30rpx 0 0;
max-height: 80vh;
display: flex;
flex-direction: column;
}
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1px solid #e8e8e8;
}
.modal-title {
font-size: 32rpx;
font-weight: 700;
color: #333;
}
.modal-close {
font-size: 40rpx;
color: #999;
padding: 10rpx;
}
/* 搜索输入框 */
.search-input-wrapper {
padding: 20rpx 30rpx;
background: #f8f9fa;
display: flex;
align-items: center;
border-bottom: 1px solid #e8e8e8;
}
.search-input {
flex: 1;
height: 60rpx;
font-size: 28rpx;
color: #333;
background: #fff;
border-radius: 30rpx;
padding: 0 50rpx 0 24rpx;
border: 1px solid #d9d9d9;
}
.search-placeholder {
color: #ccc;
}
.search-icon, .clear-icon {
position: absolute;
right: 50rpx;
font-size: 28rpx;
}
.search-icon {
color: #999;
}
.clear-icon {
color: #ccc;
padding: 10rpx;
}
/* 列表 */
.picker-list {
flex: 1;
max-height: 50vh;
}
.picker-item {
padding: 28rpx 30rpx;
border-bottom: 1px solid #f0f0f0;
font-size: 30rpx;
color: #333;
transition: all 0.2s;
}
.picker-item:active {
background: #f5f5f5;
}
.picker-item text {
display: block;
}
.item-active {
color: #2980b9;
font-weight: 600;
}
.picker-empty {
padding: 80rpx 0;
text-align: center;
font-size: 28rpx;
color: #999;
}
</style>