套餐列表,套餐筛选

main
yanzai 11 months ago
parent 3341f6d7db
commit ba482f8095

@ -48,6 +48,10 @@ class ComboController extends Controller
$combo_item = $request->post('combo_item');
$checkup_type_id = $request->post('checkup_type_id');
$keshi_name=$request->post('keshi_name');
$price_range=$request->post('price_range');
$sort_price=$request->post('sort_price');
$sort_sale_count=$request->post('sort_sale_count');
$hospital = DB::table('hospitals')->select('id', 'name', 'address', 'latitude', 'longitude')->where(['id' => $hospital])->first();
$user = DB::table('web_users')->where(['openid' => $openid, 'status' => 1, 'is_del' => 0])->first();
@ -59,7 +63,7 @@ class ComboController extends Controller
$canshu = [];
$canshu[]=$person->sex;
$sql = '';
if (isset($combo_price)) {
if (isset($combo_price) and !isset($price_range)) {
$price_list = [
"1" => [0, 299],
"2" => [300, 999],
@ -71,8 +75,13 @@ class ComboController extends Controller
$sql = " and (a.price>=? and a.price<=?) ";
$canshu[] = $price_list[$combo_price][0];
$canshu[] = $price_list[$combo_price][1];
}
if (isset($price_range) and !isset($combo_price)) {
$sql = " and (a.price>=? and a.price<=?) ";
$canshu[] = $price_range[0];
$canshu[] = $price_range[1];
}
if(isset($checkup_type_id)){
$sql = $sql . " and a.checkup_type_id=? ";
$canshu[] = $checkup_type_id;
@ -92,9 +101,12 @@ class ComboController extends Controller
$sql = $sql . " and a.name like ? ";
$canshu[] = '%'.$search.'%';
}
if (!isset($combo_sort)) {
$sql = $sql . " order by a.order ";
}
if(isset($sort_price) and $sort_price==1) $combo_sort=3;
if(isset($sort_price) and $sort_price==2) $combo_sort=4;
if(isset($sort_sale_count) and $sort_sale_count==1) $combo_sort=7;
if(isset($sort_sale_count) and $sort_sale_count==2) $combo_sort=8;
if (isset($combo_sort)) {
if ($combo_sort == 1) {
$sql = $sql . " ";
@ -114,7 +126,15 @@ class ComboController extends Controller
if ($combo_sort == 6) {
$sql = $sql . " order by b.count ";
}
if ($combo_sort == 7) {
$sql = $sql . " order by a.sale_count ";
}
if ($combo_sort == 8) {
$sql = $sql . " order by a.sale_count desc";
}
}
if (!isset($combo_sort)) {
$sql = $sql . " order by a.order ";
}
if(isset($keshi_name)){
$combo_ids=DB::table('combo_items')->where(['status'=>1,'keshi_name'=>$keshi_name]) ->pluck('combo_id')->toArray();
@ -208,12 +228,46 @@ select combo_id as c_id,count(*) as count from combo_items where status in(1) gr
'id' => $doctor,
'name' => '张大夫'
];
//获取套餐价格分布
$step = 500;
$maxPrice = 20000 + $step;
$result=DB::select("SELECT FLOOR(price / ?) * ? AS price_range_start, COUNT(*) AS count
FROM combos
WHERE price >= 0 AND price < ?
GROUP BY price_range_start;",[$step,$step,$maxPrice]);
$price_ranges = [];
for ($i = 0; $i <= 20000; $i += $step) {
$price_ranges[$i] = 0;
}
foreach ($result as $row) {
if (isset($price_ranges[$row->price_range_start])) {
$price_ranges[$row->price_range_start] = $row->count;
}
}
$formatted_price_ranges = [];
$formatted_price_ranges[]=['start' => 0,
'count' => 0];
foreach ($price_ranges as $start => $count) {
// 如果你想包括结束值,可以添加 'end' 键,例如:'end' => $start + 99
$formatted_price_ranges[] = [
'start' => $start,
'count' => $count
];
}
$price_max_min=DB::select("SELECT
MAX(price) AS highest_price,
MIN(price) AS lowest_price
FROM combos;");
return \Yz::Return(true, '获取成功', [
'list' => $combos,
'hospital' => $hospital_info,
'doctor' => $doctor_info,
'info' => $info,
'price_range' => $formatted_price_ranges,
'price_max_min' =>isset($price_range)?$price_range:[0,$maxPrice],
'price_max' =>$maxPrice,
'step' => $step,
]);
}

@ -2,18 +2,18 @@
<view>
<view>
<view class="chart_wrapper" id="line">折线图</view>
<view class="chart_wrapper" id="line"></view>
<view class="huakuai_k">
<view class="huakuai_value">
<view>{{rang0}}</view>
<view>{{rang1}}</view>
</view>
<view>
<slider @changing="huakuai0_change" activeColor="#5ab6b8" block-color="#5ab6b8" block-size="18" backgroundColor="#5ab6b8" class="huakuai0" max="99999" :value="rang0" >
<slider @change="huakuai0SendValue" @changing="huakuai0_change" activeColor="#5ab6b8" block-color="#5ab6b8" block-size="18" backgroundColor="#5ab6b8" class="huakuai0" :step="step" :max="rangMax" :value="rang0" >
</slider>
</view>
<view class="huakuai1"><slider @changing="huakuai1_change" block-size="18" block-color="#5ab6b8" activeColor="#5ab6b8" backgroundColor="#5ab6b8" max="99999" :value="rang1" /></view>
<view class="huakuai1"><slider @change="huakuai1SendValue" @changing="huakuai1_change" block-size="18" block-color="#5ab6b8" activeColor="#5ab6b8" backgroundColor="#5ab6b8" :step="step" :max="rangMax" :value="rang1" /></view>
</view>
</view>
@ -23,13 +23,66 @@
<script setup>
import {
ref,
onMounted
onMounted,defineEmits,watch
} from 'vue'
import * as echarts from 'echarts';
let rang0=ref(0);
let rang1=ref(99999);
const props = defineProps({
dataInfo: {
type: Object,
required: true
} ,
rangDate: {
type: Array,
required: true
},
step: {
type: Number,
required: true
},
rangMax: {
type: Number,
required: true
}
})
let rang0=ref(0);
let rang1=ref(0);
let rangMax=ref(0);
rangMax.value=Number(props.rangMax);
rang0.value=Number(props.rangDate[0])
rang1.value=Number(props.rangDate[1])
watch(() => props.rangDate, (newrangDate) => {
console.log(props.rangDate);
rang0.value=newrangDate[0]
rang1.value=newrangDate[1]
}, { immediate: false });
const emit = defineEmits(['huakuaiValue']);
const huakuai0SendValue=(e)=> {
rang0.value= rang0.value=e.detail.value
if(rang0.value>rang1.value){
let temp=0
temp=rang0.value
rang0.value=rang1.value
rang1.value=temp
}
emit('huakuaiValue', [rang0.value,rang1.value]);
}
const huakuai1SendValue=(e)=>{
rang1.value= rang1.value=e.detail.value
if(rang0.value>rang1.value){
let temp=0
temp=rang0.value
rang0.value=rang1.value
rang1.value=temp
}
emit('huakuaiValue', [rang0.value,rang1.value]);
}
onMounted(() => {
drawChart()
})
const huakuai0_change=(e)=>{
rang0.value=e.detail.value
@ -52,11 +105,24 @@
const drawChart = () => {
let chartDom = document.getElementById('line');
let myChart = echarts.init(chartDom);
let xdata=[];
let ydata=[];
props.dataInfo.forEach((v,i)=>{
xdata.push(v.i)
ydata.push(v.count)
})
let option = {
grid: {
left: '10%',
right: '10%',
top: '0%',
bottom: '0%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
data:xdata,
axisLine: { show: false }, // X线
axisTick: { show: false }, // X
axisLabel: { show: false } // X
@ -70,7 +136,7 @@
},
series: [
{
data: [0,8, 12,7 ,33, 5,5],
data: ydata,
type: 'line',
lineStyle: {
width: 0 ,// 线线0
@ -96,13 +162,14 @@
<style scoped>
.chart_wrapper{
height: 200rpx;
height: 100rpx;
width: 100% !important;
/* border:1px solid #ccc; */
}
.huakuai_k{
position: relative;
width: 100%;
top:-120rpx;
top:-40rpx;
}
.huakuai0{
position: relative;

@ -83,6 +83,13 @@
"navigationBarBackgroundColor": "#D8EDF2",
"navigationBarTextStyle": "black"
}
},{
"path": "pages/main/tj/tjzx_new",
"style": {
"navigationBarTitleText": "体检套餐加项",
"navigationBarBackgroundColor": "#D8EDF2",
"navigationBarTextStyle": "black"
}
},
{
"path": "pages/buy/done/done",

File diff suppressed because it is too large Load Diff

@ -0,0 +1,590 @@
<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 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(""); //
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;
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);
}
}
}
onShow(() => {
if (!!config_ref.value) {
mountedAction();
}
});
</script>
<template>
<DraggableButton />
<view>
<view v-if="!!$store.config">
<view :ref="configRef"></view>
</view>
</view>
<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
class="fixed bottom-0 left-0 w-100% h-135rpx bg-gradient-to-r from-#7fcfd3 to-#aad7d7 px-20rpx py-30rpx box-border items-center flex justify-between"
>
<text
class="text-26rpx text-#121212 b-r-1 b-r-solid b-#8D9698 pr-12rpx mr-12rpx min-w-120rpx max-w-120rpx"
>
您需付费 \n{{ total }}个项目
</text>
<view class="grow">
<view class="flex items-end" v-if="comboId != 0">
<text class="text-18rpx text-#878787">套餐价格</text>
<text class="text-21rpx text-#ED6907 mx-20rpx"
>¥ {{ packagePrice }}</text
>
<text class="text-18rpx text-#878787 line-through"
>¥ {{ packageOriginalPrice }}</text
>
</view>
<view class="flex items-end">
<text class="text-18rpx text-#878787">自选项目价格</text>
<text class="text-21rpx text-#ED6907 mx-20rpx"
>¥ {{ optionalPrice || 0 }}</text
>
<text
v-if="optionalOriginalPrice"
class="text-18rpx text-#878787 line-through"
>¥ {{ optionalOriginalPrice }}</text
>
</view>
<view class="flex items-end">
<text class="text-18rpx text-#ED6907">合计费用</text>
<text class="text-24rpx text-#ED6907 ml-20rpx mr-5rpx">¥</text>
<text class="text-36rpx text-#ED6907 mr-20rpx font-bold">{{
totalPrice || 0
}}</text>
<text
v-if="totalOriginalPrice"
class="text-18rpx text-#878787 line-through"
>¥ {{ totalOriginalPrice }}</text
>
</view>
</view>
<button
type="primary"
@click="confirm()"
class="text-#F8F8F8 w-240rpx h-hull rounded-full !bg-#239EA3 !mx-0 text-30rpx"
>
确定
</button>
</view>
</template>
<style>
.uni-tooltip-popup {
background-color: #fff;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Loading…
Cancel
Save