-
21914package-lock.json
-
3package.json
-
12121pnpm-lock.yaml
-
3src/App.vue
-
193src/components/end_billing_modal/end_billing_modal.vue
-
38src/components/fixed_bar/fixed_bar.vue
-
22src/components/order_refund/button.vue
-
57src/components/order_refund/fixed.vue
-
56src/components/order_refund/info.vue
-
234src/components/order_refund/modal.vue
-
49src/components/order_refund/permission_btn.vue
-
138src/components/period_select.vue
-
185src/components/timing_order/timing_order.vue
-
8src/js/api.js
-
12src/js/server.js
-
3src/main.js
-
4src/manifest.json
-
260src/pages.json
-
377src/pages/index/index.vue
-
6src/pages/login/login.vue
-
243src/pages/menu/forth.vue
-
32src/pages/menu/second.vue
-
117src/pages/menu/third.vue
-
4src/pages/merchant_login/merchant_login.vue
-
12src/pages/order_list/order_list.vue
-
6src/pages/order_search/order_search.vue
-
2src/pages/site/confirm/confirm.vue
-
3src/pages/web_view/web_view.vue
-
175src/pages/write_off/douyin/poi_list.vue
-
237src/pages/write_off/mall/list/list.vue
-
122src/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
-
8src/pages/write_off/ym_confirm/ym_confirm.vue
-
BINsrc/static/images/code_null.png
-
BINsrc/static/images/icon/arrow_b2.png
-
BINsrc/static/images/icon/index/green_bg_circle.png
-
BINsrc/static/images/icon/index/tab_12.png
-
BINsrc/static/images/icon/index/tab_13.png
-
BINsrc/static/images/icon/index/tab_8.png
-
BINsrc/static/images/icon/scan_code_btn.png
-
BINsrc/static/images/icon/selected_ring.png
-
BINsrc/static/images/icon/write_off_fail.png
-
BINsrc/static/images/order_null.png
-
BINsrc/static/images/scan_null.png
-
BINsrc/static/images/tab/ta_1.png
-
BINsrc/static/images/tab/ta_2.png
-
BINsrc/static/images/tab/ta_3.png
-
BINsrc/static/images/tab/ta_4.png
-
BINsrc/static/images/tab/tab_1.png
-
BINsrc/static/images/tab/tab_2.png
-
BINsrc/static/images/tab/tab_3.png
-
BINsrc/static/images/tab/tab_4.png
-
BINsrc/static/images/third_pages/banner.png
-
BINsrc/static/images/third_pages/bg.png
-
BINsrc/static/images/third_pages/tab_a.png
-
BINsrc/static/images/third_pages/tab_b.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
-
85src/store/actions.js
-
23src/store/index.js
-
13src/store/mutations.js
-
188src/subpackage/authorization/components/login.vue
-
25src/subpackage/authorization/components/user_info/iconfont.css
-
133src/subpackage/authorization/components/user_info/impower.vue
-
357src/subpackage/authorization/components/user_info/tuniaoui-wx-user-info.vue
-
9src/subpackage/authorization/js/api.js
-
10src/subpackage/authorization/js/server.js
-
16src/subpackage/authorization/pages/index.vue
-
0src/subpackage/authorization/static/images/author_modal.png
-
4src/subpackage/blacklist/pages/abnormal_list/abnormal_list.vue
-
173src/subpackage/device/components/brand_change_modal.vue
-
30src/subpackage/device/components/order/reservation_people_detail/reservation_people_detail.vue
-
42src/subpackage/device/components/order/reservation_site_detail/reservation_site_detail.vue
-
265src/subpackage/device/components/order/timing_detail/timing_detail.vue
-
6src/subpackage/device/js/device_api.js
-
90src/subpackage/device/pages/index/index.vue
-
180src/subpackage/device/pages/lighting_time/list.vue
-
271src/subpackage/device/pages/lighting_time/setting.vue
-
212src/subpackage/device/pages/order_details/order_details.vue
-
8src/subpackage/device/pages/switch_manage/switch_manage.vue
-
BINsrc/subpackage/device/static/images/delete.png
-
41src/subpackage/menu/components/bottom_logo.vue
-
87src/subpackage/menu/components/mine/header.vue
-
63src/subpackage/menu/components/mine/line_tab.vue
-
16src/subpackage/menu/pages/index.vue
-
BINsrc/subpackage/menu/static/images/arrow_b2.png
-
BINsrc/subpackage/menu/static/images/bot_logo.png
-
BINsrc/subpackage/menu/static/images/mine_tab/0.png
-
BINsrc/subpackage/menu/static/images/mine_tab/1.png
-
BINsrc/subpackage/menu/static/images/mine_tab/2.png
-
BINsrc/subpackage/menu/static/images/mine_tab/3.png
-
BINsrc/subpackage/menu/static/images/mine_tab/4.png
-
BINsrc/subpackage/menu/static/images/mine_tab/5.png
-
BINsrc/subpackage/menu/static/images/mine_tab/6.png
-
59src/subpackage/message/components/detail/answer_item.vue
21914
package-lock.json
File diff suppressed because it is too large
View File
12121
pnpm-lock.yaml
File diff suppressed because it is too large
View File
@ -1,193 +0,0 @@ |
|||
<template> |
|||
<!-- 弹框 结束计费 --> |
|||
<view class="ox-dark-mask" @touchmove.stop.prevent="moveHandle" @click.stop=""> |
|||
<view class="odm-end-modal" > |
|||
<view class="oem-close"> |
|||
<image src="/static/images/icon/x_close.png" @click="closeChange"></image> |
|||
</view> |
|||
<view class="oem-tit">结束计费</view> |
|||
<view class="oem-line">操作人:{{orderInfo.end_bill_operator_name || '-'}}</view> |
|||
<view class="oem-line">时长合计:<text class="ol-txt1">{{orderInfo.extension.duration || '-'}}</text></view> |
|||
<view class="oem-line">金额合计:<text class="ol-txt2">¥{{orderInfo.amount || 0}}</text></view> |
|||
<view class="oem-box"> |
|||
<view @click="selectBtn(1)"> |
|||
<image :class="[selectType==1?'ob-img':'']" :src="selectType==1?'/static/images/icon/selected_ring.png':''"></image> |
|||
<view :class="[selectType==1?'ov-active':'']">停止计时</view> |
|||
</view> |
|||
<view @click="selectBtn(2)"> |
|||
<image :class="[selectType==2?'ob-img':'']" :src="selectType==2?'/static/images/icon/selected_ring.png':''"></image> |
|||
<view :class="[selectType==2?'ov-active':'']">完结订单</view> |
|||
</view> |
|||
</view> |
|||
<view class="oem-tips">*<text>请输入金额</text></view> |
|||
<view class="oem-ipt"><input type="digit" v-model="input_amount"/></view> |
|||
<view class="oem-btn" hover-class="hover-active" @click="confirmChange" >确认</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/utils/util'; |
|||
import deviceApi from '../../subpackage/device/js/device_api.js'; |
|||
import deviceServer from '../../subpackage/device/js/device_server.js'; |
|||
import { mapState } from 'vuex'; |
|||
export default { |
|||
props: { |
|||
orderInfo: { |
|||
type: Object, |
|||
default: ()=>({}) |
|||
} |
|||
|
|||
}, |
|||
computed: { |
|||
...mapState(['brandInfo']), |
|||
}, |
|||
|
|||
data() { |
|||
return { |
|||
input_amount: "", |
|||
selectType: 1, //默认1(停止计时) 2(完结订单) |
|||
} |
|||
}, |
|||
methods: { |
|||
moveHandle(){}, |
|||
closeChange(){ |
|||
this.$emit('close'); |
|||
}, |
|||
|
|||
confirmChange(){ |
|||
let { brandInfo, orderInfo, input_amount, selectType } = this |
|||
if(input_amount == '')return util.showNone('请输入金额!'); |
|||
util.showLoad(); |
|||
deviceServer.get({ |
|||
url: deviceApi.timeOrderEnd, |
|||
data: { |
|||
brand_id: brandInfo.brand.id, |
|||
order_no: orderInfo.order_no, |
|||
pay_amount: parseFloat(input_amount), |
|||
end_type: selectType==1?'end_timing':selectType==2?'end_order':'', |
|||
}, |
|||
failMsg: '加载失败!' |
|||
}) |
|||
.then(res=>{ |
|||
util.hideLoad() |
|||
util.showNone('操作成功!'); |
|||
this.$emit('close'); |
|||
// setTimeout(()=>uni.navigateBack(),1200); |
|||
this.$emit('timeEndBtn'); |
|||
}) |
|||
}, |
|||
|
|||
selectBtn(type){ |
|||
this.selectType = type |
|||
}, |
|||
}, |
|||
} |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" > |
|||
@import '~style/public.scss'; |
|||
.odm-end-modal{ |
|||
position: absolute; |
|||
left: 65rpx; |
|||
top: 12%; |
|||
background-color: #fff; |
|||
width: 620rpx; |
|||
padding: 30rpx 0rpx 60rpx; |
|||
border-radius: 10rpx; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.oem-close{ |
|||
width: 100%; |
|||
@include centerFlex(flex-end); |
|||
>image{ |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
margin-right: 30rpx; |
|||
} |
|||
} |
|||
.oem-tit { |
|||
color: #1A1A1A; |
|||
font-size: 32rpx; |
|||
font-weight: 700; |
|||
margin: 16rpx 0rpx 34rpx; |
|||
} |
|||
.oem-line{ |
|||
width: 456rpx; |
|||
color: #1A1A1A; |
|||
font-size: 28rpx; |
|||
line-height: 48rpx; |
|||
.ol-txt1{ |
|||
color: #009874; |
|||
} |
|||
.ol-txt2{ |
|||
color: #FF873D; |
|||
} |
|||
} |
|||
.oem-box{ |
|||
margin: 58rpx 0 48rpx; |
|||
width: 456rpx; |
|||
@include centerFlex(space-between); |
|||
>view{ |
|||
@include centerFlex(flex-start); |
|||
>image{ |
|||
flex-shrink: 0; |
|||
width: 28rpx; |
|||
height: 28rpx; |
|||
border-radius: 50%; |
|||
border: 2rpx solid #D8D8D8; |
|||
&.ob-img{ |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
border: 0rpx solid #D8D8D8; |
|||
} |
|||
} |
|||
>view{ |
|||
margin-left: 12rpx; |
|||
font-size: 28rpx; |
|||
line-height: 48rpx; |
|||
color: #9C9C9F; |
|||
&.ov-active{ |
|||
color: #1A1A1A; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
.oem-tips{ |
|||
width: 456rpx; |
|||
margin: 0rpx 0rpx 8rpx; |
|||
color: #EA5061; |
|||
font-size: 28rpx; |
|||
>text{ |
|||
color: #333333; |
|||
} |
|||
} |
|||
.oem-ipt{ |
|||
width: 456rpx; |
|||
border: 2rpx solid #D8D8D8; |
|||
border-radius: 10rpx; |
|||
& input { |
|||
flex-grow: 1; |
|||
height: 88rpx; |
|||
color: #1A1A1A; |
|||
font-size: 28rpx; |
|||
padding: 0rpx 20rpx; |
|||
} |
|||
} |
|||
.oem-btn{ |
|||
width: 240rpx; |
|||
height: 88rpx; |
|||
margin-top: 60rpx; |
|||
border-radius: 10rpx; |
|||
background-color: #009874; |
|||
color: #FFF; |
|||
font-size: 32rpx; |
|||
line-height: 88rpx; |
|||
text-align: center; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,38 @@ |
|||
<template> |
|||
<view class="fixed-bar" :style="'padding-top:'+ fbHeight +'px;'"> |
|||
<view class="fb-fixed" id="fb"> |
|||
<slot></slot> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getNodeMes } from '@/utils/util' |
|||
export default { |
|||
data(){ |
|||
return { |
|||
fbHeight: 0, |
|||
} |
|||
}, |
|||
mounted() { |
|||
getNodeMes('#fb', this).then(res => { |
|||
this.fbHeight = res?.height || 0 |
|||
console.log(res) |
|||
}) |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.fixed-bar{ |
|||
|
|||
} |
|||
.fb-fixed{ |
|||
position: fixed; |
|||
padding-top: 20upx; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
z-index: 10; |
|||
} |
|||
</style> |
@ -0,0 +1,22 @@ |
|||
<template> |
|||
<view class="order-refund-button" @click="$emit('click')"> |
|||
<slot>退款</slot> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.order-refund-button{ |
|||
width: 192upx; |
|||
text-align: center; |
|||
border-radius: 10upx; |
|||
background-color: #fff; |
|||
border: 2upx solid $mColor; |
|||
@include flcw(32upx, 84upx, $mColor, 500); |
|||
} |
|||
</style> |
@ -0,0 +1,57 @@ |
|||
<template> |
|||
<fixed-bar v-if="isShow"> |
|||
<view class="order-refund-fixed"> |
|||
<or-button @click="$emit('click:button')"></or-button> |
|||
</view> |
|||
</fixed-bar> |
|||
</template> |
|||
|
|||
<script> |
|||
import fixedBar from "../fixed_bar/fixed_bar.vue"; |
|||
import orButton from "./button.vue"; |
|||
import { mapState } from 'vuex'; |
|||
/** |
|||
* 全部订单都能退两次, 所有订单最多只能退2次款 |
|||
* 只要订单金额是未全退的,都能退 |
|||
* 0元订单不能退 |
|||
* |
|||
*/ |
|||
export default { |
|||
components: { |
|||
fixedBar, |
|||
orButton |
|||
}, |
|||
props: [ 'pay_amount', 'refund_amount', 'refund_times' ], |
|||
computed: { |
|||
...mapState([ 'brandInfo' ]), |
|||
payAmount(){ |
|||
let { pay_amount } = this; |
|||
return +pay_amount || 0 |
|||
}, |
|||
refundAmount(){ |
|||
let { refund_amount } = this; |
|||
return +refund_amount || 0 |
|||
}, |
|||
isShow(){ |
|||
console.log('brandInfo', this.brandInfo) |
|||
let { payAmount, refundAmount, refund_times, brandInfo } = this; |
|||
if( |
|||
payAmount - refundAmount > 0 |
|||
&&[0, 1].includes(refund_times) |
|||
&&brandInfo?.permission?.['1018'] // 退款权限 |
|||
){ |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.order-refund-fixed{ |
|||
padding: 10upx 24upx; |
|||
background: #F2F2F7; |
|||
@include ctf(flex-end); |
|||
} |
|||
</style> |
@ -0,0 +1,56 @@ |
|||
<template> |
|||
<view class="refund-info"> |
|||
<view class="ri-name">退款信息{{ nameKey || '' }}</view> |
|||
<view class="ri-line"> |
|||
<view class="ri-name">退款金额:</view> |
|||
<view class="ri-value">{{ refund_price }}</view> |
|||
</view> |
|||
<view class="ri-line"> |
|||
<view class="ri-name">退款单号:</view> |
|||
<view class="ri-value">{{ refund_no }}</view> |
|||
</view> |
|||
<view class="ri-line"> |
|||
<view class="ri-name">退款时间:</view> |
|||
<view class="ri-value">{{ refund_time }}</view> |
|||
</view> |
|||
<view class="ri-line"> |
|||
<view class="ri-name">退款原因:</view> |
|||
<view class="ri-value">{{ refund_reason }}</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
nameKey: { default: '' }, |
|||
refund_price: { default: '-' }, |
|||
refund_no: { default: '-' }, |
|||
refund_time: { default: '-' }, |
|||
refund_reason: { default: '-' }, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.refund-info{ |
|||
padding: 30upx; |
|||
border-radius: 10upx; |
|||
background: #fff; |
|||
.ri-name{ |
|||
flex-shrink: 0; |
|||
@include flcw(28upx, 40upx, #9C9C9F); |
|||
&+.ri-line{ |
|||
margin-top: 16upx; |
|||
} |
|||
} |
|||
.ri-line{ |
|||
@include ctf(space-between); |
|||
.ri-value{ |
|||
flex-grow: 1; |
|||
@include flcw(28upx, 60upx, #1A1A1A); |
|||
@include tHide; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,234 @@ |
|||
<template> |
|||
<view class="order-refund-modal"> |
|||
<view class="orm-mask" v-show="isShow"> |
|||
<view class="om-content"> |
|||
<image class="oc-close" mode="aspectFit" src="../../static/images/icon/x_close.png" @click="hide"></image> |
|||
<view class="oc-title">退款</view> |
|||
<view class="oc-section"> |
|||
<view class="os-info"> |
|||
<view class="oi-name">{{ refundInfo.stadium_name || '' }}</view> |
|||
<view class="oi-line">订单编号:{{ refundInfo.order_no || '' }}</view> |
|||
<view class="oi-line">手机号码:{{ refundInfo.mobile || '' }}</view> |
|||
|
|||
<view class="os-ipts"> |
|||
<view class="oi-item"> |
|||
<view class="oi-name"> |
|||
<text class="on-txt">*</text> |
|||
退款金额 |
|||
</view> |
|||
<view class="oi-right"> |
|||
<input |
|||
class="or-ipt" |
|||
type="digit" |
|||
v-model="iptInfo.refund_amount" |
|||
:disabled="refundInfo.refund_times > 0" |
|||
:class="{ 'or-disabled': refundInfo.refund_times > 0 }" |
|||
/> |
|||
<view class="or-tip">可退{{ refundInfo.refundable_amount || 0 }}元</view> |
|||
</view> |
|||
</view> |
|||
<view class="oi-item"> |
|||
<view class="oi-name"> |
|||
<text class="on-txt">*</text> |
|||
退款积分 |
|||
</view> |
|||
<view class="oi-right"> |
|||
<input |
|||
class="or-ipt" type="digit" |
|||
v-model="iptInfo.refund_integral" |
|||
:disabled="refundInfo.refund_times > 0" |
|||
:class="{ 'or-disabled': refundInfo.refund_times > 0 }" |
|||
/> |
|||
<view class="or-tip">可退{{ refundInfo.refundable_integral || 0 }}积分</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="oc-btns"> |
|||
<view class="ob-item" @click="cancelBtn">取消</view> |
|||
<view class="ob-item" @click="confirmBtn">确认</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* PM: |
|||
* 什么状态下都能退 |
|||
* 全部订单都能退两次, 所有订单最多只能退2次款 |
|||
* 只要订单金额是未全退的,都能退 |
|||
* 0元订单不能退 |
|||
* |
|||
*/ |
|||
import { mapState } from 'vuex'; |
|||
import { showModal } from '@/utils/util'; |
|||
export default { |
|||
computed: { |
|||
...mapState([ 'brandInfo' ]) |
|||
}, |
|||
data() { |
|||
return { |
|||
isShow: false, |
|||
refundInfo: { |
|||
/** |
|||
* @param {String} stadium_name 店铺名称 |
|||
* @param {String} order_no 订单编号 |
|||
* @param {String} mobile 手机号码 |
|||
* @param {String} refundable_amount 退款金额 |
|||
* @param {String} refundable_integral 退款积分 |
|||
* @param {Number} refund_times 退款次数 |
|||
* @param {Function} cancel 取消回调 |
|||
* @param {Function} confirm 确认回调 |
|||
*/ |
|||
}, |
|||
iptInfo: { |
|||
refund_amount: '', |
|||
refund_integral: '' |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
show(initData){ |
|||
let { brandInfo } = this; |
|||
if(brandInfo?.permission?.['1018']){ |
|||
this.isShow = true; |
|||
this.init(initData); |
|||
}else{ |
|||
showModal({ |
|||
content: '您没有退款权限', |
|||
}) |
|||
} |
|||
|
|||
}, |
|||
init(data){ |
|||
this.iptInfo.refund_amount = data?.refundable_amount || '0'; |
|||
this.iptInfo.refund_integral = data?.refundable_integral || '0'; |
|||
this.refundInfo = data; |
|||
}, |
|||
hide(){ |
|||
this.isShow = false; |
|||
}, |
|||
cancelBtn() { |
|||
this.hide(); |
|||
this.$emit('click:cancel'); |
|||
this.refundInfo?.cancel?.(0); |
|||
}, |
|||
confirmBtn() { |
|||
let { iptInfo, refundInfo } = this; |
|||
|
|||
this.$emit('click:confirm'); |
|||
this.refundInfo?.confirm?.({ |
|||
refund_amount: +iptInfo?.refund_amount || 0, |
|||
refund_integral: +iptInfo?.refund_integral || 0 |
|||
}); |
|||
this.hide(); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.order-refund-modal{} |
|||
|
|||
.orm-mask{ |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background: rgba(0,0,0,.5); |
|||
z-index: 10; |
|||
} |
|||
.om-content{ |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
padding-bottom: 80upx; |
|||
width: 620upx; |
|||
border-radius: 10px; |
|||
background: #fff; |
|||
.oc-close{ |
|||
position: absolute; |
|||
top: 30upx; |
|||
right: 30upx; |
|||
width: 34upx; |
|||
height: 34upx; |
|||
} |
|||
.oc-title{ |
|||
padding-top: 78upx; |
|||
text-align: center; |
|||
@include flcw(32upx, 44upx, #333, 500); |
|||
} |
|||
.oc-section{ |
|||
padding: 30upx 30upx 0; |
|||
@include ctf(center); |
|||
.os-info{ |
|||
.oi-name{ |
|||
@include flcw(28upx, 48upx, #333); |
|||
} |
|||
.oi-line{ |
|||
@include flcw(28upx, 48upx, #9C9C9F); |
|||
} |
|||
.os-ipts{ |
|||
padding-top: 34upx; |
|||
.oi-item{ |
|||
display: flex; |
|||
align-items: flex-start; |
|||
.oi-name{ |
|||
@include flcw(28upx, 56upx, #333333); |
|||
.on-txt{ |
|||
color: #EA5061; |
|||
} |
|||
} |
|||
.oi-right{ |
|||
margin-left: 16upx; |
|||
flex-shrink: 0; |
|||
width: 312upx; |
|||
.or-ipt{ |
|||
display: block; |
|||
box-sizing: border-box; |
|||
padding: 0 20upx; |
|||
width: 100%; |
|||
height: 56upx; |
|||
border-radius: 10upx; |
|||
border: 2upx solid #D8D8D8; |
|||
@include flcw(28upx, 48upx, #9C9C9F); |
|||
&.or-disabled{ |
|||
background: #cecece; |
|||
color: #9C9C9F; |
|||
} |
|||
} |
|||
.or-tip{ |
|||
padding-left: 8upx; |
|||
@include flcw(24upx, 48upx, #EA5061); |
|||
@include tHide; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.oc-btns{ |
|||
margin-top: 32upx; |
|||
padding: 0 54upx; |
|||
@include ctf(space-between); |
|||
.ob-item{ |
|||
width: 240upx; |
|||
height: 88upx; |
|||
text-align: center; |
|||
border: 2upx solid $mColor; |
|||
border-radius: 10upx; |
|||
@include flcw(32upx, 84upx, $mColor, 500); |
|||
&+.ob-item{ |
|||
background: $mColor; |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,49 @@ |
|||
<template> |
|||
<view class="permissinon-btn"> |
|||
<or-button v-if="isShow" @click="$emit('click:button')"><slot>退款</slot></or-button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import orButton from "./button.vue"; |
|||
import { mapState } from 'vuex'; |
|||
/** |
|||
* 全部订单都能退两次, 所有订单最多只能退2次款 |
|||
* 只要订单金额是未全退的,都能退 |
|||
* 0元订单不能退 |
|||
* |
|||
*/ |
|||
export default { |
|||
components: { |
|||
orButton |
|||
}, |
|||
props: [ 'pay_amount', 'refund_amount', 'refund_times' ], |
|||
computed: { |
|||
...mapState([ 'brandInfo' ]), |
|||
payAmount(){ |
|||
let { pay_amount } = this; |
|||
return +pay_amount || 0 |
|||
}, |
|||
refundAmount(){ |
|||
let { refund_amount } = this; |
|||
return +refund_amount || 0 |
|||
}, |
|||
isShow(){ |
|||
let { payAmount, refundAmount, refund_times, brandInfo } = this; |
|||
console.log('brandInfo', payAmount, refundAmount, refund_times, brandInfo) |
|||
if( |
|||
payAmount - refundAmount > 0 |
|||
&&[0, 1].includes(refund_times) |
|||
&&brandInfo?.permission?.['1018'] // 退款权限 |
|||
){ |
|||
return true |
|||
} |
|||
return false |
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
|
|||
</style> |
@ -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,185 +0,0 @@ |
|||
<template> |
|||
<view class="timing-order" @click="toOrderDetails"> |
|||
<view class="ro-header"> |
|||
<view class="rh-view">{{orderInfo.stadium_name || '-'}}</view> |
|||
<text :class="[ 'rh-text', orderInfo.pay_status == 0?'rh-active':'' ]">{{zh_order_status(orderInfo.pay_status)}}</text> |
|||
</view> |
|||
<view class="ro-section"> |
|||
<view class="rs-line"> |
|||
<view class="rl-view">订单编号:</view> |
|||
<view class="rl-view"> |
|||
<view class="rv-view">{{orderInfo.order_no || '-'}}</view> |
|||
</view> |
|||
<image class="rl-image" src="/static/images/icon/arrow_b2.png"></image> |
|||
</view> |
|||
<!-- 场时有 人时没有 order_type: 1场时 2人时 --> |
|||
<view class="rs-line" v-if="orderInfo.order_type == 1"> |
|||
<view class="rl-view">项目:</view> |
|||
<view class="rl-view"> |
|||
<view class="rv-view">{{orderInfo.project_name || '-'}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="rs-line"> |
|||
<view class="rl-view">时长:</view> |
|||
<view class="rl-view"> |
|||
<view :class="[ 'rv-view', orderInfo.pay_status == 0?'rv-active':'' ]">{{ orderInfo.extension.duration || '-'}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="rs-btn" v-if="orderInfo.pay_status == 0&&orderInfo.early_end_timing==false"><view @click.stop="isEndBill=true">结束计费</view></view> |
|||
</view> |
|||
<view class="ro-bot" v-if="orderInfo.pay_status != 0"> |
|||
<view class="rb-total">实付款 <text class="rt-txt"> ¥{{orderInfo.pay_amount || 0}}</text></view> |
|||
</view> |
|||
|
|||
<!-- 结束计费弹框 --> |
|||
<end-billing-modal |
|||
v-if="isEndBill==true" |
|||
@close="isEndBill=false" |
|||
@timeEndBtn="timeEndBtn" |
|||
:orderInfo="orderInfo" |
|||
></end-billing-modal> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/utils/util'; |
|||
import end_billing_modal from '../end_billing_modal/end_billing_modal.vue'; |
|||
export default { |
|||
components: { |
|||
'end-billing-modal': end_billing_modal, |
|||
}, |
|||
props: { |
|||
orderInfo: { |
|||
type: Object, |
|||
default: ()=>({}) |
|||
} |
|||
}, |
|||
computed: { |
|||
zh_order_status(){ |
|||
// 订单状态 0计费中1已完成 |
|||
let { orderInfo } = this |
|||
return status =>{ |
|||
const _obj = { |
|||
'0': orderInfo.early_end_timing==true?'待支付':'计费中', |
|||
'1': '已完成', |
|||
'4': '已退款', |
|||
} |
|||
return _obj[`${status}`] || '-' |
|||
} |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
isEndBill: false, |
|||
} |
|||
}, |
|||
methods:{ |
|||
toOrderDetails(){ |
|||
let { orderInfo } = this |
|||
// let _query = {} |
|||
// _query["stadium_id"] = orderInfo.stadium_id |
|||
// _query["order_no"] = orderInfo.order_no |
|||
// _query["order_type"] = 1 |
|||
let _str = `stadium_id=${orderInfo.stadium_id || ''}&order_no=${orderInfo.order_no || ''}&order_type=1` |
|||
util.routeTo(`/subpackage/device/pages/order_details/order_details?${_str}`,'nT'); |
|||
// this.$emit('orderDetailChange'); |
|||
}, |
|||
timeEndBtn(){ |
|||
this.$emit('refreshList'); |
|||
}, |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" > |
|||
@import '~style/public.scss'; |
|||
.timing-order{ |
|||
padding: 0 24upx; |
|||
border-radius: 10upx; |
|||
background-color: #fff; |
|||
.ro-header{ |
|||
margin-bottom: 18upx; |
|||
height: 98upx; |
|||
line-height: 96upx; |
|||
border-bottom: 2upx solid #D8D8D8; |
|||
@include centerFlex(space-between); |
|||
.rh-view{ |
|||
flex-grow: 1; |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
@include textHide(1); |
|||
} |
|||
.rh-text{ |
|||
margin-left: 20upx; |
|||
flex-shrink: 0; |
|||
font-size: 28upx; |
|||
color: #9C9C9F; |
|||
} |
|||
.rh-active{ |
|||
color: $themeColor; |
|||
} |
|||
} |
|||
.ro-section{ |
|||
padding-bottom: 30upx; |
|||
.rs-line{ |
|||
display: flex; |
|||
.rl-view,.rv-view{ |
|||
line-height: 40upx; |
|||
font-size: 24upx; |
|||
color: #9c9c9f; |
|||
} |
|||
.rl-view{ |
|||
&:first-child{ |
|||
flex-shrink: 0; |
|||
} |
|||
&+.rl-view{ |
|||
flex-grow: 1; |
|||
.rv-view{ |
|||
@include textHide(1); |
|||
} |
|||
} |
|||
} |
|||
.rv-active{ |
|||
color: $themeColor; |
|||
} |
|||
>.rl-image{ |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
} |
|||
|
|||
.rs-btn{ |
|||
margin-top: 8rpx; |
|||
@include centerFlex(flex-end); |
|||
>view{ |
|||
width: 192rpx; |
|||
height: 80rpx; |
|||
border: 2rpx solid #009874; |
|||
border-radius: 10rpx; |
|||
color: #009874; |
|||
font-size: 32rpx; |
|||
font-weight: 500; |
|||
text-align: center; |
|||
line-height: 80rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.ro-bot{ |
|||
padding-top: 20upx; |
|||
padding-bottom: 30upx; |
|||
border-top: 2upx solid #D8D8D8; |
|||
.rb-total{ |
|||
line-height: 40upx; |
|||
text-align: right; |
|||
font-size: 24upx; |
|||
color: #9c9c9f; |
|||
.rt-txt{ |
|||
color: #1A1A1A; |
|||
margin-left: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,243 @@ |
|||
<template> |
|||
<view class="forth-menu"> |
|||
<!-- 后端: account-> 如果有手机号就显示手机号 没有的话显示username, 都没有的话就空好了 --> |
|||
<mine-header |
|||
:is-login="loginState" |
|||
:nickname="userInfo.nickname" |
|||
:name="userInfo.actual_name" |
|||
:account="userInfo.mobile || userInfo.username || ''" |
|||
:photo="userInfo.avatar_url" |
|||
@on:munted="menuPackageLoaded = true" |
|||
@click:login="loginBtn" |
|||
@click:update="updateUser" |
|||
></mine-header> |
|||
<block v-if="menuPackageLoaded"> |
|||
<line-tab :icon-num='0'> |
|||
<template slot="default">账号管理</template> |
|||
<template slot="right"> |
|||
<view class="ft-account"> |
|||
<view class="fc-name" v-if="loginState">{{ accountName || '-' }}</view> |
|||
<image class="fc-icon" mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image> |
|||
</view> |
|||
</template> |
|||
</line-tab> |
|||
<line-tab :icon-num='1' @click="toWebView(deadData.helpCenterLink)">帮助中心</line-tab> |
|||
<block v-if="loginState"> |
|||
<line-tab :icon-num='2' @click="toMiniProgram(deadData.assistantCoachAppid)">教练助手</line-tab> |
|||
<line-tab :icon-num='3'> |
|||
<template slot="default">收银系统</template> |
|||
<template slot="right"> |
|||
<view class="fm-copy" @click="copyLink(deadData.cashierSystemLink)">(复制网址)</view> |
|||
</template> |
|||
</line-tab> |
|||
<line-tab :icon-num='4' @click="toWebView(deadData.backstageLink)"> |
|||
<view class="fm-admin"> |
|||
<view class="fa-txt">总后台<text class="ft-txt">({{ deadData.backstageLink }})</text></view><view class="fa-copy" @click.stop="copyLink(deadData.backstageLink)">复制</view> |
|||
</view> |
|||
</line-tab> |
|||
</block> |
|||
<line-tab :icon-num='5' @click="toComplaint">投诉建议</line-tab> |
|||
<line-tab :icon-num='6' v-if="loginState" @click="unBindBtn">解绑退出</line-tab> |
|||
</block> |
|||
<bottom-logo></bottom-logo> |
|||
|
|||
<authorization-login ref="authorizationLogin"></authorization-login> |
|||
<authorization-user ref="authorizationUser"></authorization-user> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import mineHeader from "@/subpackage/menu/components/mine/header.vue"; |
|||
import lineTab from "@/subpackage/menu/components/mine/line_tab.vue"; |
|||
import bottomLogo from "@/subpackage/menu/components/bottom_logo.vue"; |
|||
import authorizationLogin from "@/subpackage/authorization/components/login.vue"; |
|||
import authorizationUser from "@/subpackage/authorization/components/user_info/impower.vue"; |
|||
import { routeTo, debounce, showLoad, hideLoad, showModal, showNone, jsonStr } from "@/utils/util.js"; |
|||
import { mapGetters, mapState } from 'vuex'; |
|||
import { servers } from '../../js/server'; |
|||
import { API } from '../../js/api'; |
|||
export default { |
|||
components:{ |
|||
mineHeader, |
|||
lineTab, |
|||
bottomLogo, |
|||
authorizationLogin, |
|||
authorizationUser, |
|||
}, |
|||
data(){ |
|||
return { |
|||
// 异步组件加载完成状态 |
|||
menuPackageLoaded: false, |
|||
userInfo: {}, |
|||
deadData: { |
|||
helpCenterLink: 'https://help.ouxuanzhineng.cn/', // 帮助中心 |
|||
cashierSystemLink: 'https://kb.ouxuanzhineng.cn/', // 收银系统 |
|||
backstageLink: 'https://admin.ouxuanzhineng.cn/', // 总后台 |
|||
assistantCoachAppid: 'wxd71043ec955dfecf', // 教练助手:AppID |
|||
}, |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapGetters([ 'loginState' ]), |
|||
...mapState([ 'brandInfo' ]), |
|||
extension(){ |
|||
return this.userInfo?.extension || {} |
|||
}, |
|||
/** |
|||
* @param {string} permission_type 1:ADMIN-STADIUM 2:ADMIN-BRAND |
|||
* */ |
|||
permissionType(){ |
|||
return this.userInfo?.extension?.permission_type || ''; |
|||
}, |
|||
accountName(){ |
|||
let { permissionType, extension } = this; |
|||
if(permissionType === 'ADMIN-STADIUM')return extension?.stadium_name ?? ''; |
|||
if(permissionType === 'ADMIN-BRAND')return extension?.brand_name ?? ''; |
|||
return ''; |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
if(this.loginState)this.getUserInfo(); |
|||
}, |
|||
methods: { |
|||
// 解绑 |
|||
unBindBtn: debounce(function(){ |
|||
let { userInfo } = this; |
|||
if(!userInfo?.id)return showModal({ content: '用户信息有误' }) |
|||
showModal({ |
|||
content: '您确定要解绑退出吗?', |
|||
showCancel: true, |
|||
success: mRes=>{ |
|||
if(mRes.confirm)this.unBindReq(userInfo.id); |
|||
} |
|||
}) |
|||
|
|||
}, 300, true), |
|||
// 解绑请求 |
|||
unBindReq(user_id){ |
|||
showLoad(); |
|||
return servers.post({ |
|||
url: API.mine.unbindAssistant, |
|||
data: { user_id }, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
hideLoad(); |
|||
let _data = res?.data || {}; |
|||
if(_data.code === 0){ |
|||
showNone('操作成功!'); |
|||
setTimeout(() => { |
|||
this.$store.commit('setLoginState', { loginState: false }); |
|||
routeTo(`/pages/login/login`,'rL'); |
|||
}, 1000); |
|||
console.log('pages menu unBindReq res --->', _data); |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
hideLoad(); |
|||
showModal({ content: err?.message || '操作失败!' }); |
|||
console.warn('pages menu unBindReq err --->', err); |
|||
// return Promise.reject(err); |
|||
}) |
|||
}, |
|||
// 更新用户信息 |
|||
updateUser(){ |
|||
this.$refs?.authorizationUser?.show?.({ success: this.getUserInfo }); |
|||
}, |
|||
// 跳转小程序 |
|||
toMiniProgram(appid){ |
|||
uni.navigateToMiniProgram({ appId: appid }); |
|||
}, |
|||
// 跳转网页 |
|||
toWebView(url){ |
|||
routeTo(`/pages/web_view/web_view?src=${jsonStr(url)}`, 'nT'); |
|||
}, |
|||
// 复制链接 |
|||
copyLink(url){ |
|||
uni.setClipboardData({ data: url }); |
|||
}, |
|||
// 投诉建议 |
|||
toComplaint(){ |
|||
let { loginState, showAuthor, brandInfo } = this; |
|||
if(!loginState)return showAuthor(); |
|||
routeTo(`/subpackage/message/pages/complaint/list?brand_id=${brandInfo?.brand?.id}`, 'nT'); |
|||
}, |
|||
// 登录 |
|||
loginBtn(){ |
|||
this.showAuthor(); |
|||
}, |
|||
showAuthor(){ |
|||
this.$refs?.authorizationLogin?.alert?.({ success: this.getUserInfo }); |
|||
}, |
|||
getUserInfo(){ |
|||
showLoad(); |
|||
return servers.post({ |
|||
url: API.mine.userCurrent, |
|||
data: {}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
hideLoad(); |
|||
let _data = res?.data || {}; |
|||
if(_data.code === 0){ |
|||
this.userInfo = _data?.data || {}; |
|||
console.log('pages menu getUserInfo res --->', _data); |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
hideLoad(); |
|||
showModal({ content: err?.message || '加载用户失败!' }); |
|||
console.warn('pages menu getUserInfo err --->', err); |
|||
// return Promise.reject(err); |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.forth-menu{ |
|||
|
|||
} |
|||
.fm-txt{ |
|||
font-size: 28upx; |
|||
.ft-copy{ |
|||
color: $mColor; |
|||
} |
|||
} |
|||
.ft-account{ |
|||
@include ctf(flex-end); |
|||
.fc-name{ |
|||
@include flcw(32upx, 48upx, #9A9A9D); |
|||
@include tHide; |
|||
} |
|||
.fc-icon{ |
|||
flex-shrink: 0; |
|||
margin-left: 22upx; |
|||
width: 30upx; |
|||
height: 30upx; |
|||
} |
|||
} |
|||
.fm-copy{ |
|||
@include flcw(32upx, 44upx, $mColor); |
|||
} |
|||
.fm-admin{ |
|||
@include ctf; |
|||
.fa-txt{ |
|||
@include flcw(32upx, 44upx, #9A9A9D); |
|||
@include tHide; |
|||
.ft-txt{ |
|||
font-size: 28upx; |
|||
} |
|||
} |
|||
.fa-copy{ |
|||
padding: 0upx 10upx; |
|||
flex-shrink: 0; |
|||
@include flcw(28upx, 44upx, $mColor); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,32 @@ |
|||
<template> |
|||
<view class="second-pages"> |
|||
<view class="sp-post"> |
|||
<view class="sp-box"> |
|||
<view class="tl-tit">板块更新中</view> |
|||
</view> |
|||
</view> |
|||
<bottom-logo is-fixed></bottom-logo> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import bottomLogo from "@/subpackage/menu/components/bottom_logo.vue"; |
|||
export default { |
|||
components:{ bottomLogo }, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.sp-post{ |
|||
padding: 24upx; |
|||
.sp-box{ |
|||
padding: 22upx 28upx; |
|||
height: 400upx; |
|||
background-image: linear-gradient(270deg, #d7d7da 0%, $mColor 100%); |
|||
.tl-tit{ |
|||
@include flcw(43upx, 60upx, #fff, 500); |
|||
@include tHide; |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,117 @@ |
|||
<template> |
|||
<view class="third-page"> |
|||
<view class="tp-container"> |
|||
<image class="tc-post" mode="aspectFit" src="/static/images/third_pages/banner.png"></image> |
|||
<view class="tc-bot"> |
|||
<view class="tb-left" @click="clickTap"> |
|||
<image class="tl-bg" mode="aspectFill" src="/static/images/third_pages/bg.png"></image> |
|||
<view class="tl-tit">采购商城</view> |
|||
<view class="tl-txt">采购专业装备</view> |
|||
</view> |
|||
<view class="tb-right"> |
|||
<view class="tr-item active" @click="clickTap"> |
|||
<view class="ti-title">客服外包</view> |
|||
<view class="ti-text">客服外包</view> |
|||
<image class="tr-icon" src="/static/images/third_pages/tab_a.png"></image> |
|||
</view> |
|||
<view class="tr-item" @click="clickTap"> |
|||
<view class="ti-title">敬请期待</view> |
|||
<view class="ti-text">敬请期待</view> |
|||
<image class="tr-icon" src="/static/images/third_pages/tab_b.png"></image> |
|||
</view> |
|||
<view class="tr-item" @click="clickTap"> |
|||
<view class="ti-title">敬请期待</view> |
|||
<view class="ti-text">敬请期待</view> |
|||
<image class="tr-icon" src="/static/images/third_pages/tab_b.png"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<bottom-logo is-fixed></bottom-logo> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import bottomLogo from "@/subpackage/menu/components/bottom_logo.vue"; |
|||
import { showNone } from "@/utils/util"; |
|||
export default { |
|||
components:{ bottomLogo }, |
|||
methods: { |
|||
clickTap(){ |
|||
showNone('板块更新中'); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.third-page{ |
|||
.tp-container{ |
|||
padding: 28upx 24upx 0upx; |
|||
.tc-post{ |
|||
display: block; |
|||
height: 400upx; |
|||
width: 100%; |
|||
} |
|||
.tc-bot{ |
|||
margin-top: 24upx; |
|||
display: flex; |
|||
align-items: stretch; |
|||
.tb-left{ |
|||
position: relative; |
|||
flex-shrink: 0; |
|||
margin-right: 22upx; |
|||
padding: 22upx 28upx; |
|||
width: 340upx; |
|||
height: 420upx; |
|||
.tl-bg{ |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: -1; |
|||
} |
|||
.tl-tit{ |
|||
@include flcw(43upx, 60upx, #fff, 500); |
|||
@include tHide; |
|||
} |
|||
.tl-txt{ |
|||
@include flcw(30upx, 42upx, #fff, 500); |
|||
@include tHide; |
|||
} |
|||
} |
|||
.tb-right{ |
|||
flex-grow: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: space-between; |
|||
.tr-item{ |
|||
position: relative; |
|||
height: 124upx; |
|||
background-image: linear-gradient(270deg, #FFFFFF 0%, #C8C8CA 100%); |
|||
padding: 16upx; |
|||
&.active{ |
|||
background-image: linear-gradient(270deg, #F2D286 0%, #E0A46F 100%); |
|||
} |
|||
.ti-title{ |
|||
@include flcw(32upx, 44upx, #fff, 500); |
|||
@include tHide; |
|||
} |
|||
.ti-text{ |
|||
@include flcw(22upx, 32upx, #fff, 500); |
|||
@include tHide; |
|||
} |
|||
.tr-icon{ |
|||
position: absolute; |
|||
right: 6upx; |
|||
bottom: 0upx; |
|||
width: 136upx; |
|||
height: 104upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</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,122 +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 { |
|||
methods: { |
|||
toPeopleNum(){ |
|||
util.routeTo(`/pages/write_off/number_of_people/number_of_people`, '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}); |
|||
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: 40 | Height: 40 | Size: 251 B After Width: 15 | Height: 15 | Size: 226 B |
Before Width: 296 | Height: 296 | Size: 51 KiB After Width: 296 | Height: 296 | Size: 7.7 KiB |
Before Width: 52 | Height: 52 | Size: 2.4 KiB After Width: 52 | Height: 52 | Size: 901 B |
After Width: 52 | Height: 52 | Size: 1.2 KiB |
Before Width: 52 | Height: 52 | Size: 2.4 KiB After Width: 52 | Height: 52 | Size: 775 B |
Before Width: 172 | Height: 172 | Size: 932 B |
Before Width: 32 | Height: 32 | Size: 419 B |
Before Width: 420 | Height: 420 | Size: 9.6 KiB |
Before Width: 380 | Height: 380 | Size: 8.5 KiB |
Before Width: 420 | Height: 420 | Size: 11 KiB |
After Width: 56 | Height: 56 | Size: 558 B |
After Width: 56 | Height: 56 | Size: 795 B |
After Width: 56 | Height: 56 | Size: 726 B |
After Width: 56 | Height: 56 | Size: 553 B |
After Width: 56 | Height: 56 | Size: 653 B |
After Width: 56 | Height: 56 | Size: 986 B |
After Width: 56 | Height: 56 | Size: 939 B |
After Width: 56 | Height: 56 | Size: 668 B |
After Width: 351 | Height: 200 | Size: 23 KiB |
After Width: 170 | Height: 210 | Size: 2.5 KiB |
After Width: 68 | Height: 57 | Size: 2.3 KiB |
After Width: 68 | Height: 57 | Size: 1.9 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,188 @@ |
|||
<template> |
|||
<view class="authorization-login" v-show="isShow"> |
|||
<view class="ic-author-modal"> |
|||
<view class="iam-title">微信授权</view> |
|||
<view class="iam-tip">您的信息和数据将受到保护</view> |
|||
<image class="iam-pic" mode="aspectFit" src="../static/images/author_modal.png"></image> |
|||
<view class="iam-btns"> |
|||
<button plain hover-class="hover-active" @click="hide">取消</button> |
|||
|
|||
<button |
|||
v-if="isProfile" |
|||
plain |
|||
hover-class="hover-active" |
|||
@click="profileConfirm" |
|||
>授权并登录</button> |
|||
<button |
|||
v-else |
|||
plain |
|||
hover-class="hover-active" |
|||
open-type="getUserInfo" |
|||
lang="zh_CN" |
|||
@getuserinfo="confirmAuthor" |
|||
>授权并登录</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { promisify, showModal, showNone, showLoad, hideLoad, routeTo } from "@/utils/util"; |
|||
import { AUTHOR_API } from "../js/api"; |
|||
import server from "../js/server"; |
|||
export default { |
|||
data(){ |
|||
return { |
|||
isShow: false, |
|||
initData: { |
|||
/** |
|||
* @param {Object} data |
|||
* @param {Function} data.success |
|||
* @param {Function} data.fail |
|||
* */ |
|||
}, |
|||
} |
|||
}, |
|||
methods: { |
|||
alert(data){ |
|||
this.isShow = true; |
|||
this.initData = data ?? {}; |
|||
}, |
|||
hide(){ |
|||
this.isShow = false; |
|||
}, |
|||
isProfile(){ |
|||
return !!uni.getUserProfile |
|||
}, |
|||
// 新获取用户信息 |
|||
profileConfirm(){ |
|||
uni.getUserProfile({ |
|||
lang: 'zh_CN', desc: '授权登陆', |
|||
success: res => { this.confirmAuthor({detail: {...res}}) }, |
|||
fail: err => { |
|||
showModal({ content: '获取用户信息失败!请重试' }); |
|||
console.warn('subpackage authorization components login getUserProfile Err ->', err) |
|||
} |
|||
}) |
|||
}, |
|||
async confirmAuthor(userRes){ |
|||
if(!userRes.detail.userInfo){ |
|||
this.hide(); |
|||
return showModal({ content: '获取用户信息失败!请稍后重试' }); |
|||
} |
|||
|
|||
let loginRes = await promisify(uni.login)(); |
|||
if(!loginRes.code){ |
|||
this.hide(); |
|||
return showModal({ content: '获取登陆凭证失败!请稍后重试' }); |
|||
} |
|||
this.serverLogin({ userRes, loginRes }) |
|||
}, |
|||
getLoginQuery({ |
|||
userInfo, |
|||
loginRes |
|||
}){ |
|||
return { |
|||
appid: uni.getAccountInfoSync?.()?.miniProgram?.appId ?? '', |
|||
code: loginRes?.code ?? '', |
|||
encryptedData: userInfo?.encryptedData ?? '', |
|||
// is_details: 1, |
|||
// 后端解密错误,直接传用户信息 |
|||
user_info: userInfo?.userInfo ?? {}, |
|||
user_raw_data: userInfo?.rawData ?? {}, |
|||
...(userInfo?.userInfo ?? {}), |
|||
} |
|||
}, |
|||
serverLogin({ userRes, loginRes }){ |
|||
showLoad(); |
|||
return server.post({ |
|||
url: AUTHOR_API.wechatMiniAppLoginAndSync, |
|||
data: this.getLoginQuery({ |
|||
userInfo: userRes.detail, |
|||
loginRes |
|||
}), |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res=>{ |
|||
hideLoad(); |
|||
let _data = res.data || {}; |
|||
if(_data.code == 0){ |
|||
if(_data.data == '')return routeTo(`/pages/login/login`,'rL'); |
|||
showNone(_data?.message || '登陆成功!'); |
|||
this.$store.commit('setLoginState', { loginState: true, token: _data.data }); |
|||
this.initData?.success?.(_data); |
|||
this.hide(); |
|||
return _data; |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
}) |
|||
.catch(err=>{ |
|||
hideLoad(); |
|||
showModal({ content: err?.message || '后台登陆失败!' }); |
|||
console.warn('subpackage authorization components login serverLogin Err ->', err); |
|||
if(this.initData?.fail)return this.initData?.fail?.(err); |
|||
return Promise.reject(err); |
|||
}) |
|||
}, |
|||
cancelAuthor(){ |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.authorization-login{ |
|||
position: fixed; |
|||
left: 0; |
|||
top: var(--window-top); |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, .5); |
|||
} |
|||
|
|||
.ic-author-modal{ |
|||
position: absolute; |
|||
left: 50%; |
|||
top: 50%; |
|||
transform: translate(-50%, -50%); |
|||
padding-top: 60upx; |
|||
width: 662upx; |
|||
height: 884upx; |
|||
border-radius: 10upx; |
|||
background-color: #fff; |
|||
.iam-title{ |
|||
margin-bottom: 22upx; |
|||
text-align: center; |
|||
@include flcw(44upx, 60upx, #1a1a1a, 500); |
|||
} |
|||
.iam-tip{ |
|||
margin-bottom: 52upx; |
|||
text-align: center; |
|||
@include flcw(28upx, 40upx, #9c9c9f); |
|||
} |
|||
.iam-pic{ |
|||
margin: 0 auto 62upx; |
|||
display: block; |
|||
width: 488upx; |
|||
height: 416upx; |
|||
} |
|||
.iam-btns{ |
|||
@include ctf(center); |
|||
>button{ |
|||
margin: 0 20upx; |
|||
width: 240upx; |
|||
height: 92upx; |
|||
text-align: center; |
|||
border-radius: 46upx; |
|||
border: 2upx solid $mColor; |
|||
@include flcw(32upx, 88upx, $mColor); |
|||
&+button{ |
|||
background-color: $mColor; |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,25 @@ |
|||
@charset "UTF-8"; |
|||
|
|||
@font-face { |
|||
font-family: "tuniaoFont"; /* Project id 3784643 */ |
|||
src: |
|||
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAN8AAsAAAAAB4gAAAMvAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDBgqCQIIdATYCJAMMCwgABCAFhH8HPRuYBiMRpmvPIfurAzsYPj7DCVbrRAmElfXCs4V6xacO8aHO69VXu54tTy8h0hcJ7ufgieY+3+xscrn9B8wKQQFBywplLZCw9SwcOyZ5pKsoAQAbcICJTr7AjPPqr06NRkeIAemFpXv8cje1+/LkuLvD789WJZUANjOe9F76qptDOSMUui/Ua0WQKpZGXaqf5hHZdAD6x8tRJtRKtQd7j5UKkk6lWywYkGADCZBnGLugJd6CAI4GOjH956Ep4k7imdNkYTGFAkm2nJyPrBNwA7YhWwgQ/K4bLXITD8wl8xxuBN+XwyYJwOAp5jFjOwNbPNwd3l3WiyFAv3sCBLjcAB6gQM3GjLLSbJpDo1ANiqsiFiX7WAQzqTcMA06j/pb/eAbEx8yMAaAChg3sDjs6COwub8IAoAD4PEZkA7iAZClPKdicmJLc2OiZcQC3cV613sc3Ab9W7YItQtio9YgdKGjgr+ANlbg5gPvXFacv8IyvKTH4pcjV7VIcfnuIAUd3VCbxcCIKj++rvr/hpx/iwxd4/5mxDXeILbBp2+ByMIlGMuQEU3gjiVaMcXk8Dn2gWo5wuRwuIldLRqRwWogvmCRXE9/kSvrVQP4iFDVWRSbRakMk/AtcBYVpO6rpah1V9J/m/Wt+q8WfsOV+S5KFTGD5dwW9KFstZUs5smuYK3V495zwUG+r/Izf0PWtbWj/HUQsAL9u+cGK8NCiAgRnaRJ49fqljrxWc4PaKs4pQwBlMLUeAzgcEGLakvg5nCZ3zgTBkZzAEEUuFEeJyMrq4BGhGT6OPjiqGd4eIZkLKGKjgTKuAAgpPIAhjmdQUngnsrJdeKTxBz4pkgjHjJQeFqFMXv8PQqg0QP+F2cbAdoHqFmaM52jYlcbNoeTq4CtPkjzHAE1Zl0QvFEjGmp9fY6vKwBI9kOvIuQhJ4kJWy0k1dVXFVXcpbfTmIIRKA/RfmG0M7G1T3cKM8VwMXGlEnR1KY0uU+CTJnM1ODk1ZdxJdSOjYdGOp+TW2k6szsNg8qIvIuQipetFCVstpQCB1lcXHXUl5ZOpfdBvgMI9QMaJi8TZdzLS36K8/ueDZOWMAAA==') format('woff2'), |
|||
url('//at.alicdn.com/t/c/font_3784643_5jru9pe5fad.woff?t=1669045092678') format('woff'), |
|||
url('//at.alicdn.com/t/c/font_3784643_5jru9pe5fad.ttf?t=1669045092678') format('truetype'); |
|||
} |
|||
|
|||
[class*='tn-icon-'] { |
|||
font-family: 'tuniaoFont' !important; |
|||
font-style: normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
text-align: center; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
.tn-icon-close:before { |
|||
content: "\e74d"; |
|||
} |
|||
|
|||
.tn-icon-camera-fill:before { |
|||
content: "\e75d"; |
|||
} |
@ -0,0 +1,133 @@ |
|||
<template> |
|||
<wx-user-info-modal |
|||
v-model="showAuthorizationModal" |
|||
@updated="updatedUserInfoEvent" |
|||
:isModal="isModal" |
|||
:alway="alway" |
|||
></wx-user-info-modal> |
|||
</template> |
|||
|
|||
<script> |
|||
import WxUserInfoModal from './tuniaoui-wx-user-info.vue'; |
|||
import { AUTHOR_API } from '../../js/api'; |
|||
import servers from '../../js/server'; |
|||
import { showModal, jsonPar, showLoad, hideLoad } from '@/utils/util'; |
|||
export default { |
|||
components: { WxUserInfoModal }, |
|||
props: { |
|||
isModal: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
alway: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
watch: { |
|||
showAuthorizationModal(nVal, oVal){ |
|||
let { initData } = this; |
|||
if(!nVal&&oVal)initData?.close?.(); |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
showAuthorizationModal: false, |
|||
initData: {}, |
|||
} |
|||
}, |
|||
methods: { |
|||
show(data){ |
|||
this.showAuthorizationModal = true; |
|||
this.initData = data; |
|||
}, |
|||
hide(){ |
|||
this.showAuthorizationModal = false; |
|||
}, |
|||
// 获取到的用户信息 |
|||
async updatedUserInfoEvent(info) { |
|||
let { initData, userEdit } = this; |
|||
try{ |
|||
let _imgUrl = await this.uploadImg(info.avatar); |
|||
let _editObj = { nickname: info.nickname, avatar_url: _imgUrl }; |
|||
await userEdit(_editObj); |
|||
this.hide(); |
|||
initData?.success?.(_editObj); |
|||
}catch(err){ |
|||
console.warn('authorize components user info impower updatedUserInfoEvent err --->', err) |
|||
initData?.fail?.(err); |
|||
} |
|||
}, |
|||
// 上传头像 |
|||
async uploadImg(url){ |
|||
try{ |
|||
showLoad(); |
|||
let _imgInfo = await servers.uploadFile({ |
|||
url: AUTHOR_API.zs_user_avatar, |
|||
filePath: url, |
|||
}); |
|||
if(_imgInfo.statusCode != 200)throw(_imgInfo); |
|||
let _imgRes = jsonPar(_imgInfo.data); |
|||
if(_imgRes.code != 0)throw(_imgRes); |
|||
hideLoad(); |
|||
return _imgRes.data.url || ''; |
|||
}catch(err){ |
|||
hideLoad(); |
|||
showModal({ content: err?.errMsg ?? err?.message ?? '上传图片失败!' }); |
|||
console.warn('authorize components user info impower uploadImg err --->', err) |
|||
return Promise.reject(err); |
|||
} |
|||
}, |
|||
// 用户信息上传 |
|||
userEdit({ nickname, avatar_url }){ |
|||
showLoad(); |
|||
return servers.post({ |
|||
url: AUTHOR_API.changeAvatar, |
|||
data: { nickname, avatar_url }, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
hideLoad(); |
|||
let _data = res?.data || {}; |
|||
if(_data.code === 0){ |
|||
console.log('userEdit res--->', _data); |
|||
return _data?.data; |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
hideLoad(); |
|||
showModal({ content: err.message || '操作失败!' }); |
|||
console.warn('authorize components user info impower userEdit err --->', err); |
|||
return Promise.reject(err); |
|||
}) |
|||
}, |
|||
// 刷新用户信息 |
|||
refreshUserInfo(){ |
|||
return servers.post({ |
|||
url: ATR_API.userCurrent, |
|||
data: {}, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
let _data = res?.data || {}; |
|||
if(_data.code === 0){ |
|||
uni.setStorageSync('userInfo', _data?.data); |
|||
this.$store.commit('refreshUserInfo', _data?.data); |
|||
return _data?.data; |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
console.warn('authorize components user info impower refreshUserInfo err --->', err); |
|||
// return Promise.reject(err); |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
</style> |
@ -0,0 +1,357 @@ |
|||
<template> |
|||
<view |
|||
v-if="openModal || alway" |
|||
class="wx-authorization-modal" |
|||
:class="{ 'modal-class': isModal }" |
|||
> |
|||
<view |
|||
class="wam__mask" |
|||
@touchmove.prevent="" |
|||
@tap.stop="closeModal" |
|||
></view> |
|||
|
|||
<!-- 内容区域 --> |
|||
<view class="wam__wrapper"> |
|||
<!-- 关闭按钮 --> |
|||
<view class="wam__close-btn" @tap.stop="closeModal"> |
|||
<text class="tn-icon-close"></text> |
|||
</view> |
|||
<!-- 标题 --> |
|||
<view class="wam__title">获取您的昵称、头像</view> |
|||
<!-- tips --> |
|||
<view class="wam__sub-title"> |
|||
获取用户头像、昵称,主要用于向用户提供具有辨识度的用户中心界面 |
|||
</view> |
|||
|
|||
<!-- 头像选择 --> |
|||
<view class="wam__avatar"> |
|||
<view class="button-shadow"> |
|||
<button |
|||
class="button" |
|||
open-type="chooseAvatar" |
|||
@chooseavatar="chooseAvatarEvent" |
|||
> |
|||
<view v-if="userInfo.avatar" class="avatar__image"> |
|||
<image class="image" :src="userInfo.avatar" mode="aspectFill"></image> |
|||
</view> |
|||
<view v-else class="avatar__empty"> |
|||
<!-- <image class="image" src="https://cdn.nlark.com/yuque/0/2022/jpeg/280373/1668928062708-assets/web-upload/764843cf-055a-4cb6-b5d3-dca528b33fd4.jpeg" mode="aspectFill"></image> --> |
|||
</view> |
|||
<view class="avatar--icon"> |
|||
<view class="tn-icon-camera-fill"></view> |
|||
</view> |
|||
</button> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 昵称输入 --> |
|||
<view class="wam__nickname"> |
|||
<view class="nickname__data"> |
|||
<input class="input" type="nickname" v-model="userInfo.nickname" placeholder="请输入昵称" placeholder-style="color: #AAAAAA;"> |
|||
</view> |
|||
</view> |
|||
|
|||
|
|||
<!-- 保存按钮 --> |
|||
<view |
|||
class="wam__submit-btn" |
|||
:class="[{ |
|||
'disabled': !userInfo.avatar || !userInfo.nickname |
|||
}]" |
|||
hover-class="tn-btn-hover-class" |
|||
:hover-stay-time="150" |
|||
@tap.stop="submitUserInfo" |
|||
> |
|||
保 存 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
export default { |
|||
options: { |
|||
// 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现(不会出现shadow节点下再去创建元素) |
|||
virtualHost: true |
|||
}, |
|||
props: { |
|||
value: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
isModal: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
alway: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
openModal: false, |
|||
userInfo: { |
|||
avatar: '', |
|||
nickname: '' |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
value: { |
|||
handler(val) { |
|||
this.openModal = val |
|||
}, |
|||
immediate: true |
|||
} |
|||
}, |
|||
methods: { |
|||
|
|||
|
|||
// 头像选择 |
|||
chooseAvatarEvent(e) { |
|||
this.userInfo.avatar = e.detail.avatarUrl |
|||
}, |
|||
|
|||
// 更新用户信息 |
|||
submitUserInfo() { |
|||
// 判断是否已经选择了用户头像和输入了用户昵称 |
|||
if (!this.userInfo.avatar || !this.userInfo.nickname) { |
|||
return uni.showToast({ |
|||
icon: 'none', |
|||
title: '请选择头像和输入用户信息' |
|||
}) |
|||
} |
|||
|
|||
// 更新完成事件 |
|||
this.$emit('updated', this.userInfo) |
|||
|
|||
}, |
|||
|
|||
// 关闭弹框 |
|||
closeModal() { |
|||
this.$emit('input', false) |
|||
}, |
|||
|
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
|
|||
@import './iconfont.css'; |
|||
|
|||
.modal-class{ |
|||
position: fixed; |
|||
left: 0; |
|||
top: 0; |
|||
width: 100vw; |
|||
height: 100vh; |
|||
z-index: 99998; |
|||
.wam { |
|||
&__mask { |
|||
display: block !important; |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
opacity: 0; |
|||
animation: showMask 0.25s ease 0.1s forwards; |
|||
} |
|||
&__close-btn { |
|||
display: block !important; |
|||
display: none; |
|||
position: absolute; |
|||
top: 30rpx; |
|||
right: 30rpx; |
|||
z-index: 99999; |
|||
} |
|||
&__wrapper{ |
|||
position: absolute; |
|||
left: 0; |
|||
bottom: 0; |
|||
width: 100%; |
|||
transform-origin: center bottom; |
|||
transform: scaleY(0); |
|||
animation: showWrapper 0.25s ease 0.1s forwards; |
|||
z-index: 99999; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.wx-authorization-modal { |
|||
// view { |
|||
// box-sizing: border-box; |
|||
// } |
|||
|
|||
.image { |
|||
width: 100%; |
|||
height: 100%; |
|||
border-radius: inherit; |
|||
} |
|||
|
|||
|
|||
|
|||
.wam { |
|||
/* mask */ |
|||
&__mask { |
|||
display: none; |
|||
} |
|||
|
|||
/* close-btn */ |
|||
&__close-btn { |
|||
display: none; |
|||
} |
|||
|
|||
/* wrapper */ |
|||
&__wrapper { |
|||
background-color: #FFFFFF; |
|||
border-radius: 20rpx 20rpx 0rpx 0rpx; |
|||
padding: 40rpx; |
|||
padding-top: 60rpx; |
|||
padding-bottom: 40rpx; |
|||
padding-bottom: calc(constant(safe-area-inset-bottom) + 40rpx); |
|||
padding-bottom: calc(env(safe-area-inset-bottom) + 40rpx); |
|||
|
|||
} |
|||
|
|||
/* title */ |
|||
&__title { |
|||
font-size: 34rpx; |
|||
} |
|||
/* sub-title */ |
|||
&__sub-title { |
|||
font-size: 26rpx; |
|||
color: #AAAAAA; |
|||
margin-top: 16rpx; |
|||
padding-bottom: 30rpx; |
|||
} |
|||
|
|||
/* 头像选择 */ |
|||
&__avatar { |
|||
width: 100%; |
|||
margin-top: 30rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
.button-shadow { |
|||
border: 8rpx solid rgba(255,255,255,0.05); |
|||
box-shadow: 0rpx 0rpx 80rpx 0rpx rgba(0, 0, 0, 0.15); |
|||
border-radius: 50%; |
|||
} |
|||
|
|||
.button { |
|||
position: relative; |
|||
width: 160rpx; |
|||
height: 160rpx; |
|||
border-radius: 50%; |
|||
overflow: visible; |
|||
background-image: repeating-linear-gradient(45deg, #E4E9EC, #F8F7F8); |
|||
color: #FFFFFF; |
|||
background-color: transparent; |
|||
padding: 0; |
|||
margin: 0; |
|||
font-size: inherit; |
|||
line-height: inherit; |
|||
border: none; |
|||
&::after { |
|||
border: none; |
|||
} |
|||
} |
|||
|
|||
.avatar { |
|||
&__empty, &__image { |
|||
width: 100%; |
|||
height: 100%; |
|||
border-radius: inherit; |
|||
} |
|||
|
|||
&--icon { |
|||
position: absolute; |
|||
right: -10rpx; |
|||
bottom: -6rpx; |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
// transform: translate(50%, 50%); |
|||
background-color: #1D2541; |
|||
color: #FFFFFF; |
|||
border-radius: 50%; |
|||
border: 6rpx solid #FFFFFF; |
|||
line-height: 1; |
|||
font-size: 36rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* 昵称 */ |
|||
&__nickname { |
|||
margin-top: 40rpx; |
|||
|
|||
.nickname { |
|||
|
|||
&__data { |
|||
margin-top: 16rpx; |
|||
width: 100%; |
|||
padding: 26rpx 20rpx; |
|||
border-radius: 10rpx; |
|||
background-color: #F8F7F8; |
|||
|
|||
.input { |
|||
color: #080808; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* 保存按钮 */ |
|||
&__submit-btn { |
|||
width: 100%; |
|||
background-color: $mColor; |
|||
color: #FFFFFF; |
|||
margin-top: 60rpx; |
|||
border-radius: 10rpx; |
|||
padding: 25rpx; |
|||
font-size: 32rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
&.disabled { |
|||
background-color: #E6E6E6; |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
|||
|
|||
.tn-btn-hover-class { |
|||
box-shadow: inset 10rpx 2rpx 40rpx 0rpx rgba(0, 0, 0, 0.05); |
|||
} |
|||
|
|||
@keyframes showMask { |
|||
0% { |
|||
opacity: 0; |
|||
} |
|||
100% { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
@keyframes showWrapper { |
|||
0% { |
|||
transform: scaleY(0); |
|||
} |
|||
100% { |
|||
transform: scaleY(1); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,9 @@ |
|||
import { ORIGIN } from '@/js/api'; |
|||
|
|||
export const AUTHOR_API = { |
|||
wechatMiniAppLoginAndSync: `${ORIGIN}/assistant/WechatMiniAppGetToken`, // 小程序授权获取token,为空就登录
|
|||
zs_user_avatar:`${ORIGIN}/upload/file/zs_user_avatar`, // 头像图片上传
|
|||
changeAvatar: `${ORIGIN}/admin/assistant/changeAvatar`, // 修改用户头像、昵称
|
|||
} |
|||
|
|||
export default AUTHOR_API; |
@ -0,0 +1,10 @@ |
|||
import { Server } from '@/js/server'; |
|||
|
|||
class _Server extends Server { |
|||
constructor(props){ |
|||
super(props) |
|||
} |
|||
} |
|||
|
|||
|
|||
export default new _Server(); |
@ -0,0 +1,16 @@ |
|||
<template> |
|||
<!-- 需要定义一个页面以及在pagesjson里声明才能生成static文件夹 --> |
|||
<view> </view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
page{ |
|||
background: #fff; |
|||
} |
|||
</style> |
Before Width: 488 | Height: 416 | Size: 14 KiB After Width: 488 | Height: 416 | Size: 14 KiB |
@ -0,0 +1,173 @@ |
|||
<template> |
|||
<view class="brand-change-modal"> |
|||
<view class="bcm-mask" v-show="isShow"> |
|||
<view class="bm-content"> |
|||
<view class="bc-title">品牌切换</view> |
|||
<input type="text" class="bc-ipt" v-model="searchTxt" placeholder="模糊搜索..." /> |
|||
<view class="bc-tip">当前选中:{{ curSelected.name || '-' }}</view> |
|||
<view class="bc-tip">Tip:控件有bug,当前选中与下方不匹配时,滑动纠正</view> |
|||
<picker-view class="bc-picker-view" immediate-change @change="pickerChange"> |
|||
<picker-view-column> |
|||
<view class="bpv-item" v-for="(e, i) in showBrandList" :key="i">{{ e.name || '-' }}</view> |
|||
</picker-view-column> |
|||
</picker-view> |
|||
|
|||
<view class="bc-btns"> |
|||
<view class="bb-item" @click="hide">取消</view> |
|||
<view class="bb-item" @click="confirm">确认</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/utils/util'; |
|||
import deviceServer from '../js/device_server'; |
|||
import deviceApi from '../js/device_api'; |
|||
import PinyinEngine from "pinyin-engine"; |
|||
export default { |
|||
data(){ |
|||
return { |
|||
isShow: false, |
|||
searchTxt: '', |
|||
brandList: [], |
|||
initOptions: {}, |
|||
pickerIdx: 0, |
|||
pyEngine: null, |
|||
} |
|||
}, |
|||
computed: { |
|||
showBrandList(){ |
|||
let { brandList, searchTxt, pyEngine } = this; |
|||
|
|||
if(searchTxt&&pyEngine?.query){ |
|||
let _ls = pyEngine.query(searchTxt); |
|||
return _ls || []; |
|||
} |
|||
return brandList.filter(item=>{ |
|||
return item.name.includes(searchTxt); |
|||
}); |
|||
}, |
|||
curSelected(){ |
|||
let { pickerIdx, showBrandList } = this; |
|||
return showBrandList?.[pickerIdx] || {}; |
|||
} |
|||
}, |
|||
mounted(){ |
|||
// this.getBrandList(); |
|||
}, |
|||
methods: { |
|||
confirm(){ |
|||
let { pickerIdx, showBrandList, initOptions } = this; |
|||
console.log('pickerIdx', pickerIdx); |
|||
console.log('showBrandList', showBrandList); |
|||
this.hide(); |
|||
if(showBrandList?.length <= 0) return; |
|||
let _brand = showBrandList[pickerIdx]; |
|||
initOptions?.success?.(_brand); |
|||
this.$emit('click:confirm', _brand); |
|||
}, |
|||
pickerChange(e){ |
|||
this.pickerIdx = e?.detail?.value?.[0]; |
|||
}, |
|||
async init(options){ |
|||
if(this.brandList?.length <= 0) await this.getBrandList(); |
|||
this.initOptions = options; |
|||
this.show(); |
|||
}, |
|||
show(){ |
|||
this.isShow = true; |
|||
}, |
|||
hide(){ |
|||
this.isShow = false; |
|||
}, |
|||
// 获取品牌列表 |
|||
getBrandList(){ |
|||
util.showLoad(); |
|||
return deviceServer.get({ |
|||
url: deviceApi.brandList, |
|||
data: {}, |
|||
failMsg: '加载品牌列表失败!' |
|||
}) |
|||
.then(res=>{ |
|||
util.hideLoad(); |
|||
let _ls = res || []; |
|||
this.brandList = _ls; |
|||
|
|||
if(_ls?.length > 0&&PinyinEngine){ |
|||
this.pyEngine = new PinyinEngine(_ls, ['name']); |
|||
} |
|||
}) |
|||
.catch(util.hideLoad) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.bcm-mask{ |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
z-index: 10; |
|||
.bm-content{ |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
transform: translate(-50%, -50%); |
|||
padding: 40upx; |
|||
width: 620upx; |
|||
border-radius: 10px; |
|||
background-color: #fff; |
|||
} |
|||
.bc-title{ |
|||
text-align: center; |
|||
@include flcw(32upx, 44upx, #1a1a1a, 500); |
|||
} |
|||
.bc-tip{ |
|||
margin-top: 10upx; |
|||
@include flcw(20upx, 30upx, #9A9A9D); |
|||
} |
|||
.bc-ipt{ |
|||
box-sizing: border-box; |
|||
margin-top: 38upx; |
|||
padding: 0 20upx; |
|||
height: 88upx; |
|||
border-radius: 10upx; |
|||
border: 2upx solid #d8d8d8; |
|||
@include flcw(28upx, 40upx, #1a1a1a, 500); |
|||
} |
|||
.bc-picker-view{ |
|||
margin-top: 20upx; |
|||
width: 100%; |
|||
height: 300upx; |
|||
.bpv-item{ |
|||
font-size: 28upx; |
|||
color: #1a1a1a; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
overflow: hidden; |
|||
} |
|||
} |
|||
.bc-btns{ |
|||
margin-top: 30upx; |
|||
@include ctf(space-between); |
|||
.bb-item{ |
|||
width: 240upx; |
|||
height: 88upx; |
|||
border-radius: 10upx; |
|||
border: 2upx solid $mColor; |
|||
text-align: center; |
|||
@include flcw(32upx, 84upx, $mColor, 500); |
|||
&+.bb-item{ |
|||
background: $mColor; |
|||
color: #fff; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -1,265 +0,0 @@ |
|||
<template> |
|||
<view class="timing-details"> |
|||
<view class="td-head"> |
|||
<view class="th-store"> |
|||
<image :src="orderInfo.stadium_logo || ''"></image> |
|||
<view>{{orderInfo.stadium_name || '-'}}</view> |
|||
</view> |
|||
<view class="th-line"> |
|||
<view>订单编号:<text>{{orderInfo.order_no || '-'}}</text></view> |
|||
<view><text :class="[orderInfo.pay_status == 0?'tl-active':'']">{{zh_order_status(orderInfo.pay_status)}}</text></view> |
|||
</view> |
|||
<view class="th-line"> |
|||
<view>创建时间:<text>{{orderInfo.model.created_at || '-'}}</text></view> |
|||
</view> |
|||
<view class="th-line"> |
|||
<view>用户昵称:<text>{{orderInfo.nickname || '-'}}</text></view> |
|||
</view> |
|||
</view> |
|||
<view class="td-box"> |
|||
<view class="tb-title">计时信息</view> |
|||
<view class="tb-line"> |
|||
<!-- 项目 场时有 人时没有 order_type: 1场时 2人时 --> |
|||
<view v-if="orderInfo.order_type==1">项目:<text>{{orderInfo.project_name || '-'}}({{orderInfo.venue_name || '-'}})</text></view> |
|||
<view>进场时间:<text>{{orderInfo.start_time || '-'}}</text></view> |
|||
<!-- 离场时间 已完成显示 --> |
|||
<view v-if="orderInfo.pay_status != 0">离场时间:<text>{{orderInfo.end_time || '-'}}</text></view> |
|||
<view>时长合计:<text>{{orderInfo.extension.duration || '-'}}</text></view> |
|||
</view> |
|||
<view class="tb-section" v-if="!(orderInfo.pay_status== 0&&orderInfo.early_end_timing==false)"> |
|||
<view class="ts-line"> |
|||
<view>金额小计</view> |
|||
<view>¥{{orderInfo.amount || 0}}</view> |
|||
</view> |
|||
<view class="ts-line"> |
|||
<view>积分抵扣</view> |
|||
<view>-¥{{orderInfo.deduction_amount ||0}}</view> |
|||
</view> |
|||
<view class="ts-line"> |
|||
<view>折扣金额</view> |
|||
<view>-¥{{orderInfo.discount_amount||0}}</view> |
|||
</view> |
|||
<view class="ts-line"> |
|||
<view>优惠券优惠</view> |
|||
<view>-¥{{orderInfo.coupons_amount || 0}}</view> |
|||
</view> |
|||
<view class="ts-total"> |
|||
<view>合计支付:<text>¥</text><text>{{orderInfo.pay_amount ||0}}</text></view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="td-box" v-if="orderInfo.pay_status != 0"> |
|||
<view class="tb-title">支付信息</view> |
|||
<view class="tb-line"> |
|||
<view>支付方式:<text>{{zh_pay_type(orderInfo.pay_type)}}</text></view> |
|||
<view>支付时间:<text>{{orderInfo.pay_time || '-'}}</text></view> |
|||
<view v-if="orderInfo.pay_type==0">微信交易号:<text>{{orderInfo.trade_no || ''}}</text></view> |
|||
<view v-if="orderInfo.pay_type==3">操作人:<text>{{orderInfo.end_bill_operator_name || ''}}</text></view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="td-box" v-if="orderInfo.pay_status == 4"> |
|||
<view class="tb-title">退款信息</view> |
|||
<view class="tb-line"> |
|||
<view>退款原因:<text>{{orderInfo.refund_reason || '-'}}</text></view> |
|||
<view>退款时间:<text>{{orderInfo.refund_time || '-'}}</text></view> |
|||
<view>退款单号:<text>{{orderInfo.refund_no || '-'}}</text></view> |
|||
</view> |
|||
</view> |
|||
<view class="td-btn" @click="isEndBill = true" v-if="orderInfo.pay_status == 0&&orderInfo.early_end_timing==false">结束计费</view> |
|||
<view class="td-btn" @click="completeBtn" v-if="orderInfo.pay_status == 0&&orderInfo.early_end_timing==true">完结订单</view> |
|||
|
|||
<!-- 结束计费弹框 --> |
|||
<end-billing-modal |
|||
v-if="isEndBill==true" |
|||
@close="isEndBill=false" |
|||
@timeEndBtn="timeEndBtn" |
|||
:orderInfo="orderInfo" |
|||
></end-billing-modal> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import util from '@/utils/util'; |
|||
import deviceServer from '../../../js/device_server'; |
|||
import deviceApi from '../../../js/device_api'; |
|||
import { mapState } from 'vuex'; |
|||
import end_billing_modal from '../../../../../components/end_billing_modal/end_billing_modal.vue'; |
|||
export default { |
|||
components: { |
|||
'end-billing-modal': end_billing_modal, |
|||
}, |
|||
props: { |
|||
orderInfo: { |
|||
type: Object, |
|||
default: ()=>({}) |
|||
} |
|||
}, |
|||
computed: { |
|||
...mapState(['brandInfo']), |
|||
zh_order_status(){ |
|||
// 订单状态 0计费中1已完成 |
|||
let { orderInfo } = this |
|||
return status =>{ |
|||
const _obj = { |
|||
'0': orderInfo.early_end_timing==true?'待支付':'计费中', |
|||
'1': '已完成', |
|||
'4': '已退款', |
|||
} |
|||
return _obj[`${status}`] || '-' |
|||
} |
|||
}, |
|||
zh_pay_type(){ |
|||
// 支付类型 0微信支付1支付宝支付2储值卡支付 |
|||
return status =>{ |
|||
const _obj = { |
|||
'0': '微信支付', |
|||
'1': '支付宝支付', |
|||
'2': '储值卡支付', |
|||
'3': '商家主动结束计费', |
|||
} |
|||
return _obj[`${status}`] || '-' |
|||
} |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
isEndBill: false, |
|||
} |
|||
}, |
|||
methods: { |
|||
completeBtn(){ |
|||
this.$emit('completeBtn'); |
|||
}, |
|||
|
|||
timeEndBtn(){ |
|||
this.$emit('refreshPage'); |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" > |
|||
@import '~style/public.scss'; |
|||
.timing-details{ |
|||
margin-bottom: 24rpx; |
|||
.td-head{ |
|||
margin: 24rpx 24rpx 0rpx; |
|||
padding: 30rpx; |
|||
background-color: #FFF; |
|||
border-radius: 10rpx 10rpx 0px 0px; |
|||
.th-store{ |
|||
padding-bottom: 26rpx; |
|||
margin-bottom: 18rpx; |
|||
border-bottom: 2rpx solid #D8D8D8; |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
>image{ |
|||
flex-shrink: 0; |
|||
width: 40rpx; |
|||
height: 40rpx; |
|||
background-color: skyblue; |
|||
|
|||
} |
|||
>view{ |
|||
flex-grow: 1; |
|||
margin-left: 14rpx; |
|||
color: #333333; |
|||
font-size: 28rpx; |
|||
} |
|||
} |
|||
.th-line{ |
|||
margin-top: 8rpx; |
|||
@include centerFlex(space-between); |
|||
>view{ |
|||
line-height: 40rpx; |
|||
font-size: 28rpx; |
|||
&:first-child{ |
|||
color: #9A9A9D; |
|||
>text{ |
|||
color: #333333; |
|||
} |
|||
} |
|||
&:nth-child(2){ |
|||
>text{ |
|||
color: #9A9A9D; |
|||
} |
|||
.tl-active{ |
|||
color: #009874; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.td-box{ |
|||
margin: 24rpx 24rpx 0rpx; |
|||
padding: 30rpx; |
|||
background-color: #FFF; |
|||
border-radius: 10rpx; |
|||
.tb-title{ |
|||
color: #9A9A9D; |
|||
font-size: 28rpx; |
|||
margin-bottom: 20rpx; |
|||
} |
|||
.tb-line{ |
|||
>view{ |
|||
line-height: 52rpx; |
|||
font-size: 28rpx; |
|||
color: #9A9A9D; |
|||
>text{ |
|||
color: #333333; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.tb-section{ |
|||
margin-top: 30rpx; |
|||
border-top: 2rpx solid #D8D8D8; |
|||
.ts-line{ |
|||
margin-top: 26rpx; |
|||
@include centerFlex(space-between); |
|||
>view{ |
|||
color: #333333; |
|||
&:first-child{ |
|||
font-size: 28rpx; |
|||
} |
|||
&:nth-child(2){ |
|||
font-size: 24rpx; |
|||
margin-right: 8rpx; |
|||
} |
|||
} |
|||
} |
|||
.ts-total{ |
|||
margin-top: 22rpx; |
|||
@include centerFlex(flex-end); |
|||
>view{ |
|||
color: #333333; |
|||
font-size: 28rpx; |
|||
>text{ |
|||
color: #FF873D; |
|||
&:first-child{ |
|||
font-size: 28rpx; |
|||
} |
|||
&:nth-child(2){ |
|||
font-size: 36rpx; |
|||
margin-right: 8rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.td-btn{ |
|||
height: 112rpx; |
|||
margin: 80rpx 24rpx; |
|||
border-radius: 10rpx; |
|||
background-color: #009874; |
|||
color: #FFF; |
|||
font-size: 32rpx; |
|||
line-height: 112rpx; |
|||
text-align: center; |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,180 @@ |
|||
<template> |
|||
<view class="lt-list"> |
|||
<view class="ll-title">{{ optionsQuery.hardware_name || '-' }}</view> |
|||
<view class="ll-list"> |
|||
<view class="ll-item" v-for="(e, i) in timingLs" :key="i"> |
|||
<view class="li-line"> |
|||
<view class="ll-txt">指令:{{ getInstructTxt(e.operate) }}</view> |
|||
<image class="ll-icon" @click="deleteItem(e)" mode="aspectFit" src="/subpackage/device/static/images/delete.png"></image> |
|||
</view> |
|||
<view class="li-line"> |
|||
<view class="ll-txt">时间:{{ e.h_m_s || '-'}}</view> |
|||
</view> |
|||
<view class="li-line"> |
|||
<view class="ll-txt">日期:{{ e.day_of_week || '-' }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="ll-fixed-space"></view> |
|||
<view class="ll-fixed"> |
|||
<view class="lf-btn" @click="addTask">添加定时任务</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
import { showModal, showNone, showLoad, hideLoad, routeTo, jsonPar, jsonStr } from "@/utils/util"; |
|||
export default { |
|||
data(){ |
|||
return { |
|||
timingLs: [], |
|||
optionsQuery: {}, |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
options.hardware_name = jsonPar(options?.hardware_name); |
|||
this.optionsQuery = options; |
|||
}, |
|||
onShow(){ |
|||
let { optionsQuery } = this; |
|||
this.getTimingList({ |
|||
hardware_id: optionsQuery?.hardware_id || '' |
|||
}) |
|||
}, |
|||
methods: { |
|||
addTask(){ |
|||
let { hardware_id, hardware_name } = this.optionsQuery; |
|||
let _qryStr = `hardware_id=${hardware_id || ''}&hardware_name=${jsonStr(hardware_name || '')}` |
|||
routeTo(`/subpackage/device/pages/lighting_time/setting?${_qryStr}`, 'nT') |
|||
}, |
|||
deleteItem(e){ |
|||
showModal({ |
|||
title: '提示', |
|||
content: '是否删除该项?', |
|||
showCancel: true, |
|||
confirmText: '是', |
|||
cancelText: '否', |
|||
success: res =>{ |
|||
if(res?.confirm){ |
|||
this.cacScheduledTaskDelete(e?.id) |
|||
.then(res=>{ |
|||
if(res === 'SUCCESS')this.getTimingList({ hardware_id: e?.hardware_id }) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
cacScheduledTaskDelete(id){ |
|||
showLoad(); |
|||
return deviceServer.post({ |
|||
url: deviceApi.cacScheduledTaskDelete, |
|||
data: { id }, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
hideLoad(); |
|||
let _data = res?.data || {}; |
|||
if(_data.code === 0){ |
|||
showModal({ |
|||
title: '提示', |
|||
content: _data.message || '操作成功!' |
|||
}) |
|||
return "SUCCESS" |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
|
|||
}) |
|||
.catch(err => { |
|||
hideLoad(); |
|||
showModal({ |
|||
title: '提示', |
|||
content: err.message || '操作失败!' |
|||
}) |
|||
console.warn('setting cacScheduledTaskSave err', err); |
|||
}) |
|||
}, |
|||
getInstructTxt(operate){ |
|||
let _obj = { |
|||
'open': '开启', |
|||
'close': '关闭' |
|||
} |
|||
return _obj?.[operate] || operate || '未知' |
|||
}, |
|||
getTimingList({ |
|||
hardware_id = '', |
|||
}){ |
|||
showLoad(); |
|||
return deviceServer.get({ |
|||
url: deviceApi.cacScheduledTaskGet, |
|||
data: { |
|||
hardware_id, |
|||
}, |
|||
failMsg: '获取定时列表失败' |
|||
}) |
|||
.then(res => { |
|||
hideLoad(); |
|||
let _ls = res || []; |
|||
this.timingLs = _ls; |
|||
}) |
|||
.catch(err => { |
|||
hideLoad(); |
|||
console.warn('lighting_time list getTimingList err --->', err); |
|||
// return Promise.reject(err); |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.ll-title{ |
|||
padding: 46upx 40upx 60upx; |
|||
@include flcw(44upx, 60upx, #1a1a1a, 500); |
|||
@include tHide; |
|||
} |
|||
.ll-list{ |
|||
.ll-item{ |
|||
padding: 24upx 30upx; |
|||
background: #fff; |
|||
&+.ll-item{ |
|||
margin-top: 24upx; |
|||
} |
|||
.li-line{ |
|||
@include ctf(space-between); |
|||
align-items: baseline; |
|||
&+.li-line{ |
|||
margin-top: 16upx; |
|||
} |
|||
.ll-txt{ |
|||
@include flcw(28upx, 40upx, #1a1a1a); |
|||
} |
|||
.ll-icon { |
|||
flex-shrink: 0; |
|||
margin-left: 12upx; |
|||
width: 44upx; |
|||
height: 44upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.ll-fixed-space{ |
|||
padding-bottom: 132upx; |
|||
@include isPd(132upx); |
|||
} |
|||
.ll-fixed{ |
|||
position: fixed; |
|||
bottom: 0; |
|||
padding: 10upx 24upx; |
|||
width: 100%; |
|||
@include isPd(10upx); |
|||
.lf-btn{ |
|||
text-align: center; |
|||
border-radius: 10upx; |
|||
background: $mColor; |
|||
@include flcw(32upx, 112upx, #fff, 500); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,271 @@ |
|||
<template> |
|||
<view class="lt-setting"> |
|||
<view class="ll-title">{{ optionsQuery.hardware_name || '-' }}</view> |
|||
|
|||
<view class="ls-container"> |
|||
<view class="lc-select"> |
|||
<view class="lc-name">指令</view> |
|||
<view class="ls-options"> |
|||
<view class="lp-item" @click="condition.instruct = 'open'"> |
|||
<view class="li-txt">开</view> |
|||
<image |
|||
class="li-icon" |
|||
mode="aspectFit" |
|||
:class="{active: condition.instruct === 'open'}" |
|||
:src="condition.instruct === 'open' ? '/subpackage/device/static/images/selected_987.png' : ''" |
|||
></image> |
|||
</view> |
|||
<view class="lp-item" @click="condition.instruct = 'close'"> |
|||
<view class="li-txt">关</view> |
|||
<image |
|||
class="li-icon" |
|||
mode="aspectFit" |
|||
:class="{active: condition.instruct === 'close'}" |
|||
:src="condition.instruct === 'close' ? '/subpackage/device/static/images/selected_987.png' : ''" |
|||
></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="lc-picker"> |
|||
<view class="lc-name">时间点</view> |
|||
<picker mode="time" @change="condition.time = $event.detail.value"> |
|||
<view class="lp-box"> |
|||
<input disabled type="text" class="lb-ipt" v-model="condition.time"> |
|||
<image class="lb-icon" mode="aspectFit" src="/subpackage/device/static/images/arrow_b2.png"></image> |
|||
</view> |
|||
</picker> |
|||
</view> |
|||
<view class="lc-switch"> |
|||
<view class="lc-name">日期</view> |
|||
<view class="ls-right"> |
|||
<switch class="lr-switch" color="#009874" @change="switchChange"></switch> |
|||
<view class="lr-txt">全选</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="lc-week-ls"> |
|||
<view |
|||
class="lwl-item" |
|||
v-for="(e, i) in weeks" |
|||
:key="i" |
|||
:class="{active: condition.weekLs.includes(e)}" |
|||
@click="weekItemClick(e)" |
|||
>{{ e }}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="ll-fixed-space"></view> |
|||
<view class="ll-fixed"> |
|||
<view class="lf-btn" @click="confirmBtn">添加定时任务</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import deviceServer from '../../js/device_server'; |
|||
import deviceApi from '../../js/device_api'; |
|||
import { showModal, showNone, showLoad, hideLoad, routeTo, jsonPar } from "@/utils/util"; |
|||
export default { |
|||
data(){ |
|||
return { |
|||
weeks: [ '日', '一', '二', '三', '四', '五', '六' ].map(e=>`星期${e}`), |
|||
condition: { |
|||
instruct: 'open', // 指令 open: 开, close: 关 |
|||
time: '00:00', // 时间点 |
|||
weekLs: [], // 日期 |
|||
}, |
|||
optionsQuery: {} |
|||
} |
|||
}, |
|||
onLoad(options){ |
|||
options.hardware_name = jsonPar(options?.hardware_name); |
|||
this.optionsQuery = options || {} |
|||
}, |
|||
methods: { |
|||
switchChange(e){ |
|||
if(e.detail.value){ |
|||
this.condition.weekLs = [ ...this.weeks]; |
|||
}else{ |
|||
this.condition.weekLs = []; |
|||
} |
|||
}, |
|||
weekItemClick(e){ |
|||
let { weekLs } = this.condition; |
|||
if(weekLs.includes(e)){ |
|||
weekLs.splice(weekLs.indexOf(e), 1); |
|||
}else{ |
|||
weekLs.push(e); |
|||
} |
|||
}, |
|||
confirmBtn(){ |
|||
let { optionsQuery, condition } = this; |
|||
if(!condition?.weekLs?.length)return showNone('请选择日期!'); |
|||
if(!condition?.time)return showNone('请选时间点!'); |
|||
this.cacScheduledTaskSave({ |
|||
hardware_id: optionsQuery?.hardware_id || '', |
|||
day_of_week: condition?.weekLs?.join(','), |
|||
h_m_s: `${condition?.time}:00`, |
|||
operate: condition?.instruct, |
|||
|
|||
}) |
|||
}, |
|||
cacScheduledTaskSave({ |
|||
hardware_id = '', |
|||
day_of_week = '', |
|||
h_m_s = '', |
|||
operate = '' |
|||
}){ |
|||
showLoad(); |
|||
return deviceServer.post({ |
|||
url: deviceApi.cacScheduledTaskSave, |
|||
data: { hardware_id, day_of_week, h_m_s, operate }, |
|||
isDefaultGet: false, |
|||
}) |
|||
.then(res => { |
|||
hideLoad(); |
|||
let _data = res?.data || {}; |
|||
if(_data.code === 0){ |
|||
showModal({ |
|||
title: '提示', |
|||
content: _data.message || '操作成功!', |
|||
}) |
|||
}else{ |
|||
return Promise.reject(_data); |
|||
} |
|||
|
|||
}) |
|||
.catch(err => { |
|||
hideLoad(); |
|||
showModal({ |
|||
title: '提示', |
|||
content: err.message || '操作失败!' |
|||
}) |
|||
console.warn('setting cacScheduledTaskSave err', err); |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.ll-title{ |
|||
padding: 46upx 40upx 60upx; |
|||
@include flcw(44upx, 60upx, #1a1a1a, 500); |
|||
@include tHide; |
|||
} |
|||
.ls-container{ |
|||
margin: 0 auto; |
|||
padding: 50upx 30upx 100upx; |
|||
width: 678upx; |
|||
border-radius: 10upx; |
|||
background: #fff; |
|||
.lc-name{ |
|||
flex-shrink: 0; |
|||
@include flcw(32upx, 44upx, #1a1a1a); |
|||
} |
|||
.lc-select{ |
|||
@include ctf(space-between); |
|||
.ls-options{ |
|||
width: 480upx; |
|||
@include ctf; |
|||
.lp-item{ |
|||
width: 50%; |
|||
@include ctf; |
|||
.li-txt{ |
|||
@include flcw(32upx, 44upx, #1a1a1a); |
|||
} |
|||
.li-icon{ |
|||
margin-left: 22upx; |
|||
flex-shrink: 0; |
|||
width: 40upx; |
|||
height: 40upx; |
|||
border: 2upx solid #D8D8D8; |
|||
border-radius: 50%; |
|||
&.active{ |
|||
border-width: 0upx; |
|||
border-color: transparent; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
.lc-picker{ |
|||
margin-top: 50upx; |
|||
@include ctf(space-between); |
|||
.lp-box{ |
|||
@include ctf(space-between); |
|||
width: 480upx; |
|||
height: 96upx; |
|||
border: 2upx solid #D8D8D8; |
|||
border-radius: 10upx; |
|||
padding: 0 20upx; |
|||
.lb-ipt{ |
|||
flex-grow: 1; |
|||
@include flcw(32upx, 44upx, #1a1a1a); |
|||
} |
|||
.lb-icon{ |
|||
flex-shrink: 0; |
|||
width: 28upx; |
|||
height: 28upx; |
|||
transform: rotateZ(90deg); |
|||
} |
|||
} |
|||
} |
|||
.lc-switch{ |
|||
margin-top: 50upx; |
|||
@include ctf(space-between); |
|||
.ls-right{ |
|||
width: 480upx; |
|||
@include ctf; |
|||
.lr-switch{ |
|||
transform: scale(.8); |
|||
} |
|||
.lr-txt{ |
|||
margin-left: 20upx; |
|||
@include flcw(32upx, 44upx, #1a1a1a); |
|||
} |
|||
} |
|||
} |
|||
.lc-week-ls{ |
|||
margin-top: 60upx; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
.lwl-item{ |
|||
margin: 0 20upx; |
|||
width: 160upx; |
|||
height: 88upx; |
|||
border-radius: 6upx; |
|||
border: 2upx solid #979797; |
|||
text-align: center; |
|||
@include flcw(32upx, 84upx, #979797); |
|||
&:nth-child(n + 4){ |
|||
margin-top: 40upx; |
|||
} |
|||
&.active{ |
|||
color: $mColor; |
|||
border-color: $mColor; |
|||
background: rgba($color: $mColor, $alpha: .12); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
.ll-fixed-space{ |
|||
padding-bottom: 132upx; |
|||
@include isPd(132upx); |
|||
} |
|||
.ll-fixed{ |
|||
position: fixed; |
|||
bottom: 0; |
|||
padding: 10upx 24upx; |
|||
width: 100%; |
|||
@include isPd(10upx); |
|||
.lf-btn{ |
|||
text-align: center; |
|||
border-radius: 10upx; |
|||
background: $mColor; |
|||
@include flcw(32upx, 112upx, #fff, 500); |
|||
} |
|||
} |
|||
</style> |
After Width: 36 | Height: 36 | Size: 365 B |
@ -0,0 +1,41 @@ |
|||
<template> |
|||
<view class="bottom-logo" :class="{ 'fixed-active': isFixed }" @click="toWebView"> |
|||
<image @click="toWebView" class="bl-img" mode="aspectFit" src="/subpackage/menu/static/images/bot_logo.png"></image> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { routeTo, jsonStr } from '@/utils/util.js' |
|||
export default { |
|||
props: { |
|||
isFixed: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
methods: { |
|||
toWebView(){ |
|||
routeTo(`/pages/web_view/web_view?src=${jsonStr('https://www.ouxuanzhineng.cn/')}`, 'nT'); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.bottom-logo{ |
|||
height: 200upx; |
|||
width: 100%; |
|||
@include ctf(center); |
|||
&.fixed-active{ |
|||
position: fixed; |
|||
left: 50%; |
|||
bottom: 0; |
|||
transform: translateX(-50%); |
|||
z-index: -1; |
|||
} |
|||
} |
|||
.bl-img{ |
|||
width: 312upx; |
|||
height: 100upx; |
|||
} |
|||
</style> |
@ -0,0 +1,87 @@ |
|||
<template> |
|||
<view class="mine-header"> |
|||
<view class="mh-user"> |
|||
<image class="mu-photo" mode="aspectFill" :src="photo"></image> |
|||
<view class="mu-info" v-if="isLogin"> |
|||
<view class="mi-line">昵称:{{ nickname || '-' }}</view> |
|||
<view class="mi-line">姓名:{{ name || '-' }}</view> |
|||
<view class="mi-line">账号:{{ account || '-' }}</view> |
|||
</view> |
|||
<button v-else class="mu-login" @click="$emit('click:login')">点击登录</button> |
|||
</view> |
|||
<view class="mh-update" v-if="isLogin" @click="$emit('click:update')">更新头像昵称</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
isLogin: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
nickname: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
name: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
account: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
photo: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
mounted(){ |
|||
console.log('mounted'); |
|||
this.$emit('on:munted'); |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.mine-header{ |
|||
padding-top: 70upx; |
|||
height: 270upx; |
|||
background: $mColor; |
|||
.mh-user{ |
|||
padding-left: 68upx; |
|||
padding-right: 30upx; |
|||
@include ctf; |
|||
.mu-photo{ |
|||
flex-shrink: 0; |
|||
margin-right: 28upx; |
|||
width: 120upx; |
|||
height: 120upx; |
|||
border-radius: 50%; |
|||
border: 4upx solid #FFFFFF; |
|||
} |
|||
.mu-info{ |
|||
.mi-line{ |
|||
@include flcw(32upx, 44upx, #FFFFFF); |
|||
@include tHide; |
|||
} |
|||
} |
|||
.mu-login{ |
|||
@include clearBtn; |
|||
width: 180upx; |
|||
height: 72upx; |
|||
text-align: center; |
|||
border-radius: 6upx; |
|||
background: #fff; |
|||
@include flcw(32upx, 72upx, $mColor, 500); |
|||
} |
|||
} |
|||
.mh-update{ |
|||
padding-left: 68upx; |
|||
margin-top: 8upx; |
|||
text-decoration: underline; |
|||
@include flcw(20upx, 28upx, #FFFFFF); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,63 @@ |
|||
<template> |
|||
<view class="line-tab" @click="$emit('click')"> |
|||
<image class="lt-icon" mode="aspectFit" :src="'/subpackage/menu/static/images/mine_tab/' + iconNum + '.png'"></image> |
|||
<view class="lt-right"> |
|||
<view class="lr-left"> |
|||
<view class="lr-name"> |
|||
<slot name="default">账号管理</slot> |
|||
</view> |
|||
</view> |
|||
<view class="lr-right"> |
|||
<slot name="right"> |
|||
<image class="lr-arrow" mode="aspectFit" src="/subpackage/menu/static/images/arrow_b2.png"></image> |
|||
</slot> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
iconNum: { |
|||
type: Number, |
|||
default: 0 |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.line-tab{ |
|||
padding-left: 22upx; |
|||
padding-right: 44upx; |
|||
height: 108upx; |
|||
background: #fff; |
|||
@include ctf; |
|||
.lt-icon{ |
|||
flex-shrink: 0; |
|||
margin-right: 22upx; |
|||
width: 48upx; |
|||
height: 48upx; |
|||
} |
|||
.lt-right{ |
|||
flex-grow: 1; |
|||
@include ctf(space-between); |
|||
.lr-left{ |
|||
.lr-name{ |
|||
@include flcw(32upx, 48upx, #9A9A9D); |
|||
@include tHide; |
|||
} |
|||
} |
|||
.lr-right{ |
|||
flex-shrink: 0; |
|||
max-width: 60%; |
|||
font-size: 0; |
|||
.lr-arrow{ |
|||
width: 30upx; |
|||
height: 30upx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,16 @@ |
|||
<template> |
|||
<!-- 需要定义一个页面以及在pagesjson里声明才能生成static文件夹 --> |
|||
<view class="menu-index"> </view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
page{ |
|||
background: #fff; |
|||
} |
|||
</style> |
After Width: 15 | Height: 15 | Size: 226 B |
After Width: 312 | Height: 100 | Size: 3.4 KiB |
After Width: 96 | Height: 96 | Size: 1.3 KiB |
After Width: 96 | Height: 96 | Size: 1.5 KiB |
After Width: 96 | Height: 96 | Size: 1.0 KiB |
After Width: 96 | Height: 96 | Size: 1.4 KiB |
After Width: 96 | Height: 96 | Size: 1.0 KiB |
After Width: 96 | Height: 96 | Size: 942 B |
After Width: 96 | Height: 96 | Size: 640 B |
@ -0,0 +1,59 @@ |
|||
<template> |
|||
<view class="answer-item" :class="{ 'active-bg': activeBg }"> |
|||
<view class="ai-user"> |
|||
<view class="au-name">{{ name || '-' }}</view> |
|||
<view class="au-time">[回复] {{ time || '-' }}</view> |
|||
</view> |
|||
<view class="ai-content">{{ content || '-' }}</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
name: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
time: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
content: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
activeBg: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.answer-item{ |
|||
padding: 30upx 22upx; |
|||
background: #fff; |
|||
border-radius: 10upx; |
|||
&.active-bg{ |
|||
background: #faeada; |
|||
} |
|||
} |
|||
.ai-user{ |
|||
@include ctf; |
|||
@include flcw(32upx, 44upx, #1A1A1A); |
|||
.au-name{ |
|||
@include tHide; |
|||
} |
|||
.au-time{ |
|||
flex-shrink: 0; |
|||
color: #9C9C9F; |
|||
} |
|||
} |
|||
.ai-content{ |
|||
padding-left: 26upx; |
|||
margin-top: 24upx; |
|||
@include flcw(28upx, 40upx, #9C9C9F); |
|||
} |
|||
</style> |