You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

950 lines
24 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup>
import DraggableButton from "@/pages/components/goHome.vue";
/**
* name
* usersa0ChunLuyu
* date2024年8月7日 20:05:05
*/
import { ref, computed } from "vue";
import { $image, $api, $response } from "@/api";
import { onShow } from "@dcloudio/uni-app";
import { useStore } from "@/store";
const $store = useStore();
const $props = defineProps({
groupId: {
type: String,
default: "",
},
});
const combo_active = ref("");
const person_active = ref("");
let popup = ref(null);
let selectKey = ref(""); // 整个选择的key
let sortIndex = ref(0); // 排序的索引
let comboIndex = ref(null); // 套餐类型索引
let crowdIndex = ref(null); // 适用人群索引
let priceIndex = ref(null); // 套餐价格索引
let projectIds = ref([]); // 项目id集合
let screenObj = ref({}); // 筛选条件
let combo_select = ref({}); // 套餐筛选条件
let comboIds = ref([]); // 套餐对比列表
let status = ref(false); // 筛选弹窗控制
const selectItemClick = async (index, key) => {
// 选择套餐条件
let data = combo_select.value;
if (selectKey.value == "sort_list") {
if (sortIndex.value == index) {
sortIndex.value = 0;
} else {
sortIndex.value = index;
}
screenObj.value.combo_sort = data[selectKey.value][index]?.id;
} else if (selectKey.value == "combo_type") {
if (comboIndex.value == index) {
comboIndex.value = null;
delete screenObj.value.combo_type;
} else {
comboIndex.value = index;
screenObj.value.combo_type = data[selectKey.value][index]?.id;
}
} else if (selectKey.value == "combo_crowd") {
if (crowdIndex.value == index) {
crowdIndex.value = null;
delete screenObj.value.combo_crowd;
} else {
crowdIndex.value = index;
screenObj.value.combo_crowd = data[selectKey.value][index]?.id;
}
} else {
if (key == "combo_price") {
if (priceIndex.value == index) {
priceIndex.value = null;
return;
}
priceIndex.value = index;
} else {
if (projectIds.value?.includes(index)) {
projectIds.value.splice(projectIds.value.indexOf(index), 1);
} else {
projectIds.value.push(index);
}
}
return;
}
await getComboList();
popup.value.close();
};
const selectDone = async () => {
if (priceIndex.value === null) {
delete screenObj.value.combo_price;
} else {
screenObj.value.combo_price =
combo_select.value["combo_price"][priceIndex.value]?.id;
}
if (projectIds.value.length) {
screenObj.value.combo_item = projectIds.value;
} else {
delete screenObj.value.combo_item;
}
await getComboList();
select_drawer_ref.value.close();
};
const remake = () => {
// 重置筛选
delete screenObj.value.combo_price;
delete screenObj.value.combo_item;
priceIndex.value = null;
projectIds.value = [];
};
const getComboSelect = async () => {
uni.showLoading();
const response = await $api("GetComboSort");
uni.hideLoading();
$response(response, async () => {
combo_select.value = response.data;
if ("sort_list" in combo_select.value) {
selectKey.value = "sort_list";
sortIndex.value = 0;
}
await getComboList();
});
};
const combo_list = ref({
list: [],
hospital: {
id: 1,
},
doctor: {
id: 0,
},
info: {
name: "",
},
});
const combo_list_computed = computed(() => {
let list = [];
for (let i in combo_list.value.list) {
let push = false;
if (!combo_active.value) {
push = true;
} else {
if (combo_list.value.list[i].combo_type === combo_active.value) {
push = true;
}
}
if (!!push) {
if (!person_active.value) {
push = true;
} else {
if (combo_list.value.list[i].person_type === person_active.value) {
push = true;
} else {
push = false;
}
}
}
if (!!push) {
list.push(combo_list.value.list[i]);
}
}
return list;
});
const getComboList = async () => {
uni.showLoading();
let obj = {
doctor: $store.save.doctor,
hospital: hospital_active.value,
};
if ($store.getCheckupTypeId()) {
let b = $store.getCheckupTypeId();
console.log();
if (Object.keys(b).length != 0) {
screenObj.value.checkup_type_id = b.id;
}
}
if (screenObj.value) {
obj = Object.assign(obj, screenObj.value);
}
const response = await $api("ComboList", obj);
uni.hideLoading();
$response(response, () => {
combo_list.value = response.data;
});
};
const contrastClick = async (item) => {
if (comboIds.value.includes(item.combo_id)) {
comboIds.value.splice(comboIds.value.indexOf(item.combo_id), 1);
} else {
if (comboIds.value.length < 3) {
comboIds.value.push(item.combo_id);
} else {
uni.showToast({
title: "最多对比3个套餐",
icon: "none",
});
}
}
$store.setComboContrast(comboIds.value);
};
const hospital_active = ref(0);
const checkHospital = () => {
let hospital_id = $store.save.hospital;
comboIds.value = $store.getComboContrast() || [];
if (!hospital_id) {
hospital_id = $store.config.hospital[0].id;
}
hospital_active.value = hospital_id;
$store.saveInfo({
hospital: hospital_id,
});
getComboSelect();
};
const tabPatients = () => {
uni.navigateTo({
url: "/pages/user/choose/choose",
});
};
const open = (key) => {
if (key) {
// 点击三个筛选条件
selectKey.value = key;
popup.value.close();
let time = setTimeout(() => {
popup.value.open("top");
clearTimeout(time);
}, 400);
} else {
// 点击筛选
popup.value.close();
selectKey.value = "screen";
select_drawer_ref.value.open();
if (screenObj.value.combo_price) {
priceIndex.value = combo_select.value["combo_price"].findIndex(
(item) => item.id == screenObj.value.combo_price
);
} else {
priceIndex.value = null;
}
if (screenObj.value.combo_item?.length) {
projectIds.value = [...screenObj.value.combo_item];
} else {
projectIds.value = [];
}
}
};
const config_ref = ref(null);
const configRef = (e) => {
if (!config_ref.value) {
config_ref.value = e;
checkHospital();
}
};
const select_drawer_ref = ref(null);
const selectDrawerRef = (e) => {
select_drawer_ref.value = e;
};
onShow(() => {
if (!!config_ref.value) {
checkHospital();
}
});
const buyClick = async (item) => {
let query = "?comboId=" + item.combo_id;
if ($props.groupId) {
// 团检把团检ID加上
query += "&groupId=" + $props.groupId;
}
// 个检只要套餐ID
// 预约 跳转到个检/团检套餐详情
uni.navigateTo({
url: "/pages/main/tj/tjxq" + query,
});
};
const toRouter = () => {
if (!comboIds.value.length) {
uni.showToast({
title: "请先选择套餐",
icon: "none",
});
return;
}
uni.navigateTo({
url: "/pages/main/combo/tcdb",
});
};
</script>
<template>
<DraggableButton />
<view>
<view v-if="!!$store.config">
<view :ref="configRef"></view>
</view>
<view class="header_wrapper">
<view
@click="toRouter"
class="center fixed pt-10rpx box-border left-40rpx bottom-5% rounded-full w-110rpx h-110rpx bg-#239EA3 flex-col"
>
<uni-badge :text="comboIds.length" absolute="rightTop" size="small">
<image
src="@/static/assets/slices/duibi.png"
mode="widthFix"
class="w-42rpx"
/>
</uni-badge>
<text class="text-22rpx text-#fff -mt-5rpx">对比</text>
</view>
<view v-if="!!combo_list.hospital.id" class="hospital_wrapper">
<view class="hospital_icon_wrapper">
<image src="@/static/assets/dingwei@2x.png"></image>
</view>
<view class="hospital_name_wrapper">{{
combo_list.hospital.name
}}</view>
<view class="hospital_select_wrapper">
<image src="@/static/assets/gengduo@2x.png"></image>
</view>
</view>
<view
v-if="!!combo_list.info.name"
class="user_wrapper"
@click="tabPatients()"
>
<view class="user_title_wrapper">就诊人:</view>
<view class="user_name_wrapper">{{ combo_list.info.name }}</view>
<view v-if="combo_list.info.count > 1" class="user_choose_wrapper">
<image src="@/static/assets/qiehuan@2x.png"></image>
</view>
</view>
</view>
<!-- <view class="relative z-999 pt-10rpx center">
<view class="doctor_wrapper">
<view class="doctor_tip_wrapper">
<text v-if="!!combo_list.doctor.id">已根据指定医生:</text>
<text v-else>可选择指定医生:</text>
</view>
<view class="doctor_name_wrapper">
{{ !!combo_list.doctor.id ? combo_list.doctor.name : "前往选择" }}
</view>
<view class="doctor_tip_wrapper">(自动筛选匹配套餐)</view>
</view>
</view> -->
<view class="select_wrapper flex" v-if="selectKey">
<template v-for="(value, key, index) in combo_select" :key="index">
<view
@click="open(key)"
class="flex-1 center text-#2f2f2f text-26rpx line-height-[1]"
v-if="key != 'combo_price' && key != 'combo_item'"
:class="{
'!text-#239EA3': selectKey == key,
}"
>
<view v-if="key == 'sort_list'">
{{ value[sortIndex]?.name || "综合排序" }}
</view>
<view v-if="key == 'combo_type'">
{{ value[comboIndex]?.name || "套餐类型" }}
</view>
<view v-if="key == 'combo_crowd'">
{{ value[crowdIndex]?.name || "适用人群" }}
</view>
<view class="select_item_icon_wrapper">
<image src="@/static/assets/xuanzegengduo@2x.png"></image>
</view>
</view>
</template>
<view
@click="open()"
:class="{
'!text-#239EA3': selectKey == 'screen',
}"
class="mx-20rpx center text-#2f2f2f text-26rpx"
>
<view>筛选</view>
<view class="select_item_icon2_wrapper">
<image src="@/static/assets/shaixuan@2x.png"></image>
</view>
</view>
</view>
<view class="list_wrapper">
<view
class="combo_wrapper"
v-for="(i, k) in combo_list_computed"
:key="k"
>
<view class="combo_info_wrapper">
<view class="combo_cover_wrapper">
<image v-if="i.cover" :src="$image(i.cover)"></image>
</view>
<view class="combo_content_wrapper">
<view class="combo_name_wrapper">{{ i.name }}</view>
<view class="combo_tags_wrapper">
<view
class="combo_tag_wrapper"
v-for="(ii, kk) in i.tag"
:key="kk"
:style="{
color: ii.text_color,
background: ii.color,
}"
>
{{ ii.text }}
</view>
</view>
<view class="combo_desc_wrapper">
{{ i.tags2?.join(" | ") }}
</view>
<view class="combo_price_wrapper">
<view class="combo_price_box_wrapper">
<view class="combo_true_price_wrapper">
<text class="combo_true_price_icon_wrapper">¥</text>
<text class="combo_true_price_number_wrapper">{{
i.price
}}</text>
</view>
<view class="combo_original_price_wrapper"
>¥{{ i.original_price }}</view
>
</view>
<view class="combo_count_wrapper">已售{{ i.count }}</view>
</view>
</view>
</view>
<view class="combo_button_wrapper">
<view @click="contrastClick(i)" class="combo_pick_button_wrapper">{{
comboIds.includes(i.combo_id) ? "已加入" : "对比"
}}</view>
<view class="combo_buy_button_wrapper" @click="buyClick(i)"
>预约</view
>
</view>
<view class="combo_line_wrapper"></view>
</view>
</view>
<uni-popup ref="popup" mask-background-color="transparent">
<view class="pt-180rpx w-full h-100vh" @click="popup.close()">
<view class="bg-[rgba(0,0,0,0.3)] h-100%">
<view
class="bg-#fff"
:class="
selectKey != 'sort_list'
? 'flex pt20rpx px10rpx pb0 box-border flex-wrap'
: ''
"
>
<view
v-for="(val, index) in combo_select[selectKey]"
:key="index"
@click.stop="selectItemClick(index)"
:class="{
'min-w-23% mx-1% mb-20rpx': selectKey != 'sort_list',
}"
>
<uni-list-item v-if="selectKey == 'sort_list'">
<template v-slot:body>
<text
class="text-26rpx"
:class="{
'!text-#239EA3': sortIndex == index,
}"
>{{ val.name }}</text
>
</template>
</uni-list-item>
<view
v-else
class="box-border px-28rpx py-20rpx text-26rpx center line-height-[1] rounded-5rpx"
:class="{
'!bg-#239EA3 !text-#fff':
(selectKey == 'combo_type' && comboIndex == index) ||
(selectKey == 'combo_crowd' && crowdIndex == index),
'!text-#747474 !bg-#e0e0e0':
(selectKey == 'combo_type' && comboIndex != index) ||
(selectKey == 'combo_crowd' && crowdIndex != index),
}"
>{{ val.name }}</view
>
</view>
</view>
</view>
</view>
</uni-popup>
<uni-drawer :ref="selectDrawerRef" mode="right">
<view>
<scroll-view scroll-y="true">
<view>
<view class="select_group_wrapper">
<view class="text-30rpx bold">套餐价格</view>
<view class="select_group_line_wrapper mt-20rpx">
<view
v-for="(val, index) in combo_select['combo_price']"
:key="index"
@click.stop="selectItemClick(index, 'combo_price')"
class="min-w-31% mx-1% mb-20rpx"
>
<view
class="box-border px-20rpx py-20rpx text-22rpx center line-height-[1] rounded-5rpx"
:class="{
'!bg-#239EA3 !text-#fff':
selectKey == 'screen' && priceIndex == index,
'!text-#747474 !bg-#e0e0e0':
selectKey == 'screen' && priceIndex != index,
}"
>{{ val.name }}</view
>
</view>
</view>
</view>
<view class="select_group_wrapper">
<view class="text-30rpx bold">体检项目(多选)</view>
<view class="select_group_line_wrapper mt-20rpx">
<view
v-for="(val, index) in combo_select['combo_item']"
:key="index"
@click.stop="selectItemClick(val.id, 'combo_item')"
class="min-w-31% mx-1% mb-20rpx"
>
<view
class="box-border px-20rpx py-20rpx text-22rpx center line-height-[1] rounded-5rpx"
:class="{
'!bg-#239EA3 !text-#fff':
selectKey == 'screen' && projectIds.includes(val.id),
'!text-#747474 !bg-#e0e0e0':
selectKey == 'screen' && !projectIds.includes(val.id),
}"
>{{ val.name }}</view
>
</view>
</view>
</view>
<view class="around">
<view
class="w-40% text-26rpx h-60rpx center rounded-full bg-#239EA3 text-#fff"
@click="remake()"
>重置</view
>
<view
class="w-40% text-26rpx h-60rpx center rounded-full bg-#239EA3 text-#fff"
@click="selectDone()"
>确定</view
>
</view>
</view>
</scroll-view>
</view>
</uni-drawer>
</view>
</template>
<style scoped>
.select_done_wrapper {
color: #ffffff;
background: #239ea3;
width: calc(100% - 60rpx);
margin: 50rpx auto 0;
height: 50rpx;
line-height: 50rpx;
text-align: center;
border-radius: 6rpx;
}
.select_group_item_wrapper {
padding: 10rpx 20rpx;
border: 1rpx solid #239ea3;
font-size: 22rpx;
margin: 20rpx 20rpx 0 0;
border-radius: 6rpx;
color: #239ea3;
}
.select_group_item_wrapper.active {
color: #ffffff;
background: #239ea3;
}
.select_group_line_wrapper {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.select_group_wrapper {
margin: 20rpx;
}
.list_wrapper {
padding-top: 30rpx;
height: calc(100vh - 100rpx - 10rpx - 70rpx - 80rpx - 30rpx - 30rpx);
width: 750rpx;
overflow-y: auto;
padding-bottom: 30rpx;
margin: 0 auto;
overflow-x: hidden;
-ms-overflow-style: none;
scrollbar-width: none;
overflow: -moz-scrollbars-none;
overflow-y: scroll;
}
.list_wrapper::-webkit-scrollbar {
display: none;
}
.combo_line_wrapper {
width: 710rpx;
height: 1rpx;
background: #e1ecee;
margin: 15rpx auto 0;
}
.combo_pick_button_wrapper {
width: 160rpx;
height: 60rpx;
background: #e1ecee;
border-radius: 30rpx;
font-weight: 400;
font-size: 28rpx;
color: #239ea3;
text-align: center;
line-height: 60rpx;
}
.combo_buy_button_wrapper {
width: 160rpx;
height: 60rpx;
background: #239ea3;
border-radius: 30rpx;
font-weight: 400;
font-size: 28rpx;
color: #ffffff;
text-align: center;
line-height: 60rpx;
margin-left: 32rpx;
margin-right: 20rpx;
}
.combo_button_wrapper {
display: flex;
align-items: center;
justify-content: end;
margin-top: 27rpx;
}
.combo_count_wrapper {
font-weight: 500;
font-size: 18rpx;
color: #8b8b8b;
line-height: 1;
}
.combo_original_price_wrapper {
font-weight: 500;
font-size: 18rpx;
color: #8b8b8b;
line-height: 1;
text-decoration-line: line-through;
margin-left: 10rpx;
}
.combo_true_price_wrapper {
font-weight: 500;
font-size: 18rpx;
color: #ec3d15;
line-height: 1;
}
.combo_true_price_number_wrapper {
font-size: 38rpx;
}
.combo_price_wrapper {
display: flex;
align-items: end;
justify-content: space-between;
margin-top: 21rpx;
}
.combo_price_box_wrapper {
display: flex;
align-items: end;
}
.combo_wrapper {
height: 307rpx;
width: 750rpx;
margin: 0 auto;
}
.combo_tags_wrapper {
display: flex;
align-items: center;
margin-top: 13rpx;
}
.combo_desc_wrapper {
font-weight: 500;
font-size: 20rpx;
color: #8b8b8b;
line-height: 1;
margin-top: 18rpx;
}
.combo_tag_wrapper {
padding-left: 13rpx;
padding-right: 13rpx;
height: 30rpx;
line-height: 30rpx;
border-radius: 5rpx;
font-weight: 400;
font-size: 18rpx;
color: #47abd8;
margin-right: 8rpx;
}
.combo_name_wrapper {
font-weight: 400;
font-size: 32rpx;
color: #0e0e0e;
line-height: 1;
}
.combo_content_wrapper {
margin-left: 30rpx;
width: calc(750rpx - 190rpx - 30rpx - 20rpx - 55rpx);
}
.combo_info_wrapper {
display: flex;
align-items: center;
width: 750rpx;
margin: 0 auto;
}
.combo_cover_wrapper {
width: 190rpx;
height: 190rpx;
margin-left: 20rpx;
}
.combo_cover_wrapper image {
width: 190rpx;
height: 190rpx;
display: block;
object-fit: contain;
}
.select_item_line_wrapper {
position: absolute;
width: 95rpx;
height: 10rpx;
background: linear-gradient(to bottom, #ffffff00, #1b9a9f);
border-radius: 5rpx;
bottom: 0;
left: 50%;
transform: translateX(calc(-50% - 8px));
opacity: 0;
}
.select_wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: 750rpx;
height: 80rpx;
background: #f1f7f7;
box-shadow: 0rpx -1rpx 1rpx 0rpx rgba(0, 0, 0, 0.1);
margin: 0 auto;
position: relative;
z-index: 999;
}
.select_item_icon_wrapper {
width: 18rpx;
height: 9rpx;
margin-left: 9rpx;
filter: grayscale(100%);
}
.select_item_icon_wrapper image {
width: 18rpx;
height: 9rpx;
display: block;
object-fit: contain;
}
.select_item_icon2_wrapper {
width: 26rpx;
height: 23rpx;
margin-left: 7rpx;
}
.select_item_icon2_wrapper image {
width: 26rpx;
height: 23rpx;
display: block;
object-fit: contain;
}
.select_item_name_wrapper {
font-weight: 400;
font-size: 26rpx;
color: #2f2f2f;
line-height: 1;
}
.select_item_wrapper {
width: 25%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
height: 80rpx;
}
.select_item_wrapper.active .select_item_name_wrapper {
color: #239ea3;
font-weight: bold;
}
.select_item_wrapper.active .select_item_icon_wrapper {
filter: grayscale(0%);
}
.select_item_wrapper.active .select_item_line_wrapper {
opacity: 1;
}
.doctor_name_wrapper {
font-weight: 400;
font-size: 24rpx;
line-height: 1;
color: #ffffff;
border-bottom: 1rpx solid #ffffff;
}
.doctor_tip_wrapper {
font-weight: 400;
font-size: 22rpx;
line-height: 1;
color: #ffffff;
}
.doctor_wrapper {
display: flex;
align-items: center;
width: 710rpx;
height: 70rpx;
background: #239ea3;
border-radius: 15rpx 15rpx 0rpx 0rpx;
padding-left: 24rpx;
}
.user_choose_wrapper {
width: 50rpx;
height: 50rpx;
margin-left: 30rpx;
}
.user_choose_wrapper image {
width: 50rpx;
height: 50rpx;
display: block;
object-fit: contain;
}
.user_title_wrapper {
font-weight: 400;
font-size: 28rpx;
color: #239ea3;
line-height: 1;
}
.user_name_wrapper {
font-weight: 400;
font-size: 28rpx;
color: #0d0d0d;
line-height: 1;
}
.user_wrapper {
height: 80rpx;
padding-left: 40rpx;
padding-right: 20rpx;
background: #ffffff;
border-radius: 40rpx 0 0 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
.header_wrapper {
display: flex;
align-items: center;
justify-content: space-between;
width: 750rpx;
height: 100rpx;
background: #d8edf2;
margin: 0 auto;
position: relative;
z-index: 999;
}
.hospital_wrapper {
display: flex;
align-items: center;
width: 50%;
}
.hospital_icon_wrapper {
width: 48rpx;
height: 48rpx;
margin-left: 20rpx;
}
.hospital_icon_wrapper image {
width: 48rpx;
height: 48rpx;
display: block;
object-fit: contain;
}
.hospital_name_wrapper {
font-weight: 400;
font-size: 28rpx;
color: #484747;
margin-left: 9rpx;
line-height: 1;
}
.hospital_select_wrapper {
width: 24rpx;
height: 14rpx;
margin-left: 19rpx;
}
.hospital_select_wrapper image {
width: 24rpx;
height: 14rpx;
display: block;
object-fit: contain;
}
</style>