From 802cc2d721bf6ab4f14684fe9525027d36ee5495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=AD=8F=E5=95=BE?= <1144797966@qq.com> Date: Wed, 19 Jun 2024 17:11:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=A6=E6=83=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/js/websocket.js | 11 +- components/payPassword.vue | 1 + framework/0-conf.js | 2 +- framework/11-api.js | 9 +- pages/login/login.vue | 107 ++++++----- pages/order/order_detail.vue | 4 +- pages/order_detail/order_detail.vue | 21 +-- pages/order_food/order_food.vue | 282 ++++++++++++++-------------- static/1.gif | Bin 0 -> 11745 bytes 9 files changed, 223 insertions(+), 214 deletions(-) create mode 100644 static/1.gif diff --git a/common/js/websocket.js b/common/js/websocket.js index c9f3680..988cb1b 100644 --- a/common/js/websocket.js +++ b/common/js/websocket.js @@ -28,7 +28,7 @@ class webSocketUtils { this.socketTask = uni.connectSocket({ url: this.url, success: () => { - console.log('正准备建立websocket中...'); + // console.log('正准备建立websocket中...'); // uni.hideLoading(); // 返回实例 return this.socketTask; @@ -37,7 +37,7 @@ class webSocketUtils { this.socketTask.onOpen((res) => { uni.hideLoading() this.connectNum = 1; - console.log('WebSocket连接正常!'); + // console.log('WebSocket连接正常!'); if (this.params) { //是否初始化请求 this.send(this.params); } @@ -52,7 +52,6 @@ class webSocketUtils { let res = JSON.parse(e.data); uni.$emit('message', res) // 普通socket信息处理 TODO - }); }); // 监听连接失败,这里代码我注释掉的原因是因为如果服务器关闭后,和下面的onclose方法一起发起重连操作,这样会导致重复连接 @@ -107,20 +106,20 @@ class webSocketUtils { } //发送消息 send(data) { - console.log("发送消息---------->", data); + // console.log("发送消息---------->", data); // 注:只有连接正常打开中 ,才能正常成功发送消息 if (this.socketTask) { this.socketTask.send({ data: JSON.stringify(data), async success() { - console.log("消息发送成功"); + // console.log("消息发送成功"); }, }); } } //开启心跳检测 start(data) { - console.log('开启心跳检测', data) + // console.log('开启心跳检测', data) this.heartbeatInterval = setInterval(() => { this.send({ data: '心跳检测', diff --git a/components/payPassword.vue b/components/payPassword.vue index ec90d2c..69ae612 100644 --- a/components/payPassword.vue +++ b/components/payPassword.vue @@ -134,6 +134,7 @@ width: 100%; height: 100%; background-color: #FFFFFF; + z-index: 999; } .pay-title { diff --git a/framework/0-conf.js b/framework/0-conf.js index d1efb19..706c58d 100644 --- a/framework/0-conf.js +++ b/framework/0-conf.js @@ -19,7 +19,7 @@ const baseUrlwws = 'ws://cashier.sxczgkj.cn/cashierService' const baseUrl = debug ? proxyApi : 'https://cashier.sxczgkj.cn/cashierService' // 线上 const baseUrlwws = debug ? proxyApiwws : 'wss://cashier.sxczgkj.cn/netty' // 线上 // const baseUrl = 'https://cashier.sxczgkj.cn/cashierService' // 线上 -// const baseUrlwws = 'wss://cashier.sxczgkj.cn/netty' // 线上 +// const baseUrlwws = 'wss://cashier.sxczgkj.cn/netty' // 线上/ // #endif // import VConsole from "./vConsole.js" diff --git a/framework/11-api.js b/framework/11-api.js index fa274dc..c7418c1 100644 --- a/framework/11-api.js +++ b/framework/11-api.js @@ -75,8 +75,8 @@ async function request(options) { token: uni.cache.get('token'), openId: uni.cache.get('miniAppOpenId'), id: uni.cache.get('userInfo').id, - loginName:"", - clientType:'' + loginName: "", + clientType: '' } } else { @@ -95,12 +95,12 @@ async function request(options) { icon: "none", success: () => { setTimeout(res => { - uni.cache.clear(); + uni.cache.set('token', ''); uni.redirectTo({ url: '/pages/login/login' }); }, 1000) - + } }) } else if (res.code == 482) { @@ -117,7 +117,6 @@ async function request(options) { setTimeout(res => { if (options.toast) { // #ifdef MP-WEIXIN - uni.hideLoading() // #endif // #ifndef MP-WEIXIN uni.pro.hideLoading() diff --git a/pages/login/login.vue b/pages/login/login.vue index ebf9cdd..861e652 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -133,12 +133,12 @@ onLoad(e) { - console.log(e,'调试1') - try { - this.types = e.types - } catch (e) { - //TODO handle the exception - } + // console.log(e, '调试1') + // try { + // this.types = e.types + // } catch (e) { + // //TODO handle the exception + // } // #ifdef APP-PLUS || H5 this.showbox = true // #endif @@ -285,7 +285,7 @@ uni.cache.set('miniAppOpenId', res.data.userInfo .miniAppOpenId) uni.cache.set('userInfo', res.data.userInfo); - if (this.types == 0) { + if (uni.cache.get('types') == 'types') { uni.reLaunch({ url: '/pages/order_food/order_food' }); @@ -319,42 +319,51 @@ // }, async userlogin(reslange) { var resdataa = reslange - // #ifdef MP-WEIXIN - uni.login({ - provider: 'weixin', - success: async (data) => { - try { - uni.getUserInfo({ - provider: 'weixin', - success: async (infoRes) => { - uni.cache.set('weixincode', data.code); - let res = await this.api.userwxlogin({ - code: uni.cache.get('weixincode'), //临时登录凭证 - rawData: infoRes.rawData, - signature: infoRes.signature, - iv: resdataa.detail.iv, - encryptedData: resdataa.detail.encryptedData - }) - if (res.code == 0) { - uni.cache.set('token', res.data.token); - uni.cache.set('miniAppOpenId', res.data.userInfo - .miniAppOpenId) - uni.cache.set('userInfo', res.data.userInfo); - if (this.types == 0) { - uni.reLaunch({ - url: '/pages/order_food/order_food' - }); - } else { - uni.pro.switchTab('index/index') + if (resdataa.detail.iv) { + // #ifdef MP-WEIXIN + uni.login({ + provider: 'weixin', + success: async (data) => { + try { + uni.getUserInfo({ + provider: 'weixin', + success: async (infoRes) => { + uni.cache.set('weixincode', data.code); + let res = await this.api.userwxlogin({ + code: uni.cache.get('weixincode'), //临时登录凭证 + rawData: infoRes.rawData, + signature: infoRes.signature, + iv: resdataa.detail.iv, + encryptedData: resdataa.detail + .encryptedData + }) + if (res.code == 0) { + uni.cache.set('token', res.data.token); + uni.cache.set('miniAppOpenId', res.data.userInfo + .miniAppOpenId) + uni.cache.set('userInfo', res.data.userInfo); + if (uni.cache.get('types') == 'types') { + uni.reLaunch({ + url: '/pages/order_food/order_food' + }); + } else { + uni.pro.switchTab('index/index') + } } - } - }, - fail: (err) => {} - }); - } catch (e) {} - } - }); - // #endif + }, + fail: (err) => {} + }); + } catch (e) {} + } + }); + // #endif + } else { + uni.showToast({ + title: '获取手机号失败!请重新获取', + icon: 'none' + }); + } + }, } }; @@ -369,12 +378,12 @@ .container { // position: relative; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100vh; - overflow: hidden; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + overflow: hidden; .top { position: absolute; @@ -392,6 +401,7 @@ left: 50%; z-index: 22; transform: translateX(-50%); + image { width: 128rpx; height: 128rpx; @@ -507,6 +517,7 @@ background: #ffffff; border-radius: 40rpx 40rpx 0px 0px; top: 220rpx; + .top_box_one { position: relative; width: 100%; diff --git a/pages/order/order_detail.vue b/pages/order/order_detail.vue index 5b80a51..70f616d 100644 --- a/pages/order/order_detail.vue +++ b/pages/order/order_detail.vue @@ -40,7 +40,7 @@ 取餐号 - {{listinfo.tableName}} + {{listinfo.outNumber}} @@ -63,8 +63,10 @@ {{item.productName}} + {{item.productSkuName}} x{{item.num}} + {{item.priceAmount}} diff --git a/pages/order_detail/order_detail.vue b/pages/order_detail/order_detail.vue index 3937d81..b049d2a 100644 --- a/pages/order_detail/order_detail.vue +++ b/pages/order_detail/order_detail.vue @@ -54,6 +54,7 @@ {{item.productName}} + {{item.productSkuName}} x{{item.num}} @@ -88,6 +89,7 @@ 可用优惠券{{couponAmount}}张 --> + @@ -193,6 +195,7 @@ return { height: '', pay_type: 1, + remark:'', listinfoid: '', listinfo: { detailList: [], @@ -263,13 +266,7 @@ } }, - // 数据处理 - socketSendMsg(data) { - if (this.socketTicket) { - this.socketTicket.send(data); - } - }, - orderfoodindex() { + orderfoodindex() {//优惠劵 uni.pro.navigateTo('index/coupons/index', { orderfood: 0, orderId: this.listinfo.id, @@ -287,13 +284,12 @@ } }); }, - async paymodfiyOrderInfo() { + async paymodfiyOrderInfo() {//支付完成后请求 let res = await this.api.paymodfiyOrderInfo({ orderId: this.listinfo.id, }) }, - // 去充值 - goRecharge() { + goRecharge() {// 去充值 uni.pro.navigateTo('/pages/member/index', { shopId: uni.cache.get('shopUser') }) @@ -348,7 +344,7 @@ uni.showToast({ title: "支付成功" }) - uni.cache.set('shopUser', '') //删除shopUser + // uni.cache.set('shopUser', '') //删除shopUser _this.paymodfiyOrderInfo() uni.redirectTo({ url: '/pages/order/order_detail?orderId=' + @@ -372,6 +368,7 @@ let res = await this.api.accountPay({ orderId: this.listinfo.id, memberId: this.amountVIP.id, + // remark: this.remark, pwd }) if (res.code == 0) { @@ -462,7 +459,7 @@ background-color: #fff; border-radius: 20upx; padding: 28upx; - margin-bottom: 28upx; + margin-bottom: 48rpx; .head { display: flex; diff --git a/pages/order_food/order_food.vue b/pages/order_food/order_food.vue index c26f83e..d7fb334 100644 --- a/pages/order_food/order_food.vue +++ b/pages/order_food/order_food.vue @@ -2,7 +2,9 @@ - + + 加载中 + @@ -63,11 +65,12 @@ 空 - - + + - + {{ item1.name }} @@ -78,18 +81,18 @@ + @click.stop="clickspecifications(item1,index,index1)"> 选规格 {{item1.cartNumber}} + @click.stop="cartadd(item1,index,index1,'-',item1.productSkuResult == null ? '单规格':'')"> {{ item1.cartNumber }} + @click.stop="cartadd(item1,index,index1,'+',item1.productSkuResult == null ? '单规格':'')"> @@ -117,15 +120,11 @@ - 清空购物车 - @@ -187,12 +186,17 @@ + + + + {{specifications.name}} - + - {{item.name}} + {{item.name}} - + 已选规格:{{skuidname.toString()}} @@ -213,18 +217,24 @@ + @click="cartadd(specifications,specifications.indexa,specifications.indexb,'-',specifications.tagSnap == null ? '单规格':'')"> {{amountcartNumber}} + @click="cartadd(specifications,specifications.indexa,specifications.indexb,'+',specifications.tagSnap == null ? '单规格':'')"> + + + + + @@ -247,6 +257,7 @@ shopList: {}, //数据类型 active: 0, showShopInfo: false, + popupshowInfo: false, showShopsku: false, titleTopNumIndex: 0, titleTopNums: [], @@ -258,8 +269,8 @@ socketTicket: null, amountcartNumber: 0, skuidsearch: '', // - salePrice: '' ,//钱数 - fixedtrue:true + salePrice: '', //钱数 + fixedtrue: true }; }, onPageScroll(e) { @@ -283,32 +294,20 @@ this.tableCode = this.getQueryString(decodeURIComponent(e.q), 'code') uni.cache.set('tableCode', this.tableCode) } - if (!uni.cache.get('token')) { - uni.reLaunch({ - url: '/pages/login/login?types=' + 0 - }); - return false - } + uni.cache.set('types', 'types'); uni.$on('message', this.getMessage) this.$nextTick(() => { this.countTitleTopNum(); //导航栏 }); }, onUnload() { - try { - this.socketSendMsg({ //定义socket数据传参 - "type": "close", //“addcart:添加购物车,create0rder:生成订单,clearCart:庆康购物车”, - }) - } catch (e) { - //TODO handle the exception - } this.socketTicket.Close() uni.$off('message') }, onShow() { - if (uni.cache.get('token')) { + setTimeout(() => { this.productqueryShopIdByTableCode() //获取shop User id - } + }, 500) }, methods: { // 单独获取他的shopUserid @@ -327,15 +326,35 @@ } }, getMessage(msg) { //wss 回显数据 + // console.log(this.shopList.productInfo) + // console.log(msg.data) + // const sumValuesByKey = (arr, key) => { + // return arr.reduce((accumulator, current) => { + // const existing = accumulator.find(item => item[key] === current[key]); + // if (existing) { + // existing.number += current.number; + // } else { + // accumulator.push({ + // ...current + // }); + // } + // return accumulator; + // }, []); + // }; + // const result = sumValuesByKey(msg.data, 'productId'); + // this.shopList.productInfo.forEach((item, index) => { + // if (item.id == result.categoryId) { + // item.products.forEach((item1,index1) => { + + // }) + // } + // }); if (msg.status != 'success') { uni.showToast({ title: msg.msg, icon: "none", }) if (msg.msg == '桌码不存在') { //卓码不存在直接退出 - this.socketSendMsg({ //定义socket数据传参 - "type": "close", //“addcart:添加购物车,create0rder:生成订单,clearCart:庆康购物车”, - }) this.socketTicket.Close() uni.$off('message') uni.navigateBack() @@ -343,12 +362,11 @@ } } else { switch (msg.type) { - case 'sku': // sku 数量 + case 'sku': // sku 数量 查询这个商品的价格和数量 this.$set(this, 'amountcartNumber', msg.amount) this.productqueryProduct() //list 数据 break; case 'clearCart': - this.specifications.duoguge = '' this.skuidname = [] this.showCart = false setTimeout(() => { @@ -362,7 +380,6 @@ break; case 'order': console.log('clearCart') - this.specifications.duoguge = '' this.skuidname = [] this.showCart = false this.cartLists = msg @@ -397,7 +414,7 @@ break; default: this.cartLists = msg - this.productqueryProduct() //list 数据 + } } }, @@ -416,45 +433,6 @@ this.socketTicket.send(data); } }, - scanCodehandle(e) { - // #ifdef MP-WEIXIN || MP-ALIPAY - uni.login({ //alipay weixin - provider: 'weixin', - success: async (data) => { - try { - uni.getUserInfo({ - provider: 'weixin', - success: async (infoRes) => { - console.log(infoRes, 81); - uni.cache.set('weixincode', data.code); - let res = await this.api.userwxlogin({ - code: uni.cache.get('weixincode'), //临时登录凭证 - encryptedData: infoRes.encryptedData, // 用户非敏感信息 - rawData: infoRes.rawData, - signature: infoRes.signature, - iv: infoRes.iv, - qrCode: uni.cache.get('tableCode') - }) - if (res.code == 0) { - uni.cache.set('token', res.data.token); - uni.cache.set('miniAppOpenId', res.data.userInfo - .miniAppOpenId) - uni.cache.set('userInfo', res.data.userInfo); - this.productqueryShopIdByTableCode() //获取shop User id - } - }, - fail: (err) => { - console.log(err) - } - }); - - } catch (e) { - console.log(e) - } - } - }); - // #endif - }, getQueryString(url, name) { //解码 var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i') var r = url.substr(1).match(reg) @@ -463,14 +441,12 @@ } return null; }, - async cartadd(item, index, index1, a, b, guge) { //列表添加 - console.log(item, index, index1, a, b, guge) - - if (guge == '单规格') { //没有规格为空 - this.specifications.duoguge = '' + async cartadd(item, index, index1, a, b) { //列表添加 a传参加减号 b是判断单规格多规格 + console.log(item, index, index1, a, b) + if (b == '单规格') { //没有规格为空 this.skuidname = [] } - this.hodgepodge(item, 1, a) //获取skuid + this.hodgepodge(item, 1, a) //获取skuid /1添加购物车 }, async cartListadd(item, index, a) { console.log(item, index, a) @@ -487,7 +463,6 @@ } catch (e) { //TODO handle the exception } - }, async productqueryProduct() { //list 数据 let res = await this.api.productqueryProduct({ @@ -496,55 +471,50 @@ }) if (res.code == 0) { this.shopList = res.data - this.fixedtrue = false + setTimeout(() => { + this.fixedtrue = false + }, 1000) this.$nextTick(() => { this.countTitleTopNum(); }); } }, - clickspecifications(e, a, b, d) { - console.log(e, a, b) + clickspecifications(item1, index, index1) { this.skuidname = [] - this.specifications = e - this.specifications.indexa = a - this.specifications.indexb = b - this.specifications.duoguge = 'duoguge' - if (e.productSkuResult.tagSnap == null) { - uni.showToast({ - title: '暂无规格', - icon: "none", - }) - return false - } - this.specifications.tagSnap = JSON.parse(e.productSkuResult.tagSnap).map((item) => { - let res = { - id: e.id, //商品id - name: item.name, - start: 0, - children: item.value.split(",") - } - return res - }) - this.specifications.tagSnap.forEach((val, index, arr) => { //初始化skuidname的数据 选择第一个 - console.log(val.children[0], 'skuidnam是否为空1') - this.skuidname.push(val.children[0]) - }) + this.specifications = item1 + this.specifications.indexa = index + this.specifications.indexb = index1 try { - this.hodgepodge(this.specifications.tagSnap[0], 2) + if (item1.productSkuResult == null) { + // 但但单个规格弹框的处理 + this.hodgepodge(this.specifications, 2) //获取skuid /2查找价格和数量 + } else { + // 多规格数据处理 + this.specifications.tagSnap = JSON.parse(item1.productSkuResult.tagSnap).map((item) => { + let res = { + id: item1.id, //商品id + name: item.name, + start: 0, + children: item.value.split(",") + } + return res + }) + this.specifications.tagSnap.forEach((val, index, arr) => { //初始化skuidname的数据 选择第一个 + this.skuidname.push(val.children[0]) + }) + this.hodgepodge(this.specifications.tagSnap[0], 2) //获取skuid /2查找价格和数量 + } + } catch (e) { //TODO handle the exception } - if (d != '更新数据') { - this.showShopsku = true - } }, async morloe(e, index, index1, item) { - console.log(index, 'skuidnam是否为空2') this.specifications.tagSnap[index]['start'] = index1 this.skuidname.splice(index, 1, e) //替换skuidname的数据 this.hodgepodge(item, 2) }, - async hodgepodge(item, a, c) { //去获取商品id 库存等 + async hodgepodge(item, a, c) { //此接口去获取商品id !!!赋值库存 数量 价格等 try { let res = await this.api.productqueryProductSku({ shopId: uni.cache.get('shopUser'), @@ -558,9 +528,9 @@ }) } else { this.skuidsearch = res.data.id // 储存skuid 用于筛选数量 - this.salePrice = res.data.salePrice // 储存skuid 用于筛选数量 + this.salePrice = res.data.salePrice // 价格 let data = null - if (a == 1) { + if (a == 1) { //1添加购物车 2是websocket返回这个商品的价格(应为不同的多规格商品返回不同的价格) data = { //定义socket数据传参 "skuId": res.data.id, "num": c == '-' ? -1 : 1, //数量 @@ -570,7 +540,7 @@ "userId": uni.cache.get('userInfo').id }; } else { - data = { //定义socket数据传参 + data = { //查询这个商品的价格 "skuId": res.data.id, "num": '', //数量 "type": "sku", //“addcart:添加购物车,create0rder:生成订单,clearCart:庆康购物车”, @@ -578,21 +548,14 @@ "shopId": uni.cache.get('shopUser'), "userId": uni.cache.get('userInfo').id }; + this.showShopsku = true //打开弹框 } uni.$u.debounce(this.socketSendMsg(data), 500) } } catch (e) {} }, - orderdetail() { - // let data = { //缓存的生成订单 //去结算 - // "skuId": '', - // "num": '', //数量 - // "type": "queryCart", //“addcart:添加购物车,create0rder:生成订单,clearCart:庆康购物车”, - // "productId": '', //商品id - // "shopId": uni.cache.get('shopUser'), - // "userId": uni.cache.get('userInfo').id - // } - let data = { // 直接生成订单 + orderdetail() { // 直接生成订单 + let data = { "skuId": '', "num": '', //数量 "type": "createOrder", //“addcart:添加购物车,create0rder:生成订单,clearCart:庆康购物车”, @@ -605,12 +568,7 @@ } uni.$u.debounce(this.socketSendMsg(data), 500) }, - orderfoodindex() { - uni.pro.navigateTo('index/coupons/index', { - orderfood: 0 - }) - }, - async cartclear() { + async cartclear() { //清空购物车 try { const data = { //定义socket数据传参 "skuId": '', @@ -779,6 +737,7 @@ height: $h; margin-top: -40upx; background: #999; + position: relative; .img { width: 100%; @@ -831,6 +790,7 @@ .left-wrap { width: $tabLeft; background-color: $bg; + padding: 0 0 $paddingSize * 3 + $cartH 0; .left { width: $tabLeft; @@ -840,7 +800,8 @@ height: $itemH; display: flex; align-items: center; - padding-left: $paddingSize; + padding: 0 $paddingSize; + justify-content: center; &.active { background-color: #fff; @@ -873,6 +834,25 @@ display: flex; padding-bottom: $paddingSize; + .langcover { + position: relative; + } + + .langcover::after { + content: '加载中..'; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 100%; + background-color: #e8e8e8; + color: #6b6b6b; + border-radius: 10rpx; + text-align: center; + line-height: 180rpx; + z-index: 1; + } + .info { flex: 1; padding-left: 20upx; @@ -973,7 +953,7 @@ width: 100%; padding: $paddingSize; position: fixed; - bottom: $paddingSize * 2; + bottom: $paddingSize; left: 0; z-index: 99; @@ -1057,10 +1037,23 @@ } .shop_sku { + position: relative; width: 700rpx; border-radius: 20rpx; background: #fff; + .positionabsolute { + position: absolute; + top: 10rpx; + left: 10rpx; + } + + .shop_skucimage { + width: 100%; + height: 440rpx; + border-radius: 20rpx 20rpx 0 0; + } + .shop_sku_name { padding: 0 $paddingSize; margin-top: 20rpx; @@ -1165,6 +1158,13 @@ } } + .showInfo { + width: 100%; + border-radius: 20rpx; + background: #fff; + max-height: 70vh; + } + .shop-info-wrap { .info-wrap { padding: $paddingSize * 2 0; diff --git a/static/1.gif b/static/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..ee8ae1c4f8306d1b21456cce9a6d85f8c15451c5 GIT binary patch literal 11745 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�SP7ijcSBa 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 literal 0 HcmV?d00001