Browse Source

add site select logic

dev
刘嘉炜 2 weeks ago
parent
commit
88651aa5b5
  1. 8
      src/subpackage/groupon/api/index.js
  2. 23
      src/subpackage/groupon/components/site/footer.vue
  3. 11
      src/subpackage/groupon/components/site/table.vue
  4. 17
      src/subpackage/groupon/js/site_select/handle.js
  5. 170
      src/subpackage/groupon/pages/site_select.vue

8
src/subpackage/groupon/api/index.js

@ -0,0 +1,8 @@
import server from '@/api/server';
export const venueTypes = params => server.post({ url: '/stadium/venue/types', ...params }); // 场馆类型
export const bookDate = params => server.post({ url: '/stadium/book/date', ...params }); // 可预订场馆列表
export const bookList = params => server.post({ url: '/stadium/book/list', ...params }); // 可预订场馆,矩阵图 时间+场馆

23
src/subpackage/groupon/components/site/footer.vue

@ -1,13 +1,15 @@
<script setup> <script setup>
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import { reactive, ref } from 'vue';
import { reactive, ref, computed } from 'vue';
import { accAdd } from "@/utils/calculation";
const emits = defineEmits([ 'click:clear' ]);
const props = defineProps({ const props = defineProps({
selectedData: { default: [] }, selectedData: { default: [] },
}) })
onLoad(() => {
});
const totalAmount = computed(_=>{
let _sData = props.selectedData ?? [];
return _sData?.length ? _sData.reduce((num, e, i) => accAdd(num, e?.price ?? 0), 0) : 0;
})
</script> </script>
<template> <template>
@ -15,13 +17,13 @@ onLoad(() => {
<view class="sf-selected" v-if="selectedData&&selectedData.length"> <view class="sf-selected" v-if="selectedData&&selectedData.length">
<view class="ss-top-bar"> <view class="ss-top-bar">
<view class="stb-select">已选择场次<text class="ss-num">{{ (selectedData&&selectedData.length) || 0 }}</text></view> <view class="stb-select">已选择场次<text class="ss-num">{{ (selectedData&&selectedData.length) || 0 }}</text></view>
<view class="stb-clear" @click="clearSelected">清空</view>
<view class="stb-clear" @click="emits('click:clear')">清空</view>
</view> </view>
<scroll-view class="vsm-selected" scroll-y> <scroll-view class="vsm-selected" scroll-y>
<view class="vs-list"> <view class="vs-list">
<view class="vl-item" v-for="(e, i) in selectedData" :key="i"> <view class="vl-item" v-for="(e, i) in selectedData" :key="i">
<view class="vi-view">{{ e.time || '-' }}</view> <view class="vi-view">{{ e.time || '-' }}</view>
<view class="vi-view">2</view>
<view class="vi-view">{{ e._venue_name ?? '-' }}</view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@ -48,8 +50,11 @@ onLoad(() => {
<view class="sf-submit-bar"> <view class="sf-submit-bar">
<view class="ssb-price">¥0.00 </view>
<view class="ssb-btn">请选择场地</view>
<view class="ssb-price">¥{{ totalAmount ?? 0 }}</view>
<view
class="ssb-btn"
:class="{ 'un-active': selectedData.length <=0 }"
>{{ selectedData.length ? '确定' : '请选择场地' }}</view>
</view> </view>
</view> </view>
</template> </template>

11
src/subpackage/groupon/components/site/table.vue

@ -12,8 +12,9 @@ const props = defineProps({
const timeList = computed(_=> { const timeList = computed(_=> {
let _table = props?.tableData; let _table = props?.tableData;
if(!_table?.length)return [];
if(_table?.length <= 0)return [];
let _items = _table?.[0]?.items ?? [], _tempArr; let _items = _table?.[0]?.items ?? [], _tempArr;
if(_items?.length <=0)return [];
_tempArr = _items.reduce((_arr, val)=>_arr.concat(val.time.split('-')), []); _tempArr = _items.reduce((_arr, val)=>_arr.concat(val.time.split('-')), []);
// //
// 00:00-00:30 && 23:00-00:00 // 00:00-00:30 && 23:00-00:00
@ -75,8 +76,8 @@ const itemClick = function(k, i, j){
@click="itemClick(k, i, j)" @click="itemClick(k, i, j)"
> >
<block v-if="k.is_valid"> <block v-if="k.is_valid">
<view class="sr-price">¥60.00</view>
<view class="sr-del" v-if="false">¥60.00</view>
<view class="sr-price">¥{{ k?.price ?? 0 }}</view>
<view class="sr-del" v-if="k.underlined_price_show">¥{{ k?.underlined_price_str ?? 0 }}</view>
</block> </block>
<view class="sr-sold" v-else>已售</view> <view class="sr-sold" v-else>已售</view>
</view> </view>
@ -192,6 +193,7 @@ const itemClick = function(k, i, j){
color: #9A9A9D; color: #9A9A9D;
} }
.sr-del{ .sr-del{
text-decoration: line-through;
@include flcw(20upx, 28upx, #9A9A9D); @include flcw(20upx, 28upx, #9A9A9D);
} }
&.green{ &.green{
@ -199,6 +201,9 @@ const itemClick = function(k, i, j){
.sr-price{ .sr-price{
color: #fff; color: #fff;
} }
.sr-del{
color: #fff;
}
} }
&.orange{ &.orange{
border-color: #FF873D; border-color: #FF873D;

17
src/subpackage/groupon/js/site_select/handle.js

@ -0,0 +1,17 @@
export function get_zh_day(date){
if(isSameDay(new Date().getTime(),new Date(date).getTime()))return '今天'
const Arr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return Arr[new Date(date).getDay()] || '';
}
// 判断是否同一天
export function isSameDay(timeStampA, timeStampB) {
let dateA = new Date(timeStampA);
let dateB = new Date(timeStampB);
return (dateA.setHours(0, 0, 0, 0) == dateB.setHours(0, 0, 0, 0));
}
// 获取中文日期
export function get_zh_date(date = new Date()){
return `${new Date(date).getMonth()+1}${new Date(date).getDate()}`
}

170
src/subpackage/groupon/pages/site_select.vue

@ -2,45 +2,153 @@
import { onLoad, onReady } from '@dcloudio/uni-app'; import { onLoad, onReady } from '@dcloudio/uni-app';
import { reactive, ref, computed, watch, nextTick } from 'vue'; import { reactive, ref, computed, watch, nextTick } from 'vue';
import { stadiumBookList } from "@/api"; import { stadiumBookList } from "@/api";
import { getNodeMes } from "@/utils/polish"
import { venueTypes, bookDate, bookList } from '../api';
import { getNodeMes, showModal } from "@/utils/polish";
import siteTable from "../components/site/table.vue"; import siteTable from "../components/site/table.vue";
import siteFooter from "../components/site/footer.vue"; import siteFooter from "../components/site/footer.vue";
const siteData = ref([]);
const scrollHeight = ref(0);
import { get_zh_day, get_zh_date } from "../js/site_select/handle";
const optQuery = ref({});
const siteData = ref([]); //
const scrollHeight = ref(0); // table
const venueTypeData = ref([]); //
const currentVenueType = ref({}); //
const bookDateData = ref([]); //
const currentBookDate = ref({}); //
const isShowTypeRuleTxt = ref(false);
const selectedData = computed(_=>{
const selectedData = computed(_=>{ //
let _temArr = []; let _temArr = [];
siteData.value.forEach(e=>{ siteData.value.forEach(e=>{
if(e?.items?.length)_temArr.push(...e?.items?.filter(ele=>ele?._is_selected))
if(e?.items?.length <= 0)return;
e?.items.forEach(ele=>{
if(!ele?._is_selected)return;
_temArr.push({
...ele,
_venue_id: e?.id ?? 0,
_venue_name: e?.name ?? ''
})
})
}); });
return _temArr return _temArr
}) })
watch(selectedData, val=>nextTick(setScrollViewSize)); watch(selectedData, val=>nextTick(setScrollViewSize));
onLoad(async (opts) => {
try{
const stadium_id = 167;
optQuery.value.stadium_id = stadium_id;
let _vtLs = await getTypeLs(stadium_id);
if(_vtLs?.length <=0)return showModal({ content: '没有场地类型!' });
let _cvt = currentVenueType.value = _vtLs[0];
let _dateLs = await getDateLs({ stadium_id, type_key: _cvt?.key ?? '', });
if(_dateLs?.length <= 0)return showModal({ content: '没有日期列表!' });
let _curDate = currentBookDate.value = _dateLs[0];
nextTick(setScrollViewSize)
getBookList({ stadium_id, type_key: _cvt?.key ?? '', date: _curDate?._date ?? '' });
}catch(err){
console.warn(`site select onload err-->`, err);
}
});
//
async function venueTypeChange(e){
let _cvt = venueTypeData.value[e.detail.value];
currentVenueType.value = _cvt;
bookDateData.value = [];
currentBookDate.value = {};
siteData.value = [];
try{
let stadium_id = optQuery?.value?.stadium_id ?? '';
let _dateLs = await getDateLs({ stadium_id, type_key: _cvt?.key ?? '', });
if(_dateLs?.length <= 0)return showModal({ content: '没有日期列表!' });
let _curDate = currentBookDate.value = _dateLs[0];
nextTick(setScrollViewSize)
getBookList({ stadium_id, type_key: _cvt?.key ?? '', date: _curDate?._date ?? '' });
}catch(err){
console.warn(`site select venueTypeChange err-->`, err);
}
}
//
async function bookDateChange(_date){
currentBookDate.value = _date;
siteData.value = [];
try{
let stadium_id = optQuery?.value?.stadium_id ?? '';
let _cvt = currentVenueType.value ?? {}
getBookList({ stadium_id, type_key: _cvt?.key ?? '', date: _date?._date ?? '' });
}catch(err){
console.warn(`site select bookDateChange err-->`, err);
}
}
//
function clearSelectedData(){
let stadium_id = optQuery?.value?.stadium_id ?? '';
let _key = currentVenueType.value?.key ?? '';
let _date = currentBookDate.value?._date ?? '';
getBookList({ stadium_id, type_key: _key, date: _date });
}
onLoad(() => {
stadiumBookList({ data: {
stadium_id: 167,
date: `2025-06-12`,
type_key: `631284d5-aed4-11ea-a89a-7085c2772a68`,
rule_type: 0,
brand_id: 63,
app_id: `wxc141a743225e7885`,
//
function getTypeLs(stadium_id){
return venueTypes({ data: { stadium_id }, catch: true })
.then(res=>{
return venueTypeData.value = res?.data ?? [];
})
}
//
function formateDateLs(dates){
if(dates?.length <= 0)return [];
return dates.map(e=>{
const _date = e.date.substr(0,10);
return {
...e,
_date,
_zh_day: get_zh_day(_date.replace(/\-/g,'/')),
_zh_date: get_zh_date(_date.replace(/\-/g,'/')),
}
})
};
//
function getDateLs({ stadium_id, type_key, num = 8 }){
return bookDate({
data: {
stadium_id,
type_key,
num
},
catch: true
})
.then(res=>{
return bookDateData.value = formateDateLs(res?.data ?? []);
});
}
// +
function getBookList({
app_id = 'wxc141a743225e7885',
brand_id = 63,
stadium_id,
date = '',
type_key = ``
}){
return bookList({ data: {
app_id,
brand_id,
stadium_id,
date,
type_key,
token: `dbce2d0c-ce5d-11ef-9e0f-5254005df464`, token: `dbce2d0c-ce5d-11ef-9e0f-5254005df464`,
enable_show_terminal: 1, enable_show_terminal: 1,
from_platform: `weixin`, from_platform: `weixin`,
} }) } })
.then(res=>{ .then(res=>{
siteData.value = res?.data;
return siteData.value = res?.data;
}) })
});
}
// Page.onReady // Page.onReady
onReady(_=>{ onReady(_=>{
setScrollViewSize(); setScrollViewSize();
})
});
// table
async function setScrollViewSize(){ async function setScrollViewSize(){
const _sysInfo = uni.getSystemInfoSync(true); const _sysInfo = uni.getSystemInfoSync(true);
let _headerInfo = await getNodeMes('#ssHeader'); let _headerInfo = await getNodeMes('#ssHeader');
@ -48,9 +156,7 @@ async function setScrollViewSize(){
let _footerInfo = await getNodeMes('#ssFooter'); let _footerInfo = await getNodeMes('#ssFooter');
let _otherHeight = _headerInfo?.height + _footerInfo?.height + _dateBarInfo?.height; let _otherHeight = _headerInfo?.height + _footerInfo?.height + _dateBarInfo?.height;
scrollHeight.value = _sysInfo?.windowHeight - (_otherHeight || 0); scrollHeight.value = _sysInfo?.windowHeight - (_otherHeight || 0);
console.log(scrollHeight.value);
} }
</script> </script>
<template> <template>
@ -61,22 +167,28 @@ async function setScrollViewSize(){
<view class="ss-name">MJ体育(天空篮球从云店)</view> <view class="ss-name">MJ体育(天空篮球从云店)</view>
</view> </view>
<view class="sh-bottom"> <view class="sh-bottom">
<picker class="sb-classify">
<view class="sc-txt">羽毛球</view>
<picker class="sb-classify" mode='selector' :range="venueTypeData" range-key="name" @change="venueTypeChange">
<view class="sc-txt">{{ currentVenueType?.name ?? '-' }}</view>
<view class="sc-icon">&#xe695;</view> <view class="sc-icon">&#xe695;</view>
</picker> </picker>
<view class="sb-desc"> <view class="sb-desc">
<view class="sd-txt">1+2号或3号+4号为一个全场</view>
<view class="sd-arrow-cover"><text>&#xe695;</text></view>
<view class="sd-full-txt" v-if="false">1号+2号或3号+4号为一个全场</view>
<view class="sd-txt">{{ currentVenueType?.rule_text ?? '' }}</view>
<view class="sd-arrow-cover" @click="isShowTypeRuleTxt = !isShowTypeRuleTxt" v-if="currentVenueType?.rule_text?.length > 17"><text>&#xe695;</text></view>
<view class="sd-full-txt" v-if="isShowTypeRuleTxt&&currentVenueType?.rule_text?.length > 17">{{ currentVenueType?.rule_text ?? '' }}</view>
</view> </view>
</view> </view>
</view> </view>
<view class="ss-main"> <view class="ss-main">
<scroll-view class="sm-dates" id="smDates" scroll-x> <scroll-view class="sm-dates" id="smDates" scroll-x>
<view class="sd-item" :class="{ active: i === 1 }" v-for="i in 20" :key="i">
<view class="si-week">今天</view>
<view class="si-day">6月10日</view>
<view
class="sd-item"
:class="{ active: currentBookDate.date === e.date }"
v-for="(e, i) in bookDateData"
:key="i"
@click="bookDateChange(e)"
>
<view class="si-week">{{ e._zh_day ?? '-' }}</view>
<view class="si-day">{{ e._zh_date ?? '-' }}</view>
</view> </view>
</scroll-view> </scroll-view>
<site-table <site-table
@ -86,7 +198,7 @@ async function setScrollViewSize(){
></site-table> ></site-table>
</view> </view>
<view class="ss-footer" id="ssFooter"> <view class="ss-footer" id="ssFooter">
<site-footer :selected-data="selectedData"></site-footer>
<site-footer :selected-data="selectedData" @click:clear="clearSelectedData"></site-footer>
</view> </view>
</view> </view>
</template> </template>

Loading…
Cancel
Save