Merge branch 'dev' of https://git.ouxuan.net/APP/ox_zhiNengZhuShou into pf_1807
tid1867
-
138src/components/period_select.vue
-
66src/pages.json
-
2src/pages/index/index.vue
-
2src/pages/order_search/order_search.vue
-
175src/pages/write_off/douyin/poi_list.vue
-
237src/pages/write_off/mall/list/list.vue
-
131src/pages/write_off/menu/menu.vue
-
70src/pages/write_off/null/null.vue
-
496src/pages/write_off/number_of_people/number_of_people.vue
-
364src/pages/write_off/operate/operate.vue
-
339src/pages/write_off/search_result/search_result.vue
-
BINsrc/static/images/code_null.png
-
BINsrc/static/images/countdown_bg.png
-
BINsrc/static/images/order_null.png
-
BINsrc/static/images/scan_null.png
-
BINsrc/static/images/write_off/mall.png
-
BINsrc/static/images/write_off/order.png
-
BINsrc/static/images/write_off/people.png
-
BINsrc/static/images/write_off/site.png
-
4src/subpackage/blacklist/pages/abnormal_list/abnormal_list.vue
-
59src/subpackage/verification/components/head_bar.vue
-
78src/subpackage/verification/components/record/dy_item.vue
-
95src/subpackage/verification/components/record/mall_item.vue
-
87src/subpackage/verification/components/record/site_item.vue
-
15src/subpackage/verification/components/stadium_picker.vue
-
7src/subpackage/verification/js/api.js
-
282src/subpackage/verification/pages/index.vue
-
62src/subpackage/verification/pages/null.vue
-
394src/subpackage/verification/pages/record.vue
-
244src/subpackage/verification/pages/record_search.vue
-
5src/subpackage/verification/pages/site_people/index.vue
-
9src/subpackage/verification/pages/site_people/modules/not_leave_modal.vue
-
15src/subpackage/verification/pages/site_people/modules/stadium_select.vue
-
BINsrc/subpackage/verification/static/images/arrow_c9f.png
-
BINsrc/subpackage/verification/static/images/calendar.png
-
BINsrc/subpackage/verification/static/images/order/null_code.png
-
BINsrc/subpackage/verification/static/images/order/null_range.png
-
BINsrc/subpackage/verification/static/images/order/null_search.png
-
BINsrc/subpackage/verification/static/images/round_close.png
-
BINsrc/subpackage/verification/static/images/scan.png
-
BINsrc/subpackage/verification/static/images/search.png
-
BINsrc/subpackage/verification/static/images/tab0.png
-
BINsrc/subpackage/verification/static/images/tab1.png
-
BINsrc/subpackage/verification/static/images/tab2.png
-
3src/subpackage/wallet/js/api.js
-
15src/subpackage/wallet/pages/douyin_withdraw/index.vue
-
77src/subpackage/wallet/pages/index/index.vue
-
82src/subpackage/wallet/pages/index/modules/recharge_modal.vue
-
6src/subpackage/wallet/pages/index/modules/wallet_info.vue
-
137src/subpackage/wallet/pages/index/recharge_record.vue
-
6src/utils/util.js
@ -0,0 +1,138 @@ |
|||||
|
<template> |
||||
|
<!-- 时间段选择 --> |
||||
|
<view class="period-select-mask" v-if="isShow" @click="isShow = false"> |
||||
|
<view class="ol-period" @click.stop="()=>false"> |
||||
|
<view class="op-tit">日期范围</view> |
||||
|
<picker mode="date" class="op-picker" @change="startTimeChange" :value="startTime"> |
||||
|
<view class="op-time"> |
||||
|
<text class="ot-tit">开始时间</text> |
||||
|
<view class="ot-right"> |
||||
|
<input class="or-ipt" placeholder="选择时间" disabled :value="startTime"/> |
||||
|
<image class="or-icon" mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
</picker> |
||||
|
<picker mode="date" class="op-picker" @change="endTimeChange" :value="endTime"> |
||||
|
<view class="op-time"> |
||||
|
<text class="ot-tit">截止时间</text> |
||||
|
<view class="ot-right"> |
||||
|
<input class="or-ipt" placeholder="选择时间" disabled :value="endTime"/> |
||||
|
<image class="or-icon" mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
</picker> |
||||
|
<view class="pl-btn active" @click="confirmBtn">确定</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { showNone, showModal } from '@/utils/util'; |
||||
|
export default { |
||||
|
props: { |
||||
|
value: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
value: { |
||||
|
handler(val) { |
||||
|
let [start, end] = val.split('_'); |
||||
|
this.startTime = start; |
||||
|
this.endTime = end; |
||||
|
}, |
||||
|
immediate: true |
||||
|
} |
||||
|
}, |
||||
|
data(){ |
||||
|
return { |
||||
|
isShow: false, |
||||
|
startTime: '', |
||||
|
endTime: '', |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
show(){ |
||||
|
this.isShow = true |
||||
|
}, |
||||
|
hide(){ |
||||
|
this.isShow = false |
||||
|
}, |
||||
|
startTimeChange(e){ |
||||
|
this.startTime = e.detail.value; |
||||
|
}, |
||||
|
endTimeChange(e){ |
||||
|
this.endTime = e.detail.value; |
||||
|
}, |
||||
|
confirmBtn(){ |
||||
|
let { startTime, endTime } = this; |
||||
|
let _sTimestemp = new Date(startTime.replace(/\-/g,'/')).getTime(); |
||||
|
let _eTimestemp = new Date(endTime.replace(/\-/g,'/')).getTime(); |
||||
|
if(_sTimestemp > _eTimestemp)return showModal({ content: '开始时间不能大于结束时间' }); |
||||
|
this.$emit('input', `${startTime}_${endTime}`); |
||||
|
this.hide(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.period-select-mask{ |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
background: rgba(0,0,0,0.4); |
||||
|
z-index: 9999; |
||||
|
} |
||||
|
.ol-period{ |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
padding-left: 38upx; |
||||
|
padding-top: 66upx; |
||||
|
height: 472upx; |
||||
|
width: 100%; |
||||
|
background-color: #fff; |
||||
|
.op-tit{ |
||||
|
@include flcw(24upx, 34upx, #9c9c9f); |
||||
|
} |
||||
|
.op-picker{ |
||||
|
width: 100%; |
||||
|
|
||||
|
} |
||||
|
.op-time{ |
||||
|
padding-right: 40upx; |
||||
|
height: 124upx; |
||||
|
border-bottom: 2upx solid #D8D8D8; |
||||
|
@include ctf(space-between); |
||||
|
.ot-tit{ |
||||
|
flex-shrink: 0; |
||||
|
@include flcw(32upx, 44upx, #1a1a1a); |
||||
|
} |
||||
|
.ot-right{ |
||||
|
flex-grow: 1; |
||||
|
@include ctf(flex-end); |
||||
|
.or-ipt{ |
||||
|
flex-grow: 1; |
||||
|
height: 100%; |
||||
|
text-align: right; |
||||
|
@include flcw(32upx, 44upx, #1a1a1a); |
||||
|
} |
||||
|
.or-icon{ |
||||
|
flex-shrink: 0; |
||||
|
margin-left: 36upx; |
||||
|
width: 28upx; |
||||
|
height: 28upx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.pl-btn{ |
||||
|
min-height: 124upx; |
||||
|
text-align: center; |
||||
|
@include flcw(32upx, 124upx, $mColor, 500); |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -1,175 +0,0 @@ |
|||||
<template> |
|
||||
<view class="dy-poi-ls"> |
|
||||
<view class="dpl-header"> |
|
||||
<stadium-picker |
|
||||
:stadium-list="stadiumList" |
|
||||
@change:stadium="stadiumChange" |
|
||||
></stadium-picker> |
|
||||
<!-- <period-picker></period-picker> --> |
|
||||
<view class="dh-number">核销数量:{{ totalNum || 0 }}</view> |
|
||||
</view> |
|
||||
<view class="dpl-list"> |
|
||||
<view class="dl-item" v-for="(e, i) in writeOffList" :key="i"> |
|
||||
<list-item |
|
||||
:order-no="e.order_no" |
|
||||
:user-phone="e.user_phone" |
|
||||
:verify-code="e.verify_code" |
|
||||
:verify-method="e.verify_method" |
|
||||
:verify-time="e.verify_time" |
|
||||
></list-item> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="r-bottom-btn"><view @click="toOperate">核销团购券</view></view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import periodPicker from "../all_components/period_picker.vue"; |
|
||||
import stadiumPicker from "../all_components/stadium_picker.vue"; |
|
||||
import listItem from "../all_components/list_item.vue"; |
|
||||
import { API } from '../../../js/api'; |
|
||||
import { servers } from '../../../js/server'; |
|
||||
import util from '../../../utils/util'; |
|
||||
import { mapState } from 'vuex'; |
|
||||
import { WRITE_OFF_STORE_NAME } from '../../../js/once_name'; |
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapState([ 'brandInfo' ]), |
|
||||
}, |
|
||||
components: { |
|
||||
periodPicker, |
|
||||
stadiumPicker, |
|
||||
listItem |
|
||||
}, |
|
||||
data() { |
|
||||
return { |
|
||||
totalNum: 0, |
|
||||
writeOffList: [], |
|
||||
stadiumList: [], |
|
||||
curStadium: {}, |
|
||||
page: 1, |
|
||||
} |
|
||||
}, |
|
||||
async onLoad() { |
|
||||
let _brand_id = this.brandInfo?.brand?.id || 63; |
|
||||
let _list = await this.getStoreList({ brand_id: _brand_id }); |
|
||||
this.stadiumList = _list || []; |
|
||||
this.getList({ brand_id: _brand_id }); |
|
||||
|
|
||||
}, |
|
||||
onReachBottom(){ |
|
||||
let { page, curStadium } = this; |
|
||||
this.getList({ |
|
||||
brand_id: curStadium?.brand_id, |
|
||||
stadium_id: curStadium?.id, |
|
||||
page: page + 1, |
|
||||
}) |
|
||||
}, |
|
||||
methods: { |
|
||||
toOperate(){ |
|
||||
let { stadiumList, curStadium } = this; |
|
||||
util.$_emit(WRITE_OFF_STORE_NAME, { |
|
||||
stadiumList, |
|
||||
curStadium, |
|
||||
}) |
|
||||
util.routeTo(`/pages/write_off/operate/operate?type=dypoi`, 'rT'); |
|
||||
}, |
|
||||
stadiumChange(stadium){ |
|
||||
this.curStadium = stadium; |
|
||||
this.page = 1; |
|
||||
this.totalNum = 0; |
|
||||
this.writeOffList = []; |
|
||||
this.getList({ |
|
||||
brand_id: stadium?.brand_id, |
|
||||
stadium_id: stadium?.id, |
|
||||
}) |
|
||||
}, |
|
||||
getList({ brand_id, stadium_id = '', date = '', page = 1, page_size = 20, order_status = 'used' }){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.dyPoiOrderList, |
|
||||
data: { brand_id, stadium_id, date, page, page_size, order_status }, |
|
||||
failMsg: '加载失败!', |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
this.totalNum = res.total || 0; |
|
||||
let _list = (res.list || []).map(e=>this.formating(e)); |
|
||||
if(page == 1)return this.writeOffList = _list; |
|
||||
if(!_list.length)return util.showNone('没有更多!'); |
|
||||
this.page = page; |
|
||||
this.writeOffList = [...this.writeOffList, ..._list]; |
|
||||
}) |
|
||||
}, |
|
||||
formating(data){ |
|
||||
let _code = data?.order_codes?.find(e=>e?.code_status == 'used'); |
|
||||
return { |
|
||||
order_no: data?.order_no || '', |
|
||||
user_phone: data?.mobile || '', |
|
||||
verify_code: _code?.code || '', |
|
||||
verify_method: _code?.verification_method || '', |
|
||||
verify_time: _code?.verification_time || '', |
|
||||
} |
|
||||
}, |
|
||||
getStoreList({ |
|
||||
page=1, |
|
||||
page_size=9999, |
|
||||
brand_id='', |
|
||||
}){ |
|
||||
return servers.get({ |
|
||||
url: API.stadiumList, |
|
||||
data: { |
|
||||
page, |
|
||||
page_size, |
|
||||
brand_id, |
|
||||
}, |
|
||||
failMsg: '获取列表失败!' |
|
||||
}) |
|
||||
.then(res=>res.list || []) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
.dy-poi-ls{ |
|
||||
@include isPd(150upx); |
|
||||
} |
|
||||
.dpl-header{ |
|
||||
position: sticky; |
|
||||
padding-bottom: 24upx; |
|
||||
background: #fff; |
|
||||
.dh-number{ |
|
||||
padding: 0 24upx; |
|
||||
text-align: right; |
|
||||
@include flcw(32upx, 44upx); |
|
||||
@include tHide; |
|
||||
} |
|
||||
} |
|
||||
.dpl-list{ |
|
||||
padding: 24upx; |
|
||||
.dl-item+ .dl-item{ |
|
||||
margin-top: 24upx; |
|
||||
} |
|
||||
} |
|
||||
.r-bottom-btn{ |
|
||||
position: fixed; |
|
||||
left: 0; |
|
||||
bottom: 0; |
|
||||
width: 100%; |
|
||||
padding: 10upx 24upx; |
|
||||
padding-bottom: calc( 10upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|
||||
padding-bottom: calc( 10upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|
||||
background-color: #f2f2f7; |
|
||||
>view{ |
|
||||
height: 112upx; |
|
||||
line-height: 112upx; |
|
||||
text-align: center; |
|
||||
font-size: 32upx; |
|
||||
border-radius: 10upx; |
|
||||
color: #fff; |
|
||||
background-color: $mColor; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,237 +0,0 @@ |
|||||
<template> |
|
||||
<view class="mall-order-ls"> |
|
||||
<view class="mol-date"> |
|
||||
<view class="md-txt">核销日期</view> |
|
||||
<view class="md-picker"> |
|
||||
<picker mode="date" @change="stChange"> |
|
||||
<view> |
|
||||
<input :value="startTime" disabled placeholder="请选择时间" /> |
|
||||
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> |
|
||||
</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
<view class="md-txt">至</view> |
|
||||
<view class="md-picker"> |
|
||||
<picker mode="date" @change="edChange"> |
|
||||
<view> |
|
||||
<input :value="endTime" disabled placeholder="请选择时间" /> |
|
||||
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> |
|
||||
</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="mol-list"> |
|
||||
<view class="ml-item" v-for="(e, i) in writeOffList" :key="i"> |
|
||||
<view class="mi-order-no"> |
|
||||
<view class="mon-num">订单编号:{{ e.product_order_no || '-' }}</view> |
|
||||
<view class="mon-btn" @click="copyBtn(e.product_order_no || '-')">复制</view> |
|
||||
</view> |
|
||||
<view class="mi-info"> |
|
||||
<view class="mi-line">取货码:{{ e.product_order_no || '-' }}</view> |
|
||||
<view class="mi-line">取货人:{{ e.product_order_self_pickup_info.name || '-' }} {{ e.product_order_self_pickup_info.phone || '-' }}</view> |
|
||||
<view class="mi-line">商品:{{ e.product_order_goods.join(';') }}</view> |
|
||||
<view class="mi-line">核验人:{{ e.optuname }}</view> |
|
||||
<view class="mi-line">取货时间:{{ e.created_at || '-' }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="mol-fixed"> |
|
||||
<view @click="toOperate">核销订单</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { API } from '../../../../js/api'; |
|
||||
import { servers } from '../../../../js/server'; |
|
||||
import util from '../../../../utils/util'; |
|
||||
import { mapState } from 'vuex'; |
|
||||
import { WRITE_OFF_STORE_NAME } from '../../../../js/once_name'; |
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapState([ 'brandInfo' ]), |
|
||||
|
|
||||
}, |
|
||||
data(){ |
|
||||
return { |
|
||||
writeOffList: [], |
|
||||
page: 1, |
|
||||
startTime: '', |
|
||||
endTime: '', |
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
onReachBottom(){ |
|
||||
let { brandInfo, startTime, endTime, page } = this; |
|
||||
this.getList({ |
|
||||
brand_id: brandInfo.brand.id, |
|
||||
stime: startTime || '', |
|
||||
etime: endTime || '', |
|
||||
page: ++page |
|
||||
}) |
|
||||
}, |
|
||||
onLoad(){ |
|
||||
// 默认显示1个月内的日期 |
|
||||
let _startDate = util.formatDate({ |
|
||||
date: new Date().getTime() - 30*24*60*60*1000 |
|
||||
}).substr(0, 10); |
|
||||
let _endDate = util.formatDate({ }).substr(0, 10); |
|
||||
this.startTime = _startDate; |
|
||||
this.endTime = _endDate; |
|
||||
// 默认显示1个月内的日期 |
|
||||
|
|
||||
this.$nextTick(_=> this.refreshPage()); |
|
||||
}, |
|
||||
methods: { |
|
||||
refreshPage(){ |
|
||||
let { brandInfo, startTime, endTime } = this; |
|
||||
this.page = 1; |
|
||||
this.writeOffList = []; |
|
||||
this.$nextTick(_=>{ |
|
||||
this.getList({ |
|
||||
brand_id: brandInfo.brand.id, |
|
||||
stime: startTime || '', |
|
||||
etime: endTime || '', |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
copyBtn(data){ |
|
||||
uni.setClipboardData({ data }) |
|
||||
}, |
|
||||
stChange(e){ |
|
||||
console.warn(e) |
|
||||
this.startTime = e.detail.value; |
|
||||
this.$nextTick(_=>this.refreshPage()); |
|
||||
}, |
|
||||
edChange(e){ |
|
||||
this.endTime = e.detail.value; |
|
||||
this.$nextTick(_=>this.refreshPage()); |
|
||||
}, |
|
||||
toOperate(){ |
|
||||
util.$_emit(WRITE_OFF_STORE_NAME, null); |
|
||||
util.routeTo(`/pages/write_off/operate/operate?type=mall`, 'nT'); |
|
||||
}, |
|
||||
getList({ brand_id, page = 1, page_size = 15, stime = '', etime = '' }){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.shop2WriteoffList, |
|
||||
data: { brand_id, page, page_size, stime, etime }, |
|
||||
failMsg: '加载失败!', |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
this.totalNum = res.total || 0; |
|
||||
let _list = res.list || []; |
|
||||
if(page == 1)return this.writeOffList = _list; |
|
||||
if(!_list.length)return util.showNone('没有更多!'); |
|
||||
this.page = page; |
|
||||
this.writeOffList = [...this.writeOffList, ..._list]; |
|
||||
|
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
@import '~style/public.scss'; |
|
||||
.mall-order-ls{ |
|
||||
padding-bottom: 122upx; |
|
||||
padding-bottom: calc( 122upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|
||||
padding-bottom: calc( 122upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|
||||
} |
|
||||
.mol-date{ |
|
||||
padding: 0 28upx; |
|
||||
height: 148upx; |
|
||||
background-color: #fff; |
|
||||
@include centerFlex(flex-start); |
|
||||
.md-txt{ |
|
||||
font-size: 32upx; |
|
||||
line-height: 44upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
.md-picker{ |
|
||||
margin: 0 20upx; |
|
||||
width: 226upx; |
|
||||
border: 2upx solid #D8D8D8; |
|
||||
border-radius: 10upx; |
|
||||
overflow: hidden; |
|
||||
view{ |
|
||||
padding: 0 10upx; |
|
||||
height: 88upx; |
|
||||
background-color: #f2f2f7; |
|
||||
@include centerFlex(space-between); |
|
||||
>input{ |
|
||||
flex-grow: 1; |
|
||||
height: 100%; |
|
||||
font-size: 28upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
>image{ |
|
||||
margin-left: 10upx; |
|
||||
flex-shrink: 0; |
|
||||
width: 22upx; |
|
||||
height: 22upx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.mol-list{ |
|
||||
padding: 24upx; |
|
||||
.ml-item{ |
|
||||
margin-bottom: 24upx; |
|
||||
padding: 0 24upx; |
|
||||
background-color: #fff; |
|
||||
.mi-order-no{ |
|
||||
padding: 30upx 4upx; |
|
||||
border-bottom: 2upx solid #f2f2f7; |
|
||||
@include centerFlex(space-between); |
|
||||
.mon-num{ |
|
||||
font-size: 28upx; |
|
||||
font-weight: 500; |
|
||||
line-height: 40upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
.mon-btn{ |
|
||||
flex-shrink: 0; |
|
||||
margin-left: 20upx; |
|
||||
font-size: 28upx; |
|
||||
line-height: 40upx; |
|
||||
color: $themeColor; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
.mi-info{ |
|
||||
padding: 30upx 4upx; |
|
||||
.mi-line{ |
|
||||
font-size: 28upx; |
|
||||
line-height: 52upx; |
|
||||
color: #9C9C9F; |
|
||||
@include textHide(1); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.mol-fixed{ |
|
||||
position: fixed; |
|
||||
left: 0; |
|
||||
bottom: 0; |
|
||||
width: 100%; |
|
||||
background-color: #fff; |
|
||||
padding: 10upx 40upx; |
|
||||
padding-bottom: calc( 10upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|
||||
padding-bottom: calc( 10upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|
||||
>view{ |
|
||||
height: 112upx; |
|
||||
line-height: 112upx; |
|
||||
text-align: center; |
|
||||
font-size: 32upx; |
|
||||
color: #fff; |
|
||||
background-color: $themeColor; |
|
||||
border-radius: 10upx; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,131 +0,0 @@ |
|||||
<template> |
|
||||
<view class="write-off-menu"> |
|
||||
<view class="wom-section"> |
|
||||
<view class="ws-tit">场地订单核销</view> |
|
||||
<view class="ws-ls"> |
|
||||
<view class="wl-item" @click="toOperate('site')"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/site.png"></image> |
|
||||
<view>场地订单核销</view> |
|
||||
</view> |
|
||||
<view class="wl-item" @click="toSiteList"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/order.png"></image> |
|
||||
<view>场地订单核销记录</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="wom-section"> |
|
||||
<view class="ws-tit">商城订单核销</view> |
|
||||
<view class="ws-ls"> |
|
||||
<view class="wl-item" @click="toOperate('mall')"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/mall.png"></image> |
|
||||
<view>商城订单核销</view> |
|
||||
</view> |
|
||||
<view class="wl-item" @click="toMallLs"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/order.png"></image> |
|
||||
<view>商城订单核销记录</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="wom-section"> |
|
||||
<view class="ws-tit">抖音团购核销</view> |
|
||||
<view class="ws-ls"> |
|
||||
<view class="wl-item" @click="toOperate('dypoi')"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/site.png"></image> |
|
||||
<view>抖音团购核销</view> |
|
||||
</view> |
|
||||
<view class="wl-item" @click="toDypoiOrderLs"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/order.png"></image> |
|
||||
<view>抖音团购核销记录</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="wom-section"> |
|
||||
<view class="ws-tit">现场散客人数</view> |
|
||||
<view class="ws-ls"> |
|
||||
<view class="wl-item" @click="toPeopleNum"> |
|
||||
<image mode="aspectFit" src="/static/images/write_off/people.png"></image> |
|
||||
<view>现场散客人数查询</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '../../../utils/util'; |
|
||||
import { WRITE_OFF_STORE_NAME } from '../../../js/once_name'; |
|
||||
export default { |
|
||||
data(){ |
|
||||
return { |
|
||||
brand_id: '' |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options){ |
|
||||
this.brand_id = options?.brand_id || '' |
|
||||
}, |
|
||||
methods: { |
|
||||
toPeopleNum(){ |
|
||||
let _qryStr = `brand_id=${this.brand_id}` |
|
||||
util.routeTo(`/subpackage/verification/pages/site_people/index?${_qryStr}`, 'nT'); |
|
||||
}, |
|
||||
toOperate(type){ |
|
||||
util.$_emit(WRITE_OFF_STORE_NAME, null); |
|
||||
util.routeTo(`/pages/write_off/operate/operate?type=${type}`, 'nT'); |
|
||||
}, |
|
||||
toSiteList(){ |
|
||||
util.routeTo(`/pages/write_off/search_result/search_result`, 'nT'); |
|
||||
}, |
|
||||
toMallLs(){ |
|
||||
util.routeTo(`/pages/write_off/mall/list/list`, 'nT'); |
|
||||
}, |
|
||||
toDypoiOrderLs(){ |
|
||||
util.routeTo(`/pages/write_off/douyin/poi_list`, 'nT'); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
@import '~style/public.scss'; |
|
||||
.write-off-menu{ |
|
||||
padding: 60upx 68upx 0upx; |
|
||||
.wom-section{ |
|
||||
margin-bottom: 30upx; |
|
||||
.ws-tit{ |
|
||||
margin-bottom: 20upx; |
|
||||
font-size: 32upx; |
|
||||
font-weight: 500; |
|
||||
line-height: 44upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
.ws-ls{ |
|
||||
@include centerFlex(space-between); |
|
||||
flex-wrap: wrap; |
|
||||
.wl-item{ |
|
||||
padding-top: 58upx; |
|
||||
margin-bottom: 32upx; |
|
||||
width: 288upx; |
|
||||
height: 220upx; |
|
||||
border-radius: 10upx; |
|
||||
background-color: #fff; |
|
||||
>image{ |
|
||||
margin: 0 auto 22upx; |
|
||||
display: block; |
|
||||
width: 60upx; |
|
||||
height: 60upx; |
|
||||
} |
|
||||
>view{ |
|
||||
text-align: center; |
|
||||
line-height: 40upx; |
|
||||
font-size: 28upx; |
|
||||
color: #9c9c9f; |
|
||||
@include textHide(1); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,70 +0,0 @@ |
|||||
<template> |
|
||||
<view class="null-container"> |
|
||||
<image mode="aspectFit" :src="imgPath"></image> |
|
||||
<view class="c-tip" v-if="operateType == 'decrypt_text'">很抱歉!获取不到二维码订单信息</view> |
|
||||
<view class="c-tip" v-if="operateType == 'verify_code'">很抱歉!获取不到验证码订单信息</view> |
|
||||
<view class="c-btn" @click="toBlack">返回</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '../../../utils/util'; |
|
||||
export default { |
|
||||
computed: { |
|
||||
imgPath(){ |
|
||||
let { operateType } = this; |
|
||||
if(operateType == 'verify_code')return '/static/images/code_null.png'; |
|
||||
if(operateType == 'decrypt_text')return '/static/images/scan_null.png'; |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options){ |
|
||||
let { type } = options; |
|
||||
this.operateType = options.type |
|
||||
}, |
|
||||
data(){ |
|
||||
return { |
|
||||
isScan: false, |
|
||||
operateType: '', // verify_code(输入)/decrypt_text(扫码) |
|
||||
} |
|
||||
}, |
|
||||
methods: { |
|
||||
toBlack(){ |
|
||||
util.routeTo(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
@import "~style/public.scss"; |
|
||||
page{ |
|
||||
background-color: #fff; |
|
||||
} |
|
||||
.null-container{ |
|
||||
padding-top: 90upx; |
|
||||
>image{ |
|
||||
display: block; |
|
||||
margin: 0 auto 86upx; |
|
||||
width: 420upx; |
|
||||
height: 420upx; |
|
||||
} |
|
||||
.c-tip{ |
|
||||
margin-bottom: 260upx; |
|
||||
line-height: 40upx; |
|
||||
text-align: center; |
|
||||
font-size: 28upx; |
|
||||
color: #9c9c9f; |
|
||||
} |
|
||||
.c-btn{ |
|
||||
margin: 0 auto; |
|
||||
width: 280upx; |
|
||||
text-align: center; |
|
||||
height: 92upx; |
|
||||
line-height: 88upx; |
|
||||
font-size: 32upx; |
|
||||
border: 2upx solid $themeColor; |
|
||||
color: $themeColor; |
|
||||
border-radius: 46upx; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,496 +0,0 @@ |
|||||
<template> |
|
||||
<view class="number-of-people"> |
|
||||
<view class="nop-store-name"> |
|
||||
<picker :range="stadiumList" range-key="name" @change="stadiumChange"> |
|
||||
<view class="nsn-frame"> |
|
||||
<input placeholder="请选择店铺" :value="curStadium.name" disabled /> |
|
||||
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> |
|
||||
</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
<view class="nop-main"> |
|
||||
<view class="nm-date">日期:{{ dateStr || '-' }}</view> |
|
||||
<view class="nm-tit">现场散客人数</view> |
|
||||
<view class="nm-num"> |
|
||||
<image mode="aspectFit" src="/static/images/countdown_bg.png"></image> |
|
||||
<view class="nn-txt-num">{{peopleInfo.present_person_number || 0}}</view> |
|
||||
</view> |
|
||||
<view class="nm-txt" @click="checkNotLeave">查看未离场订单</view> |
|
||||
<view class="nm-btn" @click="isChangeNum = true">修改人数</view> |
|
||||
<view class="nm-line"> |
|
||||
<view class="nl-txt">凌晨自动清零</view> |
|
||||
<view class="nl-switch" @click="switchChange"> |
|
||||
<switch color="#009777" disabled style="transform:scale(0.8)" :checked="peopleInfo. present_person_number_clear"></switch> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="nm-tip"> |
|
||||
<text>* 不开启凌晨自动清零,则现场灯光按【现场散客人数】去判断是否开启或关闭;修改人数会直接影响现场灯光开关!\n\r* 开启凌晨自动清零,则现场灯光按【散客订单未离场数量】去判断是否开启或关闭;修改人数不会影响现场灯光开关!但如有散客订单一直未扫码离场,可能会无法关灯,需要将未离场的散客订单设置为已离场后才可关闭灯光!</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="ox-dark-mask" v-if="isChangeNum"> |
|
||||
<view class="nop-modifies-modal"> |
|
||||
<image class="nmm-close" @click="isChangeNum = false" src="/static/images/icon/x_close.png"></image> |
|
||||
<view class="nmm-tit">修改现场散客人数</view> |
|
||||
<view class="nmm-info"> |
|
||||
<view class="ni-num">当前现场散客人数为:{{peopleInfo.present_person_number || 0}}</view> |
|
||||
<view class="ni-ipt"> |
|
||||
<input placeholder="请输入散客人数" v-model="changeNum" type="number" /> |
|
||||
</view> |
|
||||
<view class="ni-tip">修改现场人数可能会影响现场灯光开关,请谨慎操作!</view> |
|
||||
</view> |
|
||||
<view class="nmm-btns"> |
|
||||
<view @click="isChangeNum = false">取消</view> |
|
||||
<view @click="confirmChange">确认</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="ox-dark-mask" v-if="isNotLeave"> |
|
||||
<view class="nop-modifies-modal"> |
|
||||
<image class="nmm-close" @click="isNotLeave = false" src="/static/images/icon/x_close.png"></image> |
|
||||
<view class="nmm-tit nmm-btm">未离场订单</view> |
|
||||
<view class="nmm-line" v-if="orderNum.person_number>0"> |
|
||||
<view>次卡未离场:{{orderNum.person_number || 0}}</view> |
|
||||
<view @click="checkBtn(0)">查看</view> |
|
||||
</view> |
|
||||
<view class="nmm-line" v-if="orderNum.person_timing>0"> |
|
||||
<view>计时未离场:{{orderNum.person_timing || 0}}</view> |
|
||||
<view @click="checkBtn(1)">查看</view> |
|
||||
</view> |
|
||||
<view class="nmm-line"> |
|
||||
<view>年月卡未离场:{{orderNum.monthly_card||0}}</view> |
|
||||
<view @click="checkBtn(0)">查看</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { API } from '../../../js/api' |
|
||||
import { servers } from '../../../js/server' |
|
||||
import { mapState } from 'vuex'; |
|
||||
import util from '../../../utils/util'; |
|
||||
let timer = null; |
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapState([ 'brandInfo' ]), |
|
||||
}, |
|
||||
data(){ |
|
||||
return { |
|
||||
isChangeNum: false, |
|
||||
stadiumList: [], |
|
||||
curStadium: { |
|
||||
name: '' |
|
||||
}, |
|
||||
peopleInfo: {}, |
|
||||
dateStr: '-', |
|
||||
changeNum: '', |
|
||||
|
|
||||
isNotLeave: false, |
|
||||
orderNum: {}, //未离场订单数量 |
|
||||
} |
|
||||
}, |
|
||||
onLoad(options){ |
|
||||
this.initStore(); |
|
||||
this.dateStr = util.formatDate({ partition: 'zh' }) || '-'; |
|
||||
}, |
|
||||
|
|
||||
onUnload(){ |
|
||||
this.clearTime(); |
|
||||
}, |
|
||||
methods: { |
|
||||
confirmChange: util.debounce(function(){ |
|
||||
let { changeNum } = this; |
|
||||
if(isNaN(changeNum))return util.showNone('请输入正确人数!'); |
|
||||
this.isChangeNum = false; |
|
||||
this.setStadiumPresentNumber(changeNum); |
|
||||
}, 200, true), |
|
||||
setStadiumPresentNumber(num){ |
|
||||
let { curStadium } = this; |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.setStadiumPresentNumber, |
|
||||
data: { |
|
||||
brand_id: curStadium.brand_id, |
|
||||
stadium_id: curStadium.id, |
|
||||
number: +num, |
|
||||
}, |
|
||||
isDefaultGet: false, |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
if(res.data.code == 0){ |
|
||||
util.showNone(res.data.message || '操作成功!'); |
|
||||
setTimeout(_=>{ |
|
||||
this.getUserNum({ |
|
||||
stadium_id: curStadium.id, |
|
||||
brand_id: curStadium.brand_id |
|
||||
}) |
|
||||
this.initInertval(); |
|
||||
}, 1200) |
|
||||
}else{ |
|
||||
util.showNone(res.data.message || '操作失败!'); |
|
||||
} |
|
||||
}) |
|
||||
.catch(util.hideLoad) |
|
||||
}, |
|
||||
initInertval(){ |
|
||||
this.clearTime(); |
|
||||
let { curStadium } = this; |
|
||||
if(!curStadium.id || !curStadium.brand_id)return; |
|
||||
timer = setInterval(_=>{ |
|
||||
if(!curStadium.id || !curStadium.brand_id)return this.clearTime(); |
|
||||
this.getUserNum({ |
|
||||
stadium_id: curStadium.id, |
|
||||
brand_id: curStadium.brand_id |
|
||||
}) |
|
||||
}, 3000); |
|
||||
}, |
|
||||
clearTime(){ |
|
||||
clearInterval(timer); |
|
||||
timer = null; |
|
||||
}, |
|
||||
|
|
||||
stadiumChange(e){ |
|
||||
let { stadiumList } = this; |
|
||||
let _curStadium = stadiumList[e.detail.value] || {}; |
|
||||
if(!_curStadium.id || !_curStadium.brand_id)return; |
|
||||
this.curStadium = _curStadium; |
|
||||
this.getUserNum({ |
|
||||
stadium_id: _curStadium.id, |
|
||||
brand_id: _curStadium.brand_id |
|
||||
}) |
|
||||
this.initInertval(); |
|
||||
}, |
|
||||
async initStore(){ |
|
||||
let { brandInfo } = this; |
|
||||
try{ |
|
||||
util.showLoad(); |
|
||||
let _storeList = await this.getStoreList({ brand_id: brandInfo.brand.id || '' }); |
|
||||
if(!_storeList || !_storeList.length)return util.showNone('没有店铺信息'); |
|
||||
this.stadiumList = _storeList || []; |
|
||||
let _curStadium = _storeList[0] || {}; |
|
||||
this.curStadium = _curStadium; |
|
||||
this.initInertval(); |
|
||||
this.getUserNum({ |
|
||||
stadium_id: _curStadium.id, |
|
||||
brand_id: _curStadium.brand_id |
|
||||
}) |
|
||||
util.hideLoad(); |
|
||||
}catch(err){ |
|
||||
util.hideLoad(); |
|
||||
util.showNone('初始化店铺数据失败!'); |
|
||||
console.warn('加载数据失败!', err); |
|
||||
} |
|
||||
}, |
|
||||
// 获取店铺列表 |
|
||||
getStoreList({ |
|
||||
page=1, |
|
||||
page_size=9999, |
|
||||
brand_id='', |
|
||||
}){ |
|
||||
return servers.get({ |
|
||||
url: API.stadiumList, |
|
||||
data: { |
|
||||
page, |
|
||||
page_size, |
|
||||
brand_id, |
|
||||
}, |
|
||||
failMsg: '获取列表失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
let _list = res.list || []; |
|
||||
return _list |
|
||||
}) |
|
||||
}, |
|
||||
getUserNum({ |
|
||||
stadium_id, |
|
||||
brand_id, |
|
||||
}){ |
|
||||
servers.get({ |
|
||||
url: API.writeOff.timingNumber, |
|
||||
data: { stadium_id, brand_id }, |
|
||||
failMsg: '加载现场人数失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
this.peopleInfo = res |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
// 凌晨自动清零 - 未离场订单数量 |
|
||||
checkNotLeave(){ |
|
||||
let { curStadium } = this; |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.notLeavingNums, |
|
||||
data: { |
|
||||
brand_id: curStadium.brand_id, |
|
||||
stadium_id: curStadium.id, |
|
||||
}, |
|
||||
// isDefaultGet: false, |
|
||||
failMsg: '请求失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
this.orderNum = res |
|
||||
this.$nextTick(_=>{ |
|
||||
this.isNotLeave = true |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
checkBtn(type){ |
|
||||
if(type == 0)return util.routeTo(`/pages/write_off/search_result/search_result`, 'nT'); |
|
||||
if(type == 1)return util.routeTo(`/pages/order_list/order_list?order_type=1`, 'nT'); |
|
||||
}, |
|
||||
|
|
||||
switchChange(){ |
|
||||
let { peopleInfo, curStadium } = this |
|
||||
this.$nextTick(_=>{ |
|
||||
util.showModal({ |
|
||||
title: '提示', |
|
||||
content: peopleInfo.present_person_number_clear==false?'是否确认开启凌晨自动清零?':peopleInfo.present_person_number_clear==true?'是否确认关闭凌晨自动清零?':'', |
|
||||
showCancel: true, |
|
||||
success: modalRes=>{ |
|
||||
if(modalRes.confirm){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.timingOpen, //凌晨自动清零【开/关】 |
|
||||
data: { |
|
||||
brand_id: curStadium.brand_id, |
|
||||
stadium_id: curStadium.id, |
|
||||
status: peopleInfo.present_person_number_clear==false?1:peopleInfo.present_person_number_clear==true?0:'', |
|
||||
}, |
|
||||
failMsg: '请求失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
util.showNone('操作成功!'); |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
@import '~style/public.scss'; |
|
||||
page{ |
|
||||
background-color: #fff; |
|
||||
} |
|
||||
.number-of-people{ |
|
||||
.nop-store-name{ |
|
||||
height: 144upx; |
|
||||
@include centerFlex(center); |
|
||||
.nsn-frame{ |
|
||||
padding: 0 20upx; |
|
||||
width: 702upx; |
|
||||
height: 92upx; |
|
||||
border-radius: 10upx; |
|
||||
background-color: #F2F2F7; |
|
||||
@include centerFlex(space-between); |
|
||||
>input{ |
|
||||
flex-grow: 1; |
|
||||
line-height: 40upx; |
|
||||
font-size: 28upx; |
|
||||
color: #1A1A1A; |
|
||||
} |
|
||||
>image{ |
|
||||
flex-shrink: 0; |
|
||||
margin-left: 20upx; |
|
||||
width: 28upx; |
|
||||
height: 28upx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.nop-main{ |
|
||||
padding: 8upx 0upx 0; |
|
||||
.nm-date{ |
|
||||
margin: 0 24rpx 86rpx; |
|
||||
line-height: 44upx; |
|
||||
font-size: 32upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
.nm-tit{ |
|
||||
margin: 0 30rpx 16rpx; |
|
||||
text-align: center; |
|
||||
font-size: 32upx; |
|
||||
font-weight: 500; |
|
||||
} |
|
||||
.nm-num{ |
|
||||
position: relative; |
|
||||
margin: 0 auto; |
|
||||
display: block; |
|
||||
width: 400upx; |
|
||||
height: 400upx; |
|
||||
.nn-txt-num{ |
|
||||
line-height: 400upx; |
|
||||
text-align: center; |
|
||||
font-size: 96upx; |
|
||||
font-weight: 500; |
|
||||
color: $themeColor; |
|
||||
} |
|
||||
>image { |
|
||||
position: absolute; |
|
||||
left: 50%; |
|
||||
top: 50%; |
|
||||
z-index: -1; |
|
||||
margin-left: -250upx; |
|
||||
margin-top: -250upx; |
|
||||
display: block; |
|
||||
width: 500upx; |
|
||||
height: 500upx; |
|
||||
animation: Rotate 6s linear infinite |
|
||||
} |
|
||||
@keyframes Rotate{ |
|
||||
0% {transform: rotate(360deg);} |
|
||||
50% {transform: rotate(180deg);} |
|
||||
100% {transform: rotate(0deg);} |
|
||||
} |
|
||||
} |
|
||||
.nm-txt{ |
|
||||
margin: 10rpx auto 42rpx; |
|
||||
color: #9C9C9F; |
|
||||
font-size: 28rpx; |
|
||||
text-align: center; |
|
||||
line-height: 40rpx; |
|
||||
text-decoration: underline; |
|
||||
} |
|
||||
.nm-btn{ |
|
||||
margin: 0 auto; |
|
||||
width: 618upx; |
|
||||
line-height: 112upx; |
|
||||
height: 112upx; |
|
||||
text-align: center; |
|
||||
border-radius: 10upx; |
|
||||
font-size: 38upx; |
|
||||
color: #fff; |
|
||||
background-color: $themeColor; |
|
||||
} |
|
||||
.nm-line{ |
|
||||
margin: 46rpx 0 0; |
|
||||
padding: 34rpx 28rpx 20rpx 34rpx; |
|
||||
border-top: 2rpx solid #F2F2F7; |
|
||||
@include centerFlex(space-between); |
|
||||
.nl-txt{ |
|
||||
color: #1A1A1A; |
|
||||
font-size: 32rpx; |
|
||||
line-height: 44rpx; |
|
||||
} |
|
||||
|
|
||||
.nl-switch{ |
|
||||
flex-shrink: 0; |
|
||||
flex-grow: 0; |
|
||||
} |
|
||||
} |
|
||||
.nm-tip{ |
|
||||
margin: 0 32rpx 30rpx 34rpx; |
|
||||
font-size: 28upx; |
|
||||
line-height: 52upx; |
|
||||
color: #9C9C9F; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
.nop-modifies-modal{ |
|
||||
position: absolute; |
|
||||
left: 50%; |
|
||||
top: 50%; |
|
||||
transform: translate(-50%, -50%); |
|
||||
padding-top: 78upx; |
|
||||
width: 620upx; |
|
||||
height: 706upx; |
|
||||
background-color: #fff; |
|
||||
border-radius: 10upx; |
|
||||
.nmm-close{ |
|
||||
position: absolute; |
|
||||
right: 30upx; |
|
||||
top: 30upx; |
|
||||
width: 34upx; |
|
||||
height: 34upx; |
|
||||
} |
|
||||
.nmm-tit{ |
|
||||
line-height: 44upx; |
|
||||
text-align: center; |
|
||||
font-weight: 500; |
|
||||
font-size: 32upx; |
|
||||
color: #1A1A1A; |
|
||||
} |
|
||||
.nmm-info{ |
|
||||
padding: 54upx 80upx 80upx; |
|
||||
.ni-num{ |
|
||||
margin-bottom: 30upx; |
|
||||
font-size: 28upx; |
|
||||
line-height: 48upx; |
|
||||
color: #1A1A1A; |
|
||||
@include textHide(1); |
|
||||
} |
|
||||
.ni-ipt{ |
|
||||
margin-bottom: 26upx; |
|
||||
padding: 0 20upx; |
|
||||
height: 88upx; |
|
||||
border-radius: 10upx; |
|
||||
border: 2upx solid #D8D8D8; |
|
||||
>input{ |
|
||||
flex-grow: 1; |
|
||||
height: 100%; |
|
||||
font-size: 28upx; |
|
||||
color: #1A1A1A; |
|
||||
} |
|
||||
} |
|
||||
.ni-tip{ |
|
||||
font-size: 24upx; |
|
||||
line-height: 34upx; |
|
||||
color: #EA5061; |
|
||||
} |
|
||||
} |
|
||||
.nmm-btns{ |
|
||||
@include centerFlex(center); |
|
||||
>view{ |
|
||||
margin: 0 10upx; |
|
||||
width: 240upx; |
|
||||
height: 88upx; |
|
||||
line-height: 84upx; |
|
||||
text-align: center; |
|
||||
font-size: 32upx; |
|
||||
border-radius: 10upx; |
|
||||
border: 2upx solid $themeColor; |
|
||||
color: $themeColor; |
|
||||
&+view{ |
|
||||
color: #fff; |
|
||||
background-color: $themeColor; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.nmm-btm{ |
|
||||
margin-bottom: 8rpx; |
|
||||
} |
|
||||
.nmm-line{ |
|
||||
margin: 78rpx 70rpx 0 74rpx; |
|
||||
@include centerFlex(space-between); |
|
||||
>view{ |
|
||||
&:first-child{ |
|
||||
color: #1A1A1A; |
|
||||
font-size: 28rpx; |
|
||||
line-height: 48rpx; |
|
||||
} |
|
||||
&:nth-child(2){ |
|
||||
width: 156rpx; |
|
||||
height: 68rpx; |
|
||||
border: 2rpx solid #009874; |
|
||||
border-radius: 10rpx; |
|
||||
color: #009874; |
|
||||
font-size: 32rpx; |
|
||||
line-height: 64rpx; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,364 +0,0 @@ |
|||||
<template> |
|
||||
<view class="operate-container"> |
|
||||
<view class="store-bar"> |
|
||||
<text>当前门店</text> |
|
||||
<picker mode="selector" :range="stadiumList" range-key="name" @change="stadiumChange"> |
|
||||
<view> |
|
||||
<input disabled v-model="curStadium.name" /> |
|
||||
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> |
|
||||
</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
<view class="c-scan-btn" @click="scanCodeBtn"> |
|
||||
<image mode="aspectFit" src="/static/images/icon/scan_code_btn.png"></image> |
|
||||
</view> |
|
||||
<view class="c-verification-code"> |
|
||||
<view><input placeholder="输入订单验证码" v-model="iptCode" /></view> |
|
||||
<view @click="confirmBtn">确认核销</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '../../../utils/util'; |
|
||||
import { API } from '../../../js/api'; |
|
||||
import { servers } from '../../../js/server'; |
|
||||
import { WRITE_OFF_STORE_NAME, WRITE_OFF_ORDER_INFO, WRITE_OFF_MALL_ORDER_INFO } from '../../../js/once_name'; |
|
||||
import { mapState } from 'vuex'; |
|
||||
export default { |
|
||||
data(){ |
|
||||
return { |
|
||||
iptCode: '', |
|
||||
stadiumList: [], |
|
||||
curStadium: {}, |
|
||||
|
|
||||
writeOffType: '', // 新增核销类型 site(场地订单)/ mall(商城订单)/ dypoi(抖音团购) |
|
||||
|
|
||||
} |
|
||||
}, |
|
||||
computed: { |
|
||||
...mapState([ 'brandInfo' ]), |
|
||||
}, |
|
||||
onLoad(options){ |
|
||||
this.writeOffType = options.type || ''; |
|
||||
util.$_once(WRITE_OFF_STORE_NAME, data => { // 定位门店 |
|
||||
if(!data)return this.initStore(); |
|
||||
this.curStadium = data.curStadium; |
|
||||
this.stadiumList = data.stadiumList; |
|
||||
}) |
|
||||
|
|
||||
}, |
|
||||
methods: { |
|
||||
async initStore(){ |
|
||||
let { brandInfo } = this; |
|
||||
try{ |
|
||||
util.showLoad(); |
|
||||
let _storeList = await this.getStoreList({ brand_id: brandInfo.brand.id || '' }); |
|
||||
if(!_storeList || !_storeList.length)return util.showNone('没有店铺信息'); |
|
||||
this.stadiumList = _storeList || []; |
|
||||
if(_storeList.length) this.curStadium = _storeList[0]; |
|
||||
util.hideLoad(); |
|
||||
}catch(err){ |
|
||||
util.hideLoad(); |
|
||||
util.showNone('初始化店铺数据失败!'); |
|
||||
} |
|
||||
}, |
|
||||
// 获取店铺列表 |
|
||||
getStoreList({ |
|
||||
page=1, |
|
||||
page_size=99999, |
|
||||
brand_id='', |
|
||||
}){ |
|
||||
return servers.get({ |
|
||||
url: API.stadiumList, |
|
||||
data: { |
|
||||
page, |
|
||||
page_size, |
|
||||
brand_id, |
|
||||
}, |
|
||||
failMsg: '获取列表失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
let _list = res.list || []; |
|
||||
return _list |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
scanCodeBtn: util.debounce(function(){ |
|
||||
uni.scanCode({ |
|
||||
onlyFromCamera: true, |
|
||||
scanType: 'qrCode', |
|
||||
success: res=> { |
|
||||
if(util.changeLowerCase(res.scanType) !== 'qr_code')return util.showNone('不支持此类型!'); |
|
||||
|
|
||||
this.analysisOrder({ decrypt_text: res.result }); |
|
||||
}, |
|
||||
fail: function(err) { |
|
||||
util.showNone('扫码失败!'); |
|
||||
console.warn('扫码失败--->', err); |
|
||||
} |
|
||||
}) |
|
||||
}, 300, true), |
|
||||
stadiumChange(e){ |
|
||||
let { stadiumList } = this; |
|
||||
this.curStadium = stadiumList[e.detail.value]; |
|
||||
}, |
|
||||
confirmBtn: util.debounce(function(){ |
|
||||
let { iptCode } = this; |
|
||||
if(!iptCode)return util.showNone('请输入核销码!'); |
|
||||
this.analysisOrder({ verify_code: this.iptCode }); |
|
||||
}, 300, true), |
|
||||
|
|
||||
|
|
||||
// 核销请求 |
|
||||
analysisOrder({ verify_code = '', decrypt_text = '' }){ |
|
||||
let { curStadium, writeOffType } = this; |
|
||||
if(!verify_code&&!decrypt_text)return; |
|
||||
let _query = { |
|
||||
brand_id: curStadium.brand_id, |
|
||||
stadium_id: curStadium.id, |
|
||||
} |
|
||||
let _vType = ''; |
|
||||
if(!!verify_code){ |
|
||||
_vType = 'verify_code'; |
|
||||
writeOffType == 'site'&&(_query['verify_code'] = verify_code); |
|
||||
writeOffType == 'mall'&&(_query['vcode'] = verify_code); |
|
||||
} |
|
||||
if(!!decrypt_text){ |
|
||||
_vType = 'decrypt_text'; |
|
||||
writeOffType == 'site'&&(_query['decrypt_text'] = decrypt_text); |
|
||||
writeOffType == 'mall'&&(_query['vcode'] = decrypt_text); |
|
||||
} |
|
||||
if(writeOffType == 'site')return this.siteGet({ query: _query, vType: _vType, }); |
|
||||
if(writeOffType == 'mall')return this.mallGet({ query: _query, vType: _vType, }); |
|
||||
if(writeOffType == 'dypoi'){ |
|
||||
let _code = verify_code; |
|
||||
if(decrypt_text){ |
|
||||
try{ |
|
||||
_code = JSON.parse(decrypt_text)?.code; |
|
||||
}catch(err){console.warn(err)} |
|
||||
} |
|
||||
return this.dypoiGet({ |
|
||||
..._query, |
|
||||
code: _code, |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
// 抖音团购 |
|
||||
dypoiGet(query){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.dyPoiEnterVerifyOrder, |
|
||||
data: query, |
|
||||
isDefaultGet: false |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
let { code, data, message } = res?.data || {}; |
|
||||
if(code!==0)return util.showModal({ |
|
||||
title: '提示', |
|
||||
content: message || '查询失败!', |
|
||||
confirmText: '好的' |
|
||||
}) |
|
||||
if(data?.order?.order_no)return util.showModal({ |
|
||||
title: data?.order?.product_cache?.name || '提示', |
|
||||
content: '核销数量:1', |
|
||||
showCancel: true, |
|
||||
confirmText: '确认核销', |
|
||||
cancelText: '取消', |
|
||||
success: res=>{ |
|
||||
if(res.confirm){ |
|
||||
this.dypoiConfirm({ ...query }); |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
console.log('订单查询---->', res); |
|
||||
}) |
|
||||
.catch(util.hideLoad) |
|
||||
}, |
|
||||
dypoiConfirm({ |
|
||||
stadium_id = '', |
|
||||
brand_id = '', |
|
||||
code = '', |
|
||||
}){ |
|
||||
util.showLoad(); |
|
||||
servers.post({ |
|
||||
url: API.writeOff.dyPoiAssistantVerify, |
|
||||
data: { |
|
||||
stadium_id, |
|
||||
brand_id, |
|
||||
code, |
|
||||
}, |
|
||||
isDefaultGet: false |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
let { code, data, message } = res?.data || {}; |
|
||||
if(code!==0)return util.showModal({ |
|
||||
title: '提示', |
|
||||
content: message || '核销失败!', |
|
||||
confirmText: '好的' |
|
||||
}) |
|
||||
|
|
||||
util.showModal({ |
|
||||
title: '提示', |
|
||||
content: message || '核销成功!', |
|
||||
confirmText: '关闭' |
|
||||
}) |
|
||||
}) |
|
||||
.catch(util.hideLoad) |
|
||||
}, |
|
||||
// 商城订单 |
|
||||
mallGet({ query = {}, vType = '', }){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.shop2WriteoffGet, |
|
||||
data: query, |
|
||||
isDefaultGet: false |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
if(res.data.code == 0){ |
|
||||
let _data = res.data.data || {}; |
|
||||
if(_data.has_order){ |
|
||||
util.$_emit(WRITE_OFF_MALL_ORDER_INFO, {..._data.order || {}}); |
|
||||
util.routeTo(`/pages/write_off/mall/confirm/confirm?type=${vType}`, 'nT'); |
|
||||
}else{ |
|
||||
util.routeTo(`/pages/write_off/null/null?type=${vType}`, 'nT'); |
|
||||
} |
|
||||
}else{ |
|
||||
util.showNone(res.data.message || '操作失败!') |
|
||||
// util.routeTo(`/pages/write_off/null/null?type=${vType}`, 'nT'); |
|
||||
} |
|
||||
|
|
||||
}) |
|
||||
.catch(util.hideLoad) |
|
||||
}, |
|
||||
|
|
||||
// 场地/ 年月卡 / 赛事 |
|
||||
// @vType verify_code(扫码)/ decrypt_text(输入) |
|
||||
|
|
||||
siteGet({ query = {}, vType = '', }){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.enterVerifyOrder, |
|
||||
data: query, |
|
||||
isDefaultGet: false |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
if(res.data.code == 0){ |
|
||||
let _data = res.data.data || {} |
|
||||
|
|
||||
// 年月卡 |
|
||||
if(_data.extension&&_data.extension.verify_order_type === 'monthly_card'){ |
|
||||
util.$_emit(WRITE_OFF_ORDER_INFO, { data: _data, query }); |
|
||||
util.routeTo(`/pages/write_off/ym_confirm/ym_confirm?type=${vType}`, 'nT'); |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
// 赛事 |
|
||||
if(_data.extension&&_data.extension.verify_order_type === 'match_order'){ |
|
||||
util.$_emit(WRITE_OFF_ORDER_INFO, {..._data}); |
|
||||
util.routeTo(`/pages/write_off/events_order/events_order?type=${vType}`, 'nT'); |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
util.$_emit(WRITE_OFF_ORDER_INFO, {..._data}); |
|
||||
util.routeTo(`/pages/write_off/confirm_order/confirm_order?type=${vType}`, 'nT'); |
|
||||
}else{ |
|
||||
util.routeTo(`/pages/write_off/null/null?type=${vType}`, 'nT'); |
|
||||
} |
|
||||
console.log('订单查询---->', res); |
|
||||
}) |
|
||||
.catch(util.hideLoad) |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
@import '~style/public.scss'; |
|
||||
page{ |
|
||||
background-color: #f2f2f7; |
|
||||
} |
|
||||
.operate-container{ |
|
||||
.store-bar{ |
|
||||
margin-bottom: 24upx; |
|
||||
padding: 0 24upx; |
|
||||
height: 144upx; |
|
||||
background-color: #fff; |
|
||||
@include centerFlex(space-between); |
|
||||
>text{ |
|
||||
margin-right: 20upx; |
|
||||
flex-shrink: 0; |
|
||||
font-size: 28upx; |
|
||||
color: #9C9C9F; |
|
||||
} |
|
||||
>picker{ |
|
||||
flex-grow: 1; |
|
||||
} |
|
||||
view{ |
|
||||
padding: 0 20upx; |
|
||||
height: 92upx; |
|
||||
border-radius: 10upx; |
|
||||
background: #f2f2f2; |
|
||||
@include centerFlex(space-between); |
|
||||
>input{ |
|
||||
flex-grow: 1; |
|
||||
height: 100%; |
|
||||
font-size: 28upx; |
|
||||
color: #1A1A1A; |
|
||||
} |
|
||||
>image{ |
|
||||
flex-shrink: 0; |
|
||||
flex-grow: 0; |
|
||||
width: 28upx; |
|
||||
height: 28upx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.c-scan-btn{ |
|
||||
margin: 0 auto 24upx; |
|
||||
width: 702upx; |
|
||||
height: 360upx; |
|
||||
border-radius: 10upx; |
|
||||
background-color: #fff; |
|
||||
@include centerFlex(center); |
|
||||
>image{ |
|
||||
width: 172upx; |
|
||||
height: 172upx; |
|
||||
} |
|
||||
} |
|
||||
.c-verification-code{ |
|
||||
padding: 40upx; |
|
||||
border-radius: 10upx; |
|
||||
background-color: #fff; |
|
||||
>view{ |
|
||||
&:first-child{ |
|
||||
margin-bottom: 30upx; |
|
||||
padding: 0 20upx; |
|
||||
height: 112upx; |
|
||||
border-radius: 10upx; |
|
||||
background-color: #f2f2f7; |
|
||||
>input{ |
|
||||
height: 100%; |
|
||||
width: 100%; |
|
||||
font-size: 32upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
} |
|
||||
&+view{ |
|
||||
height: 112upx; |
|
||||
text-align: center; |
|
||||
line-height: 112upx; |
|
||||
border-radius: 10upx; |
|
||||
font-size: 32upx; |
|
||||
color: #fff; |
|
||||
background-color: $themeColor; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,339 +0,0 @@ |
|||||
<template> |
|
||||
<view class="search-result"> |
|
||||
<view class="store-bar"> |
|
||||
<text>当前门店</text> |
|
||||
<picker mode="selector" :range="stadiumList" range-key="name" @change="stadiumChange"> |
|
||||
<view> |
|
||||
<input disabled v-model="curStadium.name" /> |
|
||||
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> |
|
||||
</view> |
|
||||
</picker> |
|
||||
</view> |
|
||||
<view class="r-timer-select"> |
|
||||
<picker mode="date" @change="dateChange"> |
|
||||
<view> |
|
||||
<text>核销日期:{{curDate || '-'}}</text> |
|
||||
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> |
|
||||
</view> |
|
||||
</picker> |
|
||||
<view>核销数量:{{writeOffList.length || 0}}</view> |
|
||||
</view> |
|
||||
<view class="r-order-list"> |
|
||||
<view class="l-item" v-for="(e, i) in writeOffList" :key="i"> |
|
||||
<view class="i-name">{{ e.extension.stadium_name || '-' }}</view> |
|
||||
<view class="i-lines"> |
|
||||
<view> |
|
||||
<view>订单编号:{{ e.order_no || '-' }}</view> |
|
||||
<view>({{ e.type || '-' }})</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
<view>用户信息:{{ e.extension.user_phone || '-' }}({{ e.extension.nickname || '-' }})</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
<view>核销码: {{e.verify_code || '-' }}</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
<view>验证方式:{{ e.desc || '-' }}</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
<view>核销时间:{{ e.verify_time || '-'}}</view> |
|
||||
</view> |
|
||||
<view> |
|
||||
<view>离场时间:{{ e.verify_leave_time || ''}}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="i-btn" v-if="e.verify_leave_time==''" @click="leaveBtn(e)">手动离场</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
<view class="r-bottom-btn"><view @click="toOperate">核销订单</view></view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import util from '../../../utils/util'; |
|
||||
import { API } from '../../../js/api'; |
|
||||
import { servers } from '../../../js/server'; |
|
||||
import { mapState } from 'vuex'; |
|
||||
import { WRITE_OFF_STORE_NAME } from '../../../js/once_name'; |
|
||||
export default { |
|
||||
computed: { |
|
||||
...mapState([ 'brandInfo' ]), |
|
||||
}, |
|
||||
data(){ |
|
||||
return { |
|
||||
stadiumList: [], // 店铺列表 |
|
||||
curStadium: {}, // 当前店铺 |
|
||||
writeOffList: [], // 核销列表, |
|
||||
curDate: util.formatDate({}), |
|
||||
page: 1, |
|
||||
totalNum: 0, |
|
||||
} |
|
||||
}, |
|
||||
// 20210716测试:取消分页,返回当天 |
|
||||
// onReachBottom(){ |
|
||||
// let { page, curDate, curStadium } = this; |
|
||||
// this.getList({ |
|
||||
// brand_id: curStadium.brand_id || '', |
|
||||
// stadium_id: curStadium.id || '', |
|
||||
// date: curDate || '', |
|
||||
// page: ++page, |
|
||||
// }); |
|
||||
// }, |
|
||||
onLoad(){ |
|
||||
this.initPage(); |
|
||||
}, |
|
||||
onShow(){ |
|
||||
let { curStadium } = this; |
|
||||
if(curStadium&&curStadium.id)this.refreshList(); |
|
||||
}, |
|
||||
methods: { |
|
||||
refreshList(){ |
|
||||
let { curDate, curStadium } = this; |
|
||||
this.page = 1; |
|
||||
this.writeOffList = []; |
|
||||
this.getList({ |
|
||||
brand_id: curStadium.brand_id || '', |
|
||||
stadium_id: curStadium.id || '', |
|
||||
date: curDate || '', |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
dateChange(e){ |
|
||||
this.curDate = e.detail.value; |
|
||||
this.$nextTick(this.refreshList); |
|
||||
}, |
|
||||
stadiumChange(e){ |
|
||||
let { stadiumList } = this; |
|
||||
this.curStadium = stadiumList[e.detail.value]; |
|
||||
this.$nextTick(this.refreshList); |
|
||||
}, |
|
||||
|
|
||||
async initPage(){ |
|
||||
let { brandInfo } = this; |
|
||||
try{ |
|
||||
let _storeList = await this.getStoreList({ brand_id: brandInfo.brand.id || '' }); |
|
||||
this.stadiumList = _storeList || []; |
|
||||
if(_storeList.length) this.curStadium = _storeList[0]; |
|
||||
this.$nextTick(this.refreshList); |
|
||||
}catch(err){ |
|
||||
console.warn('加载数据失败!', err); |
|
||||
} |
|
||||
}, |
|
||||
toOperate(){ |
|
||||
let { stadiumList, curStadium } = this; |
|
||||
util.$_emit(WRITE_OFF_STORE_NAME, { |
|
||||
stadiumList, |
|
||||
curStadium, |
|
||||
}) |
|
||||
util.routeTo(`/pages/write_off/operate/operate?type=site`, 'nT'); |
|
||||
}, |
|
||||
getList({ brand_id, stadium_id = '', date = '', page = 1, page_size = '' }){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.listVerifyRecord, |
|
||||
data: { brand_id, stadium_id, date, page, page_size }, |
|
||||
failMsg: '加载失败!', |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
this.totalNum = res.total || 0; |
|
||||
let _list = res.list || []; |
|
||||
if(page == 1)return this.writeOffList = _list; |
|
||||
if(!_list.length)return util.showNone('没有更多!'); |
|
||||
this.page = page; |
|
||||
this.writeOffList = [...this.writeOffList, ..._list]; |
|
||||
|
|
||||
}) |
|
||||
}, |
|
||||
getStoreList({ |
|
||||
page=1, |
|
||||
page_size=9999, |
|
||||
brand_id='', |
|
||||
}){ |
|
||||
return servers.get({ |
|
||||
url: API.stadiumList, |
|
||||
data: { |
|
||||
page, |
|
||||
page_size, |
|
||||
brand_id, |
|
||||
}, |
|
||||
failMsg: '获取列表失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
let _list = res.list || []; |
|
||||
return _list |
|
||||
}) |
|
||||
}, |
|
||||
|
|
||||
leaveBtn(item){ |
|
||||
let { curStadium } = this; |
|
||||
util.showModal({ |
|
||||
title: '提示', |
|
||||
content: '是否确认手动离场?', |
|
||||
showCancel: true, |
|
||||
success: modalRes=>{ |
|
||||
if(modalRes.confirm){ |
|
||||
util.showLoad(); |
|
||||
servers.get({ |
|
||||
url: API.writeOff.leaveVerifyOrder, |
|
||||
data: { |
|
||||
brand_id: curStadium.brand_id, |
|
||||
id: item.id, |
|
||||
}, |
|
||||
failMsg: '请求失败!' |
|
||||
}) |
|
||||
.then(res=>{ |
|
||||
util.hideLoad(); |
|
||||
util.showNone('操作成功!'); |
|
||||
this.refreshList() |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
}) |
|
||||
}, |
|
||||
} |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss"> |
|
||||
@import "~style/public.scss"; |
|
||||
page{ |
|
||||
background-color: #f2f2f7; |
|
||||
} |
|
||||
.search-result{ |
|
||||
padding-bottom: 132upx; |
|
||||
padding-bottom: calc( 132upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|
||||
padding-bottom: calc( 132upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|
||||
.store-bar{ |
|
||||
padding: 0 24upx; |
|
||||
height: 144upx; |
|
||||
background-color: #fff; |
|
||||
@include centerFlex(space-between); |
|
||||
>text{ |
|
||||
margin-right: 20upx; |
|
||||
flex-shrink: 0; |
|
||||
font-size: 28upx; |
|
||||
color: #9C9C9F; |
|
||||
} |
|
||||
>picker{ |
|
||||
flex-grow: 1; |
|
||||
} |
|
||||
view{ |
|
||||
padding: 0 20upx; |
|
||||
height: 92upx; |
|
||||
border-radius: 10upx; |
|
||||
background: #f2f2f2; |
|
||||
@include centerFlex(space-between); |
|
||||
>input{ |
|
||||
flex-grow: 1; |
|
||||
height: 100%; |
|
||||
font-size: 28upx; |
|
||||
color: #1A1A1A; |
|
||||
} |
|
||||
>image{ |
|
||||
flex-shrink: 0; |
|
||||
flex-grow: 0; |
|
||||
width: 28upx; |
|
||||
height: 28upx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.r-timer-select{ |
|
||||
padding: 0 24upx; |
|
||||
margin-bottom: 10upx; |
|
||||
@include centerFlex(space-between); |
|
||||
picker{ |
|
||||
flex-shrink: 0; |
|
||||
view{ |
|
||||
padding: 24upx 0; |
|
||||
>text{ |
|
||||
font-weight: 500; |
|
||||
font-size: 32upx; |
|
||||
} |
|
||||
>image{ |
|
||||
margin-left: 16upx; |
|
||||
vertical-align: middle; |
|
||||
width: 22upx; |
|
||||
height: 22upx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
>view{ |
|
||||
max-width: 40%; |
|
||||
text-align: right; |
|
||||
font-weight: 500; |
|
||||
font-size: 32upx; |
|
||||
@include textHide(1); |
|
||||
} |
|
||||
} |
|
||||
.r-order-list{ |
|
||||
padding: 0 24upx; |
|
||||
.l-item{ |
|
||||
position: relative; |
|
||||
margin-bottom: 24upx; |
|
||||
padding: 0 20upx; |
|
||||
border-radius: 10upx; |
|
||||
background-color: #fff; |
|
||||
.i-name{ |
|
||||
height: 100upx; |
|
||||
line-height: 98upx; |
|
||||
border-bottom: 2upx solid #D8D8D8; |
|
||||
font-weight: 500; |
|
||||
font-size: 28upx; |
|
||||
color: #1a1a1a; |
|
||||
} |
|
||||
.i-lines{ |
|
||||
padding-top: 8upx; |
|
||||
padding-bottom: 32upx; |
|
||||
>view{ |
|
||||
display: flex; |
|
||||
>view{ |
|
||||
min-width: 0; |
|
||||
line-height: 52upx; |
|
||||
font-size: 28upx; |
|
||||
color: #9c9c9f; |
|
||||
@include textHide(1); |
|
||||
&+view{ |
|
||||
flex-shrink: 0; |
|
||||
color: $themeColor; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
.i-btn{ |
|
||||
position: absolute; |
|
||||
right: 20rpx; |
|
||||
bottom: 32rpx; |
|
||||
background-color: #009874; |
|
||||
border-radius: 10rpx; |
|
||||
width: 156rpx; |
|
||||
height: 68rpx; |
|
||||
color: #FFFFFF; |
|
||||
font-size: 28rpx; |
|
||||
text-align: center; |
|
||||
line-height: 68rpx; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.r-bottom-btn{ |
|
||||
position: fixed; |
|
||||
left: 0; |
|
||||
bottom: 0; |
|
||||
width: 100%; |
|
||||
padding: 10upx 24upx; |
|
||||
padding-bottom: calc( 10upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ |
|
||||
padding-bottom: calc( 10upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ |
|
||||
background-color: #f2f2f7; |
|
||||
>view{ |
|
||||
height: 112upx; |
|
||||
line-height: 112upx; |
|
||||
text-align: center; |
|
||||
font-size: 32upx; |
|
||||
border-radius: 10upx; |
|
||||
color: #fff; |
|
||||
background-color: $themeColor; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
Before Width: 380 | Height: 380 | Size: 7.4 KiB |
Before Width: 700 | Height: 700 | Size: 33 KiB |
Before Width: 380 | Height: 380 | Size: 8.5 KiB |
Before Width: 420 | Height: 420 | Size: 11 KiB |
Before Width: 128 | Height: 128 | Size: 1.4 KiB |
Before Width: 128 | Height: 128 | Size: 1.0 KiB |
Before Width: 128 | Height: 128 | Size: 1.8 KiB |
Before Width: 120 | Height: 120 | Size: 1.4 KiB |
@ -0,0 +1,59 @@ |
|||||
|
<template> |
||||
|
<view class="head-bar"> |
||||
|
<picker class="hb-picker" :range="range" :range-key="rangeKey" @change="$emit('change', $event)"> |
||||
|
<view class="hp-frame"> |
||||
|
<input class="hf-ipt" type="text" disabled :value="value" :placeholder="placeholder"> |
||||
|
<image class="hf-icon" mode="aspectFit" src="/subpackage/verification/static/images/arrow_c9f.png"></image> |
||||
|
</view> |
||||
|
</picker> |
||||
|
<image v-if="search" class="hb-icon" mode="aspectFit" src="/subpackage/verification/static/images/search.png" @click="$emit('click:search')"></image> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
value: { type: String, default: '' }, |
||||
|
placeholder: { type: String, default: '' }, |
||||
|
range: { type: Array, default: [] }, |
||||
|
rangeKey: { type: String, default: '' }, |
||||
|
search: { type: Boolean, default: false } |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.head-bar{ |
||||
|
padding-left: 24upx; |
||||
|
padding-right: 24upx; |
||||
|
height: 144upx; |
||||
|
background: #fff; |
||||
|
@include ctf(space-between); |
||||
|
.hb-picker{ |
||||
|
flex-grow: 1; |
||||
|
.hp-frame{ |
||||
|
padding: 0 24upx; |
||||
|
height: 92upx; |
||||
|
background: #f2f2f7; |
||||
|
@include ctf(space-between); |
||||
|
.hf-ipt{ |
||||
|
flex-grow: 1; |
||||
|
height: 100%; |
||||
|
@include flcw(28upx, 40upx, #333); |
||||
|
} |
||||
|
.hf-icon{ |
||||
|
flex-shrink: 0; |
||||
|
width: 28upx; |
||||
|
height: 28upx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.hb-icon{ |
||||
|
flex-shrink: 0; |
||||
|
margin-right: 16upx; |
||||
|
margin-left: 26upx; |
||||
|
width: 40upx; |
||||
|
height: 40upx; |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,78 @@ |
|||||
|
<template> |
||||
|
<view class="site-item"> |
||||
|
<!-- <view class="si-stadium">{{ stadiumName || '-' }}</view> --> |
||||
|
<view class="si-lines"> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">订单编号:{{ orderNum || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">用户信息:{{ userPhone || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">券码: {{ verifyCode || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">验证方式:{{ verifyMethod || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">核销时间:{{ verifyTime || '-' }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: [ |
||||
|
// 'stadiumName', |
||||
|
'orderNum', |
||||
|
'userPhone', |
||||
|
'verifyCode', |
||||
|
'verifyMethod', |
||||
|
'verifyTime', |
||||
|
] |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.site-item{ |
||||
|
position: relative; |
||||
|
padding: 0 20upx; |
||||
|
border-radius: 10upx; |
||||
|
background: #fff; |
||||
|
.si-stadium{ |
||||
|
min-height: 100upx; |
||||
|
border-bottom: 2upx solid #D8D8D8; |
||||
|
@include flcw(28upx, 98upx, #1A1A1A, 500); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.si-lines{ |
||||
|
padding-top: 8upx; |
||||
|
padding-bottom: 32upx; |
||||
|
.sl-item{ |
||||
|
display: flex; |
||||
|
.sl-left{ |
||||
|
@include flcw(28upx, 52upx, #9c9c9f); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.sl-right{ |
||||
|
max-width: 200upx; |
||||
|
flex-shrink: 0; |
||||
|
margin-left: 10upx; |
||||
|
@include flcw(28upx, 52upx, $mColor); |
||||
|
@include tHide; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.si-btn{ |
||||
|
position: absolute; |
||||
|
right: 20upx; |
||||
|
bottom: 32upx; |
||||
|
width: 192upx; |
||||
|
text-align: center; |
||||
|
background-color: $mColor; |
||||
|
border-radius: 10upx; |
||||
|
@include flcw(32upx, 80upx, #fff, 500); |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,95 @@ |
|||||
|
<template> |
||||
|
<view class="site-item"> |
||||
|
<view class="si-order-num"> |
||||
|
<view class="son-txt">订单编号:{{ orderNum || '-' }}</view> |
||||
|
<view class="son-copy" @click="copyBtn">复制</view> |
||||
|
</view> |
||||
|
<view class="si-lines"> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">取货码:{{ orderCode || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">取货人:{{ userName || '-' }} {{ userPhone || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">商品:{{ goodsStr || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">核验人:{{ optUser || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">取货时间:{{ createdAt || '-' }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
props: [ |
||||
|
'orderNum', |
||||
|
'orderCode', |
||||
|
'userPhone', |
||||
|
'userName', |
||||
|
'goodsStr', |
||||
|
'optUser', |
||||
|
'createdAt', |
||||
|
], |
||||
|
methods: { |
||||
|
copyBtn(){ |
||||
|
uni.setClipboardData({ data: this.orderNum }); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss"> |
||||
|
.site-item{ |
||||
|
position: relative; |
||||
|
padding: 0 20upx; |
||||
|
border-radius: 10upx; |
||||
|
background: #fff; |
||||
|
.si-order-num{ |
||||
|
min-height: 100upx; |
||||
|
border-bottom: 2upx solid #D8D8D8; |
||||
|
@include ctf; |
||||
|
.son-txt{ |
||||
|
flex-grow: 1; |
||||
|
@include flcw(28upx, 98upx, #1A1A1A, 500); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.son-copy{ |
||||
|
padding-right: 20upx; |
||||
|
margin-left: 20upx; |
||||
|
flex-shrink: 0; |
||||
|
@include flcw(28upx, 98upx, $mColor, 500); |
||||
|
} |
||||
|
} |
||||
|
.si-lines{ |
||||
|
padding-top: 8upx; |
||||
|
padding-bottom: 32upx; |
||||
|
.sl-item{ |
||||
|
display: flex; |
||||
|
.sl-left{ |
||||
|
@include flcw(28upx, 52upx, #9c9c9f); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.sl-right{ |
||||
|
max-width: 200upx; |
||||
|
flex-shrink: 0; |
||||
|
margin-left: 10upx; |
||||
|
@include flcw(28upx, 52upx, $mColor); |
||||
|
@include tHide; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.si-btn{ |
||||
|
position: absolute; |
||||
|
right: 20upx; |
||||
|
bottom: 32upx; |
||||
|
width: 192upx; |
||||
|
text-align: center; |
||||
|
background-color: $mColor; |
||||
|
border-radius: 10upx; |
||||
|
@include flcw(32upx, 80upx, #fff, 500); |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,87 @@ |
|||||
|
<template> |
||||
|
<view class="site-item"> |
||||
|
<view class="si-stadium">{{ stadiumName || '-' }}</view> |
||||
|
<view class="si-lines"> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">订单编号:{{ orderNum || '-' }}</view> |
||||
|
<view class="sl-right">({{ orderType || '-' }})</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">用户信息:{{ userPhone || '-' }}({{ userNickname || '-' }})</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">核销码: {{ verifyCode || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">验证方式:{{ verifyMethod || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">核销时间:{{ verifyTime || '-' }}</view> |
||||
|
</view> |
||||
|
<view class="sl-item"> |
||||
|
<view class="sl-left">离场时间:{{ verifyLeaveTime || '-' }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="si-btn" v-if="verifyLeaveTime === ''" @click="$emit('click:leave')">手动离场</view> |
||||
|
</view> |
||||
|
|
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: [ |
||||
|
'stadiumName', |
||||
|
'orderNum', |
||||
|
'orderType', |
||||
|
'userPhone', |
||||
|
'userNickname', |
||||
|
'verifyCode', |
||||
|
'verifyMethod', |
||||
|
'verifyTime', |
||||
|
'verifyLeaveTime', |
||||
|
] |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.site-item{ |
||||
|
position: relative; |
||||
|
padding: 0 20upx; |
||||
|
border-radius: 10upx; |
||||
|
background: #fff; |
||||
|
.si-stadium{ |
||||
|
min-height: 100upx; |
||||
|
border-bottom: 2upx solid #D8D8D8; |
||||
|
@include flcw(28upx, 98upx, #1A1A1A, 500); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.si-lines{ |
||||
|
padding-top: 8upx; |
||||
|
padding-bottom: 32upx; |
||||
|
.sl-item{ |
||||
|
display: flex; |
||||
|
.sl-left{ |
||||
|
@include flcw(28upx, 52upx, #9c9c9f); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.sl-right{ |
||||
|
max-width: 200upx; |
||||
|
flex-shrink: 0; |
||||
|
margin-left: 10upx; |
||||
|
@include flcw(28upx, 52upx, $mColor); |
||||
|
@include tHide; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.si-btn{ |
||||
|
position: absolute; |
||||
|
right: 20upx; |
||||
|
bottom: 32upx; |
||||
|
width: 192upx; |
||||
|
text-align: center; |
||||
|
background-color: $mColor; |
||||
|
border-radius: 10upx; |
||||
|
@include flcw(32upx, 80upx, #fff, 500); |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,15 @@ |
|||||
|
<template> |
||||
|
<view class="stadium-picker"> |
||||
|
|
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
|
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
|
||||
|
</style> |
@ -0,0 +1,282 @@ |
|||||
|
<template> |
||||
|
<view class="write-off-index"> |
||||
|
<head-bar |
||||
|
:range="stadiumList" range-key="name" @change="stadiumChange" |
||||
|
placeholder="请选择场馆" :value="curStadium.name" |
||||
|
></head-bar> |
||||
|
<view class="woi-section"> |
||||
|
<view class="ws-ipt-box"> |
||||
|
<input class="wib-ipt" type="text" placeholder="请输入券码" v-model="iptCode" /> |
||||
|
<image @click="scanCode" class="wib-img" mode="aspectFit" src="/subpackage/verification/static/images/scan.png"></image> |
||||
|
</view> |
||||
|
<view class="ws-txt">可输入订场、次卡、年月卡、赛事、商城到店领取商品的验证码/券码进行核销,或点扫码图标进入扫描界面扫码核销。</view> |
||||
|
<view class="ws-btn" @click="confirmBtn">确认</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="woi-btns"> |
||||
|
<view class="wb-items" @click="toAbnormal"> |
||||
|
<image class="wi-icon" mode="aspectFit" src="/subpackage/verification/static/images/tab0.png"></image> |
||||
|
<view class="wi-txt">进场人数异常</view> |
||||
|
</view> |
||||
|
<view class="wb-items" @click="toSitePeople"> |
||||
|
<image class="wi-icon" mode="aspectFit" src="/subpackage/verification/static/images/tab1.png"></image> |
||||
|
<view class="wi-txt">现场人数</view> |
||||
|
</view> |
||||
|
<view class="wb-items" @click="toRecord"> |
||||
|
<image class="wi-icon" mode="aspectFit" src="/subpackage/verification/static/images/tab2.png"></image> |
||||
|
<view class="wi-txt">核销记录</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
import API from "../js/api.js"; |
||||
|
import server from "../js/server.js"; |
||||
|
import { showLoad, hideLoad, showModal, showNone, debounce, changeLowerCase, $_emit, routeTo, jsonStr } from "@/utils/util.js"; |
||||
|
import { WRITE_OFF_ORDER_INFO } from '@/js/once_name'; |
||||
|
import headBar from "../components/head_bar.vue"; |
||||
|
export default { |
||||
|
components: { headBar }, |
||||
|
data(){ |
||||
|
return{ |
||||
|
brand_id: '', |
||||
|
stadiumList: [], |
||||
|
curStadium: {}, |
||||
|
iptCode: '', |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* @param {String} options.brand_id 品牌id |
||||
|
* @param {String} options.stadium_id 场馆id |
||||
|
*/ |
||||
|
async onLoad(options){ |
||||
|
let _brand_id = options?.brand_id || ''; |
||||
|
this.brand_id = _brand_id; |
||||
|
let _stadiumLs = await this.getStadiumLs({ brand_id: _brand_id }); |
||||
|
if(options?.stadium_id&&_stadiumLs?.length){ |
||||
|
// 设置选中场馆 |
||||
|
let _selected = _stadiumLs.find(ele => +ele.id === +(options?.stadium_id ?? '')); |
||||
|
if(_selected?.id)this.curStadium = _selected; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 现场人数 |
||||
|
toSitePeople(){ |
||||
|
let { brand_id, curStadium } = this; |
||||
|
let _qryStr = `brand_id=${brand_id}` |
||||
|
if(curStadium?.id) _qryStr += `&stadium_id=${curStadium.id}`; |
||||
|
routeTo(`/subpackage/verification/pages/site_people/index?${_qryStr}`, 'nT'); |
||||
|
}, |
||||
|
// 人数异常 |
||||
|
toAbnormal(){ |
||||
|
let { brand_id, curStadium } = this; |
||||
|
let _qryStr = `brand_id=${brand_id}` |
||||
|
if(curStadium?.id) _qryStr += `&stadium_id=${curStadium.id}`; |
||||
|
routeTo(`/subpackage/blacklist/pages/abnormal_list/abnormal_list?${_qryStr}`, 'nT'); |
||||
|
}, |
||||
|
toRecord(){ |
||||
|
let { brand_id, curStadium } = this; |
||||
|
let _qryStr = `brand_id=${brand_id}` |
||||
|
if(curStadium?.id) _qryStr += `&stadium_id=${curStadium.id}`; |
||||
|
routeTo(`/subpackage/verification/pages/record?${_qryStr}`, 'nT'); |
||||
|
}, |
||||
|
confirmBtn: debounce(function(){ |
||||
|
let { iptCode } = this; |
||||
|
let { curStadium } = this; |
||||
|
if(!curStadium?.id)return showModal({ content: '请选择场馆!' }); |
||||
|
this.verifyOrder({ |
||||
|
brand_id: curStadium?.brand_id ?? '', |
||||
|
stadium_id: curStadium?.id ?? '', |
||||
|
verify_code: iptCode ?? '', |
||||
|
}) |
||||
|
}, 300, true), |
||||
|
scanCode: debounce(function(){ |
||||
|
let { curStadium } = this; |
||||
|
if(!curStadium?.id)return showModal({ content: '请选择场馆!' }); |
||||
|
uni.scanCode({ |
||||
|
onlyFromCamera: true, |
||||
|
scanType: 'qrCode', |
||||
|
success: res=> { |
||||
|
if(changeLowerCase(res.scanType) !== 'qr_code')return showNone('不支持此类型!'); |
||||
|
let { curStadium } = this; |
||||
|
this.verifyOrder({ |
||||
|
brand_id: curStadium?.brand_id ?? '', |
||||
|
stadium_id: curStadium?.id ?? '', |
||||
|
decrypt_text: res?.result ?? '', |
||||
|
}) |
||||
|
}, |
||||
|
fail: function(err) { |
||||
|
showNone('扫码失败!'); |
||||
|
console.warn('扫码失败--->', err); |
||||
|
} |
||||
|
}) |
||||
|
}, 300, true), |
||||
|
stadiumChange(e){ |
||||
|
let { stadiumList } = this; |
||||
|
this.curStadium = stadiumList[e.detail.value]; |
||||
|
}, |
||||
|
// 获取门店列表 |
||||
|
getStadiumLs({ brand_id }){ |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: API.stadiumList, |
||||
|
data: { page_size: 9999, page: 1, brand_id }, |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
let _ls = _data?.data?.list || []; |
||||
|
return this.stadiumList = _ls; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '加载店铺失败!' |
||||
|
}) |
||||
|
console.warn('verification index getStadiumLs err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
}) |
||||
|
}, |
||||
|
/** |
||||
|
* 订单预检验 |
||||
|
* @param {String} brand_id |
||||
|
* @param {String} stadium_id |
||||
|
* @param {String} verify_code 订单验证码 |
||||
|
* @param {String} decrypt_text 二维码数据 |
||||
|
* */ |
||||
|
verifyOrder({ brand_id, stadium_id, verify_code = '', decrypt_text = '' }){ |
||||
|
let _vType = verify_code ? 'verify_code' : decrypt_text ? 'decrypt_text' : ''; |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: API.enterVerifyOrder, |
||||
|
data: { brand_id, stadium_id, verify_code, decrypt_text }, |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
let _orderData = _data?.data || {}; |
||||
|
// 商城订单 |
||||
|
if(_orderData?.extension?.verify_order_type === 'product_order'){ |
||||
|
$_emit(WRITE_OFF_MALL_ORDER_INFO, { data: _orderData }); |
||||
|
routeTo(`/pages/write_off/mall/confirm/confirm?type=${_vType}`, 'nT'); |
||||
|
return |
||||
|
} |
||||
|
// 年月卡 |
||||
|
if(_orderData?.extension?.verify_order_type === 'monthly_card'){ |
||||
|
$_emit(WRITE_OFF_ORDER_INFO, { data: _orderData, query: { brand_id, stadium_id, verify_code, decrypt_text } }); |
||||
|
routeTo(`/pages/write_off/ym_confirm/ym_confirm?type=${_vType}`, 'nT'); |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 赛事 |
||||
|
if(_orderData?.extension?.verify_order_type === 'match_order'){ |
||||
|
$_emit(WRITE_OFF_ORDER_INFO, {..._orderData}); |
||||
|
routeTo(`/pages/write_off/events_order/events_order?type=${_vType}`, 'nT'); |
||||
|
return |
||||
|
} |
||||
|
// 场次、次卡 |
||||
|
if(['person_number', 'venue_number'].includes(_orderData?.extension?.verify_order_type)){ |
||||
|
$_emit(WRITE_OFF_ORDER_INFO, { ..._orderData }); |
||||
|
routeTo(`/pages/write_off/confirm_order/confirm_order?type=${_vType}`, 'nT'); |
||||
|
return |
||||
|
} |
||||
|
showModal({ content: '暂不支持该类型核销!' }) |
||||
|
}else if(_data.code === 805){ |
||||
|
routeTo(`/subpackage/verification/pages/null?tip=${jsonStr(_data?.message ?? '')}`, 'nT'); |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '核销查询失败!' |
||||
|
}) |
||||
|
console.warn('verification index verifyOrder err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.write-off-index{ |
||||
|
|
||||
|
.woi-section{ |
||||
|
margin-top: 24upx; |
||||
|
padding-top: 26upx; |
||||
|
padding-bottom: 80upx; |
||||
|
background: #fff; |
||||
|
.ws-ipt-box{ |
||||
|
margin: 0 auto; |
||||
|
padding: 0 20upx; |
||||
|
width: 702upx; |
||||
|
height: 92upx; |
||||
|
background: #F2F2F7; |
||||
|
border-radius: 10upx; |
||||
|
@include ctf; |
||||
|
.wib-ipt{ |
||||
|
flex-grow: 1; |
||||
|
height: 100%; |
||||
|
@include flcw(28upx, 40upx, #333); |
||||
|
} |
||||
|
.wib-img{ |
||||
|
flex-shrink: 0; |
||||
|
margin-left: 20upx; |
||||
|
width: 60upx; |
||||
|
height: 60upx; |
||||
|
} |
||||
|
} |
||||
|
.ws-txt{ |
||||
|
margin-top: 24upx; |
||||
|
padding: 0 32upx; |
||||
|
@include flcw(28upx, 52upx, #333); |
||||
|
} |
||||
|
.ws-btn{ |
||||
|
margin: 22upx auto 0; |
||||
|
text-align: center; |
||||
|
width: 240upx; |
||||
|
border-radius: 10upx; |
||||
|
background: $mColor; |
||||
|
@include flcw(32upx, 88upx, #fff); |
||||
|
} |
||||
|
} |
||||
|
.woi-btns{ |
||||
|
margin-top: 24upx; |
||||
|
padding: 38upx 24upx; |
||||
|
background: #fff; |
||||
|
@include ctf(space-between); |
||||
|
.wb-items{ |
||||
|
padding: 18upx 0; |
||||
|
flex-grow: 0; |
||||
|
flex-shrink: 0; |
||||
|
width: 226upx; |
||||
|
.wi-icon{ |
||||
|
display: block; |
||||
|
margin: 0 auto; |
||||
|
width: 64upx; |
||||
|
height: 64upx; |
||||
|
} |
||||
|
.wi-txt{ |
||||
|
margin-top: 24upx; |
||||
|
text-align: center; |
||||
|
@include flcw(28upx, 40upx, #333); |
||||
|
@include tHide; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,62 @@ |
|||||
|
<template> |
||||
|
<view class="null-container"> |
||||
|
<image v-if="tipHas('二维码')" class="nc-pic" mode="aspectFit" src="/subpackage/verification/static/images/order/null_code.png"></image> |
||||
|
<image v-else-if="tipHas('范围')" class="nc-pic" mode="aspectFit" src="/subpackage/verification/static/images/order/null_range.png"></image> |
||||
|
<image v-else class="nc-pic" mode="aspectFit" src="/subpackage/verification/static/images/order/null_search.png"></image> |
||||
|
<view class="nc-txt">{{ tip || '很抱歉!获取找不到订单信息' }}</view> |
||||
|
<view class="nc-btn" @click="routeTo">返回</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { jsonPar, routeTo } from '@/utils/util'; |
||||
|
export default { |
||||
|
data(){ |
||||
|
return { |
||||
|
tip: '', |
||||
|
} |
||||
|
}, |
||||
|
onLoad(options){ |
||||
|
let _tip = options?.tip ?? ''; |
||||
|
this.tip = jsonPar(_tip); |
||||
|
}, |
||||
|
methods: { |
||||
|
tipHas(txt){ |
||||
|
let { tip } = this; |
||||
|
return tip.indexOf(txt) > -1; |
||||
|
}, |
||||
|
routeTo, |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
page{ |
||||
|
background: #fff; |
||||
|
} |
||||
|
.null-container{ |
||||
|
padding-top: 220upx; |
||||
|
.nc-pic{ |
||||
|
display: block; |
||||
|
width: 400upx; |
||||
|
height: 400upx; |
||||
|
margin: 0 auto; |
||||
|
} |
||||
|
.nc-txt{ |
||||
|
padding: 0 30upx; |
||||
|
margin-top: 80upx; |
||||
|
text-align: center; |
||||
|
@include flcw(28upx, 40upx, #9C9C9F); |
||||
|
} |
||||
|
.nc-btn{ |
||||
|
margin: 260upx auto 0; |
||||
|
width: 280upx; |
||||
|
text-align: center; |
||||
|
height: 92upx; |
||||
|
border-radius: 10upx; |
||||
|
border: 2upx solid $mColor; |
||||
|
@include flcw(32upx, 88upx, $mColor); |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,394 @@ |
|||||
|
<template> |
||||
|
<view class="verification-record"> |
||||
|
<view class="vr-header"> |
||||
|
<head-bar |
||||
|
:range="stadiumList" range-key="name" @change="stadiumChange" |
||||
|
placeholder="请选择场馆" :value="curStadium.name" |
||||
|
search |
||||
|
@click:search="toSearch" |
||||
|
></head-bar> |
||||
|
<view class="vh-tabs"> |
||||
|
<view v-for="(e,i) in tabs" :key="i" :class="{ 'vt-item': true, active: curTab === i }" @click="curTab = i">{{ e }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="vr-time-board"> |
||||
|
<view class="vtb-time" @click="showPeriodModal"> |
||||
|
<view class="vt-txt">{{ showPeriodStr }}</view> |
||||
|
<image class="vt-icon" mode="aspectFit" src="/subpackage/verification/static/images/calendar.png"></image> |
||||
|
</view> |
||||
|
<view class="vtb-num">核销数量:{{ recordLs.length || 0 }}</view> |
||||
|
</view> |
||||
|
|
||||
|
<view class="vr-list"> |
||||
|
<block v-for="(e, i) in recordLs" :key="i"> |
||||
|
<site-item |
||||
|
v-if="curTab === 0" |
||||
|
:stadium-name="e.extension&&e.extension.stadium_name" |
||||
|
:order-num="e.order_no" |
||||
|
:order-type="e.type" |
||||
|
:user-phone="e.extension&&e.extension.user_phone" |
||||
|
:user-nickname="e.extension&&e.extension.nickname" |
||||
|
:verify-code="e.verify_code" |
||||
|
:verify-method="e.desc" |
||||
|
:verify-time="e.verify_time" |
||||
|
:verify-leave-time="e.verify_leave_time" |
||||
|
@click:leave="siteLeaveBtn(e, i)" |
||||
|
></site-item> |
||||
|
<dy-item |
||||
|
v-if="curTab === 1" |
||||
|
:order-num="e.order_no" |
||||
|
:user-phone="e.user_phone" |
||||
|
:verify-code="e.verify_code" |
||||
|
:verify-method="e.verify_method" |
||||
|
:verify-time="e.verify_time" |
||||
|
></dy-item> |
||||
|
<mall-item |
||||
|
v-if="curTab === 2" |
||||
|
:order-num="e.product_order_no" |
||||
|
:order-code="e.product_order_self_pickup_info.gcode" |
||||
|
:user-phone="e.product_order_self_pickup_info.phone" |
||||
|
:user-name="e.product_order_self_pickup_info.name" |
||||
|
:goods-str="e.product_order_goods.join(';')" |
||||
|
:opt-user="e.optuname" |
||||
|
:created-at="e.created_at" |
||||
|
></mall-item> |
||||
|
<view class="vl-space" style="height: 24rpx;"></view> |
||||
|
</block> |
||||
|
|
||||
|
</view> |
||||
|
|
||||
|
<period-select ref="periodSelect" v-model="periodStr" ></period-select> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import headBar from "../components/head_bar.vue"; |
||||
|
import siteItem from "../components/record/site_item.vue"; |
||||
|
import dyItem from "../components/record/dy_item.vue"; |
||||
|
import mallItem from "../components/record/mall_item.vue"; |
||||
|
import periodSelect from "@/components/period_select.vue"; |
||||
|
import { formatDate, showLoad, hideLoad, showModal, showNone, debounce, formatTime, routeTo } from "@/utils/util"; |
||||
|
import API from "../js/api.js"; |
||||
|
import server from "../js/server.js"; |
||||
|
export default { |
||||
|
components: { headBar, siteItem, dyItem, mallItem, periodSelect }, |
||||
|
computed: { |
||||
|
// 展示时间段字符串 |
||||
|
showPeriodStr(){ |
||||
|
let { periodStr } = this; |
||||
|
return periodStr ? periodStr.replace(/\_/, ' 至 ').replace(/\-/g, '.') : '' |
||||
|
}, |
||||
|
// 时间段对象 用于请求 |
||||
|
periodObj(){ |
||||
|
let { periodStr } = this; |
||||
|
if(!periodStr)return {}; |
||||
|
let [start, end] = periodStr.split('_'); |
||||
|
if(start)start += ' 00:00:00'; |
||||
|
if(end)end += ' 23:59:59'; |
||||
|
return { |
||||
|
start: start ?? '', |
||||
|
end: end ?? '', |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
watch: { |
||||
|
periodStr(nVal, oVal){ |
||||
|
if(oVal&&nVal&&nVal !== oVal)this.refreshRecordLs(); |
||||
|
}, |
||||
|
curTab(nVal, oVal){ |
||||
|
if(nVal !== oVal)this.reloadRecordLs(); |
||||
|
} |
||||
|
}, |
||||
|
data(){ |
||||
|
return { |
||||
|
brand_id: '', |
||||
|
tabs: [ '场地核销记录', '抖音核销记录', '商城核销记录' ], |
||||
|
curTab: 0, |
||||
|
periodStr: '',/** ex: 2025-01-01_2025-01-02 */ |
||||
|
stadiumList: [], |
||||
|
curStadium: {}, |
||||
|
recordLs: [], |
||||
|
page: 1, |
||||
|
} |
||||
|
}, |
||||
|
/** |
||||
|
* @param {Object} options |
||||
|
* @param {String} options.brand_id // 品牌id |
||||
|
* @param {String} options.stadium_id // 场馆id |
||||
|
*/ |
||||
|
async onLoad(options){ |
||||
|
this.brand_id = options?.brand_id ?? ''; |
||||
|
let _stadiumLs = await this.getStadiumLs({ brand_id: options?.brand_id ?? '' }); |
||||
|
if(options?.stadium_id&&_stadiumLs?.length){ |
||||
|
// 设置选中场馆 |
||||
|
let _selected = _stadiumLs.find(ele => +ele.id === +(options?.stadium_id ?? '')); |
||||
|
if(_selected?.id)this.curStadium = _selected; |
||||
|
} |
||||
|
this.reloadRecordLs(); |
||||
|
}, |
||||
|
onReachBottom(){ |
||||
|
let { curStadium, periodObj, page, brand_id } = this; |
||||
|
this.getRecordLs({ |
||||
|
brand_id: brand_id ?? '', |
||||
|
stadium_id: curStadium?.id ?? '', |
||||
|
start_time: periodObj?.start ?? '', |
||||
|
end_time: periodObj?.end ?? '', |
||||
|
page: page + 1, |
||||
|
}); |
||||
|
}, |
||||
|
methods: { |
||||
|
// 搜索 |
||||
|
toSearch(){ |
||||
|
let { brand_id, curTab } = this; |
||||
|
routeTo(`/subpackage/verification/pages/record_search?brand_id=${brand_id}&type=${curTab}`, 'nT'); |
||||
|
}, |
||||
|
// 手动离场 |
||||
|
siteLeaveBtn: debounce(function(e, idx){ |
||||
|
console.log(e, idx); |
||||
|
showModal({ |
||||
|
content: '是否确认手动离场?', |
||||
|
showCancel: true, |
||||
|
success: async mRes=>{ |
||||
|
if(mRes.confirm){ |
||||
|
let _status = await this.leaveVerifyOrder({ brand_id: e?.brand_id ?? '', id: e?.id ?? '' }); |
||||
|
if(_status)this.recordLs[idx].verify_leave_time = formatTime(new Date()); |
||||
|
this.$forceUpdate(); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, 300, true), |
||||
|
// 初始化时间段 |
||||
|
initPeriodStr(){ |
||||
|
let _today = new Date(); |
||||
|
let _todayTimestamp = _today.getTime(); |
||||
|
let _eStr = formatDate({ date: _today }); |
||||
|
let _first30DaysTimestamp = _todayTimestamp - 30 * 24 * 60 * 60 * 1000; |
||||
|
let _sStr = formatDate({ date: new Date(_first30DaysTimestamp) }); |
||||
|
return this.periodStr = `${_sStr}_${_eStr}`; |
||||
|
}, |
||||
|
showPeriodModal(){ |
||||
|
this.$refs?.periodSelect?.show?.(); |
||||
|
}, |
||||
|
// 门店切换 |
||||
|
stadiumChange(e){ |
||||
|
let { stadiumList } = this; |
||||
|
let _curStadium = stadiumList?.[e?.detail?.value ?? 0] ?? {}; |
||||
|
this.curStadium = _curStadium; |
||||
|
this.refreshRecordLs(); |
||||
|
}, |
||||
|
// 加载/ 切换订单类型 |
||||
|
reloadRecordLs(){ |
||||
|
let { brand_id } = this; |
||||
|
this.page = 1; |
||||
|
this.recordLs = []; |
||||
|
this.initPeriodStr(); |
||||
|
let { periodObj, curStadium } = this; |
||||
|
this.getRecordLs({ |
||||
|
brand_id: brand_id ?? '' , |
||||
|
stadium_id: curStadium.id ?? '', |
||||
|
start_time: periodObj.start, |
||||
|
end_time: periodObj.end, |
||||
|
}); |
||||
|
}, |
||||
|
// 切换门店/时间 |
||||
|
refreshRecordLs(){ |
||||
|
let { curStadium, periodObj, brand_id } = this; |
||||
|
this.page = 1; |
||||
|
this.recordLs = []; |
||||
|
this.getRecordLs({ |
||||
|
brand_id: brand_id ?? '', |
||||
|
stadium_id: curStadium?.id ?? '', |
||||
|
start_time: periodObj?.start ?? '', |
||||
|
end_time: periodObj?.end ?? '', |
||||
|
}); |
||||
|
}, |
||||
|
// 获取门店列表 |
||||
|
getStadiumLs({ brand_id }){ |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: API.stadiumList, |
||||
|
data: { page_size: 9999, page: 1, brand_id }, |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
let _ls = _data?.data?.list || []; |
||||
|
return this.stadiumList = _ls; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '加载门店失败!' |
||||
|
}) |
||||
|
console.warn('verification record getStadiumLs err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
}) |
||||
|
}, |
||||
|
// 商家助手-核销查询列表 |
||||
|
getRecordLs({ brand_id, stadium_id = '', start_time = '', end_time = '', page = 1, page_size = 20 }){ |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: this.getRecordLsAPI(), |
||||
|
data: this.formatQuery({ brand_id, stadium_id, start_time, end_time, page, page_size }), |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
let _ls = this.formatRecordLs(_data?.data?.list || []); |
||||
|
if(page === 1)return this.recordLs = _ls; |
||||
|
if(!_ls.length)return showNone('没有更多!'); |
||||
|
this.page = page; |
||||
|
this.recordLs = [ ...this.recordLs, ..._ls ]; |
||||
|
return _ls; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '加载数据失败!' |
||||
|
}) |
||||
|
console.warn('verification record getRecordLs err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
}) |
||||
|
}, |
||||
|
// 获取记录列表API |
||||
|
getRecordLsAPI(){ |
||||
|
let { curTab } = this; |
||||
|
if(curTab === 0)return API.listVerifyRecord |
||||
|
if(curTab === 1)return API.dyPoiOrderList |
||||
|
if(curTab === 2)return API.shop2WriteoffList |
||||
|
}, |
||||
|
// 格式化查询参数 |
||||
|
formatQuery(query){ |
||||
|
let { curTab } = this; |
||||
|
if(curTab === 1)query['order_status'] = 'used'; |
||||
|
if(curTab === 2){ |
||||
|
query['stime'] = query?.start_time ?? ''; |
||||
|
query['etime'] = query?.end_time ?? ''; |
||||
|
delete query.start_time |
||||
|
delete query.end_time |
||||
|
} |
||||
|
return query; |
||||
|
}, |
||||
|
// 格式化数据 |
||||
|
formatRecordLs(ls){ |
||||
|
let { curTab } = this; |
||||
|
// 抖音 |
||||
|
if(curTab === 1){ |
||||
|
return ls.map(item=>{ |
||||
|
let _code = item?.order_codes?.find(e=>e?.code_status == 'used'); |
||||
|
console.log('_code',item); |
||||
|
return { |
||||
|
order_no: item?.order_no ?? '', |
||||
|
user_phone: item?.mobile ?? '', |
||||
|
verify_code: _code?.code ?? '', |
||||
|
verify_method: _code?.verification_method ?? '', |
||||
|
verify_time: _code?.verification_time ?? '', |
||||
|
}; |
||||
|
}) |
||||
|
} |
||||
|
return ls; |
||||
|
}, |
||||
|
// 核销记录列表 - 手动离场 |
||||
|
leaveVerifyOrder({ brand_id, id }){ |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: API.leaveVerifyOrder, |
||||
|
data: { brand_id, id }, |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
showNone(_data?.message || '操作成功!') |
||||
|
return true; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '操作失败!' |
||||
|
}) |
||||
|
console.warn('verification record leaveVerifyOrder err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
return false; |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.verification-record{ |
||||
|
@include isPd(20upx); |
||||
|
} |
||||
|
.vr-header{ |
||||
|
background: #fff; |
||||
|
.vh-tabs{ |
||||
|
@include ctf(space-around); |
||||
|
.vt-item{ |
||||
|
position: relative; |
||||
|
@include flcw(28upx, 88upx, #2D2D2D); |
||||
|
&.active{ |
||||
|
color: $mColor; |
||||
|
&::after{ |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
width: 100%; |
||||
|
height: 4upx; |
||||
|
background: $mColor; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.vr-time-board{ |
||||
|
padding: 24upx; |
||||
|
@include ctf(space-between); |
||||
|
.vtb-time{ |
||||
|
flex-shrink: 0; |
||||
|
padding: 0 14upx; |
||||
|
height: 62upx; |
||||
|
background: #fff; |
||||
|
@include ctf; |
||||
|
.vt-txt{ |
||||
|
max-width: 400upx; |
||||
|
@include flcw(24upx, 34upx, #1A1A1A, 500); |
||||
|
@include tHide; |
||||
|
} |
||||
|
.vt-icon{ |
||||
|
flex-shrink: 0; |
||||
|
margin-left: 30upx; |
||||
|
width: 32upx; |
||||
|
height: 32upx; |
||||
|
} |
||||
|
} |
||||
|
.vtb-num{ |
||||
|
margin-left: 20upx; |
||||
|
@include flcw(32upx, 44upx, #1A1A1A, 500); |
||||
|
@include tHide; |
||||
|
} |
||||
|
} |
||||
|
.vr-list{ |
||||
|
padding: 0 24upx; |
||||
|
|
||||
|
} |
||||
|
</style> |
@ -0,0 +1,244 @@ |
|||||
|
<template> |
||||
|
<view class="record-search"> |
||||
|
<view class="os-bar"> |
||||
|
<view> |
||||
|
<image mode="aspectFit" src="/subpackage/verification/static/images/search.png"></image> |
||||
|
<input placeholder="请输入手机号/核销码" v-model="searchTxt" confirm-type="search" @confirm="iptConfirm" /> |
||||
|
<image v-if="searchTxt!==''" mode="aspectFit" src="/subpackage/verification/static/images/round_close.png" @click="clearSearch"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="rs-ls"> |
||||
|
<block v-for="(e, i) in searchLs" :key="i"> |
||||
|
<site-item |
||||
|
v-if="orderType === 0" |
||||
|
:stadium-name="e.extension&&e.extension.stadium_name" |
||||
|
:order-num="e.order_no" |
||||
|
:order-type="e.type" |
||||
|
:user-phone="e.extension&&e.extension.user_phone" |
||||
|
:user-nickname="e.extension&&e.extension.nickname" |
||||
|
:verify-code="e.verify_code" |
||||
|
:verify-method="e.desc" |
||||
|
:verify-time="e.verify_time" |
||||
|
:verify-leave-time="e.verify_leave_time" |
||||
|
@click:leave="siteLeaveBtn(e, i)" |
||||
|
></site-item> |
||||
|
<dy-item |
||||
|
v-if="orderType === 1" |
||||
|
:order-num="e.order_no" |
||||
|
:user-phone="e.user_phone" |
||||
|
:verify-code="e.verify_code" |
||||
|
:verify-method="e.verify_method" |
||||
|
:verify-time="e.verify_time" |
||||
|
></dy-item> |
||||
|
<mall-item |
||||
|
v-if="orderType === 2" |
||||
|
:order-num="e.product_order_no" |
||||
|
:order-code="e.product_order_self_pickup_info.gcode" |
||||
|
:user-phone="e.product_order_self_pickup_info.phone" |
||||
|
:user-name="e.product_order_self_pickup_info.name" |
||||
|
:goods-str="e.product_order_goods.join(';')" |
||||
|
:opt-user="e.optuname" |
||||
|
:created-at="e.created_at" |
||||
|
></mall-item> |
||||
|
<view class="vl-space" style="height: 24rpx;"></view> |
||||
|
</block> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { formatDate, showLoad, hideLoad, showModal, showNone, debounce, formatTime, routeTo } from "@/utils/util"; |
||||
|
import API from "../js/api.js"; |
||||
|
import server from "../js/server.js"; |
||||
|
import siteItem from "../components/record/site_item.vue"; |
||||
|
import dyItem from "../components/record/dy_item.vue"; |
||||
|
import mallItem from "../components/record/mall_item.vue"; |
||||
|
export default { |
||||
|
components: { siteItem, dyItem, mallItem }, |
||||
|
data(){ |
||||
|
return { |
||||
|
brand_id: '', |
||||
|
orderType: '', |
||||
|
searchTxt: '', |
||||
|
page: 1, |
||||
|
searchLs: [], |
||||
|
} |
||||
|
}, |
||||
|
onLoad(options){ |
||||
|
this.brand_id = options?.brand_id ?? ''; |
||||
|
this.orderType = +(options?.type ?? ''); |
||||
|
}, |
||||
|
onReachBottom(){ |
||||
|
let { searchTxt, page } = this; |
||||
|
this.getRecordLs({ |
||||
|
keyword: searchTxt, |
||||
|
page: ++page |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
clearSearch(){ |
||||
|
this.searchTxt = ''; |
||||
|
}, |
||||
|
iptConfirm(e){ |
||||
|
let { brand_id } = this; |
||||
|
console.log(e); |
||||
|
this.page = 1; |
||||
|
this.searchLs = []; |
||||
|
this.getRecordLs({ |
||||
|
brand_id, |
||||
|
keyword: e?.detail?.value || '' |
||||
|
}) |
||||
|
}, |
||||
|
// 手动离场 |
||||
|
siteLeaveBtn: debounce(function(e, idx){ |
||||
|
showModal({ |
||||
|
content: '是否确认手动离场?', |
||||
|
showCancel: true, |
||||
|
success: async mRes=>{ |
||||
|
if(mRes.confirm){ |
||||
|
let _status = await this.leaveVerifyOrder({ brand_id: e?.brand_id ?? '', id: e?.id ?? '' }); |
||||
|
if(_status)this.searchLs[idx].verify_leave_time = formatTime(new Date()); |
||||
|
this.$forceUpdate(); |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
}, 300, true), |
||||
|
// 核销记录列表 - 手动离场 |
||||
|
leaveVerifyOrder({ brand_id, id }){ |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: API.leaveVerifyOrder, |
||||
|
data: { brand_id, id }, |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
showNone(_data?.message || '操作成功!') |
||||
|
return true; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '操作失败!' |
||||
|
}) |
||||
|
console.warn('verification record_search leaveVerifyOrder err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
return false; |
||||
|
}) |
||||
|
}, |
||||
|
// 商家助手-核销查询列表 |
||||
|
getRecordLs({ brand_id, stadium_id = '', start_time = '', end_time = '', page = 1, page_size = 20, keyword = '' }){ |
||||
|
showLoad(); |
||||
|
return server.post({ |
||||
|
url: this.getRecordLsAPI(), |
||||
|
data: this.formatQuery({ brand_id, stadium_id, start_time, end_time, page, page_size, keyword }), |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
let _ls = this.formatRecordLs(_data?.data?.list || []); |
||||
|
if(page === 1)return this.searchLs = _ls; |
||||
|
if(!_ls.length)return showNone('没有更多!'); |
||||
|
this.page = page; |
||||
|
this.searchLs = [ ...this.searchLs, ..._ls ]; |
||||
|
return _ls; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '加载数据失败!' |
||||
|
}) |
||||
|
console.warn('verification record_search getRecordLs err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
}) |
||||
|
}, |
||||
|
getRecordLsAPI(){ |
||||
|
let { orderType } = this; |
||||
|
if(orderType === 0)return API.listVerifyRecord |
||||
|
if(orderType === 1)return API.dyPoiOrderList |
||||
|
if(orderType === 2)return API.shop2WriteoffList |
||||
|
}, |
||||
|
formatQuery(query){ |
||||
|
let { orderType } = this; |
||||
|
if(orderType === 1)query['order_status'] = 'used'; |
||||
|
if(orderType === 2){ |
||||
|
query['stime'] = query?.start_time ?? ''; |
||||
|
query['etime'] = query?.end_time ?? ''; |
||||
|
delete query.start_time |
||||
|
delete query.end_time |
||||
|
} |
||||
|
return query; |
||||
|
}, |
||||
|
formatRecordLs(ls){ |
||||
|
let { orderType } = this; |
||||
|
// 抖音 |
||||
|
if(orderType === 1){ |
||||
|
return ls.map(item=>{ |
||||
|
let _code = item?.order_codes?.find(e=>e?.code_status == 'used'); |
||||
|
return { |
||||
|
order_no: item?.order_no ?? '', |
||||
|
user_phone: item?.mobile ?? '', |
||||
|
verify_code: _code?.code ?? '', |
||||
|
verify_method: _code?.verification_method ?? '', |
||||
|
verify_time: _code?.verification_time ?? '', |
||||
|
}; |
||||
|
}) |
||||
|
} |
||||
|
return ls; |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.record-search{ |
||||
|
@include isPd(20upx); |
||||
|
} |
||||
|
.os-bar{ |
||||
|
margin-bottom: 24upx; |
||||
|
height: 144upx; |
||||
|
background-color: #fff; |
||||
|
@include ctf(center); |
||||
|
>view{ |
||||
|
padding: 0 20upx; |
||||
|
height: 92upx; |
||||
|
width: 702upx; |
||||
|
border-radius: 10upx; |
||||
|
background-color: #f2f2f7; |
||||
|
@include ctf(center); |
||||
|
>image{ |
||||
|
margin-right: 20upx; |
||||
|
flex-shrink: 0; |
||||
|
width: 40upx; |
||||
|
height: 40upx; |
||||
|
} |
||||
|
>input{ |
||||
|
height: 100%; |
||||
|
flex-grow: 1; |
||||
|
@include flcw(32upx, 44upx, #1a1a1a); |
||||
|
&+image{ |
||||
|
flex-shrink: 0; |
||||
|
margin-right: 0; |
||||
|
margin-left: 20upx; |
||||
|
width: 32upx; |
||||
|
height: 32upx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.rs-ls{ |
||||
|
padding: 0 24upx; |
||||
|
} |
||||
|
</style> |
After Width: 28 | Height: 28 | Size: 271 B |
After Width: 16 | Height: 16 | Size: 369 B |
After Width: 200 | Height: 148 | Size: 7.6 KiB |
After Width: 185 | Height: 185 | Size: 3.6 KiB |
After Width: 185 | Height: 185 | Size: 4.4 KiB |
After Width: 32 | Height: 32 | Size: 369 B |
After Width: 60 | Height: 60 | Size: 429 B |
After Width: 20 | Height: 20 | Size: 245 B |
After Width: 64 | Height: 64 | Size: 1001 B |
After Width: 64 | Height: 64 | Size: 940 B |
After Width: 64 | Height: 64 | Size: 519 B |
@ -0,0 +1,82 @@ |
|||||
|
<template> |
||||
|
<wallet-modal title="充值" :show="isShow" @click:close="hide"> |
||||
|
<view class="recharge-container"> |
||||
|
<view class="rc-balance"> |
||||
|
<text class="rb-txt">钱包余额:</text> |
||||
|
{{ balance || 0 }}元 |
||||
|
</view> |
||||
|
<input type="digit" class="rc-ipt" v-model="iptNum" placeholder="请输入金额"> |
||||
|
<view class="rc-btns"> |
||||
|
<wm-button @click="hide">取消</wm-button> |
||||
|
<wm-button green @click="confirmBtn">确认</wm-button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</wallet-modal> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import walletModal from '../../../components/wallet_modal.vue'; |
||||
|
import wmButton from '../../../components/wm_button.vue'; |
||||
|
import { showNone } from '@/utils/util'; |
||||
|
export default { |
||||
|
props: { |
||||
|
balance: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
} |
||||
|
}, |
||||
|
components: { |
||||
|
walletModal, |
||||
|
wmButton, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isShow: false, |
||||
|
iptNum: '', |
||||
|
initData: {}, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
show(data){ |
||||
|
this.isShow = true; |
||||
|
this.initData = data ?? {}; |
||||
|
}, |
||||
|
hide(){ |
||||
|
this.isShow = false; |
||||
|
}, |
||||
|
confirmBtn(){ |
||||
|
let { initData, iptNum, hide } = this; |
||||
|
if(!iptNum || isNaN(iptNum) || Number(iptNum) <= 0)return showNone('请输入正确金额!'); |
||||
|
initData?.success?.(iptNum); |
||||
|
hide(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.recharge-container{ |
||||
|
padding: 0 50upx; |
||||
|
.rc-balance{ |
||||
|
margin-top: 60upx; |
||||
|
@include flcw(28upx, 40upx, $mColor); |
||||
|
@include tHide; |
||||
|
.rb-txt{ |
||||
|
color: #1A1A1A; |
||||
|
} |
||||
|
} |
||||
|
.rc-ipt{ |
||||
|
margin-top: 20upx; |
||||
|
padding: 0 20upx; |
||||
|
display: block; |
||||
|
height: 108upx; |
||||
|
border-radius: 10upx; |
||||
|
background: #F2F2F7; |
||||
|
@include flcw(32upx, 44upx, #1A1A1A); |
||||
|
} |
||||
|
.rc-btns{ |
||||
|
margin-top: 80upx; |
||||
|
@include ctf(space-between); |
||||
|
} |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,137 @@ |
|||||
|
<template> |
||||
|
<view class="recharge-record"> |
||||
|
<filtrate-bar |
||||
|
:filter-list="['全部', '已完成', '已退款']" |
||||
|
ref="filtrateBar" |
||||
|
@change:times="timesChange" |
||||
|
@change:filter="filterBtn" |
||||
|
></filtrate-bar> |
||||
|
<view class="rr-ls"> |
||||
|
<view class="rl-item" v-for="(e, i) in rechargeList" :key="i"> |
||||
|
<record-line name="充值金额" :tag="getTagTxt(e.pay_status)" >{{ e.amount || 0 }}</record-line> |
||||
|
<record-line name="充值单号">{{ e.order_no || '-' }}</record-line> |
||||
|
<record-line name="充值时间">{{ e.pay_time || '-' }}</record-line> |
||||
|
<record-line name="支付方式">{{ e.pay_type || '-' }}</record-line> |
||||
|
<record-line name="交易流水号">{{ e.trans_no || '-' }}</record-line> |
||||
|
<record-line name="充值途径"> |
||||
|
{{ e.optsourse || '-' }} <block v-if="e.optname"> ({{ e.optname }}) </block> |
||||
|
</record-line> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import filtrateBar from '../../components/filtrate_bar.vue'; |
||||
|
import recordLine from '../../components/record_line.vue'; |
||||
|
import { WALLET_API } from '../../js/api'; |
||||
|
import servers from '../../js/server'; |
||||
|
import { routeTo, showLoad, hideLoad, debounce, showModal, showNone } from '@/utils/util'; |
||||
|
export default { |
||||
|
components: { |
||||
|
filtrateBar, |
||||
|
recordLine, |
||||
|
}, |
||||
|
data(){ |
||||
|
return { |
||||
|
rechargeList: [], |
||||
|
page: 1, |
||||
|
brand_id: '', |
||||
|
|
||||
|
stime: '', |
||||
|
etime: '', |
||||
|
status: '' // 0:未支付, 1:已支付, 2:已退款 |
||||
|
} |
||||
|
}, |
||||
|
onLoad(opts){ |
||||
|
let _bid = opts?.brand_id ?? ''; |
||||
|
this.brand_id = _bid; |
||||
|
let { startDate, endDate } = this.$refs.filtrateBar.getTimes(); |
||||
|
this.stime = startDate; |
||||
|
this.etime = endDate; |
||||
|
this.getRechargeList({ brand_id: _bid, stime: startDate, etime: endDate }); |
||||
|
}, |
||||
|
onReachBottom(){ |
||||
|
let { brand_id, page, stime, etime } = this; |
||||
|
this.getRechargeList({ brand_id, page: ++page, stime, etime }); |
||||
|
}, |
||||
|
methods: { |
||||
|
getTagTxt(status = ''){ |
||||
|
return status === 0 ? '未支付' : |
||||
|
status === 1 ? '已完成' : |
||||
|
status === 2 ? '已退款' : ''; |
||||
|
}, |
||||
|
timesChange(e){ |
||||
|
let { startDate, endDate } = e; |
||||
|
this.stime = startDate ?? ''; |
||||
|
this.etime = endDate ?? ''; |
||||
|
this.refreshLs(); |
||||
|
}, |
||||
|
filterBtn(idx) { |
||||
|
let _status = idx === 0 ? '' : idx; |
||||
|
this.status = _status; |
||||
|
this.refreshLs(); |
||||
|
}, |
||||
|
refreshLs(){ |
||||
|
let { brand_id, stime, etime, status } = this; |
||||
|
this.page = 1; |
||||
|
this.rechargeList = []; |
||||
|
this.getRechargeList({ |
||||
|
brand_id: brand_id, |
||||
|
pay_status: status, |
||||
|
stime, |
||||
|
etime, |
||||
|
}); |
||||
|
}, |
||||
|
// 获取充值记录 |
||||
|
getRechargeList({ brand_id, pay_status = '', stime = '', etime = '', page_size = 20, page = 1 }){ |
||||
|
showLoad(); |
||||
|
return servers.post({ |
||||
|
url: WALLET_API.rechargeList, |
||||
|
data: { brand_id, pay_status, stime, etime, page_size, page }, |
||||
|
isDefaultGet: false, |
||||
|
}) |
||||
|
.then(res => { |
||||
|
hideLoad(); |
||||
|
let _data = res?.data || {}; |
||||
|
if(_data.code === 0){ |
||||
|
let _ls = _data?.data?.list || []; |
||||
|
if(page === 1)return this.rechargeList = _ls; |
||||
|
if(_ls?.length <= 0)return showNone('没有更多!'); |
||||
|
this.rechargeList = [ ...this.rechargeList, ..._ls ]; |
||||
|
this.page = page; |
||||
|
}else{ |
||||
|
return Promise.reject(_data); |
||||
|
} |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
hideLoad(); |
||||
|
showModal({ |
||||
|
title: '提示', |
||||
|
content: err.message || '加载失败!' |
||||
|
}) |
||||
|
console.warn('wallet index getPayInfo err --->', err); |
||||
|
// return Promise.reject(err); |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.recharge-record{ |
||||
|
|
||||
|
} |
||||
|
.rr-ls{ |
||||
|
padding: 24upx; |
||||
|
.rl-item{ |
||||
|
padding: 26upx 20upx; |
||||
|
border-radius: 10upx; |
||||
|
background: #fff; |
||||
|
&+ .rl-item{ |
||||
|
margin-top: 24upx; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |