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> |