Commit 4c23005f by 张成

update

parent 48673cc2
......@@ -3,8 +3,11 @@
@import "uview-ui/index.scss";
</style>
<script>
import Store from '@/store';
export default {
onLaunch: function () {
Store.commit('setAuthorization', uni.getStorageSync('Authorization'))
Store.commit('setUserInfo', uni.getStorageSync('userInfo'))
// uni.showLoading({
// title: '加载中...',
// mask:true
......@@ -15,11 +18,7 @@ export default {
},
onHide: function () {
},
methods: {
unilogin() {
}
}
}
</script>
......@@ -27,7 +26,7 @@ export default {
/*每个页面公共css */
.pages {
background: #F2F2F2;
min-height: calc(100vh - 100rpx);
min-height: 100vh;
}
* {
......
<template>
<div>
<u-popup :show="show" :round="10" closeable mode="bottom" @close="close">
<div class="order_flow">
<div class="code">取单码 {{ orderInfo.orderNum }}</div>
<image mode="scaleToFill" :src="qrCode" class="qr_code"></image>
<div class="flow_describe">
<h3>扫码流程 </h3>
<image :mode="'aspectFit'" width="600px" class="flow_img" src="/static/imgs/order_flow.png">
</image>
</div>
<div class="flow_describe">
<h3>注意事项</h3>
<view class="text">
<view>*热饮温度高,推荐使用纸吸管,纸吸管体验更佳。拿到后请小心饮用,吸入时请注意烫口喔</view>
<view>*冷饮如选择冰块分装,冰块分装后饮品将不满杯,敬请谅解。</view>
<view>*冷饮去冰如选择椰椰雪糕,默认分装椰椰雪糕,敬请谅解</view>
</view>
</div>
</div>
</u-popup>
</div>
</template>
<script>
export default {
data() {
return {
orderInfo: {},
qrCode: '',
show: false,
}
},
onLoad() {
},
methods: {
close() {
this.show = false
},
open(data, path) {
this.show = true
this.orderInfo = data;
this.qrCode = path
},
jsonParse(json) {
return JSON.parse(json)
},
}
}
</script>
<style lang="scss" scoped>
.pages {
padding-top: 1rpx;
padding-bottom: 30rpx;
}
.text {
font-size: 20rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 30rpx;
}
.order_status {
width: 686rpx;
height: 174rpx;
background: #FFFFFF;
border-radius: 10rpx;
margin: 32rpx auto 0;
padding: 14px;
.status_text {
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #000000;
text-align: center;
}
.btns {
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.btn {
width: 160rpx;
height: 52rpx;
background: #006ECF;
border-radius: 6rpx;
display: inline-block;
margin: 20rpx;
padding: 0;
line-height: 52rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
font-size: 20rpx;
text-align: center;
}
}
.order_flow {
background: #FFFFFF;
border-radius: 10rpx;
margin-top: 32rpx;
padding-top: 65rpx;
.code {
font-size: 36rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #000000;
text-align: center;
}
.qr_code {
width: 308rpx;
height: 310rpx;
display: block;
margin: 25rpx auto;
background-color: #ccc;
}
.flow_describe {
width: 686rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(166, 166, 166, 0.5);
border-radius: 10rpx;
margin: 0 auto;
padding: 30rpx;
h3 {
font-size: 28rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #000000;
}
.flow_img {
width: 600rpx;
height: 214rpx;
display: block;
margin: 24rpx auto;
}
}
}
.customer_service {
height: 90rpx;
line-height: 90rpx;
background: #FFFFFF;
border-radius: 10rpx;
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
padding: 0 64rpx;
margin: 32rpx 0;
display: flex;
justify-content: space-between;
}
</style>
\ No newline at end of file
<template>
<view class="page-body">
<scroll-view class="nav-left" scroll-y :scroll-top="scrollLeftTop" scroll-with-animation>
<view class="nav-left-item" v-for="item in classifyData" @click="categoryClickMain(item.id)" :key="item.id"
:class="item.id == categoryId ? 'active' : ''">
<span>{{ item.name }}</span>
<view :class="item.id == categoryId ? 'active-line' : ''"></view>
</view>
</scroll-view>
<scroll-view class="nav-right" scroll-y :scroll-top="scrollTop" @scroll="scroll" @touchstart="openScroll"
scroll-with-animation>
<view v-for="category in classifyData" :id="category.id" :key="category.id" class="box">
<view :style="loads" class="right-title">{{ category.name }}</view>
<view class="nav-right-item" v-for="item in category.goods" :key="item.goodsId"
@click="cart(item, category)">
<image src="../../static/imgs/isRecommend.png" v-if="item.isRecommend == 1" class="isRecommend" />
<image class="thumbnail" v-if="item.pics.thumbnailApplet" :src="item.pics.thumbnailApplet" />
<image class="thumbnail" v-else :src="item.pics.thumbnail" />
<view class="info">
<view class="goods-name">{{ item.name }}</view>
<view class="tags">
<view class="tag-item" v-for="tag in item.tags" :key="tag">{{ tag }}</view>
</view>
<view class="dis-box">
<view class="dis">{{ item.desc || '' }}</view>
<view class="add-btn" @click.stop="getallNum(item, category)">+</view>
</view>
<view class="mon">
<view class="discount">{{ getPrice(item).discount || item.discount }}</view>
<view class="price"><text class="num">{{ getPrice(item).price || item.price }}</text>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
name: 'menuAssembly',
watch: {},
data() {
return {
classifyData: [],
categoryId: '',
categoryPostion: [],
scrollLeftTop: 0,
scrollTop: 0,
scrolled: true
}
},
methods: {
getPrice(data) {
const { skus } = data;
if (!skus && skus.length == 0) return;
const sku = data.skus.find(v => v.isDefault == 1 && v.state != 2) || data.skus.find(v => v.isDefault == 0 && v.state != 2);
if (sku) {
return sku
}
return {}
},
createList(data) {
this.classifyData = data;
this.$nextTick(() => {
const query = uni.createSelectorQuery().in(this);
query.selectAll('.box').boundingClientRect(data => {
this.categoryPostion = data
}).exec();
})
},
getallNum(item, category) {
this.$emit('getallNum', item, category)
},
openScroll() {
this.scrolled = true
},
scroll(e) {
if (!this.scrolled) return;
const { categoryPostion } = this;
const [el] = categoryPostion.filter(item => item.top - e.target.scrollTop >= 20);
if (el) this.categoryId = el.id
},
categoryClickMain(id) {
this.scrolled = false
this.categoryId = id;
this.categoryPostion.forEach(item => {
if (item.id == id) {
this.scrollTop = item.top - 320
}
});
},
cart: (item, category) => {
uni.setStorageSync('goodsInfo', JSON.stringify({ ...item, category }));
uni.navigateTo({ url: '/menuSubPackage/pages/goodsDetail/goodsDetail' })
}
}
}
</script>
<style lang="scss" scoped>
.menu-box {
min-height: 100vh;
.shop-info {
position: absolute;
left: 32rpx;
color: #FFFFFF;
.shop-box {
min-width: 300rpx;
font-size: 28rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
display: flex;
.shop-name {
flex: 1;
}
.arrow-right-select {
width: 9rpx;
}
}
.distance {
height: 46rpx;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 42rpx;
}
}
}
.menu-banner {
height: 376rpx;
position: relative;
image {
width: 100%;
height: 376rpx;
}
.login-area {
display: flex;
width: 624rpx;
height: 88rpx;
padding: 20rpx 22rpx;
background: rgba(255, 255, 255, 0.2);
box-shadow: 0rpx 4rpx 6rpx 0rpx rgba(0, 0, 0, 0.1);
border-radius: 10rpx;
backdrop-filter: blur(10rpx);
position: absolute;
z-index: 1;
bottom: 0;
left: 64rpx;
box-sizing: border-box;
.avatar {
display: flex;
justify-items: center;
align-items: center;
background: red;
width: 50rpx;
height: 48rpx;
margin-right: 22rpx;
box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(50, 50, 50, 0.25);
border-radius: 4rpx;
image {
width: 100%;
height: 100%;
}
;
}
.user-info {
flex: 1;
.user-name {
height: 28rpx;
font-size: 20rpx;
font-family: ArialMT;
color: #FFFFFF;
line-height: 22rpx;
}
.dialog {
display: flex;
height: 22rpx;
font-size: 16rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 22rpx;
.content {
flex: 1;
}
.arrow {
width: 10rpx;
height: 12px;
display: flex;
font-size: 20rpx;
justify-content: center;
align-items: center;
}
}
}
.login-btn {
// width: 114rpx;
height: 48rpx;
background: #006ECF;
border-radius: 4rpx;
font-size: 20rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
line-height: 48rpx;
text-align: center;
}
}
}
.order-banner {
width: 686rpx;
height: 179rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 8rpx 0rpx rgba(166, 166, 166, 0.5);
border-radius: 10rpx;
box-sizing: border-box;
position: relative;
left: 32rpx;
top: -8rpx;
z-index: 1;
display: flex;
.info {
padding-left: 32rpx;
flex: 1;
.first {
height: 44rpx;
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #323232;
line-height: 44rpx;
margin-top: 40rpx;
}
.second {
margin-top: 20rpx;
height: 34rpx;
font-size: 24rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #323232;
line-height: 34rpx;
.time {
font-size: 28rpx;
font-family: Arial-BoldMT, Arial;
font-weight: normal;
color: #006ECF;
margin: 0 16rpx;
}
}
}
.line {
width: 0;
height: 104rpx;
border-right: 4rpx solid #006ECF;
position: absolute;
right: 188rpx;
top: 36rpx;
}
.barCode-box {
margin-top: 30rpx;
width: 150rpx;
height: 122rpx;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
flex-direction: column;
.barCode {
width: 86rpx;
height: 86rpx;
background: #006ECF;
image {
width: 100%;
height: 100%;
}
}
.barCode-dis {
text-align: center;
margin-top: 14rpx;
font-size: 16rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #666666;
line-height: 22rpx;
}
}
}
.page-body {
display: flex;
background: #fff;
overflow: hidden;
}
.nav {
display: flex;
width: 100%;
}
.nav-left {
width: 152rpx;
background: #fff;
border-right: 2rpx solid #D5D5D5;
height: calc(100vh - 376rpx);
overflow: auto;
}
.nav-left-item {
position: relative;
height: 170rpx;
line-height: 170rpx;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
display: flex;
align-items: center;
justify-content: center;
}
.nav-left-item:last-child {
border-bottom: none;
}
.nav-right {
height: calc(100vh - 376rpx);
overflow: auto;
box-sizing: border-box;
padding-top: 30rpx;
width: 596rpx;
}
.box {
display: block;
overflow: hidden;
/* min-height: 100vh; */
/*若您的子分类过少想使得每个子分类占满屏请放开上边注视 */
}
.box:last-child {
border: none;
// min-height: 100vh;
}
.right-title {
padding-left: 28rpx;
margin-bottom: 40rpx;
height: 44rpx;
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #000000;
line-height: 44rpx;
}
.nav-right-item {
display: flex;
padding: 0rpx 36rpx 0rpx 42rpx;
margin-bottom: 50rpx;
height: 162rpx;
background: #fff;
position: relative;
.thumbnail {
//缩略图
display: flex;
align-items: center;
width: 140rpx;
height: 140rpx;
margin-right: 34rpx;
}
.info {
flex: 1;
.goods-name {
height: 40rpx;
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 40rpx;
}
.tags {
.tag-item {
height: 24rpx;
border-radius: 4rpx;
border: 2rpx solid #006ECF;
margin-right: 10rpx;
padding: 4rpx 6rpx;
font-size: 16rpx;
font-family: ArialMT;
color: #006ECF;
line-height: 24rpx;
display: inline-block;
}
}
.dis-box {
display: flex;
font-size: 20rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 40rpx;
.dis {
flex: 1;
}
.add-btn {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: #006ECF;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 36rpx;
}
}
.mon {
.discount {
display: inline-block;
height: 32rpx;
font-size: 24rpx;
font-family: Arial-BoldMT, Arial;
font-weight: normal;
color: #EB5F17;
line-height: 32rpx;
margin-right: 6rpx;
}
.price {
display: inline-block;
height: 22rpx;
font-size: 20rpx;
font-family: ArialMT;
color: #666666;
line-height: 22rpx;
.num {
text-decoration: line-through;
}
}
}
}
.isRecommend {
position: absolute;
width: 30rpx;
height: 30rpx;
top: 10rpx;
left: 50rpx
}
}
.nav-right-item image {
width: 150rpx;
height: 150rpx;
}
.active {
font-weight: 600;
color: #000000;
background: #fff;
}
.active-line {
height: 170rpx;
width: 2rpx;
position: absolute;
right: -2rpx;
top: 0;
z-index: 1;
border-right: 8rpx solid #006ECF;
;
}
::-webkit-scrollbar {
/*取消小程序的默认导航条样式*/
width: 0;
height: 0;
color: transparent;
}
</style>
\ No newline at end of file
......@@ -30,9 +30,9 @@
<view class="size">
<text style="font-size: 28rpx;color: #000000;">{{ item.name }}</text>
<text style="font-size:20rpx;color:#666666">
<text v-for="(rl, index) in item.skus[0].rules" :key="rl.ruleName">
<text v-for="(rl, index) in item.sku.rules" :key="rl.ruleName">
{{ rl.ruleName }}
<text v-if="index != item.skus.rules.length - 1">/</text>
<text v-if="index != item.sku.rules.length - 1">/</text>
</text>
</text>
<text>
......@@ -56,9 +56,9 @@
</u-popup>
<view class="end" v-if="goods.length">
<view class="end-left">
<view @click.stop="openShopCar" class="end-left">
<view style="display:flex">
<view class="car-img" @click.stop="openShopCar">
<view class="car-img">
<text class="badge" v-if="totalNum">{{ totalNum }}</text>
</view>
<text class="shopClassStyle">{{ totalPrice.toFixed(2) }}</text>
......@@ -143,7 +143,7 @@ export default {
uni.showToast({ title: '已拒绝手机号授权', icon: 'error' })
}
},
change(e) { console.log(e) },
change(e) { },
selected(item) {
item.flag = !item.flag
if (!item.flag) {
......@@ -183,7 +183,7 @@ export default {
add(item) {
let s = 0;
this.goods.forEach(function (val) {
s += val.num;
s += Number(val.num);
}, 0);
if (s >= 9) {
uni.showToast({
......@@ -192,7 +192,7 @@ export default {
});
return;
}
let num = item.num
let num = Number(item.num)
item.num = num + 1
uni.setStorageSync('shopCarInfo', this.goods);
}
......@@ -384,7 +384,7 @@ export default {
height: 92rpx;
background-color: rgb(253, 253, 253);
position: fixed;
bottom: 50px;
bottom: 0;
left: 0;
display: flex;
z-index: 10075;
......
<template>
<!-- Tab -->
<u-tabbar zIndex="10075" v-model="selectedTabbar" :border="false" inactive-color="#000000" height="50" active-color="#006ECF" :fixed="true" :safeAreaInsetBottom="true" @change="beforeSwitch">
<u-tabbar-item v-for="(item,index) in list" :key="item.text" :text="item.text" :icon="selectedTabbar==index?item.activeIcon:item.icon"></u-tabbar-item>
<u-tabbar zIndex="10075" v-model="selectedTabbar" :border="false" inactive-color="#000000" height="50"
active-color="#006ECF" :fixed="true" :safeAreaInsetBottom="true" @change="beforeSwitch">
<u-tabbar-item v-for="(item, index) in list" :key="item.text" :text="item.text"
:icon="selectedTabbar == index ? item.activeIcon : item.icon"></u-tabbar-item>
</u-tabbar>
</template>
<script>
export default {
data() {
return {
}
return {}
},
props: ['selectedTabbar'],
computed: {
......@@ -21,7 +21,9 @@ export default {
},
methods: {
//点击tab
beforeSwitch(index) {
uni.switchTab({ url: this.list[index].pagePath });
return true;
}
......
import App from './App'
import App from './App';
//引入vuex
import store from './store'
import utils from './utils/utils'
import store from './store';
import utils from './utils/utils';
// console.log(Vue.$u,22)
// 需要在Vue.use(uView)之后执行
// #ifndef VUE3
import Vue from 'vue'
import Vue from 'vue';
import uView from 'uview-ui';
import User from '@/request/user';
Vue.use(uView);
Vue.prototype.$utils = utils
Vue.config.productionTip = false
App.mpType = 'app'
Vue.prototype.$utils = utils;
Vue.prototype.setPrice = (price) => price && Number(price).toFixed(2);
Vue.prototype.loginByPhoneNumber = (e) => {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
User.getPhoneNumber(e);
} else if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
uni.showToast({ title: '已拒绝手机号授权', icon: 'error' });
}
};
Vue.config.productionTip = false;
App.mpType = 'app';
const app = new Vue({
...App,
store
})
app.$mount()
require('./request/index')(app);
store,
});
app.$mount();
require('./request/index')(app);
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
import { createSSRApp } from 'vue';
export function createApp() {
const app = createSSRApp(App)
const app = createSSRApp(App);
return {
app
}
app,
};
}
// #endif
<template>
<view class="product-list">
<u-sticky bgColor="#fff" >
<u-tabs :list="list1" ref="uTabs" :current="current" @change="tabsChange"></u-tabs>
</u-sticky>
<swiper :current="swiperCurrent" @change="transition">
<swiper-item class="swiper-item" v-for="(item, index) in tabs" :key="index">
<scroll-view scroll-y style="height:100%;width: 100%;" @scrolltolower="onreachBottom">
{{item.value}}
</scroll-view>
</swiper-item>
</swiper>
<view ew class="product-list">
<div v-for="item in list" :key="item.id" @click="selectedShop(item)" class="shop_item">
<div class="header">
<h3>{{ item.name }}</h3>
<span>距离 {{ item.distance }}</span>
</div>
<div class="dec">
<div class="address">{{ item.address }}</div>
<a class="xaidan">去下单</a>
</div>
<div class="time">
<u-icon name="clock" color="#2979ff" size="16"></u-icon>
<div>营业时间:{{ item.startTime }} - {{ item.endTime }}</div>
</div>
</div>
</view>
</template>
<script>
export default {
import { $EventBus } from '@/utils/EventBus';
export default {
data() {
return {
swiperCurrent: 0,
current: 0,
tabs:[
{value:'111111111111'},
{value:'222222222222'},
{value:'333333333333'},
{value:'444444444444'},
],
list1: [{
name: '国家',
}, {
name: '城市',
}, {
name: '全部地区'
}]
show: true,
columns: [],
list: []
}
},
methods:{
// tabs通知swiper切换
tabsChange(e) {
this.swiperCurrent = e.index;
onShow() {
this.list = uni.getStorageSync('shops');
},
// swiper-item左右移动,通知tabs的滑块跟随移动
transition(e) {
this.current = e.detail.current
console.log(e.detail.current,'-------')
methods: {
selectedShop(item) {
uni.setStorage({ key: 'shopData', data: item });
uni.switchTab({ url: '/pages/menu/menu' })
$EventBus.$emit('getMenuList', item);
}
},
// scroll-view到底部加载更多
onreachBottom() {
console.log(11111111111)
}
</script>
<style lang="scss" scoped>
.shop_item {
width: 90%;
height: 264rpx;
background: #FFFFFF;
border-radius: 10rpx;
border: 2rpx solid #006ECF;
padding: 32rpx;
box-sizing: border-box;
margin: 30rpx auto;
.header {
display: flex;
align-items: center;
justify-content: space-between;
h3 {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
}
span {
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
}
}
</script>
.dec {
display: flex;
justify-content: space-between;
margin-top: 22rpx;
<style lang="scss" scoped>
.product-list{
.address {
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFa
}
.xaidan {
font-size: 24rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #FFFFFF;
width: 188rpx;
text-align: center;
height: 40rpx;
line-height: 40rpx;
background: #006ECF;
border-radius: 6px;
display: block;
margin-left: 20rpx;
}
}
.time {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 20rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
margin-top: 30rpx;
}
}
</style>
\ No newline at end of file
......@@ -2,30 +2,44 @@
<view class="spec-content">
<view v-if="goodInfo">
<view class="uni-margin-wrap">
<swiper class="swiper">
<swiper v-if="goodInfo.pics.introImagesApplet" class="swiper">
<swiper-item v-for="item in goodInfo.pics.introImagesApplet" :key="item">
<image :src="item" class="swiper_img" mode="scaleToFill"></image>
</swiper-item>
</swiper>
<swiper v-else class="swiper">
<swiper-item v-for="item in goodInfo.pics.introImages" :key="item">
<image :src="item" class="swiper_img" mode="aspectFit"></image>
<image :src="item" class="swiper_img" mode="scaleToFill"></image>
</swiper-item>
</swiper>
</view>
<view class="good spec-info-left">
<text class="good-name">{{ goodInfo.name }}</text>
<view class="specs">
<!-- 规格 -->
<view v-for="specItem in goodInfo.specs" :key="specItem.specId">
<view class="good-spec-name">{{ specItem.specName }}</view>
<view class="good-spec-rule">
<view class="good-spec-rule-item" v-for="specItemRule in specItem.rules"
@click="selectRoles(specItemRule, specItem)" :class="{ active: isActvie(specItemRule) }"
:key="specItemRule.ruleId">
<div v-for="specItemRule in specItem.rules" class="div_item" :key="specItemRule.ruleId">
<div v-if="setDefaultStyle(specItemRule.ruleId)" class="default"></div>
<button class="good-spec-rule-item" :disabled="UseIt(specItemRule.ruleId)"
@click="selectRoles(specItemRule, specItem)"
:class="{ active: isActvie(specItemRule) }">
<view>{{ specItemRule.ruleName }}</view>
</view>
</button>
</div>
</view>
</view>
</view>
</view>
<view class="spec-detail">
<view class="spec-detail-title spec-info-left">商品详情</view>
<view class="spec-detail-img" v-for="item in goodInfo.pics.detailImages" :key="item">
<view v-if="goodInfo.pics.detailImagesApplet">
<view class="spec-detail-img" v-for="item in goodInfo.pics.detailImagesApplet" :key="item">
<image class="spec-detail-img-item" :src="item" mode="scaleToFill"></image>
</view>
</view>
<view v-else class="spec-detail-img" v-for="item in goodInfo.pics.detailImages" :key="item">
<image class="spec-detail-img-item" :src="item" mode="scaleToFill"></image>
</view>
<!-- 底部空白 -->
......@@ -34,18 +48,27 @@
<view class="good-select good-select-height">
<view class="good-select-price">
<text class="good-select-price-normal">¥100</text>
<text class="good-select-price-small">¥10</text>
<div>
<text class="good-select-price-normal">{{ priceTotal.discount }}</text>
<text class="good-select-price-small">{{ priceTotal.price }}</text>
</div>
<div v-if="!size > 0">已售罄</div>
<div v-else class="set_size">
<u-icon name="minus-circle" @click="reduceGood" color="#2979ff" size="22">
</u-icon>
<span>{{ size }}</span>
<u-icon name="plus-circle-fill" color="#2979ff" @click="addGood" size="22"></u-icon>
</div>
</view>
<view class="good-select-cont">
<span class="good-select-btn1" @click="getallNum('buyNow')" v-if="userms">
<view v-if="size > 0" class="good-select-cont">
<a class="good-select-btn1" @click="getallNum()" v-if="userms">
立即购买
</span>
</a>
<button v-if="!userms" class="good-select-btn1" style="border-radius: 0;" open-type="getPhoneNumber"
@getphonenumber="getallNum">
立即购买
</button>
<span class="good-select-btn2" @click="getallNum" type="default">加入购物袋</span>
<span class="good-select-btn2" @click="shoppingCart" type="default">加入购物袋</span>
</view>
</view>
</view>
......@@ -61,15 +84,59 @@ export default {
title: 'Hello1',
imglist: [{ img: "/static/logo.png" }, { img: "/static/ggxz01.png" }],
goodInfo: null,
selected: []
selected: [],
available: [],
goods: {},
skusDefault: [],
pirce: 0,
size: 0,
}
},
onLoad(option) {
const goodsInfo = uni.getStorageSync('goodsInfo')
this.goodInfo = JSON.parse(goodsInfo)
onShow() {
uni.removeStorageSync('goodsList');
},
onLoad() {
uni.removeStorageSync('goodsList');
const goodsInfo = JSON.parse(uni.getStorageSync('goodsInfo'));
this.goodInfo = goodsInfo;
const skus = goodsInfo.skus;
if (skus) {
const sku = skus.find(v => v.isDefault == 1 && v.state == 1) || skus.find(v => v.isDefault == 0 && v.state == 1);
this.skusDefault = skus.find(v => v.isDefault == 1);
if (!sku) return;
this.selected.push(...sku.rules)
skus.forEach(item => {
if (item.state == 1) {
item.rules.forEach(rule => {
this.available.push(rule.ruleId)
})
}
})
}
this.$nextTick(() => {
this.buildGoods(e => {
if (e) {
this.size = 1
} else {
this.size = 0
}
})
})
},
methods: {
setDefaultStyle(id) {
let selected = false;
if (this.skusDefault && this.skusDefault.rules) {
this.skusDefault.rules.forEach(item => {
if (item.ruleId == id) {
selected = true
}
});
}
return selected
},
selectRoles(specItemRule, parent) {
const { selected } = this;
selected.forEach((item, index) => {
......@@ -78,19 +145,12 @@ export default {
}
});
this.selected.push({ ...specItemRule, specId: parent.specId })
this.buildGoods()
},
isActvie(data) {
return this.selected.filter(item => item.ruleId == data.ruleId).length > 0
},
getallNum(type) {
let Authorization = uni.getStorageSync('Authorization');
if (!Authorization) {
this.loginByPhoneNumber(e);
return
}
buildGoods(callback) {
const skusObj = {};
let selectedSku = null
const skus = this.goodInfo.skus;
......@@ -102,31 +162,58 @@ export default {
for (let item in skusObj) {
const selStr = selectedrules.toString()
const itemStr = skusObj[item].toString()
if (selStr === itemStr) {
selectedSku = item
}
if (selStr === itemStr) selectedSku = item;
}
const [sku] = skus.filter(item => item.skuId == selectedSku);
if (skus.state == 2) {
if (!sku || skus.state == 2) {
uni.showToast({ title: '本商品已经售罄', icon: 'none' });
return;
callback && callback()
} else {
const { category, ...goods } = this.goodInfo;
goods.skus = [sku];
goods.sku = sku
goods.num = 1;
goods.flag = true;
goods.skuId = selectedSku
goods.categoryId = category.id;
goods.goodsName = category.name;
Utils.getallNum(goods);
if (type == 'buyNow') {
uni.navigateTo({ url: `/orderSubPackage/pages/settlement/index?buyType=1` })
this.goods = goods
callback && callback(true)
}
},
addGood() {
if (this.size < 9) {
this.size = this.size + 1;
} else {
uni.switchTab({ url: '/pages/menu/menu' })
uni.showToast({
title: '最多可一次购买9杯',
icon: 'none',
});
}
},
reduceGood() {
const { size } = this
if (size > 1) {
this.size = size - 1;
}
},
shoppingCart() {
const { goods } = this;
goods.num = this.size;
Utils.getallNum(goods)
uni.switchTab({ url: '/pages/menu/menu' })
},
getallNum(e) {
let Authorization = uni.getStorageSync('Authorization');
if (!Authorization) {
this.loginByPhoneNumber(e);
return
}
const { goods } = this;
goods.num = this.size
Utils.addGoods(goods)
uni.navigateTo({ url: `/orderSubPackage/pages/settlement/index?buyType=1&goodsList=1` })
},
// 付款前未登录发起授权
loginByPhoneNumber(e) {
......@@ -136,13 +223,28 @@ export default {
uni.showToast({ title: '已拒绝手机号授权', icon: 'error' })
}
},
UseIt(ruleId) {
return this.available.indexOf(ruleId) == -1
}
},
computed: {
userms() {
return this.$store.getters.Authorization;
},
priceTotal() {
let discount = 0;
let price = 0;
const { goods } = this;
if (goods.sku) {
discount = goods.sku.discount * this.size
price = goods.sku.price * this.size
}
return { discount: discount.toFixed(2), price: price.toFixed(2) }
}
},
}
</script>
......@@ -162,7 +264,10 @@ export default {
height: 100% !important;
}
.spec-content {}
.spec-content {
width: 100%;
overflow-x: hidden;
}
.spec-info-left {
padding: 22rpx 34rpx;
......@@ -203,20 +308,46 @@ export default {
margin-left: 8rpx;
margin-top: 24rpx;
flex-wrap: wrap;
.div_item {
position: relative;
width: 120rpx;
height: 48rpx;
margin-right: 10rpx;
margin-top: 10rpx;
line-height: 48rpx;
margin-left: 10rpx;
.default {
width: 15rpx;
height: 15rpx;
background-color: red;
border-radius: 50%;
position: absolute;
left: -5rpx;
top: -5rpx;
z-index: 9
}
}
}
}
.good-spec-rule-item {
width: 120rpx;
height: 48rpx;
width: 100%;
height: 100%;
border-radius: 6rpx;
font-size: 24rpx;
margin-right: 10rpx;
margin-top: 10rpx;
color: #000;
line-height: 48rpx;
text-align: center;
display: inline-block;
margin: 0;
margin: 0;
padding: 0;
line-height: 50rpx;
&.active {
background: #006ECF;
......@@ -253,6 +384,8 @@ export default {
bottom: 0rpx;
text-align: center;
background-color: #fff;
height: auto;
padding-bottom: 20rpx;
}
.good-select-price {
......@@ -260,6 +393,8 @@ export default {
align-items: center;
height: 58rpx;
background: #FFFFFF;
justify-content: space-between;
padding: 10rpx 34rpx;
}
.good-select-price-normal {
......@@ -306,4 +441,12 @@ export default {
text-align: center;
color: #fff;
}
.set_size {
display: flex;
span {
margin: 0 20rpx
}
}
</style>
<!-- 本页面如果不是从购物车发起的则获取到的数据需要存到vuex等待发起支付时组装数据 -->
<template>
<view>
<u-button @click="saveReserve">付款</u-button>
</view>
</template>
<script>
import Utils from '@/utils/utils'
import Menu from '@/request/menu'
export default {
data() {
return {
buyType:0,//发起支付的页面标识//// 从购物车发起:buyType=1;// 立即购买:buyType=2;// 扫码进入:buyType=3;
orderId:null,//扫码进来的orderId
viewData:{},//预支付数据订单数据
totalPrice:0,//总金额
totalNum:0,//总数量
}
},
onLoad(options) {
if(options.buyType){
this.buyType = options.buyType;
}
if(options.orderId){
this.orderId = options.orderId;
}
if(options.totalPrice){
this.totalPrice = options.totalPrice;
}
if(options.totalNum){
this.totalNum = options.totalNum;
}
},
onShow() {
if(this.orderId!=null && this.buyType==3){
this.getOrderInfo()
}
},
onUnload(event){
if(this.orderId && this.buyType==3){
uni.switchTab({
url:'/pages/menu/menu'
});
}
return true;
},
methods: {
// 扫码直接进来的订单需要重新获取数据,获取到之后要存到vuex等待支付时组装数据
async getOrderInfo(){
let res = await Menu.getScreenShopCar(this.orderId);
if(res.data.code==200){
this.viewData = res.data.data;
//这里取到数据后需要计算出总价和总数量存给this.totalPrice和this.totalNum;
// 需要组装成和购物车一样的数据存进vuex等待支付。
// ###############未完成处理
this.$store.commit('saveOrderPrePayInfo',res.data.data);
}
},
//结算组装数据发起订单
async saveReserve() {
// 组装购物车数据或者立即支付数据
let res = await Utils.AssemblyOrder(this.totalPrice,this.totalNum,this.buyType);
if(res){
// 发起订单
let orderInfo = await Menu.saveReserve(res);
if(orderInfo && orderInfo.data.code==200){
let payMent = await Menu.requestPayment(orderInfo.data.data,res,this.buyType);
}
}
}
}
}
</script>
<style>
</style>
<template>
<scroll-view class="msg" scroll-y>
<view class="msg_item" v-for="item in list" @click="toRead(item)" :key="item.id">
<view class="msg_item_title_time">
<view v-if="item.isRead == 1" class="sign"></view>
<h3 class="title">{{ item.title || 'HOOLOO' }}</h3>
<view class="time">{{ item.createdAt }}</view>
</view>
<view class="msg_content">{{ item.message }}</view>
</view>
</scroll-view>
</template>
<script>
import Mine from '@/request/mine'
export default {
data() {
return {
list: []
}
},
onShow() {
this.getList()
},
methods: {
async getList() {
const { data } = await Mine.getMsg();
this.list = data.rows
},
async toRead(item) {
const { id } = item
const res = await Mine.read({ id, isRead: 2 })
if (res) {
this.getList()
}
}
}
}
</script>
<style lang="scss" scoped>
.msg_item {
width: 100%;
height: 116rpx;
background: #FFFFFF;
padding: 24rpx 62rpx;
box-sizing: border-box;
.msg_item_title_time {
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
.sign {
width: 16rpx;
height: 16rpx;
background: #006ECF;
border-radius: 50%;
position: absolute;
left: -30rpx;
top: 30%
}
.title {
font-size: 24rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 34rpx
}
.time {
font-size: 20rpx;
font-family: PingFangSC-Regular,
PingFang SC;
font-weight: 400;
color: #333333;
line-height: 28rpx;
}
}
.msg_content {
font-size: 20rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 28rpx;
}
}
</style>
\ No newline at end of file
......@@ -9,5 +9,4 @@ export default {
</script>
<style>
</style>
\ No newline at end of file
<template>
<div class="pages">
<div class="order_status">
<view class="status_text" v-if="orderInfo.state == 0">订单状态:创建未校验</view>
<view class="status_text" v-if="orderInfo.state == 1">订单状态:未支付</view>
<view class="status_text" v-if="orderInfo.state == 2">订单状态:排队中</view>
<view class="status_text" v-if="orderInfo.state == 3">订单状态:制作中</view>
<view class="status_text" v-if="orderInfo.state == 4">订单状态:制作完成</view>
<view class="status_text" v-if="orderInfo.state == 5">订单状态:待取超时</view>
<view class="status_text" v-if="orderInfo.state == 6">订单状态:完成</view>
<view class="status_text" v-if="orderInfo.state == 7">订单状态:取消</view>
<view class="status_text" v-if="orderInfo.state == 8">订单状态:取消</view>
<view class="status_text" v-if="orderInfo.state == 9">订单状态:取消</view>
<view class="status_text" v-if="orderInfo.state == 10">订单状态:取消</view>
<view class="status_text" v-if="orderInfo.state == 11">订单状态:已退款</view>
<view class="status_text" v-if="orderInfo.state == 12">订单状态:部分退款</view>
<div>
<a type="primary" @click="toRefund" v-if="orderInfo.state == 1" class="btn">申请退款</a>
<view class="status_text">{{ orderStatusText }}</view>
<div class="btns">
<a type="primary" @click="cancelOrder" v-if="orderInfo.state == 1" class="btn">取消订单</a>
<a type="primary" @click="PayNow" v-if="orderInfo.state == 1" class="btn">立即支付</a>
<a type="primary" @click="toRefund" v-if="orderInfo.state == 2" class="btn">申请退款</a>
<a type="primary" @click="oneMoreOrder(orderInfo)" v-if="!qrShow || orderInfo.state == 6"
class="btn">再来一单</a>
</div>
</div>
<div class="order_flow">
<div class="code">取单码 Mon999</div>
<image mode="aspectFit" :src="orderInfo.pickCode" class="qr_code"></image>
<div class="flow_describe">
<div v-if="qrShow" class="code">取单码 {{ orderInfo.orderNum }}</div>
<div v-if="qrShow" class="qr_code">
<image mode="aspectFit" :src="ewmImg" class="qr"></image>
<view class="status_text">{{ orderStatusText }}</view>
</div>
<canvas class="canvas-code" canvas-id="myQrcode"
style="background:#fff;width: 200px;height: 200px; display:block; left:-800rpx;position:absolute;" />
<div v-if="qrShow" class="flow_describe">
<h3>扫码流程 </h3>
<image :mode="'aspectFit'" width="600px" class="flow_img" src="../../../static/imgs/order_flow.png">
</image>
</div>
<div class="shop_info">
<div class="address">
<div class="address_1">北京朝阳建外SOHO东区A座店</div>
<div class="address_2">距您132m,请确定门店后下单</div>
<div class="address_1">{{ orderInfo.shop.name }}</div>
<div class="address_2">{{ orderInfo.shop.address }}</div>
</div>
<div v-for="item in orderInfo.orderDetails" :key="item.id">
<div class="goods">
<div class="goods_item">
<image mode="aspectFit" :src="jsonParse(item.goods.pics).thumbnail" class="goods_img">
<image mode="aspectFit" v-if="jsonParse(item.goods.pics).thumbnailApplet"
:src="jsonParse(item.goods.pics).thumbnailApplet" class="goods_img">
</image>
<image mode="aspectFit" v-else :src="jsonParse(item.goods.pics).thumbnail"
class="goods_img">
</image>
<div class="goods_text">
<div class="goods_name">
<div class="name">{{ item.goodsName }}</div>
<div class="price">¥{{ item.realAmount }}</div>
<div class="price">¥{{ setPrice(item.amount) }}</div>
</div>
<div class="goods_psce">
<div class="psce_name">
......@@ -59,11 +58,11 @@
<div class="discount">
<div class="discount_1">
<div class="name">优惠免减</div>
<div class="price">- ¥5</div>
<div class="price">¥{{ setPrice(item.amount - item.realAmount) }}</div>
</div>
<div class="concessional_rate">
<div class="name">优惠免减</div>
<div class="price">- ¥5</div>
<div class="name">特惠价</div>
<div class="price">¥{{ setPrice(item.realAmount) }}</div>
</div>
</div>
</div>
......@@ -71,7 +70,7 @@
<div class="size">共一件商品</div>
<div>
<span class="paid_in">实付</span>
<span class="money">10</span>
<span class="money">{{ setPrice(orderInfo.amount) }}</span>
</div>
</div>
</div>
......@@ -83,15 +82,15 @@
<h3>订单信息</h3>
<div class="item">
<span class="label">下单时间:</span>
<span class="value">2022-11-12 10:20:20</span>
<span class="value">{{ orderInfo.createdAt }}</span>
</div>
<div class="item">
<span class="label">取单码号:</span>
<span class="value">2022-11-12 10:20:20</span>
<span class="value">{{ orderInfo.orderNum }}</span>
</div>
<div class="item">
<span class="label">订单编号:</span>
<span class="value">2022-11-12 10:20:20</span>
<span class="value">{{ orderInfo.orderNo }}</span>
</div>
</div>
......@@ -104,25 +103,133 @@
</template>
<script>
import Order from '@/request/order'
import Order from '@/request/order';
import QRCode from '@/utils/qrCode'
import Menu from '@/request/menu';
import Utils from '@/utils/utils'
import { $EventBus } from "@/utils/EventBus";
export default {
onLoad() {
this.orderInfo = uni.getStorageSync('orderInfo');
const resData = uni.getStorageSync('orderInfo');
this.orderInfo = resData
this.ewmImg = '/static/imgs/noQr.png'
const isBuild = ['4', '5', '6', '7'].indexOf(this.orderInfo.state) != -1;
if (isBuild) {
new QRCode('myQrcode', {
text: this.orderInfo.pickCode,
width: 141, //canvas 画布的宽
height: 141, //canvas 画布的高
padding: 0, // 生成二维码四周自动留边宽度,不传入默认为0
correctLevel: QRCode.CorrectLevel.L, // 二维码可辨识度
callback: (res) => {
this.ewmImg = res.path
}
})
}
},
data() {
return {
orderInfo: {}
orderInfo: {},
ewmImg: ''
}
},
methods: {
async oneMoreOrder(item) {
uni.removeStorageSync('shopCarInfo');
$EventBus.$emit('updateCar');
const numObj = {}
const { id, shopId, orderDetails } = item;
orderDetails.forEach(item => {
orderDetails[item.skuId] = item.num
})
const { data } = await Order.moreOrder({ orderId: id, shopId });
data.data.forEach(item => {
const skuId = item.skus[0].skuId
const nextData = { ...item, skuId, num: orderDetails[skuId], flag: true, sku: item.skus[0] }
if (nextData.sku.state == 1) {
Utils.getallNum(nextData)
}
});
uni.switchTab({ url: '/pages/menu/menu' })
},
async PayNow() {
const orderInfo = await Order.payOrder({ orderId: this.orderInfo.id })
if (orderInfo) {
if (orderInfo && orderInfo.data.code == 200) {
await Menu.requestPayment(orderInfo.data.data);
}
}
},
toRefund() {
uni.showModal({
title: '确认退款',
success: (res) => {
if (res.confirm) {
Order.orderRefund({ orderId: this.orderInfo.id, refundAmount: this.orderInfo.amount }).then(res => {
console.log(res);
uni.switchTab({ url: '/pages/menu/menu' })
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
},
jsonParse(json) {
return JSON.parse(json)
},
cancelOrder() {
Order.cancelOrder({ orderId: this.orderInfo.id }).then(res => {
uni.switchTab({ url: '/pages/menu/menu' })
})
},
},
computed: {
qrShow() {
return ['8', '9', '10', '11', '12', '13', '14', '15', '50'].indexOf(this.orderInfo.state) == -1
},
isBuildQrcode() {
return
},
orderStatusText() {
switch (this.orderInfo.state) {
case '1':
return '未支付'
case '2':
return '已支付'
case '3':
return '排队中'
case '4':
return '制作完成'
case '5':
return '取餐中'
case '6':
return '已完成'
case '7':
return '待取超时'
case '8':
return '已取消取消'
case '9':
return '已取消取消'
case '10':
return '已取消取消'
case '11':
return '已取消取消'
case '12':
return '退款中'
case '13':
return '退款失败'
case '14':
return '部分退款'
case '15':
return '已退款'
default:
return '未知状态'
}
}
}
}
......@@ -136,7 +243,7 @@ export default {
.order_status {
width: 686rpx;
height: 174rpx;
max-height: 174rpx;
background: #FFFFFF;
border-radius: 10rpx;
margin: 32rpx auto 0;
......@@ -150,13 +257,22 @@ export default {
text-align: center;
}
.btns {
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.btn {
width: 160rpx;
height: 52rpx;
background: #006ECF;
border-radius: 6rpx;
display: block;
margin: 20rpx auto;
display: inline-block;
margin: 20rpx;
padding: 0;
line-height: 52rpx;
font-family: PingFangSC-Medium, PingFang SC;
......@@ -190,6 +306,24 @@ export default {
display: block;
margin: 25rpx auto;
background-color: #ccc;
position: relative;
.status_text {
font-size: 48rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #FFFFFF;
line-height: 66rpx;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.qr {
width: 100%;
height: 100%;
}
}
.flow_describe {
......@@ -258,8 +392,8 @@ export default {
.goods {
margin-top: 35rpx;
padding-top: 35rpx;
margin-top: 10rpx;
padding-top: 15rpx;
.goods_item {
display: flex;
......
......@@ -3,26 +3,32 @@
<div class="shop_info">
<h3>门店确认</h3>
<div class="address">
<div class="address_1">北京朝阳建外SOHO东区A座店</div>
<div class="address_2">距您132m,请确定门店后下单</div>
<div class="address_1">{{ shopData.name }}</div>
<div class="address_2">距您{{ shopData.distance }},请确定门店后下单</div>
</div>
<div class="take_order">
<div class="title">取单时间</div>
<div class="time">现在下单,预计 <span class="min">5</span> 分钟后取餐</div>
<div class="time">现在下单,预计 <span class="min">{{ duration }}</span> 分钟后取餐</div>
</div>
</div>
<div class="goods_info">
<h3>商品详情</h3>
<div class="goods" v-for="item in goods" :key="item.goodsId">
<div class="goods_item">
<image mode="aspectFit" class="goods_img" src=""></image>
<image mode="aspectFit" v-if="item.pics.thumbnailApplet" class="goods_img"
:src="item.pics.thumbnailApplet"></image>
<image v-else class="goods_img" :src="item.pics.thumbnail"></image>
<div class="goods_text">
<div class="goods_name">
<div class="name">{{ item.name }}</div>
<div class="price">¥{{ item.sku.price }}</div>
<div class="price">¥{{ setPrice(item.sku.price) }}</div>
</div>
<div class="goods_psce">
<div class="psce_name">/</div>
<div class="psce_name">
<span v-for="rule in item.sku.rules" :key="rule.ruleId">{{ rule.ruleName }}/</span>
</div>
<div class="size">x {{ item.num }}</div>
</div>
</div>
......@@ -30,11 +36,11 @@
<div class="discount">
<div class="discount_1">
<div class="name">优惠免减</div>
<div class="price">- ¥{{ itemReduction(item.sku.discount, item.sku.price) }}</div>
<div class="price">- ¥{{ itemReduction(item.sku.discount, item.sku.price, item.num) }}</div>
</div>
<div class="concessional_rate">
<div class="name">特惠价</div>
<div class="price">¥{{ item.sku.discount }}</div>
<div class="price">¥{{ setPrice(item.sku.discount * item.num) }}</div>
</div>
</div>
</div>
......@@ -54,7 +60,7 @@
<span>微信支付</span>
</div>
</div>
<div style="height:150rpx"></div>
<div class="footer">
<div class="total">
<div class="the_sum">
......@@ -65,11 +71,11 @@
<div class="price">总优惠¥{{ reduction }}</div>
</div>
</div>
<view class="payment" @click="saveReserve" v-if="userms">
<view class="payment" @click="messageAndSave" v-if="userms">
付款
</view>
<button v-if="!userms" class="payment" style="border-radius: 0;" open-type="getPhoneNumber"
@getphonenumber="saveReserve">
@getphonenumber="getPhoneNumber">
付款
</button>
......@@ -78,25 +84,80 @@
</template>
<script>
import { $EventBus } from "../../../utils/EventBus";
import { $EventBus } from "@/utils/EventBus";
import Utils from '@/utils/utils'
import Menu from '@/request/menu'
import User from '@/request/user'
import Order from '@/request/order'
export default {
onShow() {
if (this.goods) {
Order.getWaitTine({
shopId: uni.getStorageSync('shopData').id,
goods: this.goods
}).then(({ data }) => {
this.duration = data.data
})
}
},
onLoad(option) {
this.buyType = option.buyType;
console.log(uni.getStorageSync('shopCarInfo'));
this.goods = uni.getStorageSync('shopCarInfo') || [];
$EventBus.$on('updateCar', () => {
this.goods = uni.getStorageSync('shopCarInfo') || [];
});
// 商品详情页点击立即支付进入
if (option.goodsList) {
const shopData = uni.getStorageSync('shopData');
this.shopData = shopData
this.buyType = 3;
console.log(uni.getStorageSync('goodsList'));
this.goods = uni.getStorageSync('goodsList') || [];
this.payType = '2'
return
}
// 微信扫码进入
this.option = JSON.stringify(option)
const { q } = option;
if (q) {
User.getLocation((location) => {
uni.removeStorageSync('shopCarInfo');
$EventBus.$emit('updateCar');
this.buyType = 'A';
let id = decodeURIComponent(q).split('?')[1].split('=')[1];
Menu.getScreenShopCar(id, location).then(res => {
const data = JSON.parse(res.data.data);
this.shopData = data.shop;
this.goods = data.goods.map(item => {
const data = { ...item, skuId: item.sku.skuId, flag: true }
Utils.getallNum(data)
return data
})
})
})
return
}
// 购物车点击进入
const shopData = uni.getStorageSync('shopData');
this.shopData = shopData
this.buyType = 3;
const shopCarInfo = uni.getStorageSync('shopCarInfo') || []
this.goods = shopCarInfo.filter(item => item.flag);
Order.getWaitTine({
shopId: uni.getStorageSync('shopData').id,
goods: this.goods
}).then(({ data }) => {
this.duration = data.data
})
},
data() {
return {
goods: [],
buyType: ''
buyType: '',
shopData: {},
option: '',
payType: '1',
duration: ''
}
},
computed: {
userms() {
return this.$store.getters.Authorization;
......@@ -108,7 +169,6 @@ export default {
})
return totalNum
},
reduction() {
let price = 0;
let discountNum = 0;
......@@ -118,7 +178,7 @@ export default {
discountNum += item.num * sku.discount
price += item.num * sku.price
} else {
totalPrice += 0
discountNum += 0
price += 0
}
})
......@@ -126,27 +186,56 @@ export default {
},
totalPrice() {
let totalPrice = 0;
this.goods.forEach(item => {
const sku = item.sku;
item.flag ? totalPrice += item.num * sku.discount : totalPrice += 0
item.flag ? totalPrice += (item.num * sku.discount) : (totalPrice += 0)
})
return totalPrice
return totalPrice.toFixed(2)
}
},
methods: {
itemReduction(discount, price) {
return (price - discount).toFixed(2)
itemReduction(discount, price, num) {
return ((price - discount) * num).toFixed(2)
},
// 手机号授权登录
getPhoneNumber(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
User.getPhoneNumber(e);
} else if (e.detail.errMsg == "getPhoneNumber:fail user deny") {
uni.showToast({ title: '已拒绝手机号授权', icon: 'error' })
}
},
messageAndSave() {
wx.requestSubscribeMessage({
tmplIds: ['1uErx-15S-3vuopXSvvsxCeM_Jd-1iZC-nXzd2yW3QU', 'Q4HDwBEvpTXpwtZktqWm4SZOTEuQK1x48xjqjD2GqyM', 'Fu_CPIXa0cnJ4EDdVKqFQ3qqKJccMqt2oorI5mfNq74'],
success: () => {
uni.setStorageSync('isMessage', 'true')
User.setAllow(1)
this.saveReserve()
},
fail: () => {
User.setAllow(2)
this.saveReserve()
}
})
},
//结算组装数据发起订单
async saveReserve() {
// 组装购物车数据或者立即支付数据
let res = await Utils.AssemblyOrder(this.totalPrice, this.totalNum, this.buyType);
let list = [];
if (this.payType == '1') {
list = uni.getStorageSync('shopCarInfo').filter((v) => v.flag == true);
} else {
list = uni.getStorageSync('goodsList').filter((v) => v.flag == true);
}
let res = await Utils.AssemblyOrder(this.totalPrice, this.totalNum, this.buyType, list);
if (res) {
// 发起订单
let orderInfo = await Menu.saveReserve(res);
if (orderInfo && orderInfo.data.code == 200) {
let payMent = await Menu.requestPayment(orderInfo.data.data, res, this.buyType);
await Menu.requestPayment(orderInfo.data.data, res, this.buyType);
}
}
}
......
......@@ -3,13 +3,6 @@
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
"pages": [
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/menu/menu",
"style": {
......@@ -76,7 +69,22 @@
},
{
"root": "mineSubPackage",
"pages": []
"pages": [
{
"path": "pages/msg/index",
"style": {
"navigationBarTitleText": "消息列表",
"enablePullDownRefresh": false
}
},
{
"path": "pages/msgInfo/index",
"style": {
"navigationBarTitleText": "消息详情",
"enablePullDownRefresh": false
}
}
]
}
],
"globalStyle": {
......@@ -86,16 +94,28 @@
"backgroundColor": "#ffffff"
},
"tabBar": {
"custom": true,
"custom": false,
"color": "#000000",
"selectedColor": "#006ECF",
"iconWidth": "32px",
"list": [
{
"pagePath": "pages/menu/menu"
"iconPath": "/static/imgs/icon-unselect-menu.png",
"selectedIconPath": "/static/imgs/icon-selected-menu.png",
"pagePath": "pages/menu/menu",
"text": "菜单"
},
{
"pagePath": "pages/order/order"
"iconPath": "/static/imgs/icon-unselect-order.png",
"selectedIconPath": "/static/imgs/icon-selected-order.png",
"pagePath": "pages/order/order",
"text": "订单"
},
{
"pagePath": "pages/mine/mine"
"iconPath": "/static/imgs/icon-unselect-mine.png",
"selectedIconPath": "/static/imgs/icon-selected-mine.png",
"pagePath": "pages/mine/mine",
"text": "我的"
}
]
}
......
......@@ -15,59 +15,59 @@ export default {
}
},
onLoad(options) {
this.id = '';
this.$store.commit('setOrderId', '');
if (options.q) {
let url = decodeURIComponent(options.q);
this.id = url.split('/')[url.split('/').length - 1];
this.$store.commit('setOrderId', this.id);
}
uni.reLaunch({url: '/pages/menu/menu'})
// this.id = '';
// this.$store.commit('setOrderId', '');
// if (options.q) {
// let url = decodeURIComponent(options.q);
// this.id = url.split('/')[url.split('/').length - 1];
// this.$store.commit('setOrderId', this.id);
// }
// this.id=1;
},
async onShow() {
// let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
// let curRoute = routes[routes.length - 1].route //获取当前页面路由
//   let curParam = routes[routes.length - 1].options;
//  console.log(curParam)
let Authorization = uni.getStorageSync(`Authorization`);
let userPhoneInfo = uni.getStorageSync(`userPhoneInfo`);
if (Authorization && userPhoneInfo) {
this.$store.commit('setUserPhoneInfo', userPhoneInfo);
this.$store.commit('setAuthorization', Authorization);
if (this.id != '') {
uni.navigateTo({
url: `/menuSubPackage/pages/settlement/settlement?orderId=${this.id}&buyType=3`
})
} else {
uni.reLaunch({
url: '/pages/menu/menu'
})
}
} else {
uni.removeStorageSync('Authorization');
uni.removeStorageSync('userPhoneInfo');
if (this.id != '') {
let _this = this;
uni.showToast({
title: '请授权登录',
icon: 'error',
success() {
setTimeout(() => {
uni.reLaunch({
url: '/pages/menu/menu?orderId=' + _this.id
})
}, 1500)
}
})
} else {
uni.reLaunch({
url: '/pages/menu/menu'
})
}
// async onShow() {
// // let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
// // let curRoute = routes[routes.length - 1].route //获取当前页面路由
// //   let curParam = routes[routes.length - 1].options;
// let Authorization = uni.getStorageSync(`Authorization`);
// let userPhoneInfo = uni.getStorageSync(`userPhoneInfo`);
// if (Authorization && userPhoneInfo) {
// this.$store.commit('setUserPhoneInfo', userPhoneInfo);
// this.$store.commit('setAuthorization', Authorization);
// if (this.id != '') {
// uni.navigateTo({
// url: `/menuSubPackage/pages/settlement/settlement?orderId=${this.id}&buyType=3`
// })
// } else {
// uni.reLaunch({
// url: '/pages/menu/menu'
// })
// }
// } else {
// uni.removeStorageSync('Authorization');
// uni.removeStorageSync('userPhoneInfo');
// if (this.id != '') {
// let _this = this;
// uni.showToast({
// title: '请授权登录',
// icon: 'error',
// success() {
// setTimeout(() => {
// uni.reLaunch({
// url: '/pages/menu/menu?orderId=' + _this.id
// })
// }, 1500)
// }
// })
// } else {
// uni.reLaunch({
// url: '/pages/menu/menu'
// })
// }
}
},
// }
// },
methods: {
}
}
......
<template>
<view class="menu-box" :style="{ height: `${height}px` }">
<view class="menu-box">
<view class="menu-banner">
<image src="../../static/imgs/banner.png"></image>
<view class="shop-info" :style="{ top: `${menuINfo.top}px` }">
<view class="shop-box"
:style="{ height: `${menuINfo.height}px`, 'line-height': `${menuINfo.height}px` }"
@click="changeLocaltion">
<text class="shop-name">{{ shopInfo.name }}</text>
<view class="shop-info" :style="'top:120rpx'">
<view class="shop-box">
<text @click="openShow" class="shop-name">{{ shopInfo.name }}</text>
<u-icon name="arrow-right" class="arrow-right-select" color="#FFFFFF"></u-icon>
</view>
<view class="distance">距您130m</view>
<view v-if="shopInfo.distance" class="distance">距您{{ shopInfo.distance }}</view>
</view>
<view class="login-area">
<view class="avatar">
<image :src="'../../static/logo.png'"></image>
</view>
<view class="user-info">
<view class="user-name" v-if="userms">HI!{{ '我是谁' }}</view>
<view class="user-info" @click="goToMyPage(userms)">
<view class="user-name" v-if="userms">HI!{{ userInfo.customerName || '我是谁' }}</view>
<view class="user-name" v-else>未登录</view>
<view class="dialog">
<view class="content" v-if="userms">希望你今天,明天,天天都开心~</view>
......@@ -30,179 +28,155 @@
</view>
<view class="order-banner" v-if="buied">
<view class="info">
<view class="first">取单码:Mon999</view>
<view class="second">请您耐心等候,剩余等候时间<text class="time">3</text>分钟</view>
<view class="first">取单码:{{ orderInfo.orderNum }}</view>
<view class="second">请您耐心等候,剩余等候时间<text class="time">{{ orderInfo.waitTime }}</text>分钟</view>
</view>
<view class="line"></view>
<view class="barCode-box">
<view class="barCode">
<image :src="'../../static/logo.png'"></image>
<view @click="openQrcode" class="barCode">
<image :src="'../../static/imgs/icon-barcode.png'"></image>
</view>
<view class="barCode-dis">点击二维码取单</view>
</view>
</view>
<view class="page-body">
<scroll-view class="nav-left" scroll-y :style="{ height: `${height - bannerh}px` }"
:scroll-top="scrollLeftTop" scroll-with-animation>
<view class="nav-left-item" @click="categoryClickMain(index)" :key="index"
:class="index == categoryActive ? 'active' : ''" v-for="(item, index) in classifyData">
{{ item.name }}
<view :class="index == categoryActive ? 'active-line' : ''"></view>
</view>
</scroll-view>
<scroll-view class="nav-right" scroll-y :scroll-top="scrollTop" @scroll="scroll"
:style="{ height: `${height - bannerh}px` }" scroll-with-animation>
<view v-for="category in classifyData" :key="category.id" class="box">
<view class="right-title">{{ category.name }}</view>
<view class="nav-right-item" v-for="item in category.goods" :key="item.goodsId"
@click="cart(item, category)">
<image class="thumbnail" :src="item.pics.thumbnail" />
<view class="info">
<view class="goods-name">{{ item.name }}</view>
<view class="tags">
<view class="tag-item" v-for="tag in item.tags" :key="tag">{{ tag }}</view>
</view>
<view class="dis-box">
<view class="dis">{{ item.desc }}</view>
<view class="add-btn" @click.stop="getallNum(item, category)">+</view>
</view>
<view class="mon">
<view class="discount">{{ item.discount }}</view>
<view class="price"><text class="num">{{ item.price }}</text></view>
</view>
</view>
</view>
</view>
</scroll-view>
<shopCar ref="shopbar"></shopCar>
<tabBar :selectedTabbar="selectedTabbar"></tabBar>
</view>
<ShopCar ref="shopbar" />
<MenuAssembly ref="MenuAssembly" @getallNum="getallNum" />
<u-picker @cancel="show = false" :show="show" :immediateChange="true" ref="uPicker" :columns="columns"
@confirm="confirm" keyName="name" @change="changeHandler"></u-picker>
<OrderQrCode ref="OrderQrCode" />
<canvas class="canvas-code" canvas-id="myQrcode2"
style="background:#fff;width: 200px;height: 200px; display:block; left:-800rpx;position:absolute;" />
</view>
</template>
<script>
import MenuAssembly from '@/components/menuAssembly'
import User from '@/request/user'
import ShopCar from '../../components/shopCar/shopCar.vue'
import Utils from '@/utils/utils'
import Menu from '@/request/menu'
import { $EventBus } from '@/utils/EventBus';
import Order from '@/request/order'
import OrderQrCode from '@/components/OrderQrCode'
import QRCode from '@/utils/qrCode'
export default {
components: { ShopCar },
components: { ShopCar, MenuAssembly, OrderQrCode },
data() {
return {
orderId: null,// 如果有扫码进来的支付orderId则存入
shopInfo: { name: '请选择' },// 店铺信息
menuINfo: {},
buied: false,//控制首页取单码区域显隐
orderBannerh: 0,
bannerh: 0,
name: "wkiwi",
height: 0,
categoryActive: 0,
scrollTop: 0,
scrollLeftTop: 0,
// scrollHeight: 0,
orderInfo: {},//即将取餐的订单信息
classifyData: [],
arr: [0, 584, 1168, 1752, 2336, 2805, 3274, 3858, 4442, 4911, 5380, 5734, 6203, 6672, 7017],
leftItemHeight: 51,
navLeftHeight: 0,
diff: 0,
tabBarHeight: 50,
selectedTabbar: 0, //选中的tab
customerName: '',
show: false,
columns: []
};
},
computed: {
userms() {
let res = this.$store.getters.Authorization;
return res;
}
return this.$store.getters.Authorization;
},
created() {
this.getLocation();
this.menuINfo = uni.getMenuButtonBoundingClientRect();
//如果你的分类数据为后台异步获取请 将下方代码放置你的数据回调中
// this.$nextTick(()=>{
// this.getHeightList();
// })
userInfo() {
return this.$store.state.user.userInfo;
},
async onShow() {
let _this = this;
// 获取首页菜单数据
let shopInfo = this.$store.getters.shopInfo;
if (shopInfo && shopInfo[0]?.id) {
await this.getMenuList(shopInfo[0].id);
} else {
await this.getMenuList(12);
}
uni.createSelectorQuery().select(".menu-banner").boundingClientRect(data => {
_this.bannerh = data.height;
}).exec();
if (this.buied) {
uni.createSelectorQuery().select(".order-banner").boundingClientRect(data => {
_this.orderBannerh = data.height;
_this.height = uni.getSystemInfoSync().windowHeight - _this.tabBarHeight - _this.orderBannerh;
}).exec();
}
else {
this.height = uni.getSystemInfoSync().windowHeight - this.tabBarHeight;
}
this.getHeightList();
},
onHide() {
this.$refs.shopbar.showShopCar = false;
created() {
this.getLocation()
},
onLoad: async function (options) {
if (options.orderId) { this.orderId = options.orderId; }
onLoad: async function () {
User.getAddress()
$EventBus.$off('getMenuList')
$EventBus.$on('getMenuList', (data) => {
this.shopInfo = data;
this.getMenuList(data.id)
})
},
onReady() { },
onHide() {
this.$refs.shopbar.showShopCar = false;
},
async onShow() {
if (!this.userms) return;
const res = await Order.getHomeOrder()
const data = res?.data
if (data?.data) {
this.buied = true;
this.orderInfo = data.data
} else {
this.buied = false
}
},
methods: {
// 获取用户授权登录
uniGetUserInfo() { User.uniGetUserInfo(); },
openQrcode() {
new QRCode('myQrcode2', {
text: this.orderInfo.pickCode,
width: 141, //canvas 画布的宽
height: 141, //canvas 画布的高
padding: 0, // 生成二维码四周自动留边宽度,不传入默认为0
correctLevel: QRCode.CorrectLevel.L, // 二维码可辨识度
callback: (res) => {
this.$refs.OrderQrCode.open(this.orderInfo, res.path)
}
})
},
openShow() {
const postion = uni.getStorageSync('location');
if (postion) {
Order.getShop(postion).then(res => {
const data = res.data.data
const two = data[0].children
const three = two[0].children
this.columns = [[...data], [...two], [...three]]
this.show = true
})
return
}
this.getLocation((data) => {
Order.getShop(data).then(res => {
const data = res.data.data
const two = data[0].children
const three = two[0].children
this.columns = [[...data], [...two], [...three]]
this.show = true
})
})
},
changeHandler() { },
confirm(res) {
const { value } = res;
const shops = value[2].shops;
this.show = false;
console.log(shops);
uni.setStorageSync('shops', shops);
uni.navigateTo({ url: '/menuSubPackage/pages/areaSelect/areaSelect' })
},
// 手机号授权登录
getPhoneNumber(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
User.getPhoneNumber(e, this.orderId);
User.getPhoneNumber(e);
} else if (e.detail.errMsg == "getPhoneNumber:fail user deny") {
uni.showToast({ title: '已拒绝手机号授权', icon: 'error' })
}
},
changeLocaltion() {
uni.navigateTo({ url: '/menuSubPackage/pages/areaSelect/areaSelect' })
},
// 获取定位授权
getLocation() {
let _this = this;
getLocation(callback) {
uni.getSetting({
success: (res) => {
if (!res.authSetting['scope.userLocation']) {
uni.authorize({
scope: 'scope.userLocation',
success: (e) => { //1.1 允许授权
User.getLocation();
success: () => { //1.1 允许授权
User.getLocation(data => {
callback ? callback(data) : User.getAddress()
});
},
fail: (err) => { //1.2 拒绝授权
uni.showModal({
title: '提示',
content: '您已拒绝授权定位,请重新开启',
confirmText: '去开启',
success() {
uni.openSetting({
success(res) {
if (res.authSetting['scope.userLocation'] == true) {
User.getLocation();
}
}
})
}
})
wx.exitMiniProgram({ success: (res) => { } })
}
})
} else {
User.getLocation();
User.getLocation(data => {
callback && callback(data)
});
}
}
})
......@@ -212,14 +186,14 @@ export default {
if (data.code == 200) {
data.data = data.data;
this.$store.commit('setMenuAllInfo', data.data);
this.classifyData = data.data.categorys;
this.$refs.MenuAssembly.createList(data.data.categorys)
}
},
// 加入购物车数据
getallNum(item, category) {
let itemCopy = JSON.parse(JSON.stringify(item));
const sku = itemCopy.skus.find(v => v.isDefault == 1 && v.state != 2) || itemCopy.skus.find(v => v.isDefault == 0 && v.state != 2);
if (!itemCopy.skus) {
if (!sku) {
uni.showToast({ title: '本商品已经售罄', icon: 'none' });
return;
} else {
......@@ -233,58 +207,18 @@ export default {
Utils.getallNum(itemCopy);
}
},
getHeightList() {
let _this = this;
let selectorQuery = uni.createSelectorQuery();
selectorQuery.selectAll(".nav-left-item").boundingClientRect(function (rects) {
_this.leftItemHeight = rects[0].height;
_this.navLeftHeight = _this.leftItemHeight * _this.classifyData.length;
_this.diff = _this.navLeftHeight; //- _this.height
});
selectorQuery.selectAll(".box").boundingClientRect(function (rects) {
let arr = [0], top = 0;
rects.forEach(function (rect) {
top += rect.height;
arr.push(top);
});
_this.arr = arr;
}).exec();
},
scroll(e) {
let _this = this;
if (this.timeoutId) { clearTimeout(this.timeoutId) }
this.timeoutId = setTimeout(function () {//节流
_this.scrollHeight = e.detail.scrollTop + 1 + _this.height / 2;
//+1不要删除,解决最后一项某种情况下翻到底部,左边按钮并不会切换至最后一个
//若想使切换参考线为屏幕顶部请删除 _this.height/2
for (let i = 0; i < _this.arr.length; i++) {
let height1 = _this.arr[i];
let height2 = _this.arr[i + 1];
if (!height2 || (_this.scrollHeight >= height1 && _this.scrollHeight < height2)) {
_this.categoryActive = i;
_this.diff > 0 && (_this.scrollLeftTop = Math.round((_this.categoryActive * _this.diff) / (_this.classifyData.length)));
return false;
}
}
_this.categoryActive = 0;
_this.timeoutId = undefined;
}, 0);
},
categoryClickMain(index) {
this.categoryActive = index;
this.scrollTop == this.arr[index] ? (this.scrollTop = this.scrollTop + 1) : (this.scrollTop = this.arr[index]); //防止两次相等造成点击不触发滚动时间
},
cart: (item, category) => {
uni.setStorageSync('goodsInfo', JSON.stringify({ ...item, category }));
uni.navigateTo({ url: '/menuSubPackage/pages/goodsDetail/goodsDetail' })
goToMyPage(logined) {
logined && uni.switchTab({ url: '/pages/mine/mine' })
}
},
}
</script>
<style lang="scss">
<style lang="scss" scoped>
.menu-box {
min-height: 100vh;
.shop-info {
position: absolute;
left: 32rpx;
......@@ -479,7 +413,6 @@ export default {
.barCode {
width: 86rpx;
height: 86rpx;
background: #006ECF;
image {
width: 100%;
......@@ -498,192 +431,4 @@ export default {
}
}
}
.page-body {
display: flex;
background: #fff;
overflow: hidden;
}
.nav {
display: flex;
width: 100%;
}
.nav-left {
width: 152rpx;
background: #fff;
border-right: 2rpx solid #D5D5D5;
}
.nav-left-item {
position: relative;
height: 170rpx;
line-height: 170rpx;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
display: flex;
align-items: center;
justify-content: center;
}
.nav-left-item:last-child {
border-bottom: none;
}
.nav-right {
width: 596rpx;
}
.box {
display: block;
overflow: hidden;
/* min-height: 100vh; */
/*若您的子分类过少想使得每个子分类占满屏请放开上边注视 */
}
.box:last-child {
border: none;
// min-height: 100vh;
}
.right-title {
padding-left: 28rpx;
margin-bottom: 40rpx;
height: 44rpx;
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #000000;
line-height: 44rpx;
}
.nav-right-item {
display: flex;
padding: 0rpx 36rpx 0rpx 42rpx;
margin-bottom: 50rpx;
height: 162rpx;
background: #fff;
.thumbnail {
//缩略图
display: flex;
align-items: center;
width: 140rpx;
height: 140rpx;
margin-right: 34rpx;
}
.info {
flex: 1;
.goods-name {
height: 40rpx;
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 40rpx;
}
.tags {
.tag-item {
height: 24rpx;
border-radius: 4rpx;
border: 2rpx solid #006ECF;
margin-right: 10rpx;
padding: 4rpx 6rpx;
font-size: 16rpx;
font-family: ArialMT;
color: #006ECF;
line-height: 24rpx;
display: inline-block;
}
}
.dis-box {
display: flex;
font-size: 20rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 40rpx;
.dis {
flex: 1;
}
.add-btn {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
background: #006ECF;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 36rpx;
}
}
.mon {
.discount {
display: inline-block;
height: 32rpx;
font-size: 24rpx;
font-family: Arial-BoldMT, Arial;
font-weight: normal;
color: #EB5F17;
line-height: 32rpx;
margin-right: 6rpx;
}
.price {
display: inline-block;
height: 22rpx;
font-size: 20rpx;
font-family: ArialMT;
color: #666666;
line-height: 22rpx;
.num {
text-decoration: line-through;
}
}
}
}
}
.nav-right-item image {
width: 150rpx;
height: 150rpx;
}
.active {
font-weight: 600;
color: #000000;
background: #fff;
}
.active-line {
height: 170rpx;
width: 2rpx;
position: absolute;
right: -2rpx;
top: 0;
z-index: 1;
border-right: 4rpx solid #006ECF;
;
}
::-webkit-scrollbar {
/*取消小程序的默认导航条样式*/
width: 0;
height: 0;
color: transparent;
}
</style>
<template>
<view>
<!-- 单向联动菜单 -->
<view class="scroll-box" :style="{ 'height': scrollHeight +'px' }">
<!-- 左边栏 -->
<view class="left-tab">
<scroll-view class="tab" scroll-y="true" scroll-with-animation >
<block v-for="(item,index) in tabData" :key="index" >
<!-- 标签动态样式 -->
<view class="tab-item" :class=" [currentTab==index ? 'active' : 'none'] " @click="clickTab"
:data-current="index" :data-title="[item.title]" >
{{item.title}}
</view>
</block>
</scroll-view>
</view>
<!-- 右边页面 -->
<scroll-view class="right-box" scroll-y="true" :scroll-top="scrollTop" @scroll="scroll" >
<view class="page-view">
<view class="class-item">
<view class="item-title">
<text>{{goodsTitle}}</text>
</view>
<view class="item-container">
<view class="thumb-box" v-for="(item, index) in menuData" :key="index">
<view class="left-image">
<image class="item-menu-image" :src="item.imgUrl" mode=""></image>
</view>
<view class="right-text">
<view class="item-menu-name">{{item.name}}</view>
<view class="item-menu-explain">{{item.explain}}</view>
<view class="item-menu-ps">
<view class="item-menu-price">¥{{item.price}}</view>
<!-- Animate动画库使用 https://blog.csdn.net/qq_40976321/article/details/107379659 -->
<view class="item-menu-select" hover-class="animated rotateOut" @click="addCar" :data-item="[item]">加购</view>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 底部购物车 -->
<view class="car" v-if="isShowCar">
<view class="car-left">
<view class="car-pice">¥{{totalPrice}}</view>
</view>
<view class="car-right">
<view class="car-text">选好了</view>
</view>
</view>
<!-- 凸起图标 -->
<view class="car-img-back" v-if="isShowCar" @click="clickCar">
<image class="car-img" src="../../../static/icon/png/bag.png" mode=""></image>
<!-- 角标 -->
<view class="car-num">
<text class="car-num-text">{{totalNum}}</text>
</view>
</view>
<!-- 购物车列表 -->
<view class="car-list" v-if="isShowList">
<scroll-view scroll-y="true" style="height: 500rpx;">
<view class="car-box" v-for="(item, index) in carData" :key="index">
<view class="car-left-image" style="width: 23%;">
<image class="car-menu-image" :src="item.imgUrl" mode=""></image>
</view>
<view class="car-right-text" style="width: 73%;">
<view class="car-menu-name">{{item.name}}</view>
<view class="car-menu-explain">{{item.explain}}</view>
<view class="car-menu-ps">
<view class="car-menu-price" >¥{{item.price}}</view>
<view class="car-num-select" >
<view @click="clickMinus(index)">
<image style="width: 48rpx;height: 48rpx;" src="../../../static/icon/png/jian.png" ></image>
</view>
<view style="margin: 0rpx 15rpx;font-size: 28rpx;"> {{item.num}} </view>
<view @click="clickAdd(index)">
<image style="width: 48rpx;height: 48rpx;" src="../../../static/icon/png/jia.png" ></image>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 遮罩层 -->
<view class="car-mark" v-if="isShowCarMark" @click="clickCarMark"></view>
</view>
</template>
<script>
export default {
data() {
return {
menuData:[]
}
},
methods:{
//点击左边类别栏事件
clickTab(e) {
let clickIndex = e.target.dataset.current //当前标签的索引
this.currentTab = clickIndex
let tapTitle = e.target.dataset.title //获得点击的标题
this.goodsTitle = tapTitle[0]
//对数组进行筛选,让右边的列表只显示对应类别的数据
this.menuData = this.tempData.filter(item => item.title == this.goodsTitle)
//滚动条返回顶部
this.scrollTop = 0
},
//记录滚动条位置
scroll : function(e) {
this.scrollTop = e.detail.scrollTop
},
//显示、隐藏购物车清单
clickCar(){
this.isShowList = !this.isShowList
this.isShowCarMark = !this.isShowCarMark
},
clickCarMark(){
this.isShowList = !this.isShowList
this.isShowCarMark = !this.isShowCarMark
},
//**********商品加入购物车 ***************
addCar(e){
//获得点击加购的商品数据
let item = e.target.dataset.item[0]
//如果购物车里的商品name = 点击数据商品name 则返回此元素下标
let index = this.carData.findIndex(ev => ev.name === item.name)
//如果购物车不存在相同的商品
if(index === -1) {
item.num = 1 //添加数量属性num ,默认为 1【原数据没有数量字段】
this.carData.push(item) //把商品追加进购物车
} else {
this.carData[index].num++ //存在相同的商品则数量叠加
}
//更新总数与总价
this.allNum()
this.allPrice()
//显示购物车
this.isShowCar = true
},
//增加数量
clickAdd(index){
this.carData[index].num = this.carData[index].num + 1
this.allNum()
this.allPrice()
},
//减少数量,小于1时删除元素
clickMinus(index){
if(this.carData[index].num > 1){
this.carData[index].num = this.carData[index].num - 1
} else {
this.carData.splice(index,1) //从数组删除元素
}
this.allNum()
this.allPrice()
},
// 计算商品总数量
allNum() {
let count = 0;
this.carData.forEach(item=>{
count+=item.num
})
this.totalNum = count
//购物车有商品的时候,滚动栏高度减少,让出位置给购物车
if(this.totalNum === 1 && this.isAddHeight){
this.scrollHeight = this.scrollHeight - 50
this.isAddHeight = false
}
//购物车没有商品的时候,隐藏组件,还原滚动栏高度
if (this.totalNum === 0){
this.scrollHeight = this.scrollHeight + 50
this.isAddHeight = true
this.isShowCar = false
this.clickCar()
}
},
// 计算商品总价格
allPrice() {
let Price = 0;
this.carData.forEach(item=>{
//总价格=数量 X 单价 ,由于数组的单价是字符串类型,所以要先转换成浮点数字类型
Price+=item.num * parseFloat(item.price)
})
//Number类型的数据调用toFixed方法,指定保留几位小数,返回的数据是一个string类型
this.totalPrice = Price.toFixed(2)
},
}
}
</script>
<style lang="scss">
.scroll-box{
display: flex;
flex-direction: row;
/* 需要定义高度,否则不能分栏滚动 */
/* height: calc(78.2vh); */
}
.left-tab{
flex: 1; /*均匀分配元素*/
display: flex;
overflow: hidden;
background: #f6f6f6;
}
.tab{
width: 150rpx;
height: 100%;
}
.tab-item{
height: 100rpx;
background: #f6f6f6;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
line-height: 1;
}
.active{ /* 选项卡活动时的样式 */
color:#A7D500;
font-weight: bolder;
background: #ffffff;
}
/* 右边页面样式 */
.right-box {
left: 15%;
width: 80%;
background: #f6f6f6;
}
.page-view {
padding: 10rpx;
}
.class-item {
margin-bottom: 30rpx;
background-color: #fff;
padding: 16rpx;
border-radius: 8rpx;
}
.item-title {
font-size: 26rpx;
color: $u-main-color;
font-weight: bold;
}
.item-container {
display: flex;
flex-direction: column;
}
.thumb-box {
width: 98%;
height: 150rpx;
display: flex;
flex-direction: row;
align-items: center;
/* justify-content: center; */
margin-top: 50rpx;
}
.item-menu-image {
width: 150rpx;
height: 150rpx;
}
.item-menu-name {
font-weight: normal;
font-size: 28rpx;
margin-bottom: 10rpx;
}
.item-menu-explain{
font-size: 20rpx;
margin-bottom: 10rpx;
/* 下方四项配合使用,超出范围的显示... */
width: 400rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.item-menu-ps{
display: flex;
flex-direction: row;
justify-content: space-between; /*两边对齐*/
}
.item-menu-price{
font-size: 26rpx;
font-weight: 600;
}
.item-menu-select{
width: 100rpx;
height: 36rpx;
/* 文字垂直居中 (line-height)和(height)设置一样就可以 */
line-height: 36rpx;
/* 文字水平居中 */
text-align:center;
font-size: 22rpx;
background-color: #A7D500;
border-radius: 50rpx;
}
/* 购物车 */
.car{
display: flex;
flex-direction: row;
align-items: center;
height: 100rpx;
width: 100%;
position: fixed;
bottom: 0rpx;
background-color:#ffffff ;
z-index: 79;
}
.car-img-back{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 100rpx;
width: 100rpx;
position: fixed;
bottom: 35rpx;
left: 30rpx;
background-color: #A7D500;
border-radius: 50%;
z-index: 79;
}
.car-img{
height: 60rpx;
width: 60rpx;
}
.car-left{
/* 平均分布元素,父元素display: flex; 子元素flex:1; */
flex: 1;
}
.car-pice{
padding-left: 160rpx;
font-size: 34rpx;
font-weight: 700;
}
.car-num{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 30rpx;
width: 30rpx;
position: fixed;
bottom: 100rpx;
left: 110rpx;
background-color: #ffea49;
border-radius: 50%;
z-index: 79;
}
.car-num-text{
font-size: 20rpx;
}
.car-right{
/* 平均分布元素,父元素display: flex; 子元素flex:1; */
flex: 1;
}
.car-text{
height: 100rpx;
width: 200rpx;
line-height: 100rpx;
margin-left: 200rpx;
text-align: center;
background-color: #A7D500;
}
.car-list{
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 500rpx;
width: 100%;
position: fixed;
bottom: 100rpx;
background-color: #ffffff;
border-radius: 10px 10px 0px 0px;
z-index: 78;
}
.car-container {
display: flex;
flex-direction: column;
width: 100%;
}
.car-box {
width: 100%;
height: 120rpx;
display: flex;
flex-direction: row;
align-items: center;
padding: 20rpx 10rpx;
border-bottom: solid #f4f4f4 1px;
}
.car-menu-image {
width: 100rpx;
height: 100rpx;
margin-left: 35rpx;
}
.car-menu-name {
font-weight: normal;
font-size: 28rpx;
margin-bottom: 10rpx;
}
.car-menu-explain{
font-size: 20rpx;
margin-bottom: 10rpx;
/* 下方四项配合使用,超出范围的显示... */
width: 400rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.car-menu-ps{
display: flex;
flex-direction: row;
justify-content: space-between; /*两边对齐*/
}
.car-menu-price{
font-size: 26rpx;
font-weight: 600;
}
.car-num-select{
display: flex;
flex-direction: row;
width: 160rpx;
height: 36rpx;
}
/* 遮罩层 */
.car-mark{
position: fixed;
left:0;
top:0;
width:100%;
height:100%;
z-index:77;
background-color: rgba(0, 0, 0, 0.4);
transition: all 0.3s ease-in 0s;
}
</style>
\ No newline at end of file
......@@ -7,16 +7,16 @@
</view>
<image src="../../static/imgs/banner.png"></image>
</view>
<view class="mod11 flex-col">
<view v-if="userms" class="mod11 flex-col">
<view class="box16 flex-col"></view>
<text class="txt6">小黑山羊</text>
<text class="txt6">{{ userInfo.customerName || '我是谁' }}</text>
<view class="right_arrow">
<u-icon name="arrow-right" color="#fff" size="14"></u-icon>
</view>
</view>
<button class="mod11 flex-col" v-else open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">立刻登录</button>
<view class="contents">
<view class="myOrder">
<view class="myOrder" @click="goToPage('order')">
<view class="order1">我的订单</view>
<view class="order2">点击查看订单</view>
<view>
......@@ -25,7 +25,7 @@
</view>
</view>
<view class="right_box">
<view class="box">
<view class="box" @click.stop="goToPage('coupon')">
<view class="left">
<h3>HOOLOO券</h3>
<view class="dec">优惠多多不要错过</view>
......@@ -35,11 +35,13 @@
</view>
</view>
<view class="box two">
<view class="left">
<button v-if="!userms" class="payment" open-type="getPhoneNumber" @getphonenumber.stop="goToPage">
</button>
<view @click="goToPage('msg')" class="left">
<h3>我的消息</h3>
<view class="dec">点击查看我的消息</view>
</view>
<view class="right">
<view @click="goToPage('msg')" class="right">
<image class="right_img" src="../../static/imgs/myMail.png"></image>
</view>
</view>
......@@ -49,30 +51,64 @@
<h3>常用功能</h3>
<view class="function_item">
<u-icon name="server-fill" color="#000000" size="16"></u-icon>
<text class="function_item_text">联系客服</text>
<button class="function_item_text" open-type="contact" bindcontact="handleContact"
session-from="sessionFrom">联系客服</button>
<u-icon name="arrow-right" class="function_item_icon" color="#000000" size="16"></u-icon>
</view>
</view>
<tabBar :selectedTabbar="selectedTabbar"></tabBar>
</view>
</template>
<script>
import User from '@/request/user'
export default {
data() {
return {
selectedTabbar: 2,//选中的tab
}
},
computed: {
userms() {
return this.$store.getters.Authorization;
},
userInfo() {
return this.$store.state.user.userInfo;
},
},
methods: {
// 手机号授权登录
getPhoneNumber(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
User.getPhoneNumber(e);
} else if (e.detail.errMsg == "getPhoneNumber:fail user deny") {
uni.showToast({ title: '已拒绝手机号授权', icon: 'error' })
}
},
goToPage(page) {
if (!this.userms) {
this.loginByPhoneNumber(page)
return
}
page == 'order' && uni.switchTab({ url: '/pages/order/order' })
page == 'coupon' && uni.showToast({ title: '功能未开放!', icon: 'none' });
page == 'msg' && uni.navigateTo({ url: '/mineSubPackage/pages/msg/index' })
}
}
}
</script>
<style lang="scss" scoped>
.payment {
border-radius: 0;
display: block;
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
left: 0;
}
.menu-box {}
.menu-banner {
......@@ -191,6 +227,7 @@ export default {
align-items: center;
justify-content: space-between;
padding: 0 36rpx;
position: relative;
&.two {
margin-top: 15rpx;
......@@ -252,9 +289,21 @@ export default {
margin-top: 20rpx;
.function_item_text {
margin: 0;
margin-left: 10rpx;
padding: 10rpx;
line-height: 1;
background-color: #FFFFFF;
font-size: 24rpx;
border-radius: 0px;
}
.function_item_text::after {
position: unset !important;
border: unset;
}
.function_item_icon {
margin-left: auto;
}
......
......@@ -5,25 +5,33 @@
<view class="order_header">
<view>
<h3 class="order_adrass">{{ item.shop.name }}</h3>
<text class="order_time">{{ item.shop.payTime }}</text>
<text class="order_time">{{ item.createdAt }}</text>
</view>
<view class="order_status" v-if="item.state == 0">创建未校验</view>
<view class="order_status" v-if="item.state == 1">未支付</view>
<view class="order_status" v-if="item.state == 2">排队中</view>
<view class="order_status" v-if="item.state == 3">制作中</view>
<view class="order_status" v-if="item.state == 4">制作完成</view>
<view class="order_status" v-if="item.state == 5">待取超时</view>
<view class="order_status" v-if="item.state == 6">完成</view>
<view class="order_status" v-if="item.state == 7">取消</view>
<view class="order_status" v-if="item.state == 8">取消</view>
<view class="order_status" v-if="item.state == 9">取消</view>
<view class="order_status" v-if="item.state == 10">取消</view>
<view class="order_status" v-if="item.state == 11">已退款</view>
<view class="order_status" v-if="item.state == 12">部分退款</view>
<view class=" order_status" v-if="item.state == 1">未支付</view>
<view class=" order_status" v-if="item.state == 2">已支付</view>
<view class=" order_status" v-if="item.state == 3">支付制作中</view>
<view class=" order_status" v-if="item.state == 4">制作完成未取</view>
<view class=" order_status" v-if="item.state == 5">取餐中</view>
<view class=" order_status" v-if="item.state == 6">正常完成</view>
<view class=" order_status" v-if="item.state == 7">待取超时</view>
<view class=" order_status" v-if="item.state == 8">未支付取消</view>
<view class=" order_status" v-if="item.state == 9">支付后制作前取消</view>
<view class=" order_status" v-if="item.state == 10">制作中取消</view>
<view class=" order_status" v-if="item.state == 11">制作完成取消</view>
<view class=" order_status" v-if="item.state == 12">退款中</view>
<view class=" order_status" v-if="item.state == 13">退款失败</view>
<view class=" order_status" v-if="item.state == 14">部分退款</view>
<view class=" order_status" v-if="item.state == 15">已退款</view>
<view class=" order_status" v-if="item.state == 50">其他人工干预状态</view>
</view>
<view class="order_content">
<div class="order_content">
<view>
<view class="goods_item" v-for="good in item.orderDetails" :key="good.id">
<image class="goods_img" :src="jsonParse(good.goods.pics).thumbnail"></image>
<image class="goods_img" v-if="jsonParse(good.goods.pics).thumbnailApplet"
:src="jsonParse(good.goods.pics).thumbnailApplet"></image>
<image v-else class="goods_img" :src="jsonParse(good.goods.pics).thumbnail"></image>
<view class="goods_text">
<view class="goods_title">{{ good.goodsName }}×{{ good.num }}</view>
<view class="goods_spce">
......@@ -34,47 +42,100 @@
</view>
</view>
</view>
<view v-if="item.state == 4 || item.state == 5 || item.state == 6 || item.state == 7"
class="qr_code">
<image class="qr_code_img" src="/static/imgs/icon-barcode.png"></image>
<view class="qr_text">点击二维码取单</view>
</view>
</div>
<view class="order_footer">
<view class="total">
1件商品 合计: <text class="price">¥10.00</text>
{{ orderDetailsSize(item.orderDetails) }}件商品 合计: <text class="price">{{ item.amount }}</text>
</view>
<!-- <a class="btn" type="primary">再来一单</a> -->
<a class="btn" @click.stop="PayNow(item)" v-if="item.state == 1" type="primary">立刻支付</a>
<a class="btn" v-else @click.stop="oneMoreOrder(item)" type="primary">再来一单</a>
</view>
</view>
</view>
<tabBar :selectedTabbar="selectedTabbar"></tabBar>
</view>
</template>
<script>
import order from '@/request/order'
import Menu from '@/request/menu';
import Utils from '@/utils/utils'
import { $EventBus } from "@/utils/EventBus";
export default {
name: 'order',
data() {
return {
selectedTabbar: 1,//选中的tab
list: []
}
},
async onLoad() {
const { data } = await order.getMyOrder();
this.list = data.rows
onShow() {
this.getList()
},
async onShow() {
computed: {
userms() {
return this.$store.getters.Authorization;
},
},
methods: {
async oneMoreOrder(item) {
uni.removeStorageSync('shopCarInfo');
$EventBus.$emit('updateCar');
const numObj = {}
const { id, shopId, orderDetails } = item;
orderDetails.forEach(item => {
orderDetails[item.skuId] = item.num
})
const { data } = await order.moreOrder({ orderId: id, shopId });
data.data.forEach(item => {
const skuId = item.skus[0].skuId
const nextData = { ...item, skuId, num: orderDetails[skuId], flag: true, sku: item.skus[0] }
if (nextData.sku.state == 1) {
Utils.getallNum(nextData)
}
});
uni.switchTab({ url: '/pages/menu/menu' })
},
async getList() {
if (!this.userms) return
const { data } = await order.getMyOrder();
if (data) {
this.list = data.rows
} else {
uni.showToast({ title: '请登录!', icon: 'error' })
}
},
async PayNow({ id }) {
const orderInfo = await order.payOrder({ orderId: id })
if (orderInfo) {
if (orderInfo && orderInfo.data.code == 200) {
await Menu.requestPayment(orderInfo.data.data);
this.getList()
}
}
},
methods: {
openInfo(data) {
uni.setStorageSync('orderInfo', data);
let url = '/orderSubPackage/pages/orderInfo/index'
// : '/orderSubPackage/pages/settlement/index'
uni.navigateTo({ url })
},
jsonParse(json) {
return JSON.parse(json)
const data = json || {}
return JSON.parse(data)
},
orderDetailsSize(orderDetails) {
let size = 0;
orderDetails.forEach(item => {
const { num } = item;
size += Number(num)
});
return size
}
......@@ -124,6 +185,26 @@ export default {
.order_content {
margin-top: 38rpx;
display: flex;
justify-content: space-between;
align-items: center;
.qr_code {
font-size: 16rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #666666;
line-height: 22rpx;
text-align: center;
margin-right: 15rpx;
margin-top: 30rpx;
.qr_code_img {
width: 76rpx;
height: 76rpx;
}
}
.goods_item {
display: flex;
......
import appConfig from '@/static/config/index.js';
import User from '@/request/user';
export function getBaseUrl() {
if (process.env.NODE_ENV === 'development') {
return appConfig.devApi;
......@@ -34,16 +35,11 @@ module.exports = (vm) => {
'/weixin/getShop',
'/weixin/infoByShop',
'/application/getData',
'/weixin/getArea',
];
if (Authorization && configUrl.indexOf(config.url) == -1) {
config.header.Authorization = Authorization;
}
console.log(config, 4444);
if (!Authorization) {
// 如果token不存在,return Promise.reject(config) 会取消本次请求
// return Promise.reject(config);
}
return config;
},
(config) => {
......@@ -55,9 +51,13 @@ module.exports = (vm) => {
uni.$u.http.interceptors.response.use(
(response) => {
uni.hideLoading();
/* 对响应成功做点什么 可使用async await 做异步操作*/
if (response.data.code !== 200) {
// 服务端返回的状态码不等于200,则reject()
const phoneNumber = uni.getStorageSync('phoneNumber');
if (response.data.code == 401 && phoneNumber) {
User.getAuthorization(phoneNumber);
}
uni.showToast({
title: response.data.msg,
icon: 'none',
......@@ -65,12 +65,12 @@ module.exports = (vm) => {
});
return Promise.reject(response);
} // return Promise.reject 可使promise状态进入catch
return response;
},
(response) => {
uni.hideLoading();
/* 对响应错误做点什么 (statusCode !== 200)*/
console.log(response);
return Promise.reject(response);
}
);
......
import Utils from '@/utils/utils'
import { $EventBus } from '@/utils/EventBus';
export default {
// 获取菜单列表
getMenuList(id) {
return uni.$u.http.get('/weixin/infoByShop', {
params:{
shopId: id
}
}).then(res => {
return uni.$u.http
.get('/weixin/infoByShop', {
params: {
shopId: id,
},
})
.then((res) => {
return res;
}).catch(err => {
uni.showToast({title:'服务器错误',icon:'none'})
})
.catch((err) => {
uni.showToast({ title: '服务器错误', icon: 'none' });
});
},
// 获取点单屏幕的订单信息
getScreenShopCar(key) {
return uni.$u.http.get('/application/getData', {
params:{
key: key
}
}).then(res => {
getScreenShopCar(key, location) {
return uni.$u.http
.post('/application/getData', {
key,
location,
})
.then((res) => {
return res;
}).catch(err => {
})
.catch((err) => {
uni.showToast({
title: '服务器错误',
icon: 'none'
icon: 'none',
});
return err;
})
});
},
// 下单获取预支付订单
saveReserve(data) {
return uni.$u.http.post('/order', data).then(res => {
console.log(res,444411111)
return uni.$u.http
.post('/order', data)
.then((res) => {
return res;
}).catch(err => {
})
.catch((err) => { });
},
// saveReserve 为业务接口
requestPayment(data, oldData, buyType) {
......@@ -49,39 +54,24 @@ export default {
signType: data.signType || 'MD5', // 签名算法
paySign: data.paySign, // 签名
success: function (res) {
if (res.errMsg == 'requestPayment:ok'){
uni.showToast({
title: '支付成功'
});
if (buyType==1){
let shopCarInfo = uni.getStorageSync('shopCarInfo');
for (let i = 0; i < oldData.length; i++){
let element = oldData[i];
for (let y = 0; y < shopCarInfo.length; y++) {
let item = shopCarInfo[y];
if (item.skus[0].skuId === element.skus[0].skuId) {
shopCarInfo.splice(index, 1);
}
}
}
if (res.errMsg == 'requestPayment:ok') {
// 删除购物车数据后重新放回购物车
uni.setStorageSync('shopCarInfo', shopCarInfo);
uni.setStorageSync('shopCarInfo', []);
$EventBus.$emit('updateCar');
uni.navigateTo({
url:'/page/menu/menu'
})
uni.switchTab({ url: '/pages/order/order' });
}
}
// 业务逻辑。。。
},
fail: function (err) {
uni.showToast({
title:'支付失败',
icon:'error'
})
}
title: '支付失败',
icon: 'error',
});
}
}
\ No newline at end of file
uni.setStorageSync('shopCarInfo', []);
$EventBus.$emit('updateCar');
uni.switchTab({ url: '/pages/order/order' });
},
});
},
};
export default {
getList(id) {
}
}
\ No newline at end of file
getList(id) {},
getMsg() {
return uni.$u.http
.get('/system/message/list', {})
.then((res) => {
return res;
})
.catch((err) => {
uni.showToast({ title: '服务器错误', icon: 'none' });
});
},
read(data) {
return uni.$u.http
.put('/system/message', data)
.then((res) => {
return res;
})
.catch((err) => {
uni.showToast({ title: '服务器错误', icon: 'none' });
});
},
};
......@@ -5,12 +5,95 @@ export default {
params: {},
})
.then((res) => res)
.catch((err) => uni.showToast({ title: '服务器错误', icon: 'none' }));
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
orderRefund(data) {
return uni.$u.http
.post('/system/refund', data)
.then((res) => res)
.catch((err) => uni.showToast({ title: '服务器错误', icon: 'none' }));
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
getShop(params) {
return uni.$u.http
.get('/weixin/getArea', {
params,
})
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
// 校验sku是否可用
chekSku(params) {
return uni.$u.http
.get('/application/checkSku', {
params,
})
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
cancelOrder(params) {
return uni.$u.http
.get('order/cancel', {
params,
})
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
// 立刻支付
payOrder(params) {
return uni.$u.http
.get('order/payOrder', {
params,
})
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
getHomeOrder(params) {
return uni.$u.http
.get('/app/getHomeOrder', {
params: {},
})
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
getWaitTine(data) {
return uni.$u.http
.post('app/getWaitTine', data)
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
moreOrder(params) {
return uni.$u.http
.get('/app/getNextOrder', {
params,
})
.then((res) => res)
.catch((err) => {
// uni.showToast({ title: '服务器错误', icon: 'none' })
console.log('服务器错误');
});
},
};
import Store from '@/store';
import { $EventBus } from '../../utils/EventBus';
import { $EventBus } from '@/utils/EventBus';
export default {
getLocation() {
getLocation(callback) {
let _this = this;
return uni.getLocation({
type: 'gcj02', //返回可以用于uni.openLocation的经纬度
success: function (res) {
console.log(res, 'res');
var params = {
lat: res.latitude,
lng: res.longitude,
};
Store.commit('saveLocation', params);
uni.setStorage({ key: 'location', data: params });
callback && callback(params);
// return params;
_this.getAddress(params);
},
fail: function (res) {
console.log(res, 3333);
uni.showToast({
title: '获取地址失败,将导致部分功能不可用',
icon: 'none',
......@@ -24,7 +24,7 @@ export default {
},
});
},
// 获取具体位置店铺/weixin/getShop
// 获取默认店铺
getAddress(params) {
return uni.$u.http
.get('/weixin/getShop', {
......@@ -32,10 +32,11 @@ export default {
})
.then((res) => {
if (res.data.code == 200) {
console.log(res.data.data, 12345678);
Store.commit('saveShopInfo', res.data.data);
if (res.data.data.length) {
$EventBus.$emit('getMenuList', res.data.data[0]);
uni.setStorage({ key: 'shopData', data: res.data.data });
if (res.data.data) {
$EventBus.$emit('getMenuList', res.data.data);
}
}
return res;
......@@ -44,21 +45,7 @@ export default {
return err;
});
},
// 通过地址选择店铺xxxx
// getAddress(params) {
// return uni.$u.http.get('/weixin/getShop', {
// params
// }).then((res) => {
// if (res.data.code == 200) {
// console.log(res.data.data, 12345678)
// Store.commit('saveShopInfo', res.data.data);
// }
// return res;
// }).catch(err => {
// return err;
// });
// },
uniLogin(res, orderId) {
uniLogin(res) {
uni.login({
provider: 'weixin',
success: function (data) {
......@@ -66,28 +53,19 @@ export default {
uni.$u.http
.post('/weixin/login', {
code: data.code,
source: 3, //默认是3,扫码进来是2
source: 3,
iv: res.iv,
encryptedData: res.encryptedData,
})
.then((response) => {
if (response.statusCode == 200 && response.data && response.data.code == 200) {
uni.setStorage({ key: 'Authorization', data: response.data.token });
Store.commit('setAuthorization', response.data.token);
uni.showToast({
title: '登录成功',
success() {
setTimeout(() => {
// 如果扫码进来的带有orderId则授权成功之后跳入结算页面
if (orderId) {
uni.navigateTo({
url: '/menuSubPackage/pages/settlement/settlement?orderId=' + orderId,
});
} else {
}
}, 1500);
},
});
.then((res) => {
const { statusCode, data } = res;
const { code, token, phoneNumber } = data;
if (statusCode == 200 && data && code == 200) {
uni.setStorage({ key: 'Authorization', data: token });
uni.setStorage({ key: 'phoneNumber', data: phoneNumber });
uni.setStorage({ key: 'userInfo', data: data });
Store.commit('setUserInfo', data);
Store.commit('setAuthorization', token);
}
})
.catch((err) => {
......@@ -98,25 +76,33 @@ export default {
},
});
},
// 手机号授权登录
getPhoneNumber(res, orderId) {
uni.setStorage({
key: 'userPhoneInfo',
data: res,
getAuthorization(phoneNumber) {
uni.$u.http.post('/weixin/refreshToken ', { phoneNumber }).then((res) => {
const { data } = res;
uni.setStorage({ key: 'Authorization', data: data.token });
Store.commit('setAuthorization', data.token);
uni.showToast({ title: '登录成功!' });
});
},
// 手机号授权登录
getPhoneNumber(res) {
uni.setStorage({ key: 'userPhoneInfo', data: res });
Store.commit('setUserPhoneInfo', res);
this.uniLogin(res.detail, orderId);
uni.setStorage({ key: 'phoneInfo', data: res });
this.uniLogin(res.detail);
},
async uniGetUserInfo(e) {
uni.getUserProfile({
//授权后可以通过uni.getUserProfile得到用户信息
lang: 'zh_CN',
desc: '用于完善用户信息',
success: (res) => {
uni.setStorage({ key: 'userInfo', data: res });
Store.commit('setUserInfo', res);
// this.uniLogin(res);
setAllow(allow) {
uni.$u.http
.get('/system/customer/allow', {
params: {
allow,
},
})
.then((res) => {
return res;
})
.catch((err) => {
uni.showToast({ title: '服务器错误', icon: 'none' });
});
},
};
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import menu from './modules/menu'
import getters from './getters'
Vue.use(Vuex)
import Vue from 'vue';
import Vuex from 'vuex';
import user from './modules/user';
import menu from './modules/menu';
import getters from './getters';
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
user,
menu
menu,
},
state: {
list: [
{
icon: "/static/imgs/icon-unselect-menu.png",
activeIcon: '/static/imgs/icon-selected-menu.png',
customIcon: false,
pagePath: "/pages/menu/menu",
text: '菜单'
},
{
icon: "/static/imgs/icon-unselect-order.png",
activeIcon: '/static/imgs/icon-selected-order.png',
pagePath: "/pages/order/order",
text: '订单',
customIcon: false
},
{
icon: "/static/imgs/icon-unselect-mine.png",
activeIcon: '/static/imgs/icon-selected-mine.png',
pagePath: "/pages/mine/mine",
text: '我的'
}
],
list: [],
orderId:''//外部扫码进入的商品id
orderId: '', //外部扫码进入的商品id
},
mutations: {
// 设置扫码进入的商品id
setOrderId(state, orderId) {
state.orderId = orderId;
}
},
},
getters,
actions: {}
})
export default store
\ No newline at end of file
actions: {},
});
export default store;
const user = {
state: {
userInfo: null, //授权信息
userInfo: {}, //授权信息
Authorization: null, //是否授权
location:null,//用户经纬度
userPhoneInfo:null,
shopInfo:null,//店铺信息
orderId:null//扫码进入时携带的订单id
location: null, //用户经纬度
userPhoneInfo: null,
shopInfo: null, //店铺信息
orderId: null, //扫码进入时携带的订单id
},
mutations: {
// 保存扫码进入时携带的订单id
......@@ -15,7 +14,6 @@ const user = {
},
// 设置是否授权
setAuthorization(state, data) {
console.log(data,665)
state.Authorization = data;
},
// 设置用户允许昵称头像授权时的信息
......@@ -33,12 +31,10 @@ const user = {
// 当前店铺信息
saveShopInfo(state, shopInfo) {
state.shopInfo = shopInfo;
}
},
},
actions: {
}
}
actions: {},
};
export default user
export default user;
// Core code comes from https://github.com/davidshimjs/qrcodejs
var QRCode;
(function () {
/**
* Get the type by string length
*
* @private
* @param {String} sText
* @param {Number} nCorrectLevel
* @return {Number} type
*/
function _getTypeNumber(sText, nCorrectLevel) {
var nType = 1;
var length = _getUTF8Length(sText);
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
var nLimit = 0;
switch (nCorrectLevel) {
case QRErrorCorrectLevel.L:
nLimit = QRCodeLimitLength[i][0];
break;
case QRErrorCorrectLevel.M:
nLimit = QRCodeLimitLength[i][1];
break;
case QRErrorCorrectLevel.Q:
nLimit = QRCodeLimitLength[i][2];
break;
case QRErrorCorrectLevel.H:
nLimit = QRCodeLimitLength[i][3];
break;
}
if (length <= nLimit) {
break;
} else {
nType++;
}
}
if (nType > QRCodeLimitLength.length) {
throw new Error('Too long data');
}
return nType;
}
function _getUTF8Length(sText) {
var replacedText = encodeURI(sText)
.toString()
.replace(/\%[0-9a-fA-F]{2}/g, 'a');
return replacedText.length + (replacedText.length != sText ? 3 : 0);
}
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
this.parsedData = [];
// Added to support UTF-8 Characters
for (var i = 0, l = this.data.length; i < l; i++) {
var byteArray = [];
var code = this.data.charCodeAt(i);
if (code > 0x10000) {
byteArray[0] = 0xf0 | ((code & 0x1c0000) >>> 18);
byteArray[1] = 0x80 | ((code & 0x3f000) >>> 12);
byteArray[2] = 0x80 | ((code & 0xfc0) >>> 6);
byteArray[3] = 0x80 | (code & 0x3f);
} else if (code > 0x800) {
byteArray[0] = 0xe0 | ((code & 0xf000) >>> 12);
byteArray[1] = 0x80 | ((code & 0xfc0) >>> 6);
byteArray[2] = 0x80 | (code & 0x3f);
} else if (code > 0x80) {
byteArray[0] = 0xc0 | ((code & 0x7c0) >>> 6);
byteArray[1] = 0x80 | (code & 0x3f);
} else {
byteArray[0] = code;
}
this.parsedData.push(byteArray);
}
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
if (this.parsedData.length != this.data.length) {
this.parsedData.unshift(191);
this.parsedData.unshift(187);
this.parsedData.unshift(239);
}
}
QR8bitByte.prototype = {
getLength: function (buffer) {
return this.parsedData.length;
},
write: function (buffer) {
for (var i = 0, l = this.parsedData.length; i < l; i++) {
buffer.put(this.parsedData[i], 8);
}
},
};
// QRCodeModel
function QRCodeModel(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
QRCodeModel.prototype = {
addData: function (data) {
var newData = new QR8bitByte(data);
this.dataList.push(newData);
this.dataCache = null;
},
isDark: function (row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
throw new Error(row + ',' + col);
}
return this.modules[row][col];
},
getModuleCount: function () {
return this.moduleCount;
},
make: function () {
this.makeImpl(false, this.getBestMaskPattern());
},
makeImpl: function (test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17;
this.modules = new Array(this.moduleCount);
for (var row = 0; row < this.moduleCount; row++) {
this.modules[row] = new Array(this.moduleCount);
for (var col = 0; col < this.moduleCount; col++) {
this.modules[row][col] = null;
}
}
this.setupPositionProbePattern(0, 0);
this.setupPositionProbePattern(this.moduleCount - 7, 0);
this.setupPositionProbePattern(0, this.moduleCount - 7);
this.setupPositionAdjustPattern();
this.setupTimingPattern();
this.setupTypeInfo(test, maskPattern);
if (this.typeNumber >= 7) {
this.setupTypeNumber(test);
}
if (this.dataCache == null) {
this.dataCache = QRCodeModel.createData(
this.typeNumber,
this.errorCorrectLevel,
this.dataList
);
}
this.mapData(this.dataCache, maskPattern);
},
setupPositionProbePattern: function (row, col) {
for (var r = -1; r <= 7; r++) {
if (row + r <= -1 || this.moduleCount <= row + r) continue;
for (var c = -1; c <= 7; c++) {
if (col + c <= -1 || this.moduleCount <= col + c) continue;
if (
(0 <= r && r <= 6 && (c == 0 || c == 6)) ||
(0 <= c && c <= 6 && (r == 0 || r == 6)) ||
(2 <= r && r <= 4 && 2 <= c && c <= 4)
) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
},
getBestMaskPattern: function () {
var minLostPoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i++) {
this.makeImpl(true, i);
var lostPoint = QRUtil.getLostPoint(this);
if (i == 0 || minLostPoint > lostPoint) {
minLostPoint = lostPoint;
pattern = i;
}
}
return pattern;
},
createMovieClip: function (target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
var cs = 1;
this.make();
for (var row = 0; row < this.modules.length; row++) {
var y = row * cs;
for (var col = 0; col < this.modules[row].length; col++) {
var x = col * cs;
var dark = this.modules[row][col];
if (dark) {
qr_mc.beginFill(0, 100);
qr_mc.moveTo(x, y);
qr_mc.lineTo(x + cs, y);
qr_mc.lineTo(x + cs, y + cs);
qr_mc.lineTo(x, y + cs);
qr_mc.endFill();
}
}
}
return qr_mc;
},
setupTimingPattern: function () {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) {
continue;
}
this.modules[r][6] = r % 2 == 0;
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) {
continue;
}
this.modules[6][c] = c % 2 == 0;
}
},
setupPositionAdjustPattern: function () {
var pos = QRUtil.getPatternPosition(this.typeNumber);
for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i];
var col = pos[j];
if (this.modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r++) {
for (var c = -2; c <= 2; c++) {
if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
this.modules[row + r][col + c] = true;
} else {
this.modules[row + r][col + c] = false;
}
}
}
}
}
},
setupTypeNumber: function (test) {
var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
for (var i = 0; i < 18; i++) {
var mod = !test && ((bits >> i) & 1) == 1;
this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i++) {
var mod = !test && ((bits >> i) & 1) == 1;
this.modules[(i % 3) + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
}
},
setupTypeInfo: function (test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern;
var bits = QRUtil.getBCHTypeInfo(data);
for (var i = 0; i < 15; i++) {
var mod = !test && ((bits >> i) & 1) == 1;
if (i < 6) {
this.modules[i][8] = mod;
} else if (i < 8) {
this.modules[i + 1][8] = mod;
} else {
this.modules[this.moduleCount - 15 + i][8] = mod;
}
}
for (var i = 0; i < 15; i++) {
var mod = !test && ((bits >> i) & 1) == 1;
if (i < 8) {
this.modules[8][this.moduleCount - i - 1] = mod;
} else if (i < 9) {
this.modules[8][15 - i - 1 + 1] = mod;
} else {
this.modules[8][15 - i - 1] = mod;
}
}
this.modules[this.moduleCount - 8][8] = !test;
},
mapData: function (data, maskPattern) {
var inc = -1;
var row = this.moduleCount - 1;
var bitIndex = 7;
var byteIndex = 0;
for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--;
while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false;
if (byteIndex < data.length) {
dark = ((data[byteIndex] >>> bitIndex) & 1) == 1;
}
var mask = QRUtil.getMask(maskPattern, row, col - c);
if (mask) {
dark = !dark;
}
this.modules[row][col - c] = dark;
bitIndex--;
if (bitIndex == -1) {
byteIndex++;
bitIndex = 7;
}
}
}
row += inc;
if (row < 0 || this.moduleCount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
},
};
QRCodeModel.PAD0 = 0xec;
QRCodeModel.PAD1 = 0x11;
QRCodeModel.createData = function (typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
var buffer = new QRBitBuffer();
for (var i = 0; i < dataList.length; i++) {
var data = dataList[i];
buffer.put(data.mode, 4);
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
data.write(buffer);
}
var totalDataCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalDataCount += rsBlocks[i].dataCount;
}
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error(
'code length overflow. (' + buffer.getLengthInBits() + '>' + totalDataCount * 8 + ')'
);
}
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
buffer.put(0, 4);
}
while (buffer.getLengthInBits() % 8 != 0) {
buffer.putBit(false);
}
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCodeModel.PAD0, 8);
if (buffer.getLengthInBits() >= totalDataCount * 8) {
break;
}
buffer.put(QRCodeModel.PAD1, 8);
}
return QRCodeModel.createBytes(buffer, rsBlocks);
};
QRCodeModel.createBytes = function (buffer, rsBlocks) {
var offset = 0;
var maxDcCount = 0;
var maxEcCount = 0;
var dcdata = new Array(rsBlocks.length);
var ecdata = new Array(rsBlocks.length);
for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount;
var ecCount = rsBlocks[r].totalCount - dcCount;
maxDcCount = Math.max(maxDcCount, dcCount);
maxEcCount = Math.max(maxEcCount, ecCount);
dcdata[r] = new Array(dcCount);
for (var i = 0; i < dcdata[r].length; i++) {
dcdata[r][i] = 0xff & buffer.buffer[i + offset];
}
offset += dcCount;
var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
var modPoly = rawPoly.mod(rsPoly);
ecdata[r] = new Array(rsPoly.getLength() - 1);
for (var i = 0; i < ecdata[r].length; i++) {
var modIndex = i + modPoly.getLength() - ecdata[r].length;
ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0;
}
}
var totalCodeCount = 0;
for (var i = 0; i < rsBlocks.length; i++) {
totalCodeCount += rsBlocks[i].totalCount;
}
var data = new Array(totalCodeCount);
var index = 0;
for (var i = 0; i < maxDcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < dcdata[r].length) {
data[index++] = dcdata[r][i];
}
}
}
for (var i = 0; i < maxEcCount; i++) {
for (var r = 0; r < rsBlocks.length; r++) {
if (i < ecdata[r].length) {
data[index++] = ecdata[r][i];
}
}
}
return data;
};
var QRMode = {
MODE_NUMBER: 1 << 0,
MODE_ALPHA_NUM: 1 << 1,
MODE_8BIT_BYTE: 1 << 2,
MODE_KANJI: 1 << 3,
};
var QRErrorCorrectLevel = { L: 1, M: 0, Q: 3, H: 2 };
var QRMaskPattern = {
PATTERN000: 0,
PATTERN001: 1,
PATTERN010: 2,
PATTERN011: 3,
PATTERN100: 4,
PATTERN101: 5,
PATTERN110: 6,
PATTERN111: 7,
};
var QRUtil = {
PATTERN_POSITION_TABLE: [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170],
],
G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
getBCHTypeInfo: function (data) {
var d = data << 10;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15));
}
return ((data << 10) | d) ^ QRUtil.G15_MASK;
},
getBCHTypeNumber: function (data) {
var d = data << 12;
while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18));
}
return (data << 12) | d;
},
getBCHDigit: function (data) {
var digit = 0;
while (data != 0) {
digit++;
data >>>= 1;
}
return digit;
},
getPatternPosition: function (typeNumber) {
return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
},
getMask: function (maskPattern, i, j) {
switch (maskPattern) {
case QRMaskPattern.PATTERN000:
return (i + j) % 2 == 0;
case QRMaskPattern.PATTERN001:
return i % 2 == 0;
case QRMaskPattern.PATTERN010:
return j % 3 == 0;
case QRMaskPattern.PATTERN011:
return (i + j) % 3 == 0;
case QRMaskPattern.PATTERN100:
return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
case QRMaskPattern.PATTERN101:
return ((i * j) % 2) + ((i * j) % 3) == 0;
case QRMaskPattern.PATTERN110:
return (((i * j) % 2) + ((i * j) % 3)) % 2 == 0;
case QRMaskPattern.PATTERN111:
return (((i * j) % 3) + ((i + j) % 2)) % 2 == 0;
default:
throw new Error('bad maskPattern:' + maskPattern);
}
},
getErrorCorrectPolynomial: function (errorCorrectLength) {
var a = new QRPolynomial([1], 0);
for (var i = 0; i < errorCorrectLength; i++) {
a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
}
return a;
},
getLengthInBits: function (mode, type) {
if (1 <= type && type < 10) {
switch (mode) {
case QRMode.MODE_NUMBER:
return 10;
case QRMode.MODE_ALPHA_NUM:
return 9;
case QRMode.MODE_8BIT_BYTE:
return 8;
case QRMode.MODE_KANJI:
return 8;
default:
throw new Error('mode:' + mode);
}
} else if (type < 27) {
switch (mode) {
case QRMode.MODE_NUMBER:
return 12;
case QRMode.MODE_ALPHA_NUM:
return 11;
case QRMode.MODE_8BIT_BYTE:
return 16;
case QRMode.MODE_KANJI:
return 10;
default:
throw new Error('mode:' + mode);
}
} else if (type < 41) {
switch (mode) {
case QRMode.MODE_NUMBER:
return 14;
case QRMode.MODE_ALPHA_NUM:
return 13;
case QRMode.MODE_8BIT_BYTE:
return 16;
case QRMode.MODE_KANJI:
return 12;
default:
throw new Error('mode:' + mode);
}
} else {
throw new Error('type:' + type);
}
},
getLostPoint: function (qrCode) {
var moduleCount = qrCode.getModuleCount();
var lostPoint = 0;
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0;
var dark = qrCode.isDark(row, col);
for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrCode.isDark(row + r, col + c)) {
sameCount++;
}
}
}
if (sameCount > 5) {
lostPoint += 3 + sameCount - 5;
}
}
}
for (var row = 0; row < moduleCount - 1; row++) {
for (var col = 0; col < moduleCount - 1; col++) {
var count = 0;
if (qrCode.isDark(row, col)) count++;
if (qrCode.isDark(row + 1, col)) count++;
if (qrCode.isDark(row, col + 1)) count++;
if (qrCode.isDark(row + 1, col + 1)) count++;
if (count == 0 || count == 4) {
lostPoint += 3;
}
}
}
for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount - 6; col++) {
if (
qrCode.isDark(row, col) &&
!qrCode.isDark(row, col + 1) &&
qrCode.isDark(row, col + 2) &&
qrCode.isDark(row, col + 3) &&
qrCode.isDark(row, col + 4) &&
!qrCode.isDark(row, col + 5) &&
qrCode.isDark(row, col + 6)
) {
lostPoint += 40;
}
}
}
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount - 6; row++) {
if (
qrCode.isDark(row, col) &&
!qrCode.isDark(row + 1, col) &&
qrCode.isDark(row + 2, col) &&
qrCode.isDark(row + 3, col) &&
qrCode.isDark(row + 4, col) &&
!qrCode.isDark(row + 5, col) &&
qrCode.isDark(row + 6, col)
) {
lostPoint += 40;
}
}
}
var darkCount = 0;
for (var col = 0; col < moduleCount; col++) {
for (var row = 0; row < moduleCount; row++) {
if (qrCode.isDark(row, col)) {
darkCount++;
}
}
}
var ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5;
lostPoint += ratio * 10;
return lostPoint;
},
};
var QRMath = {
glog: function (n) {
if (n < 1) {
throw new Error('glog(' + n + ')');
}
return QRMath.LOG_TABLE[n];
},
gexp: function (n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return QRMath.EXP_TABLE[n];
},
EXP_TABLE: new Array(256),
LOG_TABLE: new Array(256),
};
for (var i = 0; i < 8; i++) {
QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
QRMath.EXP_TABLE[i] =
QRMath.EXP_TABLE[i - 4] ^
QRMath.EXP_TABLE[i - 5] ^
QRMath.EXP_TABLE[i - 6] ^
QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
}
function QRPolynomial(num, shift) {
if (num.length == undefined) {
throw new Error(num.length + '/' + shift);
}
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset++;
}
this.num = new Array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i++) {
this.num[i] = num[i + offset];
}
}
QRPolynomial.prototype = {
get: function (index) {
return this.num[index];
},
getLength: function () {
return this.num.length;
},
multiply: function (e) {
var num = new Array(this.getLength() + e.getLength() - 1);
for (var i = 0; i < this.getLength(); i++) {
for (var j = 0; j < e.getLength(); j++) {
num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
}
}
return new QRPolynomial(num, 0);
},
mod: function (e) {
if (this.getLength() - e.getLength() < 0) {
return this;
}
var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
var num = new Array(this.getLength());
for (var i = 0; i < this.getLength(); i++) {
num[i] = this.get(i);
}
for (var i = 0; i < e.getLength(); i++) {
num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
}
return new QRPolynomial(num, 0).mod(e);
},
};
function QRRSBlock(totalCount, dataCount) {
this.totalCount = totalCount;
this.dataCount = dataCount;
}
QRRSBlock.RS_BLOCK_TABLE = [
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16],
[4, 101, 81],
[1, 80, 50, 4, 81, 51],
[4, 50, 22, 4, 51, 23],
[3, 36, 12, 8, 37, 13],
[2, 116, 92, 2, 117, 93],
[6, 58, 36, 2, 59, 37],
[4, 46, 20, 6, 47, 21],
[7, 42, 14, 4, 43, 15],
[4, 133, 107],
[8, 59, 37, 1, 60, 38],
[8, 44, 20, 4, 45, 21],
[12, 33, 11, 4, 34, 12],
[3, 145, 115, 1, 146, 116],
[4, 64, 40, 5, 65, 41],
[11, 36, 16, 5, 37, 17],
[11, 36, 12, 5, 37, 13],
[5, 109, 87, 1, 110, 88],
[5, 65, 41, 5, 66, 42],
[5, 54, 24, 7, 55, 25],
[11, 36, 12],
[5, 122, 98, 1, 123, 99],
[7, 73, 45, 3, 74, 46],
[15, 43, 19, 2, 44, 20],
[3, 45, 15, 13, 46, 16],
[1, 135, 107, 5, 136, 108],
[10, 74, 46, 1, 75, 47],
[1, 50, 22, 15, 51, 23],
[2, 42, 14, 17, 43, 15],
[5, 150, 120, 1, 151, 121],
[9, 69, 43, 4, 70, 44],
[17, 50, 22, 1, 51, 23],
[2, 42, 14, 19, 43, 15],
[3, 141, 113, 4, 142, 114],
[3, 70, 44, 11, 71, 45],
[17, 47, 21, 4, 48, 22],
[9, 39, 13, 16, 40, 14],
[3, 135, 107, 5, 136, 108],
[3, 67, 41, 13, 68, 42],
[15, 54, 24, 5, 55, 25],
[15, 43, 15, 10, 44, 16],
[4, 144, 116, 4, 145, 117],
[17, 68, 42],
[17, 50, 22, 6, 51, 23],
[19, 46, 16, 6, 47, 17],
[2, 139, 111, 7, 140, 112],
[17, 74, 46],
[7, 54, 24, 16, 55, 25],
[34, 37, 13],
[4, 151, 121, 5, 152, 122],
[4, 75, 47, 14, 76, 48],
[11, 54, 24, 14, 55, 25],
[16, 45, 15, 14, 46, 16],
[6, 147, 117, 4, 148, 118],
[6, 73, 45, 14, 74, 46],
[11, 54, 24, 16, 55, 25],
[30, 46, 16, 2, 47, 17],
[8, 132, 106, 4, 133, 107],
[8, 75, 47, 13, 76, 48],
[7, 54, 24, 22, 55, 25],
[22, 45, 15, 13, 46, 16],
[10, 142, 114, 2, 143, 115],
[19, 74, 46, 4, 75, 47],
[28, 50, 22, 6, 51, 23],
[33, 46, 16, 4, 47, 17],
[8, 152, 122, 4, 153, 123],
[22, 73, 45, 3, 74, 46],
[8, 53, 23, 26, 54, 24],
[12, 45, 15, 28, 46, 16],
[3, 147, 117, 10, 148, 118],
[3, 73, 45, 23, 74, 46],
[4, 54, 24, 31, 55, 25],
[11, 45, 15, 31, 46, 16],
[7, 146, 116, 7, 147, 117],
[21, 73, 45, 7, 74, 46],
[1, 53, 23, 37, 54, 24],
[19, 45, 15, 26, 46, 16],
[5, 145, 115, 10, 146, 116],
[19, 75, 47, 10, 76, 48],
[15, 54, 24, 25, 55, 25],
[23, 45, 15, 25, 46, 16],
[13, 145, 115, 3, 146, 116],
[2, 74, 46, 29, 75, 47],
[42, 54, 24, 1, 55, 25],
[23, 45, 15, 28, 46, 16],
[17, 145, 115],
[10, 74, 46, 23, 75, 47],
[10, 54, 24, 35, 55, 25],
[19, 45, 15, 35, 46, 16],
[17, 145, 115, 1, 146, 116],
[14, 74, 46, 21, 75, 47],
[29, 54, 24, 19, 55, 25],
[11, 45, 15, 46, 46, 16],
[13, 145, 115, 6, 146, 116],
[14, 74, 46, 23, 75, 47],
[44, 54, 24, 7, 55, 25],
[59, 46, 16, 1, 47, 17],
[12, 151, 121, 7, 152, 122],
[12, 75, 47, 26, 76, 48],
[39, 54, 24, 14, 55, 25],
[22, 45, 15, 41, 46, 16],
[6, 151, 121, 14, 152, 122],
[6, 75, 47, 34, 76, 48],
[46, 54, 24, 10, 55, 25],
[2, 45, 15, 64, 46, 16],
[17, 152, 122, 4, 153, 123],
[29, 74, 46, 14, 75, 47],
[49, 54, 24, 10, 55, 25],
[24, 45, 15, 46, 46, 16],
[4, 152, 122, 18, 153, 123],
[13, 74, 46, 32, 75, 47],
[48, 54, 24, 14, 55, 25],
[42, 45, 15, 32, 46, 16],
[20, 147, 117, 4, 148, 118],
[40, 75, 47, 7, 76, 48],
[43, 54, 24, 22, 55, 25],
[10, 45, 15, 67, 46, 16],
[19, 148, 118, 6, 149, 119],
[18, 75, 47, 31, 76, 48],
[34, 54, 24, 34, 55, 25],
[20, 45, 15, 61, 46, 16],
];
QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
if (rsBlock == undefined) {
throw new Error(
'bad rs block @ typeNumber:' + typeNumber + '/errorCorrectLevel:' + errorCorrectLevel
);
}
var length = rsBlock.length / 3;
var list = [];
for (var i = 0; i < length; i++) {
var count = rsBlock[i * 3 + 0];
var totalCount = rsBlock[i * 3 + 1];
var dataCount = rsBlock[i * 3 + 2];
for (var j = 0; j < count; j++) {
list.push(new QRRSBlock(totalCount, dataCount));
}
}
return list;
};
QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) {
switch (errorCorrectLevel) {
case QRErrorCorrectLevel.L:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
case QRErrorCorrectLevel.M:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
case QRErrorCorrectLevel.Q:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
case QRErrorCorrectLevel.H:
return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
default:
return undefined;
}
};
function QRBitBuffer() {
this.buffer = [];
this.length = 0;
}
QRBitBuffer.prototype = {
get: function (index) {
var bufIndex = Math.floor(index / 8);
return ((this.buffer[bufIndex] >>> (7 - (index % 8))) & 1) == 1;
},
put: function (num, length) {
for (var i = 0; i < length; i++) {
this.putBit(((num >>> (length - i - 1)) & 1) == 1);
}
},
getLengthInBits: function () {
return this.length;
},
putBit: function (bit) {
var bufIndex = Math.floor(this.length / 8);
if (this.buffer.length <= bufIndex) {
this.buffer.push(0);
}
if (bit) {
this.buffer[bufIndex] |= 0x80 >>> this.length % 8;
}
this.length++;
},
};
var QRCodeLimitLength = [
[17, 14, 11, 7],
[32, 26, 20, 14],
[53, 42, 32, 24],
[78, 62, 46, 34],
[106, 84, 60, 44],
[134, 106, 74, 58],
[154, 122, 86, 64],
[192, 152, 108, 84],
[230, 180, 130, 98],
[271, 213, 151, 119],
[321, 251, 177, 137],
[367, 287, 203, 155],
[425, 331, 241, 177],
[458, 362, 258, 194],
[520, 412, 292, 220],
[586, 450, 322, 250],
[644, 504, 364, 280],
[718, 560, 394, 310],
[792, 624, 442, 338],
[858, 666, 482, 382],
[929, 711, 509, 403],
[1003, 779, 565, 439],
[1091, 857, 611, 461],
[1171, 911, 661, 511],
[1273, 997, 715, 535],
[1367, 1059, 751, 593],
[1465, 1125, 805, 625],
[1528, 1190, 868, 658],
[1628, 1264, 908, 698],
[1732, 1370, 982, 742],
[1840, 1452, 1030, 790],
[1952, 1538, 1112, 842],
[2068, 1628, 1168, 898],
[2188, 1722, 1228, 958],
[2303, 1809, 1283, 983],
[2431, 1911, 1351, 1051],
[2563, 1989, 1423, 1093],
[2699, 2099, 1499, 1139],
[2809, 2213, 1579, 1219],
[2953, 2331, 1663, 1273],
];
// QRCode object
QRCode = function (canvasId, vOption) {
this._htOption = {
width: 256,
height: 256,
typeNumber: 4,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRErrorCorrectLevel.H,
};
if (typeof vOption === 'string') {
vOption = {
text: vOption,
};
}
// Overwrites options
if (vOption) {
for (var i in vOption) {
this._htOption[i] = vOption[i];
}
}
this._oQRCode = null;
this.canvasId = canvasId;
if (this._htOption.text && this.canvasId) {
this.makeCode(this._htOption.text);
}
};
QRCode.prototype.makeCode = function (sText) {
this._oQRCode = new QRCodeModel(
_getTypeNumber(sText, this._htOption.correctLevel),
this._htOption.correctLevel
);
this._oQRCode.addData(sText);
this._oQRCode.make();
this.makeImage();
};
QRCode.prototype.makeImage = function () {
var _oContext;
if (this._htOption.usingIn) {
_oContext = wx.createCanvasContext(this.canvasId, this._htOption.usingIn);
} else {
_oContext = wx.createCanvasContext(this.canvasId);
}
var _htOption = this._htOption;
var oQRCode = this._oQRCode;
var nCount = oQRCode.getModuleCount();
var nWidth = _htOption.padding
? (_htOption.width - 2 * _htOption.padding) / nCount
: _htOption.width / nCount;
var nHeight = _htOption.padding
? (_htOption.height - 2 * _htOption.padding) / nCount
: _htOption.height / nCount;
var nRoundedHeight = Math.round(nHeight);
var nRoundedWidth = Math.round(nWidth);
if (_htOption.image && _htOption.image != '') {
_oContext.drawImage(_htOption.image, 0, 0, _htOption.width, _htOption.height);
}
_oContext.setFillStyle('#fff');
_oContext.fillRect(0, 0, _htOption.width, _htOption.height);
_oContext.save();
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
var bIsDark = oQRCode.isDark(row, col);
var nLeft = _htOption.padding ? col * nWidth + _htOption.padding : col * nWidth;
var nTop = _htOption.padding ? row * nHeight + _htOption.padding : row * nHeight;
_oContext.setStrokeStyle(bIsDark ? _htOption.colorDark : _htOption.colorLight);
// _oContext.setStrokeStyle('red')
_oContext.setLineWidth(1);
_oContext.setFillStyle(bIsDark ? _htOption.colorDark : _htOption.colorLight);
// _oContext.setFillStyle('red')
// if (bIsDark) {
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
// }
// 안티 앨리어싱 방지 처리
// if (bIsDark) {
_oContext.strokeRect(
Math.floor(nLeft) + 0.5,
Math.floor(nTop) + 0.5,
nRoundedHeight
);
_oContext.strokeRect(
Math.ceil(nLeft) - 0.5,
Math.ceil(nTop) - 0.5,
nRoundedWidth,
nRoundedHeight
);
// }
// _oContext.fillRect(
// Math.floor(nLeft) + 0.5,
// Math.floor(nTop) + 0.5,
// nRoundedWidth,
// nRoundedHeight
// );
// _oContext.fillRect(
// Math.ceil(nLeft) - 0.5,
// Math.ceil(nTop) - 0.5,
// nRoundedWidth,
// nRoundedHeight
// );
// _oContext.clearRect(
// Math.floor(nLeft) + 0.5,
// Math.floor(nTop) + 0.5,
// nRoundedWidth,
// nRoundedHeight
// );
// _oContext.clearRect(
// Math.ceil(nLeft) - 0.5,
// Math.ceil(nTop) - 0.5,
// nRoundedWidth,
// nRoundedHeight
// );
}
}
_oContext.draw(false, () => {
setTimeout(() => {
this.exportImage();
}, 800);
});
};
// 保存为图片,将临时路径传给回调
QRCode.prototype.exportImage = function (callback) {
if (this._htOption.callback && typeof this._htOption.callback === 'function') {
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: this._htOption.width,
height: this._htOption.height,
destWidth: this._htOption.width,
destHeight: this._htOption.height,
canvasId: this.canvasId,
success: (res) => {
this._htOption.callback({ path: res.tempFilePath });
},
});
}
};
QRCode.CorrectLevel = QRErrorCorrectLevel;
})();
module.exports = QRCode;
import Config from '../static/config/index.js';
import WXBizDataCrypt from './WXBizDataCrypt.js';
import { $EventBus } from './EventBus';
import Store from '@/store';
export default {
// 组装提交订单数据
AssemblyOrder(totalPrice, totalNum) {
let shopCarInfo = uni.getStorageSync('shopCarInfo').filter((v) => v.flag == true);
AssemblyOrder(totalPrice, totalNum, buyType, shopCarInfo) {
if (shopCarInfo && totalPrice > 0 && totalNum > 0) {
let orderDetails = [];
for (let i = 0; i < shopCarInfo.length; i++) {
let item = shopCarInfo[i];
let res = {
goodsId: item.goodsId, //商品id
goodsName: item.name, //商品名称
machineId: undefined, //点单屏机器ID
num: item.num, //当前sku数量
realAmount: item.sku.discount * item.num, //实付金额
amount: item.sku.price * item.num, //总价格
specRuleDetail: JSON.stringify(item.sku.rules), //规格选项详情
specRuleIds: item.sku.rules.map((item) => item.ruleId).join(','), //规格选项详情
skuId: item.skuId, //"sku ID"
......@@ -24,12 +25,13 @@ export default {
orderDetails.push(res);
}
const shopData = uni.getStorageSync('shopData');
let DAta = {
amount: totalPrice, //商品总金额
goodsNum: totalNum, //商品总数量
shopId: '12', //店铺
shopId: shopData.id, //店铺f
machineId: undefined, //机器ID
source: 3, //小程序固定传3
source: buyType, //小程序固定传3
orderDetails: orderDetails,
};
return DAta;
......@@ -40,17 +42,19 @@ export default {
}
},
// 加入购物车数据
getallNum(Obj) {
async getallNum(Obj, callback) {
console.log(Obj);
let shopCarInfo = uni.getStorageSync('shopCarInfo') || [];
let size = 0;
shopCarInfo.forEach((item) => (size += item.num), 0);
shopCarInfo.forEach((item) => (size += item.num));
if (size >= 9) {
uni.showToast({
title: '最多可一次购买9杯',
icon: 'none',
});
return;
return false;
}
if (shopCarInfo) {
let currentGoods = shopCarInfo.find((v) => v.goodsId == Obj.goodsId && v.skuId == Obj.skuId);
if (currentGoods) {
......@@ -61,9 +65,38 @@ export default {
} else {
shopCarInfo = [Obj];
}
console.log(Obj);
uni.setStorageSync('shopCarInfo', shopCarInfo);
console.log(shopCarInfo);
$EventBus.$emit('updateCar');
if (callback) {
callback();
}
},
// 商品详情立即购买
async addGoods(Obj) {
let goodsList = [];
let size = 0;
goodsList.forEach((item) => (size += item.num));
if (size >= 9) {
uni.showToast({
title: '最多可一次购买9杯',
icon: 'none',
});
return false;
}
if (goodsList) {
let currentGoods = goodsList.find(
(item) => item.goodsId == Obj.goodsId && item.skuId == Obj.skuId
);
if (currentGoods) {
currentGoods.num += 1;
} else {
goodsList.push(Obj);
}
} else {
goodsList = [Obj];
}
uni.setStorageSync('goodsList', goodsList);
},
// 解密手机
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment