Browse Source

finish pay

dev
赵明涛 11 months ago
parent
commit
4c74f2a2a4
  1. 61
      uniapp_project_code/src/App.vue
  2. 62
      uniapp_project_code/src/components/index/keyboard/input_box_QR.vue
  3. 9
      uniapp_project_code/src/components/index/keyboard/input_box_end_phone.vue
  4. 53
      uniapp_project_code/src/components/index/keyboard/keyboard_listener.vue
  5. 2
      uniapp_project_code/src/components/index/keyboard/view_keyboard.vue
  6. 250
      uniapp_project_code/src/components/index/list_item.vue
  7. 48
      uniapp_project_code/src/components/index/list_item_nvue.nvue
  8. 25
      uniapp_project_code/src/components/index/view_footer.nvue
  9. 4
      uniapp_project_code/src/components/index/view_header.nvue
  10. 2
      uniapp_project_code/src/components/pay/paying.vue
  11. 2
      uniapp_project_code/src/components/pay/success.vue
  12. 15
      uniapp_project_code/src/manifest.json
  13. 11
      uniapp_project_code/src/pages.json
  14. 398
      uniapp_project_code/src/pages/index/-index.nvue
  15. 169
      uniapp_project_code/src/pages/index/index.nvue
  16. 461
      uniapp_project_code/src/pages/index/index.vue
  17. 29
      uniapp_project_code/src/pages/index/standby.nvue
  18. 232
      uniapp_project_code/src/pages/pay/index.vue
  19. 35
      uniapp_project_code/src/utils/api.js
  20. 219
      uniapp_project_code/src/utils/dictOfKeyboard.js
  21. 113
      uniapp_project_code/src/utils/server.js
  22. 40
      uniapp_project_code/src/utils/util.js

61
uniapp_project_code/src/App.vue

@ -1,13 +1,52 @@
<script setup>
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
onLaunch(() => {
console.log("App Launch");
});
onShow(() => {
console.log("App Show");
});
onHide(() => {
console.log("App Hide");
});
<script >
// import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
// import { ref } from 'vue'
// onLaunch(() => {
// console.log("App Launch");
// });
// onShow(() => {
// console.log("App Show");
// });
// onHide(() => {
// console.log("App Hide");
// });
export default {
onLaunch() {
console.log("App Launch default");
},
onShow() {
console.log("App Show default");
},
onHide() {
console.log("App Hide default");
},
globalData: {
goodsList : [],
shopList : [],
accountInfo : {
brand_id: "63",
store_id: "167", //stadium_id
username: "Ella06",
password: "123456",
assistant_client:"PC",
token: "e6cabeae-0c1a-11ee-aa40-5254005df464",
},
loginInfo : {
phone: "",
password: "",
token: "",
vip: false,
},
payInfo : {
payType: "",
paySuccess: false,
},
},
methods: {
}
}
</script>
<style></style>

62
uniapp_project_code/src/components/index/keyboard/input_box_QR.vue

@ -1,23 +1,26 @@
<template>
<cover-view class="keyboard-box" :style="{ height: props.maskHeight + 'px' }" @touchmove.prevent="" @click.stop="">
<view class="keyboard-box" :style="{ height: props.maskHeight + 'px' }" @touchmove.prevent="" @click.stop="">
<view class="kb-area">
<image class="del-icon" src="/static/index/del_icon_big.png" mode="aspectFit"
@click="handle_closeKeyboardBox" />
<text class="txt-title">输入条形码</text>
<view class="txt-input">
<view class="txt-input" :class="{'err-border':errTip}">
<text class="txt" :class="getInputClass()">{{inputValue||"请输入条形码"}}</text>
</view>
<text class="txt-err-tip" v-if="errTip">查询不到该条形码商品信息, 请检查是否有误</text>
<view class="input-keyboard">
<viewKeyboard :maxInput="props.maxInput" @inputValueUpdate="accept_inputValueUpdate"></viewKeyboard>
<viewKeyboard :maxInput="props.maxInput" @inputValueUpdate="accept_inputValueUpdate"
@checkRes="handle_checkRes"></viewKeyboard>
<view class="sure-btn" @click="handle_clickCommit">
<text class="txt">确定</text>
</view>
</view>
</view>
</cover-view>
</view>
</template>
<script setup>
@ -26,7 +29,7 @@
import {
onMounted,
ref
ref,
} from 'vue'
//define emits or props
@ -43,20 +46,32 @@
})
let inputValue = ref("") //
let errTip = ref(false) //
onMounted(async (res) => {
console.log(res + ` the keyboard_box component is now mounted. ` + props.maskHeight)
console.log( ` the keyboard_box component is now mounted. ` ,app.globalData)
})
const handle_closeKeyboardBox = () => {
emits("showIt", "false")
}
const handle_clickCommit = () => {
emits("clickCommit", inputValue.value)
const handle_clickCommit = async () => {
console.log("handle_clickCommit")
// emits("clickCommit", inputValue.value)
await searchGoodBySku(inputValue.value).then((goods)=>{
let inputCode = inputValue.value
emits("clickCommit", {inputCode,goods})
}).catch((err)=>{
console.error("searchGoodBySku err:",err)
errTip.value = true
})
}
const accept_inputValueUpdate = (i) => {
console.log("accept_inputValueClick:", i)
inputValue.value = i
if(inputValue.value.length > 0){
errTip.value = false
}
}
// getInputClass
@ -71,6 +86,22 @@
if (i == 10) return "0"
if (i == 11) return "" //delete
}
const searchGoodBySku=(sku)=>{
let app = getApp();
return new Promise((resolve,reject)=>{
let _list = app.globalData.goodsList.list
// let _good = _list.find(item=>item.erp_goods.erp_goods_sku == sku)
//sku,
let _goods = _list.filter(item=>item.erp_goods.erp_goods_sku == sku)
console.log("searchGoodBySku:",_goods)
if(_goods.length){
resolve(_goods)
}else{
reject("未找到商品")
}
})
}
</script>
<style lang="scss" scoped>
@ -109,13 +140,14 @@
color: #333333;
}
.txt-input {
@include ctf(flex-start);
flex-direction: row;
margin-top: 62rpx;
margin-bottom: 69rpx;
padding-left: 20rpx;
width: 470.83rpx;
width: 470rpx;
height: 69.44rpx;
border: 0.69rpx solid #979797;
border-radius: 6.94rpx;
@ -135,6 +167,18 @@
color: #999999;
}
}
.err-border {
border: 0.69rpx solid #FF0000;
}
.txt-err-tip {
align-self: flex-start;
font-weight: 400;
font-size: 19.44rpx;
color: #FF0000;
margin-left: 31.25rpx;
position: absolute;
top: 218.33rpx;
}
.input-keyboard {
width: 533.33rpx;

9
uniapp_project_code/src/components/index/keyboard/input_box_end_phone.vue

@ -1,5 +1,5 @@
<template>
<cover-view class="keyboard-box" :style="{ height: props.maskHeight + 'px' }" @touchmove.prevent="" @click.stop="">
<view class="keyboard-box" :style="{ height: props.maskHeight + 'px' }" @touchmove.prevent="" @click.stop="">
<view class="kb-area">
<image class="del-icon" src="/static/index/del_icon_big.png" mode="aspectFit"
@ -27,7 +27,7 @@
</view>
</view>
</cover-view>
</view>
</template>
<script setup>
@ -55,7 +55,7 @@
let inputValue = ref("") //
onMounted(async (res) => {
console.log(res + ` the keyboard_box component is now mounted. ` + props.maskHeight)
console.log( `the input_box_end_phone component is now mounted. ` + props.maskHeight)
})
const handle_closeKeyboardBox = () => {
@ -95,11 +95,12 @@
right: auto;
bottom: auto;
background: rgba(0, 0, 0, 0.5);
z-index: 11;
z-index: 1;
@include ctf(center);
.kb-area {
z-index: 12;
width: 533.33rpx;
// height: 827.64rpx;
background: #fff;

53
uniapp_project_code/src/components/index/keyboard/keyboard_listener.vue

@ -0,0 +1,53 @@
<template>
<view></view>
</template>
<script>
export default {
methods: {
onEvent(event) {
this.$emit(event.type, event)
},
},
}
</script>
<script module="keyboard" lang="renderjs">
import { onBeforeUnmount } from 'vue';
export default {
mounted() {
const onKey = (event) => {
const keys1 = ['type', 'timeStamp']
const keys2 = ['altKey', 'code', 'ctrlKey', 'isComposing', 'key', 'location', 'metaKey', 'repeat',
'shiftKey'
]
const keys3 = ['char', 'charCode', 'keyCode', 'keyIdentifier', 'keyLocation', 'which']
const data = {}
keys1.concat(keys2, keys3).forEach(key => data[key] = event[key])
this.$ownerInstance.callMethod('onEvent', data)
}
const names = ['keydown', 'keyup']
names.forEach(name => {
document.addEventListener(name, onKey, false)
})
// this.$on('hook:beforeDestroy', () => {
// names.forEach(name => {
// document.removeEventListener(name, onKey, false)
// })
// })
},
setup() {
//
onBeforeUnmount(() => {
names.forEach(name => {
document.removeEventListener(name, onKey, false);
});
});
}
}
</script>
<style>
</style>

2
uniapp_project_code/src/components/index/keyboard/view_keyboard.vue

@ -30,7 +30,7 @@
let activeValue = ref("") //active btn value
onMounted(async (res) => {
console.log(res + ` the keyboard_box component is now mounted. ` + props.maskHeight)
// console.log(res + ` the keyboard_box component is now mounted. ` + props.maskHeight)
})
const getNumBtnClass = (i) => {

250
uniapp_project_code/src/components/index/list_item.vue

@ -0,0 +1,250 @@
<template>
<!-- nvue用flex布局 -->
<view class="buy-item">
<view class="buy-item-left">
<image class="img" :src="mitem.goods_img||'-'" mode="aspectFill"></image>
</view>
<view class="buy-item-right">
<view class="br-top">
<text class="brt-title">{{mitem.erp_goods?.erp_goods_name||"-"}}</text>
<image class="img" src="/static/index/delete_icon.png" mode="scaleToFill" @click="del"/>
</view>
<view class="br-bottom">
<view class="brb-left">
<!-- 规格 -->
<text class="brb-specs">{{mitem.erp_goods?.erp_goods_specs||"-"}}</text>
<view class="brb-price">
<text class="brbp-single-price">¥{{mitem.erp_goods?.erp_goods_price||"-"}}</text>
<text class="brbp-underline-price">¥{{mitem.erp_goods?.erp_goods_price||"-"}}</text>
</view>
</view>
<view class="brb-middle">
<image class="img" src="/static/index/del_icon.png" mode="scaleToFill" @click="minus" />
<text class="txt">{{mitem.shopCount||1}}</text>
<image class="img" src="/static/index/add_icon.png" mode="scaleToFill" @click="add"/>
</view>
<view class="brb-right">
<view class="brbr-get-score">
<text class="txt">下单得积分</text>
<text class="brbr-score">{{mitem.score||0}}</text></view>
<view class="brbr-total-price">
<text class="brbrp-price1">¥</text>
<text class="brbrp-price2">{{mitem.shopCountPrice||"-"}}</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import util from "@/utils/util.js"
import {
onMounted,
ref,
} from 'vue'
//define emits or props
const emits = defineEmits(['delItem','addItem','minusItem'])
const props = defineProps(['mkey','mitem'])
onMounted(async (res) => {
// console.log( ` the keyboard_box component is now mounted. ` )
})
//add or minus
const add = () => {
emits("addItem", props.mkey)
}
const minus = () => {
emits("minusItem", props.mkey)
}
//delete
const del = () => {
emits("delItem", props.mkey)
}
</script>
<style lang="scss" scoped>
.buy-item {
margin-bottom: 13.89rpx;
// padding: 11.11rpx 17.36rpx;
width: 750rpx;
height: 125rpx;
@include fls(space-between);
flex-direction: row;
background: #F5F7F8;
// background: #FFFFFF;
// background: lightgray;
background: #eaeaea;//,
.buy-item-left {
@include fls(center);
flex-direction: row;
.img {
width: 97.22rpx;
height: 97.22rpx;
background: #F8F8F8;
border-radius: 6.94rpx;
background-color: lightgray;
}
margin:0 14rpx;
}
.buy-item-right {
@include fls(flex-start);
flex-direction: column;
// width: 600rpx;
width: 100%;
// height: 100%;
// height: 102.78rpx;
.br-top {
@include fls(space-between);
flex-direction: row;
// justify-content: flex-end;
align-items: flex-end;
width: 600rpx;
// padding-top: 10rpx;
height: 30rpx;
.brt-title {
font-weight: 500;
font-size: 16.67rpx;
color: #333333;
}
.img {
width: 23.61rpx;
height: 23.61rpx;
// background-color: lightgray;
}
}
.br-bottom {
@include ctf(center);
flex-direction: row;
// width: 100%;
// height: 100%;
// width: 600rpx;
// background-color: #999999;
height: 60rpx;
margin-top: 20rpx;
.brb-left {
@include fls(space-between);
flex-direction: column;
align-items: flex-start;
// background-color: lightcyan;
// width: 33%;
// height: 100%;
width: 200rpx;
height: 60rpx;
.brb-specs {
font-weight: 500;
font-size: 16.67rpx;
color: #999999;
// margin-bottom: 20rpx;
}
.brb-price {
@include fls(space-between);
flex-direction: row;
.brbp-single-price {
font-weight: 800;
font-size: 16.67rpx;
color: #333333;
margin-right: 20.28rpx;
}
.brbp-underline-price {
font-weight: 500;
font-size: 12.5rpx;
color: #9A9A9D;
text-decoration: line-through;
}
}
}
.brb-middle {
@include fls(space-between);
flex-direction: row;
// width: 33%;
width: 200rpx;
// width: 107rpx;
height: 50rpx;
// padding: 0 46.5rpx;
.img{
width: 27.78rpx;
height: 27.78rpx;
}
.txt {
font-weight: 800;
font-size: 20.83rpx;
color: #333333;
}
}
.brb-right {
@include fls(space-between);
// background-color: lightcyan;
flex-direction: column;
align-items: flex-end;
// width: 33%;
width: 200rpx;
height: 60rpx;
.brbr-get-score {
@include fls(center);
flex-direction: row;
width: 90.28rpx;
height: 25rpx;
// opacity: 0.5;
// background-image: linear-gradient(135deg, #FF873D 0%, #FFBC70 100%);
background-color: #FFBC70;
border-radius: 3.47rpx;
font-size: 12.5rpx;
color: #333333;
.txt{
font-size: 12.5rpx;
color: #333333;
}
.brbr-score {
color: #ff873d;
font-size: 13.89rpx;
}
// >text {
// font-weight: 500;
// color: #333333;
// font-size: 11rpx;
// }
}
.brbr-total-price {
font-weight: 500;
font-size: 12.5rpx;
color: #1A1A1A;
@include fls(center);
flex-direction: row;
.brbrp-price1 {
font-weight: 800;
font-size: 16.67rpx;
color: #ff873d;
}
.brbrp-price2 {
font-weight: 800;
font-size: 22.22rpx;
color: #ff873d;
}
}
}
}
}
}</style>

48
uniapp_project_code/src/components/index/list_item.nvue → uniapp_project_code/src/components/index/list_item_nvue.nvue

@ -2,33 +2,34 @@
<!-- nvue用flex布局 -->
<view class="buy-item">
<view class="buy-item-left">
<image class="img" src="https://img.yzcdn.cn/vant/cat.jpeg" mode="aspectFill"></image>
<image class="img" :src="mitem.goods_img||'-'" mode="aspectFill"></image>
</view>
<view class="buy-item-right">
<view class="br-top">
<text class="brt-title">维他命柠檬茶锡兰风味250ml</text>
<image class="img" src="/static/index/delete_icon.png" mode="scaleToFill" />
<text class="brt-title">{{mitem.erp_goods?.erp_goods_name||"-"}}</text>
<image class="img" src="/static/index/delete_icon.png" mode="scaleToFill" @click="del"/>
</view>
<view class="br-bottom">
<view class="brb-left">
<text class="brb-specs">330ml</text>
<!-- 规格 -->
<text class="brb-specs">{{mitem.erp_goods?.erp_goods_specs||"-"}}</text>
<view class="brb-price">
<text class="brbp-single-price">¥4.90</text>
<text class="brbp-underline-price">¥9.90</text>
<text class="brbp-single-price">¥{{mitem.erp_goods?.erp_goods_price||"-"}}</text>
<text class="brbp-underline-price">¥{{mitem.erp_goods?.erp_goods_price||"-"}}</text>
</view>
</view>
<view class="brb-middle">
<image class="img" src="/static/index/del_icon.png" mode="scaleToFill" />
<text class="txt">1</text>
<image class="img" src="/static/index/add_icon.png" mode="scaleToFill" />
<image class="img" src="/static/index/del_icon.png" mode="scaleToFill" @click="minus" />
<text class="txt">{{mitem.shopCount||1}}</text>
<image class="img" src="/static/index/add_icon.png" mode="scaleToFill" @click="add"/>
</view>
<view class="brb-right">
<view class="brbr-get-score">
<text class="txt">下单得积分</text>
<text class="brbr-score">50</text></view>
<text class="brbr-score">{{mitem.score||0}}</text></view>
<view class="brbr-total-price">
<text class="brbrp-price1">¥</text>
<text class="brbrp-price2">4.90</text>
<text class="brbrp-price2">{{mitem.shopCountPrice||"-"}}</text>
</view>
</view>
</view>
@ -37,7 +38,30 @@
</template>
<script setup>
import util from "@/utils/util.js"
import {
onMounted,
ref,
} from 'vue'
//define emits or props
const emits = defineEmits(['delItem','addItem','minusItem'])
const props = defineProps(['mkey','mitem'])
onMounted(async (res) => {
// console.log( ` the keyboard_box component is now mounted. ` )
})
//add or minus
const add = () => {
emits("addItem", props.mkey)
}
const minus = () => {
emits("minusItem", props.mkey)
}
//delete
const del = () => {
emits("delItem", props.mkey)
}
</script>
<style lang="scss" scoped>

25
uniapp_project_code/src/components/index/view_footer.nvue

@ -25,12 +25,12 @@
<view class="f-total-price">
<text class="txt1">应付:</text>
<text class="txt2">¥</text>
<text class="txt3">4.90 </text>
<text class="txt3">{{tolPrice}}</text>
</view>
<text class="txt_middle">|</text>
<view class="f-total-count">
<text class="txt">商品:</text>
<text class="txt">15</text>
<text class="txt">{{tolCount}}</text>
</view>
</view>
<view class="fi-choose">
@ -45,7 +45,7 @@
</view>
</view>
<view class="btn-style" @click="clickToPay">
<view class="btn-style" @click="handle_clickToPay">
<text class="txt">去付款</text>
</view>
<!-- <button-square class="btn-style">
@ -61,16 +61,26 @@ import {
import util from "@/utils/util.js"
//触发自定义事件
const emits = defineEmits(['clickQR','clickVIP'])
const emits = defineEmits(['clickQR','clickVIP','clickToPay'])
const props = defineProps({
maskHeight: {
type: Number,
default: 200
},
// tolPrice: {
// maxInput: {
// type: Number,
// default: 10
// }
tolCount: {
type: Number,
default: 0
},
tolPrice: {
type: Number,
default: 0
}
})
let inputValue = ref("")
@ -82,8 +92,8 @@ import util from "@/utils/util.js"
let handle_clickVIP = ()=>{
emits("clickVIP","")
}
let clickToPay = ()=>{
util.routeTo(`/pages/pay/index`, 'nT');
let handle_clickToPay = ()=>{
emits("clickToPay","")
}
onMounted(async (res) => {
@ -95,7 +105,7 @@ import util from "@/utils/util.js"
<style lang="scss" scoped>
.footer-box {
z-index: 5;
padding: 11.11rpx 27.78rpx;
// padding: 11.11rpx 27.78rpx;
background-color: aquamarine;
width: 750rpx;
@include fls(flex-start);
@ -313,6 +323,7 @@ import util from "@/utils/util.js"
.btn-style{
@include fls(center);
margin-bottom: 10rpx;
width: 694.44rpx;
height: 83.33rpx;
// background-image: linear-gradient(180deg, #FFBC70 0%, #FF873D 100%);

4
uniapp_project_code/src/components/index/view_header.nvue

@ -35,7 +35,7 @@ const getBorderStyle = computed(() => {
})
const handle_closeUse = () => {
util.routeTo(`/pages/index/index`, 'rL');
util.routeTo(`/pages/index/standby`, 'rL');
// emits("closeUse", "false")
}
</script>
@ -43,7 +43,7 @@ const handle_closeUse = () => {
<style lang="scss" scoped>
.header-box {
z-index: 5;
padding: 11.11rpx 0;
// padding: 11.11rpx 0;
height: 79.17rpx;
width: 750rpx;
@include ctf(space-between);

2
uniapp_project_code/src/components/pay/paying.vue

@ -45,7 +45,7 @@
const handle_clickCard = () => {
console.log("handle_clickCard")
emits("clickVipCard", "false")
emits("clickVipCard", "")
}
</script>

2
uniapp_project_code/src/components/pay/success.vue

@ -44,7 +44,7 @@ const emits = defineEmits(['clickToIndex'])
const props = defineProps({
paySuccessInfo: {
type: Object,
default: "{}"
default: {}
},
})

15
uniapp_project_code/src/manifest.json

@ -68,5 +68,18 @@
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
"vueVersion" : "3",
"h5" : {
"devServer" : {
"proxy" : {
"/api" : {
"target" : "http://localhost:5173",
"changeOrigin" : true,
"pathRewrite" : {
"^/api" : ""
}
}
}
}
}
}

11
uniapp_project_code/src/pages.json

@ -1,7 +1,7 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/pay/index",
"path": "pages/index/standby",
"style": {
"navigationStyle": "custom"
}
@ -18,13 +18,20 @@
"navigationStyle": "custom"
}
},
{
"path": "pages/pay/index",
"style": {
"navigationStyle": "custom"
}
},
{
"path": "pages/login/success",
"style": {
"navigationStyle": "custom"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",

398
uniapp_project_code/src/pages/index/-index.nvue

@ -0,0 +1,398 @@
<template>
<view class="main-page">
<!-- <page-standby v-if="showPageStandby" @click="showPageStandby=!showPageStandby"></page-standby> -->
<view>
<view-header class="mheader" @closeStandby="handle_closeStandby"></view-header>
<view class="holdplace" :style="{ height: 100 + 'px' }"></view>
<block v-for="(e,i) in shopList" :key="i">
<list-item :mkey="i" :mitem="e" @addItem="handle_add" @minusItem="handle_minus" @delItem="handle_del"></list-item>
</block>
<view class="holdplace" :style="{ height: footerHeight + 'px' }"></view>
<view ref="mfooter" class="mfooter" v-if="true">
<view-footer :tolPrice="shopListTotalPrice" :tolCount="shopListTotalCount" @clickQR="handle_clickQR" @clickVIP="handle_clickVIP"></view-footer>
</view>
<!-- 条形码输入框 -->
<input-qr-box v-if="showQRInputBox" :maskHeight="screenHeight" :maxInput="11"
@showIt="handle_closeQRInputBox" @clickCommit="handle_clickCommit_qr"></input-qr-box>
<!-- 手机尾号后4位数验证 -->
<input-box-end-phone v-if="showEndPhoneBox" :maskHeight="screenHeight" :maxInput="4"
@showIt="handle_closeEndPhoneBox" @clickCommit="handle_clickCommit_qr"></input-box-end-phone>
</view>
<keyboard-listener style="height: 1px;" @keyup="onKeyup" @keydown="onKeydown" ></keyboard-listener>
</view>
</template>
<script>
import util from "@/utils/util.js"
import dictKeyboard from '@/utils/dictOfKeyboard'
import { API } from "@/utils/api";
import { ox } from "@/utils/server";
import pageStandby from '@/components/index/page_standby.vue';//待机页
import viewHeader from '@/components/index/view_header.nvue';//头部
import viewFooter from '@/components/index/view_footer.nvue';//底部
import listItem from '@/components/index/list_item.nvue';//列表项
import inputQrBox from '@/components/index/keyboard/input_box_QR.vue'; //条形码
import inputBoxEndPhone from '@/components/index/keyboard/input_box_end_phone.vue';//手机号尾号
import keyboardListener from '@/components/index/keyboard/keyboard_listener.vue';//键盘监听
import { uni } from "@dcloudio/uni-h5";
// import { ref } from 'vue';
// import { onLoad,onReady } from '@dcloudio/uni-app';
// #ifdef APP-NVUE
let dom = weex.requireModule("dom");
// #endif
const app = getApp();
export default {
components: {
'page-standby': pageStandby,
'view-header': viewHeader,
'view-footer': viewFooter,
'list-item': listItem,
'input-qr-box': inputQrBox,
'input-box-end-phone': inputBoxEndPhone,
'keyboard-listener': keyboardListener,
},
watch:{
//已拆分standby到单独页面, 不再需要计算在本nvue页面高度
// showPageStandby(ov,nv){
// if(nv){
// // #ifdef APP-NVUE
// setTimeout(async()=>{
// dom = weex.requireModule("dom");
// let size = await util.getNvueRefSize(this,dom,"mfooter");
// this.footerHeight = size.height.toFixed(2)
// },200)
// // #endif
// }
// }
},
computed: {
shopListTotalPrice(){
let _total = 0
this.shopList.forEach(item=>{
_total += item.shopCountPrice
})
return _total
},
shopListTotalCount(){
let _total = 0
this.shopList.forEach(item=>{
_total += item.shopCount
})
return _total
},
//已拆分standby到单独页面, 不再需要计算在本nvue页面高度
// footerHeight(){
// return this.screenHeight - 100
// }
},
data() {
return {
// showPageStandby: false,
showQRInputBox:false,
showEndPhoneBox:false,
screenHeight: '',
footerHeight: '',
globalData: app.globalData,
shopList: [],
decryptList: [],
strResult: "",
}
},
async onLoad(res) {
console.log("onload:",res)
await this.updateGoodsList()
// let skulist = this.searchGoodBySku("1000000001")
let skulist = await this.searchGoodBySku("10000012")
//将skulist合并到shopList
this.shopList = this.shopList.concat(skulist)
console.log("skulist:",this.shopList)
// this.test()
// this.showPageStandby = true
},
async onReady() {
this.screenHeight = await util.getPageHeight()
console.log(`the index page onReady----` + this.screenHeight)
this.setFooterHeight()
},
methods: {
clickToUse() {
util.routeTo(`/pages/login/success`, 'nT');
},
handle_closeStandby(val) {
console.log("handle_closeSetting", val)
this.showPageStandby = !this.showPageStandby
},
handle_closeQRInputBox(val) {
console.log("handle_closeKeyboardBox", val)
this.showQRInputBox = !this.showQRInputBox
},
handle_closeEndPhoneBox(val) {
console.log("handle_closeEndPhoneBox", val)
this.showEndPhoneBox = !this.showEndPhoneBox
},
handle_clickQR() {
util.showNone("输入条形码")
this.showQRInputBox = !this.showQRInputBox
},
handle_clickCommit_qr(res){
console.log("handle_clickCommit_qr",res)
console.log(JSON.stringify(res.goods))
// util.showNone("条码"+res.inputCode+"-"+res.goods.length)
util.showNone("添加商品成功,数量:"+res.goods.length+"个");
this.shopList = this.shopList.concat(res.goods)
this.showQRInputBox = !this.showQRInputBox
},
handle_clickVIP() {
util.showNone("会员登录")
this.showEndPhoneBox = !this.showEndPhoneBox
},
async setFooterHeight(){
// #ifdef APP-NVUE
let size = await util.getNvueRefSize(this,dom,"mfooter");
this.footerHeight = size.height.toFixed(2)
// #endif
},
// 按键松开事件
async onKeyup(event) {
console.log("按键松开事件: ",event)
let res = dictKeyboard.dict[event.keyCode];
console.log("未转换:",res);
console.log("this.decryptList0: "+ this.decryptList)
this.decryptList.push(res);
console.log("this.decryptList0: ",this.decryptList)
if(event.keyCode != 13) {
return console.log("this.decryptList1: ",this.decryptList)
};
this.decryptList.pop();
this.strResult = await dictKeyboard.resultScan(this.decryptList);
console.log("扫码结果strResult--22:", this.strResult)
this.orderQrcode = this.strResult
console.log("扫码结果--11:", this.decryptList)
console.log("扫码结果--33:", this.strResult)
this.decryptList.splice(0);
console.log("this.decryptList2: "+this.decryptList)
//过滤结果中的down_arrow
if(this.strResult.indexOf("down_arrow") != -1){
this.strResult = this.strResult.replace("down_arrow","")
}
console.log("扫码结果--44:", this.strResult)
let skulist = await this.searchGoodBySku(this.strResult)
//将skulist合并到shopList
this.shopList = this.shopList.concat(skulist)
console.log("skulist:",this.shopList)
// let info = await this.getOrderInfo(this.strResult)
// console.log("核销码状态---111", info)
// this.clearTimer()
// this.isShowPage = 1
// this.setTimerCountdown();
// if(info.status == true){
// this.bindOrderInfo = info.order
// this.bindOrderInfo.order_type = info.order_type || ''
// return this.issueBtn(); //发放手环
// }else{
// return this.tipsTxt = "核销码不可用\n请重试或联系管理员";
// }
},
// 监听按键按下事件
onKeydown(event) {
console.log("监听按键按下事件: ",event)
},
handle_add(i){
console.log("handle_add",i)
this.shopList[i].shopCount++
this.shopList[i].shopCountPrice = (this.shopList[i].erp_goods?.erp_goods_price||0) * this.shopList[i].shopCount
},
handle_minus(i){
console.log("handle_minus",i)
if(this.shopList[i].shopCount>1){
this.shopList[i].shopCount--
this.shopList[i].shopCountPrice = (this.shopList[i].erp_goods?.erp_goods_price||0) * this.shopList[i].shopCount
}else{
util.showNone("商品数量不能小于1")
}
},
handle_del(i){
let that = this
console.log("handle_del",i)
that.shopList.splice(i,1)
util.showNone("删除成功")
// 真机异常, 会导致白屏, 原因未知
// uni.showModal({
// title: '提示',
// content: '确定删除该商品吗?',
// success: function (res) {
// if (res.confirm) {
// that.shopList.splice(i,1)
// uni.showToast({
// title: '删除成功',
// icon: 'success'
// });
// } else if (res.cancel) {
// uni.showToast({
// title: '取消删除',
// icon: 'none'
// });
// }
// }
// });
},
test(){
console.log("test")
let url = "https://testmanager.ouxuanzhineng.cn/admin/erpRetailGoods/list?brand_id=63&stadium_id=167&type_key=&key=&page=1&page_size=9999&is_sale=1&is_show_on_assistant=1&token=e6cabeae-0c1a-11ee-aa40-5254005df464";
//将url请求的参数转化为json对象并打印
let urlParams = util.getUrlParams(url);
console.log("urlParams:",urlParams)
return ox.get({
url: API.getGoodsList,
data: urlParams,
isDefaultGet: false
}).then(res=>{
console.log("test suc: ",res)
return res
})
},
// 业务逻辑
getGoodFromPad(sku,brand_id){
return ox.get({
url: API.getGoodFromPad,
data: {
sku,brand_id
},
isDefaultGet: true
})
.then(res=>{
util.hideLoad();
// console.log("离场校验 suc: ",res)
if(res.data.code == 0){}
return res
})
},
// 更新商品列表
async updateGoodsList(){
let _list = await this.getGoodsList()
//打印信息
console.log("app.globaldata: ",app.globalData)
app.globalData.goodsList = _list
},
// 更新购物车列表
updateShopList(){
app.globalData.shopList = this.shopList
},
getGoodsList(){
let url = "https://testmanager.ouxuanzhineng.cn/admin/erpRetailGoods/list?brand_id=63&stadium_id=167&type_key=&key=&page=1&page_size=9999&is_sale=1&is_show_on_assistant=1&token=e6cabeae-0c1a-11ee-aa40-5254005df464";
let urlParams = util.getUrlParams(url);
console.log("需要适配urlParams:",urlParams)
return ox.get({
url: API.getGoodsList,
data: urlParams,
isDefaultGet: true,
failMsg:"获取商品列表失败"
})
.then(res=>{
util.hideLoad();
console.log("getGoodsList suc: ",res)
//为res.list中每一项设置shopCountPrice,shopCount
res.list.forEach(item=>{
item.shopCount = 1
item.shopCountPrice = item.erp_goods.erp_goods_price
})
return res
})
},
searchGoodBySku(sku){
return new Promise((resolve,reject)=>{
let _list = app.globalData.goodsList.list
// let _good = _list.find(item=>item.erp_goods.erp_goods_sku == sku)
//sku可能不唯一, 返回数组
let _goods = _list.filter(item=>item.erp_goods.erp_goods_sku == sku)
if(_goods.length){
resolve(_goods)
}else{
reject("未找到商品")
}
})
},
}
}
</script>
<style lang="scss" scoped>
// page{
// background: #F5F7F8;
// }
.main-page {
// background-color: red;
width: 750rpx;
// height: auto;
// padding-top: 100rpx;
// padding-bottom: 120rpx;
.holdplace {
height: 100rpx;
}
// height: 1000rpx;
// width: 100%;
// height: 100%;
// background-color: #fff;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
.mheader {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 100rpx;
// background: #fff;
z-index: 5;
}
.mfooter {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
z-index: 5;
}
}
</style>

169
uniapp_project_code/src/pages/index/index.nvue

@ -1,169 +0,0 @@
<template>
<view class="main-page">
<page-standby v-if="showPageStandby" @click="showPageStandby=!showPageStandby"></page-standby>
<view v-else>
<view-header class="mheader" @closeStandby="handle_closeStandby"></view-header>
<view class="holdplace" :style="{ height: 100 + 'px' }"></view>
<block v-for="i in 8">
<list-item :ikey="i">i</list-item>
</block>
<view class="holdplace" :style="{ height: footerHeight + 'px' }"></view>
<view ref="mfooter" class="mfooter" v-if="true">
<view-footer @clickQR="handle_clickQR" @clickVIP="handle_clickVIP"></view-footer>
</view>
<!-- 条形码输入框 -->
<input-qr-box v-if="showQRInputBox" :maskHeight="screenHeight" :maxInput="11"
@showIt="handle_closeQRInputBox" @clickCommit="handle_clickCommit_qr"></input-qr-box>
<!-- 手机尾号后4位数验证 -->
<input-box-end-phone v-if="showEndPhoneBox" :maskHeight="screenHeight" :maxInput="4"
@showIt="handle_closeEndPhoneBox" @clickCommit="handle_clickCommit_qr"></input-box-end-phone>
</view>
</view>
</template>
<script>
import util from "@/utils/util.js"
import pageStandby from '@/components/index/page_standby.vue';//待机页
import viewHeader from '@/components/index/view_header.nvue';//头部
import viewFooter from '@/components/index/view_footer.nvue';//底部
import listItem from '@/components/index/list_item.nvue';//列表项
import inputQrBox from '@/components/index/keyboard/input_box_QR.vue'; //条形码
import inputBoxEndPhone from '@/components/index/keyboard/input_box_end_phone.vue';//手机号尾号
// import { ref } from 'vue';
// import { onLoad,onReady } from '@dcloudio/uni-app';
// #ifdef APP-NVUE
let dom = weex.requireModule("dom");
// #endif
export default {
components: {
'page-standby': pageStandby,
'view-header': viewHeader,
'view-footer': viewFooter,
'list-item': listItem,
'input-qr-box': inputQrBox,
'input-box-end-phone': inputBoxEndPhone,
},
watch:{
showPageStandby(ov,nv){
if(nv){
// #ifdef APP-NVUE
setTimeout(async()=>{
dom = weex.requireModule("dom");
let size = await util.getNvueRefSize(this,dom,"mfooter");
this.footerHeight = size.height.toFixed(2)
},200)
// #endif
}
}
},
data() {
return {
showPageStandby: false,
showQRInputBox:false,
showEndPhoneBox:false,
screenHeight: '',
footerHeight: '',
}
},
async onLoad(res) {
console.log("onload:",res)
this.showPageStandby = true
},
async onReady() {
this.screenHeight = await util.getPageHeight()
console.log(`the index page onReady----` + this.screenHeight)
this.setFooterHeight()
},
methods: {
clickToUse() {
util.routeTo(`/pages/login/success`, 'nT');
},
handle_closeStandby(val) {
console.log("handle_closeSetting", val)
this.showPageStandby = !this.showPageStandby
},
handle_closeQRInputBox(val) {
console.log("handle_closeKeyboardBox", val)
this.showQRInputBox = !this.showQRInputBox
},
handle_closeEndPhoneBox(val) {
console.log("handle_closeEndPhoneBox", val)
this.showEndPhoneBox = !this.showEndPhoneBox
},
handle_clickQR() {
util.showNone("输入条形码")
this.showQRInputBox = !this.showQRInputBox
},
handle_clickCommit_qr(val){
console.log("handle_clickCommit_qr",val)
util.showNone("输入条形码"+val)
this.showQRInputBox = !this.showQRInputBox
},
handle_clickVIP() {
util.showNone("会员登录")
this.showEndPhoneBox = !this.showEndPhoneBox
},
async setFooterHeight(){
// #ifdef APP-NVUE
let size = await util.getNvueRefSize(this,dom,"mfooter");
this.footerHeight = size.height.toFixed(2)
// #endif
},
}
}
</script>
<style lang="scss" scoped>
// page{
// background: #F5F7F8;
// }
.main-page {
// background-color: red;
width: 750rpx;
// height: auto;
// padding-top: 100rpx;
// padding-bottom: 120rpx;
.holdplace {
height: 100rpx;
}
// height: 1000rpx;
// width: 100%;
// height: 100%;
// background-color: #fff;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
.mheader {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 100rpx;
// background: #fff;
z-index: 5;
}
.mfooter {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
z-index: 5;
}
}
</style>

461
uniapp_project_code/src/pages/index/index.vue

@ -0,0 +1,461 @@
<template>
<view class="main-page">
<!-- <page-standby v-if="showPageStandby" @click="showPageStandby=!showPageStandby"></page-standby> -->
<view>
<view-header class="mheader" @closeStandby="handle_closeStandby"></view-header>
<view class="holdplace" :style="{ height: 100 + 'rpx' }"></view>
<block v-for="(e,i) in shopList" :key="i">
<list-item :mkey="i" :mitem="e" @addItem="handle_add" @minusItem="handle_minus"
@delItem="handle_del"></list-item>
</block>
<view class="holdplace" :style="{ height:'340rpx' }"></view>
<!-- <view class="holdplace" :style="{ height: footerHeight + 'px' }"></view> -->
<view ref="mfooter" class="mfooter" v-if="true">
<view-footer :tolPrice="shopListTotalPrice" :tolCount="shopListTotalCount" @clickQR="handle_clickQR"
@clickVIP="handle_clickVIP" @clickToPay = "clickToPay"></view-footer>
</view>
<!-- 条形码输入框 -->
<input-qr-box v-if="showQRInputBox" :maskHeight="screenHeight" :maxInput="11"
@showIt="handle_closeQRInputBox" @clickCommit="handle_clickCommit_qr"></input-qr-box>
<!-- 手机尾号后4位数验证 -->
<input-box-end-phone v-if="showEndPhoneBox" :maskHeight="screenHeight" :maxInput="4"
@showIt="handle_closeEndPhoneBox" @clickCommit="handle_clickCommit_qr"></input-box-end-phone>
</view>
<keyboard-listener style="height: 1px;" @keyup="onKeyup" @keydown="onKeydown"></keyboard-listener>
</view>
</template>
<script>
import util from "@/utils/util.js"
import dictKeyboard from '@/utils/dictOfKeyboard'
import {
API
} from "@/utils/api";
import {
ox
} from "@/utils/server";
import pageStandby from '@/components/index/page_standby.vue'; //
import viewHeader from '@/components/index/view_header.nvue'; //
import viewFooter from '@/components/index/view_footer.nvue'; //
import listItem from '@/components/index/list_item.vue'; //
import inputQrBox from '@/components/index/keyboard/input_box_QR.vue'; //
import inputBoxEndPhone from '@/components/index/keyboard/input_box_end_phone.vue'; //
import keyboardListener from '@/components/index/keyboard/keyboard_listener.vue'; //
// import { uni } from "@dcloudio/uni-h5";
// import { ref } from 'vue';
// import { onLoad,onReady } from '@dcloudio/uni-app';
// #ifdef APP-NVUE
let dom = weex.requireModule("dom");
// #endif
let app = "";
export default {
components: {
'page-standby': pageStandby,
'view-header': viewHeader,
'view-footer': viewFooter,
'list-item': listItem,
'input-qr-box': inputQrBox,
'input-box-end-phone': inputBoxEndPhone,
'keyboard-listener': keyboardListener,
},
watch: {
//standby, nvue
// showPageStandby(ov,nv){
// if(nv){
// // #ifdef APP-NVUE
// setTimeout(async()=>{
// dom = weex.requireModule("dom");
// let size = await util.getNvueRefSize(this,dom,"mfooter");
// this.footerHeight = size.height.toFixed(2)
// },200)
// // #endif
// }
// }
},
computed: {
shopListTotalPrice() {
let _total = 0
this.shopList.forEach(item => {
_total += item.shopCountPrice
})
return _total
},
shopListTotalCount() {
let _total = 0
this.shopList.forEach(item => {
_total += item.shopCount
})
return _total
},
//standby, nvue
// footerHeight(){
// return this.screenHeight - 100
// }
},
data() {
return {
// showPageStandby: false,
showQRInputBox: false,
showEndPhoneBox: false,
screenHeight: '',
footerHeight: '',
// globalData: app.globalData,
globalData: "",
shopList: [],
decryptList: [],
strResult: "",
}
},
async onLoad(res) {
console.log("onload:", res)
// this.test()
// this.showPageStandby = true
},
async onReady() {
this.screenHeight = await util.getPageHeight()
// this.globalData = app.globalData
console.log(`the index page onReady----` + this.screenHeight)
app = getApp();
setTimeout(async () => {
await this.updateGoodsList().then(async () => {
console.log("skulist:", this.shopList)
})
console.log("test set SKU 10000012")
let skulist = await this.searchGoodBySku("10000012")
//skulistshopList
this.shopList = this.shopList.concat(skulist)
this.setFooterHeight()
}, 1000)
},
methods: {
clickToPay() {
// shopList {
// "id": 57,
// "name": "",
// "price": 1,
// "nums": 1,
// "unit": ""
// }
let shopListData = this.shopList.map(item => {
return {
id: item.erp_goods.id,
name: item.erp_goods.erp_goods_name,
price: item.erp_goods.erp_goods_price,
nums: item.shopCount,
unit: item.erp_goods.erp_goods_unit
}
})
// shopCount
let _query = {
shopList: shopListData,
shopListTotalPrice: this.shopListTotalPrice,
shopListTotalCount: this.shopListTotalCount
}
util.routeTo(`/pages/pay/index?query=${JSON.stringify(_query)}`, 'nT');
},
clickToUse() {
util.routeTo(`/pages/login/success`, 'nT');
},
handle_closeStandby(val) {
console.log("handle_closeSetting", val)
this.showPageStandby = !this.showPageStandby
},
handle_closeQRInputBox(val) {
console.log("handle_closeKeyboardBox", val)
this.showQRInputBox = !this.showQRInputBox
},
handle_closeEndPhoneBox(val) {
console.log("handle_closeEndPhoneBox", val)
this.showEndPhoneBox = !this.showEndPhoneBox
},
handle_clickQR() {
util.showNone("输入条形码")
this.showQRInputBox = !this.showQRInputBox
},
handle_clickCommit_qr(res) {
console.log("handle_clickCommit_qr", res)
console.log(JSON.stringify(res.goods))
// util.showNone(""+res.inputCode+"-"+res.goods.length)
util.showNone("添加商品成功,数量:" + res.goods.length + "个");
this.shopList = this.shopList.concat(res.goods)
this.showQRInputBox = !this.showQRInputBox
},
handle_clickVIP() {
util.showNone("会员登录")
this.showEndPhoneBox = !this.showEndPhoneBox
},
async setFooterHeight() {
// #ifdef APP-NVUE
console.log("APP-NVUE setFooterHeight")
let size1 = await util.getNvueRefSize(this, dom, "mfooter");
this.footerHeight = size1.height.toFixed(2)
// #endif
// #ifdef H5
console.log("H5 setFooterHeight")
let size2 = await util.getH5RefSize(this, "mfooter");
console.log("H5 setFooterHeight size2:", size2)
this.footerHeight = size2.height.toFixed(2)
// #endif
},
//
async onKeyup(event) {
console.log("按键松开事件: ", event)
let res = dictKeyboard.dict[event.keyCode];
console.log("未转换:", res);
console.log("this.decryptList0: " + this.decryptList)
this.decryptList.push(res);
console.log("this.decryptList0: ", this.decryptList)
if (event.keyCode != 13) {
return console.log("this.decryptList1: ", this.decryptList)
};
this.decryptList.pop();
this.strResult = await dictKeyboard.resultScan(this.decryptList);
console.log("扫码结果strResult--22:", this.strResult)
this.orderQrcode = this.strResult
console.log("扫码结果--11:", this.decryptList)
console.log("扫码结果--33:", this.strResult)
this.decryptList.splice(0);
console.log("this.decryptList2: " + this.decryptList)
//down_arrow
if (this.strResult.indexOf("down_arrow") != -1) {
this.strResult = this.strResult.replace("down_arrow", "")
}
console.log("扫码结果--44:", this.strResult)
let skulist = await this.searchGoodBySku(this.strResult)
//skulistshopList
this.shopList = this.shopList.concat(skulist)
console.log("skulist:", this.shopList)
// let info = await this.getOrderInfo(this.strResult)
// console.log("---111", info)
// this.clearTimer()
// this.isShowPage = 1
// this.setTimerCountdown();
// if(info.status == true){
// this.bindOrderInfo = info.order
// this.bindOrderInfo.order_type = info.order_type || ''
// return this.issueBtn(); //
// }else{
// return this.tipsTxt = "\n";
// }
},
//
onKeydown(event) {
console.log("监听按键按下事件: ", event)
},
handle_add(i) {
console.log("handle_add", i)
this.shopList[i].shopCount++
this.shopList[i].shopCountPrice = (this.shopList[i].erp_goods?.erp_goods_price || 0) * this.shopList[i]
.shopCount
},
handle_minus(i) {
console.log("handle_minus", i)
if (this.shopList[i].shopCount > 1) {
this.shopList[i].shopCount--
this.shopList[i].shopCountPrice = (this.shopList[i].erp_goods?.erp_goods_price || 0) * this.shopList[i]
.shopCount
} else {
util.showNone("商品数量不能小于1")
}
},
handle_del(i) {
let that = this
console.log("handle_del", i)
that.shopList.splice(i, 1)
util.showNone("删除成功")
// , ,
// uni.showModal({
// title: '',
// content: '',
// success: function (res) {
// if (res.confirm) {
// that.shopList.splice(i,1)
// uni.showToast({
// title: '',
// icon: 'success'
// });
// } else if (res.cancel) {
// uni.showToast({
// title: '',
// icon: 'none'
// });
// }
// }
// });
},
test() {
console.log("test")
let url =
"https://testmanager.ouxuanzhineng.cn/admin/erpRetailGoods/list?brand_id=63&stadium_id=167&type_key=&key=&page=1&page_size=9999&is_sale=1&is_show_on_assistant=1&token=e6cabeae-0c1a-11ee-aa40-5254005df464";
//urljson
let urlParams = util.getUrlParams(url);
console.log("urlParams:", urlParams)
return ox.get({
url: API.getGoodsList,
data: urlParams,
isDefaultGet: false
}).then(res => {
console.log("test suc: ", res)
return res
})
},
//
getGoodFromPad(sku, brand_id) {
return ox.get({
url: API.getGoodFromPad,
data: {
sku,
brand_id
},
isDefaultGet: true
})
.then(res => {
util.hideLoad();
// console.log(" suc: ",res)
if (res.data.code == 0) {}
return res
})
},
//
async updateGoodsList() {
let _list = await this.getGoodsList()
//
console.log("app.globaldata: ", app.globalData)
app.globalData.goodsList = _list
},
//
updateShopList() {
app.globalData.shopList = this.shopList
},
getGoodsList() {
let url =
"https://testmanager.ouxuanzhineng.cn/admin/erpRetailGoods/list?brand_id=63&stadium_id=167&type_key=&key=&page=1&page_size=9999&is_sale=1&is_show_on_assistant=1&token=e6cabeae-0c1a-11ee-aa40-5254005df464";
let urlParams = util.getUrlParams(url);
console.log("需要适配urlParams:", urlParams)
return ox.get({
url: API.getGoodsList,
data: urlParams,
isDefaultGet: true,
failMsg: "获取商品列表失败"
})
.then(res => {
util.hideLoad();
console.log("getGoodsList suc: ", res)
//res.listshopCountPrice,shopCount
res.list.forEach(item => {
item.shopCount = 1
item.shopCountPrice = item.erp_goods.erp_goods_price
})
return res
})
},
searchGoodBySku(sku) {
console.log("apppp", app)
return new Promise((resolve, reject) => {
let _list = app.globalData.goodsList.list
// let _good = _list.find(item=>item.erp_goods.erp_goods_sku == sku)
//sku,
let _goods = _list.filter(item => item.erp_goods.erp_goods_sku == sku)
if (_goods.length) {
resolve(_goods)
} else {
reject("未找到商品")
}
})
},
}
}
</script>
<style lang="scss" scoped>
// page{
// background: #F5F7F8;
// }
.main-page {
// background-color: red;
width: 750rpx;
@include fls(flex-start);
flex-direction: column;
// height: auto;
// padding-top: 100rpx;
// padding-bottom: 120rpx;
.holdplace {
height: 110rpx;
}
// height: 1000rpx;
// width: 100%;
// height: 100%;
// background-color: #fff;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
.mheader {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 100rpx;
// background: #fff;
z-index: 5;
}
.mfooter {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
z-index: 5;
}
}
</style>

29
uniapp_project_code/src/pages/index/standby.nvue

@ -0,0 +1,29 @@
<template>
<view>
<page-standby @click="toIndex"></page-standby>
</view>
</template>
<script setup>
import { ref, onMounted ,getCurrentInstance } from 'vue';
import { onLoad,onReady } from '@dcloudio/uni-app';
import pageStandby from '@/components/index/page_standby.vue';//待机页
import util from "@/utils/util.js"
// const screenHeight = ref(1200);
onMounted(async () => {
// screenHeight.value = await util.getPageHeight()
// console.log(`page-standby onMounted` + screenHeight.value)
});
const toIndex = ()=>{
util.routeTo(`/pages/index/index`, 'nT');
}
</script>
<style lang="scss" scoped>
</style>

232
uniapp_project_code/src/pages/pay/index.vue

@ -1,26 +1,38 @@
<template>
<view class="pay-page">
<view v-if="!paySuccess">
<view-header class="mheader" :backgroundCustom="('none')" :needBorder="('false')"
@closeUse="handle_closeUse"></view-header>
<keyboard-listener @keyup="onKeyup" @keydown="onKeydown" ></keyboard-listener>
<view v-if="paySuccessStatus==0">
<view-header class="mheader" :backgroundCustom="('none')" :needBorder="(false)"
@closeUse=""></view-header>
<paying v-if="true" @clickVipCard="handle_clickVipCard"></paying>
</view>
<pay-success v-else></pay-success>
<!-- 手机尾号后4位数验证 -->
<input-box-end-phone v-if="showEndPhoneBox" :maskHeight="screenHeight" :maxInput="4"
@showIt="handle_closeEndPhoneBox" @clickCommit="handle_clickCommit_qr"></input-box-end-phone>
@showIt="handle_closeEndPhoneBox" @clickCommit="handle_clickCommit_end_phone"></input-box-end-phone>
<!-- 条形码输入框 -->
<!-- <input-qr-box v-if="false" :maskHeight="screenHeight" :maxInput="11"
@showIt="handle_closeQRInputBox" @clickCommit="handle_clickCommit_qr"></input-qr-box> -->
</view>
</template>
<script>
import util from "@/utils/util.js"
import {
API
} from "@/utils/api";
import {
ox
} from "@/utils/server";
import dictKeyboard from '@/utils/dictOfKeyboard'
import viewHeader from '@/components/index/view_header.nvue';//
import inputQrBox from '@/components/index/keyboard/input_box_QR.vue'; //
import inputBoxEndPhone from '@/components/index/keyboard/input_box_end_phone.vue';//
import paying from '@/components/pay/paying.vue';//
import paySuccess from '@/components/pay/success.vue';//
import keyboardListener from '@/components/index/keyboard/keyboard_listener.vue';//
export default {
components: {
@ -28,41 +40,181 @@
'input-box-end-phone': inputBoxEndPhone,
'paying': paying,
'pay-success': paySuccess,
'input-qr-box': inputQrBox,
'keyboard-listener': keyboardListener,
},
watch:{
showPageStandby(ov,nv){
if(nv){
// #ifdef APP-NVUE
setTimeout(async()=>{
dom = weex.requireModule("dom");
let size = await util.getNvueRefSize(this,dom,"mfooter");
this.footerHeight = size.height.toFixed(2)
},200)
// #endif
}
}
},
data() {
return {
showPageStandby: false,
showEndPhoneBox:false,
screenHeight: '',
screenHeight: '1000',
footerHeight: '',
paySuccess:false,
paySuccessStatus:0,
decryptList: [],
strResult: "",
dataQuery:""
}
},
async onLoad(res) {
console.log("pay onload:",res)
this.setPayData(res)
},
async onReady() {
await this.setPageHeight()
},
methods: {
setPayData(res){
console.log("setPayData:",res)
res = JSON.parse(res.query)
console.log("setPayData1:",res)
let _data = {
goods_data:res.shopList,
amount:res.shopListTotalPrice,
}
console.log("setPayData2:",_data)
this.dataQuery = _data
},
// 101112131415WECHAT_MICROPAY,28ALI_BARCODEPAY
getPayType(code){
let pay_type = ""
if(code.indexOf("10") == 0 || code.indexOf("11") == 0 || code.indexOf("12") == 0 || code.indexOf("13") == 0 || code.indexOf("14") == 0 || code.indexOf("15") == 0){
pay_type = "WECHAT_MICROPAY"
}else if(code.indexOf("28") == 0){
pay_type = "ALI_BARCODEPAY"
}else{
pay_type = null
}
return pay_type
},
async acceptScanCode(code) {
console.log("acceptScanCode:",code)
// util.showNone("...")
util.showLoad("交易处理中...")
let pay_code = code
let pay_type = this.getPayType(pay_code)
if(pay_type == null){
util.showNone("支付类型未知,请重试!")
return
}
await this.makeOrder((makeInfo)=>{
console.log("makeInfo-result",makeInfo)
}).then((orderInfo)=>{
console.log("orderInfo-result",orderInfo)
return this.payOrder({
"order_no":orderInfo.order_no,
pay_code,pay_type
})
}).then((payInfo)=>{
console.log("payInfo-result:",payInfo)
return this.checkOrder(payInfo)
}).then((checkInfo)=>{
console.log("最终checkInfo:",checkInfo)
let {payRes,checkRes} = checkInfo
// util.showNone(payRes.res.respMsg+"-"+payRes.res.respCode)
if(checkRes.pay_order.status == "1"){
util.showNone(checkRes.res.respMsg+"-"+checkRes.res.respCode)
this.paySuccessStatus = 1
}else{
util.showNone(checkRes.res.respMsg+"-"+checkRes.res.respCode)
}
}).finally(()=>{
util.hideLoad()
})
},
async makeOrder(){
let {store_id,brand_id,token} = getApp().globalData.accountInfo
let {goods_data,amount} = this.dataQuery
let urlParams = {
store_id,brand_id,token,amount,
"goods_data": goods_data,
"pay_type": 7,
"other_pay_type":"付款码支付",
"card_no": "",
"mark": ""
}
console.log("需要适配makeOrder urlParams:", urlParams)
return ox.post({
url: API.makeOrder,
data: urlParams,
isDefaultGet: true,
failMsg: '操作失败!'
})
.then(res => {
util.hideLoad();
console.log("makeOrder suc: ", res)
return res
})
},
payOrder(orderInfo){
console.log("payOrder get param:",orderInfo)
let {order_no,pay_code,pay_type} = orderInfo
let {goods_data,amount} = this.dataQuery
let {store_id,brand_id,token} = getApp().globalData.accountInfo
let urlParams = {
order_no,
pay_code,
pay_type,
brand_id,
token,
"order_amt": amount, //TODO -
"goods_info": order_no,
}
console.log("需要适配payOrder urlParams:", urlParams)
return ox.post({
url: API.payOrder,
data: urlParams,
isDefaultGet: true,
failMsg: "payOrder fail"
})
.then(res => {
console.log("payOrder suc: ", res)
let _pay_res = {
"order_no": order_no,
"pay_code": pay_code,
"pay_type": pay_type,
"orderAmt":res.res.orderAmt,
"transNo":res.res.transNo,
"res":res.res
}
return _pay_res
})
},
checkOrder(res){
let {store_id,brand_id,token} = getApp().globalData.accountInfo
let {transNo,orderAmt,payCode} = res
let urlParams= {
transNo,payCode,brand_id,token,orderAmt,
"manual": "yes",//
}
console.log("需要适配checkOrder urlParams:", urlParams)
return ox.get({
url: API.checkOrder,
data: urlParams,
isDefaultGet: true,
failMsg: "checkOrder fail"
})
.then(res2 => {
console.log("checkOrder suc: ", res)
return {
payRes:res,
checkRes:res2
}
})
},
handle_clickVipCard() {
util.showNone("储值卡支付未接入")
this.paySuccess = true
// this.handle_clickVIP()
// this.paySuccess = true
this.handle_clickVIP()
// util.routeTo(`/pages/pay/success`, 'nT');
},
@ -70,14 +222,52 @@
console.log("handle_closeEndPhoneBox", val)
this.showEndPhoneBox = !this.showEndPhoneBox
},
handle_clickCommit_end_phone(val) {
console.log("handle_clickCommit_end_phone", val)
this.showEndPhoneBox = !this.showEndPhoneBox
},
handle_closeQRInputBox(val) {
console.log("handle_closeQRInputBox", val)
},
handle_clickCommit_qr(val) {
console.log("handle_clickCommit_qr", val)
this.showQRInputBox = !this.showQRInputBox
},
handle_clickVIP() {
util.showNone("会员登录")
// util.showNone("")
this.showEndPhoneBox = !this.showEndPhoneBox
},
async setPageHeight(){
this.screenHeight = await util.getPageHeight()
},
//
async onKeyup(event) {
let res = dictKeyboard.dict[event.keyCode];
this.decryptList.push(res);
if(event.keyCode != 13) {
return console.log("this.decryptList1: ",this.decryptList)
};
this.decryptList.pop();
this.strResult = await dictKeyboard.resultScan(this.decryptList);
this.orderQrcode = this.strResult
// console.log("--", this.strResult)
this.decryptList.splice(0);
console.log("this.decryptList: "+this.decryptList)
//down_arrow
if(this.strResult.indexOf("down_arrow") != -1){
this.strResult = this.strResult.replace("down_arrow","")
}
console.log("扫码最终结果--:", this.strResult)
this.acceptScanCode(this.strResult)
},
//
onKeydown(event) {
// console.log(": ",event)
},
}
}

35
uniapp_project_code/src/utils/api.js

@ -0,0 +1,35 @@
// export const ORIGIN = `http://ouxuanmaganer.ouxuanzhineng.cn`; // 正式
export const ORIGIN = `https://testmanager.ouxuanzhineng.cn`; // 测试
export const API = {
padLogin: `${ORIGIN}/assistant/WechatMiniApplogin`, //登录
padList: `${ORIGIN}/admin/stadium/list`, //pad 选择列表
// admin/erpRetailGoods/list
getGoodsList: `${ORIGIN}/admin/erpRetailGoods/list`, //获取商品列表
// /erpRetailGoods/getErpGoodsBySkuOfPad
getGoodFromPad: `${ORIGIN}/admin/erpRetailGoods/getErpGoodsBySkuOfPad`, //通过sku获取商品信息
// classifyer/all
getGoodsClassify: `${ORIGIN}/classifyer/all`, //获取商品分类
// admin/erp/retailByPayOfQrcode
makeOrder: `${ORIGIN}/admin/erp/retailByPayOfQrcode`, //生成订单
// admin/order/pay/online/payByScannedCode
payOrder: `${ORIGIN}/admin/order/pay/online/payByScannedCode`, //支付订单
// pay/huishouqian/checkOrder
checkOrder: `${ORIGIN}/pay/huishouqian/checkOrder`, //轮询订单结果
}
export default { ORIGIN, API };

219
uniapp_project_code/src/utils/dictOfKeyboard.js

@ -0,0 +1,219 @@
var dict = {
'8': 'backspace',
'9': 'tab',
'13': 'enter',
'16': 'shift',
'17': 'ctrl',
'18': 'alt',
'19': 'pause_break',
'20': 'caps_lock',
'27': 'escape',
'33': 'page_up',
'34': 'page_down',
'35': 'end',
'36': 'home',
'37': 'left_arrow',
'38': 'up_arrow',
'39': 'right_arrow',
'40': 'down_arrow',
'45': 'insert', //控制键键码值 Insert
'46': 'delete', //控制键键码值 delete
'48': '0', // 以下是0~9 字母和数字键的键码值 0
'49': '1',
'50': '2',
'51': '3',
'52': '4',
'53': '5',
'54': '6',
'55': '7',
'56': '8',
'57': '9',
'65': 'a', // 以下是a~z 字母和数字键的键码值 a
'66': 'b',
'67': 'c',
'68': 'd',
'69': 'e',
'70': 'f',
'71': 'g',
'72': 'h',
'73': 'i',
'74': 'j',
'75': 'k',
'76': 'l',
'77': 'm',
'78': 'n',
'79': 'o',
'80': 'p',
'81': 'q',
'82': 'r',
'83': 's',
'84': 't',
'85': 'u',
'86': 'v',
'87': 'w',
'88': 'x',
'89': 'y',
'90': 'z',
'91': 'left_window_key',
'92': 'right_window_key',
'93': 'select_key',
'96': 'numpad_0', //数字键盘 0
'97': 'numpad_1', //数字键盘 1
'98': 'numpad_2', //数字键盘 2
'99': 'numpad_3', //数字键盘 3
'100': 'numpad_4', //数字键盘 4
'101': 'numpad_5', //数字键盘 5
'102': 'numpad_6', //数字键盘 6
'103': 'numpad_7', //数字键盘 7
'104': 'numpad_8', //数字键盘 8
'105': 'numpad_9', //数字键盘 9
'106': 'multiply', //数字键盘*
'107': 'add', // 数字键盘+
'109': 'subtract', // 数字键盘-
'110': 'decimal_point', // 数字键盘.
'111': 'divide', // 数字键盘/
'112': 'f1',
'113': 'f2',
'114': 'f3',
'115': 'f4',
'116': 'f5',
'117': 'f6',
'118': 'f7',
'119': 'f8',
'120': 'f9',
'121': 'f10',
'122': 'f11',
'123': 'f12',
'144': 'num_lock', // Num Lock
'145': 'scroll_lock',
'186': 'semi_colon', // 以下是 shift+键 或者 键
'187': 'equal_sign',
'188': 'comma',
'189': 'dash',
'190': 'period',
'191': 'forward_slash',
'192': 'grave_accent',
'219': 'open_bracket',
'220': 'back_slash',
'221': 'close_braket',
'222': 'single_quote'
}
async function resultScan(result) {
// 控制键 双键: shift + key 单键: key
let controlKey = ['semi_colon', 'equal_sign', 'comma', 'dash', 'period', 'forward_slash', 'grave_accent', 'open_bracket', 'back_slash', 'close_braket', 'single_quote', '8', '7', '6', '5', '4', '3', '2', '1'];
let controlRet = [
{ double: ':', single: ';' },
{ double: '+', single: '=' },
{ double: '<', single: ',' },
{ double: '_', single: '-' },
{ double: '>', single: '.' },
{ double: '?', single: '/' },
{ double: '~', single: '`' },
{ double: '{', single: '[' },
{ double: '|', single: '/' },
{ double: '}', single: ']' },
{ double: '"', single: "'" },
{ double: '*', single: "8" },
{ double: '&', single: "7" },
{ double: '^', single: "6" },
{ double: '%', single: "5" },
{ double: '$', single: "4" },
{ double: '#', single: "3" },
{ double: '@', single: "2" },
{ double: '!', single: "1" }
];
// 数字键盘
let numKey = ['multiply', 'divide', 'add', 'subtract', 'decimal_point']
let numRet = ['*', '/', '+', '-', '.']
// 字母键盘
let letterKey = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
let letterRet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
result = await getControlKey(result, controlKey, controlRet)
result = await getLetterKey(result, letterKey, letterRet)
result = await getNumKey(result, numKey, numRet)
console.log('result 最后结果: ', result.join('')); //指定分隔符)
return result.join('') || '';
}
function getControlKey(result, controlKey, controlRet){
return new Promise((rs,rj)=>{
let list = []
try{
result.forEach(function(item, index, arr) {
controlKey.forEach(function(item2, index2, arr2) {
if(item === item2) {
if(arr[index+1] == "shift"){
// arr.splice(index+1, 1);
arr[index+1] = ''
arr[index] = controlRet[index2].double
}
else arr[index] = controlRet[index2].single;
}
});
});
list = result
}catch(e){
console.warn("异常:",e);
}
rs(list)
})
}
function getLetterKey(result, letterKey, letterRet){
return new Promise((rs,rj)=>{
let list = []
try{
result.forEach(function(item, index, arr) {
letterKey.forEach(function(item2, index2, arr2) {
if(item === item2) {
if(arr[index+1] == "shift"){
// arr.splice(index+1, 1);
arr[index+1] = ''
arr[index] = arr[index].toUpperCase(); //小写字母转大写字母
}
}
});
});
list = result
}catch(e){
console.warn("异常:",e);
}
rs(list)
})
}
function getNumKey(result, numKey, numRet){
return new Promise((rs,rj)=>{
let list = []
try{
result.forEach(function(item, index, arr) {
numKey.forEach(function(item2, index2, arr2) {
if(item === item2) {
arr[index] = numRet[index2];
}
});
});
list = result
}catch(e){
console.warn("异常:",e);
}
rs(list)
})
}
export default {
dict: dict,
resultScan: resultScan,
};

113
uniapp_project_code/src/utils/server.js

@ -0,0 +1,113 @@
import util from '../utils/util';
const islog = true
export class Server {
request(url,data,method,header,isDefaultGet,failMsg){
return new Promise(async (rs,rj)=>{
// const _token = uni.getStorageSync('venueData').token || '';
// if(_token)data['token'] = _token;
// if(method === 'POST'&&_token)url = url + `?token=${_token}`
uni.request({
url,
timeout: 60000,
sslVerify:false,
data,
method, // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {...header}, // 设置请求的 header // {'custom-header': 'application/json'}
success: res=>{
// if(islog)console.log('req success---->',{
// link: url,
// query: data,
// method: method,
// data: res,
// })
if(isDefaultGet){
if(failMsg == '')throw Error('默认回调,失败提示不能为空 key -> failMsg');
defaultGet({
url,
data,
res,
failMsg,
resolve: rs,
reject: rj
});
return
}
if(islog){
let weburl = getWebURL(data,url)
let temp = url.split("?")[0].split("/")
let postName = temp[temp.length-1]
console.log("-------------------->> ["+postName+"][log]\n"+"请求 Data: \n" + JSON.stringify(data)+ "\n URL:\n"+weburl+"\n <<-------------------- ["+postName+"][log] ↑↑↑\n")
}
rs(res);
},
fail: err=>{
if(islog)console.log('req fail---->',{
link: url,
query: data,
method: method,
data: err,
})
util.hideLoad();
if(typeof(err.errMsg) == 'string'&&(err.errMsg.indexOf('timeout')!=-1 || err.errMsg.indexOf('interrupted')!=-1 || err.errMsg.indexOf('请求超时')!=-1)){
util.showNone('网络超时!');
}else if(typeof(err.errMsg) == 'string'){
util.showNone(err.errMsg);
}else{
util.showNone('请求数据失败!请检查当前网络状态。');
}
rj(err);
},
complete(result) {
// if(util.debug){
util.showLog(data,url,result)
// }
}
})
})
function defaultGet({res,failMsg,resolve,reject,url,data}){
if(res.data.code == 0){
resolve(res.data.data);
}else{
util.hideLoad();
util.showNone(res.data.message || failMsg || '');
reject({url,res,data});
}
}
}
get({url,data={},header={},isDefaultGet=true,failMsg=''}){
return this.request(url,data,'GET',header,isDefaultGet,failMsg);
}
post({url,data={},header={},isDefaultGet=true,failMsg=''}){
return this.request(url,data,'POST',header,isDefaultGet,failMsg);
}
// post({url,data={},header={'custom-header': 'application/json'},isDefaultGet=true,failMsg=''}){
// return this.request(url,data,'POST',header,isDefaultGet,failMsg);
// }
uploadFile({url,filePath,onProgressCallBack,formData={}}){
return new Promise((rs,rj)=>{
let uploadTask = wx.uploadFile({
url,filePath,formData,name:'file',success:rs,fail:rj
})
uploadTask.onProgressUpdate(res=>onProgressCallBack&&onProgressCallBack(res))
})
}
}
function getWebURL(data,url){
let result = ""
for(var i in data){
result+=`&${i}=${data[i]}`
}
return url+"?"+result.slice(1)
}
export const ox = new Server();
export default { ox, Server };

40
uniapp_project_code/src/utils/util.js

@ -472,6 +472,44 @@ function getNvueRefSize(that,dom,refName){
// #endif
})
}
function getH5RefSize(that,refName){
return new Promise((rs,rj)=>{
// #ifdef H5
// 创建查询请求
const query = uni.createSelectorQuery().in(that);
// 选择需要查询的元素
query.select('.'+refName).boundingClientRect();
// 执行查询
query.exec((res) => {
console.log(res);
if (res[0]) {
// res[0] 是包含节点信息的对象,其中 height 属性是元素的高度
const height = res[0].height;
console.log('元素的高度为:', height);
rs(res[0])
} else {
console.log('未找到指定元素');
rj(false)
}
});
// #endif
})
}
// getUrlParams
function getUrlParams(url) {
var params = {};
var arr = url.split("?");
if (arr.length <= 1) {
return params;
}
arr = arr[1].split("&");
for (var i = 0; i < arr.length; i++) {
var temp = arr[i].split("=");
params[temp[0]] = temp[1];
}
return params;
}
export default {
checkSerialPortMessage,
formatTime,
@ -505,10 +543,12 @@ export default {
debug,
showLog,
getWebURL,
getUrlParams,
timestampToFormatDate,
isExportLog,
getAPIV4,
getAPIV3,
getPageHeight,
getNvueRefSize,
getH5RefSize,
}
Loading…
Cancel
Save