Browse Source

add logic

dev
刘嘉炜 2 weeks ago
parent
commit
1758520c5b
  1. 2
      src/api/server.js
  2. 35
      src/subpackage/groupon/components/confirm_template.vue
  3. 11
      src/subpackage/groupon/components/ticket_item.vue
  4. 39
      src/subpackage/groupon/pages/confirm_order/ticket.vue
  5. 28
      src/subpackage/groupon/pages/list.vue
  6. 38
      src/subpackage/groupon/pages/site_select.vue
  7. 78
      src/subpackage/groupon/pages/stadiums.vue
  8. BIN
      src/subpackage/groupon/static/images/ticket_icon.png

2
src/api/server.js

@ -20,6 +20,8 @@ server.interceptors.request.use(
config => {
let _token = uni.getStorageSync('token');
if(_token)config.data.token = _token;
// 后端: 加这个好像就不用传品牌id了吧
config.data.from_platform = 'ouxuan_org_douyin';
loading.show(config.loading);
return config;
},

35
src/subpackage/groupon/components/confirm_template.vue

@ -1,6 +1,24 @@
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { reactive, ref } from "vue";
const props = defineProps({
stadiumLogo: {
type: String,
default: ''
},
stadiumName: {
type: String,
default: ''
},
stadiumAddress: {
type: String,
default: ''
},
payAmount: {
type: Number,
default: -1
}
});
onLoad(() => {
});
@ -11,17 +29,17 @@ onLoad(() => {
<view class="confirm-template">
<view class="ct-stadium">
<view class="cs-top">
<view class="ct-logo"></view>
<view class="ct-name">MJ体育(天空篮球从云店)</view>
<image v-if="stadiumLogo" class="ct-logo" mode="aspectFit" :src="stadiumLogo || ''"></image>
<view class="ct-name">{{ stadiumName || '-' }}</view>
</view>
<view class="cs-detail">地址白云区从云路822号城市像素6楼电梯5楼走到6楼</view>
<view class="cs-detail">地址{{ stadiumAddress || '-' }}</view>
</view>
<slot></slot>
<view class="ct-fixed">
<view class="cf-price">
<text class="cp-txt">应付金额</text> ¥0.00
<view class="cf-price" v-if="payAmount >= 0">
<text class="cp-txt">应付金额</text> ¥{{ payAmount }}
</view>
<view class="cf-btn">确认兑换</view>
<view class="cf-btn" :class="{ 'cf-full': payAmount < 0 }">确认兑换</view>
</view>
</view>
</template>
@ -39,7 +57,6 @@ onLoad(() => {
margin-right: 20upx;
width: 36upx;
height: 36upx;
background: skyblue;
}
.ct-name{
flex-grow: 1;
@ -70,6 +87,10 @@ onLoad(() => {
border-radius: 20upx;
background-color: $redColor;
@include flcw(32upx, 88upx, #fff);
&.cf-full{
flex-grow: 1;
width: auto;
}
}
.cf-price{
flex-grow: 1;

11
src/subpackage/groupon/components/ticket_item.vue

@ -13,6 +13,14 @@ const props = defineProps({
endTimeStamp: {
type: Number,
default: 0
},
orderId: {
type: String,
default: ''
},
isUseBtn: {
type: Boolean,
default: false
}
});
@ -31,8 +39,9 @@ const endTime = computed(() => {
<view class="ti-left">
<view class="tl-tit">{{ ticketName ?? '' }}</view>
<view class="tl-time" v-if="endTime">有效时间{{ startTime }}{{ endTime }}</view>
<view class="tl-time" v-if="orderId">核销券号{{ orderId }}</view>
</view>
<view class="ti-btn" @click="emits('click:use')">立即使用</view>
<view v-if="isUseBtn" class="ti-btn" @click="emits('click:use')">立即使用</view>
</view>
</template>

39
src/subpackage/groupon/pages/confirm_order/ticket.vue

@ -1,36 +1,58 @@
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { reactive, ref } from "vue";
import { reactive, ref, onMounted, getCurrentInstance, computed } from "vue";
import confirmTemplate from "../../components/confirm_template.vue";
import ticketItem from "../../components/ticket_item.vue";
const stadiumInfo = ref({}); //
const ticketInfo = ref({}); //
onLoad(() => {
});
const expireTimeStr = computed(() => {
return ticketInfo.expire_time ? new Date(ticketInfo.expire_time * 1000).toLocaleDateString() : '';
});
onMounted(() =>{
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel();
eventChannel.on('dataFromGrouponStadiums', function(data) {
ticketInfo.value = data?.ticket || {};
stadiumInfo.value = data?.stadium || {};
})
})
</script>
<template>
<confirm-template>
<confirm-template
:stadiumLogo="stadiumInfo?.logo || ''"
:stadiumName="stadiumInfo?.name || ''"
:stadiumAddress="stadiumInfo?.address || ''"
>
<view class="ticket-info">
<view class="ti-content">
<view class="tc-tit">产品信息</view>
<view class="tc-price">
<view class="tp-left">单次卡</view>
<view class="tp-right">¥15</view>
<view class="tp-left">{{ ticketInfo?.merchandise_name ?? '-' }}</view>
<!-- pm: 次卡这里把价格隐藏掉吧 -->
<!-- <view class="tp-right">¥15</view> -->
</view>
<view class="tc-time">
<view class="tt-val">有效期至2020-10-16 15:45:20</view>
<view class="tt-val">有效期至{{ expireTimeStr ?? '-' }}</view>
<view class="tt-val">x1</view>
</view>
<view class="tc-line"></view>
<view class="tc-ticket-info">
<view class="tti-icon"></view>
<image class="tti-icon" mode="aspectFit" src="@/subpackage/groupon/static/images/ticket_icon.png"></image>
<view class="tti-right">
<view class="tr-txt">团购券 <text class="tt-orange">已选1张</text> </view>
<view class="tr-price">-¥15</view>
<!-- pm: 次卡这里把价格隐藏掉吧 -->
<!-- <view class="tr-price">-¥15</view> -->
</view>
</view>
<ticket-item></ticket-item>
<ticket-item
:ticketName="ticketInfo?.dy_title ?? '-'"
:orderId="ticketInfo?.order_id ?? ''"
></ticket-item>
</view>
</view>
</confirm-template>
@ -87,7 +109,6 @@ onLoad(() => {
flex-shrink: 0;
width: 40upx;
height: 40upx;
background: skyblue;
}
.tti-right{
flex-grow: 1;

28
src/subpackage/groupon/pages/list.vue

@ -17,14 +17,32 @@ onLoad(() => {
}
})
.then(res => {
console.log('票券列表--->', res);
if(res?.data?.data?.total === 0)return showModal({ content: '暂无票券' });
ticketLs.value = res.data?.data?.orders || [];
});
});
function ticketClick(){
routeTo('/subpackage/groupon/pages/stadiums');
function ticketClick(e){
let [ certificates ] = e?.certificates || [];
let _ouxuan_group_purchase_info = certificates?.sku_info?.ouxuan_group_purchase_info ?? {};
let _merchandise_type = _ouxuan_group_purchase_info?.merchandise_type;
if(![0, 1].includes(_merchandise_type))return showModal({ content: '无效的商品类型' });
let _ticketInfo = {
order_id: e?.order_id ?? '',
expire_time: certificates?.expire_time ?? 0,
dy_title: certificates?.sku_info?.title ?? '',
merchandise_name: _ouxuan_group_purchase_info?.merchandise_name ?? '',
// merchandise_type 1-> 0->
merchandise_type: _ouxuan_group_purchase_info?.merchandise_type,
}
uni.navigateTo({
url: `/subpackage/groupon/pages/stadiums`,
success: res => {
// eventChannel
res.eventChannel.emit('dataForGrouponStadiums', { ticket: _ticketInfo });
}
});
}
</script>
@ -33,10 +51,12 @@ function ticketClick(){
<view class="groupon-list">
<view class="gl-item" v-for="(e, i) in ticketLs" :key="i">
<ticket-item
isUseBtn
:ticketName="e?.certificates?.[0]?.sku_info?.title ?? ''"
:startTimeStamp="e?.certificates?.[0]?.start_time ?? 0"
:endTimeStamp="e?.certificates?.[0]?.expire_time ?? 0"
@click:use="ticketClick"></ticket-item>
@click:use="ticketClick(e)"
></ticket-item>
</view>
</view>
</template>

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

@ -1,6 +1,6 @@
<script setup>
import { onLoad, onReady } from '@dcloudio/uni-app';
import { reactive, ref, computed, watch, nextTick } from 'vue';
import { reactive, ref, computed, watch, nextTick, onMounted, getCurrentInstance } from 'vue';
import { stadiumBookList } from "@/api";
import { venueTypes, bookDate, bookList } from '../api';
import { getNodeMes, showModal } from "@/utils/polish";
@ -15,6 +15,8 @@ const currentVenueType = ref({}); // 当前场地类型
const bookDateData = ref([]); //
const currentBookDate = ref({}); //
const isShowTypeRuleTxt = ref(false);
const stadiumInfo = ref({}); //
const ticketInfo = null; //
const selectedData = computed(_=>{ //
let _temArr = [];
@ -34,10 +36,18 @@ const selectedData = computed(_=>{ // 已选中场地
watch(selectedData, val=>nextTick(setScrollViewSize));
onLoad(async (opts) => {
onMounted(() =>{
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel();
eventChannel.on('dataFromGrouponStadiums', data => {
ticketInfo = data?.ticket || {};
stadiumInfo.value = data?.stadium || {};
if(!stadiumInfo.value?.id)return showModal({ content: '无效的场馆信息' });
initPage(data?.stadium?.id);
})
})
async function initPage(stadium_id){
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];
@ -49,7 +59,7 @@ onLoad(async (opts) => {
}catch(err){
console.warn(`site select onload err-->`, err);
}
});
}
//
async function venueTypeChange(e){
let _cvt = venueTypeData.value[e.detail.value];
@ -58,7 +68,7 @@ async function venueTypeChange(e){
currentBookDate.value = {};
siteData.value = [];
try{
let stadium_id = optQuery?.value?.stadium_id ?? '';
let stadium_id = stadiumInfo?.value?.id ?? '';
let _dateLs = await getDateLs({ stadium_id, type_key: _cvt?.key ?? '', });
if(_dateLs?.length <= 0)return showModal({ content: '没有日期列表!' });
let _curDate = currentBookDate.value = _dateLs[0];
@ -73,7 +83,7 @@ async function bookDateChange(_date){
currentBookDate.value = _date;
siteData.value = [];
try{
let stadium_id = optQuery?.value?.stadium_id ?? '';
let stadium_id = stadiumInfo?.value?.id ?? '';
let _cvt = currentVenueType.value ?? {}
getBookList({ stadium_id, type_key: _cvt?.key ?? '', date: _date?._date ?? '' });
}catch(err){
@ -82,7 +92,7 @@ async function bookDateChange(_date){
}
//
function clearSelectedData(){
let stadium_id = optQuery?.value?.stadium_id ?? '';
let stadium_id = stadiumInfo?.value?.id ?? '';
let _key = currentVenueType.value?.key ?? '';
let _date = currentBookDate.value?._date ?? '';
getBookList({ stadium_id, type_key: _key, date: _date });
@ -124,21 +134,14 @@ function getDateLs({ stadium_id, type_key, num = 8 }){
}
// +
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`,
enable_show_terminal: 1,
from_platform: `weixin`,
} })
.then(res=>{
return siteData.value = res?.data;
@ -163,8 +166,8 @@ async function setScrollViewSize(){
<view class="site-select">
<view class="ss-header" id="ssHeader">
<view class="sh-stadium">
<view class="ss-logo"></view>
<view class="ss-name">MJ体育(天空篮球从云店)</view>
<image v-if="stadiumInfo?.logo" mode="aspectFit" class="ss-logo" :src="stadiumInfo.logo"></image>
<view class="ss-name">{{ stadiumInfo?.name ?? '-' }}</view>
</view>
<view class="sh-bottom">
<picker class="sb-classify" mode='selector' :range="venueTypeData" range-key="name" @change="venueTypeChange">
@ -217,7 +220,6 @@ async function setScrollViewSize(){
margin-right: 20upx;
width: 36upx;
height: 36upx;
background: skyblue;
}
.ss-name{
flex-grow: 1;

78
src/subpackage/groupon/pages/stadiums.vue

@ -1,6 +1,6 @@
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { reactive, ref, watch } from "vue";
import { reactive, ref, watch, onMounted, getCurrentInstance } from "vue";
import searchBar from "../components/search_bar.vue";
import { countCity, stadiumFind } from "../api";
import { routeTo, showModal } from '@/utils/polish';
@ -11,6 +11,8 @@ const stadiumKey = ref(''); // 搜索门店
const stadiumLs = ref([]);
const appid = tt.getEnvInfoSync()?.microapp?.appId ?? '';
const ticketInfo = null; //
watch(cityName, val=>{
stadiumLs.value = [];
stadiumFind({
@ -28,38 +30,28 @@ watch(cityName, val=>{
})
});
onLoad(opts => {
countCity({
data: { brand_id: opts?.brand_id ?? '' }
})
console.log('opts--->', opts);
countCity({ data: {} })
.then(res=>{
console.log('城市列表--->', res);
return cityLs.value = res.data?.list || [];
})
.then(cityLs => {
if(!cityLs?.length) return showModal({ content: '暂无城市' });
if(opts?.appid)appid = opts?.appid;
cityName.value = cityLs[0]?.city ?? '';
})
});
function updateStadiumLs({
appid = '',
city = '',
key = '',
}){
return stadiumFind({
data: { appid, city, key, },
onMounted(() =>{
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel();
eventChannel.on('dataForGrouponStadiums', data => {
ticketInfo = data?.ticket ?? null;
})
.then(stadiumRes => {
let _ls = stadiumRes?.data?.list || [];
if(!_ls?.length) return showModal({ content: '暂无门店' });
stadiumLs.value = _ls;
})
}
function getBusinessTime(stadiumInfo){ //
})
//
function getBusinessTime(stadiumInfo){
let _businessTime = stadiumInfo?.business_times || [];
let _str = ''
if(_businessTime?.length){
@ -79,7 +71,7 @@ function getBusinessTime(stadiumInfo){ // 营业时间
}
return _str || '-';
}
//
function phoneCall(phone) {
if(!phone) return showModal({ content: '暂无联系电话' });
uni.makePhoneCall({ phoneNumber: phone,
@ -92,7 +84,7 @@ function phoneCall(phone) {
}
});
}
//
function openMap(res){
uni.openLocation({
latitude: +(res?.lat || 0),
@ -108,7 +100,7 @@ function openMap(res){
}
});
}
//
function searchKeyConfrim(val){
stadiumLs.value = [];
stadiumFind({
@ -123,6 +115,36 @@ function searchKeyConfrim(val){
stadiumLs.value = _ls;
})
}
//
function toNextStep(stadiumInfo){
showModal({
content: `是否确认选择${stadiumInfo?.name ?? '-'}作为核销门店?`,
confirmText: '确认',
cancelText: '取消',
showCancel: true,
success: res=>{
if(!res.confirm) return;
let _mt = ticketInfo?.merchandise_type;
let _url = _mt === 0 ? '/subpackage/groupon/pages/confirm_order/ticket'
: _mt === 1 ? '/subpackage/groupon/pages/site_select' : '';
uni.navigateTo({
url: _url,
success: res => {
res.eventChannel.emit('dataFromGrouponStadiums', {
stadium: {
id: stadiumInfo?.id || '',
name: stadiumInfo?.name || '',
address: stadiumInfo?.address || '',
logo: stadiumInfo?.logo || '',
},
ticket: ticketInfo
})
}
});
}
})
}
</script>
<template>
@ -136,10 +158,10 @@ function searchKeyConfrim(val){
></search-bar>
</view>
<view class="stadium-ls">
<view class="sl-item" v-for="(e, i) in stadiumLs" :key="i">
<view class="sl-item" v-for="(e, i) in stadiumLs" :key="i" @click="toNextStep(e)">
<view class="si-info">
<view class="si-top">
<image class="st-logo" mode="aspectFit" :src="e.logo"></image>
<image class="st-logo" v-if="e.logo" mode="aspectFit" :src="e.logo"></image>
<view class="st-name">{{ e?.name || '-' }}</view>
</view>
<view class="si-line">
@ -154,8 +176,8 @@ function searchKeyConfrim(val){
<view class="si-right">
<view class="sr-txt">去核销</view>
<view class="sr-icons">
<view class="si-item" @click="phoneCall(e.contact_mobile)">&#xe605;</view>
<view class="si-item" @click="openMap(e)">&#xe672;</view>
<view class="si-item" @click.stop="phoneCall(e.contact_mobile)">&#xe605;</view>
<view class="si-item" @click.stop="openMap(e)">&#xe672;</view>
</view>
</view>
</view>

BIN
src/subpackage/groupon/static/images/ticket_icon.png

After

Width: 40  |  Height: 40  |  Size: 1.9 KiB

Loading…
Cancel
Save