Browse Source

Merge branch 'dev' of https://git.ouxuan.net/APP/ox_zhiNengZhuShou into dev

organize
zmt 3 years ago
parent
commit
33b555a9d7
  1. 10
      src/js/api.js
  2. 8
      src/js/once_name.js
  3. 30
      src/pages.json
  4. 25
      src/pages/employee/manage/manage.vue
  5. 4
      src/pages/employee/review_list/review_list.vue
  6. 2
      src/pages/index/index.vue
  7. 480
      src/pages/site/manage/manage.vue
  8. 284
      src/pages/write_off/mall/confirm/confirm.vue
  9. 237
      src/pages/write_off/mall/list/list.vue
  10. 150
      src/pages/write_off/mall/success/success.vue
  11. 108
      src/pages/write_off/menu/menu.vue
  12. 362
      src/pages/write_off/number_of_people/number_of_people.vue
  13. 113
      src/pages/write_off/operate/operate.vue
  14. 4
      src/pages/write_off/search_result/search_result.vue
  15. BIN
      src/static/images/countdown_bg.png
  16. BIN
      src/static/images/icon/choose.png
  17. BIN
      src/static/images/write_off/mall.png
  18. BIN
      src/static/images/write_off/order.png
  19. BIN
      src/static/images/write_off/people.png
  20. BIN
      src/static/images/write_off/site.png
  21. 24
      src/store/index.js
  22. 3
      src/subpackage/device/components/order/reservation_site_detail/reservation_site_detail.vue
  23. 7
      src/subpackage/device/pages/switch_manage/switch_manage.vue

10
src/js/api.js

@ -3,7 +3,6 @@ export const ORIGIN = `https://testmanager.ouxuanzhineng.cn`; // 测试
// export const ORIGIN = `http://192.168.1.135:9090`; // 20210927 测试 // export const ORIGIN = `http://192.168.1.135:9090`; // 20210927 测试
export const API = { export const API = {
wechatMiniAppLoginAndSync: `${ORIGIN}/assistant/WechatMiniAppGetToken`, // 小程序授权获取token,为空就登录 wechatMiniAppLoginAndSync: `${ORIGIN}/assistant/WechatMiniAppGetToken`, // 小程序授权获取token,为空就登录
WechatMiniApplogin: `${ORIGIN}/assistant/WechatMiniApplogin`, // 小程序登录获取token WechatMiniApplogin: `${ORIGIN}/assistant/WechatMiniApplogin`, // 小程序登录获取token
@ -102,6 +101,15 @@ API['writeOff'] = {
assistantVerify: `${ORIGIN}/admin/stadium/order/assistantVerify`, // 商家助手-核销查询-核销 assistantVerify: `${ORIGIN}/admin/stadium/order/assistantVerify`, // 商家助手-核销查询-核销
userMonthlyCardVerify: `${ORIGIN}/admin/userMonthlyCard/verify`, // 年月卡核销-后台 userMonthlyCardVerify: `${ORIGIN}/admin/userMonthlyCard/verify`, // 年月卡核销-后台
userMonthlyCardOpenGate: `${ORIGIN}/admin/userMonthlyCard/openGate`, // 年月卡开门-后台 userMonthlyCardOpenGate: `${ORIGIN}/admin/userMonthlyCard/openGate`, // 年月卡开门-后台
// 20211228 新增商城核销
shop2WriteoffList: `${ORIGIN}/admin/assistant/shop2/writeoffList`, // 商城订单核销 - 列表
shop2WriteoffGet: `${ORIGIN}/admin/assistant/shop2/writeoffGet`, // 商城订单核销 - 获取订单信息
shop2WriteoffSet: `${ORIGIN}/admin/assistant/shop2/writeoffSet`, // 商城订单核销 - 确认核销
timingNumber: `${ORIGIN}/stadium/person/timing/number`, // 现场人数
setStadiumPresentNumber: `${ORIGIN}/admin/stadium/setStadiumPresentNumber`, // 商家助手散客人数校正
} }
export default { ORIGIN, API }; export default { ORIGIN, API };

8
src/js/once_name.js

@ -4,9 +4,15 @@
export const WRITE_OFF_STORE_INFO = 'stadium_list'; export const WRITE_OFF_STORE_INFO = 'stadium_list';
export const WRITE_OFF_ORDER_INFO = 'order_info'; export const WRITE_OFF_ORDER_INFO = 'order_info';
export const WRITE_OFF_YM_ORDER_INFO = 'ym_order_info'; // 年月卡订单核销 export const WRITE_OFF_YM_ORDER_INFO = 'ym_order_info'; // 年月卡订单核销
export const WRITE_OFF_MALL_ORDER_INFO = 'mall_order_info'; // 商城订单核销
export const WRITE_OFF_MALL_ORDER_SUCCESS = 'mall_order_success'; // 商城订单核销成功!
export default { export default {
WRITE_OFF_STORE_INFO, WRITE_OFF_STORE_INFO,
WRITE_OFF_ORDER_INFO, WRITE_OFF_ORDER_INFO,
WRITE_OFF_YM_ORDER_INFO
WRITE_OFF_YM_ORDER_INFO,
WRITE_OFF_MALL_ORDER_INFO,
WRITE_OFF_MALL_ORDER_SUCCESS
} }

30
src/pages.json

@ -134,6 +134,36 @@
} }
}, },
{ {
"path": "pages/write_off/mall/success/success",
"style": {
"navigationBarTitleText": "核销订单"
}
},
{
"path": "pages/write_off/mall/confirm/confirm",
"style": {
"navigationBarTitleText": "核销订单"
}
},
{
"path": "pages/write_off/mall/list/list",
"style": {
"navigationBarTitleText": "商城订单核销"
}
},
{
"path": "pages/write_off/number_of_people/number_of_people",
"style": {
"navigationBarTitleText": "查询"
}
},
{
"path": "pages/write_off/menu/menu",
"style": {
"navigationBarTitleText": "核销订单"
}
},
{
"path": "pages/write_off/ym_card_gated/ym_card_gated", "path": "pages/write_off/ym_card_gated/ym_card_gated",
"style": { "style": {
"navigationBarTitleText": "核销订单" "navigationBarTitleText": "核销订单"

25
src/pages/employee/manage/manage.vue

@ -59,8 +59,19 @@
<view class="ei-author"> <view class="ei-author">
<view>权限</view> <view>权限</view>
<view> <view>
<view class="tag-active" v-if="k.extension.permission.menu.length == permissionArr.length">全部权限</view>
<view v-else v-for="e in k.extension.permission.menu" :key="e">{{permissionObj[e] || ''}}</view>
<view
class="tag-active"
v-if="isAllAuthor({
adminLs: k.extension.permission.menu,
localLs: permissionArr,
})"
>全部权限</view>
<block v-else >
<block v-for="e in k.extension.permission.menu" :key="e">
<view v-if="!!permissionObj[e]">{{permissionObj[e] || ''}}</view>
</block>
</block>
</view> </view>
</view> </view>
</view> </view>
@ -114,11 +125,21 @@ export default {
} }
}, },
onLoad(){ onLoad(){
}, },
onShow(){ onShow(){
this.refreshEmployList(); this.refreshEmployList();
}, },
methods: { methods: {
//
isAllAuthor({
adminLs = [],
localLs = []
}){
if(!localLs || !adminLs || !adminLs.length || !localLs.length)return false;
let _unAuthorLs = localLs.filter(ele=>!adminLs.includes(+ele.key))
return !_unAuthorLs.length
},
// //
employeeDelete: util.debounce(function(){ employeeDelete: util.debounce(function(){
let _employeeList = this.employeeInfo.employee || []; let _employeeList = this.employeeInfo.employee || [];

4
src/pages/employee/review_list/review_list.vue

@ -4,13 +4,13 @@
<view>审核 {{reviewInfo.total || 0}} </view> <view>审核 {{reviewInfo.total || 0}} </view>
<view @click="selectAll"> <view @click="selectAll">
<text>全选</text> <text>全选</text>
<image :class="[isAllSelected?'img-active':'']" mode="aspectFit" :src="isAllSelected?'/static/images/icon/selected_987.png':''"></image>
<image :class="[isAllSelected?'img-active':'']" mode="aspectFit" :src="isAllSelected?'/static/images/icon/choose.png':''"></image>
</view> </view>
</view> </view>
<view class="rl-users"> <view class="rl-users">
<view class="ru-item" v-for="(e,i) in reviewInfo.list" :key="i"> <view class="ru-item" v-for="(e,i) in reviewInfo.list" :key="i">
<view> <view>
<image @click="userSelect(i)" :class="['ri-icon',e.isSelected?'active':'']" mode="aspectFit" :src="e.isSelected?'/static/images/icon/selected_987.png':''"></image>
<image @click="userSelect(i)" :class="['ri-icon',e.isSelected?'active':'']" mode="aspectFit" :src="e.isSelected?'/static/images/icon/choose.png':''"></image>
<image class="ri-avatar" mode="apsectFill" :src="e.avatar_url || ''" @click="toSingleReview(e)"></image> <image class="ri-avatar" mode="apsectFill" :src="e.avatar_url || ''" @click="toSingleReview(e)"></image>
<view @click="toSingleReview(e)">{{e.actual_name || '-'}}</view> <view @click="toSingleReview(e)">{{e.actual_name || '-'}}</view>
</view> </view>

2
src/pages/index/index.vue

@ -104,7 +104,7 @@
{ {
id: 4, id: 4,
name: '核销查询', name: '核销查询',
path: '/pages/write_off/search_result/search_result',
path: '/pages/write_off/menu/menu',
serverKey: 1008 // serverKey: 1008 //
}, },
{ {

480
src/pages/site/manage/manage.vue

@ -1,81 +1,100 @@
<template> <template>
<view class="site-manage"> <view class="site-manage">
<view class="sm-header">
<picker mode="selector" :range="storeList" range-key="name" @change="storePickerChange">
<view class="sh-address">
<text>{{curStoreInfo.name || '-'}}</text>
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image>
</view>
</picker>
<view class="sh-type">
<picker mode="selector" :range="typeList" range-key="name" @change="typePckerChange">
<view class="st-type">
<text>{{curTypeInfo.name || '-'}}</text>
<view class="sm-sticky-box">
<view class="sm-header">
<picker mode="selector" :range="storeList" range-key="name" @change="storePickerChange">
<view class="sh-address">
<text>{{curStoreInfo.name || '-'}}</text>
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image> <image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image>
</view> </view>
</picker> </picker>
<view class="st-tip">{{curTypeInfo.rule_text || '-'}}</view>
</view>
<view class="sh-date" v-if="dateList.length">
<picker
mode="date"
:value="dateList[0].dateStr"
data-type='start'
@change="datePickerChange">
<view class="sd-box">
<text>{{ dateList[0].ZhDateStr || '-' }}</text>
<view></view>
</view>
</picker>
<text></text>
<picker
mode="date"
:value="dateList[dateList.length - 1].dateStr"
data-type="end"
@change="datePickerChange">
<view class="sd-box">
<text>{{ dateList[dateList.length - 1].ZhDateStr || '-' }}</text>
<view></view>
<view class="sh-type">
<picker mode="selector" :range="typeList" range-key="name" @change="typePckerChange">
<view class="st-type">
<text>{{curTypeInfo.name || '-'}}</text>
<image mode="aspectFit" src="/static/images/icon/arrow_c33.png"></image>
</view>
</picker>
<view class="st-tip">{{curTypeInfo.rule_text || '-'}}</view>
</view>
<view class="sh-date" v-if="dateList.length">
<picker
mode="date"
:value="dateList[0].dateStr"
data-type='start'
@change="datePickerChange">
<view class="sd-box">
<text>{{ dateList[0].ZhDateStr || '-' }}</text>
<view></view>
</view>
</picker>
<text></text>
<picker
mode="date"
:value="dateList[dateList.length - 1].dateStr"
data-type="end"
@change="datePickerChange">
<view class="sd-box">
<text>{{ dateList[dateList.length - 1].ZhDateStr || '-' }}</text>
<view></view>
</view>
</picker>
</view>
<picker mode="date" @change="timeSlotChange" v-if="false">
<view class="sh-time" v-if="dateList.length>1">
<text>{{dateList[0].ZhDateStr || '-'}} {{dateList[dateList.length-1].ZhDateStr || '-'}}</text>
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
</view> </view>
</picker> </picker>
</view> </view>
<picker mode="date" @change="timeSlotChange" v-if="false">
<view class="sh-time" v-if="dateList.length>1">
<text>{{dateList[0].ZhDateStr || '-'}} {{dateList[dateList.length-1].ZhDateStr || '-'}}</text>
<image mode="aspectFit" src="/static/images/icon/arrow_b2.png"></image>
<scroll-view class="sm-times" scroll-x>
<view
v-for="(e,i) in dateList"
:key="i"
:class="['st-item', curDateInfo.dateStr===e.dateStr?'active':'']"
@click="dateChange(e)"
>
<view class="si-txt">
<view>{{e.dayStr || '-'}}</view>
<view>{{e.showDateStr || '-'}}</view>
</view>
</view> </view>
</picker>
</scroll-view>
</view> </view>
<scroll-view class="sm-times" scroll-x>
<view
v-for="(e,i) in dateList"
:key="i"
:class="['st-item', curDateInfo.dateStr===e.dateStr?'active':'']"
@click="dateChange(e)"
>
<view class="si-txt">
<view>{{e.dayStr || '-'}}</view>
<view>{{e.showDateStr || '-'}}</view>
</view>
</view>
</scroll-view>
<view class="sm-venue"> <view class="sm-venue">
<view class="sv-time-interval">
<!-- <view class="sv-time-interval">
<view class="sti-item" v-for="(e,i) in venueTimeList" :key="i"> <view class="sti-item" v-for="(e,i) in venueTimeList" :key="i">
<view>{{ e || '-' }}</view> <view>{{ e || '-' }}</view>
</view> </view>
</view>
<scroll-view class="sti-venue-list" enable-flex scroll-x :style="venueAreaSize">
<view class="svl-list" v-for="(e, i) in venueList" :key="i">
<view class="sl-item">{{e.venue_name || '-'}}</view>
<view class="sl-item" v-for="(k,j) in e.items" :key="j" @click="venueSelect(i,j)">
<view
:class="[ k._isSelect? 'cyan' : '', getVenueStatusnInfo(k).className ]"
>
{{ getVenueStatusnInfo(k).zh_text || '-' }}
</view> -->
<scroll-view class="sti-venue-list" enable-flex scroll-x scroll-y enhanced :bounces="false" :style="venueAreaSize">
<view class="svl-box">
<view class="sticky-cover"></view>
<view class="sl-time-ls">
<view class="sti-item" v-for="(e,i) in venueTimeList" :key="i">
<view>{{ e || '-' }}</view>
</view>
</view>
<view class="sl-name-ls">
<view class="snl-item" v-for="(e, i) in venueList" :key="i">{{e.venue_name || '-'}}</view>
</view>
<view class="sl-vanue-ls">
<view class="svl-list" v-for="(e, i) in venueList" :key="i">
<!-- <view class="sl-item">{{e.venue_name || '-'}}</view> -->
<view class="sl-item" v-for="(k,j) in e.items" :key="j" @click="venueSelect(i,j)">
<view
:class="[ k._isSelect? 'cyan' : '', getVenueStatusnInfo(k).className ]"
>
{{ getVenueStatusnInfo(k).zh_text || '-' }}
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
<view class="sm-fixd-bot"> <view class="sm-fixd-bot">
@ -209,6 +228,8 @@ export default {
getVenueStatusnInfo(info){ getVenueStatusnInfo(info){
// //
if(info.overdue&&info.type == 'empty_venue')return { zh_text: info.message || info.price, type: 'overdue', className: 'gray', } if(info.overdue&&info.type == 'empty_venue')return { zh_text: info.message || info.price, type: 'overdue', className: 'gray', }
// isLinkage
if(info.isLinkage&&info.isLinkage == true)return { zh_text: info.message || info.price || 0, type: 'linkage', className: 'gray', }
switch(info.type){ switch(info.type){
case 'no_price_venue': case 'no_price_venue':
return { zh_text: info.message || '无法订场', type: info.type, className: 'grey', } return { zh_text: info.message || '无法订场', type: info.type, className: 'grey', }
@ -273,12 +294,13 @@ export default {
this.venueList = []; this.venueList = [];
this.boardInfo = null; this.boardInfo = null;
this.selectedVenueList = []; this.selectedVenueList = [];
this.$nextTick(_ => this.setVenueAreaSize());
let _res = await this.getVenueList({ let _res = await this.getVenueList({
type_key: curTypeInfo.key || '', type_key: curTypeInfo.key || '',
stadium_id: curStoreInfo.id || '', stadium_id: curStoreInfo.id || '',
date: curDateInfo.dateStr || '', date: curDateInfo.dateStr || '',
}) })
let _list = _res.dashboard || [];
let _list = _res || [];
if(!_list.length)return util.showNone('没有场地信息!'); if(!_list.length)return util.showNone('没有场地信息!');
this.venueList = _list || []; this.venueList = _list || [];
@ -296,6 +318,7 @@ export default {
// //
clearSelectedList(){ clearSelectedList(){
this.refreshVenues(); this.refreshVenues();
// this.$nextTick(_=>this.getSelectedVenues()); // this.$nextTick(_=>this.getSelectedVenues());
}, },
// //
@ -329,7 +352,9 @@ export default {
venueInfo: {...this.getVenueStatusnInfo(_curTarget)}, venueInfo: {...this.getVenueStatusnInfo(_curTarget)},
} }
} }
if(_curTarget.type !== 'empty_venue')return; if(_curTarget.type !== 'empty_venue')return;
if(_curTarget.isLinkage == true)return;
_venueList[i].items[j]._isSelect = !_curTarget._isSelect; _venueList[i].items[j]._isSelect = !_curTarget._isSelect;
@ -352,7 +377,15 @@ export default {
// }) || []; // }) || [];
// -----> // ----->
//
_venueList = this.checkLinkageVenue({
group: i,
venueList: _venueList,
selectedKey: '_isSelect',
linkageKey: 'isLinkage',
linkageIDArrKey: 'link_venue_ids',
linkageIDKey: 'venue_id',
})
this.venueList = _venueList; this.venueList = _venueList;
this.$nextTick(_=>{ this.$nextTick(_=>{
// if(_ctnList.length>1){ // if(_ctnList.length>1){
@ -363,6 +396,76 @@ export default {
this.getSelectedVenues(); this.getSelectedVenues();
}) })
}, },
// &
// checkLinkageVenue({
// group = 0, //
// venueList = [], //
// selectedKey = 'selectedKey', // key
// linkageKey = 'linkageKey', // key
// linkageIDArrKey = 'link_venue_ids',
// linkageIDKey = 'venue_id',
// curTag
// }){
// let _curGroupInfo = {...venueList[group]};
// for(let i=0; i<venueList.length; i++){
// let _link_venue_ids = _curGroupInfo[linkageIDArrKey] || [];
// if(_link_venue_ids.includes(venueList[i][linkageIDKey])){
// _curGroupInfo.items.forEach(ele=>{
// //
// if(venueList[i].link_venue_ids && venueList[i].link_venue_ids.length == 1){
// venueList[i].items[ele._defineIndex][linkageKey] = !!_curGroupInfo.items[ele._defineIndex][selectedKey];
// }
// //
// if(venueList[i].link_venue_ids && venueList[i].link_venue_ids.length > 1){
// let _link_venueLs = venueList.filter(item=> venueList[i].link_venue_ids.includes(item[linkageIDKey]));
// // ex: [ true, false ];
// let _link_venueLs_selectedLs = _link_venueLs.map(el=> el['items'][ele._defineIndex] && el['items'][ele._defineIndex][selectedKey]);
// venueList[i].items[ele._defineIndex][linkageKey] = _link_venueLs_selectedLs.includes(true); //
// }
// });
// }
// }
// return venueList || [];
// },
// &
checkLinkageVenue({
group = 0, //
venueList = [], //
selectedKey = 'selectedKey', // key
linkageKey = 'linkageKey', // key
linkageIDArrKey = 'link_venue_ids', //
linkageIDKey = 'venue_id', // id
curTag
}){
let _curGroupInfo = {...venueList[group]};
for(let i=0; i<venueList.length; i++){
let _link_venue_ids = _curGroupInfo[linkageIDArrKey] || [];
// id
_link_venue_ids = _link_venue_ids.filter(ele=>_curGroupInfo[linkageIDKey] !=ele);
if(_link_venue_ids.includes(venueList[i][linkageIDKey])){
_curGroupInfo.items.forEach(ele=>{
//
if(venueList[i].link_venue_ids && venueList[i].link_venue_ids.length == 1){
venueList[i].items[ele._defineIndex][linkageKey] = !!_curGroupInfo.items[ele._defineIndex][selectedKey];
}
//
if(venueList[i].link_venue_ids && venueList[i].link_venue_ids.length > 1){
// id bug
let _linkVenueIds = venueList[i].link_venue_ids.filter(e=>e !=venueList[i][linkageIDKey]);
//
let _link_venueLs = venueList.filter(item=> _linkVenueIds.includes(item[linkageIDKey]));
// ex: [ true, false ];
let _link_venueLs_selectedLs = _link_venueLs.map(el=> el['items'][ele._defineIndex] && el['items'][ele._defineIndex][selectedKey]);
venueList[i].items[ele._defineIndex][linkageKey] = _link_venueLs_selectedLs.includes(true); //
}
});
}
}
return venueList || [];
},
// //
getSelectedVenues(){ getSelectedVenues(){
let { venueList } = this; let { venueList } = this;
@ -379,6 +482,7 @@ export default {
}) })
this.totalPrice = _totalPrice.toFixed(2); this.totalPrice = _totalPrice.toFixed(2);
this.selectedVenueList = _arr || []; this.selectedVenueList = _arr || [];
this.$nextTick(_ => this.setVenueAreaSize());
return _arr; return _arr;
}, },
// tab // tab
@ -449,7 +553,15 @@ export default {
return servers.get({ return servers.get({
url: API.venue.venueList, url: API.venue.venueList,
data: { stadium_id, type_key, date }, data: { stadium_id, type_key, date },
failMsg: '加载分类失败!'
failMsg: '加载场地列表失败!'
})
.then(res=>{
let _ls = res.dashboard || [];
_ls.map(ele => ele.items.map((item, index) =>{
item._defineIndex = index;
return item;
}))
return _ls;
}) })
}, },
// //
@ -469,12 +581,21 @@ export default {
}) })
}, },
// //
setVenueAreaSize(){
const sysInfo = uni.getSystemInfoSync();
util.getNodeMes('.sv-time-interval')
.then(res=>{
this.venueAreaSize = `width:${sysInfo.screenWidth - res.width}px;height:${res.height}px;`
})
async setVenueAreaSize(){
let _fixedBotInfo = {}, _fixedTopInfo = {};
const _sysInfo = uni.getSystemInfoSync() || {};
try{
_fixedTopInfo = await util.getNodeMes('.sm-sticky-box');
_fixedBotInfo = await util.getNodeMes('.sm-fixd-bot');
}catch(err){
console.warn('get fixed nodes info err', err);
}
let _totalHeight = ( _fixedBotInfo.height || 0 ) + ( _fixedTopInfo.height || 0 );
this.venueAreaSize = `width:${ _sysInfo.screenWidth || 0 }px;height:${ ( _sysInfo.windowHeight || 0 ) - _totalHeight }px;`
// util.getNodeMes('.sv-time-interval')
// .then(res=>{
// this.venueAreaSize = `width:${sysInfo.screenWidth - (res.width || 0)}px;height:${res.height || 0}px;`
// })
}, },
} }
} }
@ -486,10 +607,10 @@ export default {
background-color: #fff; background-color: #fff;
} }
.site-manage{ .site-manage{
/* 动态设置页面高度出现页面跳点,直接设置底部最大高度 ,按钮价格 + 已选滚动区域 + 连场提示*/
padding-bottom: calc( 108upx + 370upx + 60upx);
padding-bottom: calc( 108upx + 370upx + 60upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
padding-bottom: calc( 108upx + 370upx + 60upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
.sm-sticky-box{
background-color: #fff;
}
.sm-header{ .sm-header{
padding: 0 24upx; padding: 0 24upx;
.sh-address{ .sh-address{
@ -680,77 +801,170 @@ export default {
} }
} }
.sti-venue-list{ .sti-venue-list{
vertical-align: top;
display: inline-block;
// vertical-align: top;
// display: inline-block;
background-color: #f2f2f7; background-color: #f2f2f7;
text-align: left;
white-space: nowrap;
.svl-list{
display: inline-block;
width: 196upx;
.sl-item{
height: 90upx;
&:not(:first-child){
@include centerFlex(center);
>view{
padding: 0 10upx;
width: 176upx;
height: 72upx;
line-height: 68upx;
text-align: center;
border: 2upx solid $themeColor;
border-radius: 10upx;
font-size: 28upx;
color: $themeColor;
background-color: #fff;
@include textHide(1);
&.grey{
color: #9A9A9D;
border-color: #D7D7DD;
background-color: #D7D7DD;
}
&.green{
color: #FFF;
border-color: $themeColor;
background-color: $themeColor;
}
&.cyan{
background-color: rgba($color: #33CCA9, $alpha: .18);
}
&.black{
color: #FFF;
border-color: #333333;
background-color: #333333;
}
&.blue{
color: #fff;
border-color: #4F7CC7;
background-color: #4F7CC7;
}
&.pistac{
color: #fff;
background-color: #68C43B;
border-color: #68C43B;
}
&.gray{
border-color: #9A9A9D;
color: #9A9A9D;
}
}
// text-align: left;
// white-space: nowrap;
.svl-box{
width: fit-content;
height: fit-content;
.sticky-cover{
position: sticky;
left: 0;
top: 0;
width: 0upx;
height: 0upx;
z-index: 5;
&::after{
content: '';
position: absolute;
left: 0;
top: 0;
width: 110upx;
height: 60upx;
background-color: #fff;
} }
&:first-child{
}
.sl-name-ls{
position: sticky;
padding-left: 112upx;
top: 0;
width: fit-content;
white-space: nowrap;
font-size: 0;
.snl-item{
vertical-align: top;
display: inline-block;
width: 196upx;
height: 72upx; height: 72upx;
line-height: 70upx; line-height: 70upx;
text-align: center; text-align: center;
font-size: 24upx; font-size: 24upx;
font-weight: 500; font-weight: 500;
border-bottom: 2upx solid #D8D8D8; border-bottom: 2upx solid #D8D8D8;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
background-color: #fff; background-color: #fff;
color: #333; color: #333;
@include textHide(1);
}
}
.sl-time-ls{
position: sticky;
left: 0;
top: 0;
z-index: 2;
float: left;
display: inline-block;
vertical-align: top;
background-color: #fff;
.sti-item{
position: relative;
width: 112upx;
height: 90upx;
border-right: 2upx solid #d8d8d8;
>view{
position: absolute;
left: 0;
top: 50%;
padding: 0 10upx;
height: 100%;
width: 100%;
text-align: center;
line-height: 84upx;
font-size: 24upx;
color: #333;
@include textHide(1);
}
&::after{
content: '';
position: absolute;
bottom: 0;
right: 0;
width: 14upx;
height: 2upx;
background-color: #d8d8d8;
}
&:first-child,&:last-child{
&::after{
display: none;
}
}
&:first-child{
height: 72upx;
>view{
line-height: 72upx;
}
}
&:last-child>view{
background-color: #fff;
}
}
}
.sl-vanue-ls{
font-size: 0;
text-align: left;
white-space: nowrap;
.svl-list{
vertical-align: top;
display: inline-block;
width: 196upx;
.sl-item{
height: 90upx;
@include centerFlex(center);
>view{
padding: 0 10upx;
width: 176upx;
height: 72upx;
line-height: 68upx;
text-align: center;
border: 2upx solid $themeColor;
border-radius: 10upx;
font-size: 28upx;
color: $themeColor;
background-color: #fff;
@include textHide(1);
&.grey{
color: #9A9A9D;
border-color: #D7D7DD;
background-color: #D7D7DD;
}
&.green{
color: #FFF;
border-color: $themeColor;
background-color: $themeColor;
}
&.cyan{
background-color: rgba($color: #33CCA9, $alpha: .18);
}
&.black{
color: #FFF;
border-color: #333333;
background-color: #333333;
}
&.blue{
color: #fff;
border-color: #4F7CC7;
background-color: #4F7CC7;
}
&.pistac{
color: #fff;
background-color: #68C43B;
border-color: #68C43B;
}
&.gray{
border-color: #9A9A9D;
color: #9A9A9D;
}
}
}
} }
} }
} }
} }
} }
.sm-fixd-bot{ .sm-fixd-bot{
@ -761,6 +975,7 @@ export default {
padding-bottom: calc( 0upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */ padding-bottom: calc( 0upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
padding-bottom: calc( 0upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */ padding-bottom: calc( 0upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
width: 100%; width: 100%;
z-index: 5;
background-color: #fff; background-color: #fff;
.sfb-selected-section{ .sfb-selected-section{
.sss-bar{ .sss-bar{
@ -900,6 +1115,7 @@ export default {
position: fixed; position: fixed;
left: 50%; left: 50%;
top: 50%; top: 50%;
z-index: 10;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
max-width: 600upx; max-width: 600upx;
padding: 20upx 30upx; padding: 20upx 30upx;

284
src/pages/write_off/mall/confirm/confirm.vue

@ -0,0 +1,284 @@
<template>
<view class="mall-ls-confirm">
<!-- 20211228 pm 说写死 -->
<view class="mlc-status">{{ '待发货' }}</view>
<view class="mlc-main">
<view class="mm-top mm-box">
<view class="mt-line">
<view>下单时间</view>
<view>{{ orderInfo.success_time || '-' }}</view>
</view>
<view class="mt-line">
<view>订单编号</view>
<view>{{ orderInfo.order_no || '-' }}</view>
<view @click="copyBtn(orderInfo.order_no || '-')">复制</view>
</view>
</view>
<view class="mm-user-info mm-box">
<view class="mm-tit">收货人信息</view>
<view class="mui-info">
<view class="mi-line">配送方式{{ sendMethod }}</view>
<view class="mi-line">{{ pickupInfo.name || '-' }} {{ pickupInfo.phone || '-' }}</view>
<view class="mi-line">{{ pickupInfo.store_name || '-' }}</view>
<view class="mi-addr">{{ pickupInfo.store_addr || '-' }}</view>
</view>
<view class="mui-code">取货码{{ pickupInfo.gcode || '-' }}</view>
</view>
<view class="mm-goods" v-if="goodsLs.length">
<view class="mm-tit">商品信息</view>
<view class="mg-ls">
<view class="ml-item" v-for="(e, i) in goodsLs" :key="i">
<image mode="aspectFill" :src="e.product_imgs || ''"></image>
<view class="mi-info">
<view class="mi-name">{{ e.product_name || '-' }}</view>
<view class="mi-spec">
<view>{{ getSpecTxt(e) }}</view>
<view>×{{ e.product_nums || 0 }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="mlc-fixd-btn" @click="confirmBtn">确认核销</view>
</view>
</template>
<script>
import util from '../../../../utils/util';
import { API } from '../../../../js/api';
import { servers } from '../../../../js/server';
import { WRITE_OFF_MALL_ORDER_INFO, WRITE_OFF_MALL_ORDER_SUCCESS } from '../../../../js/once_name';
import { mapState } from 'vuex';
export default {
computed: {
goodsLs(){
let { orderInfo } = this;
if(!orderInfo || !orderInfo.product_order_goods || !orderInfo.product_order_goods.length)return [];
return orderInfo.product_order_goods || [];
},
setStatusTxt() {
let { orderInfo } = this;
if(!orderInfo || orderInfo.pay_status == undefined)return '-';
// 0 1 2 3 4 5 6退 7退 8退
let statusArr = ['待付款', '待发货', '待收货', '交易完成', '交易完成', '订单关闭', '退款中', '退款完成', '退款关闭'];
return statusArr[orderInfo.pay_status] || '-';
},
sendMethod(){
let { orderInfo } = this;
if(!orderInfo)return '-';
if(orderInfo.product_order_self_pickup == 1)return '自提';
if(orderInfo.product_order_self_pickup == 0)return '快递';
return '-'
},
pickupInfo(){
let { orderInfo } = this;
if(!orderInfo || !orderInfo.product_order_self_pickup_info)return {};
return orderInfo.product_order_self_pickup_info
},
},
data(){
return {
orderInfo: {
product_order_self_pickup_info: {}
}
}
},
onLoad(options){
console.warn(options)
util.$_once(WRITE_OFF_MALL_ORDER_INFO, data => {
console.warn(data)
this.orderInfo = data || { };
})
},
methods: {
confirmBtn: util.debounce(function(){
let { orderInfo, pickupInfo } = this;
util.showLoad();
servers.post({
url: API.writeOff.shop2WriteoffSet,
data: {
vcode: pickupInfo.gcode,
brand_id: orderInfo.brand_id,
},
isDefaultGet: false,
})
.then(res=>{
util.hideLoad();
if(res.data.code == 0){
let _ls = res.data.data || [];
util.$_emit(WRITE_OFF_MALL_ORDER_SUCCESS, _ls);
util.routeTo(`/pages/write_off/mall/success/success`, 'rT')
}else{
util.showNone(res.data.message || '操作失败!')
}
})
.catch(util.hideLoad)
}, 200, true),
copyBtn(data){
uni.setClipboardData({ data });
},
getSpecTxt(e){
if(
e.product_spec_multi == 1&&
e.product_spec_multi_info&&
e.product_spec_multi_info.spec_info&&
e.product_spec_multi_info.spec_info.length){
let specStr = (e.product_spec_multi_info.spec_info).join(";")
return specStr;
}
return '-';
}
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.mall-ls-confirm{
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 */
}
.mlc-status{
padding: 0 44upx;
height: 106upx;
line-height: 106upx;
font-size: 36upx;
color: #fff;
font-weight: 500;
background-color: $themeColor;
}
.mlc-main{
padding: 24upx;
.mm-box{
margin-bottom: 24upx;
padding: 30upx 28upx;
background-color: #fff;
border-radius: 10upx;
}
.mm-tit{
padding-bottom: 20upx;
line-height: 44upx;
font-weight: 500;
font-size: 28upx;
color: #333;
border-bottom: 2upx solid #F2F2F7;
}
.mm-top{
.mt-line{
@include centerFlex(flex-start);
>view{
font-size: 28upx;
line-height: 60upx;
color: #333;
&:first-child{
margin-right: 60upx;
flex-shrink: 0;
flex-grow: 0;
color: #9A9A9D;
}
&:nth-child(2){
@include textHide(1);
}
&:nth-child(3){
margin-left: 30upx;
flex-shrink: 0;
color: $themeColor;
}
}
}
}
.mm-user-info{
.mui-info{
padding: 20upx 0;
border-bottom: 2upx solid #F2F2F7;
.mi-line{
margin-bottom: 14upx;
font-size: 28upx;
line-height: 40upx;
color: #333;
@include textHide(1);
}
.mi-addr{
font-size: 28upx;
line-height: 40upx;
color: #9C9C9F;
}
}
.mui-code{
padding-top: 30upx;
font-weight: 500;
font-size: 32upx;
color: #333;
}
}
.mm-goods{
padding: 22upx 28upx 0;
border-radius: 10upx;
background-color: #fff;
.mg-ls{
.ml-item{
padding: 30upx 0upx;
@include centerFlex(space-between);
&:not(:last-child){
border-bottom: 2upx solid #F2F2F7;
}
>image{
flex-shrink: 0;
margin-right: 20upx;
width: 180upx;
height: 180upx;
border-radius: 10upx;
}
.mi-info{
flex-grow: 1;
.mi-name{
width: 330upx;
margin-bottom: 12upx;
font-size: 28upx;
line-height: 40upx;
min-height: 80upx;
color: #333;
@include textHide(2);
}
.mi-spec{
width: 100%;
@include centerFlex(space-between);
>view{
font-size: 24upx;
line-height: 34upx;
color: #9A9A9D;
@include textHide(1);
&:first-child{
flex-grow: 1;
}
&+view{
flex-shrink: 0;
margin-left: 20upx;
max-width: 30%;
}
}
}
}
}
}
}
}
.mlc-fixd-btn{
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 10upx;
bottom: calc( 10upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
bottom: calc( 10upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
width: 622upx;
height: 112upx;
line-height: 112upx;
text-align: center;
font-size: 32upx;
border-radius: 10upx;
color: #fff;
background-color: $themeColor;
}
</style>

237
src/pages/write_off/mall/list/list.vue

@ -0,0 +1,237 @@
<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>

150
src/pages/write_off/mall/success/success.vue

@ -0,0 +1,150 @@
<template>
<view class="confirm-success">
<view class="cs-tip">
<image mode="aspectFit" src="/static/images/icon/success_tip.png"></image>
<view>核销成功</view>
</view>
<view class="cs-goods">
<view class="cg-tit">请将以下商品取给客户</view>
<view class="mm-goods">
<view class="mm-tit">商品信息</view>
<view class="mg-ls">
<view class="ml-item" v-for="(e, i) in orderList" :key="i">
<image mode="aspectFill" :src="e.imgs || ''"></image>
<view class="mi-info">
<view class="mi-name">{{ e.name || '-' }}</view>
<view class="mi-spec">
<view>{{ e.spec || '-' }}</view>
<view>×{{ e.nums || 0 }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="mlc-fixd-btn" @click="backBtn">返回继续核销</view>
</view>
</template>
<script>
import { WRITE_OFF_MALL_ORDER_SUCCESS } from '../../../../js/once_name'
import util from '../../../../utils/util'
export default {
data(){
return {
orderList: []
}
},
onLoad(options){
util.$_once(WRITE_OFF_MALL_ORDER_SUCCESS, list=>{
this.orderList = list || [];
})
},
methods: {
backBtn(){
util.routeTo();
}
}
}
</script>
<style lang="scss">
@import '~style/public.scss';
.confirm-success{
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 */
}
.cs-tip{
padding: 84upx 0upx 104upx;
>image{
display: block;
margin: 0 auto 46upx;
width: 100upx;
height: 100upx;
}
>view{
text-align: center;
line-height: 66upx;
font-size: 48upx;
font-weight: 500;
color: #333;
}
}
.cs-goods{
padding: 0 24upx;
.cg-tit{
margin-bottom: 20upx;
font-weight: 500;
font-size: 32upx;
line-height: 44upx;
color: #1a1a1a;
}
.mm-goods{
padding: 22upx 28upx 0;
border-radius: 10upx;
background-color: #fff;
.mg-ls{
.ml-item{
padding: 30upx 0upx;
@include centerFlex(space-between);
&:not(:last-child){
border-bottom: 2upx solid #F2F2F7;
}
>image{
flex-shrink: 0;
margin-right: 20upx;
width: 180upx;
height: 180upx;
border-radius: 10upx;
}
.mi-info{
flex-grow: 1;
.mi-name{
width: 330upx;
margin-bottom: 12upx;
font-size: 28upx;
line-height: 40upx;
color: #333;
@include textHide(2);
}
.mi-spec{
width: 100%;
@include centerFlex(space-between);
>view{
font-size: 24upx;
line-height: 34upx;
color: #9A9A9D;
@include textHide(1);
&:first-child{
flex-grow: 1;
}
&+view{
flex-shrink: 0;
margin-left: 20upx;
max-width: 30%;
}
}
}
}
}
}
}
}
.mlc-fixd-btn{
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 10upx;
bottom: calc( 10upx + constant(safe-area-inset-bottom)); /* 兼容 iOS < 11.2 */
bottom: calc( 10upx + env(safe-area-inset-bottom)); /* 兼容 iOS >= 11.2 */
width: 622upx;
height: 112upx;
line-height: 112upx;
text-align: center;
font-size: 32upx;
border-radius: 10upx;
color: #fff;
background-color: $themeColor;
}
</style>

108
src/pages/write_off/menu/menu.vue

@ -0,0 +1,108 @@
<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="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';
import { API } from '../../../js/api';
import { servers } from '../../../js/server';
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');
},
}
}
</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>

362
src/pages/write_off/number_of_people/number_of_people.vue

@ -0,0 +1,362 @@
<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-btn" @click="isChangeNum = true">修改人数</view>
<view class="nm-tip">
<text>温馨提示\n\r修改现场人数可能会影 响现场灯光开关请谨慎操作 如后台有开启散客开关灯功能的则散客人数达到阶梯最低X人时对应灯光会自动开灯;少于X人的已开启的灯会自动关闭</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>
</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: '',
}
},
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.curStadium,
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
})
}
}
}
</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 30upx 0;
.nm-date{
margin-bottom: 86upx;
line-height: 44upx;
font-size: 32upx;
color: #1a1a1a;
}
.nm-tit{
margin-bottom: 48upx;
text-align: center;
font-size: 32upx;
font-weight: 500;
}
.nm-num{
position: relative;
margin: 0 auto 100upx;
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-btn{
margin: 0 auto 106upx;
width: 618upx;
line-height: 112upx;
height: 112upx;
text-align: center;
border-radius: 10upx;
font-size: 38upx;
color: #fff;
background-color: $themeColor;
}
.nm-tip{
margin-bottom: 30upx;
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;
}
}
}
}
}
</style>

113
src/pages/write_off/operate/operate.vue

@ -23,7 +23,7 @@
import util from '../../../utils/util'; import util from '../../../utils/util';
import { API } from '../../../js/api'; import { API } from '../../../js/api';
import { servers } from '../../../js/server'; import { servers } from '../../../js/server';
import { WRITE_OFF_STORE_NAME, WRITE_OFF_ORDER_INFO } from '../../../js/once_name';
import { WRITE_OFF_STORE_NAME, WRITE_OFF_ORDER_INFO, WRITE_OFF_MALL_ORDER_INFO } from '../../../js/once_name';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
export default { export default {
data(){ data(){
@ -31,20 +31,62 @@ export default {
iptCode: '', iptCode: '',
stadiumList: [], stadiumList: [],
curStadium: {}, curStadium: {},
writeOffType: '', // site()/ mall()
} }
}, },
computed: { computed: {
...mapState([ 'brandInfo' ]), ...mapState([ 'brandInfo' ]),
}, },
onLoad(){
onLoad(options){
this.writeOffType = options.type || '';
util.$_once(WRITE_OFF_STORE_NAME, data => { util.$_once(WRITE_OFF_STORE_NAME, data => {
console.warn(data);
if(!data)return this.initStore();
this.curStadium = data.curStadium; this.curStadium = data.curStadium;
this.stadiumList = data.stadiumList; this.stadiumList = data.stadiumList;
}) })
console.warn(this.brandInfo)
// console.warn(this.brandInfo)
}, },
methods: { 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('初始化店铺数据失败!');
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
})
},
scanCodeBtn: util.debounce(function(){ scanCodeBtn: util.debounce(function(){
uni.scanCode({ uni.scanCode({
onlyFromCamera: true, onlyFromCamera: true,
@ -66,6 +108,8 @@ export default {
this.curStadium = stadiumList[e.detail.value]; this.curStadium = stadiumList[e.detail.value];
}, },
confirmBtn: util.debounce(function(){ confirmBtn: util.debounce(function(){
let { iptCode } = this;
if(!iptCode)return util.showNone('请输入核销码!');
this.analysisOrder({ verify_code: this.iptCode }); this.analysisOrder({ verify_code: this.iptCode });
return return
let _timeSta = new Date().getTime(); let _timeSta = new Date().getTime();
@ -74,41 +118,78 @@ export default {
return util.routeTo(`/pages/write_off/confirm_order/confirm_order`, 'nT'); return util.routeTo(`/pages/write_off/confirm_order/confirm_order`, 'nT');
}, 300, true), }, 300, true),
//
analysisOrder({ verify_code, decrypt_text }){ analysisOrder({ verify_code, decrypt_text }){
let { curStadium, brandInfo } = this;
if(!verify_code&!decrypt_text)return;
let { curStadium, brandInfo, writeOffType } = this;
if(!verify_code&&!decrypt_text)return;
let _query = { let _query = {
brand_id: brandInfo.brand.id, brand_id: brandInfo.brand.id,
stadium_id: curStadium.id, stadium_id: curStadium.id,
} }
let type = '';
let _vType = '';
if(!!verify_code){ if(!!verify_code){
_query['verify_code'] = verify_code;
type = 'verify_code';
_vType = 'verify_code';
writeOffType == 'site'&&(_query['verify_code'] = verify_code);
writeOffType == 'mall'&&(_query['vcode'] = verify_code);
} }
if(!!decrypt_text){ if(!!decrypt_text){
type = 'decrypt_text';
_query['decrypt_text'] = 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, });
},
//
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)
},
// /
siteGet({ query = {}, vType = '', }){
util.showLoad(); util.showLoad();
servers.get({ servers.get({
url: API.writeOff.enterVerifyOrder, url: API.writeOff.enterVerifyOrder,
data: _query,
data: query,
isDefaultGet: false isDefaultGet: false
}) })
.then(res=>{ .then(res=>{
util.hideLoad(); util.hideLoad();
if(res.data.code == 0){ if(res.data.code == 0){
let _data = res.data.data || {} let _data = res.data.data || {}
util.$_emit(WRITE_OFF_ORDER_INFO, {..._data});
if(_data.extension&&_data.extension.verify_order_type === 'monthly_card'){ if(_data.extension&&_data.extension.verify_order_type === 'monthly_card'){
util.routeTo(`/pages/write_off/ym_confirm/ym_confirm?type=${type}`, 'nT');
util.$_emit(WRITE_OFF_ORDER_INFO, {..._data});
util.routeTo(`/pages/write_off/ym_confirm/ym_confirm?type=${vType}`, 'nT');
return return
} }
util.routeTo(`/pages/write_off/confirm_order/confirm_order?type=${type}`, 'nT');
util.$_emit(WRITE_OFF_ORDER_INFO, {..._data});
util.routeTo(`/pages/write_off/confirm_order/confirm_order?type=${vType}`, 'nT');
}else{ }else{
util.routeTo(`/pages/write_off/null/null?type=${type}`, 'nT');
util.routeTo(`/pages/write_off/null/null?type=${vType}`, 'nT');
} }
console.log('订单查询---->', res); console.log('订单查询---->', res);
}) })

4
src/pages/write_off/search_result/search_result.vue

@ -39,7 +39,7 @@
<view>核销时间{{ e.verify_time || '-'}}</view> <view>核销时间{{ e.verify_time || '-'}}</view>
</view> </view>
<view> <view>
<view>离场时间{{ e.verify_leave_time || '-'}}</view>
<view>离场时间{{ e.verify_leave_time || '未扫码离场'}}</view>
</view> </view>
</view> </view>
</view> </view>
@ -124,7 +124,7 @@ export default {
stadiumList, stadiumList,
curStadium, curStadium,
}) })
util.routeTo(`/pages/write_off/operate/operate`, 'nT');
util.routeTo(`/pages/write_off/operate/operate?type=site`, 'nT');
}, },
getList({ brand_id, stadium_id = '', date = '', page = 1, page_size = '' }){ getList({ brand_id, stadium_id = '', date = '', page = 1, page_size = '' }){
util.showLoad(); util.showLoad();

BIN
src/static/images/countdown_bg.png

After

Width: 700  |  Height: 700  |  Size: 33 KiB

BIN
src/static/images/icon/choose.png

After

Width: 36  |  Height: 36  |  Size: 392 B

BIN
src/static/images/write_off/mall.png

After

Width: 128  |  Height: 128  |  Size: 1.4 KiB

BIN
src/static/images/write_off/order.png

After

Width: 128  |  Height: 128  |  Size: 1.0 KiB

BIN
src/static/images/write_off/people.png

After

Width: 128  |  Height: 128  |  Size: 1.8 KiB

BIN
src/static/images/write_off/site.png

After

Width: 120  |  Height: 120  |  Size: 1.4 KiB

24
src/store/index.js

@ -16,22 +16,32 @@ export default new Vuex.Store({
brandInfo: { brandInfo: {
brand: {} brand: {}
}, },
// permissionObj: { // 权限代号对应
// '1001': '营业额',
// '1002': '收款记录',
// '1003': '经营分析',
// '1004': '预约订单',
// '1005': '会员卡订单',
// '1006': '积分订单',
// '1007': '员工管理',
// '1008': '查询核销',
// '1009': '场地管理',
// '1010': '设备管理',
// '1011': '商品零售',
// '1012': '订单管理',
// '1013': '课程管理',
// },
permissionObj: { // 权限代号对应 permissionObj: { // 权限代号对应
'1001': '营业额', '1001': '营业额',
'1002': '收款记录', '1002': '收款记录',
'1003': '经营分析',
'1004': '预约订单',
'1005': '会员卡订单',
'1006': '积分订单',
'1012': '订单管理',
'1007': '员工管理', '1007': '员工管理',
'1008': '查询核销',
'1008': '核销查询',
'1009': '场地管理', '1009': '场地管理',
'1010': '设备管理', '1010': '设备管理',
'1011': '商品零售', '1011': '商品零售',
'1012': '订单管理',
'1013': '课程管理', '1013': '课程管理',
}, },
// 场地占用提交页面信息 // 场地占用提交页面信息
occupyInfo: { occupyInfo: {
storeInfo: {}, // 店铺信息 storeInfo: {}, // 店铺信息

3
src/subpackage/device/components/order/reservation_site_detail/reservation_site_detail.vue

@ -119,7 +119,8 @@
</view> </view>
</view> </view>
<view class="rs-btn" @click="refunndBtn" v-if="orderInfo.pay_status == 1 || orderInfo.pay_status == 2">退款</view>
<!-- 2022/01/04 PM: 禁用退款功能 -->
<!-- <view class="rs-btn" @click="refunndBtn" v-if="orderInfo.pay_status == 1 || orderInfo.pay_status == 2">退款</view> -->
</view> </view>
</template> </template>

7
src/subpackage/device/pages/switch_manage/switch_manage.vue

@ -199,6 +199,7 @@ export default {
if(switchInfo.hardware_type === 'AccessControl'&&status == 1){ if(switchInfo.hardware_type === 'AccessControl'&&status == 1){
//->& 20201224 5
this.operateReq({data: this.getOperateReqData({ switchInfo, status: 0 }), isTip: false, isLoad: false}); this.operateReq({data: this.getOperateReqData({ switchInfo, status: 0 }), isTip: false, isLoad: false});
} }
@ -272,7 +273,7 @@ export default {
} }
let _data = this.getSwitchStatusQuery(switchInfo); let _data = this.getSwitchStatusQuery(switchInfo);
_data = DEVICE_FUN.AC_filterCloudACData(data,switchInfo);
_data = DEVICE_FUN.AC_filterCloudACData(_data,switchInfo);
this.getStatusReq({ this.getStatusReq({
data: _data, data: _data,
@ -292,10 +293,10 @@ export default {
util.hideLoad(); util.hideLoad();
let _data = res.data || {}; let _data = res.data || {};
console.log(this.changeLowerCase(_data.data)) console.log(this.changeLowerCase(_data.data))
if(_data.code == 504 || this.changeLowerCase(_data.data).indexOf('timeout')!=-1){
if(_data.code == 504 || this.changeLowerCase(_data.data).indexOf('timeout')!=-1){ // 线
_deviceList[index]['defineStatusCode'] = 0; _deviceList[index]['defineStatusCode'] = 0;
}else if(_data.code == 0&&this.changeLowerCase(_data.data).indexOf('timeout')==-1){
}else if(_data.code == 0&&this.changeLowerCase(_data.data).indexOf('timeout')==-1){ // 线
_deviceList[index]['defineStatusCode'] = 1; _deviceList[index]['defineStatusCode'] = 1;
}else{ }else{
util.showNone(_data.message || '操作失败!'); util.showNone(_data.message || '操作失败!');

Loading…
Cancel
Save