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.

626 lines
18 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年9月11日 19:24:50
*/
import {
ref
} from "vue";
import {
$api,
$response,
$image
} from "@/api";
import {
onShow
} from "@dcloudio/uni-app";
import {
useStore
} from "@/store";
// comboId 套餐ID 没有套餐ID就是个人自选项目
// itemIds 自选ID
const $props = defineProps({
comboId: {
type: String,
default: "",
},
itemIds: {
type: String,
default: "",
},
personId: {
type: String,
default: "",
},
groupId: {
type: String,
default: "",
},
wj: {
type: String,
default: "",
},
});
const $store = useStore();
let wj = ref(""); //
let leftList = ref({}); // 左侧列表
let tabIndex = ref(""); // 默认选中
let rightLeft = ref([]); // 右侧列表
let selectIds = ref([]); // 选中id列表
let selectItems = ref([]); // 选中项目列表
let BuyInfo = ref(""); //BuyInfo接口返回
let headImg = ref(""); // 头部图片
let packagePrice = ref(0); //套餐折扣价格
let packageOriginalPrice = ref(0); //套餐原始价格
let optionalPrice = ref(0); //自选折扣价格
let optionalOriginalPrice = ref(0); //自选原始价格
let totalPrice = ref(0); // 总折扣价格
let totalOriginalPrice = ref(0); // 总原始价格
let total = ref(0); // 总项目数
let comboId = ref(""); // 套餐id
let recommendPackageList = ref([]); // 推荐套餐列表
let popup = ref(null); // 推荐套餐弹窗
let popupTip = ref(null); // 剩余额度提示弹窗
let groupLength = ref(0); // 团检自带的套餐数量
let status = ref(0); // 1个检套餐 2个检自选 3团检套餐 4团检自选
let personId = ref(""); // 就诊人ID
let groupId = ref(""); // 团检id
let losePrice = ref(0); // 剩余金额
// let query = ref(""); // 参数
let popupItemList = ref(null); //已选项目列表弹窗
const getComboRecommend = async () => {
// 获取推荐套餐
const response = await $api("ComboRecommend", {
person_id: personId.value,
item_ids: selectIds.value,
});
$response(response, () => {
recommendPackageList.value = response.data.combos;
if (recommendPackageList.value.length > 0) {
popup.value.open("center");
} else {
toDetails();
}
uni.hideLoading();
});
};
const getAllItems = async (e) => {
// 获取全部项目
const response = await $api("GetAllItems", {
search: e?.value,
});
$response(response, () => {
leftList.value = response.data.list;
if (Object.keys(leftList.value).length) {
let keys = Object.keys(leftList.value);
tabIndex.value = keys[0];
rightLeft.value = leftList.value[keys[0]].children;
headImg.value = leftList.value[keys[0]].head_img;
}
});
};
const getBuyInfo = async () => {
// 获取购买信息
uni.showLoading({
title: "加载中",
});
let obj = {
item_ids: selectIds.value,
hospital: $store.save_info.hospital,
person_id: personId.value,
group_id: groupId.value,
combo_id: comboId.value,
wj: wj.value,
};
if (comboId.value) {
obj.combo_id = comboId.value;
}
const response = await $api("BuyInfo", obj);
console.log(response)
if (response.status === false) {
uni.hideLoading();
uni.$lu.toast(response.msg);
return false;
}
$response(response, () => {
groupLength.value = response.data.group_info ?
response.data.group_info[0]?.items?.length :
0;
packagePrice.value = response.data.combo_info.price;
packageOriginalPrice.value = response.data.combo_info.original_price;
optionalPrice.value = response.data.items_info.price;
optionalOriginalPrice.value = response.data.items_info.original_price;
BuyInfo.value = response.data;
totalPrice.value = response.data.true_price;
totalOriginalPrice.value = response.data.original_price;
//total.value = response.data.pay_item_count;
losePrice.value = response.data.lose_price;
if (status.value == 4 && groupLength.value) {
// 团检无套餐ID的情况下需要判断一下 是否有团检自带套餐
status.value = 3;
}
uni.hideLoading();
});
};
const confirm = async () => {
// 确定
// status 1个检套餐 2个检自选 3团检套餐 4团检自选
if (status.value == 3) {
// 团检套餐
// query.value = "?groupId=" +
// groupId.value +
// "&itemIds=" +
// itemIds +
// "&comboId=" +
// comboId.value;
}
if (status.value == 4) {
// 团检自选
if (!selectIds.value.length) {
uni.$lu.toast("请选择项目");
return;
}
if (!groupLength.value) {
// 团检项目为空的话需要弹推荐套餐
getComboRecommend();
return;
}
}
if (status.value == 1) {
// 个检套餐
// query.value = "?itemIds=" + itemIds + "&comboId=" + comboId.value;
}
if (status.value == 2) {
// 个检自选
// query.value = "?itemIds=" + itemIds + "&personId=" + personId.value;
if (!selectIds.value.length) {
uni.$lu.toast("请选择项目");
return;
}
// 自选触发推荐套餐
getComboRecommend();
return;
}
toDetails();
};
const toDetails = (state) => {
// 去详情页
if (losePrice.value > 0 && !state) {
// popupTip.value.open("center"); // 弹剩余额度提醒
//return;
}
const itemIds = selectIds.value.length > 0 ? selectIds.value.join(",") : "";
let query = "?comboId=" + comboId.value + "&itemIds=" + itemIds;
if (groupId.value) {
query += "&groupId=" + groupId.value;
}
if ($props.wj) {
query += "&wj=" + $props.wj
}
console.log($props.comboId || $props.itemIds ? 2 : 1);
let delta = 0;
if (groupId.value) {
if (groupLength.value) {
delta = 2;
} else {
if ($props.comboId || $props.itemIds) {
delta = 2;
} else {
delta = 1;
}
}
} else {
if ($props.comboId || $props.itemIds) {
delta = 2;
} else {
delta = 1;
}
}
uni.navigateBack({
delta: delta,
success: () => {
let time = setTimeout(
() => {
clearTimeout(time);
uni.navigateTo({
url: "/pages/main/tj/tjxq" + query,
});
},
delta == 2 ? 800 : 500
);
},
});
};
const buy = async (item) => {
if (item) {
comboId.value = item.combo_id;
selectIds.value = [];
await getBuyInfo();
}
// 预约套餐
popup.value.close(); // 关闭推荐套餐弹窗
toDetails();
};
const mountedAction = async () => {
selectIds.value = $props.itemIds ? $props.itemIds.split(",") : [];
comboId.value = $props.comboId || "";
personId.value = $store.getUser().person_id || "";
groupId.value = $props.groupId || "";
wj.value = $props.wj || "";
if (groupId.value) {
if (comboId.value) {
// 团检套餐
status.value = 3;
} else {
// 团检自选
status.value = 4;
}
} else {
if (comboId.value) {
// 个检套餐
status.value = 1;
} else {
// 个检自选
status.value = 2;
}
}
console.log(status.value, "1个检套餐 2个检自选 3团检套餐 4团检自选");
await getAllItems(); // 获取全部项目
// await getComboRecommend();
await getBuyInfo(); // 获取购买信息
};
const config_ref = ref(null);
const configRef = (e) => {
if (!config_ref.value) {
config_ref.value = e;
mountedAction();
}
};
const XuanZeItem = async (item) => {
let doi = ""
if (selectIds.value.includes(item.id)) {
selectIds.value.splice(selectIds.value.indexOf(item.id), 1);
doi = "del"
} else {
selectIds.value.push(item.id);
doi = "add"
}
let a = await getBuyInfo()
if (a === false) {
if (doi == "add") {
selectIds.value.splice(selectIds.value.indexOf(item.id), 1);
}
if (doi == "del") {
selectIds.value.push(item.id);
}
}
}
const openPopupItemList = () => {
selectItems.value = [];
if (BuyInfo.value.items_info) {
BuyInfo.value.items_info.items.forEach((v, i) => {
v.children.forEach((v2, i2) => {
selectItems.value.push(v2)
})
})
}
if (selectItems.value.length > 0) {
popupItemList.value.open()
}
}
const ClearItems=async()=>{
selectIds.value=[];
await getBuyInfo()
popupItemList.value.close()
}
onShow(() => {
if (!!config_ref.value) {
mountedAction();
}
});
</script>
<template>
<DraggableButton />
<view>
<view v-if="!!$store.config">
<view :ref="configRef"></view>
</view>
</view>
<uni-popup ref="popupItemList" type="bottom">
<view class="popupItemList-content">
<view style="display: flex;justify-content: space-between;margin-bottom: 34rpx;">
<view style="font-size: 30rpx;">已加购项目</view>
<view style="color: #9E9E9F;display: flex;align-items: center;" @click="ClearItems()">
<uni-icons type="trash" color="#9E9E9F" size="20"></uni-icons>
<view style="font-size: 20rpx;">清空</view>
</view>
</view>
<view v-for="(item,index) in selectItems">
<view class="itemlist_list" @click="XuanZeItem(item)">
<view>
<view style="display: flex; align-items: center;margin-bottom: 20rpx;">
<view class="itemlist_bianhao">{{index+1}}</view>
<view class="itemlist_itemname">{{item.name}}</view>
</view>
<view style="display: flex;align-items: end;">
<view class="itemlist_price"><span style="font-size: 20rpx;">¥</span>{{item.price}}</view>
<view class="itemlist_org_price line-through">{{item.original_price}}</view>
</view>
</view>
<view :class="{
'!bg-#009fa8 !b-#008e99': selectIds.includes(item.id),
}" class="w-24rpx h-24rpx b-1 b-solid b-#009fa8 bg-#fff rounded-24rpx center">
<image v-if="selectIds.includes(item.id)" class="w-20rpx" src="@/static/assets/select.png"
mode="widthFix" />
</view>
</view>
</view>
</view>
</uni-popup>
<uni-popup ref="popupTip">
<view class="mb-70rpx bg-#fff text-center box-border pt-80rpx pb-50rpx px-65rpx w-90vw rounded-15rpx">
<view class="w-full text-center text-##090909 text-26rpx line-height-[50rpx]">您还剩余
{{ losePrice }}
元体检额度尚未使用,确认提交后剩余体检额度将无法使用!
</view>
<view class="mt-50rpx between">
<button type="primary" @click="toDetails(1)"
class="w-196rpx h-68rpx center text-#fff text-24rpx !bg-#239EA3 rounded-8rpx">
我想好了
</button>
<button @click="popupTip.close()"
class="w-196rpx h-68rpx center text-#239EA3 text-24rpx !bg-#D9F3F2 rounded-8rpx">
我再想想
</button>
</view>
</view>
</uni-popup>
<uni-popup ref="popup">
<view class="bg-#fff rounded-15rpx w-95vw px-20rpx box-border">
<view class="center relative pt-47rpx pb-32rpx text-36rpx">
<text class="line-height-[1]">推荐套餐</text>
<uni-icons @click="popup.close()" type="closeempty" color="#A6A6A6" size="26"
class="absolute right-40rpx top-30rpx"></uni-icons>
</view>
<view v-for="(item, index) in recommendPackageList" :key="index"
class="pt-40rpx pb-15rpx box-border b-0 b-t-1 b-solid b-#E1ECEE">
<view class="flex w-full">
<image v-if="item.cover" :src="$image(item.cover)" class="w-190rpx h-190rpx mr-37rpx"
mode="widthFix" />
<view class="flex flex-col grow">
<text>{{ item.name }}</text>
<view class="mt-13rpx mb-18rpx">
<uni-tag v-for="(val, i) in item.tags" :key="i" size="small" :inverted="true"
:text="val.text" class="mr-8rpx" :custom-style="
'background-color:' +
val.color +
';border-color:' +
val.color +
'; color:' +
val.text_color +
';'
" />
</view>
<view>
<text v-for="(val, i) in item.tags2" :key="i"
class="text-#8B8B8B text-20rpx line-height-[1] px-5rpx b-0 b-r-2 b-solid b-#8B8B8B">{{ val }}</text>
</view>
<view class="mt-20rpx w-full flex items-end">
<text class="text-18rpx text-#EC3D15">¥</text>
<text class="text-38rpx text-#EC3D15 mx-10rpx -mb-8rpx">{{
item.price
}}</text>
<text class="text-18rpx text-#878787 line-through">{{
item.original_price
}}</text>
<text class="text-18rpx text-#878787 ml-auto mr-55rpx">已售{{ item.count }}</text>
</view>
</view>
</view>
<view class="between mt-30rpx">
<view class="text-#8B8B8B text-22rpx">
相似度
<text class="text-#239EA3">{{ item.recommend?.xiangsidu }}</text>
{{ item.recommend?.count > 0 ? "增加" : "减少" }}了
<text class="text-#239EA3">{{
Math.abs(item.recommend?.count)
}}</text>
个项目,{{
Number(item.recommend?.money.replace(/,/, "")) > 0
? "增加"
: "减少"
}}了
<text class="text-#239EA3">¥{{ item.recommend?.money.replace(/-/, "") }}</text>
</view>
<button type="primary" @click="buy(item)"
class="w-160rpx h-60rpx center text-#fff text-28rpx !bg-#239EA3 rounded-full">
预约
</button>
</view>
</view>
<view class="b-0 b-t-1 b-solid b-#E1ECEE pt-80rpx pb-70rpx">
<button type="primary" @click="buy()"
class="w-300rpx h-78rpx center text-#fff text-30rpx !bg-#239EA3 rounded-10rpx">
跳过
</button>
</view>
</view>
</uni-popup>
<view class="bg-#d8edf2">
<uni-search-bar class="search" radius="100" placeholder="请输入关键字搜索" @clear="getAllItems()"
@cancel="getAllItems()" @confirm="getAllItems" />
</view>
<view class="mt-20rpx flex min-h-100%" style="background-color: #eef7f7;">
<view class="min-w-214rpx max-w-214rpx mr-20rpx min-h-100% text-center">
<view class="w-100% rounded-r-full text-#0E0E0E text-25rpx px-20rpx w-100% center h-84rpx box-border"
v-for="(item, index) in leftList" :key="index" :class="{
'bg-gradient-to-r from-#edf6f5 to-#bbdfe2': tabIndex == index,
}" @click="
() => {
tabIndex = index;
rightLeft = item.children;
headImg = item.head_img;
}
">
{{ item.title }}
</view>
<view style="height: 150rpx;"></view>
</view>
<view class="grow min-h-100% bg-#fff pb-200rpx">
<view v-for="(item, index) in rightLeft" :key="index" :class="{
'!b-0': index == rightLeft.length - 1,
}" class="flex justify-between center py-30rpx px-20rpx b-b-1px b-b-solid b-b-#e5e5e5">
<view class="w-40% text-#0E0E0E text-24rpx flex items-center">
<text>{{ item.title }}</text>
<uni-tooltip>
<!-- 定义插槽,插槽名为 content -->
<template v-slot:content>
<!-- 在这里编写自定义的 HTML 或组件 -->
<view class="w-30vw">
<text>{{ item.desc }}</text>
</view>
</template>
<!-- 触发提示的按钮 -->
<uni-icons color="#009fa8" type="help-filled" size="14"></uni-icons>
</uni-tooltip>
</view>
<view class="w-58% items-end flex justify-between" @click="XuanZeItem(item)">
<text class="text-#EC3D15 text-26rpx">¥ {{ item.price }}</text>
<text class="text-#9e9d9d text-20rpx line-through">¥ {{ item.original_price }}</text>
<view :class="{
'!bg-#009fa8 !b-#008e99': selectIds.includes(item.id),
}" class="w-24rpx h-24rpx b-1 b-solid b-#c3e9eb bg-#ccecee rounded-8rpx center">
<image v-if="selectIds.includes(item.id)" class="w-20rpx" src="@/static/assets/select.png"
mode="widthFix" />
</view>
</view>
</view>
</view>
</view>
<view style="z-index: 999;"
class="fixed bottom-0 left-0 w-100% h-150rpx bg-gradient-to-r from-#02b4bd to-#ABD7D7 px-20rpx py-30rpx box-border items-center flex justify-between">
<view style="position: relative;" class="w-110rpx h-129rpx ml-60rpx mt-5rpx" @click="openPopupItemList()">
<image class="w-110rpx h-129rpx" src="@/static/assets/buy/xiong.png" mode="widthFix" />
<view class="yuandian">
{{ selectIds.length }}
</view>
</view>
<view class="grow" style="margin-left: 10rpx;">
<view class="flex items-end">
<text class="text-46rpx text-#e95513 ml-20rpx mr-5rpx">¥</text>
<text class="text-46rpx text-#e95513 mr-10rpx font-bold">{{
optionalPrice || 0
}}</text>
<text v-if="optionalOriginalPrice" class="text-26rpx text-#3e3a39 line-through">¥
{{ optionalOriginalPrice }}</text>
</view>
</view>
<view @click="confirm()" class="button">
</view>
</view>
</template>
<style>
.uni-tooltip-popup {
background-color: #fff;
}
</style>
<style>
.button {
color: #00828e;
background-color: #fff;
height: 58rpx;
line-height: 58rpx;
text-align: center;
width: 174rpx;
border-radius: 58rpx;
margin-right: 20rpx;
font-size: 29rpx;
}
.popupItemList-content {
padding: 40rpx 40rpx 180rpx 40rpx;
border-radius: 40rpx;
background-color: #fff;
}
.yuandian {
position: absolute;
top: 55rpx;
right: -10rpx;
background-color: #E95513;
height: 26rpx;
width: 26rpx;
border-radius: 13rpx;
color: #fff;
font-size: 20rpx;
text-align: center;
font-weight: 900;
}
.itemlist_org_price {
color: #9E9E9F;
font-weight: bolder;
font-size: 18rpx;
margin-left: 10rpx;
padding-bottom: 5rpx;
}
.itemlist_price {
color: #E95513;
font-weight: bolder;
font-size: 32rpx;
}
.itemlist_itemname {
font-size: 30rpx;
font-weight: bolder;
}
.itemlist_list {
display: flex;
width: 100%;
justify-content: space-between;
border-bottom: 1px solid #00828e;
padding-bottom: 20rpx;
margin-bottom: 20rpx;
align-items: center;
}
.itemlist_bianhao{
height: 26rpx;
width: 26rpx;
margin-right: 10rpx;
border-radius: 26rpx;
line-height: 26rpx;
color: #fff;
font-size: 20rpx;
font-weight: bolder;
text-align: center;
background: linear-gradient(to right, #67a8aa, #8ce7e7);
}
</style>