186 lines
4.5 KiB
Vue
186 lines
4.5 KiB
Vue
<template>
|
|
<view class="page">
|
|
<view class="top">
|
|
<uni-easyinput v-model="keyword" prefixIcon="search" placeholder="请搜索诊断名称" @input="onInput" />
|
|
</view>
|
|
|
|
<scroll-view scroll-y class="scroll">
|
|
<view v-for="item in showList" :key="item.key" class="row" @click="toggle(item)">
|
|
<view class="label">{{ item.label }}</view>
|
|
<uni-icons :type="selectedMap[item.label] ? 'checkmarkempty' : ''" size="22" color="#007aff" />
|
|
</view>
|
|
<view v-if="showList.length === 0" class="empty">暂无诊断数据</view>
|
|
<view style="height: 240rpx;"></view>
|
|
</scroll-view>
|
|
|
|
<view class="footer">
|
|
<button class="btn primary" @click="save">确定</button>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, onUnmounted, ref } from 'vue';
|
|
import { onLoad } from '@dcloudio/uni-app';
|
|
import api from '@/utils/api';
|
|
import { toast } from '@/utils/widget';
|
|
|
|
const ready = ref(false);
|
|
const keyword = ref('');
|
|
const list = ref([]);
|
|
const selections = ref([]);
|
|
const mult = ref(false);
|
|
const eventName = ref('change-diagnosis');
|
|
|
|
const selectedMap = computed(() => selections.value.reduce((m, i) => ((m[i] = true), m), {}));
|
|
|
|
function normalizeText(v) {
|
|
return v ? String(v) : '';
|
|
}
|
|
|
|
const fullMatched = computed(() => {
|
|
const value = String(keyword.value || '').trim();
|
|
if (!value) return null;
|
|
return { label: value, value, key: `full_${value}` };
|
|
});
|
|
|
|
const showList = computed(() => {
|
|
const base = Array.isArray(list.value) ? list.value : [];
|
|
const arr = [];
|
|
if (fullMatched.value) arr.push(fullMatched.value);
|
|
base.forEach((i) => {
|
|
if (!i || !i.label) return;
|
|
if (fullMatched.value && i.label === fullMatched.value.label) return;
|
|
arr.push(i);
|
|
});
|
|
return arr;
|
|
});
|
|
|
|
let timer = null;
|
|
function onInput() {
|
|
if (timer) clearTimeout(timer);
|
|
timer = setTimeout(() => {
|
|
timer = null;
|
|
query();
|
|
}, 600);
|
|
}
|
|
|
|
onUnmounted(() => {
|
|
if (timer) clearTimeout(timer);
|
|
});
|
|
|
|
onLoad((opt) => {
|
|
eventName.value = opt?.eventName ? String(opt.eventName) : 'change-diagnosis';
|
|
mult.value = String(opt?.mult || '') === 'YES';
|
|
|
|
if (mult.value) {
|
|
const data = uni.getStorageSync('diagnosis-list-selection');
|
|
selections.value = Array.isArray(data) ? data : [];
|
|
uni.removeStorageSync('diagnosis-list-selection');
|
|
} else {
|
|
const v = opt?.value ? String(opt.value) : '';
|
|
selections.value = v ? [v] : [];
|
|
}
|
|
|
|
ready.value = true;
|
|
query();
|
|
});
|
|
|
|
async function query() {
|
|
if (!ready.value) return;
|
|
const value = String(keyword.value || '').trim();
|
|
|
|
uni.showLoading({ title: '加载中...' });
|
|
try {
|
|
const res = await api('getDisease', { diseaseName: value });
|
|
const arr = Array.isArray(res?.data?.data) ? res.data.data : [];
|
|
list.value = arr
|
|
.map((i) => {
|
|
const label = normalizeText(i?.diseaseName);
|
|
const code = normalizeText(i?.code);
|
|
if (!label) return null;
|
|
return { label, value: code || label, key: code || label };
|
|
})
|
|
.filter(Boolean);
|
|
} catch (e) {
|
|
list.value = [];
|
|
} finally {
|
|
uni.hideLoading();
|
|
}
|
|
}
|
|
|
|
function toggle(item) {
|
|
if (!item || !item.label) return;
|
|
const index = selections.value.findIndex((i) => i === item.label);
|
|
if (index >= 0) {
|
|
selections.value.splice(index, 1);
|
|
return;
|
|
}
|
|
if (mult.value) selections.value.push(item.label);
|
|
else selections.value = [item.label];
|
|
}
|
|
|
|
function save() {
|
|
if (selections.value.length === 0) return toast('请选择');
|
|
if (mult.value) uni.$emit(eventName.value, selections.value);
|
|
else uni.$emit(eventName.value, selections.value[0]);
|
|
uni.navigateBack();
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.page {
|
|
min-height: 100vh;
|
|
background: #fff;
|
|
padding-bottom: calc(152rpx + env(safe-area-inset-bottom));
|
|
}
|
|
.top {
|
|
padding: 24rpx 28rpx;
|
|
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
|
|
}
|
|
.scroll {
|
|
height: calc(100vh - 280rpx);
|
|
}
|
|
.row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 28rpx 28rpx;
|
|
border-bottom: 2rpx solid #f2f2f2;
|
|
}
|
|
.label {
|
|
font-size: 28rpx;
|
|
color: #111827;
|
|
margin-right: 20rpx;
|
|
}
|
|
.empty {
|
|
padding: 120rpx 0;
|
|
text-align: center;
|
|
color: #9aa0a6;
|
|
font-size: 26rpx;
|
|
}
|
|
.footer {
|
|
position: fixed;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: #fff;
|
|
padding: 24rpx 28rpx calc(24rpx + env(safe-area-inset-bottom));
|
|
box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
|
|
}
|
|
.btn {
|
|
width: 100%;
|
|
height: 88rpx;
|
|
line-height: 88rpx;
|
|
border-radius: 12rpx;
|
|
font-size: 30rpx;
|
|
}
|
|
.btn::after {
|
|
border: none;
|
|
}
|
|
.btn.primary {
|
|
background: #4f6ef7;
|
|
color: #fff;
|
|
}
|
|
</style>
|