273 lines
7.7 KiB
Vue
273 lines
7.7 KiB
Vue
<template>
|
||
<el-popover :visible="selectVisible" placement="bottom" :width="'18vw'" @after-enter="initClickOutside">
|
||
<el-form :model="queryParams" class="query-form" label-width="5.625rem">
|
||
<!-- 病人类型选择 -->
|
||
<el-form-item label="病人类型:" prop="brly">
|
||
<el-select v-model="queryParams.brly" placeholder="全部" clearable>
|
||
<el-option v-for="item in brlyOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="药敏:" prop="finish">
|
||
<el-radio-group v-model="queryParams.finish" @change="handleRadioChange">
|
||
<el-radio value="1" @click.native="handleRadioClick('1', 'finish')">已完成</el-radio>
|
||
<el-radio value="0" @click.native="handleRadioClick('0', 'finish')">未完成</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
|
||
|
||
<!-- 审核状态选择 -->
|
||
<el-form-item label="审核状态:" prop="jgbz">
|
||
<el-radio-group v-model="queryParams.jgbz" @change="handleRadioChange">
|
||
<el-radio value="2" @click.native="handleRadioClick('2', 'jgbz')">已审核</el-radio>
|
||
<el-radio value="3" @click.native="handleRadioClick('3', 'jgbz')">初报</el-radio>
|
||
<el-radio value="4" @click.native="handleRadioClick('4', 'jgbz')">二报</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
|
||
<el-row>
|
||
<el-col :span="7">
|
||
|
||
</el-col>
|
||
<el-col :span="7">
|
||
<!-- 危急值选择 -->
|
||
<el-form-item prop="alarmflag" label-width="0">
|
||
<el-checkbox v-model="queryParams.alarmflag" true-value="1" false-value=""> 警 </el-checkbox>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<!-- 急诊选择 -->
|
||
<el-form-item prop="jzbz" label-width="0">
|
||
<el-checkbox v-model="queryParams.jzbz" true-value="1" false-value=""> 急诊 </el-checkbox>
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
|
||
<!-- 打印状态选择 -->
|
||
<el-form-item label="打印状态:" prop="dybz">
|
||
<el-radio-group v-model="queryParams.dybz" @chnage="handleRadioChange">
|
||
<el-radio value="1" @click.native="handleRadioClick('1', 'dybz')">已打印</el-radio>
|
||
<el-radio value="0" @click.native="handleRadioClick('0', 'dybz')">未打印</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
|
||
|
||
<!-- 操作按钮 -->
|
||
<el-form-item>
|
||
<el-button type="primary" @click="handleQuery" :size="props.size">确认查询</el-button>
|
||
<el-button @click="handleReset" style="margin-left: 0.5rem" :size="props.size">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<template #reference>
|
||
<el-input v-model="selectShowValue" :size="props.size" @clear="clearHandle"
|
||
@click="selectVisible = !selectVisible" :placeholder="props.placeholder" readonly
|
||
:style="{ width: props.width }" suffix-icon="ArrowDown" :clearable="props.clearable" />
|
||
</template>
|
||
</el-popover>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, defineProps, defineEmits, nextTick, watch } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
|
||
// 定义下拉选项类型
|
||
interface OptionItem {
|
||
label: string
|
||
value: string | number
|
||
}
|
||
|
||
// 定义查询参数类型
|
||
interface QueryParams {
|
||
brly?: string | number
|
||
jgbz?: string | number
|
||
dybz?: string | number
|
||
alarmflag?: string | number
|
||
jzbz?: string | number
|
||
finish?: string | number
|
||
autojgbz?: string | number
|
||
}
|
||
|
||
// 定义组件Props
|
||
const props = defineProps<{
|
||
// 可传入初始查询参数
|
||
initialParams?: Partial<QueryParams>,
|
||
// 宽度
|
||
width?: string,
|
||
// 是否禁用
|
||
disabled?: boolean,
|
||
// 是否可清空
|
||
clearable?: boolean,
|
||
// 是否显示查询按钮
|
||
showQueryButton?: boolean,
|
||
// 是否显示重置按钮
|
||
showResetButton?: boolean,
|
||
// 尺寸
|
||
size?: 'large' | 'default' | 'small',
|
||
// 占位符
|
||
placeholder?: string,
|
||
dictData?: any
|
||
}>()
|
||
|
||
|
||
watch(() => props.dictData, () => {
|
||
brlyOptions.value = props.dictData.PT
|
||
optionMaps.brly = props.dictData.PT
|
||
})
|
||
|
||
// 定义组件事件
|
||
const emit = defineEmits<{
|
||
// 查询事件,返回查询参数
|
||
(e: 'query', params: QueryParams): void
|
||
// 重置事件
|
||
(e: 'reset'): void
|
||
}>()
|
||
const selectVisible = ref(false)
|
||
const selectShowValue = ref('')
|
||
const selectRef = ref()
|
||
// 病人类型选项
|
||
const brlyOptions = ref<OptionItem[]>([])
|
||
// 审核状态选项
|
||
const jgbzOptions: OptionItem[] = [
|
||
{ label: '已审核', value: 2 },
|
||
{ label: '初报', value: 3 },
|
||
{ label: '二报', value: 4 },
|
||
]
|
||
|
||
// 打印状态选项
|
||
const dybzOptions: OptionItem[] = [
|
||
{ label: '未打印', value: 0 },
|
||
{ label: '已打印', value: 1 },
|
||
]
|
||
|
||
// 危急值选项
|
||
const alarmflagOptions: OptionItem[] = [
|
||
{ label: '危急值', value: 1 },
|
||
{ label: '无', value: 0 }
|
||
]
|
||
|
||
// 急诊选项
|
||
const emergencyOptions: OptionItem[] = [
|
||
{ label: '急诊', value: 1 },
|
||
{ label: '否', value: 0 }
|
||
]
|
||
|
||
// 完成状态选项
|
||
const finishOptions: OptionItem[] = [
|
||
{ label: '未完成', value: 0 },
|
||
{ label: '已完成', value: 1 },
|
||
]
|
||
|
||
// 自审状态选项
|
||
const autojgbzOptions: OptionItem[] = [
|
||
{ label: '否', value: 0 },
|
||
{ label: '自审', value: 1 },
|
||
]
|
||
|
||
|
||
// 创建选项映射关系,方便查找label
|
||
const optionMaps = {
|
||
brly: props.dictData.PT,
|
||
jgbz: jgbzOptions,
|
||
dybz: dybzOptions,
|
||
alarmflag: alarmflagOptions,
|
||
jzbz: emergencyOptions,
|
||
finish: finishOptions,
|
||
autojgbz: autojgbzOptions
|
||
}
|
||
|
||
// 查询参数
|
||
const queryParams = ref<QueryParams>({
|
||
...props.initialParams
|
||
})
|
||
|
||
// 由于更多按钮在 app 元素内,给 app 元素注册的点击事件必须在弹出框显示后并且是一次性的
|
||
// 防止更多按钮的事件与之冲突
|
||
const initClickOutside = () => {
|
||
document.getElementById('app')!.addEventListener('click', () => {
|
||
selectVisible.value = false
|
||
}, { once: true })
|
||
}
|
||
|
||
// 记录上一次选中的值
|
||
const lastRadioValue = ref<string | undefined>(undefined);
|
||
const handleRadioChange = (value: string) => {
|
||
lastRadioValue.value = value;
|
||
};
|
||
const handleRadioClick = (value: string, zd: keyof QueryParams) => {
|
||
if (value === lastRadioValue.value) {
|
||
setTimeout(() => {
|
||
queryParams.value[zd] = undefined;
|
||
lastRadioValue.value = undefined;
|
||
}, 100);
|
||
} else {
|
||
lastRadioValue.value = value;
|
||
}
|
||
};
|
||
|
||
|
||
const clearHandle = () => {
|
||
queryParams.value = {}
|
||
selectShowValue.value = ''
|
||
}
|
||
|
||
// 根据值和选项列表获取对应的label
|
||
const getLabelByValue = (value: string | number | undefined, options: OptionItem[]) => {
|
||
if (value === undefined || value === null || value === '') return ''
|
||
const item = options.find(option => option.value == value)
|
||
return item ? item.label : ''
|
||
}
|
||
|
||
// 处理查询
|
||
const handleQuery = () => {
|
||
// 过滤空值参数
|
||
const filteredParams = Object.fromEntries(
|
||
Object.entries(queryParams.value).filter(([_, v]) => v !== undefined && v !== null && v !== '')
|
||
) as QueryParams
|
||
|
||
// 收集所有选中项的label
|
||
const labels: string[] = []
|
||
Object.entries(filteredParams).forEach(([key, value]) => {
|
||
// @ts-ignore
|
||
const options = optionMaps[key]
|
||
if (options) {
|
||
const label = getLabelByValue(value, options)
|
||
if (label) labels.push(label)
|
||
}
|
||
})
|
||
|
||
// 拼接label并设置到显示值
|
||
selectShowValue.value = labels.join(',')
|
||
console.log('selectShowValue.value==>', selectShowValue.value);
|
||
|
||
emit('query', filteredParams)
|
||
|
||
selectVisible.value = false;
|
||
}
|
||
|
||
// 处理重置
|
||
const handleReset = () => {
|
||
selectShowValue.value = ''
|
||
queryParams.value = {}
|
||
selectVisible.value = false;
|
||
emit('reset')
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.query-form {
|
||
|
||
:deep(.el-form-item) {
|
||
margin-bottom: .5rem;
|
||
}
|
||
}
|
||
|
||
/* 响应式调整 */
|
||
@media (max-width: 768px) {
|
||
.query-form {
|
||
:deep(.el-form-item) {
|
||
margin-bottom: 12px;
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
</style> |