-
14uniapp_project_code/.hbuilderx/launch.json
-
13uniapp_project_code/readme.md
-
28uniapp_project_code/src/components/index/button_green_square.vue
-
270uniapp_project_code/src/components/index/keyboard/keyboard_box.vue
-
222uniapp_project_code/src/components/index/list_item.nvue
-
114uniapp_project_code/src/components/index/page_standby.vue
-
324uniapp_project_code/src/components/index/view_footer.nvue
-
62uniapp_project_code/src/components/index/view_header.nvue
-
39uniapp_project_code/src/components/login/background_nvue.vue
-
4uniapp_project_code/src/components/login/button.vue
-
10uniapp_project_code/src/components/login/setting_mask.vue
-
28uniapp_project_code/src/main.js
-
2uniapp_project_code/src/manifest.json
-
11uniapp_project_code/src/pages.json
-
149uniapp_project_code/src/pages/index/index.nvue
-
12uniapp_project_code/src/pages/index/index.vue
-
8uniapp_project_code/src/pages/login/index.vue
-
31uniapp_project_code/src/pages/login/success.vue
-
BINuniapp_project_code/src/static/images/saoma.png
-
BINuniapp_project_code/src/static/index/add_icon.png
-
BINuniapp_project_code/src/static/index/camera_icon.png
-
BINuniapp_project_code/src/static/index/del_icon.png
-
BINuniapp_project_code/src/static/index/del_icon_big.png
-
BINuniapp_project_code/src/static/index/delete_icon.png
-
BINuniapp_project_code/src/static/index/orange_arrow_right.png
-
BINuniapp_project_code/src/static/index/qr_icon.png
-
BINuniapp_project_code/src/static/index/vip_icon.png
-
BINuniapp_project_code/src/static/index_person.png
-
BINuniapp_project_code/src/static/index_tips.png
-
8uniapp_project_code/src/uni.scss
-
514uniapp_project_code/src/utils/util.js
@ -1,16 +1,20 @@ |
|||
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ |
|||
{ |
|||
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ |
|||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 |
|||
"version" : "0.0", |
|||
"configurations": [{ |
|||
"app-plus" : |
|||
"configurations" : [ |
|||
{ |
|||
"app-plus" : { |
|||
"launchtype" : "local" |
|||
}, |
|||
"default" : |
|||
{ |
|||
"default" : { |
|||
"launchtype" : "local" |
|||
}, |
|||
"type" : "uniCloud" |
|||
}, |
|||
{ |
|||
"playground" : "standard", |
|||
"type" : "uni-app:app-android" |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,13 @@ |
|||
### 项目说明 |
|||
|
|||
### nvue页面注意事项 |
|||
|
|||
1. Android 端在一个页面内使用大量圆角边框会造成性能问题,尤其是多个角的样式还不一样的话更耗费性能。应避免这类使用。 |
|||
2. nvue 页面的布局排列方向默认为竖排(column) |
|||
3. nvue 页面只能使用flex布局 |
|||
4. nvue 页面控制显隐只可以使用v-if不可以使用v-show |
|||
5. 在 App.vue 中定义的全局 js 变量不会在 nvue 页面生效。globalData和vuex是生效的。 |
|||
6. 不能在 style 中引入字体文件 |
|||
7. 不支持在 nvue 页面使用 typescript/ts。 |
|||
|
|||
参考: https://uniapp.dcloud.net.cn/tutorial/page.html#nvue-%E5%BC%80%E5%8F%91%E4%B8%8E-vue-%E5%BC%80%E5%8F%91%E7%9A%84%E5%B8%B8%E8%A7%81%E5%8C%BA%E5%88%AB |
@ -0,0 +1,28 @@ |
|||
<template> |
|||
<view class="btn-box"> |
|||
<button class="login-button" type="primary"> |
|||
<slot/> |
|||
</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.btn-box{ |
|||
// padding: 0 165upx; |
|||
@include ctf(center); |
|||
} |
|||
.login-button{ |
|||
// @include clearBtn; |
|||
// width: 100%; |
|||
// width: 632.64rpx; |
|||
// height: 104.17rpx; |
|||
height: 60.17rpx; |
|||
// background-image: linear-gradient(180deg, #00C9AC 0%, #009874 100%); |
|||
// @include flcw(33.33upx, 46.53upx, #fff, 500); |
|||
background-color: #00C9AC; |
|||
} |
|||
</style> |
@ -0,0 +1,270 @@ |
|||
<template> |
|||
<cover-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="scaleToFill" |
|||
@click="handle_closeKeyboardBox" /> |
|||
<text class="txt-title">输入条形码</text> |
|||
<view class="txt-input"> |
|||
<text class="txt" :class="getInputClass()">{{inputValue||"请输入条形码"}}</text> |
|||
</view> |
|||
|
|||
<view class="input-keyboard"> |
|||
<view class="i-keyboard"> |
|||
<view class="num-btn" v-for="i in 11" |
|||
:class="[getNumBtnClass(i),{'active-value':(activeValue == i) }]" @click="clickKeyboard(i)"> |
|||
<text class="txt" v-if="(i<11)">{{getNumClick(i)}}</text> |
|||
<image class="img" v-else src="/static/index/del_icon_big.png" mode="widthFix" /> |
|||
</view> |
|||
</view> |
|||
<view class="sure-btn"> |
|||
<text class="txt">确定</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</cover-view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import { |
|||
onMounted, |
|||
ref |
|||
} from 'vue' |
|||
import util from "@/utils/util.js" |
|||
|
|||
//触发自定义事件 |
|||
const emits = defineEmits(['showIt']) |
|||
const props = defineProps({ |
|||
maskHeight: { |
|||
type: Number, |
|||
default: 200 |
|||
}, |
|||
maxInput: { |
|||
type: Number, |
|||
default: 10 |
|||
} |
|||
}) |
|||
|
|||
let inputValue = ref("") // |
|||
let activeValue = ref("") // |
|||
|
|||
onMounted(async (res) => { |
|||
console.log(res + ` the keyboard_box component is now mounted. ` + props.maskHeight) |
|||
}) |
|||
|
|||
const handle_closeKeyboardBox = () => { |
|||
emits("showIt", "false") |
|||
} |
|||
|
|||
const getNumBtnClass = (i) => { |
|||
if (i == 11) { |
|||
return "num-btn-last-child" |
|||
} |
|||
return "num-btn" |
|||
} |
|||
// getInputClass |
|||
const getInputClass = () => { |
|||
if (inputValue.value == "") { |
|||
return "txt-blank" |
|||
} |
|||
return "txt-write" |
|||
} |
|||
const getNumClick = (i) => { |
|||
if (i <= 9) return i |
|||
if (i == 10) return "0" |
|||
if (i == 11) return "" //delete |
|||
} |
|||
//click keyboard |
|||
const clickKeyboard = util.debounce((i) => { |
|||
console.log("clickKeyboard:", i) |
|||
// add input react |
|||
activeValue.value = i |
|||
setTimeout(() => { |
|||
activeValue.value = "" |
|||
}, 100) |
|||
|
|||
if (i == 11) { //handle delete input |
|||
inputValue.value = inputValue.value.substring(0, inputValue.value.length - 1) |
|||
} else { |
|||
//limit maxInput |
|||
if (inputValue.value.length >= props.maxInput) { |
|||
return util.showNone(`最大输入${props.maxInput}位`) |
|||
} |
|||
inputValue.value += getNumClick(i) |
|||
} |
|||
}, 20, true) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.keyboard-box { |
|||
|
|||
width: 750rpx; |
|||
height: 1000rpx; |
|||
position: fixed; |
|||
left: 0; |
|||
top: 0; |
|||
right: auto; |
|||
bottom: auto; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
z-index: 11; |
|||
|
|||
@include ctf(center); |
|||
|
|||
.kb-area { |
|||
width: 533.33rpx; |
|||
height: 807.64rpx; |
|||
background: #fff; |
|||
border-radius: 13.89rpx; |
|||
@include ctf(flex-start); |
|||
flex-direction: column; |
|||
|
|||
.del-icon { |
|||
width: 27.78rpx; |
|||
height: 27.78rpx; |
|||
align-self: flex-end; |
|||
margin: 21rpx 21rpx 0 0; |
|||
} |
|||
.txt-title { |
|||
font-weight: 600; |
|||
font-size: 25rpx; |
|||
color: #333333; |
|||
} |
|||
.txt-input { |
|||
@include ctf(flex-start); |
|||
flex-direction: row; |
|||
margin-top: 62rpx; |
|||
margin-bottom: 69rpx; |
|||
padding-left: 20rpx; |
|||
width: 470.83rpx; |
|||
height: 69.44rpx; |
|||
border: 0.69rpx solid #979797; |
|||
border-radius: 6.94rpx; |
|||
.txt { |
|||
font-weight: 700; |
|||
} |
|||
.txt-write { |
|||
font-weight: 700; |
|||
font-size: 25rpx; |
|||
color: #333333; |
|||
} |
|||
.txt-blank { |
|||
font-size: 22.22rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
|
|||
.input-keyboard { |
|||
width: 533.33rpx; |
|||
height: 536.81rpx; |
|||
background: #E8E8E8; |
|||
border-radius: 0 0 6.94rpx 6.94rpx; |
|||
@include ctf(center); |
|||
flex-direction: column; |
|||
|
|||
.i-keyboard { |
|||
// width: 232.69rpx; |
|||
// height: 317.53rpx; |
|||
width: 260rpx; |
|||
// background-color: beige; |
|||
@include ctf(flex-start); |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
|
|||
.num-btn { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
background: #FFFFFF; |
|||
box-shadow: 0 2.08rpx 0 0 #00000033; |
|||
border-radius: 3rpx; |
|||
@include ctf(center); |
|||
margin: 11rpx; |
|||
|
|||
.txt { |
|||
font-weight: 800; |
|||
font-size: 44rpx; |
|||
color: #000000; |
|||
} |
|||
} |
|||
|
|||
.num-btn-last-child { |
|||
width: 150rpx; |
|||
background: #D1D6D8; |
|||
|
|||
.img { |
|||
width: 47.5rpx; |
|||
height: 38rpx; |
|||
// background: #454A52; |
|||
} |
|||
} |
|||
|
|||
.active-value { |
|||
background: #009874; |
|||
} |
|||
|
|||
.del-btn { |
|||
width: 69.44rpx; |
|||
height: 69.44rpx; |
|||
background: #FFFFFF; |
|||
border-radius: 6.94rpx; |
|||
@include ctf(center); |
|||
margin: 10rpx; |
|||
|
|||
.txt { |
|||
font-weight: 500; |
|||
font-size: 25rpx; |
|||
color: #333333; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.sure-btn { |
|||
margin-top: 50rpx; |
|||
width: 490.28rpx; |
|||
height: 69.44rpx; |
|||
background: #009874; |
|||
border-radius: 6.94rpx; |
|||
@include ctf(center); |
|||
|
|||
.txt { |
|||
font-weight: 500; |
|||
font-size: 25rpx; |
|||
color: #FFFFFF; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
.video-tip { |
|||
@include ctf(flex-start); |
|||
flex-direction: row; |
|||
|
|||
.v-image { |
|||
width: 70.03rpx; |
|||
height: 54.17rpx; |
|||
} |
|||
.v-text { |
|||
margin-left: 16rpx; |
|||
font-weight: 400; |
|||
font-size: 19.44rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
|
|||
.cancel-button { |
|||
@include ctf(center); |
|||
width: 131.94rpx; |
|||
height: 51.39rpx; |
|||
border: 0.69rpx solid #999999; |
|||
border-radius: 6.94rpx; |
|||
|
|||
.v-text { |
|||
@include flcw(33.33upx, 46.53upx, #fff, 500); |
|||
font-weight: 500; |
|||
font-size: 16.67rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,222 @@ |
|||
<template> |
|||
<!-- 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> |
|||
</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" /> |
|||
</view> |
|||
<view class="br-bottom"> |
|||
<view class="brb-left"> |
|||
<text class="brb-specs">330ml</text> |
|||
<view class="brb-price"> |
|||
<text class="brbp-single-price">¥4.90</text> |
|||
<text class="brbp-underline-price">¥9.90</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" /> |
|||
</view> |
|||
<view class="brb-right"> |
|||
<view class="brbr-get-score"> |
|||
<text class="txt">下单得积分</text> |
|||
<text class="brbr-score">50</text></view> |
|||
<view class="brbr-total-price"> |
|||
<text class="brbrp-price1">¥</text> |
|||
<text class="brbrp-price2">4.90</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
|
|||
</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; |
|||
|
|||
.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; |
|||
} |
|||
} |
|||
|
|||
.buy-item-right { |
|||
@include fls(flex-start); |
|||
flex-direction: column; |
|||
width: 600rpx; |
|||
// 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> |
@ -0,0 +1,114 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<view class="content_title"> |
|||
<text class="txt">欧轩智能场馆丛云店</text> |
|||
</view> |
|||
<view class="content_info"> |
|||
<text class="txt">欢迎使用自助收银</text> |
|||
</view> |
|||
<image class="content_tip" src="/static/index_tips.png" mode="scaleToFill" /> |
|||
<image class="content_img" src="/static/index_person.png" mode="scaleToFill" /> |
|||
<!-- <main-click-btn > --> |
|||
<view class="content_btn" @click="clickToUse"> |
|||
<image class="icon_saoma" src="/static/images/saoma.png" mode="scaleToFill" /> |
|||
<view> |
|||
<text class="txt">请扫描商品条形码</text> |
|||
</view> |
|||
</view> |
|||
<!-- </main-click-btn> --> |
|||
<view class="content_logo"> |
|||
<text class="txt">欧轩智能场馆提供技术支持</text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import mainClickBtn from '@/components/index/button_green_square.vue'; |
|||
import util from "@/utils/util.js" |
|||
|
|||
function clickToUse() { |
|||
util.routeTo(`/pages/login/success`, 'nT'); |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
|
|||
// background-color: #fff; |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
.content_title { |
|||
// align-self: flex-start; |
|||
width: 750rpx; |
|||
margin-left: 47rpx; |
|||
margin-top: 50rpx; |
|||
.txt{ |
|||
font-weight: 800; |
|||
font-size: 25rpx; |
|||
color: #1A1A1A; |
|||
} |
|||
} |
|||
|
|||
.content_info { |
|||
margin-top: 49rpx; |
|||
// margin-top: 19rpx; |
|||
.txt{ |
|||
font-weight: 800; |
|||
font-size: 58.33rpx; |
|||
color: #1A1A1A; |
|||
} |
|||
} |
|||
|
|||
.content_tip { |
|||
width: 470.83rpx; |
|||
height: 120.83rpx; |
|||
// margin-top: 68rpx; |
|||
margin-top: 28rpx; |
|||
} |
|||
|
|||
.content_img { |
|||
width: 617rpx; |
|||
height: 625rpx; |
|||
margin-top: 31rpx; |
|||
margin-bottom: 30rpx; |
|||
} |
|||
|
|||
.content_logo { |
|||
|
|||
margin-top: 38rpx; |
|||
margin-bottom: 40rpx; |
|||
.txt{ |
|||
font-weight: 400; |
|||
font-size: 19.44rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
// background-image: linear-gradient(180deg, #00C9AC 0%, #009874 100%); |
|||
.content_btn { |
|||
width: 632.64rpx; |
|||
height: 100%; |
|||
background-color: #009874; |
|||
@include ctf(center); |
|||
flex-direction: row; |
|||
// background: #000; |
|||
.icon_saoma { |
|||
width: 41.67rpx; |
|||
height: 41.67rpx; |
|||
margin-right: 10rpx; |
|||
// display: inline; |
|||
} |
|||
|
|||
.txt{ |
|||
font-weight: 500; |
|||
font-size: 33.33rpx; |
|||
color: #FFFFFF; |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
</style> |
@ -0,0 +1,324 @@ |
|||
<template> |
|||
<view class="footer-box"> |
|||
<view class="f-user"> |
|||
<!-- <image src="/static/index/camera_icon.png" mode="scaleToFill" /> --> |
|||
<text class="txt">猫星人(18316553589)</text> |
|||
</view> |
|||
<view class="f-line"></view> |
|||
<view class="f-vip-info" v-if="true"> |
|||
<view class="f-coupon"> |
|||
<text class="txt1">优惠券:</text> |
|||
<text class="txt2">-¥</text> |
|||
<text class="txt3">6.00 </text> |
|||
<image class="img" src="/static/index/orange_arrow_right.png" mode="scaleToFill" /> |
|||
</view> |
|||
<view class="f-score"> |
|||
<text class="txt1">积分:</text> |
|||
<text class="txt2">-¥</text> |
|||
<text class="txt3">2.00 </text> |
|||
<image class="img" src="/static/index/orange_arrow_right.png" mode="scaleToFill" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="f-buy-info"> |
|||
<view class="fi-area"> |
|||
<view class="f-total-price"> |
|||
<text class="txt1">应付:</text> |
|||
<text class="txt2">¥</text> |
|||
<text class="txt3">4.90 </text> |
|||
</view> |
|||
<text class="txt_middle">|</text> |
|||
<view class="f-total-count"> |
|||
<text class="txt">商品:</text> |
|||
<text class="txt">15</text> |
|||
</view> |
|||
</view> |
|||
<view class="fi-choose"> |
|||
<view class="qr-box " @click="handle_clickQR"> |
|||
<image class="qr-img" src="/static/index/qr_icon.png" mode="scaleToFill" /> |
|||
<text class="txt">输入条形码</text> |
|||
</view> |
|||
<view class="vip-box " @click="handle_clickVIP"> |
|||
<image class="vip-img" src="/static/index/vip_icon.png" mode="scaleToFill" /> |
|||
<text class="txt">会员登录</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="btn-style"> |
|||
<text class="txt">去付款</text> |
|||
</view> |
|||
<!-- <button-square class="btn-style"> |
|||
</button-square> --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
import buttonSquare from '@/components/index/button_green_square.vue'; |
|||
import { |
|||
onMounted,ref |
|||
} from 'vue' |
|||
import util from "@/utils/util.js" |
|||
|
|||
//触发自定义事件 |
|||
const emits = defineEmits(['clickQR','clickVIP']) |
|||
const props = defineProps({ |
|||
maskHeight: { |
|||
type: Number, |
|||
default: 200 |
|||
}, |
|||
// maxInput: { |
|||
// type: Number, |
|||
// default: 10 |
|||
// } |
|||
}) |
|||
|
|||
let inputValue = ref("") |
|||
let activeValue = ref("") |
|||
|
|||
let handle_clickQR = ()=>{ |
|||
emits("clickQR","") |
|||
} |
|||
let handle_clickVIP = ()=>{ |
|||
emits("clickVIP","") |
|||
} |
|||
|
|||
onMounted(async (res) => { |
|||
console.log(res + ` the keyboard_box component is now mounted. ` + props.maskHeight) |
|||
}) |
|||
|
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.footer-box { |
|||
z-index: 5; |
|||
padding: 11.11rpx 27.78rpx; |
|||
background-color: aquamarine; |
|||
width: 750rpx; |
|||
@include fls(flex-start); |
|||
flex-direction: column; |
|||
background: #FFFFFF; |
|||
box-shadow: 0 -3.47rpx 3.47rpx 0 #7474741a; |
|||
border-top: 1rpx solid #F5F7F8; |
|||
.f-user { |
|||
@include fls(flex-start); |
|||
flex-direction: row; |
|||
// width: 100%; |
|||
width: 694.44rpx; |
|||
margin: 11rpx 0; |
|||
.txt{ |
|||
font-weight: 800; |
|||
font-size: 19.44rpx; |
|||
} |
|||
.img { |
|||
width: 70.03rpx; |
|||
height: 54.17rpx; |
|||
} |
|||
} |
|||
|
|||
.f-line { |
|||
width: 694.44rpx; |
|||
height: 3rpx; |
|||
background: #F5F7F8; |
|||
} |
|||
|
|||
.f-vip-info { |
|||
@include fls(flex-start); |
|||
flex-direction: row; |
|||
// width: 100%; |
|||
width: 694.44rpx; |
|||
margin: 30rpx 0 0rpx 0; |
|||
.f-coupon { |
|||
@include fls(center); |
|||
flex-direction: row; |
|||
|
|||
|
|||
.txt1 { |
|||
font-weight: 700; |
|||
font-size: 22.22rpx; |
|||
color: #333333; |
|||
} |
|||
|
|||
.txt2 { |
|||
font-weight: 700; |
|||
font-size: 22.22rpx; |
|||
color: #ff873d; |
|||
} |
|||
|
|||
.txt3 { |
|||
font-weight: 700; |
|||
font-size: 22.22rpx; |
|||
color: #ff873d; |
|||
} |
|||
|
|||
.img { |
|||
width: 19.44rpx; |
|||
height: 19.44rpx; |
|||
margin-left: 10rpx; |
|||
} |
|||
} |
|||
|
|||
.f-score { |
|||
@include fls(center); |
|||
flex-direction: row; |
|||
|
|||
margin-left: 52rpx; |
|||
|
|||
.txt1 { |
|||
font-weight: 700; |
|||
font-size: 22.22rpx; |
|||
color: #333333; |
|||
} |
|||
|
|||
.txt2 { |
|||
font-weight: 700; |
|||
font-size: 22.22rpx; |
|||
color: #ff873d; |
|||
} |
|||
|
|||
.txt3 { |
|||
font-weight: 700; |
|||
font-size: 22.22rpx; |
|||
color: #ff873d; |
|||
} |
|||
|
|||
.img { |
|||
width: 19.44rpx; |
|||
height: 19.44rpx; |
|||
margin-left: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.f-buy-info { |
|||
@include fls(space-between); |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
// width: 100%; |
|||
width: 694.44rpx; |
|||
// background-color: #787878; |
|||
margin: 10rpx 0 30rpx 0; |
|||
height: 66rpx; |
|||
.fi-area { |
|||
@include fls(flex-start); |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
.f-total-price { |
|||
@include fls(flex-start); |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
// width: 180rpx; |
|||
.txt1 { |
|||
font-weight: 700; |
|||
color: #333333; |
|||
font-size: 22.22rpx; |
|||
} |
|||
|
|||
.txt2 { |
|||
font-weight: 700; |
|||
color: #ff873d; |
|||
font-size: 43.06rpx; |
|||
margin-bottom: -10rpx; |
|||
} |
|||
|
|||
.txt3{ |
|||
font-weight: 700; |
|||
color: #ff873d; |
|||
font-size: 43.06rpx; |
|||
margin-bottom: -10rpx; |
|||
} |
|||
} |
|||
|
|||
.txt_middle { |
|||
font-weight: 700; |
|||
font-size: 22rpx; |
|||
color: #333333; |
|||
margin: 0 27.78rpx; |
|||
} |
|||
|
|||
.f-total-count { |
|||
@include fls(flex-start); |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
// height: 100%; |
|||
.txt{ |
|||
font-size: 22.22rpx; |
|||
color: #333333; |
|||
font-weight: 700; |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
.fi-choose { |
|||
@include fls(center); |
|||
flex-direction: row; |
|||
.qr-box { |
|||
@include fls(space-between); |
|||
flex-direction: column; |
|||
height: 60rpx; |
|||
margin-right: 27.78rpx; |
|||
.qr-img { |
|||
width: 47.22rpx; |
|||
height: 22.92rpx; |
|||
} |
|||
.vip-img { |
|||
width: 49.31rpx; |
|||
height: 22.92rpx; |
|||
} |
|||
.txt{ |
|||
font-size: 19.44rpx; |
|||
color: #787878; |
|||
} |
|||
} |
|||
.vip-box { |
|||
@include fls(space-between); |
|||
flex-direction: column; |
|||
height: 60rpx; |
|||
.vip-img { |
|||
width: 49.31rpx; |
|||
height: 22.92rpx; |
|||
} |
|||
.txt{ |
|||
font-size: 19.44rpx; |
|||
color: #787878; |
|||
} |
|||
} |
|||
// .mview:first-child { |
|||
|
|||
// } |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
|
|||
|
|||
.cancel-button { |
|||
// @include clearBtn; |
|||
// @include ctf(center); |
|||
width: 131.94rpx; |
|||
height: 51.39rpx; |
|||
border: 0.69rpx solid #999999; |
|||
border-radius: 6.94rpx; |
|||
@include flcw(33.33upx, 46.53upx, #fff, 500); |
|||
font-weight: 500; |
|||
font-size: 16.67rpx; |
|||
color: #999999; |
|||
} |
|||
|
|||
.btn-style{ |
|||
@include fls(center); |
|||
width: 694.44rpx; |
|||
height: 83.33rpx; |
|||
// background-image: linear-gradient(180deg, #FFBC70 0%, #FF873D 100%); |
|||
background-color: #FF873D; |
|||
background: #FF873D; |
|||
border-radius: 6.94rpx; |
|||
|
|||
.txt{ |
|||
@include flcw(27.78upx, 27.78upx, #fff, 700); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,62 @@ |
|||
<template> |
|||
<view class="header-box"> |
|||
<view class="video-tip"> |
|||
<image class="v-image" src="/static/index/camera_icon.png" mode="widthFix" /> |
|||
<text class="v-text">您已进入视频覆盖区</text> |
|||
</view> |
|||
<view class="cancel-button" @click="handle_closeStandby"> |
|||
<text class="v-text"> 取消交易</text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
//触发自定义事件 |
|||
const emits = defineEmits(['closeStandby']) |
|||
|
|||
const handle_closeStandby = ()=>{ |
|||
emits("closeStandby","false") |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.header-box { |
|||
z-index: 5; |
|||
padding: 11.11rpx 17.36rpx; |
|||
height: 79.17rpx; |
|||
width: 750rpx; |
|||
@include ctf(space-between); |
|||
flex-direction: row; |
|||
background: #F5F7F8; |
|||
border-bottom: 1rpx solid #F5F7F8; |
|||
} |
|||
|
|||
.video-tip { |
|||
@include ctf(flex-start); |
|||
flex-direction: row; |
|||
.v-image { |
|||
width: 70.03rpx; |
|||
height: 54.17rpx; |
|||
} |
|||
.v-text{ |
|||
margin-left: 16rpx; |
|||
font-weight: 400; |
|||
font-size: 19.44rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
|
|||
.cancel-button { |
|||
@include ctf(center); |
|||
width: 131.94rpx; |
|||
height: 51.39rpx; |
|||
border: 0.69rpx solid #999999; |
|||
border-radius: 6.94rpx; |
|||
.v-text{ |
|||
@include flcw(33.33upx, 46.53upx, #fff, 500); |
|||
font-weight: 500; |
|||
font-size: 16.67rpx; |
|||
color: #999999; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,39 @@ |
|||
<template> |
|||
<view class="background"> |
|||
<image class="bg-img" src="../../static/login_bg.jpg" mode="widthFix"></image> |
|||
<slot></slot> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.background { |
|||
// width: 750rpx; |
|||
// height: 1300rpx; |
|||
// height: 100vh; |
|||
.bg-img{ |
|||
// position: fixed; |
|||
// top: 0; |
|||
// left: 0; |
|||
width: 750rpx; |
|||
// height: 1900rpx; |
|||
height: 100vh; |
|||
position: absolute; |
|||
left: 0; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
// padding-top: -1000rpx; |
|||
// margin-top: -1000rpx; |
|||
background-size: 100% 100%; |
|||
background-repeat: no-repeat; |
|||
background-image: url("/static/login_bg.jpg"); |
|||
} |
|||
|
|||
} |
|||
</style> |
@ -1,27 +1,28 @@ |
|||
{ |
|||
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages |
|||
{ |
|||
"path": "pages/login/index", |
|||
"path": "pages/index/index", |
|||
"style": { |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/login/success", |
|||
"path": "pages/login/index", |
|||
"style": { |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/index/index", |
|||
"path": "pages/login/success", |
|||
"style": { |
|||
"navigationBarTitleText": "uni-app" |
|||
"navigationStyle": "custom" |
|||
} |
|||
} |
|||
|
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "uni-app", |
|||
"navigationBarTitleText": "欧轩收银端", |
|||
"navigationBarBackgroundColor": "#F8F8F8", |
|||
"backgroundColor": "#F8F8F8" |
|||
} |
|||
|
@ -0,0 +1,149 @@ |
|||
<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> |
|||
|
|||
<keyboard-box v-if="showKeyboardBox" :maskHeight="screenHeight" :maxInput="maxInput" @showIt="handle_closeKeyboardBox"></keyboard-box> |
|||
</view> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import pageStandby from '@/components/index/page_standby.vue'; |
|||
import util from "@/utils/util.js" |
|||
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 keyboardBox from '@/components/index/keyboard/keyboard_box.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, |
|||
'keyboard-box': keyboardBox, |
|||
}, |
|||
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, |
|||
showKeyboardBox:false, |
|||
screenHeight: '', |
|||
footerHeight: '', |
|||
} |
|||
}, |
|||
async onLoad(res) { |
|||
console.log("onload:",res) |
|||
this.screenHeight = await util.getPageHeight() |
|||
console.log(`the index page onLoad----` + this.screenHeight) |
|||
}, |
|||
async onReady() { |
|||
this.setFooterHeight() |
|||
}, |
|||
methods: { |
|||
clickToUse() { |
|||
util.routeTo(`/pages/login/success`, 'nT'); |
|||
}, |
|||
handle_closeStandby(val) { |
|||
console.log("handle_closeSetting", val) |
|||
this.showPageStandby = !this.showPageStandby |
|||
}, |
|||
handle_closeKeyboardBox(val) { |
|||
console.log("handle_closeKeyboardBox", val) |
|||
this.showKeyboardBox = !this.showKeyboardBox |
|||
}, |
|||
handle_clickQR() { |
|||
util.showNone("输入条形码") |
|||
this.showKeyboardBox = !this.showKeyboardBox |
|||
}, |
|||
handle_clickVIP() { |
|||
util.showNone("会员登录") |
|||
}, |
|||
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> |
@ -1,12 +0,0 @@ |
|||
<template> |
|||
<view class="content"> |
|||
999 |
|||
</view> |
|||
</template> |
|||
|
|||
<script setup> |
|||
</script> |
|||
|
|||
<style> |
|||
|
|||
</style> |
After Width: 41 | Height: 41 | Size: 438 B |
After Width: 55 | Height: 55 | Size: 1.9 KiB |
After Width: 70 | Height: 54 | Size: 1.5 KiB |
After Width: 55 | Height: 55 | Size: 1.0 KiB |
After Width: 55 | Height: 55 | Size: 958 B |
After Width: 23 | Height: 23 | Size: 357 B |
After Width: 19 | Height: 19 | Size: 380 B |
After Width: 48 | Height: 22 | Size: 243 B |
After Width: 47 | Height: 22 | Size: 885 B |
After Width: 1252 | Height: 1235 | Size: 223 KiB |
After Width: 940 | Height: 244 | Size: 33 KiB |
@ -0,0 +1,514 @@ |
|||
// import {emojiMap,emojiUrl} from './emojiMap';
|
|||
|
|||
export const phoneReg = new RegExp(/^1(3|4|5|6|7|8|9)\d{9}$/); |
|||
export const mailReg = new RegExp(/^\w+((.\w+)|(-\w+))@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+).[A-Za-z0-9]+$/); |
|||
export const specialReg = new RegExp("[^a-zA-Z0-9\_\u4e00-\u9fa5]","i"); |
|||
|
|||
export const debug = false //是否开启debug模式,使用非离线工程模式调试
|
|||
|
|||
export const isExportLog = false //是否开启log输出
|
|||
|
|||
export const formatTime = date => { |
|||
const year = date.getFullYear() |
|||
const month = date.getMonth() + 1 |
|||
const day = date.getDate() |
|||
const hour = date.getHours() |
|||
const minute = date.getMinutes() |
|||
const second = date.getSeconds() |
|||
|
|||
return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':') |
|||
} |
|||
|
|||
export const formatDate = ({ date= new Date(), partition= '-' }) => { |
|||
let _date; |
|||
if(typeof (date) === 'string'&&date.indexOf('-')!=-1){ |
|||
_date = new Date(date.replace(/\-/g,'/')) |
|||
}else{ |
|||
_date = new Date(date) |
|||
} |
|||
const year = _date.getFullYear(); |
|||
const month = _date.getMonth() + 1; |
|||
const day = _date.getDate(); |
|||
|
|||
if(partition == 'zh')return `${year}年${month}月${day}日` |
|||
return [year, month, day].map(formatNumber).join(partition); |
|||
} |
|||
|
|||
export const formatNumber = n => { |
|||
n = n.toString() |
|||
return n[1] ? n : '0' + n |
|||
} |
|||
// 路由跳转
|
|||
export const routeTo = (url,type) => { |
|||
switch(type){ |
|||
case 'nT': uni.navigateTo({url}); |
|||
break |
|||
case 'rT': uni.redirectTo({url}); |
|||
break |
|||
case 'rL': uni.reLaunch({url}); |
|||
break |
|||
case 'sT': uni.switchTab({url}); |
|||
break |
|||
default: uni.navigateBack({delta: 1}) |
|||
break |
|||
} |
|||
} |
|||
|
|||
function showNone(txt,duration=1500){ |
|||
uni.hideToast(); |
|||
uni.hideLoading(); |
|||
uni.showToast({ |
|||
mask: true, |
|||
title: txt, |
|||
icon: 'none', |
|||
duration, |
|||
}) |
|||
} |
|||
|
|||
function showLoad(title='加载中', mask=true){ |
|||
uni.showLoading({ |
|||
mask, |
|||
title, |
|||
}) |
|||
} |
|||
function hideLoad(){ |
|||
uni.hideLoading() |
|||
} |
|||
function showModal({ |
|||
title='提示', |
|||
content='', |
|||
showCancel=false, |
|||
cancelText='取消', |
|||
confirmText='确定', |
|||
confirmColor='#009874', |
|||
success, |
|||
fail, |
|||
complete |
|||
}){ |
|||
uni.showModal({ |
|||
title, |
|||
content, |
|||
showCancel, |
|||
cancelText, |
|||
confirmColor, |
|||
confirmText, |
|||
success, |
|||
fail, |
|||
complete |
|||
}) |
|||
} |
|||
|
|||
function debounce(func, wait, immediate) { |
|||
let timeout, args, context, timestamp, result; |
|||
const later = function() { |
|||
// 据上一次触发时间间隔
|
|||
const last = +new Date() - timestamp; |
|||
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
|
|||
if (last < wait && last > 0) { |
|||
timeout = setTimeout(later, wait - last); |
|||
} else { |
|||
timeout = null; |
|||
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
|
|||
if (!immediate) { |
|||
result = func.apply(context, args); |
|||
if (!timeout) context = args = null; |
|||
} |
|||
} |
|||
} |
|||
return function(...args) { |
|||
context = this; |
|||
timestamp = +new Date(); |
|||
const callNow = immediate && !timeout; |
|||
// 如果延时不存在,重新设定延时
|
|||
if (!timeout) timeout = setTimeout(later, wait); |
|||
if (callNow) { |
|||
result = func.apply(context, args); |
|||
context = args = null; |
|||
} |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
function jsonStr(data){ |
|||
return encodeURIComponent(JSON.stringify(data)) |
|||
} |
|||
function jsonPar(json){ |
|||
return JSON.parse(decodeURIComponent(json)) |
|||
} |
|||
|
|||
export let promisify = api => { |
|||
return (options, ...params) => { |
|||
return new Promise((resolve, reject) => { |
|||
api(Object.assign({}, options, { success: resolve, fail: reject }), ...params); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function previousPageFunction({fnName,query}){ |
|||
return new Promise((rs,rj)=>{ |
|||
try{ |
|||
if(getCurrentPages().length>1){ |
|||
console.log(getCurrentPages()) |
|||
getCurrentPages()[getCurrentPages().length-2]['$vm'][fnName](query); |
|||
rs('success'); |
|||
}else{ |
|||
console.error('当前路由栈为一,无法调取上一页数据'); |
|||
rj('当前路由栈为一,无法调取上一页数据'); |
|||
} |
|||
}catch(err){ |
|||
console.error('调用上一页面栈方法失败!',err); |
|||
rj('调用上一页面栈方法失败!'); |
|||
} |
|||
}) |
|||
|
|||
} |
|||
|
|||
// 获取节点信息
|
|||
function getNodeMes(selector,_this=null){ |
|||
return new Promise(rs=>{ |
|||
let query = _this ? uni.createSelectorQuery().in(_this) : uni.createSelectorQuery(); |
|||
query.select(selector).boundingClientRect(res=>{ |
|||
rs(res) |
|||
// this.height = uni.getSystemInfoSync().windowHeight - res.height;
|
|||
}).exec() |
|||
}) |
|||
} |
|||
|
|||
export const convertBase64 = function(base64data){ |
|||
const fsm = uni.getFileSystemManager(); |
|||
const FILE_BASE_NAME = 'tmp_base64src';//临时文件名
|
|||
return new Promise((resolve, reject) => { |
|||
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []; //去掉 base64 的头信息:
|
|||
if (!format) { |
|||
reject(new Error('ERROR_BASE64SRC_PARSE')); |
|||
} |
|||
const filePath = `${uni.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`; |
|||
const buffer = bodyData&&uni.base64ToArrayBuffer(bodyData); //将 base64 数据转换为 ArrayBuffer 数据
|
|||
// console.log(uni.base64ToArrayBuffer(bodyData))
|
|||
fsm.writeFile({ //将 ArrayBuffer 写为本地用户路径的二进制图片文件 //图片文件路径在 uni.env.USER_DATA_PATH 中
|
|||
filePath, |
|||
data: buffer, |
|||
encoding: 'binary', |
|||
success() { |
|||
// console.log(buffer)
|
|||
resolve(filePath); |
|||
}, |
|||
fail() { |
|||
reject(new Error('ERROR_BASE64SRC_WRITE')); |
|||
}, |
|||
}); |
|||
}); |
|||
} |
|||
export function failAuthorizeTosetting(content='调用失败,请打开检查授权状态'){ |
|||
showModal({ |
|||
title:'提示', |
|||
content, |
|||
showCancel:true, |
|||
confirmText:'打开', |
|||
success:res=>{if(res.confirm)uni.openSetting()} |
|||
}) |
|||
} |
|||
|
|||
// 解析小程序码 scene 参数
|
|||
export function getSceneQuery(scene){ |
|||
const queryStr = decodeURIComponent(scene) || null; |
|||
let queryObj = queryStr.split('&').reduce((obj,el)=>{ |
|||
let arr = el.split('='); |
|||
obj[`${arr[0]}`] = arr[1]; |
|||
return obj; |
|||
},{}) || null; |
|||
return queryObj; |
|||
} |
|||
|
|||
// 格式化聊天内容
|
|||
// export function formatContent(str = ''){
|
|||
// let reg = /\[[\u4e00-\u9fa5_a-zA-Z0-9]{1,}\]/gi;
|
|||
// let strArr = str.split(reg) || [];
|
|||
// let emojiArr = str.match(reg) || [];
|
|||
// let contentList = [];
|
|||
// strArr.forEach(ele=>{
|
|||
// if(ele)contentList.push({
|
|||
// type:'txt',
|
|||
// content:ele
|
|||
// });
|
|||
// if(!!emojiArr.length){
|
|||
// let iconKey = emojiArr.splice(0,1)[0];
|
|||
// if(emojiMap[iconKey]){
|
|||
// contentList.push({
|
|||
// type:'icon',
|
|||
// src:`${emojiUrl}${emojiMap[iconKey]}`
|
|||
// })
|
|||
// }else{
|
|||
// contentList.push({
|
|||
// type:'txt',
|
|||
// content:iconKey
|
|||
// });
|
|||
// }
|
|||
// }
|
|||
// });
|
|||
// return contentList
|
|||
// }
|
|||
//获取地址栏里(URL)传递的参数
|
|||
function getUrlQuery(key,url){ |
|||
var _url = decodeURI(url).split('?a=1').join(''); //剪切'?a=1'安卓兼容,再获取参数
|
|||
if(_url.indexOf(`${key}=`) !=-1){ |
|||
return _url.split(`${key}=`)[1].split('&')[0] |
|||
} |
|||
return null |
|||
} |
|||
|
|||
//获取地址字段栏信息 腾讯获取授权码时
|
|||
function getQueryString(name) { |
|||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
|||
var r = window.location.search.substr(1).match(reg); |
|||
if (r != null) return (r[2]); // 编码的字符串进行解码
|
|||
return null; |
|||
} |
|||
|
|||
function getRandom(min, max) { |
|||
return Math.round(Math.random() * (max - min)) + min; |
|||
} |
|||
|
|||
export function get_zh_day(date){ |
|||
if(isSameDay(new Date().getTime(),new Date(date).getTime()))return '今天' |
|||
const Arr = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; |
|||
return Arr[new Date(date).getDay()] || ''; |
|||
} |
|||
|
|||
// 判断是否同一天
|
|||
export function isSameDay(timeStampA, timeStampB) { |
|||
let dateA = new Date(timeStampA); |
|||
let dateB = new Date(timeStampB); |
|||
return (dateA.setHours(0, 0, 0, 0) == dateB.setHours(0, 0, 0, 0)); |
|||
} |
|||
|
|||
// 获取中文日期
|
|||
export function get_zh_date(date = new Date()){ |
|||
return `${new Date(date).getMonth()+1}月${new Date(date).getDate()}日` |
|||
} |
|||
|
|||
export function substrDate(date){ |
|||
if(!date)return; |
|||
return date.substr(0,10) || '-' |
|||
} |
|||
|
|||
// package 貌似为保留字,作为参数时 编译报错
|
|||
export function requestPayment(query = {}){ |
|||
showLoad(); |
|||
uni.requestPayment({ |
|||
timeStamp: query.timeStamp || '', |
|||
nonceStr: query.nonceStr || '', |
|||
package: query.package || '', |
|||
signType: query.signType || '', |
|||
paySign: query.paySign || '', |
|||
success: function(res){ |
|||
query.success&&query.success(res) |
|||
}, |
|||
fail: function(res){ |
|||
query.fail&&query.fail(res) |
|||
}, |
|||
complete: function(res){ |
|||
hideLoad(); |
|||
query.complete&&query.complete(res) |
|||
}, |
|||
}) |
|||
} |
|||
function getQueryStr({url,name}){ |
|||
let queryArr = (url.split('?')[1] || '').split("&") || []; |
|||
// let vars = query.split("&");
|
|||
for (let i=0;i<queryArr.length;i++) { |
|||
let pair = queryArr[i].split("="); |
|||
if(pair[0] == name)return pair[1] || ''; |
|||
} |
|||
return ''; |
|||
} |
|||
|
|||
function formatScene(scene = ''){ |
|||
let queryArr = scene.split('&'); |
|||
return queryArr.reduce((obj,e,i)=>{ |
|||
let _arr = e.split('='); |
|||
obj[_arr[0]] = _arr[1]; |
|||
return obj; |
|||
},{}) || {}; |
|||
} |
|||
|
|||
// 获取当天、明天、昨天的日期
|
|||
function specialFormatDate(num){ |
|||
// num:表示距离当前日期的天数,0表示当天,1明天,-1昨天
|
|||
var now = new Date(); |
|||
var nowTime = now.getTime(); |
|||
var oneDayTime = 24 * 60 * 60 * 1000; |
|||
var ShowTime = nowTime + num * oneDayTime; |
|||
var myDate = new Date(ShowTime); |
|||
let arrDate = {}; |
|||
arrDate['y'] = myDate.getFullYear(); //年
|
|||
arrDate['m'] = myDate.getMonth() + 1; //月
|
|||
arrDate['d'] = myDate.getDate(); //日
|
|||
return arrDate; |
|||
} |
|||
// 时分秒 转为毫秒
|
|||
function timeToSec(hour, min, sec) { |
|||
var s = Number(hour * 3600) + Number(min * 60) + Number(sec); |
|||
return s * 1000; |
|||
} |
|||
|
|||
//log日志函数
|
|||
function showLog(data,url,response){ |
|||
let weburl = getWebURL(data,url) |
|||
let temp = url.split("?")[0].split("/") |
|||
let postName = temp[temp.length-1] |
|||
if(isExportLog){ |
|||
console.error("-------------------->> ["+postName+"][log]\n" |
|||
+"请求 Data: \n" + JSON.stringify(data) |
|||
+"\n URL:\n"+weburl |
|||
+"\n 服务端返回:\n"+JSON.stringify(response.data) |
|||
+"\n <<-------------------- ["+postName+"][log] ↑↑↑\n") |
|||
} |
|||
} |
|||
//获取拼接url
|
|||
function getWebURL(data,url){ |
|||
let result = "" |
|||
for(var i in data){ |
|||
result+=`&${i}=${data[i]}` |
|||
} |
|||
return url+"?"+result.slice(1) |
|||
} |
|||
|
|||
// 时间戳转时间格式
|
|||
function timestampToFormatDate(value){ |
|||
if(!value)return "-"; |
|||
var date = new Date(value); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
|
|||
var year = date.getFullYear(); |
|||
var month = ("0" + (date.getMonth() + 1)).slice(-2); |
|||
var sdate = ("0" + (date.getDate())).slice(-2); |
|||
var hour = ("0" + (date.getHours())).slice(-2); |
|||
var minute = ("0" + (date.getMinutes())).slice(-2); |
|||
var second = ("0" + (date.getSeconds())).slice(-2); |
|||
var result = year + "." + month + "." + sdate + " " + hour + ":" + minute + ":" + second; |
|||
return result || '-'; |
|||
} |
|||
|
|||
function checkSerialPortMessage(msg){ |
|||
if(!msg)return""; |
|||
if(msg=="aa01ea")return""; //第四版设备,每次刷卡后会2次返回该数据.
|
|||
return msg |
|||
} |
|||
function getAPIV4(){ |
|||
// 一个包含了代码里的所有api_name的js数组,名字叫api_name_arr
|
|||
//参考文档2023-07-05-v4版(1)/3568外设接口sdk-1.3.1-2023-07-05-v4版/ph-API文档_20230705.pdf
|
|||
var api_name_arr = [ |
|||
"whiteLight_Control_Open", //白光-开
|
|||
"whiteLight_Control_Close", //白光-关
|
|||
"orange_Led_Open", //橙灯-开
|
|||
"close_Led", //关闭所有灯
|
|||
"red_Led_Open", //红灯-开
|
|||
"green_Led_Open", //绿灯-开
|
|||
"shutdown", //关机
|
|||
"reboot", //重启
|
|||
"showNavigationBar", //显示导航栏
|
|||
"hideNavigationBar", //隐藏导航栏
|
|||
"showStatusBar", //显示状态栏
|
|||
"hideStatusBar", //隐藏状态栏
|
|||
"nocanStatusBarDrop", //禁止下拉状态栏
|
|||
"canStatusBarDrop", //允许下拉状态栏
|
|||
"fc_read", //读取防拆状态
|
|||
"setSystemTime", //设置系统时间 value:时间戳,单位为毫秒, 比如:1634464800000 为 2021-10-17 18:00
|
|||
"isDebugMode", //设置是否打印日志 value:true,false
|
|||
"doorbell_control_open", //拉高门铃
|
|||
"doorbell_control_close", //拉低门铃
|
|||
"ds_control_read", //读取门磁电平
|
|||
"open_door_read", //读取开门 door 电平
|
|||
"fire_alm_read", //读取烟雾传感器电平
|
|||
"reboot_start_app",//开机启动app
|
|||
]; |
|||
console.warn("注意[setSystemTime, isDebugMode]选项需传入value") |
|||
return api_name_arr |
|||
} |
|||
function getAPIV3(){ |
|||
// 一个包含了代码里的所有api_name的js数组,名字叫api_name_arr
|
|||
//参考文档3568-SDK-V3/sdkapi-v20201022-r20230522/%E4%B8%BB%E6%9D%BFAPI%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C(20230522).pdf
|
|||
var api_name_arr = [ |
|||
"hideNavigationBar", //
|
|||
"showNavigationBar", //
|
|||
"hideStatusBar", //
|
|||
"showStatusBar", //
|
|||
"navigationBarMaxIdle", //
|
|||
"KEEPALIVE_SETUP", //
|
|||
"KEEPALIVE_UNSET_ALL", //
|
|||
"KEEPALIVE_UNSET", //
|
|||
"BOOT_SETUP", //
|
|||
"BOOT_UNSET_ALL", //
|
|||
"BOOT_UNSET", //
|
|||
"hardShutdown", //
|
|||
"hardReboot", //
|
|||
"softReboot", //
|
|||
"getStatusBarStatus", //
|
|||
]; |
|||
// console.warn("注意[setSystemTime, isDebugMode]选项需传入value")
|
|||
return api_name_arr |
|||
} |
|||
|
|||
function getPageHeight() { |
|||
return new Promise((resolve, reject) => { |
|||
uni.getSystemInfo({ |
|||
success: function(res) { |
|||
// console.log("getSystemInfores", res)
|
|||
resolve(res.windowHeight) |
|||
}, |
|||
fail:(fail)=>{ |
|||
console.log("getSystemInfo fail", fail) |
|||
reject(1000)}, |
|||
}) |
|||
}) |
|||
} |
|||
function getNvueRefSize(that,dom,refName){ |
|||
return new Promise((rs,rj)=>{ |
|||
// #ifdef APP-NVUE
|
|||
let size = dom.getComponentRect(that.$refs[refName], async (option) => { |
|||
// console.log("getNvueRefSize: ",option.result)
|
|||
if(option.result)rs(option.size) |
|||
rj(false) |
|||
}); |
|||
// #endif
|
|||
}) |
|||
} |
|||
export default { |
|||
checkSerialPortMessage, |
|||
formatTime, |
|||
formatNumber, |
|||
formatDate, |
|||
routeTo, |
|||
showNone, |
|||
showLoad, |
|||
hideLoad, |
|||
showModal, |
|||
debounce, |
|||
jsonStr, |
|||
jsonPar, |
|||
promisify, |
|||
previousPageFunction, |
|||
getNodeMes, |
|||
failAuthorizeTosetting, |
|||
getSceneQuery, |
|||
getUrlQuery, |
|||
getQueryString, |
|||
getRandom, |
|||
get_zh_day, |
|||
isSameDay, |
|||
get_zh_date, |
|||
substrDate, |
|||
requestPayment, |
|||
getQueryStr, |
|||
formatScene, |
|||
specialFormatDate, |
|||
timeToSec, |
|||
debug, |
|||
showLog, |
|||
getWebURL, |
|||
timestampToFormatDate, |
|||
isExportLog, |
|||
getAPIV4, |
|||
getAPIV3, |
|||
getPageHeight, |
|||
getNvueRefSize, |
|||
} |