提交 25cf68a2 authored 作者: 宋雄's avatar 宋雄

Initial commit

上级
/unpackage
{
// 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" : {
"launchtype" : "local"
},
"default" : {
"launchtype" : "local"
},
"mp-weixin" : {
"launchtype" : "local"
},
"type" : "uniCloud"
},
{
"openVueDevtools" : false,
"type" : "uni-app:miniProgram"
},
{
"playground" : "standard",
"type" : "uni-app:app-ios_simulator"
},
{
"playground" : "custom",
"type" : "uni-app:app-android"
}
]
}
<script>
export default {
globalData: {
isMobieDevice: true,
physicalInvoiceList: [], // 新增物理发票信息
btmInset: 0
},
onLaunch: function() {
//小程序自动更新
if (uni.canIUse('getUpdateManager')) {
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(res => {
// 请求完新版本信息的回调
if (res.hasUpdate) {
updateManager.onUpdateReady(() => {
uni.showModal({
title: this.$t('index.update-note'),
content: this.$t('index.msg-update'),
success: res => {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
}
});
});
updateManager.onUpdateFailed(() => {
// 新的版本下载失败
uni.showModal({
title: this.$t('index.msg-updated'),
content: this.$t('index.msg-update-tips')
});
});
}
});
}
let _this = this;
wx.getSystemInfo({
success: function(res) {
let platform = res.platform
_this.globalData.isMobieDevice = platform == "ios" || platform == "android" ||
platform == "devtools"
}
})
const {
safeAreaInsets
} = uni.getSystemInfoSync()
this.btmInset = safeAreaInsets.bottom
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style lang="scss">
/*每个页面公共css */
@import '@/uni_modules/uni-scss/index.scss';
/* #ifndef APP-NVUE */
@import '@/static/customicons.css';
// 设置整个项目的背景色
page {
background-color: #F5F5F6;
}
/* #endif */
.example-info {
font-size: 14px;
color: #333;
padding: 10px;
}
.custom-uni-list {
/deep/ .uni-list--border-top {
left: 15px !important;
right: 15px !important;
}
/deep/ .uni-list--border-bottom {
left: 15px !important;
right: 15px !important;
}
/deep/ .uni-list--border::after {
left: 15px !important;
right: 15px !important;
}
/deep/ .uni-list-item__content {
flex: none !important;
}
/deep/ .uni-list-item__content-title {
color: #697077 !important;
}
/deep/ .uni-list-item__extra {
flex: auto;
}
/deep/ .uni-list-item__extra-text {
font-size: 14px !important;
color: #222222 !important;
}
.custom-uni-value {
flex: auto;
text-align: right;
font-size: 14px;
color: #B60001;
}
.list-item-left {
position: absolute;
flex: auto;
left: 240rpx;
text-align: left;
font-size: 14px;
color: #333;
}
}
</style>
\ No newline at end of file
<template>
<view class="authorization-box" v-if="show">
<view class="title">{{$t('index.athor-login')}}</view>
<view class="message">{{$t('index.login-note')}}</view>
<view class="btn-box">
<button class="button" type="primary" @click="toLogin" hover-class="none">{{$t('index.login')}}</button>
</view>
</view>
</template>
<script>
export default {
props: {
show: {
type: Boolean,
default: false
},
url: String
},
data() {
return {
}
},
methods: {
toLogin() {
uni.navigateTo({
url: `/pages/login/index?url=${encodeURIComponent(JSON.stringify(this.url))}`
});
}
}
}
</script>
<style lang="scss">
.authorization-box {
box-sizing: border-box;
// height: 100vh;
padding-top: 100rpx;
// background-color: #FFFFFF;
.title {
text-align: center;
font-size: 16px;
color: #B60001;
font-weight: bold;
}
.message {
font-size: 14px;
margin-top: 60rpx;
text-align: center;
color: #99A0AF;
}
.btn-box {
margin-top: 100rpx;
.button {
width: 300rpx;
height: 40px;
line-height: 40px;
background-color: #B60001;
font-size: 14px;
color: #FFFFFF;
}
}
}
</style>
\ No newline at end of file
<template>
<uni-popup ref="authorizationPopup" background-color="#fff">
<view class="authorization-box">
<view class="title">授权登录</view>
<view class="message">为了更完美的体验,请登录</view>
<view class="btn-box">
<button class="button" type="primary" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber" hover-class="none">登录</button>
</view>
<view class="refuse" @click="refuse">拒绝</view>
</view>
</uni-popup>
</template>
<script>
import {
customerWxToken,
getUserInfo
} from "@/config/api.js"
export default {
props: {
},
data() {
return {
code: ''
}
},
methods: {
openAuthorization() {
this.$refs.authorizationPopup.open('center')
uni.login({
provider: 'weixin',
success: loginRes=> {
if(loginRes.errMsg === "login:ok") {
this.code = loginRes.code
}
}
});
},
refuse() {
this.$refs.authorizationPopup.close()
uni.showModal({
content: '您拒绝了授权,登录失败!',
showCancel: false
})
},
//获取手机号
async onGetPhoneNumber(e) {
this.$refs.authorizationPopup.close()
if (!e.detail.code) { //用户决绝授权
//拒绝授权后弹出一些提示
uni.showModal({
content: '您拒绝了授权,登录失败!',
showCancel: false
})
} else { //允许授权
let data = await customerWxToken({
code: this.code,
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
})
let res = JSON.parse(data.content.token)
uni.setStorageSync('token', res.token)
let info = await getUserInfo({
params: {
token: res.token
}
})
let userInfo = {
customerCode: info.content.userInfo.customerCode,
customerName: info.content.userInfo.customerName
}
uni.setStorageSync('userInfo', JSON.stringify(userInfo))
uni.setStorageSync('userBtnPerms', JSON.stringify(info.content.userBtnPerms));
this.$emit('success')
}
}
}
}
</script>
<style lang="scss">
.authorization-box {
box-sizing: border-box;
width: 560rpx;
padding-top: 30rpx;
background-color: #FFFFFF;
.title {
text-align: center;
font-size: 16px;
color: #B60001;
font-weight: bold;
}
.message {
font-size: 14px;
margin-top: 30rpx;
margin-bottom: 50rpx;
text-align: center;
color: #99A0AF;
padding: 0 50rpx;
}
.btn-box {
padding: 0 50rpx;
.button {
height: 40px;
line-height: 40px;
background-color: #B60001;
font-size: 14px;
color: #FFFFFF;
}
}
.refuse {
margin-top: 10px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 13px;
color: #DE0000;
border-top: 1rpx solid #D5E2F3;
}
}
</style>
<template>
<view class="nodate-box" v-if="show" :class="{'full': isFull}">
<image class="nodate" src="http://manage.51svalue.com/group1/M00/00/7A/CgAAEWOYGf2ARB2zAADF0CpS_Pc912.png" mode="aspectFill"></image>
<view class="text">{{text}}</view>
</view>
</template>
<script>
export default {
props: {
show: {
type: Boolean,
default: false
},
text: {
type: String,
default: '暂无数据'
},
isFull: {
type: Boolean,
default: true
}
},
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss">
.nodate-box {
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
&.full {
// height: 100%;
height: 100vh;
.nodate {
margin-top: 280rpx;
width: 340rpx;
height: 254rpx;
}
.text {
margin-top: 50rpx;
}
}
.nodate {
width: 170rpx;
height: 127rpx;
}
.text {
font-size: 28rpx;
color: #B60001;
margin-top: 20rpx;
}
}
</style>
<template>
<checkbox-group @change="changePolicy">
<label>
<view class="policy-box">
<checkbox value="true" :checked="checked" color="#B60001" style="transform:scale(0.8)" />
<text class="text">{{$t('index.mark-as-read')}}</text>
<text class="policy" @click.stop="readAgreement">{{$t('index.agreement-title')}}</text>
<text class="text">{{$t('index.and')}}</text>
<text class="policy" @click.stop="readPolicy">{{$t('index.policy-title')}}</text>
</view>
</label>
</checkbox-group>
</template>
<script>
export default {
props: {
checked: {
type: Boolean,
default: false
}
},
methods: {
changePolicy(e) {
this.$emit('change', e.detail.value.length)
},
readPolicy() {
uni.navigateTo({
url: '/pages/policy/policy'
})
},
readAgreement() {
uni.navigateTo({
url: '/pages/policy/agreement'
})
}
}
}
</script>
<style lang="scss">
.policy-box {
padding: 0 30rpx;
font-size: 14px;
vertical-align: middle;
.text {
color: #B60001;
vertical-align: middle;
}
.policy {
color: #B60001;
vertical-align: middle;
}
}
</style>
\ No newline at end of file
<template>
<view style="padding-top: 5px;">
<view class="product-list" v-for="(item,index) in list" :key="item.defaultSpecsId">
<view class="product-shop" v-if="showShop">
{{item.supplierName||item.sellerName||item.platformName}}
</view>
<view class="product-content" :style="{paddingBottom: showAddress?'0':'30rpx'}">
<view style="display: flex; align-items: center;" @click="onDetail(item)">
<view class="left">
<image v-if="item.imageUrl != undefined" class="image" mode="aspectFill"
:src="item.imageUrl[0]">
</image>
<image v-else class="image" mode="aspectFill" src="/static/none.jpg"></image>
<view class="type">{{item.deliveryWayName}}</view>
</view>
<view class="right">
<view class="detail">
<view class="name">{{item.name}}({{item.availableCount}}{{item.productVo.unit}})</view>
<view class="text"
style="display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;overflow: hidden;text-overflow: ellipsis;">
{{$t('index.card-num')}}{{item.productVo.brandNumber }} |
{{$t('index.factory')}}{{item.productVo.manufacturer}} |
{{$t('index.spec')}}{{item.productVo.varieties}}
</view>
</view>
<view class="btn-box" v-if="operate==true">
<view class="price-view">
<text class="price">{{item.priceStr | transformPrice}}</text>
<text class="unit"
v-if="item.priceStr !== '注册可见' && item.priceStr !== 'null'">{{$t('index.yuan')}}/{{item.productVo.unit}}</text>
</view>
<view class="operate">
<view class="cart"
:class="(item.availableCount > 0 && item.isInvalid == 'F' && item.priceStr && item.priceStr !== 'null') ? 'valid' : 'disabled'"
@click.stop="addCart(item)">
<image :src="web('icon_cart_add.png')" mode="aspectFit"></image>
</view>
<view class="buy"
:class="(item.availableCount > 0 && item.isInvalid == 'F' && item.priceStr && item.priceStr !== 'null' ) ? 'valid' : 'disabled'"
@click.stop="buyNow(item)">{{$t('index.buy-now')}}</view>
</view>
</view>
</view>
</view>
<view class="product-address" v-if="showAddress ">
<text>{{$t('index.delivery-from')}}</text>
<text style="color:#333;">{{ item.warehouseName}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* 自营商城模块
* @description 标题栏
* @property {Array} list 商品集合
*/
import VueI18n from 'vue-i18n'
import messages from '@/locale/index.js'
import {
web
} from '@/utils/util.js'
let i18nConfig = {
locale: uni.getLocale(),
messages
}
const i18n = new VueI18n(i18nConfig)
export default {
name: 'shopingMall',
props: {
list: {
type: Array,
default: []
},
operate: {
type: Boolean,
default: true
},
showShop: {
type: Boolean,
default: false
},
showAddress: {
type: Boolean,
default: false
}
},
data() {
return {}
},
filters: {
transformPrice(str) {
if (str == 'null' || str == undefined) {
return i18n.t('index.price-expire')
} else {
let price = str.match(/^\d+(?:\.\d{0,2})?/, '')?.[0] || str // 两位小数
return price.replace(/(?:\.0*|(\.\d+?)0+)$/, '$1') // 去除最后的0
}
}
},
watch: {
},
methods: {
web(name) {
return web(name)
},
addCart(item) {
if (item.priceStr == 'null') return
this.$emit('addCar', item)
},
buyNow(item) {
if (item.priceStr == 'null') return
this.$emit('buyNow', item)
},
onDetail(item) {
uni.navigateTo({
url: `/pages/product/index?id=${item.id}&platformType=${item.platformType}`
});
// this.mixinCheckLogin().then(()=> {
// uni.navigateTo({
// url: `/pages/product/index?id=${id}`
// });
// }).catch(()=> {
// uni.navigateTo({
// url: `/pages/login/index?url=${encodeURIComponent(JSON.stringify('/pages/home/index'))}`
// });
// })
}
}
}
</script>
<style lang="scss">
.product-list {
margin-top: 30rpx;
.product-shop {
padding-left: 30rpx;
color: #697077;
height: 72rpx;
line-height: 72rpx;
background: #f7f9fa;
margin-bottom: 20rpx;
}
.product-content {
display: flex;
flex-direction: column;
background: #fff;
padding: 15px 10px;
.left {
display: flex;
position: relative;
.image {
width: 98px;
height: 98px;
}
.type {
position: absolute;
top: 0;
left: 0;
height: 24px;
width: 40px;
text-align: center;
background-color: #FFEEEE;
font-size: 12px;
color: #B60001;
text-align: center;
line-height: 24px;
}
}
.right {
padding-left: 12px;
width: 430rpx;
.detail {
display: flex;
flex-direction: column;
height: 70px;
.name {
word-break: break-all;
font-size: 30rpx;
font-weight: 500;
color: #222;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.text {
font-size: 12px;
color: #99A0AF;
margin-top: 10rpx;
word-break: break-all;
}
}
}
.btn-box {
display: flex;
align-items: center;
height: 28px;
position: relative;
font-size: 28rpx;
.price-view {
display: flex;
flex-grow: 1;
.price {
color: #B60001;
font-size: 40rpx;
line-height: 1;
}
.unit {
color: #B60001;
font-size: 12px;
margin-left: 3px;
white-space: nowrap;
}
}
.operate {
display: flex;
.cart {
width: 28px;
height: 28px;
line-height: 28px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
background: #FFEEEE;
image {
width: 20px;
height: 20px;
}
&.valid {
color: #F36E03;
}
&.disabled {
color: #bcbec2;
}
}
.buy {
color: #fff;
width: 80px;
height: 28px;
line-height: 28px;
background: #B60001;
text-align: center;
margin-left: 10px;
&.valid {
color: #fff;
}
&.disabled {
color: #bcbec2;
}
}
}
}
.product-address {
margin-top: 30rpx;
height: 80rpx;
line-height: 80rpx;
color: #999;
font-size: 26rpx;
border-top: 1px solid #f2f2f2;
}
}
}
</style>
\ No newline at end of file
<template>
<view class="condition-box">
<view class="search-box">
<image :src="icon" class="icon"></image>
<input class="uni-input" :value="searchValue" confirm-type="search" @confirm="onSearch" @input="onInput"
:placeholder="placeholder" @keyup.enter.native="onSearch" placeholder-style="color:#B9B9B9" />
</view>
<view class="screen-box" @click="onScreen">
<image class="image" mode="aspectFill" :src="web('shaixuan.png')"></image>
</view>
</view>
</template>
<script>
/**
* 自营商城模块
* @description 标题栏
* @property {String} placeholder 搜索框placeholder
*/
import {
web
} from '@/utils/util.js'
export default {
props: {
placeholder: {
type: String,
default: '请输入'
}
},
data() {
return {
searchValue: '',
icon: web('icon_search.png')
}
},
watch: {
},
methods: {
web(name) {
return web(name)
},
onInput({
detail
}) {
this.searchValue = detail.value
},
onSearch() {
this.$emit('search', this.searchValue)
},
onScreen() {
this.$emit('screen')
}
}
}
</script>
<style lang="scss">
.condition-box {
display: flex;
align-items: center;
.search-box {
flex: auto;
position: relative;
.uni-input {
font-size: 14px;
color: #333;
height: 88rpx;
line-height: 66rpx;
border-radius: 12rpx;
padding-left: 42px;
padding-right: 10px;
background: #F3F3F3;
}
.icon {
position: absolute;
left: 10px;
top: 10px;
width: 48rpx;
height: 48rpx;
z-index: 1;
}
}
.screen-box {
flex: none;
height: 100%;
display: flex;
align-items: center;
margin-left: 30rpx;
.text {
font-size: 28rpx;
color: #99A0AF;
}
.image {
width: 48rpx;
height: 48rpx;
margin-left: 5px;
}
}
}
</style>
\ No newline at end of file
<template>
<view class="stepper-box">
<view class="reduce" :style="{'height': height + 'px'}" :class="{'disabled': priceValue <= min || disabled}" @click.stop="onReduce"></view>
<input class="uni-input" :style="{'width': width + 'px','height': height + 'px'}" :class="{'disabled': disabled}" :disabled="disabled" @click.stop @input="onInput"
v-model="priceValue" type="digit" />
<view class="plus" :style="{'height': height + 'px'}" :class="{'disabled': priceValue >= maxNumber || disabled}" @click.stop="onPlus"></view>
</view>
</template>
<script>
/**
* 步进器
* @description 步进器
* @property {Number}
*/
import {
debounce
} from '@/utils/util.js'
let timer = null;
export default {
props: {
value: {
type: Number,
default: 1
},
digit: {
type: Number,
default: 4
},
min: {
type: [Number, String, undefined],
default: 0.001
},
max: {
type: [Number, String, undefined],
default: Number.MAX_SAFE_INTEGER
},
disabled: {
type: Boolean,
default: false
},
item: {
type: Object
},
height: {
type: [Number, String],
default: 26
},
width: {
type: [Number, String],
default: 44
}
},
watch: {
value: {
handler(newV) {
this.priceValue = Number(newV)
},
immediate: true
}
},
data() {
return {
priceValue: 1
}
},
computed: {
maxNumber() {
let newVal = ''
if (['string', 'number'].includes(typeof this.max) && this.max !== '' && !isNaN(Number(this.max))) {
newVal = Number(this.max)
} else {
newVal = Number.MAX_SAFE_INTEGER
}
return newVal
}
},
methods: {
onInput: debounce(function(e) {
const {
value
} = e.detail || {
value: 1
}
let formatted = String(value).replace(/[^0-9.]/g, '')
const pair = formatted.split('.');
if (formatted.indexOf('.') !== -1) {
formatted = `${pair[0]}.${pair[1].slice(0, 4)}`
}
let priceMin = Number(this.min) || 0.0001
formatted = Math.max(Math.min(this.maxNumber, formatted), priceMin)
this.priceValue = formatted
const digitValue = parseFloat(Number(formatted).toFixed(this.digit))
this.$emit('input', digitValue, this.item)
}, 1000),
// 减少数量
onReduce() {
if (this.priceValue <= this.min || this.disabled) return
let number = this.priceValue > (this.min + 1) ? (this.priceValue - 1).toFixed(4) : this.min
this.priceValue = Math.floor(Number(number))
if (timer) {
clearTimeout(timer)
timer = null
}
let that = this
timer = setTimeout(() => {
const digitValue = parseFloat(Number(number).toFixed(this.digit))
this.$emit('reduce', digitValue, that.item)
clearTimeout(timer)
timer = null
}, 300)
},
// 增加数量
onPlus() {
if (this.priceValue >= this.maxNumber || this.disabled) return
let number = this.priceValue > (this.maxNumber - 1) ? this.maxNumber : (this.priceValue + 1).toFixed(4)
this.priceValue = Number(number)
if (timer) {
clearTimeout(timer)
timer = null
}
let that = this
timer = setTimeout(() => {
const digitValue = parseFloat(Number(number).toFixed(this.digit))
this.$emit('plus', digitValue, that.item)
clearTimeout(timer)
timer = null
}, 300)
}
}
}
</script>
<style lang="scss">
.stepper-box {
display: inline-flex;
align-self: flex-end;
.reduce {
flex: none;
box-sizing: border-box;
width: 32px;
border: 1rpx solid #D5E2F3;
border-right: 1rpx solid #D5E2F3;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
position: relative;
&.disabled {
background-color: #f5f5f5;
}
&::after {
content: " ";
position: absolute;
top: 50%;
left: 12px;
width: 8px;
height: 0;
border-top: 1px solid #D5E2F3;
}
}
.uni-input {
flex: auto;
box-sizing: border-box;
text-align: center;
font-size: 12px;
color: #B60001;
border-top: 1rpx solid #D5E2F3;
border-bottom: 1rpx solid #D5E2F3;
&.disabled {
color: #D5E2F3;
background-color: #f5f5f5;
}
}
.plus {
flex: none;
box-sizing: border-box;
width: 32px;
border: 1rpx solid #D5E2F3;
border-left: 1rpx solid #D5E2F3;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
position: relative;
&.disabled {
background-color: #f5f5f5;
}
&::before {
content: " ";
position: absolute;
top: 50%;
left: 12px;
width: 8px;
height: 0;
border-top: 1px solid #D5E2F3;
}
&::after {
content: " ";
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%);
width: 0;
height: 8px;
border-right: 1px solid #D5E2F3;
}
}
}
</style>
\ No newline at end of file
<template>
<view class="uni-section">
<view class="uni-section-header" nvue>
<view v-if="type" class="uni-section__head">
<view :class="type" class="uni-section__head-tag"/>
</view>
<view class="uni-section__content">
<text :class="{'distraction':!subTitle}" :style="{color:color}" class="uni-section__content-title">{{ title }}</text>
<text v-if="subTitle" class="uni-section__content-sub">{{ subTitle }}</text>
</view>
</view>
<view :style="{padding: padding ? '10px' : ''}">
<slot/>
</view>
</view>
</template>
<script>
/**
* Section 标题栏
* @description 标题栏
* @property {String} type = [line|circle] 标题装饰类型
* @value line 竖线
* @value circle 圆形
* @property {String} title 主标题
* @property {String} subTitle 副标题
*/
export default {
name: 'UniSection',
emits:['click'],
props: {
type: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
color:{
type: String,
default: '#333'
},
subTitle: {
type: String,
default: ''
},
padding: {
type: Boolean,
default: false
}
},
data() {
return {}
},
watch: {
title(newVal) {
if (uni.report && newVal !== '') {
uni.report('title', newVal)
}
}
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" >
$uni-primary: #2979ff !default;
.uni-section {
background-color: #fff;
// overflow: hidden;
margin-top: 10px;
}
.uni-section-header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 12px 10px;
// height: 50px;
font-weight: normal;
}
.uni-section__head {
flex-direction: row;
justify-content: center;
align-items: center;
margin-right: 10px;
}
.line {
height: 12px;
background-color: $uni-primary;
border-radius: 10px;
width: 4px;
}
.circle {
width: 8px;
height: 8px;
border-top-right-radius: 50px;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
background-color: $uni-primary;
}
.uni-section__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
color: #333;
}
.uni-section__content-title {
font-size: 14px;
color: $uni-primary;
}
.distraction {
flex-direction: row;
align-items: center;
}
.uni-section__content-sub {
font-size: 12px;
color: #999;
line-height: 16px;
margin-top: 2px;
}
</style>
<template>
<view class="box" v-if="SHOW_TOP">
<view class="arrow" :style="{ marginRight: marRight + 'px', marginTop: marTop + 'px' }"></view>
<view class="body">
<view class="textContent">{{ text }}</view>
<view class="split-line"></view>
<view class="cancle_btn" @click="okHandler"><image src="../../static/cancle.svg" mode=""></image></view>
</view>
</view>
</template>
<script>
const STORAGE_KEY_ONE = 'ADD-MYAPP-KEY-ONE';
export default {
data() {
return {
SHOW_TOP: false,
SHOW_TOP_key: 1,
marRight: 66,
marTop: 0
};
},
props: {
text: {
type: String,
default: '添加到我的小程序'
},
isCustom: { //是否开启了自定义头部
type: Boolean,
default: false
}
},
onReady() {
this.initTips();
},
methods: {
initTips: function() {
// 判断是否已经显示过
let cacheOne = uni.getStorageSync(STORAGE_KEY_ONE);
const now = +new Date();
// 校验缓存数据 以及缓存时间是否过期(关闭后缓存一个月 一个月后重新提示用户)
if (cacheOne && now - cacheOne < 30 * 24 * 3600000) return;
// 处理根据系统信息处理位移箭头位置(重点)
let systemInfo = wx.getSystemInfoSync();
let client = wx.getMenuButtonBoundingClientRect();
if (systemInfo && client) {
this.marRight = systemInfo.screenWidth - client.left - 28;
if (this.isCustom) {
this.marTop = client.bottom + client.top - systemInfo.statusBarHeight;
}
}
// 没显示过,则进行展示
this.SHOW_TOP = true;
let duration = setTimeout(()=> {
if(this.SHOW_TOP) {
this.okHandler()
clearTimeout(duration)
}
}, 10000)
},
okHandler: function() {
const storage_key = this.SHOW_TOP_key;
let key = STORAGE_KEY_ONE;
this.SHOW_TOP = false;
uni.setStorage({
key,
data: +new Date()
});
}
}
};
</script>
<style scoped>
.box {
position: fixed;
top: 0;
/* left: 0; */
right: 0;
z-index: 10073;
display: flex;
justify-content: flex-end;
align-items: flex-end;
flex-direction: column;
width: 600rpx;
}
.arrow {
width: 0;
height: 0;
margin-right: 120rpx;
border-width: 10rpx;
border-style: solid;
border-color: transparent transparent rgba(0, 0, 0, 0.7) transparent;
}
.body {
background-color: rgba(0, 0, 0, 0.7);
/* box-shadow: 0 10rpx 20rpx -10rpx #34b5e2; */
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
height: 70rpx;
padding: 0 18rpx 0 30rpx;
margin-right: 60rpx;
}
.textContent {
color: #fff;
font-size: 26rpx;
font-weight: 400;
/* padding: 0 10rpx; */
}
.split-line {
padding: 0 20rpx;
height: 100%;
position: relative;
}
.split-line:after {
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 2rpx;
height: 40rpx;
background: #a6a6a6;
}
.cancle_btn {
display: flex;
justify-content: center;
}
.cancle_btn image {
width: 22rpx;
height: 22rpx;
}
</style>
差异被折叠。
import Request from '@/utils/luch-request/luch-request/index.js'
import serverConfig from './server_config.js'
const http = new Request()
import VueI18n from 'vue-i18n'
import messages from '@/locale/index.js'
let i18nConfig = {
locale: uni.getLocale(),
messages
}
const i18n = new VueI18n(i18nConfig)
http.setConfig((config) => {
/* config 为默认全局配置*/
config.baseURL = serverConfig.baseURL;
config.header = {
'Content-Type': 'application/json;charset=UTF-8',
'platform_name': serverConfig.platform_name,
'platform_short_code': serverConfig.platform_short_code
}
let platformCode = uni.getStorageSync('platform_code');
if (platformCode == '') {
platformCode = 'P00001'
}
config.header['platform_code'] = platformCode
return config
})
//请求前拦截
let loginPopupNum = 0;
// let isTokenFlase = 0
http.interceptors.request.use((config) => { // 可使用async await 做异步操作
config.header = {
...config.header,
}
//获取存储的token
const token = uni.getStorageSync('token');
config.header['X-Token'] = token;
// 根据custom参数中配置的是否需要loading
if (config.custom.load) {
loginPopupNum++
uni.showLoading({
title: i18n.t('index.loading')
});
}
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
})
// 请求后拦截器
http.interceptors.response.use((response) => {
setTimeout(() => {
loginPopupNum--
if (loginPopupNum <= 0) {
uni.hideLoading();
}
}, 30)
if (response.data.success) {
return response.data
} else {
setTimeout(() => {
uni.showToast({
title: response.data.content,
icon: 'none',
duration: 2000
})
}, 60)
return Promise.reject(response)
}
}, (response) => {
setTimeout(() => {
loginPopupNum--
if (loginPopupNum <= 0) {
uni.hideLoading();
}
}, 30)
//未登录时清空缓存跳转
if (response.statusCode == 401) {
// uni.clearStorageSync()
// uni.showToast({
// title: '登录失效',
// icon: 'error',
// duration: 2000
// })
// setTimeout(()=> {
// uni.navigateTo({
// url: `/pages/login/index?url=${encodeURIComponent(JSON.stringify('/pages/home/index'))}`
// });
// }, 1500)
// if(isTokenFlase === 0) {
// isTokenFlase += 1
let token = uni.getStorageSync('token')
if (token) {
return new Promise((gloabResolve, gloabReject) => {
http.get('/jwt/refreshCustomerWxToken', {
params: {
token
}
}).then(({
content
}) => {
uni.setStorageSync('token', content.body.token);
const config = response.config
if (config.method === "POST") {
let cb = new Promise((resolve, reject) => {
http.post(config.url, {
...config.params
}, {
custom: config.custom
})
.then(res => {
resolve(res)
})
.catch(err => {
reject(err)
})
})
gloabResolve(cb)
}
if (config.method === "GET") {
let cb = new Promise((resolve, reject) => {
http.get(config.url, {
...config.params
}, {
custom: config.custom
})
.then(res => {
resolve(res)
})
.catch(err => {
reject(err)
})
})
gloabResolve(cb)
}
}).catch(err => {
gloabReject(err)
})
})
} else {
uni.showToast({
title: '请登录',
icon: 'error',
duration: 2000
})
}
// }
} else {
return Promise.reject(response)
}
})
export const setConfig = (platCode) => {
http.setConfig((config) => {
/* config 为默认全局配置*/
config.header['platform_code'] = platCode
return config
})
}
export {
http
}
\ No newline at end of file
/***
* 接口参数
*/
const serverConfig = {
baseURL: "http://116.148.227.177:8760",
// baseURL: "http://www.supew.com/",
/* 根域名 */
// baseURL: "http://114.67.111.37:8001", /* 根域名 */
// baseURL:'http://192.168.0.112:8760',
platform_code: 'P00001',
platform_name: encodeURI('中国台州直集采中心'),
platform_short_code: 'P00001'
}
export default serverConfig
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
差异被折叠。
import en from './en.json'
import zhHans from './zh-Hans.json'
export default {
en,
'zh-Hans': zhHans
}
\ No newline at end of file
差异被折叠。
import messages from './locale/index.js'
let i18nConfig = {
locale: uni.getStorageSync('locate') || uni.getLocale(),
messages
}
// #ifndef VUE3
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const i18n = new VueI18n(i18nConfig)
import App from './App'
let mixinLogin = require('@/utils/mixin-login.js');
Vue.mixin(mixinLogin);
// import store from './store' //引入vuex
// Vue.prototype.$store = store
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
i18n,
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif
\ No newline at end of file
{
"name" : "b2b-seller",
"appid" : "__UNI__52880D1",
"description" : "一款用于提供企业与企业之间通过互联网进行产品、服务及信息的交换的专业app,好看又好用",
"versionName" : "1.0.1",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
/* 5+App特有相关 */
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"nvueStyleCompiler" : "uni-app",
"modules" : {
"Camera" : {},
"Barcode" : {}
},
/* 模块配置 */
"distribute" : {
/* 应用发布信息 */
"android" : {
/* android打包配置 */
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {
"dSYMs" : false
},
/* ios打包配置 */
"sdkConfigs" : {
"ad" : {},
"share" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
},
"splashscreen" : {
"androidStyle" : "common"
}
},
"nativePlugins" : {
"lemonjk-FileSelect" : {
"appid_android" : "com.taizhou.b2b_seller",
"__plugin_info__" : {
"name" : "FileSelect",
"description" : "文件选取插件",
"platforms" : "Android,iOS",
"url" : "",
"android_package_name" : "com.taizhou.b2b_seller",
"ios_bundle_id" : "com.taizhou.b2b_seller",
"isCloud" : false,
"bought" : -1,
"pid" : "",
"parameters" : {
"appid_android" : {
"des" : "请填写你当前应用的包名,必需填写,否则可能无法使用。(在菜单中->发行->原生App-云打包中可以查看包名信息)",
"key" : "",
"value" : ""
}
}
}
}
}
},
/* SDK配置 */
"quickapp" : {},
/* 快应用特有相关 */
"mp-weixin" : {
/* 小程序特有相关 */
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"vueVersion" : "2",
"locale" : "zh-Hans",
"fallbackLocale" : "zh-Hans",
"quickapp-webview" : {
"package" : "com.taizhou.b2b"
}
}
{
"name": "FileSelect",
"id": "lemonjk-FileSelect",
"version": "4.0.5",
"description": "文件选取插件",
"_dp_type": "nativeplugin",
"_dp_nativeplugin": {
"android": {
"plugins": [{
"type": "module",
"name": "lemonjk-FileSelect",
"class": "com.lemonjk.fileselect.FileSelectModule"
}],
"compileOptions": {
"sourceCompatibility": "1.8",
"targetCompatibility": "1.8"
},
"dependencies": [
],
"integrateType": "aar",
"permissions": [
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"/>"
],
"parameters": {
"appid_android": {
"des": "请填写你当前应用的包名,必需填写,否则可能无法使用。(在菜单中->发行->原生App-云打包中可以查看包名信息)",
"placeholder": "LEMONJK_APPID"
}
},
"abis": [
"armeabi-v7a",
"arm64-v8a"
],
"minSdkVersion": 21
},
"ios": {
"plugins": [
{
"type": "module",
"name": "lemonjk-FileSelect",
"class": "LemonFileSelectModule"
}
],
"integrateType": "framework",
"deploymentTarget": "11.0"
}
}
}
\ No newline at end of file
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论