master
Lee1203 2022-07-31 10:14:22 +08:00
commit b17b1c1dad
231 changed files with 32855 additions and 0 deletions

16
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,16 @@
{ // launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

63
App.vue Normal file
View File

@ -0,0 +1,63 @@
<script>
export default {
globalData:{
projectname:'', //
lat:'', //
lng:'' ,//
hostapi:'https://laonon.scdxtc.cn' //
},
// show
onLaunch: function() {
uni.login({
success: (res) => {
uni.request({
url: this.globalData.hostapi +'/api/user/login',
data:{code:res.code},
success: (result) => {
console.log(result,'登录信息')
if(result.data.code == 0) {
uni.setStorageSync('userId',result.data.account_id);
uni.setStorageSync('token',result.data.data.token);//token
uni.setStorageSync('openid',result.data.data.openid);//openid
uni.setStorageSync('expire',result.data.data.expire);//
uni.setStorageSync('phone_active',result.data.data.phone_active);//
uni.setStorageSync('is_active',result.data.data.is_active);//
uni.setStorageSync('invite_code',result.data.data.invite_code);//
}
}
})
}
})
},
onShow: function() {
},
onHide: function() {
},
methods:{
}
};
</script>
<style>
/* 阿里巴巴矢量图标库 start */
@import url("./commons/icon-font.css");
/* 阿里巴巴矢量图标库 end */
/* 项目基础样式 start */
@import url("./commons/base.css");
/* 项目基础样式 end */
/* 项目页面样式 start */
@import url("./commons/style.css");
/* 项目页面样式 end */
/* 动画样式 start */
@import url("./commons/animate.min.css");
/* 动画样式 end */
@import url("./commons/loading.css");
</style>

12
commons/animate.min.css vendored Normal file

File diff suppressed because one or more lines are too long

177
commons/base.css Normal file
View File

@ -0,0 +1,177 @@
/* flex布局 */
.flex {display: flex;}
/* 盒模型 */
.border-box{box-sizing: border-box;}
/* 背景颜色 */
.background-white{background-color: #ffffff;}
.background-orange{background-color: #febf00;}
.background-grey{background-color: #484848;}
/* 圆角 */
.radius10{border-radius: 10rpx;}
.radius15{border-radius: 15rpx;}
.radius20{border-radius: 20rpx;}
.radius25{border-radius: 25rpx;}
.radius30{border-radius: 30rpx;}
.radius35{border-radius: 35rpx;}
.radius40{border-radius: 40rpx;}
.radius100{border-radius: 100%;}
/* 外边距 */
.mar-sxc10{margin: 10rpx auto;}
.mar-sxc15{margin: 15rpx auto;}
.mar-sxc20{margin: 20rpx auto;}
.mar-sxc25{margin: 25rpx auto;}
.mar-sxc30{margin: 30rpx auto;}
.mar-sx10{margin: 10rpx 0;}
.mar-sx15{margin: 15rpx 0;}
.mar-sx20{margin: 20rpx 0;}
.mar-sx25{margin: 25rpx 0;}
.mar-sx30{margin: 30rpx 0;}
.mar-zy10{margin: 0 10rpx;}
.mar-zy15{margin: 0 15rpx;}
.mar-zy20{margin: 0 20rpx;}
.mar-zy25{margin: 0 25rpx;}
.mar-zy30{margin: 0 30rpx;}
.mar-s10{margin-top: 10rpx;}
.mar-s15{margin-top: 15rpx;}
.mar-s20{margin-top: 20rpx;}
.mar-s25{margin-top: 25rpx;}
.mar-s30{margin-top: 30rpx;}
.mar-s35{margin-top: 35rpx;}
.mar-s40{margin-top: 40rpx;}
.mar-s50{margin-top: 50rpx;}
.mar-s60{margin-top: 60rpx;}
.mar-s70{margin-top: 70rpx;}
.mar-s80{margin-top: 80rpx;}
.mar-x10{margin-bottom: 10rpx;}
.mar-x15{margin-bottom: 15rpx;}
.mar-x20{margin-bottom: 20rpx;}
.mar-x25{margin-bottom: 25rpx;}
.mar-x30{margin-bottom: 30rpx;}
.mar-x35{margin-bottom: 35rpx;}
.mar-x40{margin-bottom: 40rpx;}
.mar-x50{margin-bottom: 50rpx;}
.mar-x60{margin-bottom: 60rpx;}
.mar-x70{margin-bottom: 70rpx;}
.mar-x80{margin-bottom: 80rpx;}
/* 内边距 */
.pad-all10{padding: 10rpx;}
.pad-all15{padding: 15rpx;}
.pad-all20{padding: 20rpx;}
.pad-all25{padding: 25rpx;}
.pad-all30{padding: 30rpx;}
.pad-all35{padding: 35rpx;}
.pad-all40{padding: 40rpx;}
.pad-sx10{padding: 10rpx 0;}
.pad-sx15{padding: 15rpx 0;}
.pad-sx20{padding: 20rpx 0;}
.pad-sx25{padding: 25rpx 0;}
.pad-sx30{padding: 30rpx 0;}
.pad-sx35{padding: 35rpx 0;}
.pad-sx40{padding: 40rpx 0;}
.pad-zy10{padding: 0 10rpx;}
.pad-zy15{padding: 0 15rpx;}
.pad-zy20{padding: 0 20rpx;}
.pad-zy25{padding: 0 25rpx;}
.pad-zy30{padding: 0 30rpx;}
.pad-zy35{padding: 0 35rpx;}
.pad-zy40{padding: 0 40rpx;}
.pad-x130{padding-bottom: 130rpx;}
.pad-x140{padding-bottom: 140rpx;}
.pad-x150{padding-bottom: 150rpx;}
.pad-x160{padding-bottom: 160rpx;}
.pad-x170{padding-bottom: 170rpx;}
.pad-x180{padding-bottom: 180rpx;}
.pad-x190{padding-bottom: 190rpx;}
/* 字体 */
.font18{ font-size: 24rpx;}
.font20{ font-size: 24rpx;}
.font24{ font-size: 24rpx;}
.font26{ font-size: 26rpx;}
.font28{ font-size: 28rpx;}
.font30{ font-size: 30rpx;}
.font32{ font-size: 32rpx;}
.font34{ font-size: 34rpx;}
.font36{ font-size: 36rpx;}
.font38{ font-size: 38rpx;}
.font40{ font-size: 40rpx;}
.font42{ font-size: 42rpx;}
.font44{ font-size: 44rpx;}
.font46{ font-size: 46rpx;}
.font48{ font-size: 48rpx;}
.font60{ font-size: 60rpx;}
.color-ff{ color: #ffffff;}
.color-00{ color: #000000;}
.color-48{ color: #484848;}
.color-66{ color: #666666;}
.color-99{ color: #999999;}
.color-orange{color: #febf00;}
.color-red{ color: #dd062f;}
.color-8c{ color: #8c8c9b;}
/* 文字行数 */
.clips1{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 1;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips2{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips3{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips4{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 4;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips5{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 5;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips6{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 6;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips7{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 7;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips8{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 8;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips9{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 9;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
.clips10{display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 10;overflow: hidden;text-overflow: ellipsis;word-wrap: break-word;word-break:break-all;}
image{
/* 照顾低版本浏览器 如果图片外面包含了链接会有边框的问题 */
border: 0;
/* 取消图片底侧有空白缝隙的问题 ① */
vertical-align: middle;
/* 取消图片底侧有空白缝隙的问题 ② */
object-fit: cover;
}
/* 去除滚动条 */
scroll-view ::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
/* 圆圈中间一个原点 start */
.mo-item {
width: 30rpx;
height: 30rpx;
border-radius: 100%;
border: 2rpx solid #000000;
box-sizing: border-box;
}
.active-item{
position: relative;
display: flex;
justify-content: center;
align-items: center;
border: 2rpx solid #FF0000;
}
.active-item::before{
content: '';
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 20rpx;
height: 20rpx;
border-radius: 100%;
background-color: #FF0000;
}

155
commons/icon-font.css Normal file
View File

@ -0,0 +1,155 @@
@font-face {
font-family: "iconfont"; /* Project id 3180711 */
src: url('https://at.alicdn.com/t/font_3180711_atv5gkgm4w4.woff2?t=1651830764889') format('woff2'),
url('https://at.alicdn.com/t/font_3180711_atv5gkgm4w4.woff?t=1651830764889') format('woff'),
url('https://at.alicdn.com/t/font_3180711_atv5gkgm4w4.ttf?t=1651830764889') format('truetype');
}
.icon {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-del:before {
content: "\e718";
}
.icon-cut:before {
content: "\e609";
}
.icon-add:before {
content: "\e60a";
}
.icon-add-picture05:before {
content: "\e639";
}
.icon-add-picture04:before {
content: "\e636";
}
.icon-add-picture03:before {
content: "\e642";
}
.icon-add-picture02:before {
content: "\e8bc";
}
.icon-add-picture01:before {
content: "\e62c";
}
.icon-sandian:before {
content: "\e769";
}
.icon-nothing-collection:before {
content: "\e610";
}
.icon-nothing-more:before {
content: "\e624";
}
.icon-nothing-data:before {
content: "\e60c";
}
.icon-address-check:before {
content: "\e6c2";
}
.icon-address-unchecked:before {
content: "\e623";
}
.icon-navigate-now:before {
content: "\e640";
}
.icon-send-goods:before {
content: "\e601";
}
.icon-payment:before {
content: "\e602";
}
.icon-finish:before {
content: "\e63f";
}
.icon-take:before {
content: "\e649";
}
.icon-refund:before {
content: "\e613";
}
.icon-customer-black:before {
content: "\ec2e";
}
.icon-customer:before {
content: "\e628";
}
.icon-check:before {
content: "\e61e";
}
.icon-del-white:before {
content: "\e61f";
}
.icon-screen:before {
content: "\e60b";
}
.icon-search:before {
content: "\e653";
}
.icon-caidan-mo:before {
content: "\e73e";
}
.icon-renwu-mo:before {
content: "\e73f";
}
.icon-shop-cart:before {
content: "\e73d";
}
.icon-caidan-active:before {
content: "\e608";
}
.icon-renwu-acitve:before {
content: "\e67c";
}
.icon-home-mo:before {
content: "\e673";
}
.icon-home-active:before {
content: "\e674";
}
.icon-return:before {
content: "\e600";
}
.icon-next:before {
content: "\e60e";
}

1054
commons/loading.css Normal file

File diff suppressed because it is too large Load Diff

1271
commons/style.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,41 @@
<template>
<view class="nothing">
<view class="nothing-box">
<image v-if="imgSrc!=''" class="nothing-img" :src="imgSrc" mode="aspectFill" lazy-load></image>
<i class="iconImg icon"
:class="['icon-nothing-more','icon-nothing-data','icon-nothing-collection'][currentType]"></i>
<view v-if="currentType!=1" class="nothing-con">{{content}}</view>
</view>
</view>
</template>
<script>
export default {
name:"nothing-page",
props:{
imgSrc:{ //
type:String,
default:''
},
content:{ //
type:String,
default:'暂无内容'
},
currentType:{ // icon
type:Number,
default: 0
}
},
data() {
return {};
}
}
</script>
<style scoped>
.nothing{position: fixed;top: 0;bottom: 0;left: 0;right: 0;display: flex;justify-content: center;align-items: center;}
.nothing-box{display: flex;justify-content: center;flex-direction: column;align-items: center;}
.nothing-box .nothing-img{width: 470rpx;height: 270rpx;}
.iconImg {font-size: 280rpx;color: #999999;}
.nothing-con{font-size: 24rpx;font-family: PingFang SC;font-weight: 500;color: #999999;}
</style>

View File

@ -0,0 +1,54 @@
<template>
<view :style="{
color: textColor,
fontSize: textFontSize,
fontWeight: `${ ifBold ? 'bold' : 0 }`,
textAlign: `${ ifCenter ? 'center' : 'left' }`,
padding: paddingStr
}">{{textStr}}</view>
</template>
<script>
export default {
name:"pitera",
props:{
//
textStr: {
type:String,
default:'-- NO MORE --'
},
//
textColor: {
type:String,
default:'#999999'
},
//
textFontSize: {
type: String,
default: '24rpx'
},
//
ifBold: {
type:Boolean,
default:false
},
//
ifCenter: {
type:Boolean,
default: true
},
//
paddingStr: {
type:String,
default:'20rpx'
}
},
data() {
return {};
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,122 @@
<template>
<view class="share-coupon pad-all20 border-box">
<view class="coupon radius100 flex" @tap="goCoupon">
<view class="icon flex">
<image src="/static/icon/icon-coupon.png" mode="widthFix"></image>
<text class="font24 color-ff">领券</text>
</view>
</view>
<view class="share radius100 flex" @tap="shareImgEv(spuId)">
<view class="icon flex">
<image src="/static/icon/icon-share.png" mode="widthFix"></image>
<text class="font24 color-ff">分享给好友</text>
</view>
</view>
</view>
</template>
<script>
import { base64ToPath } from '@/jsFile/base64-src.js';
export default {
name:'share-coupon',
props:{
spuId:{
type:Number,
default:0
}
},
data() {
return {
footBarList:[], //
shareFlag:true, //
};
},
onLoad() {
},
methods:{
//
goCoupon(){
uni.navigateTo({
url:`/pagesA/coupon/coupon?index=1`
})
},
//
shareImgEv(id){
this.$toolAll.tools.showToast('分享图生成中...','none',10000);
if(this.shareFlag){
this.shareFlag = false;
this.$requst.post('/api/spu/share-img',{spu_id:id}).then(res=>{
console.log(base64ToPath(res.data.poster),'分享图片')
base64ToPath(res.data.poster).then(path=>{
uni.hideToast();
this.$toolAll.tools.showToast('正在调起分享...');
wx.showShareImageMenu({
path: path,
success:(res=>{
this.shareFlag = true;
}),
fail:(err=>{
this.shareFlag = true;
})
})
})
})
} else {this.$toolAll.tools.showToast('请勿重复点击');}
},
}
}
</script>
<style>
.share-coupon{
width: 164rpx;
position: fixed;
right: 0;
bottom: 188rpx;
z-index: 99;
}
.coupon{
justify-content: center;
align-items: center;
width: 124rpx;
height: 124rpx;
background-color: #febf00;
box-shadow: 0 0 20rpx rgba(254,191,0,.4);
margin-bottom: 30rpx;
}
.coupon image{
width: 47rpx;
height: 47rpx;
}
.coupon text{
width: 100%;
text-align: center;
line-height: 1.2;
margin-top: 10rpx;
}
.share{
justify-content: center;
align-items: center;
width: 124rpx;
height: 124rpx;
background-color: #00b809;
box-shadow: 0 0 20rpx rgba(0,184,9,.4);
line-height: 1.6;
}
.share image{
width: 56rpx;
height: 46rpx;
}
.share text{
width: 100%;
text-align: center;
line-height: 1.2;
margin-top: 8rpx;
transform: scale(.84);
}
.coupon .icon,
.share .icon{
flex-wrap: wrap;
justify-content: center;
}
</style>

View File

@ -0,0 +1,415 @@
<template>
<view>
<!-- 全选 -->
<view class="change-all border-box background-white font26 flex" :style="{top:statusHeight+50+'px'}">
<label class="label flex" @tap="chooseAll"><radio :checked="allChoose" color="#febf00" style="transform: scale(.8);"/><text>全选</text></label>
<view class="del-cart" @tap="delShopEv"></view>
</view>
<view class="slide-list">
<view class="slide-item" v-for="(item, index) in listData" :key="index">
<view class="slide-item-li border-box background-white flex" @tap.stop="goDetail(item.spuId)">
<label class="radio" @tap.stop="chooseEv(index)"><radio :checked="item.ifcheck" color="#febf00"/></label>
<view class="shop-img radius30">
<image :src="item.image" mode="widthFix"></image>
</view>
<view class="shop-txt">
<view class="shop-txt-top">
<view class="title font30 clips1">{{item.title}}</view>
<view class="specs font24 color-66 mar-sx10 clips2">规格{{item.skuName}}</view>
</view>
<view class="shop-txt-bottom flex">
<!-- 商品价格 -->
<view class="price font30 color-red">{{item.price}}</view>
<!-- 商品数量 -->
<view class="num font24 flex">
<!-- 减数量 -->
<i class="icon icon-cut count-btn fon24 color-ff radius10 flex" @tap.stop="addCutEv(index,0)" :style="{backgroundColor: item.num==minNum || item.slide_x!=0 ? '#d3d3d3' : '#febf00'}"></i>
<!-- 实际数量 -->
<input class="input border-box radius10" type="digit" @blur="blurEv(index,$event)" @focus="focusEv(item.num)" :disabled="item.slide_x!=0" v-model="item.num">
<!-- 加数量 -->
<i class="icon icon-add count-btn fon24 color-ff radius10 flex" @tap.stop="addCutEv(index,1)" :style="{backgroundColor: item.num==maxNum || item.slide_x!=0 ? '#d3d3d3' : '#febf00'}"></i>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 提交订单 -->
<view class="pull-footer-bg background-white pad-all20 radius30 border-box">
<view class="pull-footer background-grey radius30 pad-all20 border-box flex">
<view class="price color-ff">
<view class="font36">合计{{allPrice>0?allPrice:'0'}}</view>
</view>
<view class="btn font36 color-48 radius30 flex" :style="{background: !buyNum ? '#cccccc' : '#febf00'}" @tap="submitEv">{{allPrice==0 ? '' : ''}}</view>
</view>
</view>
<view v-if="listData.length!=0 && total==listData.length"><pitera textStr="—— 到底啦 ——"></pitera></view>
<nothing-page v-if="!ifLoading && !listData.length" content="您的购物车,空空如也(*^▽^*)"></nothing-page>
</view>
</template>
<script>
import { mapState,mapGetters,mapMutations } from 'vuex'//mapState
import pitera from '@/components/nothing/pitera';
import {getCartInfo} from '@/jsFile/public-api.js';
export default {
components:{
pitera
},
name: 'cart-slide',
props: {
list: { //list
type: Array,
default () {
return [];
}
},
button: { //list
type: Array,
default () {
return [
// {title: '',background: '#c4c7cd'},
{title: '删除',background: 'linear-gradient(to right,#ff3771 0%,#fd5549 100%)'}
];
}
},
customB:{
type:String,
default:'0'
},
skuId:{
type:String,
default:0
}
},
data() {
return {
statusHeight:uni.getSystemInfoSync().statusBarHeight,
listData: [],
start_slide_x: 0,
btnWidth: 0,
startX: 0,
LastX: 0,
startTime: 0,
itemIndex: 0,
originalNum:0,//
maxNum:99999,//
minNum:1,//
ifLoading:true,
page:1,
size:10,
total:0,
delIds:'', //ids
};
},
computed: {
windowWidth() {
return uni.getSystemInfoSync().windowWidth;
},
//
allPrice() {
let allPrice = 0;
this.listData.forEach(item=>{
if(item.ifcheck) {
allPrice += parseFloat(item.price*item.num);
}
})
return this.$toolAll.tools.addXiaoShu(allPrice);
// return allPrice.toString();
},
//
buyNum() {
let buyNum = 0;
this.listData.forEach(item=>{
if(item.ifcheck) {
buyNum += 1;
}
})
return buyNum;
},
//
allChoose() {
let ifAll = false;
if(this.listData.length) {
let temparr = this.listData.filter(item=>{return item.ifcheck==false})
temparr.length==0 ? ifAll = true : ifAll = false;
let delTemparr = this.listData.filter(item=>{return item.ifcheck==true})
let delArr = [];
delTemparr.forEach(item=>{
delArr.push(item.id)
})
//
this.delIds = delArr.join(',');
}
return ifAll
},
...mapState({
}),
},
mounted() {
this.listData = this.list;
this.getList();
},
methods: {
//
getList(){
uni.showLoading();
this.total = 0;
let params = {
page:this.page,
size:this.size
}
this.$requst.post('/api/order/shopping-cart',params).then(res=>{
if(res.code==0){
if(uni.getStorageSync('business_code')!==''){
this.vipPrice = true;
}
this.total = res.data.total;
console.log(res,'购物车列表')
if(this.page==1) this.listData = [];
if(res.data.list.length){
res.data.list.forEach(item=>{
let obj = {
id: item.id,
spuId:item.spu.id,
skuId:item.sku_id,
coding:item.sku.coding,
image: item.spu.spu_cover,
title: item.spu.spu_name,
content: item.spu.unit,
customTitle: item.sku.custom_title,
skuName: item.sku.sku_name,
slide_x: 0,
price:item.sku.sku_price,
num:item.num,
ifcheck:this.skuId==item.sku_id ? true : false,
ifExit:true,
ifShow:true,
}
this.listData.push(obj);
})
}
}
this.ifLoading = false;
uni.hideLoading();
})
},
//
chooseAll(){
let exit = this.listData.filter(item=>item.ifcheck==false);
if(exit.length){
this.listData.forEach(item=>item.ifcheck = true);
} else {
this.listData.forEach(item=>{item.ifcheck = false});
}
},
//
submitEv(){
if(this.allPrice==0) {
//
uni.reLaunch({
url:`/pages/index/index`
})
} else {
//
let buyList = [];
this.listData.forEach(item=>{
if(item.ifcheck) {
let obj = {
sku_coding: item.coding,
num: item.num
}
buyList.push(obj);
}
})
uni.setStorageSync('buyList',buyList);
uni.navigateTo({
url:'/pages/cart/settlement'
})
}
},
//
chooseEv(index) {
this.listData[index].ifcheck = !this.listData[index].ifcheck;
},
//
addCutEv(index,num) {
if(this.listData[index].slide_x==0){
if(num) {
//
if(this.listData[index].num != this.maxNum) {
this.listData[index].num++;
}
} else {
//
if(this.listData[index].num > this.minNum) {
this.listData[index].num--;
}
}
this.$requst.post('/api/order/shopping-cart-change-num',{id:this.listData[index].id,num:this.listData[index].num}).then(res=>{
if(res.code!=0){
this.$toolAll.tools.showToast(res.msg);
}
})
}
},
//
delShopEv(){
if(this.delIds!==''){
uni.showModal({
title: '提示',
content: '是否删除选中商品?',
success: (res)=> {
if (res.confirm) {
//
this.confirmDel();
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}
},
//
confirmDel(){
this.$requst.post('/api/order/shopping-cart-del',{ids:this.delIds.toString()}).then(res=>{
if(res.code==0){
this.$toolAll.tools.showToast('删除成功');
// this.getList();
if(this.listData.length){
this.listData.forEach((item,index)=>{
if(item.ifcheck){
this.listData.splice(index,1);
}
})
}
this.$store.commit('setNum', this.listData.length);
this.totalPrice();
}else{
this.$toolAll.tools.showToast(res.msg)
}
})
},
//
totalPrice() {
let totalPrice = 0;
this.listData.forEach(item=>{
totalPrice += parseFloat(item.price*item.num);
})
totalPrice = this.$toolAll.tools.addXiaoShu(totalPrice);
this.$store.commit('setPrice', totalPrice);
},
//
goDetail(id) {
uni.navigateTo({
url:`/pagesB/shop-detail/shop-detail?id=${id}`
})
},
//
focusEv(num) {
//
this.originalNum = num;
},
//
blurEv(index,e) {
//
let currentNum = e.detail.value*1;
// 0 =
this.listData[index].num = currentNum ? currentNum > this.maxNum ? this.maxNum : currentNum : this.originalNum;
},
}
};
</script>
<style scoped>
.slide-list{
margin-top: 20rpx;
}
.slide-item-li{
align-items: center;
width: calc(100% - 40rpx);
padding: 30rpx 0;
margin: 0 auto;
border-bottom: 2rpx solid #eaeaea;
}
.slide-item-li .radio>radio{
transform: scale(.8);
margin-left: -5rpx;
}
.slide-item-li .shop-img{
width: 194rpx;
height: 194rpx;
margin: 0 24rpx 0 6rpx;
overflow: hidden;
}
.slide-item-li .shop-img image{
width: 100%;
min-height: 194rpx;
}
.slide-item-li .shop-txt{
width: calc(100% - 264rpx);
}
.slide-item-li .shop-txt-top{
min-height: 134rpx;
}
.slide-item-li .shop-txt-top .title{
line-height: 1.5;
}
.slide-item-li .shop-txt-top .specs{
line-height: 1.5;
}
.slide-item-li .shop-txt-bottom{
justify-content: space-between;
align-items: center;
width: 100%;
height: 50rpx;
}
.slide-item-li .shop-txt-bottom .price{
line-height: 1.5;
}
.slide-item-li .shop-txt-bottom .num{
justify-content: space-between;
align-items: center;
width: 170rpx;
}
.slide-item-li .shop-txt-bottom .num>.count-btn{
justify-content: center;
align-items: center;
width: 40rpx;
height: 40rpx;
}
.slide-item-li .shop-txt-bottom .num>.input{
width: 78rpx;
height: 40rpx;
border: 2rpx solid #d3d3d3;
text-align: center;
}
.change-all{
justify-content: space-between;
align-items: center;
width: calc(100% - 40rpx);
height: 80rpx;
margin: 0 auto;
border-bottom: 2rpx solid #eaeaea;
position: sticky;
left: 0;
z-index: 9;
}
.change-all .label{
align-items: center;
margin-left: -5rpx;
}
</style>

View File

@ -0,0 +1,175 @@
<template>
<view class="status-box" :style="{marginBottom: marginBottom}">
<!-- 网络电量栏 -->
<view :style="{height: statusBarHeight+'px',background: backgroudColor}"></view>
<!-- 头部状态栏 -->
<view class="status-nav flex" :style="{background: backgroudColor,height:navBarHeight}">
<!-- 返回键 -->
<view class="left-box flex" @tap="backEv" v-if="ifReturn" :style="{height: navBarHeight}">
<slot name="leftcontent">
<i class="icon icon-return" style="font-size: 38rpx;" :style="{color: returnColor}"></i>
</slot>
</view>
<!-- 标题 -->
<view class="tab-title" :style="{color: titleColor,justifyContent: ifCenter ? 'center' : '',padding: ifCenter ? '0px' : `${ifReturn ? '0 38' : '0 15'}px`}">
<view class="title-box" :class="['','clips1','clips2'][clipNumber*1]" :style="{maxWidth: ifCenter ? '360rpx' : '70%'}">
<!-- 有网络 -->
<view v-if="ifTitle && ifNet">{{navBarTitle}}</view>
<!-- 无网络 -->
<view v-if="!ifNet">{{netText}}<text @tap="refreshEv" style="color: #3875F6;margin-left: 20rpx;">刷新</text></view>
</view>
</view>
<!-- 右侧图标 -->
<view class="right-box flex" :style="{height: navBarHeight}">
<slot name="rightcontent"></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'status-nav',
props: {
//
backgroudColor: {
type: String,
default: '#FFFFFF'
},
//
navBarHeight: {
type: String,
default: '50px'
},
//
ifReturn: {
type: Boolean,
default: true
},
//
returnColor: {
type: String,
default: '#000000'
},
//
ifTitle: {
type: Boolean,
default: true
},
//
navBarTitle: {
type: String,
default: ''
},
//
clipNumber: {
type: String,
default: '1'
},
//
titleColor: {
type: String,
default: '#000000'
},
//
ifCenter: {
type: Boolean,
default: true
},
//
marginBottom: {
type: String,
default: '20rpx'
},
},
data() {
return {
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
ifNet: true, //
netText: '当前无网络',
netTimer: null
}
},
mounted() {
//
this.$toolAll.tools.networkStatus();
//
this.$toolAll.tools.obtainPagePath();
setTimeout(() => {
this.ifNet = uni.getStorageSync('isNet');
}, 500)
},
methods: {
//
refreshEv() {
this.netText = '正在刷新...';
let outTime = 0; //
this.netTimer = setInterval(() => {
outTime++;
this.$toolAll.tools.networkStatus();
if (uni.getStorageSync('isNet')) {
clearInterval(this.netTimer);
this.ifNet = true;
}
if (outTime == 10) {
clearInterval(this.netTimer);
this.netText = '刷新失败';
outTime = 0;
}
}, 1000)
},
//
backEv() {
uni.navigateBack({
delta: 1,
fail: () => {
uni.reLaunch({
url: '/pages/tabbar/index/index'
})
}
})
}
}
}
</script>
<style scoped>
.status-box {
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
}
.status-nav {
align-items: center;
width: 100%;
position: relative;
}
.left-box {
justify-content: center;
align-items: center;
position: absolute;
padding: 0 20rpx;
}
.right-box {
justify-content: center;
align-items: center;
position: absolute;
right: 0;
padding: 0 20rpx;
}
.tab-title {
width: 100%;
font-size: 36rpx;
display: flex;
}
.tab-title .title-box {
margin-top: -4rpx;
}
</style>

View File

@ -0,0 +1,156 @@
<template>
<view class="tabbar border-box pad-sx40 background-white pad-zy20 flex" v-if="isLoading">
<view class="content background-grey border-box color-ff flex">
<view class="nav flex" @tap="chooseFootTab(index)" v-for="(item,index) in footBarList" :key="index" v-if="current == index">
<image :style="{width:[39,32][index]+'rpx',height:[40,38][index]+'rpx'}" :src="item.iconPath" mode="widthFix"></image>
<view class="title fon24" :class="current==index ? 'active' : ''">{{item.title}}</view>
</view>
<view class="price font60">
<text>{{cartPrice>0?cartPrice:'0'}}</text>
</view>
</view>
<view class="cart background-orange font36 color-48 flex" @tap="goCart">
<text>购物车</text>
<view class="amount font26" v-if="cartNum*1 <= 99">
(<text>{{cartNum}}</text>)
</view>
<view class="amount font26" v-if="cartNum*1 > 99">
(<text>99</text>)
</view>
</view>
</view>
</template>
<script>
import {getCartInfo} from '@/jsFile/public-api.js';
import { mapState } from 'vuex'; //mapState
export default {
name:'tabbar',
props:{
//
current:{
type:String,
default:'1'
},
},
data() {
return {
footBarList:[], //
isLoading:false,
};
},
mounted() {
//
this.$toolAll.tools.obtainPagePath();
// +
const query = wx.createSelectorQuery().in(this)
query.select('.tabbar').boundingClientRect((rect) => {
this.$store.commit('footHeightEv',rect.height);
}).exec()
//
this.getTabbarList();
},
computed:{
...mapState({
cartNum: state=> state.moduleA.cartNum,
cartPrice: state=> state.moduleA.cartPrice
}),
},
methods:{
//
getTabbarList(){
this.$requst.get('/api/index/mini-program-setting').then(res=>{
if(res.code == 0){
console.log(res,'底部信息')
let tabbarArr = [];
res.data.footBar.forEach(item=>{
let obj = {
iconPath:this.$hostHttp+item.icon,
title:item.name,
}
tabbarArr.push(obj)
})
this.footBarList = tabbarArr;
//
getCartInfo();
this.isLoading = true;
}
})
},
// tabbar
chooseFootTab(index){
if(index==0){
uni.reLaunch({url:'/pages/index/index'})
}else {
if(this.$toolAll.tools.judgeAuth()) {
//
switch (index){
case 1:
uni.reLaunch({url:'/pages/my/my'})
break;
}
}
}
},
//
goCart(){
uni.navigateTo({
url:'/pages/cart/cart',
})
}
}
}
</script>
<style>
.tabbar{
justify-content: space-between;
align-items: center;
width: 100%;
padding: 20rpx 20rpx 40rpx;
position: fixed;
left: 0;
bottom: 0;
z-index: 99;
}
.content{
align-items: center;
width: 70.5%;
height: 130rpx;
padding: 22rpx 7rpx;
border-radius: 30rpx 0 0 30rpx;
}
.content .nav{
justify-content: center;
flex-wrap: wrap;
width: 144rpx;
height: 100%;
border-right: 2rpx solid #FFFFFF;
}
.nav>image{
margin-top: 7rpx;
}
.nav>.title{
width: 100%;
font-size: 24rpx;
line-height: 1.5;
text-align: center;
}
.content .price{
width: calc(100% - 144rpx);
text-indent: 36rpx;
}
.cart{
justify-content: center;
align-items: center;
width: 29.5%;
height: 130rpx;
border-radius: 0 30rpx 30rpx 0;
}
.cart>.amount{
line-height: 2;
margin-left: 10rpx;
}
.cart>.amount text{
margin: 0 4rpx;
}
</style>

201
jsFile/base64-src.js Normal file
View File

@ -0,0 +1,201 @@
function getLocalFilePath(path) {
if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf(
'_downloads') === 0) {
return path
}
if (path.indexOf('file://') === 0) {
return path
}
if (path.indexOf('/storage/emulated/0/') === 0) {
return path
}
if (path.indexOf('/') === 0) {
var localFilePath = plus.io.convertAbsoluteFileSystem(path)
if (localFilePath !== path) {
return localFilePath
} else {
path = path.substr(1)
}
}
return '_www/' + path
}
function dataUrlToBase64(str) {
var array = str.split(',')
return array[array.length - 1]
}
var index = 0
function getNewFileId() {
return Date.now() + String(index++)
}
function biggerThan(v1, v2) {
var v1Array = v1.split('.')
var v2Array = v2.split('.')
var update = false
for (var index = 0; index < v2Array.length; index++) {
var diff = v1Array[index] - v2Array[index]
if (diff !== 0) {
update = diff > 0
break
}
}
return update
}
export function pathToBase64(path) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
if (typeof FileReader === 'function') {
var xhr = new XMLHttpRequest()
xhr.open('GET', path, true)
xhr.responseType = 'blob'
xhr.onload = function() {
if (this.status === 200) {
let fileReader = new FileReader()
fileReader.onload = function(e) {
resolve(e.target.result)
}
fileReader.onerror = reject
fileReader.readAsDataURL(this.response)
}
}
xhr.onerror = reject
xhr.send()
return
}
var canvas = document.createElement('canvas')
var c2x = canvas.getContext('2d')
var img = new Image
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
c2x.drawImage(img, 0, 0)
resolve(canvas.toDataURL())
canvas.height = canvas.width = 0
}
img.onerror = reject
img.src = path
return
}
if (typeof plus === 'object') {
plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) {
entry.file(function(file) {
var fileReader = new plus.io.FileReader()
fileReader.onload = function(data) {
resolve(data.target.result)
}
fileReader.onerror = function(error) {
reject(error)
}
fileReader.readAsDataURL(file)
}, function(error) {
reject(error)
})
}, function(error) {
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
wx.getFileSystemManager().readFile({
filePath: path,
encoding: 'base64',
success: function(res) {
resolve('data:image/png;base64,' + res.data)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}
export function base64ToPath(base64) {
return new Promise(function(resolve, reject) {
if (typeof window === 'object' && 'document' in window) {
base64 = base64.split(',')
var type = base64[0].match(/:(.*?);/)[1]
var str = atob(base64[1])
var n = str.length
var array = new Uint8Array(n)
while (n--) {
array[n] = str.charCodeAt(n)
}
return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], {
type: type
})))
}
var extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/)
if (extName) {
extName = extName[1]
} else {
reject(new Error('base64 error'))
}
var fileName = getNewFileId() + '.' + extName
if (typeof plus === 'object') {
var basePath = '_doc'
var dirPath = 'uniapp_temp'
var filePath = basePath + '/' + dirPath + '/' + fileName
if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime
.innerVersion)) {
plus.io.resolveLocalFileSystemURL(basePath, function(entry) {
entry.getDirectory(dirPath, {
create: true,
exclusive: false,
}, function(entry) {
entry.getFile(fileName, {
create: true,
exclusive: false,
}, function(entry) {
entry.createWriter(function(writer) {
writer.onwrite = function() {
resolve(filePath)
}
writer.onerror = reject
writer.seek(0)
writer.writeAsBinary(dataUrlToBase64(base64))
}, reject)
}, reject)
}, reject)
}, reject)
return
}
var bitmap = new plus.nativeObj.Bitmap(fileName)
bitmap.loadBase64Data(base64, function() {
bitmap.save(filePath, {}, function() {
bitmap.clear()
resolve(filePath)
}, function(error) {
bitmap.clear()
reject(error)
})
}, function(error) {
bitmap.clear()
reject(error)
})
return
}
if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
var filePath = wx.env.USER_DATA_PATH + '/' + fileName
wx.getFileSystemManager().writeFile({
filePath: filePath,
data: dataUrlToBase64(base64),
encoding: 'base64',
success: function() {
resolve(filePath)
},
fail: function(error) {
reject(error)
}
})
return
}
reject(new Error('not support'))
})
}

18
jsFile/public-api.js Normal file
View File

@ -0,0 +1,18 @@
import requst from './requst.js';
import store from '@/store/index.js'
// 查询轮播位置
export function slidePosition(data) {
return requst.get("/api/common/slide-positions");
}
// 查询购物车信息
export function getCartInfo(){
return requst.get('/api/user/info').then(res=>{
if(res.code==0){
let cartObj = res.data.shopping_cart_info;
store.commit('setNum', cartObj.count)
store.commit('setPrice', cartObj.total_price)
}
})
}

195
jsFile/requst.js Normal file
View File

@ -0,0 +1,195 @@
// 清理所有缓存并前往登录授权页
const goLogin = () => {
uni.clearStorageSync();
uni.navigateTo({
url: '/pages/login/login'
})
}
let flag = true;
// 刷新token并跳转到当前页面
var authTimer = null;
const refreshTokenPage = () => {
clearTimeout(authTimer);
// 获取当前页面路径
let currentRoutes = getCurrentPages(); // 获取当前打开过的页面路由数组
let currentRoute = currentRoutes[currentRoutes.length - 1].route //获取当前页面路由
let currentParam = currentRoutes[currentRoutes.length - 1].options; //获取路由参数
// 拼接参数
let param = ''
for (let key in currentParam) {
param += '?' + key + '=' + currentParam[key]
}
let localRoute = '/'+ currentRoute + param;
if(localRoute !== '/pages/login/login'){
uni.login({
success: (res) => {
uni.request({
url:'https://laonon.scdxtc.cn/api/user/login',
data:{code:res.code},
success: (result) => {
if(result.data.code == 0) {
uni.setStorageSync('userId',result.data.account_id);
uni.setStorageSync('token',result.data.data.token);//缓存token
uni.setStorageSync('openid',result.data.data.openid);//缓存openid
uni.setStorageSync('expire',result.data.data.expire);//缓存失效时间(时间戳格式)
uni.setStorageSync('phone_active',result.data.data.phone_active);//是否授权手机号
uni.setStorageSync('is_active',result.data.data.is_active);//是否授权头像和昵称
uni.setStorageSync('invite_code',result.data.data.invite_code);//缓存邀请码
uni.reLaunch({ // 重新进入当前页面
url:localRoute
})
}
}
})
}
})
}
flag = true;
}
// 请求错误处理
const checkError = (e) => {
console.log('500接口错误');
// console.error("----接口错误----", e)
if (e.data) {
if (e.data.code) {
switch (Number(e.data.code)) {
case 500:
// 接口错误
console.log('500接口错误');
case 4003:
// 参数错误
console.log('4003参数错误');
break;
case 4004:
// 记录不存在
console.log('4004记录不存在');
break;
case 5001:
// xxx错误
console.log('5001xxx错误');
break;
case 5050:
// 服务器错误,请稍后重试
console.log('5050服务器错误请稍后重试');
// 调用到登录页
goLogin();
break;
case 5051:
// 未知错误
console.log('5051未知错误');
break;
case 6001:
// token验证失败或已失效
console.log('6001token验证失败或已失效');
if(flag) {
flag = false;
// 调用刷新token事件并跳转到当前页面
refreshTokenPage();
}
break;
}
}
}
}
// 封装request的(GET、POST)请求
const request = (method, url, options) => {
let methods = '';
let headers = {};
switch (method) {
case 'get':
methods = 'GET'
headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
}
break;
case 'post':
methods = 'POST'
headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
}
break;
case 'postForm':
methods = 'POST'
headers = {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
}
break;
}
return new Promise((resolve, reject) => {
uni.request({
url: `${getApp().globalData.hostapi}${url}`,
method: methods,
data: options,
header: headers,
success: res => {
console.log(`${url}返的结果===>`,res);
if (res.statusCode == 200) {
resolve(res.data);
if(res.data.code !== 0){
// 接口返回错误信息
checkError(res);
}
} else {
// 接口返回错误信息
checkError(res);
}
},
fail: e => {
// 接口请求错误
checkError(e, reject);
},
complete: rest => {
// 是否成功,都会执行
console.log(rest,100);
}
})
})
}
// 上传文件 封装请求
const uploadFile = (url, options) => {
let tempData = options || {}
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${getApp().globalData.hostapi}${url}`,
filePath: tempData.path,
name: 'image',
fileType:'image',
formData: tempData,
header: {
'Content-Type': 'multipart/form-data;charset=UTF-8',
'Authorization': 'Bearer '+uni.getStorageSync('token') || ''
},
success: res => {
if (res.statusCode == 200) {
let temp = JSON.parse(res.data)
if (temp.code == 0) {
resolve(temp)
}
}
}
});
})
}
export default {
get: (url, options) => {
return request('get', url, options)
},
// JOSN格式
post: (url, options) => {
return request('post', url, options)
},
// form-data格式
postForm: (url, options) => {
return request('postForm', url, options)
},
// 上传
upload: (url, options) => {
return uploadFile(url, options)
}
}

627
jsFile/tools.js Normal file
View File

@ -0,0 +1,627 @@
const tools = {
timer:'',
/**
* @description 埋点倒计时
*/
daoTime(){
let daoTime = uni.getStorageSync('daoTime')
if(daoTime==''){//初次判断倒计时是否为空
uni.setStorageSync('daoTime',60)//设置倒计时
daoTime = uni.getStorageSync('daoTime')
this.timer = setInterval(()=>{
uni.setStorageSync('daoTime',daoTime--)//设置倒计时
if(uni.getStorageSync('daoTime')<=0 || uni.getStorageSync('maiList').length==5){
uni.removeStorageSync('daoTime')//清空倒计时
clearInterval(this.timer)//关闭倒计时
// console.log('上/报,埋点');
uni.removeStorageSync('maiList')//清空上报参数
this.daoTime()//重新倒计时
}
},1000)
} else {//继续当前倒计时倒计
this.timer = setInterval(()=>{
uni.setStorageSync('daoTime',daoTime--)//设置倒计时
if(uni.getStorageSync('daoTime')<=0 || uni.getStorageSync('maiList').length==5){
uni.removeStorageSync('daoTime')//清空倒计时
clearInterval(this.timer)//关闭倒计时
// console.log('上报,埋点');
uni.removeStorageSync('maiList')//清空上报参数
this.daoTime()//重新倒计时
}
},1000)
}
},
/**
* @description 关闭倒计时
*/
closeTimer(){
clearInterval(this.timer)
console.log('倒计时清空了');
},
/**
* @description 获取字符串中的数字
*/
obtainCount(str) {
return parseInt(str.replace(/[^0-9]/ig,""))
},
/**
* @description 获取微信扫码后的结果并解析
*/
unescapeEv(op) {
let str = unescape(op.q);
return str;
},
/**
* @description 手机号验证
*/
isPhone:function(phone){
// 手机号正则表达式
let reg_tel = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
return !reg_tel.test(phone);
},
/**
* @description 电子邮箱验证
*/
isEmail(email){
let reg_email = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
return !reg_email.test(email);
},
/**
* @description 身份证验证
*/
isIdentity(identity) {
let reg_identity = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
return !reg_identity.test(identity);
},
/**
* @description 手机号中间四位用"****"带替
*/
hideMPhone(phone){
return `${phone.substr(0, 3)}****${phone.substr(7)}`
},
/**
* @description 手机号中间加字符
*/
phoneAddChat(phone,startNum=3,endNum=7,character=' '){
let phoneStr = phone;
phoneStr = phoneStr.replace(/\s*/g, "");
var phoneArr = [];
for(var i = 0; i < phoneStr.length; i++){
if (i==startNum||i==endNum){
phoneArr.push(`${character}` + phoneStr.charAt(i));
} else {
phoneArr.push(phoneStr.charAt(i));
}
}
phone = phoneArr.join("");
return phone;
},
/**
* @description 昵称从第一个字开始后面的都用"*"代替
*/
hideName(name,num){
return `${name.substr(0, 1)}****${name.substr(name.length-1)}`
},
/**
* @description 金额转换各三位数使用英文","隔开
*/
changeNum(num){
if (num) {
// 针对整数部分进行格式化处理,这是此方法的核心,也是稍难理解的一个地方,逆向的来思考或者采用简单的事例来实现就容易多了
/*
也可以这样想象现在有一串数字字符串在你面前如果让你给他家千分位的逗号的话你是怎么来思考和操作的?
字符串长度为0/1/2/3时都不用添加
字符串长度大于3的时候从右往左数有三位字符就加一个逗号然后继续往前数直到不到往前数少于三位字符为止
*/
num = num+''; // 数字转换为字符串,数字是没有.length属性的
for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
num = num.substring(0, num.length - (4 * i + 3)) + ',' + num.substring(num.length - (4 * i + 3))
}
// 将数据(符号、整数部分、小数部分)整体组合返回
return num;
}
},
/**
* @description 整数添加.00小数就不添加
*/
addXiaoShu(num){
// console.log(num,'添加小数点后两位小数');
let str = num.toString();
str = str*1;
str = str.toFixed(2);
str = str+'';
return str.includes('.') ? str : str = num + '.00';
},
// type:+加、-减、*乘、/除
// len:小数后保留几位
/**
* @description 数字换算解决失精度问题
*/
operationEv(num1,num2,type,len=0){
// 将数字转化成字符串
num1 = num1.toString();
num2 = num2.toString();
// 获取小数点的位置
var index1 = num1.indexOf(".");
var index2 = num2.indexOf(".");
// 如果小数点存在,那么就再获取各自的小数位数
var ws1 = 0;
var ws2 = 0;
if(index1 != -1){
ws1 = num1.split(".")[1].length;
}
if(index2 != -1){
ws2 = num2.split(".")[1].length;
}
// 看谁的小数位数大,谁的小数位数小
var bigger = (ws1 > ws2) ? ws1 : ws2;
var smaller = (ws1 < ws2) ? ws1 : ws2;
// 计算得到需要补齐的0的个数
var zerosCount = bigger - smaller;
// 好了,现在不管三七二十,全部去除小数点
num1 = num1.replace(".","");
num2 = num2.replace(".","");
// 比较num1和num2谁大比较方法就是看谁是smaller是smaller的一方就补0
if(ws1 == smaller){
for (var i = 0; i < zerosCount; i++) {
num1 += "0";
}
} else {
for (var i = 0; i < zerosCount; i++) {
num2 += "0";
}
}
// 开始计算
var sum = "";
if(type=="+"){
// 加
sum = parseInt(num1) + parseInt(num2);
}
if(type=="-"){
// 减
sum = parseInt(num1) - parseInt(num2);
}
if(type=="*"){
// 乘
sum = parseInt(num1) * parseInt(num2);
}
if(type=="/"){
// 除
sum = parseInt(num1) / parseInt(num2);
}
// 根据较大的小数位数计算倍数
var beishu = 1;
for (var i = 0; i < bigger; i++) {
beishu = beishu*10;
}
sum = sum/beishu;
if(type=="*"){
switch (bigger){
case 1:
sum = sum / 10;
break;
case 2:
sum = sum / 100;
break;
case 3:
sum = sum / 1000;
break;
}
}
if(type=="/"){
switch (bigger){
case 1:
sum = sum * 10;
break;
case 2:
sum = sum * 100;
break;
case 3:
sum = sum * 1000;
break;
}
}
len!=0 ? sum = sum.toFixed(len) : '';
return sum;
},
/**
* @description 金额输入框验证
*/
checkPrice(number,zong){
let reg = /^[0-9]*$/;//数字正则表达式
let newObj = {}
zong = parseInt(zong).toString()//取小数点左边的整数
if(!reg.test(number)){//不是数字时
newObj = {
len:zong.length,//动态设置长度
val:zong//动态设置值正整数的总金额
}
} else {//是数字时
newObj = {
len:zong.length,
val:number//动态设置当前输入的值
}
if(number*1 > zong*1){//输入的金额大于总金额
newObj.val = zong//赋值总金额
}
}
return newObj
},
/**
* @description 文本提示
*/
showToast: function(msg, icon='none',time) {
// 弹框显示时间默认2秒
var newTime = 2000
if (time) {newTime = time;}
return uni.showToast({
title: msg,
icon: icon,
duration:newTime
})
},
/**
* @description 富文本处理
*/
escape2Html(str) {
var arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' };
return str.replace(/&(lt|gt|nbsp|amp|quot|src);/ig, function (all, t) {
return arrEntities[t];
})
.replace('<section', '<div')
.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, p1) => {
return `<img mode="widthFix" style="max-width:100%!important;height:auto" src='${p1.indexOf('http') > -1 ? p1 : 'https://laonon.scdxtc.cn' + p1}' />`
})
},
/**
* @description 检查网络状态
*/
networkStatus(){
uni.getNetworkType({
success: (res)=> {
console.log('当前网络状态:',res.networkType);//none当前无网络连接
if(res.networkType=='none'){
uni.setStorageSync('isNet',false)
} else {
uni.setStorageSync('isNet',true);
// 微信小程序原生API性能优化
// #ifdef MP-WEIXIN
// 连网下,检测小程序是否有更新
this.checkUpdate();
// #endif
}
}
});
},
/**
* @description app小程序的检测版本并更新
*/
checkUpdate(){
// 检测app
// #ifdef APP-PLUS
// #endif
//检测小程序
// #ifdef MP-WEIXIN
var self = this;
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager();//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function(res) {// 请求完新版本信息的回调
if (res.hasUpdate) {
//检测到新版本,需要更新,给出提示
wx.showModal({
title: '更新提示',
content: '检测到新版本,是否下载新版本并重启小程序?',
success: function(res) {
if (res.confirm) {
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
self.downLoadAndUpdate(updateManager)
// 清除所有缓存
uni.clearStorage();
uni.clearStorageSync();
} else if (res.cancel) {
//用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
wx.showModal({
title: '温馨提示~',
content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~',
showCancel:false,//隐藏取消按钮
confirmText:"确定更新",//只保留确定更新按钮
success: function(res) {
if (res.confirm) {
//下载新版本,并重新应用
self.downLoadAndUpdate(updateManager)
}
}
})
}
}
})
}
})
} else { // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
// #endif
},
// 下载小程序新版本并重启应用
downLoadAndUpdate(updateManager){
var self = this;
wx.showLoading(); //静默下载更新小程序新版本
updateManager.onUpdateReady(function () {
wx.hideLoading(); //新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
// 清除缓存
uni.clearStorageSync();
uni.clearStorage();
})
updateManager.onUpdateFailed(function () { // 新的版本下载失败
wx.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
})
})
},
/**
* @description 文本复制
*/
clickCopy(data){
uni.setClipboardData({
data: data,
success: ()=> {
uni.showToast({title: '复制成功',duration: 2000,icon: 'none'});
}
});
},
authTimer:null,
/**
* @description 判断是否授权没授权前往登录页面授权
*/
judgeAuth(){
let auth = false;
clearTimeout(this.authTimer);
if(!uni.getStorageSync('token') || uni.getStorageSync('is_active') == 0) {
this.showToast('请授权登录');
this.authTimer = setTimeout(()=>{
uni.reLaunch({url:'/pages/login/login'});
},2000)
} else {
auth = true;
}
return auth;
},
/**
* @description 判断当前环境清空日志输出
*/
currentContext(){
// #ifdef APP-PLUS
if(uni.getSystemInfoSync().platform != "devtools"){//devtools开发版 值域为ios、android、mac3.1.10+、windows3.1.10+、linux3.1.10+
// console.log = () =>{}
}
// #endif
// 微信小程序原生API性能优化
// #ifdef MP-WEIXIN
let hInfo = wx.getAccountInfoSync();
// console.log(hInfo.envVersion);//develop:开发版 trial体验版 release正式版
if(hInfo.miniProgram.envVersion == "release"){
// 清除所有输出日志
console.log = () =>{};
// 开启埋点倒计时
// this.daoTime();
}
// #endif
},
/**
* @description 禁止小程序使用右上角分享
*/
disableShareEv(){
// #ifdef MP-WEIXIN
wx.hideShareMenu({
menus: ['shareAppMessage', 'shareTimeline']
})
// #endif
},
/**
* @description 获取当前页面完整url
*/
obtainPagePath(){
let pages = getCurrentPages();
// 获取纯页面路径
let route = pages[pages.length - 1].route;
uni.setStorageSync('url',route);
// 获取当前页面url带参数
let routeParam = pages[pages.length - 1].$page.fullPath;
// console.log(routeParam.options,'获取当前url参数');
uni.setStorageSync('page-path-options',routeParam);
console.log(uni.getStorageSync('page-path-options'),'当前页面完整路径');
},
/**
* @description 拨打电话
* @param {Number} phone
*/
countCustomer(phone=10086){
const res = uni.getSystemInfoSync();
if(res.platform=='ios'){
uni.makePhoneCall({
phoneNumber:phone*1,
success: () => {},
fail: () => {}
})
} else {
uni.showActionSheet({
itemList:[phone,'立即呼叫'],
itemColor:'#3875F6',
success: (res) => {
if(res.tapIndex==1){
uni.makePhoneCall({
phoneNumber:phone
})
}
}
})
}
},
/**
* @description 图片选择
* @param {Number} count
*/
uploadImg(count=1) {
let imgArr = [];
uni.chooseImage({
count:count,
sizeType:['compressed'],
sourceType:['album','camera'],
success: (res) => {
let files = res.tempFilePaths
console.log(files);
files.forEach(item=>{
imgArr.push(item);
})
}
})
return imgArr;
},
/**
* @description 打开小程序获取用户信息权限
*/
wxOpenSet() {
// #ifdef MP-WEIXIN
// 用户信息
uni.authorize({
scope:'scope.userInfo',
success: (res) => {},
fail: (res) => {
uni.showModal({
content:'检测到您没打开获取信息功能权限,是否去设置打开?',
confirmText: "确认",
cancelText:'取消',
success: (res) => {
if(res.confirm){
uni.openSetting({
success: (res) => {
console.log(res);
}
})
}else{
console.log('取消');
}
}
})
}
})
// #endif
},
/**
* @description 传入目的地的经纬度地点名称详细地址打开地图导航到达目的地
*/
goFlag:true,
goThere(latitude=30.656693,longitude=104.136425,address="四川省成都市成华区双店路B口"){
if(this.goFlag){
this.goFlag = false;
// #ifdef MP-WEIXIN
wx.getLocation({//获取当前经纬度
type: 'wgs84', //返回可以用于wx.openLocation的经纬度官方提示bug: iOS 6.3.30 type 参数不生效,只会返回 wgs84 类型的坐标信息
success: (res)=> {
wx.openLocation({//​使用微信内置地图查看位置。
latitude: parseFloat(latitude),//要去的纬度-地址
longitude: parseFloat(longitude),//要去的经度-地址
address: address,
fail:err=>{
tools.showToast('地址信息错误');
}
})
}
})
// #endif
// #ifdef APP-PLUS || H5
uni.openLocation({
latitude: parseFloat(latitude),
longitude: parseFloat(longitude),
address:address,
success:()=> {
console.log('success');
},
fail:err=>{
console.log(err)
}
});
// #endif
setTimeout(()=>{
this.goFlag = true;
},2000)
} else {
tools.showToast('请勿多次点击');
}
},
/**
* @description 保存图片
* @param {String} src
*/
saveImg(src) {
// #ifdef APP-PLUS
uni.saveImageToPhotosAlbum({
filePath: src,
success:(resimg)=> {}
});
// #endif
// #ifdef MP-WEIXIN
let exist = src.slice(0,4);
if(exist=='http') {
uni.downloadFile({
url: src,
success: (res) => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: ()=> {
uni.showToast({title:'保存成功',icon:'error'})
},
fail: () => {
uni.showToast({title:'保存失败',icon:'error'})
}
});
}
})
} else {
wx.saveFile({
tempFilePath: src,
success:(wximg)=> {}
})
}
// #endif
},
/**
* @description 把base64转换成图片
* @param {String} data
*/
getBase64ImageUrl(data) {
/// 获取到base64Data
var base64Data = data;
/// 通过微信小程序自带方法将base64转为二进制去除特殊符号再转回base64
base64Data = wx.arrayBufferToBase64(wx.base64ToArrayBuffer(base64Data));
/// 拼接请求头data格式可以为image/png或者image/jpeg等看需求
const base64ImgUrl = "data:image/png;base64," + base64Data;
/// 刷新数据
return base64ImgUrl;
},
}
export default {
tools
}

31
main.js Normal file
View File

@ -0,0 +1,31 @@
import Vue from 'vue';
import App from './App';
import store from './store'
Vue.prototype.$store = store
import nothingPage from './components/nothing/nothing-page.vue';//引入无内容组件
Vue.component('nothing-page',nothingPage);//全局注册无内容组件
import statusNav from './components/status-nav/status-nav.vue'; //引入头部组件
Vue.component('status-nav',statusNav);//全局注册头部组件
// 常用便捷式公共方法
import tools from '@/jsFile/tools.js';
Vue.prototype.$toolAll = tools;
// 响应数据
import requst from '@/jsFile/requst.js';
Vue.prototype.$requst = requst;
//公共域名
Vue.prototype.$hostHttp = 'https://laonon.scdxtc.cn';
App.mpType = 'app';
const app = new Vue({
store,
...App
})
app.$mount()

87
manifest.json Normal file
View File

@ -0,0 +1,87 @@
{
"name" : "app适配微信小程序",
"appid" : "__UNI__768F35C",
"description" : "这是一款基于uniapp开发的app和微信小程序的模板框架",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"compilerVersion" : 3,
/* 5+App */
"modules" : {
"Payment" : {},
"Share" : {}
},
/* */
"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.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<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" : {},
/* ios */
"sdkConfigs" : {
"maps" : {},
"payment" : {
"weixin" : {
"__platform__" : [ "ios", "android" ],
"appid" : "wx2654bc27c419ada6",
"UniversalLinks" : ""
}
},
"push" : {},
"geolocation" : {},
"share" : {
"weixin" : {
"appid" : "wx2654bc27c419ada6",
"UniversalLinks" : ""
}
},
"ad" : {}
}
},
"splashscreen" : {
"alwaysShowBeforeRender" : false,
"waiting" : false
}
},
/* SDK */
"quickapp" : {},
/* */
"mp-weixin" : {
/* */
"appid" : "wxa02e44170bc722cd",
"setting" : {
"urlCheck" : true,
"es6" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "您的位置信息将用于小程序位置接口的效果展示"
}
}
},
"mp-baidu" : {
"appid" : "24346353"
}
}

15
package-lock.json generated Normal file
View File

@ -0,0 +1,15 @@
{
"name": "轮播视频和图片",
"version": "1.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "轮播视频和图片",
"version": "1.0.1",
"dependencies": {
"moment": "^2.29.3"
}
}
}
}

11
package.json Normal file
View File

@ -0,0 +1,11 @@
{
"id": "zhuge-swiper",
"name": "轮播视频和图片",
"version": "1.0.1",
"description": "自动轮播视频和图片组件。播放视频时停止轮播手动滑动swiper时视频停止播放",
"keywords": [
"vue",
"swiper",
"zhuge"
]
}

164
pages.json Normal file
View File

@ -0,0 +1,164 @@
{
"pages": [
{ //
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": false
}
},
{ //
"path": "pages/my/my",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false
}
},
{ //
"path" : "pages/cart/cart",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "pages/cart/settlement",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "pages/cart/finish",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "pages/login/login",
"style" : {
"navigationBarTitleText": "登录",
"enablePullDownRefresh": false
}
}
],
"subPackages": [{ //A
"root": "pagesA",
"pages": [
{ //
"path" : "address/address",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "recharge/recharge",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "integral/integral",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "distribution/distribution",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "coupon/coupon",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "order/order",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "order/detail",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
]
},
{ //B
"root": "pagesB",
"pages": [
{ //
"path" : "shop-detail/shop-detail",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "ucenter/ucenter",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "disclaimers/disclaimers",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "integral-rule/integral-rule",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{ //
"path" : "distributor/distributor",
"style" : {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
]
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF", //
"navigationStyle": "custom", //
"backgroundColor":"#FFFFFF",//
"backgroundTextStyle":"light",// loading dark / light
// "transparentTitle":"none",// always / auto / none
"app-plus": {
"titleNView": false, //APPH5
"bounce": "none",
"scrollIndicator": "none"
}
},
"condition" : { //
"current": 0, //(list )
"list": [
{
"name": "", //
"path": "", //
"query": "" //onLoad
}
]
}
}

39
pages/cart/cart.vue Normal file
View File

@ -0,0 +1,39 @@
<template>
<view class="pad-b150">
<status-nav :ifReturn="true" navBarTitle="购物车" :marginBottom="0"></status-nav>
<view class="cart-content">
<cart-slide ref="cart" :skuId='skuId'></cart-slide>
</view>
</view>
</template>
<script>
//
import cartSlide from '@/components/shopping-carts/cart-slide';
export default {
components:{
cartSlide
},
data() {
return {
skuId:''
}
},
onReachBottom() {
this.$refs.cart.getList();
},
onShow() {
uni.removeStorageSync('buyList');
},
onLoad(op) {
if(op.skuId) this.skuId = op.skuId;
},
methods: {
}
}
</script>
<style>
</style>

48
pages/cart/finish.vue Normal file
View File

@ -0,0 +1,48 @@
<template>
<view>
<status-nav :ifReturn="false" navBarTitle="完成" :marginBottom="0"></status-nav>
<view class="finish-content">
<view class="finish-img flex">
<image src="/static/icon/icon-finish.png" mode="widthFix"></image>
</view>
<view class="finish-txt font48">支付已完成</view>
<view class="finish-btns font36 border-box">
<view class="btn radius30 border-box background-orange flex" @tap="goShop"></view>
<view class="btn radius30 border-box flex" @tap="goOrder"></view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imgsrc:'',
id:'',//id
}
},
onLoad(op) {
console.log(op)
this.id = op.id
},
methods: {
//
goOrder(){
uni.navigateTo({
url:`/pagesA/order/detail?id=${this.id}`
})
},
//
goShop(){
uni.navigateTo({
url:'/pages/index/index'
})
},
}
}
</script>
<style>
</style>

360
pages/cart/settlement.vue Normal file
View File

@ -0,0 +1,360 @@
<template>
<view class="pad-x150" v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="确认订单" :marginBottom="0"></status-nav>
<!-- 收件人信息 -->
<view class="settlement-content pad-zy20 border-box">
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">收件人信息</view>
<view class="addressee-info mar-s20 flex" @tap="toAddress">
<view class="txt" v-if="default_address">
<view class="font30 mar-x10">{{default_address.name}}<text>{{default_address.phone}}</text></view>
<text class="font24 color-8c">{{default_address.province_str}}{{default_address.city_str}}{{default_address.county_str}}{{default_address.address}}</text>
</view>
<view class="txt" v-else>
<view class="font30 color-8c" style="line-height: 2;">请选择地址</view>
</view>
<image src="/static/icon/icon-more.png" mode="widthFix"></image>
</view>
</view>
<!-- 订单信息 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">订单信息</view>
<view class="shop-slide-list">
<view class="shop-slide-item">
<view class="item border-box background-white flex" v-for="(item,index) in orderShopList" :key="index">
<view class="shop-img radius30">
<image :src="item.spu_cover" mode="widthFix"></image>
</view>
<view class="shop-txt">
<view class="shop-txt-top">
<view class="title font30 clips1">{{item.goods_name}}</view>
<view class="specs font24 color-66 mar-sx10 clips2">规格{{item.sku_name}}</view>
</view>
<view class="shop-txt-bottom flex">
<!-- 商品价格 -->
<view class="price font30 color-red">{{item.price}}<text class="font24 color-66">x{{item.num}}</text></view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 优惠选择 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">优惠选择</view>
<view class="section-list font30">
<view class="item flex" v-if="orderInfo.vip_level>0">
<label class="radio" @tap="chooseEv('vip')"><radio :checked="vipCheck" color="#febf00"/>会员折扣</label>
<view class="txt flex">
<view>{{orderInfo.membership_discount}}</view>
<view class="btn"></view>
</view>
</view>
<view class="item flex" @tap.stop="toCoupon">
<label class="radio" @tap.stop="chooseEv('coupon')"><radio :checked="couponCheck" color="#febf00"/>优惠券</label>
<view class="txt flex">
<view class="color-red" v-if="couponList.length">{{'-'+ couponList[couponIndex].amount}}</view>
<view class="btn">
<image src="/static/icon/icon-join.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</view>
<!-- 积分抵扣 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">积分抵扣</view>
<view class="section-list font30">
<view class="item flex">
<label class="radio" @tap="scoreCheck=!scoreCheck"><radio :checked="scoreCheck && orderInfo.available_score>0" color="#febf00"/>可用积分</label>
<view class="txt flex">
<view class="color-66">{{orderInfo.available_score}}</view>
<view class="btn"></view>
</view>
</view>
</view>
</view>
<!-- 支付方式 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">支付方式</view>
<view class="section-list font30">
<view class="item flex">
<label class="radio" @tap="wechatCheck=!wechatCheck"><radio :checked="wechatCheck" color="#febf00"/>微信支付</label>
</view>
<view class="item flex">
<label class="radio" @tap="priceCheck=!priceCheck"><radio :checked="priceCheck" color="#febf00"/>余额支付</label>
<view class="txt flex">
<view class="color-66">{{orderInfo.available_balance}}</view>
<view class="btn"></view>
</view>
</view>
</view>
</view>
</view>
<!-- 尾部 -->
<view class="pull-footer-bg background-white pad-all20 radius30 border-box">
<view class="pull-footer background-grey radius30 pad-all20 border-box flex">
<view class="price color-ff" style="margin-left: 24rpx;">
<view class="font36 flex">合计<span>{{totalPrice}}</span></view>
<text class="font26" v-if="discountPrice>0">{{discountPrice}}</text>
</view>
<view class="btn font36 color-48 background-orange radius30 flex" @tap="submitEv"></view>
</view>
</view>
<!-- 优惠券弹窗 -->
<view class="pull-bg" style="background-color: rgba(0,0,0,.3);" v-show="isCoupon"></view>
<view class="coupon-box border-box background-white" v-show="isCoupon">
<view class="title font36 background-white pad-sx25">优惠券选择</view>
<scroll-view scroll-y="true" class="coupon-scoll">
<view class="coupon-list pad-zy20 border-box">
<view class="coupon-item radius30 mar-s40 flex" v-for="(item,index) in couponList" :key="index" @tap="changeCoupon(index)">
<view class="price color-ff border-box"><text class="font30"></text>{{parseInt(item.amount)}}</view>
<view class="txt">
<view class="font36">{{item.name}}</view>
<view class="font24 color-8c mar-s10">{{parseInt(item.condition)}}{{parseInt(item.amount)}}</view>
<view class="font24 color-8c mar-s10">{{item.begin_at}}{{item.end_at}}</view>
</view>
<view class="btn mar-zy20 color-ff font24" v-if="index == couponIndex"></view>
</view>
</view>
</scroll-view>
<view class="coupon-btns border-box pad-zy20 color-48 mar-sx30 flex">
<view class="btn font36 radius30 background-orange" @tap="useCoupon">使</view>
<view class="btn font36 radius30" style="background-color: #e9e9e9;" @tap="closeCoupon"></view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
orderInfo:{}, //
default_address:{}, //
orderShopList:[], //
couponList:[], //
couponIndex:0, //
vipCheck: false, //
couponCheck:false, //
scoreCheck:false, //
wechatCheck:false, //
priceCheck:false, //
isCoupon:false, //
flag:true,
preferential_options:'coupon',//
totalPrice:'',//
discountPrice:'', //
isLoading:false,
}
},
onShow() {
this.getOrderInfo();
},
methods: {
//
toAddress(){
uni.navigateTo({
url:`/pagesA/address/address?type=change`
})
},
//
computePrice(){
//
if(this.vipCheck && !this.couponCheck){
this.discountPrice = this.$toolAll.tools.addXiaoShu(this.orderInfo.total_price*(1 - this.$toolAll.tools.addXiaoShu(this.orderInfo.membership_discount)/10));
this.totalPrice = this.$toolAll.tools.addXiaoShu(this.orderInfo.total_price-this.discountPrice);
}
if(this.couponCheck && !this.vipCheck){
this.discountPrice = this.$toolAll.tools.addXiaoShu(this.couponList[this.couponIndex].amount);
this.totalPrice = this.$toolAll.tools.addXiaoShu(this.orderInfo.total_price - this.discountPrice);
}
if(!this.couponCheck && !this.vipCheck){
this.discountPrice = 0;
this.totalPrice = this.$toolAll.tools.addXiaoShu(this.orderInfo.total_price);
}
},
//
getOrderInfo(){
uni.showLoading({
title:'加载中'
})
let params = {
sku_list: uni.getStorageSync('buyList'),
}
this.$requst.post('/api/order/prepare-info',params).then(res=>{
if(res.code == 0){
console.log(res,'订单准备信息');
//
this.orderInfo = res.data;
//
let baseArr = res.data.available_coupon_list;
let couponArr = baseArr.sort(function (a, b) {
return b.amount - a.amount;
});
this.couponList = couponArr;
if(this.couponList.length==0){
this.couponCheck = false;
}
//
this.orderShopList = res.data.list;
//
let addr_id = uni.getStorageSync('addr_id');
if(addr_id){
//
this.getAddrDetail(addr_id);
}else{
this.default_address = res.data.default_address;
}
//
this.discountPrice = 0;
this.totalPrice = this.$toolAll.tools.addXiaoShu(this.orderInfo.total_price);
}
uni.hideLoading();
this.isLoading = true;
})
},
//
getAddrDetail(id){
this.$requst.post('/api/user/address-info',{id:id}).then(res=>{
if(res.code == 0){
console.log(res,'地址详情');
this.default_address = res.data;
}
})
},
//
toCoupon(){
if(this.couponList.length){
this.isCoupon =true;
}else{
this.$toolAll.tools.showToast('还没有优惠券');
}
},
//
changeCoupon(index){
if(index!==this.couponIndex){
this.couponIndex = index;
}
},
//
useCoupon(){
this.isCoupon = false;
},
//
closeCoupon(){
this.isCoupon = false;
this.couponIndex = 0;
},
//
chooseEv(type){
if(type == 'vip'){
if(this.vipCheck){
this.vipCheck = false;
}else{
this.vipCheck = true;
this.couponCheck = false;
}
this.computePrice();
}
if(type == 'coupon'){
if(this.couponCheck){
this.couponCheck = false;
}else{
this.couponCheck = true;
this.vipCheck = false;
}
this.computePrice();
}
},
//
submitEv(){
this.flag = false;
if(this.vipCheck){
this.preferential_options = 'membership_discount';
}
if(this.couponCheck){
this.preferential_options = 'coupon';
}
if(!this.couponCheck && !this.vipCheck){
this.preferential_options = '';
}
if(this.default_address == null) {
this.$toolAll.tools.showToast('请填写地址信息');
}else{
if(this.wechatCheck || this.priceCheck){
let params = {
sku_list: uni.getStorageSync('buyList'),
preferential_options:this.preferential_options,
coupon_id: this.couponCheck?this.couponList[this.couponIndex].id:'',
deduction_points:this.scoreCheck?1:0,
is_balance:this.priceCheck?1:0,
is_wechat:this.wechatCheck?1:0,
address_id:this.default_address.id
}
this.$requst.post('/api/order/create',params).then(res=>{
if(res.code==0) {
console.log(res,'支付返回')
if(res.data.need_wechat_pay == 1){
//
this.callPayMent(res.data.payment_params);
}else{
this.$toolAll.tools.showToast('支付成功(*^▽^*)');
uni.removeStorageSync('addr_id');
uni.navigateTo({
url:`/pages/cart/finish?id=${res.data.id}`
})
}
}else{
console.log(res.msg,'提示信息')
this.$toolAll.tools.showToast(res.msg);
this.flag = true;
}
})
}else{
this.$toolAll.tools.showToast('请选择支付方式');
}
}
},
//
callPayMent(data){
//
wx.requestPayment({
'timeStamp': data.timeStamp,
'nonceStr': data.nonceStr,
'package': data.package,
"signType": data.signType,
'paySign': data.sign,
'success': function (res) { //
console.log('支付成功:',res);
this.$toolAll.tools.showToast('支付成功(*^▽^*)');
uni.removeStorageSync('addr_id');
uni.navigateTo({
url:`/pages/cart/finish?id=${res.data.id}`
})
},
'fail': function (res) { //
console.log('支付失败:' + JSON.stringify(res));
}
})
},
}
}
</script>
<style>
</style>

379
pages/index/index.vue Normal file
View File

@ -0,0 +1,379 @@
<template>
<view>
<view class="index-page pad-x190 border-box" v-if="isLoading">
<!-- 顶部背景 -->
<view class="index-top">
<image :src="indexBackground" mode="widthFix"></image>
</view>
<view class="index-content background-white">
<!-- 搜索 -->
<view class="pull-search-bg background-white radius20 pad-sx30 border-box">
<view class="pull-search radius20 flex" v-if="isShow">
<image class="img" src="/static/icon/icon-search.png" mode="widthFix"></image>
<input class="input pad-zy15 border-box font30" v-model="keyword" type="text" placeholder="搜索" confirm-type="search" @confirm="doSearch" placeholder-style="color: #666666">
</view>
</view>
<!-- 商品分类 -->
<view class="index-cate-bg pad-zy20 background-white" :class="!isShow?'show':''" id="index-cate-bg">
<view class="index-cate pad-zy20 border-box" :class="!isShow?'show':''">
<view class="pull-title">
<view class="txt font32 pad-sx10" v-if="isShow"></view>
<view class="line background-orange" v-if="isShow"></view>
</view>
<view class="cate-list-bg">
<scroll-view scroll-x="true" :scroll-left="tabsScrollLeft" @scroll="scroll">
<view class="cate-list flex" id="tab_list" :style="{width:cateWidth}">
<view class="cate-item" :class="index==currentIndex?'color-orange':''" id="tab_item" v-for="(item,index) in cateList" :key="index" @tap="changeCateEv(index)">
<view class="img mar-sx20"><image :src="item.cover" mode="widthFix"></image></view>
<view class="txt font24">{{item.title}}</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
<!-- 商品列表 -->
<view class="commodity pad-zy20 border-box flex">
<view class="item mar-s40 radius20" v-for="(item,index) in commodityList" :key="index" @tap.stop="goDetail(item.id)">
<view class="img">
<image :src="item.cover" mode="widthFix"></image>
</view>
<view class="txt pad-all20">
<view class="title fon30 clips2">{{item.name}}</view>
<view class="price font30 mar-sx10">{{item.price}}</view>
<view class="bottom flex">
<view class="sold font24 color-99">{{item.amount>=100?'99+':item.amount}}件已售</view>
<view class="btn font24 background-orange flex" @tap.stop="joinCart(index)">加入购物车</view>
</view>
</view>
</view>
</view>
<!-- 到底啦 -->
<view class="no-more font24" v-if="noMore"><text> 到底啦 </text></view>
</view>
</view>
<!-- 搜索结果 -->
<view class="pull-bg" v-if="showSearch"></view>
<view class="search-box border-box" v-if="showSearch" @tap.stop="closeSearch">
<view class="close-box" :style="{height:statusHeight+50+'px'}" @tap="closeSearch"></view>
<!-- 搜索 -->
<view class="search-bg background-white pad-sx30 border-box">
<view class="search radius20 flex">
<image class="img" src="/static/icon/icon-search.png" mode="widthFix"></image>
<input class="input pad-zy15 border-box font30" v-model="keyword" type="text" placeholder="搜索" confirm-type="search" @confirm="doSearch" placeholder-style="color: #666666">
</view>
</view>
<view class="keyword-txt background-white font30">关键词{{searchKeyword}}</view>
<scroll-view scroll-y="true" class="search-list background-white">
<!-- 搜索列表 -->
<view class="commodity pad-zy20 border-box flex">
<view class="item mar-s40 radius20" v-for="(item,index) in searchList" :key="index" @tap.stop="goDetail(item.id)">
<view class="img">
<image :src="item.cover" mode="widthFix"></image>
</view>
<view class="txt pad-all20">
<view class="title fon30 clips2">{{item.name}}</view>
<view class="price font30 mar-sx10">{{item.price}}</view>
<view class="bottom flex">
<view class="sold font24 color-99">{{item.stock>=100?'99+':item.stock}}件已售</view>
<view class="btn font24 background-orange flex" @tap.stop="joinCart(index)">加入购物车</view>
</view>
</view>
</view>
</view>
<!-- 没有相关结果 -->
<view class="no-more font24" v-if="searchList.length==0"><text> 没有相关结果 </text></view>
</scroll-view>
</view>
<!-- 尾部 -->
<tabbar v-if="isLoading"></tabbar>
</view>
</template>
<script>
import tabbar from '@/components/tabbar/tabbar';
import {getCartInfo} from '@/jsFile/public-api.js';
import {mapState} from 'vuex'//mapState
export default {
components:{
tabbar
},
data() {
return {
statusHeight:uni.getSystemInfoSync().statusBarHeight,
scrollTop:0, //
isShow: true, //
//
currentIndex:0,
scrollLeft:0,
tabsScrollLeft:0,
cateWidth:'',
indexBackground:'', //
keyword:'', //
cateList:[], //
commodityList:[], //
ifLoading:true,
page:1, //
size:10, //
total:0, //
noMore:false, //
vip_level:0, //
keyword:'', //
searchKeyword:'', //
searchList:[], //
showSearch:false, //
isLoading:false,
}
},
onLoad() {
//
this.getUserInfo();
//
this.getTabbarEv();
//
this.getCateEv();
},
onShow() {
this.playTimer = setTimeout(()=>{
this.isplay = true;
},2000)
this.vip_level = uni.getStorageSync('vip_level');
},
onReady() {
},
onHide() {
clearTimeout(this.playTimer);
this.isplay =false;
},
onPageScroll(object){
this.setTop();
if(object.scrollTop>this.scrollTop){
this.isShow = false;
}else{
this.isShow = true;
}
},
//
onShareAppMessage(res) {
},
//
onShareTimeline(res){
},
//
onReachBottom(e) {
if(!this.noMore){
this.page++;
//
this.getCommodityEv(this.cateList[this.currentIndex].id);
}
},
watch: {
list() {
this.setTabList()
},
value() {
this.currentIndex = this.value
this.setTabList()
}
},
methods: {
//
getUserInfo(){
this.$requst.get('/api/user/info').then(res=>{
if(res.code == 0){
console.log(res,'个人信息')
uni.setStorageSync('vip_level',res.data.vip_level);
}
})
},
//
getTabbarEv(){
this.$requst.get('/api/index/mini-program-setting').then(res=>{
if(res.code == 0){
console.log(res,'个性装扮')
this.indexBackground = this.$hostHttp + res.data.indexBackground;
}
})
},
//
getCateEv(){
this.$requst.get('/api/spu/category').then(res=>{
if(res.code == 0){
console.log(res,'商品分类')
let cateArr =[];
res.data.forEach(item=>{
let obj = {
id:item.id,
title:item.title,
cover:item.cover
}
cateArr.push(obj);
})
this.cateList = cateArr;
this.cateWidth = this.cateList.length*158 - 58 + 'rpx';
//
this.getCommodityEv(this.cateList[this.currentIndex].id);
}
})
},
//
getCommodityEv(id){
uni.showLoading({
title:'加载中'
})
let params = {
page:this.page,
size:this.size,
category_id:id
}
this.$requst.get('/api/spu/list',params).then(res=>{
if(res.code == 0){
console.log(res,'商品列表')
this.total = res.data.total;
let commodityArr = [];
res.data.list.forEach(item=>{
let obj = {
id:item.id,
cover:item.cover,
name:item.name,
original_price:item.original_price,
price:item.price,
tag:item.tag,
stock:item.stock,
sku_id:item.default_sku.id,
amount:item.amount,
}
commodityArr.push(obj)
})
this.commodityList = this.commodityList.concat(commodityArr);
if(this.commodityList.length==this.total){
this.noMore =true;
}
}
uni.hideLoading();
this.isLoading = true;
})
},
//
joinCart(index){
if(this.$toolAll.tools.judgeAuth()) {
this.$requst.post('/api/order/shopping-cart-add',{sku_id:this.commodityList[index].sku_id,num:1}).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('加入购物车成功(*^▽^*)');
getCartInfo();
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
}
},
//
goDetail(id){
uni.navigateTo({
url:`/pagesB/shop-detail/shop-detail?id=${id}`
})
},
//
changeCateEv(index) {
if(this.currentIndex !== index){
this.currentIndex = index;
//
this.commodityList = [];
this.noMore = false;
this.getCommodityEv(this.cateList[index].id);
//
this.setTabList();
}
},
//
setTabList() {
this.$nextTick(() => {
if (this.cateList.length > 0) {
//
this.setLeft()
}
})
},
//
setLeft() {
let lineLeft = 0;
this.getElementData('#tab_list', (data) => {
let list = data[0];
this.getElementData('#tab_item', (res) => {
let el = res[this.currentIndex]
lineLeft = el.width / 2 + (-list.left) + el.left - list.width / 2 - this.scrollLeft
this.tabsScrollLeft = this.scrollLeft + lineLeft
})
})
},
//
setTop(){
this.getElementData('#index-cate-bg', (res) => {
let el = res[0];
this.scrollTop = el.top + el.height/4;
})
},
// DOM
getElementData(el, callback) {
uni.createSelectorQuery().in(this).selectAll(el).boundingClientRect().exec((data) => {
callback(data[0]);
});
},
//
scroll(e) {
this.scrollLeft = e.detail.scrollLeft;
},
//
doSearch(){
this.showSearch = true;
this.searchKeyword = this.keyword;
this.keyword = '';
this.$requst.get('/api/spu/list',{keyword:this.searchKeyword}).then(res=>{
if(res.code == 0){
console.log(res,'搜索列表')
this.total = res.data.total;
let searchArr = [];
res.data.list.forEach(item=>{
let obj = {
id:item.id,
cover:item.cover,
name:item.name,
original_price:item.original_price,
price:item.price,
tag:item.tag,
stock:item.stock,
sku_id:item.default_sku.id
}
searchArr.push(obj)
})
this.searchList = this.searchList.concat(searchArr);
}
})
},
//
closeSearch(){
this.showSearch = false;
this.searchKeyword = '';
this.searchList = [];
}
}
}
</script>
<style>
</style>

142
pages/login/login.vue Normal file
View File

@ -0,0 +1,142 @@
<template>
<view>
<view class='login-header'>
<image class="infoImg" mode="aspectFill" :src="userInfo.avatarUrl || imgSrc"></image>
<view class="logo-name">{{appletName}}</view>
<view class="logo-title font24 color-99 mar-s20" style="text-align: center;">{{appleSubtitle}}</view>
</view>
<view class="login-footer">
<view class="login-btn radius20 color-48 font36" :style="{background:'#febf00'}" type='primary' @tap="bindGetUserInfo"></view>
<view class="agreement-box font30">如您点击授权您将同意授权<text @tap="toAgreement" class="agreement">免责声明</text></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
userInfo: {}, //
canIGetUserProfile: false,
imgSrc: '/static/img/logo.png', //logo
appletName:'“老农极鲜~土货”', //
appleSubtitle:'精选特产尽在土货',
isShowP:false,
};
},
onLoad() {
if (uni.getUserProfile) {
this.canIGetUserProfile = true;
}
},
methods: {
// logo
setLogo(){
this.$requst.get('index/base-config').then(res=>{
this.imgSrc = this.$http + res.data.logo;
this.appletName = res.data.appletName;
})
},
refuse(){//
this.isShowP=false;
this.$toolAll.tools.showToast('登录成功','success')
uni.reLaunch({url:'/pages/index/index'})
},
getphonenumber(e){//
let ya = this;
wx.login({
success:(res)=>{
this.$requst.post('/api/user/login',{code:res.code}).then(result => {
if(e.detail.errMsg=="getPhoneNumber:ok"){
this.$requst.post('user/bind-phone',{openid: result.data.openid,session_key:result.data.session_key, iv:e.detail.iv,encryptedData:e.detail.encryptedData}).then(res=>{
console.log('手机号信息:',res);
if(res.code==0){
this.$toolAll.tools.showToast('手机号绑定成功');
this.isShowP = true;
} else this.$toolAll.tools.showToast(res.msg);
},error=>{})
} else {
// console.log('')
}
}).catch(err=>{
console.log(err);
})
}
})
},
toAgreement(){
uni.navigateTo({
url:'/pagesB/disclaimers/disclaimers'
})
},
//
bindGetUserInfo(e) {
let ya = this;
//
uni.getUserProfile({
desc: '登录',
lang: 'zh_CN',
success: (res) => {
ya.userInfo = res.userInfo;
uni.login({
provider: 'weixin',
success: (res)=> {
if (res.code) {
ya.updateUserInfo(res.code);
} else {
uni.showToast({
title: '登录失败!',
duration: 2000
});
}
},
});
},
fail: (res) => {}
});
},
//
updateUserInfo(code) {
let ya = this;
uni.showToast({
title: '登录中...',
icon:'loading',
duration:10000
})
var params = {
code:code,
nickname: ya.userInfo.nickName,//
headimgurl: ya.userInfo.avatarUrl,//
country: ya.userInfo.country,//
province: ya.userInfo.province,//
city: ya.userInfo.city,//
gender: ya.userInfo.gender,//
language:ya.userInfo.language,//
is_active:1
}
this.$requst.post('/api/user/login',params).then(res => {
if(res.code == 0){
uni.setStorageSync('userId',res.data.account_id)
uni.setStorageSync('token',res.data.token)//token
uni.setStorageSync('openid',res.data.openid)//openid
uni.setStorageSync('expire',res.data.expire)//
uni.setStorageSync('phone_active',res.data.phone_active)//
uni.setStorageSync('is_active',res.data.is_active)//
uni.setStorageSync('business_code',res.data.business_code)//
if(uni.getStorageSync('page-path-options')) {
uni.reLaunch({ //
url:uni.getStorageSync('page-path-options')
})
} else {
uni.reLaunch({
url:'/pages/index/index'
})
}
}
},error => {})
}
}
}
</script>
<style scoped>
</style>

406
pages/my/my.vue Normal file
View File

@ -0,0 +1,406 @@
<template>
<view class="pad-x170" v-if="isLoading">
<!-- 滚动顶部 -->
<view class="scrool-top background-white" :style="{height:statusHeight+50+'px'}" v-if="scroolTop"></view>
<view class="my-top">
<view class="my-bg">
<image src="/static/img/my-bg.jpg" mode="widthFix"></image>
</view>
<!-- 头部 -->
<view class="my-herder pad-zy20 border-box">
<view class="my-message color-ff flex">
<!-- 头像 -->
<view class="my-portrait radius100">
<image :src="headPortrait" mode="widthFix"></image>
</view>
<!-- 用户名 -->
<view class="my-txt flex">
<view class="my-nickname font36 flex">
<text>{{nickName}}</text>
<image :src="vip_info.ico" mode="widthFix" v-if="vip_info.ico!==''"></image>
</view>
<view class="my-vip-txt font24 background-orange radius25 pad-zy40 mar-s20 flex">{{vip_info.name}}</view>
</view>
</view>
<view class="my-money color-ff flex">
<view class="item">
<view class="font48">{{userInfo.score}}</view>
<text class="font24">我的积分</text>
</view>
<view class="item">
<view class="font48">{{userInfo.coupon_count}}</view>
<text class="font24">我的优惠券</text>
</view>
<view class="item">
<view class="font48">{{userInfo.balance}}</view>
<text class="font24">我的余额</text>
</view>
</view>
<!-- 订单量 -->
<view class="my-order background-grey border-box flex">
<view class="item" v-for="(item,index) in myOrder" :key="index" @tap="changeOrder(index)">
<view class="img flex">
<image :src="item.imgSrc" mode="widthFix" :style="{width:item.iconWidth+'rpx',height:item.iconHeight+'rpx'}"></image>
<view class="point radius100" v-if="orderObj.indexOf(index.toString())!=-1 && myOrder[index].num>0"></view>
</view>
<view class="txt font24 color-ff">{{item.title}}</view>
</view>
</view>
</view>
</view>
<!-- 其他资料 -->
<view class="my-content pad-all40">
<view class="item flex" v-for="(item,index) in listData" :key="index" @tap.stop="toMore(index)" v-if="showObj.indexOf(index.toString())!=-1">
<view class="title flex">
<view class="img flex">
<image :src="item.imgSrc" :style="{width:item.iconWidth+'rpx',height:item.iconHeight+'rpx'}" mode="widthFix"></image>
</view>
<view class="title font28">{{item.titele}}</view>
</view>
<view class="more">
<image src="/static/icon/icon-join.png" mode="widthFix" style="width: 14rpx;height: 26rpx;"></image>
</view>
<button class="get-phone-btn" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumberA" v-if="index==0&&mobile==''"></button>
<button class="get-phone-btn" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumberB" v-if="index==1&&mobile==''"></button>
</view>
</view>
<!-- 会员注册 -->
<view class="pull-bg" style="background-color: rgba(0,0,0,.3);" v-if="isVip || isShow"></view>
<view class="vip-box-bg border-box" v-if="isVip">
<view class="vip-box radius20 background-white font30">
<view class="title">会员注册</view>
<view class="vip-list">
<view class="vip-item mar-s20">
<view class="tips color-99">姓名</view>
<input class="input" type="text" v-model="myName" placeholder="请输入姓名" placeholder-style="color:#000000">
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">电话</view>
<input class="input" type="number" v-model="myPhone" placeholder="请输入电话" placeholder-style="color:#000000">
</view>
</view>
<view class="submit-btn font36 background-orange radius30 mar-s60 flex" @tap="submitEv"></view>
<view class="close-btn" @tap="closeEv">
<image src="/static/icon/close-btn.png" mode="widthFix"></image>
</view>
</view>
</view>
<!-- 分销码 -->
<view class="vip-box-bg border-box" v-if="isShow">
<view class="vip-box radius20 background-white font30">
<view class="title">分销二维码</view>
<view class="vip-code flex" style="padding: 40rpx 0 20rpx;">
<image :src="codeImg" mode="widthFix"></image>
</view>
<view class="submit-btn font36 radius30 color-ff mar-s60 flex" style="background-color: #00b809;position: relative;" @tap="submitEv">
<image src="/static/icon/icon-wechat.png" mode="widthFix"></image>
<text>分享给朋友</text>
<button class="shear-btn" type="primary" open-type="share"></button>
</view>
<view class="close-btn" @tap="closeEv">
<image src="/static/icon/close-btn.png" mode="widthFix"></image>
</view>
</view>
</view>
<!-- 底部tab -->
<tabbar current="0" v-if="isLoading"></tabbar>
</view>
</template>
<script>
import tabbar from '@/components/tabbar/tabbar.vue';
import {getCarInfo} from '@/jsFile/public-api.js';
import {mapState} from 'vuex'//mapState
export default {
components:{
tabbar,
},
data() {
return {
statusHeight:uni.getSystemInfoSync().statusBarHeight,
scroolTop:false, //
headPortrait:'', //
nickName:'', //
businessCode:'', //
customerSrc:'', //
vip_info:{}, //
myOrder:[
{title:'全部',tag:'all',imgSrc:'/static/icon/icon-order-01.png',num:0,iconWidth:42,iconHeight:44},
{title:'待付款',tag:'waiting',imgSrc:'/static/icon/icon-order-02.png',num:0,iconWidth:46,iconHeight:40},
{title:'已下单',tag:'paid',imgSrc:'/static/icon/icon-order-03.png',num:0,iconWidth:50,iconHeight:44},
{title:'已发货',tag:'shipped',imgSrc:'/static/icon/icon-order-04.png',num:0,iconWidth:48,iconHeight:42},
{title:'已完成',tag:'completed',imgSrc:'/static/icon/icon-order-05.png',num:0,iconWidth:49,iconHeight:44}
],//
listData:[
{titele:'个人资料',imgSrc:'/static/icon/icon-my-01.png',iconWidth:35,iconHeight:36},
{titele:'注册会员',imgSrc:'/static/icon/icon-my-02.png',iconWidth:40,iconHeight:34},
{titele:'地址管理',imgSrc:'/static/icon/icon-my-03.png',iconWidth:32,iconHeight:40},
{titele:'余额充值',imgSrc:'/static/icon/icon-my-04.png',iconWidth:34,iconHeight:28},
{titele:'积分管理',imgSrc:'/static/icon/icon-my-05.png',iconWidth:32,iconHeight:30},
{titele:'分销管理',imgSrc:'/static/icon/icon-my-06.png',iconWidth:35,iconHeight:35},
{titele:'优惠券管理',imgSrc:'/static/icon/icon-my-07.png',iconWidth:38,iconHeight:27},
{titele:'我的分享码',imgSrc:'/static/icon/icon-my-08.png',iconWidth:34,iconHeight:40},
{titele:'免责声明',imgSrc:'/static/icon/icon-my-09.png',iconWidth:40,iconHeight:40}
],//
vip_level:0,//
isVip:false, //
myName:'', //
myPhone:'', //
flag:true,
vipCode:'', //
showObj:'012345678', //
mobile:'', //
orderObj:'123', //
userInfo:'',//
isLoading:false,
shareFlag:true, //
isShow:false,
codeImg:'', //
}
},
onPageScroll(object){
if(object.scrollTop>50){
this.scroolTop = true;
}else{
this.scroolTop = false;
}
},
onHide() {
},
onShow() {
this.getUserInfo();
if(uni.getStorageSync('showVip')){
this.showVip = uni.getStorageSync('showVip');
}else{
uni.setStorageSync('showVip','true');
}
},
//
onShareAppMessage(res) {
if(res.from==='button'){//
this.isShow = false;
return {
title:'分销二维码',
imageUrl:this.codeImg,
success: function (res) {
if(res.errMsg == 'shareAppMessage:ok'){
console.log("成功",res)
}
},
fail:function(res){
console.log("失败",res)
}
}
}
},
methods: {
//
getUserInfo(){
uni.showLoading({
title:'加载中'
});
this.$requst.get('/api/user/info').then(res=>{
console.log(res,'用户信息')
if(res.code==0) {
this.userInfo = res.data;
uni.setStorageSync('business_id',res.data.business_id);
let newArr = res.data.order_count;
this.headPortrait = res.data.headimgurl;
this.nickName = res.data.nickname;
this.mobile = res.data.mobile,
this.myPhone = this.mobile,
this.businessCode = res.data.business_code;
this.vip_level = res.data.vip_level;
this.vip_info = res.data.vip_info;
this.myOrder[0].num = newArr.all;
this.myOrder[1].num = newArr.waiting;
this.myOrder[2].num = newArr.paid;
this.myOrder[3].num = newArr.shipped;
this.myOrder[4].num = newArr.completed;
if(this.vip_level!==0){
this.showObj='02345678'
}
//
this.getCodeEv();
}
uni.hideLoading();
this.isLoading = true;
})
},
//
getCodeEv(){
this.$requst.post('/api/user/my-distribution-code').then(res=>{
if(res.code == 0){
console.log(res,'分销码');
this.codeImg = this.$hostHttp + res.data.qr;
}
})
},
//
toMore(index){
if(index == 0){
if(this.mobile!==''){
uni.navigateTo({
url:`/pagesB/ucenter/ucenter`
})
}
}else if(index == 1){
if(this.vip_level == 0 && this.mobile!==''){
this.isVip = true;
}
}else if(index == 2){
uni.navigateTo({
url:`/pagesA/address/address`
})
}else if(index == 3){
uni.navigateTo({
url:`/pagesA/recharge/recharge`
})
}else if(index == 4){
uni.navigateTo({
url:`/pagesA/integral/integral`
})
}else if(index == 5){
uni.navigateTo({
url:`/pagesA/distribution/distribution`
})
}else if(index == 6){
uni.navigateTo({
url:`/pagesA/coupon/coupon`
})
}else if(index == 7){
this.isShow = true;
}else if(index == 8){
uni.navigateTo({
url:`/pagesB/disclaimers/disclaimers`
})
}
},
//
onGetPhoneNumberA(e){
if(e.detail.errMsg=="getPhoneNumber:fail user deny"){ //
this.$toolAll.tools.showToast('您已拒绝授权');
}else{ //
let params={
iv:e.detail.iv,
encryptedData:e.detail.encryptedData
}
this.$requst.post('/api/user/bind-phone',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('绑定成功');
this.getUserInfo();
uni.navigateTo({
url:`/pagesB/ucenter/ucenter`
})
}else{
this.$toolAll.tools.showToast(res.msg);
}
})
}
},
onGetPhoneNumberB(e){
if(e.detail.errMsg=="getPhoneNumber:fail user deny"){ //
this.$toolAll.tools.showToast('您已拒绝授权');
}else{ //
let params={
iv:e.detail.iv,
encryptedData:e.detail.encryptedData
}
this.$requst.post('/api/user/bind-phone',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('绑定成功');
this.getUserInfo();
this.isVip =true;
}else{
this.$toolAll.tools.showToast(res.msg);
}
})
}
},
//
submitEv(){
if(this.checkEmpty() && this.flag){
this.flag = false;
let params = {
real_name:this.myName,
mobile:this.myPhone,
}
this.$requst.post('/api/user/register-vip',params).then(res=>{
if(res.code==0) {
this.closeEv(); //
this.getUserInfo(); //
}else{
this.$toolAll.tools.showToast(res.msg);
}
setTimeout(()=>{
this.flag = true;
},2000)
})
}
},
//
checkEmpty(){
let result = false;
if(!this.myName) {
this.$toolAll.tools.showToast('请填写姓名');
} else if(this.$toolAll.tools.isPhone(this.myPhone)) {
this.$toolAll.tools.showToast('请正确填写联系电话');
} else {
result = true;
}
return result;
},
//
closeEv(){
this.isVip = false;
this.myName = '';
this.flag = true;
this.isShow = false;
},
//
changeOrder(index){
uni.navigateTo({
url:`/pagesA/order/order?tag=${this.myOrder[index].tag}&index=${index}`
})
},
//
saveImg(){
this.$toolAll.tools.saveImg(this.customerSrc);
},
//
shareImgEv(id){
this.$toolAll.tools.showToast('分享图生成中...','none',10000);
if(this.shareFlag){
this.shareFlag = false;
this.$requst.post('/api/spu/share-img',{spu_id:id}).then(res=>{
console.log(base64ToPath(res.data.poster),'分享图片')
base64ToPath(res.data.poster).then(path=>{
uni.hideToast();
this.$toolAll.tools.showToast('正在调起分享...');
wx.showShareImageMenu({
path: path,
success:(res=>{
this.shareFlag = true;
}),
fail:(err=>{
this.shareFlag = true;
})
})
})
})
} else {this.$toolAll.tools.showToast('请勿重复点击');}
},
}
}
</script>
<style>
</style>

278
pagesA/address/address.vue Normal file
View File

@ -0,0 +1,278 @@
<template>
<view class="pad-x170" v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="地址管理" :marginBottom="0"></status-nav>
<!-- 收件人信息 -->
<view class="settlement-content pad-zy20 border-box">
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30" v-for="(item,index) in addressList" :key="index">
<view class="addr-info mar-s20" @tap.stop="changeAddr(item.id)">
<view class="txt mar-x20">
<view class="font30 mar-x10">{{item.name}}<text style="margin-left: 30rpx;">{{item.phone}}</text></view>
<text class="font24 color-8c">{{item.addressMsg}}</text>
</view>
<view class="addr-bottom font28 flex">
<label class="radio flex"><radio :checked="item.is_default" @tap.stop="chooseEv(item.id)" color="#febf00"/>设为默认地址</label>
<view class="btns flex">
<view class="btn" @tap="openEdit(item.id)"></view>
<view class="btn" @tap="delAddress(item.id)"></view>
</view>
</view>
</view>
</view>
</view>
<!-- 尾部 -->
<view class="pull-btn background-white border-box">
<view class="btn background-orange font36 radius30 flex" @tap="openAdd"></view>
</view>
<!-- 地址编辑 -->
<view class="pull-bg" style="background-color: rgba(0,0,0,.3);" v-show="isShow"></view>
<view class="vip-box-bg border-box" v-if="isShow">
<view class="vip-box radius20 background-white font30">
<view class="title">收件人地址</view>
<view class="vip-list">
<view class="vip-item mar-s20">
<view class="tips color-99">姓名</view>
<input class="input" type="text" v-model="name" placeholder="请输入姓名" placeholder-style="color:#000000">
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">电话</view>
<input class="input" type="number" v-model="phone" placeholder="请输入联系电话" placeholder-style="color:#000000">
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">地址</view>
<picker mode="region" @change="change">
<view class="addr-input flex">
<view class="input-box flex">
<input class="input-flex clips1" type="text" v-model="province" disabled="true">
<image src="/static/icon/icon-shop.png" mode="widthFix"></image>
</view>
<view class="input-box flex">
<input class="input-flex clips1" type="text" v-model="city" disabled="true">
<image src="/static/icon/icon-shop.png" mode="widthFix"></image>
</view>
<view class="input-box flex">
<input class="input-flex clips1" type="text" v-model="county" disabled="true">
<image src="/static/icon/icon-shop.png" mode="widthFix"></image>
</view>
</view>
</picker>
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">详细地址</view>
<input class="input" type="number" v-model="address" placeholder="请输入详细地址" placeholder-style="color:#000000">
</view>
</view>
<view class="submit-btn font36 background-orange radius30 mar-s60 flex" @tap="editAddress(id)"></view>
<view class="close-btn" @tap="closeEv">
<image src="/static/icon/close-btn.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isShow:false, //
addressList:[], //
name:'', //
phone:'', //
province:'北京市', //
city:'北京市', //
county:'东城区',//
address:'', //
id:'', //id
changeType:'', //
flag: true, //
isLoading:false,
}
},
onLoad(op) {
if(op.type!==''){
this.changeType = op.type;
}
},
onShow() {
this.getAddress();
},
mounted() {
this.getAddress();
},
methods: {
//
changeAddr(id){
if(this.changeType == 'change'){
// id
uni.setStorageSync('addr_id',id);
//
uni.navigateBack({
delta:1,
})
}else{
return false;
}
},
//
getAddress(){
uni.showLoading({
title:'加载中'
})
this.$requst.post('/api/user/address').then(res=>{
if(res.code == 0){
console.log(res,'地址列表');
let addrArr = [];
res.data.forEach(item=>{
let addrObj = {
id:item.id,
name:item.name,
phone:item.phone,
addressMsg:item.province_str+item.city_str+item.county_str+item.address,
is_default:item.is_default
}
addrArr.push(addrObj);
})
this.addressList = addrArr;
}
uni.hideLoading();
this.isLoading = true;
})
},
// &
editAddress(){
if(this.checkEmpty() && this.flag){
let params ={
id:this.id==''?'':this.id,
name:this.name,
phone:this.phone,
province_str:this.province,
city_str:this.city,
county_str:this.county,
address:this.address
}
console.log(params,'地址信息');
this.$requst.post('/api/user/address-save',params).then(res=>{
if(res.code == 0){
if(this.id == ''){
this.$toolAll.tools.showToast('新增成功');
}else{
this.$toolAll.tools.showToast('编辑成功');
}
//
this.closeEv();
//
this.getAddress();
setTimeout(()=>{
this.flag = true;
},1200)
}else{
this.$toolAll.tools.showToast(res.msg);
setTimeout(()=>{
this.flag = true;
},1200)
}
})
}
},
//
checkEmpty(){
let result = false;
if(!this.name) {
this.$toolAll.tools.showToast('请填写联系人');
} else if(this.$toolAll.tools.isPhone(this.phone)) {
this.$toolAll.tools.showToast('请正确填写联系电话');
} else if(!this.province && !this.city && !this.county) {
this.$toolAll.tools.showToast('请选择地址');
} else if(!this.address) {
this.$toolAll.tools.showToast('请填写详细地址');
} else {
result = true;
}
return result;
},
//
getAddressInfo(id){
this.$requst.post('/api/user/address-info',{id:id}).then(res=>{
if(res.code == 0){
this.name = res.data.name;
this.phone = res.data.phone;
this.province = res.data.province_str;
this.city = res.data.city_str;
this.county = res.data.county_str;
this.address = res.data.address;
this.isShow = true;
}
})
},
//
chooseEv(id){
if(this.flag){
this.$requst.post('/api/user/address-set-default',{id:id}).then(res=>{
if(res.code == 0){
this.$toolAll.tools.showToast('设置成功');
//
this.getAddress();
setTimeout(()=>{
this.flag = true;
},1200)
}
})
}
},
//
delAddress(id){
if(this.flag){
this.$requst.post('/api/user/address-del',{id:id}).then(res=>{
if(res.code == 0){
this.$toolAll.tools.showToast('删除成功');
//
this.getAddress();
setTimeout(()=>{
this.flag = true;
},1200)
}
})
}
},
//
openEdit(id){
if(id!==''){
this.id = id;
this.getAddressInfo(id);
}
},
//
openAdd(){
this.isShow = true;
this.name = '';
this.phone = '';
this.province = '北京市';
this.city = '北京市';
this.county = '东城区';
this.address = '';
},
//
change(e){
this.province = e.detail.value[0];
this.city = e.detail.value[1];
this.county = e.detail.value[2];
},
//
closeEv(){
this.isShow = false;
},
}
}
</script>
<style>
</style>

115
pagesA/coupon/coupon.vue Normal file
View File

@ -0,0 +1,115 @@
<template>
<view v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="优惠券" :marginBottom="0"></status-nav>
<!-- 优惠券 -->
<view class="record-nav border-box flex" style="background-color: #f5f5f5;padding: 40rpx 20rpx;margin: 0;">
<view class="item color-8c radius20 border-box" :class="index==navIndex?'cur':''" v-for="(item,index) in navList" :key="index" @tap="changeNav(index)">{{item.title}}</view>
</view>
<!-- 优惠券列表 -->
<view class="coupon-list pad-zy20 border-box">
<view class="coupon-item radius30 mar-s40 flex" :class="navIndex==2?'grey':''" v-for="(item,index) in couponList" :key="index">
<view class="price color-ff border-box"><text class="font30"></text>{{parseInt(item.amount)}}</view>
<view class="txt">
<view class="font36">{{item.name}}</view>
<view class="font24 color-8c mar-s10">{{parseInt(item.condition)}}{{parseInt(item.amount)}}</view>
<view class="font24 color-8c mar-s10">{{item.begin_at}}{{item.end_at}}</view>
</view>
<view class="btn mar-zy20 color-ff font24" v-if="navIndex==0" @tap="useEv">使</view>
<view class="btn mar-zy20 color-ff font24" v-if="navIndex==1" @tap="receiveEv(item.id,index)"></view>
</view>
</view>
<!-- 到底啦 -->
<view class="no-more font24" v-if="noMore" style="margin-top: 20rpx;"><text> 到底啦 </text></view>
</view>
</template>
<script>
export default {
data() {
return {
navList:[
{title:'已领取',tag:'normal'},
{title:'可领取',tag:'waiting'},
{title:'已过期',tag:'invalid'}
], //
navIndex:0, //
couponList:[], //
page:1,
size:10,
noMore:false,
isLoading:false,
}
},
onLoad(op) {
if(op.index){
this.navIndex = op.index;
}
},
onShow() {
this.getCouponEv();
},
onReachBottom() {
if(!this.noMore){
this.page++;
//
this.getCouponEv();
}
},
methods: {
//
getCouponEv(){
uni.showLoading({
title:'加载中'
})
let params = {
page:this.page,
size:this.size,
status:this.navList[this.navIndex].tag
}
this.$requst.post('/api/user/get-coupon-list',params).then(res=>{
if(res.code == 0){
console.log(res,'优惠券列表');
if(res.data.length == 0){
this.noMore = true;
}
this.couponList = this.couponList.concat(res.data);
}
uni.hideLoading();
this.isLoading = true;
})
},
// 使
useEv(){
//
uni.reLaunch({
url:`/pages/index/index`
})
},
//
receiveEv(id){
this.$requst.get('/api/user/get-coupon',{coupon_id:id}).then(res=>{
if(res.code == 0){
this.$toolAll.tools.showToast('领取成功');
this.couponList.splice(index,1)
}
})
},
//
changeNav(index){
if(index!==this.navIndex){
this.navIndex = index;
//
this.noMore = false;
this.couponList = [];
this.page = 1;
//
this.getCouponEv();
}
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,423 @@
<template>
<view class="pad-x150" v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="分销中心" :marginBottom="0"></status-nav>
<!-- 分销概况 -->
<view class="distribution border-box">
<view class="distribution-msg radius30 pad-all40 border-box">
<view class="distribution-txt border-box flex">
<view class="txt">
<view class="title font30 mar-x20">我的佣金</view>
<view class="price font60"><text class="font48"></text>{{commission}}</view>
</view>
<view class="code-btn mar-s10" @tap="openCode">
<image src="/static/icon/icon-code.png" mode="widthFix" style="width: 87rpx;height: 87rpx;"></image>
<view class="font24 mar-s10">查看分销码</view>
</view>
</view>
<view class="distribution-profit mar-s40 flex">
<view class="item">
<text class="font24">累计收益</text>
<view class="profit-price font36 mar-s10">{{cumulative_income>0?cumulative_income:'0'}}</view>
</view>
<view class="line"></view>
<view class="item">
<text class="font24">累计提现</text>
<view class="profit-price font36 mar-s10">{{cumulative_withdrawal>0?cumulative_withdrawal:'0'}}</view>
</view>
<view class="line"></view>
<view class="item">
<text class="font24">我的团队</text>
<view class="profit-price font36 mar-s10">{{my_team}}</view>
</view>
</view>
</view>
</view>
<!-- 记录导航 -->
<view class="record-nav border-box pad-zy20 flex">
<view class="item color-8c radius20 border-box" :class="index==navIndex?'cur':''" v-for="(item,index) in navList" :key="index" @tap="changeNav(index)">{{item}}</view>
</view>
<!-- 记录列表 -->
<view class="record-list border-box">
<!-- 团队导航 -->
<view class="team-nav flex" v-if="navIndex==1">
<view class="item" v-for="(item,index) in teamNav" :key="index" @tap="changeTeam(index)">
<view class="txt font30">{{item}}</view>
<view class="line mar-s15" :class="index==teamIndex?'background-orange':''"></view>
</view>
</view>
<view class="record-item border-box pad-sx40 flex" v-for="(item,index) in recordList" :key="index">
<view class="left flex">
<view class="img radius30" v-if="item.cover">
<image :src="item.cover" mode="widthFix"></image>
</view>
<view class="txt">
<view class="font36 mar-x10"><text class="font26" v-if="navIndex==2"></text>{{item.name}}</view>
<view class="font24 color-99">{{item.created_at}}</view>
</view>
</view>
<view class="right">
<view class="font24" v-if="navIndex==2">
<text v-if="item.title=='待审批'">{{item.title}}</text>
<text class="color-red" v-if="item.title=='已驳回'">{{item.title}}</text>
<text style="color: #7b7b7b;" v-if="item.title=='已完成'">{{item.title}}</text>
</view>
<view class="font24" v-else>{{item.title}}</view>
<view class="font30 color-red mar-s10" v-if="item.price">{{item.price>0&&navIndex==0?'+'+item.price:item.price}}</view>
</view>
</view>
<!-- 到底啦 -->
<view class="no-more font24" v-if="noMore"><text> 到底啦 </text></view>
</view>
<!-- 尾部 -->
<view class="pull-btn border-box" style="background-color: #f5f5f5; padding-top: 28rpx;">
<view class="btn background-orange font36 radius30 flex" @tap="openWithdrawal"></view>
</view>
<!-- 分销码 -->
<view class="pull-bg" style="background-color: rgba(0,0,0,.3);" v-show="isShow || withdrawal"></view>
<view class="vip-box-bg border-box" v-if="isShow">
<view class="vip-box radius20 background-white font30">
<view class="title">分销二维码</view>
<view class="vip-code flex">
<image :src="codeImg" mode="widthFix"></image>
</view>
<view class="submit-btn font36 radius30 color-ff mar-s60 flex" style="background-color: #00b809;position: relative;">
<image src="/static/icon/icon-wechat.png" mode="widthFix"></image>
<text>分享给朋友</text>
<button class="shear-btn" type="primary" open-type="share"></button>
</view>
<view class="close-btn" @tap="closeEv">
<image src="/static/icon/close-btn.png" mode="widthFix"></image>
</view>
</view>
</view>
<!-- 提现 -->
<view class="vip-box-bg border-box" v-if="withdrawal">
<view class="vip-box radius20 background-white font30">
<view class="title">提现申请</view>
<view class="vip-list">
<view class="vip-item mar-s20">
<view class="tips color-99">提现金额</view>
<input class="input" type="number" v-model="myPrice" placeholder="请输入提现金额" placeholder-style="color:#000000">
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">姓名</view>
<input class="input color-99" type="text" v-model="real_name" disabled="true">
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">开户行</view>
<input class="input color-99" type="number" v-model="deposit_bank" disabled="true">
</view>
<view class="vip-item mar-s40">
<view class="tips color-99">银行卡号</view>
<input class="input color-99" type="number" v-model="bank_account" disabled="true">
</view>
</view>
<view class="submit-btn font36 background-orange radius30 mar-s60 flex" @tap="submitEv"></view>
<view class="close-btn" @tap="closeEv">
<image src="/static/icon/close-btn.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isShow:false, //
withdrawal:false, //
navList:['返利记录','我的团队','提现记录'], //
navIndex:0, //
teamNav:['经销商团队','我的消费团'], //
teamIndex:0, //
recordList:[], //
commission:0, //
cumulative_income:0, //
cumulative_withdrawal:0, //
my_team:0, //
codeImg:'', //
real_name:'', //
bank_account:'',//
deposit_bank:'', //
myPrice:'', //
page:1,
size:10,
noMore:false,
flag:true,
isLoading:false,
}
},
onLoad(op) {
// //
// this.getRebateEv();
// //
// this.getMyTeam();
// //
// this.getWithdrawal();
//
this.getCodeEv();
//
this.getRecordList();
},
//
onShareAppMessage(res) {
this.isShow = false;
if(res.from==='button'){//
return {
title:'分销二维码',
imageUrl:this.codeImg,
success: function (res) {
if(res.errMsg == 'shareAppMessage:ok'){
console.log("成功",res)
}
},
fail:function(res){
console.log("失败",res)
}
}
}
},
onReachBottom() {
if(!this.noMor){
this.page++;
//
this.getRecordList();
}
},
onShow() {
this.getUserInfo();
},
methods: {
//
getUserInfo(){
this.$requst.post('/api/user/info').then(res=>{
if(res.code == 0){
console.log(res,'用户信息');
this.commission = res.data.commission;
this.cumulative_income = this.$toolAll.tools.addXiaoShu(res.data.cumulative_income);
this.cumulative_withdrawal = this.$toolAll.tools.addXiaoShu(res.data.cumulative_withdrawal);
this.my_team = res.data.my_team;
}
})
},
//
getCodeEv(){
this.$requst.post('/api/user/my-distribution-code').then(res=>{
if(res.code == 0){
console.log(res,'分销码');
this.codeImg = this.$hostHttp + res.data.qr;
}
})
},
//
getRecordList(){
uni.showLoading({
title:'加载中'
})
if(this.navIndex == 0){
let params = {
page:this.page,
size:this.size,
type:'commission'
}
this.$requst.post('/api/user/data-log-list',params).then(res=>{
if(res.code==0){
console.log(res,'返利记录');
let recordArr = [];
res.data.forEach(item=>{
let obj = {
id:item.id,
name:item.subAccount==null?'':item.subAccount.nickname,
cover:item.subAccount==null?'':item.subAccount.headimgurl,
created_at:item.created_at,
title:item.name,
price:this.$toolAll.tools.addXiaoShu(item.num)
}
recordArr.push(obj);
})
if(recordArr.length==0){
this.noMor = true;
}
this.recordList = this.recordList.concat(recordArr);
}
})
}
if(this.navIndex == 1){
if(this.teamIndex == 0){
let params = {
page:this.page,
size:this.size,
is_distributor:1
}
this.$requst.post('/api/user/team-list',params).then(res=>{
if(res.code==0){
console.log(res,'经销商团队');
let recordArr = [];
res.data.forEach(item=>{
let obj = {
id:item.id,
name:item.nickname,
cover:item.headimgurl,
created_at:item.created_at,
title:'累计返利',
price:this.$toolAll.tools.addXiaoShu(item.contribution)
}
recordArr.push(obj);
})
if(recordArr.length==0){
this.noMor = true;
}
this.recordList = this.recordList.concat(recordArr);
}
})
}else{
let params = {
page:this.page,
size:this.size,
is_distributor:0
}
this.$requst.post('/api/user/team-list',params).then(res=>{
if(res.code==0){
console.log(res,'我的消费团队');
let recordArr = [];
res.data.forEach(item=>{
let obj = {
id:item.id,
name:item.nickname,
cover:item.headimgurl,
created_at:item.created_at,
title:'累计返利',
price:this.$toolAll.tools.addXiaoShu(item.contribution)
}
recordArr.push(obj);
})
if(recordArr.length==0){
this.noMor = true;
}
this.recordList = this.recordList.concat(recordArr);
}
})
}
}
if(this.navIndex == 2){
let params = {
page:this.page,
size:this.size
}
this.$requst.post('/api/user/withdrawal-commission-log-list',params).then(res=>{
if(res.code==0){
console.log(res,'提现列表');
let recordArr = [];
res.data.forEach(item=>{
let obj = {
id:item.id,
name:this.$toolAll.tools.addXiaoShu(item.number),
cover:'',
created_at:item.created_at,
title:item.status,
price:''
}
recordArr.push(obj);
})
if(recordArr.length==0){
this.noMor = true;
}
this.recordList = this.recordList.concat(recordArr);
}
})
}
uni.hideLoading();
this.isLoading = true;
},
//
openCode(){
this.isShow = true;
},
//
openWithdrawal(){
this.$requst.post('/api/user/get-deposit-bank-info').then(res=>{
if(res.code==0){
console.log(res,'提现账户信息');
this.real_name = res.data.real_name;
this.bank_account =res.data.bank_account;
this.deposit_bank = res.data.deposit_bank;
this.withdrawal = true;
}
})
},
//
submitEv(){
if(this.checkEmpty() && this.flag){
let params = {
commission:this.myPrice,
username:this.real_name,
deposit_bank:this.deposit_bank,
bank_account:this.bank_account
}
this.$requst.post('/api/user/commission-withdrawal',params).then(res=>{
if(res.code==0){
console.log(res,'提现成功');
this.withdrawal = false;
this.getUserInfo();
}else{
this.$toolAll.tools.showToast(res.msg);
}
setTimeout(()=>{
this.flag = true;
},2000)
})
}
},
//
checkEmpty(){
let result = false;
if(!this.myPrice) {
this.$toolAll.tools.showToast('请填写提现金额');
} else {
result = true;
}
return result;
},
//
changeNav(index){
if(index!==this.navIndex){
this.navIndex = index;
this.page = 0;
this.recordList = [];
//
this.getRecordList();
}
},
//
changeTeam(index){
if(index!==this.teamIndex){
this.teamIndex = index;
this.page = 0;
this.recordList = [];
//
this.getRecordList();
}
},
//
closeEv(){
this.isShow = false;
this.withdrawal =false;
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,109 @@
<template>
<view v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="我的积分" :marginBottom="0"></status-nav>
<!-- 余额概况 -->
<view class="recharge border-box">
<view class="recharge-msg radius30 border-box">
<view class="txt flex">
<text class="font30">我的积分</text>
<text class="font24" @tap="goIntegralRule"></text>
</view>
<view class="price font60">{{score}}</view>
</view>
</view>
<!-- 明细 -->
<view class="recharge-detailed border-box pad-all20 mar-s20">
<view class="recharge-title font30 flex">
<view class="line background-orange"></view>
<text>积分明细</text>
</view>
<view class="detailed-list">
<view class="detailed-item font30 border-box pad-sx20 flex" v-for="(item,index) in detailedList" :key="index">
<view class="txt">
<view class="name mar-x10">{{item.name}}</view>
<view class="time font24 color-99">{{item.created_at}}</view>
</view>
<view class="price" style="margin-right: 10rpx;" :class="item.num<0?'color-red':''">{{item.num}}</view>
</view>
</view>
</view>
<!-- 到底啦 -->
<view class="no-more font24" style="margin-top: 20rpx;" v-if="noMore"><text> 到底啦 </text></view>
</view>
</template>
<script>
export default {
data() {
return {
detailedList:[],//
score:0, //
page:1,
size:10,
total:0,
noMore:false,
isLoading:false,
}
},
onShow() {
//
this.getUserInfo();
},
onReachBottom() {
if(!this.noMore){
this.page++;
//
this.getScoreEV();
}
},
methods: {
//
getUserInfo(){
this.$requst.post('/api/user/info').then(res=>{
if(res.code == 0){
console.log(res,'用户信息');
this.score = res.data.score;
this.detailedList = [];
//
this.getScoreEV();
}
})
},
//
getScoreEV(){
uni.showLoading({
title:'加载中'
})
let params = {
page:this.page,
size:this.size,
type:'score'
}
this.$requst.post('/api/user/data-log-list',params).then(res=>{
if(res.code == 0){
console.log(res,'积分明细');
if(res.data==0){
this.noMore = true;
}
this.detailedList = this.detailedList.concat(res.data);
}
uni.hideLoading();
this.isLoading = true;
})
},
//
goIntegralRule(){
uni.navigateTo({
url:`/pagesB/integral-rule/integral-rule`
})
}
}
}
</script>
<style>
</style>

199
pagesA/order/detail.vue Normal file
View File

@ -0,0 +1,199 @@
<template>
<view class="pad-x170" v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="订单详情" :marginBottom="0"></status-nav>
<!-- 收件人信息 -->
<view class="settlement-content pad-zy20 border-box">
<!-- 订单简介 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="order-info pad-zy20 border-box">
<view class="flex mar-s20">
<text>订单编号</text>
<text>{{orderDetail.coding}}</text>
</view>
<view class="flex mar-s20">
<text>下单时间</text>
<text>{{orderDetail.created_at}}</text>
</view>
<view class="flex mar-s20">
<text>订单状态</text>
<text>{{orderDetail.status_text}}</text>
</view>
</view>
</view>
<!-- 订单信息 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">订单信息</view>
<view class="shop-slide-list">
<view class="shop-slide-item">
<view class="item border-box background-white flex" v-for="(item,index) in orderDetail.skus" :key="index">
<view class="shop-img radius30">
<image :src="item.spu_cover" mode="widthFix"></image>
</view>
<view class="shop-txt">
<view class="shop-txt-top">
<view class="title font30 clips1">{{item.spu_name}}</view>
<view class="specs font24 color-66 mar-sx10 clips2">规格{{item.sku_name}}</view>
</view>
<view class="shop-txt-bottom flex">
<!-- 商品价格 -->
<view class="price font30 color-red">{{item.price}}<text class="font24 color-66">x{{item.num}}</text></view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 收货信息 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30">
<view class="title">收货信息</view>
<view class="addressee-info mar-s20 flex">
<view class="txt">
<view class="font30 mar-x10">{{orderDetail.address_info.name}}<text>{{orderDetail.address_info.phone}}</text></view>
<text class="font24 color-8c">{{orderDetail.address_info.province_str}}{{orderDetail.address_info.city_str}}{{orderDetail.address_info.county_str}}{{orderDetail.address_info.address}}</text>
</view>
</view>
</view>
<!-- 物流信息 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30" v-if="orderDetail.express_name!==''">
<view class="title">物流信息</view>
<view class="addressee-info mar-s20 flex">
<view class="txt" style="width: 100%;">
<view class="font30 mar-x10">{{orderDetail.express_name}}</view>
<view class="txt-coding font24 flex" style="margin-top: 10rpx;">
<text class="color-8c">快递单号{{orderDetail.express_number}}</text>
<view class="copy_btn" @tap="copyEV"></view>
</view>
</view>
</view>
</view>
<!-- 付款信息 -->
<view class="section background-white radius30 mar-x40 pad-all25 border-box font30" v-if="orderDetail.status!=='waiting'">
<view class="pay-info">
<view class="flex">
<text>商品总金额</text>
<text class="color-red">{{orderDetail.original_price}}</text>
</view>
<view class="flex mar-s20">
<text>折扣优惠</text>
<text class="color-red">{{orderDetail.discount_money>0?orderDetail.discount_money:0}}</text>
</view>
<view class="flex mar-s20">
<text>积分抵扣</text>
<text class="color-red">{{orderDetail.score_deduction_money>0?orderDetail.score_deduction_money:0}}</text>
</view>
<view class="pay-actual mar-s30 flex">实付款:<text class="color-red font36">{{priceAll>0?'¥'+ priceAll:0}}</text></view>
</view>
</view>
</view>
<!-- 尾部 -->
<view class="pull-btn background-white border-box" style="box-shadow: 0 -9rpx 21rpx rgba(0,0,0,.1);">
<view class="btn border-btn border-box color-8c font36 radius30 flex" @tap="cancleEv(orderDetail.coding)" v-if="orderDetail.status == 'waiting' || orderDetail.status == 'paid'"></view>
<view class="btn border-box background-orange color-ff font36 radius30 flex" @tap="affirmEv(orderDetail.id)" v-if="orderDetail.status == 'shipped'"></view>
<view class="btn border-btn border-box color-8c font36 radius30 flex" @tap="buyAgain" v-if="orderDetail.status == 'completed' || orderDetail.status == 'closed'"></view>
</view>
</view>
</template>
<script>
import {getCartInfo} from '@/jsFile/public-api.js';
import {mapState} from 'vuex'//mapState
export default {
data() {
return {
orderDetail:{}, //
flag:true,
isLoading:false,
id:0, //id
priceAll:'', //
}
},
onLoad(op) {
if(op.id !== ''){
this.id = op.id;
}
this.getOrderDetail();
},
//
onShareAppMessage() {
},
//
onShareTimeline(res){
},
methods: {
//
getOrderDetail(){
uni.showLoading({
title:'加载中'
});
this.$requst.get('/api/user/order-detail',{id:this.id}).then(res=>{
if(res.code==0){
console.log(res,'订单详情')
this.orderDetail = res.data;
this.priceAll = this.$toolAll.tools.addXiaoShu(parseFloat(res.data.balance) + parseFloat(res.data.wechat));
}
uni.hideLoading();
this.isLoading = true;
})
},
//
cancleEv(coding){
let params = {
order_coding: coding //
}
this.$requst.post('/api/order/cancel',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('取消订单成功(*^▽^*)');
uni.navigateTo({
url:'/pagesA/order/order'
})
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
},
//
affirmEv(id){
let params = {
order_id: id //
}
this.$requst.post('/api/order/accepted',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('确认收货成功(*^▽^*)');
uni.navigateTo({
url:'/pagesA/order/order'
})
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
},
//
buyAgain(index){
let buyList = [];
let newArr = this.orderDetail;
newArr.skus.forEach(item=>{
let obj = {
sku_coding: item.coding,
num: item.num
}
buyList.push(obj);
})
uni.setStorageSync('buyList',buyList);
uni.navigateTo({
url:'/pages/cart/settlement'
})
},
//
copyEV(){
this.$toolAll.tools.clickCopy(this.orderDetail.express_number);
},
}
}
</script>
<style scoped>
</style>

298
pagesA/order/order.vue Normal file
View File

@ -0,0 +1,298 @@
<template>
<view v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="订单管理" :marginBottom="0"></status-nav>
<!-- 订单搜索 -->
<view class="order-search">
<input class="input font30 pad-zy40 color-66 radius20 border-box" type="text" placeholder="请输入订单编号" placeholder-style="color:#666666">
</view>
<!-- 订单导航 -->
<view class="order-nav-bg mar-s30" :style="{top:newTop+'px'}">
<scroll-view scroll-x="true" :scroll-left="tabsScrollLeft" @scroll="scroll">
<view class="order-nav flex" id="tab_list" :style="{width:navWidth}">
<view id="tab_item" class="item font30 color-8c radius20" :class="activeIndex == index?'cur':''" v-for="(item,index) in orderNav" @tap="changeNav(index,item.tag)">{{item.title}}</view>
</view>
</scroll-view>
</view>
<!-- 订单列表 -->
<view class="order-list">
<view class="order-item" @tap.stop="toDetail(item.id)" v-for="(item,index) in orderList" :key="index">
<view class="order-code flex">
<text>订单号{{item.coding}}</text>
<text class="status color-red" v-if="item.status=='waiting'">{{item.status_text}}</text>
<text class="status" style="color: #02d20b;" v-if="item.status=='paid' || item.status=='shipped'">{{item.status_text}}</text>
<text class="status color-99" v-if="item.status=='completed' || item.status=='closed'">{{item.status_text}}</text>
</view>
<view class="item-bg">
<view class="item flex" v-for="(item1,index1) in item.skus" :key="index1">
<view class="img"><image :src="item1.spu_cover" mode="widthFix"></image></view>
<view class="txt">
<view class="title clips1">{{item1.spu_name}}</view>
<view class="specs clips2">规格{{item1.sku_name}}</view>
<view class="price flex">
<text>{{item1.price}}</text>
<view><text>x</text>{{item1.num}}</view>
</view>
</view>
</view>
</view>
<view class="total-price flex">
<text>合计{{item.price}}</text>
<view class="btns flex" v-if="item.status == 'waiting'">
<view class="btn border-box" @tap.stop="cancleEv(item.coding)">取消订单</view>
<view class="btn btn-01 border-box" @tap.stop="payEv(item.coding)">立即支付</view>
</view>
<view class="btns flex" v-if="item.status == 'paid'">
<view class="btn border-box" @tap.stop="cancleEv(item.coding)">取消订单</view>
</view>
<view class="btns flex" v-if="item.status == 'shipped'">
<view class="btn btn-02 border-box background-orange" @tap.stop="affirmEv(item.id)">确认收货</view>
</view>
<view class="btns flex" v-if="item.status == 'completed' || item.status == 'closed'">
<view class="btn border-box" @tap.stop="buyAgain(index)">再次购买</view>
</view>
</view>
</view>
</view>
<!-- 到底啦 -->
<view class="no-more font24" style="margin: 0;padding: 25rpx 0;" v-if="total!==0&&totalAll==total"><text> 到底啦 </text></view>
<!-- 没有内容 -->
<nothing-page v-if="total==0&&totalAll == total" content="还没有相关订单哟(*^▽^*)"></nothing-page>
</view>
</template>
<script>
import {getCartInfo} from '@/jsFile/public-api.js';
import {mapState} from 'vuex'//mapState
export default {
data() {
return {
newTop:uni.getSystemInfoSync().statusBarHeight + 50,
orderNav:[
{title:'全部',tag:'all'},
{title:'待付款',tag:'waiting'},
{title:'已下单',tag:'paid'},
{title:'已发货',tag:'shipped'},
{title:'已完成',tag:'completed'},
],
activeIndex:0,
scrollLeft:0,
tabsScrollLeft:0,
navWidth:'', //
orderList:[],
flag:true,
isLoading:false,
total:0,
totalAll:-1,
page: 1,
size: 10,
tag: 'all'
}
},
onLoad(op) {
if(op.tag !== ''){
this.tag = op.tag;
}
if(op.index !== ''){
this.activeIndex = op.index;
}
this.navWidth = this.orderNav.length*150 - 20 + 'rpx';
//
this.setTabList();
},
onShow() {
this.getOrderList();
},
onReachBottom(e) {
if(this.orderList.length<this.total){
this.page++;
this.getOrderList();
}
},
//
onShareAppMessage() {
},
//
onShareTimeline(res){
},
methods: {
//
changeNav(index,tag) {
this.total=0;
this.totalAll=-1;
this.activeIndex = index;
this.tag = tag;
this.orderList=[];
this.page = 1;
this.getOrderList();
//
this.setTabList();
},
//
getOrderList(){
uni.showLoading({
title:'加载中'
});
let params = {
page: this.page,
size: this.size,
tag: this.tag
}
this.$requst.get('/api/user/order',params).then(res=>{
console.log(res,'订单列表')
if(res.data.length!=0){
this.total = res.data.total;
let newArr = [];
res.data.list.forEach(item=>{
let obj = {
id: item.id, //id
coding: item.coding, //
price: item.price, //
status: item.status, //
status_text: item.status_text, //
skus: item.skus //
}
newArr.push(obj);
})
this.orderList = this.orderList.concat(newArr);
if(this.orderList.length == this.total){
this.totalAll = this.total;
}
}
uni.hideLoading();
this.isLoading = true;
})
},
//
toDetail(id){
uni.navigateTo({
url:`/pagesA/order/detail?id=${id}`
})
},
//
cancleEv(coding){
let params = {
order_coding: coding //
}
this.$requst.post('/api/order/cancel',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('取消订单成功(*^▽^*)');
this.orderList = [];
this.page = 1;
this.getOrderList();
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
},
//
affirmEv(id){
let params = {
order_id: id //
}
this.$requst.post('/api/order/accepted',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('确认收货成功(*^▽^*)');
this.orderList = [];
this.page = 1;
this.getOrderList();
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
},
//
buyAgain(index){
let buyList = [];
let newArr = this.orderList[index];
newArr.skus.forEach(item=>{
let obj = {
sku_coding: item.coding,
num: item.num
}
buyList.push(obj);
})
uni.setStorageSync('buyList',buyList);
uni.navigateTo({
url:'/pages/cart/settlement'
})
},
//
payEv(coding){
this.$requst.post('/api/order/pay',{order_coding:coding}).then(res=>{
if(res.code==0) {
console.log(res,'立即支付');
//
this.callPayMent(res.data.payment_params)
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
},
//
callPayMent(data){
//
wx.requestPayment({
'timeStamp': data.timeStamp,
'nonceStr': data.nonceStr,
'package': data.package,
"signType": data.signType,
'paySign': data.sign,
'success': function (res) { //
console.log('支付成功:',res);
this.$toolAll.tools.showToast('支付成功(*^▽^*)');
uni.navigateTo({
url:`/pages/cart/finish`
})
},
'fail': function (res) { //
console.log('支付失败:' + JSON.stringify(res));
}
})
},
//
setTabList() {
this.$nextTick(() => {
if (this.orderNav.length > 0) {
//
this.setLeft()
}
})
},
//
setLeft() {
let lineLeft = 0;
this.getElementData('#tab_list', (data) => {
let list = data[0];
this.getElementData('#tab_item', (res) => {
let el = res[this.activeIndex]
lineLeft = el.width / 2 + (-list.left) + el.left - list.width / 2 - this.scrollLeft
this.tabsScrollLeft = this.scrollLeft + lineLeft
})
})
},
// DOM
getElementData(el, callback) {
uni.createSelectorQuery().in(this).selectAll(el).boundingClientRect().exec((data) => {
callback(data[0]);
});
},
//
scroll(e) {
this.scrollLeft = e.detail.scrollLeft;
},
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,191 @@
<template>
<view class="pad-x170" v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="我的余额" :marginBottom="0"></status-nav>
<!-- 余额概况 -->
<view class="recharge border-box">
<view class="recharge-msg radius30 border-box">
<view class="txt flex">
<text class="font30">我的余额</text>
<text class="font24">余额可用于购物使用</text>
</view>
<view class="price font60"><text class="font48"></text>{{balance}}</view>
</view>
</view>
<!-- 充值金额 -->
<view class="recharge-amount border-box pad-all20 mar-s20">
<view class="recharge-title font30 flex">
<view class="line background-orange"></view>
<text>充值金额</text>
</view>
<view class="amount-list flex">
<view class="amount-item border-box radius20 mar-s25" @tap="changeAmount(index)" :class="index==amountIndex?'checked':''" v-for="(item,index) in amountList" :key="index">
<view class="font48 mar-s15">{{parseInt(item.money)}}</view>
<text class="font24">售价{{parseInt(item.price)}}</text>
</view>
</view>
</view>
<!-- 明细 -->
<view class="recharge-detailed border-box pad-all20 mar-s20">
<view class="recharge-title font30 flex">
<view class="line background-orange"></view>
<text>消费明细</text>
</view>
<view class="detailed-list">
<view class="detailed-item font30 border-box pad-sx20 flex" v-for="(item,index) in detailedList" :key="index">
<view class="txt">
<view class="name mar-x10">{{item.title}}</view>
<view class="time font24 color-99">{{item.create_time}}</view>
</view>
<view class="price" :class="parseFloat(item.money)<0?'color-red':''">{{item.money}}</view>
</view>
</view>
</view>
<!-- 尾部 -->
<view class="pull-footer-bg background-white pad-all20 radius30 border-box">
<view class="pull-footer background-grey radius30 pad-all20 border-box flex">
<view class="price color-ff" style="margin-left: 24rpx;">
<view class="font60 flex">{{amountPrice}}</view>
</view>
<view class="btn font36 color-48 background-orange radius30 flex" @tap="submitEv"></view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
amountList:[],//
amountIndex:0, //
amountPrice:'', //
detailedList:[],//
balance:'', //
flag:true,
isLoading:false,
}
},
onShow() {
//
this.getUserInfo();
//
this.getAmountMode();
},
methods: {
//
getUserInfo(){
this.$requst.post('/api/user/info').then(res=>{
if(res.code == 0){
console.log(res,'用户信息');
this.balance = res.data.balance;
//
this.getPeiceDetailed();
}
})
},
//
getAmountMode(){
this.$requst.post('/api/user/recharge-template-list').then(res=>{
if(res.code == 0){
console.log(res,'充值模板');
let amountArr = [];
res.data.forEach(item=>{
let amountObj = {
id:item.id,
name:item.name,
money:item.money,
price:item.price,
status:item.status
}
amountArr.push(amountObj);
})
this.amountList = amountArr;
this.amountPrice = this.$toolAll.tools.addXiaoShu(this.amountList[0].price);
}
})
},
//
getPeiceDetailed(){
uni.showLoading({
title:'加载中'
})
this.$requst.post('/api/user/balance-log-list',{template_id:this.amountList[this.amountIndex].id}).then(res=>{
if(res.code == 0){
console.log(res,'余额记录');
this.detailedList = res.data;
}
uni.hideLoading();
this.isLoading = true;
})
},
//
changeAmount(index){
if(index!==this.amountIndex){
this.amountIndex = index;
this.amountPrice = this.$toolAll.tools.addXiaoShu(this.amountList[index].price);
}
},
//
submitEv(){
if(this.flag){
this.$requst.post('/api/recharge/create',{template_id:this.amountList[this.amountIndex].id}).then(res=>{
if(res.code == 0){
console.log(res,'发起充值');
//
this.callPayMent(res.data);
}else{
this.$toolAll.tools.showToast(res.msg);
}
})
}
},
//
callPayMent(data){
//
wx.requestPayment({
'timeStamp': data.timeStamp,
'nonceStr': data.nonceStr,
'package': data.package,
"signType": data.signType,
'paySign': data.sign,
'success': function (res) { //
console.log('支付成功:',res);
this.amountConfirm(data.coding);
},
'fail': function (res) { //
console.log('支付失败:' + JSON.stringify(res));
}
})
},
//
amountConfirm(coding){
this.$requst.post('/api/recharge/paid',{order_coding:coding}).then(res=>{
if(res.code == 0){
console.log(res,'充值成功');
this.$toolAll.tools.showToast('充值成功');
//
this.getUserInfo();
setTimeout(()=>{
this.flag = true;
},1200)
}else{
this.$toolAll.tools.showToast(res.msg);
setTimeout(()=>{
this.flag = true;
},1200)
}
})
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,47 @@
<template>
<view>
<status-nav :ifReturn="true" navBarTitle="免责声明" :marginBottom="0"></status-nav>
<!-- 内容 -->
<view class="disclaimers border-box" :style="{'min-height':disclaimersHeight}">
<view class="disclaimers-txt font24 color-8c">
<rich-text :nodes="disclaimers"></rich-text>
</view>
</view>
</view>
</template>
<script>
import {mapState} from 'vuex'//mapState
export default {
data() {
return {
disclaimersHeight: `calc(100vh - ${uni.getSystemInfoSync().statusBarHeight + 50}px)`,
disclaimers:'',
}
},
onLoad(op) {
//
this.getDisclaimers();
},
methods: {
//
getDisclaimers(){
uni.showLoading({
title:'加载中'
});
this.$requst.get('/api/index/statement').then(res=>{
if(res.code==0){
this.disclaimers = this.$toolAll.tools.escape2Html(res.data.content);
} else {
this.$toolAll.tools.showToast(res.msg);
}
uni.hideLoading();
})
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,105 @@
<template>
<view>
<status-nav :ifReturn="true" navBarTitle="经销商申请" :marginBottom="0"></status-nav>
<!-- 内容 -->
<view class="distributor border-box" :style="{'min-height':disclaimersHeight}">
<view class="tags font24" style="text-align: center;color: #ff0000;">请认真填写相关信息此信息将用于分销提现使用</view>
<view class="distributor-list font30">
<view class="distributor-item color-99 mar-s40">
<view class="tips">我的邀请人</view>
<input class="input" type="text" :value="invite_name" disabled="true">
</view>
<view class="distributor-item mar-s40">
<view class="tips color-99">姓名</view>
<input class="input" type="text" v-model="real_name" placeholder="请输入您的真实姓名" placeholder-style="color:#000000">
</view>
<view class="distributor-item mar-s40">
<view class="tips color-99">电话</view>
<input class="input" type="number" v-model="phone" placeholder="请输入您的手机号" placeholder-style="color:#000000">
</view>
<view class="distributor-item mar-s40">
<view class="tips color-99">开户行</view>
<input class="input" type="text" v-model="deposit_bank" placeholder="请填写开户行(如:中国银行)" placeholder-style="color:#000000">
</view>
<view class="distributor-item mar-s40">
<view class="tips color-99">银行卡号</view>
<input class="input" type="number" v-model="bank_account" placeholder="请填写银行卡号" placeholder-style="color:#000000">
</view>
</view>
</view>
<view class="distributor-btn background-white border-box" @tap="submitEv">
<view class="btn font36 background-orange color-48 radius30 flex">立即提交</view>
</view>
</view>
</template>
<script>
import {mapState} from 'vuex'//mapState
export default {
data() {
return {
disclaimersHeight: `calc(100vh - ${uni.getSystemInfoSync().statusBarHeight + 50}px)`,
disclaimers:'',
invite_code:'',
invite_name:'',
real_name:'',
phone:'',
deposit_bank:'',
bank_account:'',
flag:true,
}
},
onLoad(op) {
console.log(op,1212121212)
this.invite_code = op.invite_code;
this.invite_name = op.invite_name;
},
methods: {
//
submitEv(){
if(this.checkEmpty() && this.flag){
let params = {
invite_code:this.invite_code,
invite_name:this.invite_name,
real_name:this.real_name,
phone:this.phone,
deposit_bank:this.deposit_bank,
bank_account:this.bank_account,
}
this.$requst.post('/api/user/distributor-apply',params).then(res=>{
if(res.code==0){
uni.reLaunch({
url:`/pages/index/index`
})
} else {
this.$toolAll.tools.showToast(res.msg);
}
setTimeout(()=>{
this.flag = true;
},2000)
})
}
},
//
checkEmpty(){
let result = false;
if(!this.real_name) {
this.$toolAll.tools.showToast('请填写真实姓名');
} else if(this.$toolAll.tools.isPhone(this.phone)) {
this.$toolAll.tools.showToast('请正确填写手机号');
}if(!this.deposit_bank) {
this.$toolAll.tools.showToast('请填写开户行');
}if(!this.bank_account) {
this.$toolAll.tools.showToast('请填写卡号');
} else {
result = true;
}
return result;
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,50 @@
<template>
<view v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="积分规则" :marginBottom="0"></status-nav>
<!-- 内容 -->
<view class="disclaimers border-box" :style="{'min-height':disclaimersHeight}">
<view class="disclaimers-txt font24 color-8c">
<view class="txt">{{integral_rule.deduction_points_score}}积分可抵扣{{integral_rule.deduction_points_score_value}}</view>
<view class="txt">每下单{{integral_rule.place_order_score}}可获得{{integral_rule.place_order_score_value}}积分</view>
</view>
</view>
</view>
</template>
<script>
import {mapState} from 'vuex'//mapState
export default {
data() {
return {
disclaimersHeight: `calc(100vh - ${uni.getSystemInfoSync().statusBarHeight + 50}px)`,
integral_rule:{},
isLoading:false,
}
},
onLoad(op) {
//
this.getDisclaimers();
},
methods: {
//
getDisclaimers(){
uni.showLoading({
title:'加载中'
});
this.$requst.get('/api/user/integral-rule').then(res=>{
if(res.code==0){
this.integral_rule = res.data;
} else {
this.$toolAll.tools.showToast(res.msg);
}
uni.hideLoading();
this.isLoading =true;
})
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,229 @@
<template>
<view class="pad-x170">
<!-- 滚动顶部 -->
<view class="scrool-top background-white" :style="{height:statusHeight+50+'px'}" v-if="scroolTop"></view>
<!-- 返回按钮 -->
<view class="back-btn flex" :style="{top:statusHeight+'px'}" @tap="backEv">
<i class="icon icon-return" style="font-size: 38rpx;" :style="{color: '#000000'}"></i>
</view>
<!-- 商品轮播 -->
<view class="shop-top-img">
<image :src="shopDetail.images[0]" mode="widthFix"></image>
</view>
<view class="shop-content pad-all20 background-white">
<!-- 商品标题 -->
<view class="shop-title font40 mar-x30">{{shopDetail.name}}</view>
<!-- 商品详情 -->
<view class="shop-body">
<view class="pull-title">
<view class="txt font32 pad-sx10">详情介绍</view>
<view class="line background-orange"></view>
</view>
<view class="body-txt font30 color-48">
<rich-text :nodes="shopDetail.content"></rich-text>
</view>
</view>
</view>
<!-- 规格 -->
<view class="pull-bg" v-if="showSku"></view>
<view class="shop-specs background-white border-box" v-if="showSku">
<view class="specs-top flex">
<view class="title font30">规格选择</view>
<view class="close" @tap="closeSpecs">
<image src="/static/icon/icon-close.png" mode="widthFix"></image>
</view>
</view>
<scroll-view scroll-y="true" class="specs-list">
<view class="specs-item border-box radius20 mar-s20 pad-zy20 font36 flex" :class="skuIndex==index?'active':''" v-for="(item,index) in shopSku" :key="index" @tap="changeSpecs(index)">
<text>{{item.title}}</text>
<text>{{vip_level>0?item.price:item.original_price}}</text>
</view>
</scroll-view>
<view class="specs-btns flex">
<view class="btn radius30 font36 color-ff background-orange flex" @tap="buyNow"></view>
<view class="btn radius30 font36 color-ff background-grey flex" @tap="joinCart"></view>
</view>
</view>
<!-- 尾部 -->
<view class="shop-foot border-box background-white pad-all20">
<view class="shop-footer background-grey pad-sx15 radius30 flex">
<view class="shop-nav font24 color-ff flex" @tap="goHome">
<image src="/static/icon/icon-home.png" mode="widthFix"></image>
<text>首页</text>
</view>
<view class="shop-cart background-white radius100 flex" @tap="goCart">
<image src="/static/icon/icon-cart.png" mode="widthFix"></image>
<view class="shop-num radius100 font24 color-ff flex" v-if="cartNum*1>=0&&cartNum*1<=99">
<text>{{cartNum}}</text>
</view>
<view class="shop-num radius100 font24 color-ff flex" v-if="cartNum*1>99">
<text>99</text>
</view>
</view>
<view class="shop-btn background-orange font36 color-48 radius30 flex" @tap="openSpecs"></view>
</view>
</view>
<!-- 分享&领券 -->
<share-coupon :spuId="shopDetail.id"></share-coupon>
</view>
</template>
<script>
import {getCartInfo} from '@/jsFile/public-api.js';
import {mapState} from 'vuex'//mapState
export default {
data() {
return {
statusHeight:uni.getSystemInfoSync().statusBarHeight,
scroolTop:false, //
shopDetail:{}, //
shopSku:[], //
showSku:false, //
skuIndex:0, //
id:0, //id
vip_level:0, //
isLoading: true,
shareImg:'', //
}
},
onLoad(op) {
if(op !== ''){
this.id = op.id;
//
this.getDetail(op.id);
//
this.getSku(op.id);
}
},
onShow() {
this.vip_level = uni.getStorageSync('vip_level');
getCartInfo();
},
computed:{
...mapState({
cartNum: state=> state.moduleA.cartNum
}),
},
onPageScroll(object){
if(object.scrollTop>50){
this.scroolTop = true;
}else{
this.scroolTop = false;
}
},
onShareAppMessage(res) {
},
//
onShareTimeline(res){
},
mounted() {
//
this.$toolAll.tools.obtainPagePath();
},
methods: {
//
getDetail(id){
uni.showLoading({
title:'加载中'
});
this.isLoading =false;
this.$requst.get('/api/spu/detail',{id:id}).then(res=>{
if(res.code==0) {
console.log(res,'详情')
let shopObj = {
id:res.data.detail.id,
images:res.data.detail.images.split(','),
name:res.data.detail.name,
content:this.$toolAll.tools.escape2Html(res.data.detail.content)
}
this.shopDetail = shopObj; //
}
uni.hideLoading();
this.isLoading =true;
})
},
//
getSku(id){
this.$requst.get('/api/spu/spec',{id:id}).then(res=>{
if(res.code==0) {
console.log(res,'规格')
this.shopSku = res.data.sku_list; //
}
})
},
//
openSpecs(){
this.showSku =true;
},
//
changeSpecs(index){
if(this.skuIndex !== index){
this.skuIndex = index;
}
},
//
closeSpecs(){
this.showSku =false;
},
//
joinCart(){
if(this.$toolAll.tools.judgeAuth()) {
this.$requst.post('/api/order/shopping-cart-add',{sku_id:this.shopSku[this.skuIndex].id,num:1}).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('加入购物车成功(*^▽^*)');
getCartInfo();
//
this.closeSpecs();
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
}
},
//
buyNow(){
if(this.$toolAll.tools.judgeAuth()) {
this.$requst.post('/api/order/shopping-cart-add',{sku_id:this.shopSku[this.skuIndex].id,num:1}).then(res=>{
if(res.code==0) {
//
this.closeSpecs();
uni.navigateTo({
url:`/pages/cart/cart`
})
} else {
this.$toolAll.tools.showToast(res.msg)
}
})
}
},
//
goHome(){
uni.reLaunch({
url:'/pages/index/index',
})
},
//
goCart(){
uni.navigateTo({
url:'/pages/cart/cart',
})
},
//
backEv(){
uni.navigateBack({
delta:1
})
}
}
}
</script>
<style>
</style>

229
pagesB/ucenter/ucenter.vue Normal file
View File

@ -0,0 +1,229 @@
<template>
<view v-if="isLoading">
<status-nav :ifReturn="true" navBarTitle="个人中心" :marginBottom="0"></status-nav>
<view class="ucenter-bg border-box" :style="{'min-height':windoHeight - statusHeight - 50+'px'}">
<view class="ucenter">
<view class="item item-first flex">
<view class="title">头像</view>
<view class="img">
<image :src="headImgUrl" mode="widthFix"></image>
</view>
</view>
<view class="item flex">
<view class="title">昵称</view>
<view class="msg">{{nickName}}</view>
</view>
<view class="item flex" @tap="openEdit('real_name')">
<view class="title">真实姓名</view>
<input class="msg" type="text" v-model="realName" disabled="true">
<view class="more">
<image src="/static/public/icon-my-more.png" mode="widthFix"></image>
</view>
</view>
<view class="item flex" style="position: relative;">
<view class="title">联系电话</view>
<input class="msg" type="number" v-model="mobile" disabled="true">
<view class="more">
<image src="/static/public/icon-my-more.png" mode="widthFix"></image>
</view>
<button class="get-phone-btn" open-type="getPhoneNumber" @getphonenumber="onGetPhoneNumber"></button>
</view>
<picker mode="region" @change="change">
<view class="item flex">
<view class="title">联系地址</view>
<input class="msg" type="text" v-model="area" disabled="true">
<view class="more">
<image src="/static/public/icon-my-more.png" mode="widthFix"></image>
</view>
</view>
</picker>
<view class="item flex" @tap="openEdit('address')">
<view class="title">详细地址</view>
<input class="msg" type="text" v-model="address" disabled="true">
<view class="more">
<image src="/static/public/icon-my-more.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
<!-- 修改信息 -->
<view class="pull-bg" style="background-color: rgba(0,0,0,.3);" v-show="isOpen" @tap="closeEdit"></view>
<view class="vip-box-bg border-box" v-if="isOpen">
<view class="vip-box radius20 background-white font30">
<view class="title">{{title}}</view>
<view class="vip-list">
<view class="vip-item mar-s20">
<view class="tips color-99">{{subtitle}}</view>
<input class="input" type="text" v-model="msg" :placeholder="placeholder" placeholder-style="color:#000000">
</view>
</view>
<view class="submit-btn font36 background-orange radius30 mar-s60 flex" @tap="submitEdit"></view>
<view class="close-btn" @tap="closeEdit">
<image src="/static/icon/close-btn.png" mode="widthFix"></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
windoHeight:uni.getSystemInfoSync().windowHeight,
statusHeight:uni.getSystemInfoSync().statusBarHeight,
headImgUrl:'', //
nickName:'', //
businessCode:'', //
realName:'',//
mobile:'',//
area:'',//
address:'',//
isOpen:false, //
title:'', //
subtitle:'', //
msg:'', //
field:'', //
placeholder:'', //
headImg:'', //
province:'', //
city:'', //
county:'', //
isLoading:false,
}
},
onLoad(op) {
this.getUserData();
},
onShow() {
},
methods: {
//
getUserData(){
uni.showLoading({
title:'加载中'
});
this.$requst.get('/api/user/info').then(res=>{
console.log(res,'用户信息')
if(res.code==0) {
this.headImgUrl = res.data.headimgurl;
this.nickName = res.data.nickname;
this.businessCode = res.data.business_code;
this.realName= res.data.real_name;
this.mobile= res.data.mobile;
this.area= res.data.province+res.data.city+res.data.county;
this.address= res.data.address;
}
uni.hideLoading();
this.isLoading = true;
})
},
//
openEdit(type){
if(type == 'real_name'){
this.title = '真实姓名';
this.subtitle = '真实姓名';
this.placeholder = this.realName;
this.isOpen = true;
this.field = 'real_name';
}
if(type == 'address'){
this.title = '详细地址';
this.subtitle = '详细地址';
this.placeholder = this.address;
this.isOpen = true;
this.field = 'address';
}
},
//
change(e){
this.area = e.detail.value[0] + e.detail.value[1] + e.detail.value[2];
this.province = e.detail.value[0];
this.city = e.detail.value[1];
this.county = e.detail.value[2];
this.field = 'area'
setTimeout(()=>{
this.submitEdit()
},200)
},
//
submitEdit(){
if(this.field == 'real_name'){
var params = {
real_name:this.msg
}
console.log(params,123)
}
if(this.field == 'address'){
var params = {
address:this.msg
}
}
if(this.field == 'area'){
var params = {
province:this.province,
city:this.city,
county:this.county
}
}
uni.showLoading({
title:'修改中'
});
if(params){
this.$requst.post('/api/user/edit-info',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('修改成功');
//
this.closeEdit();
//
this.getUserData();
}
})
}else{
this.$toolAll.tools.showToast('您没有更改信息');
//
this.closeEdit();
}
uni.hideLoading();
},
//
closeEdit(){
this.title = '';
this.subtitle = '';
this.msg='';
this.isOpen = false;
this.type=''
},
//
onGetPhoneNumber(e){
if(e.detail.errMsg=="getPhoneNumber:fail user deny"){ //
this.$toolAll.tools.showToast('您已拒绝授权');
}else{ //
let params={
iv:e.detail.iv,
encryptedData:e.detail.encryptedData
}
this.$requst.post('/api/user/bind-phone',params).then(res=>{
if(res.code==0) {
this.$toolAll.tools.showToast('绑定成功');
//
this.getUserData();
}else{
this.$toolAll.tools.showToast(res.msg);
}
})
}
},
}
}
</script>
<style>
</style>

77
project.config.json Normal file
View File

@ -0,0 +1,77 @@
{
"description": "项目配置文件",
"packOptions": {
"ignore": []
},
"setting": {
"urlCheck": true,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": false,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"lazyloadPlaceholderEnable": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useIsolateContext": false,
"userConfirmedBundleSwitch": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"disableUseStrict": false,
"minifyWXML": true,
"showES6CompileOption": false,
"useCompilerPlugins": false,
"ignoreUploadUnusedFiles": true
},
"compileType": "miniprogram",
"libVersion": "2.22.0",
"appid": "wx987dc41899f719e8",
"projectname": "%E4%BD%A9%E4%B8%BD%E5%95%86%E5%9F%8E",
"debugOptions": {
"hidedInDevtools": []
},
"scripts": {},
"staticServerOptions": {
"baseURL": "",
"servePath": ""
},
"isGameTourist": false,
"condition": {
"search": {
"list": []
},
"conversation": {
"list": []
},
"game": {
"list": []
},
"plugin": {
"list": []
},
"gamePlugin": {
"list": []
},
"miniprogram": {
"list": []
}
}
}

BIN
static/icon/close-btn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
static/icon/icon-back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

BIN
static/icon/icon-cart.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/icon/icon-close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/icon/icon-code.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
static/icon/icon-coupon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/icon/icon-finish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
static/icon/icon-home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/icon/icon-join.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/icon/icon-more.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/icon/icon-my-01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/icon/icon-my-02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
static/icon/icon-my-03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
static/icon/icon-my-04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/icon/icon-my-05.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
static/icon/icon-my-06.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/icon/icon-my-07.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/icon/icon-my-08.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
static/icon/icon-my-09.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/icon/icon-search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/icon/icon-share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
static/icon/icon-shop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
static/icon/icon-wechat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
static/img/code.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
static/img/icon-vip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
static/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
static/img/my-bg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
static/img/recharge-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

1
store/actions.js Normal file
View File

@ -0,0 +1 @@
// 根级别的 action

16
store/index.js Normal file
View File

@ -0,0 +1,16 @@
// 组装模块并导出 store 的地方
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from '@/store/modules/moduleA'
import moduleB from '@/store/modules/moduleB'
Vue.use(Vuex);//vue的插件机制
//Vuex.modules 模块选项
const store = new Vuex.Store({
modules: {
moduleA,
moduleB
}
})
export default store

112
store/modules/moduleA.js Normal file
View File

@ -0,0 +1,112 @@
// 购物车模块
export default {
state:{//存放状态
// 底部导航的高
footHeight:'',
token:'token已生成',
userInfo:{},
count:0,
publicColor:'',
todos: [{
id: 1,
text: '我是内容一',
done: true
},
{
id: 2,
text: '我是内容二',
done: false
}
],
obj:{
a:'吃鸡腿',
b:'吃自助餐'
},
titleList:[],
imgList:[],
onLineList:[],
cartNum:0,
cartPrice:0,
geList:[],
changeBusiness:false,
},
// Vuex中store数据改变的唯一方法就是mutations 不适合异步方法
mutations: {
setNum(state,num){
state.cartNum = num;
},
setPrice(state,price){
state.cartPrice = price;
},
setGe(state,payload){
state.geList = payload.geList;
},
footHeightEv(state,str){
state.footHeight = str;
},
add(state) {
state.count = 7;
},
add2(state, payload) {
state.count = payload.amount;
},
// 单个属性处理方法
setToken(state,str) {
state.token = str;
},
// 对象处理方法
updateUserInfo(state, payload) {
// 变更状态
state.userInfo = payload.userInfo;
},
// 新增字段方法
newProp(state,payload) {
state.obj = { ...state.obj, c: payload.c };
},
updateState(state, payload) {
state.onLineList = payload.list;
}
},
// 可以执行任意的同步和异步操作
actions:{
addCountAction ({commit}) {
commit('add')
},
addCountAction2 (context , payload) {
context.commit('add2', payload)
},
// 异步方法
addCountAction3 (context , payload) {
setTimeout(function () {
context.commit('add2', payload)
}, 2000)
},
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
},
// Vuex 允许我们在 store 中定义“getter”可以认为是 store 的计算属性),对 state 的加工,是派生出来的数据。 可以在多组件中共享 getter 函数,这样做还可以提高运行效率。
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
//state :可以访问数据
//getters访问其他函数等同于 store.getters
return getters.doneTodos.length
},
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
}

87
store/modules/moduleB.js Normal file
View File

@ -0,0 +1,87 @@
export default {
state:{//存放状态
token:'token已生成',
userInfo:{},
count:0,
publicColor:'',
todos: [{
id: 1,
text: '我是内容一',
done: true
},
{
id: 2,
text: '我是内容二',
done: false
}
],
obj:{
a:'吃鸡腿',
b:'吃自助餐'
}
},
// Vuex中store数据改变的唯一方法就是mutations 不适合异步方法
mutations: {
add(state) {
state.count = 7;
},
add2(state, payload) {
state.count = payload.amount;
},
// 单个属性处理方法
setToken(state,str) {
state.token = str;
},
// 对象处理方法
updateUserInfo(state, payload) {
// 变更状态
state.userInfo = payload.userInfo;
},
// 新增字段方法
newProp(state,payload) {
state.obj = { ...state.obj, c: payload.c };
}
},
// 可以执行任意的同步和异步操作
actions:{
addCountAction ({commit}) {
commit('add')
},
addCountAction2 (context , payload) {
context.commit('add2', payload)
},
// 异步方法
addCountAction3 (context , payload) {
setTimeout(function () {
context.commit('add2', payload)
}, 2000)
},
actionA ({ commit }) {
return new Promise((resolve, reject) => {
setTimeout(() => {
commit('someMutation')
resolve()
}, 1000)
})
},
actionB ({ dispatch, commit }) {
return dispatch('actionA').then(() => {
commit('someOtherMutation')
})
}
},
// Vuex 允许我们在 store 中定义“getter”可以认为是 store 的计算属性),对 state 的加工,是派生出来的数据。 可以在多组件中共享 getter 函数,这样做还可以提高运行效率。
getters: {
// doneTodos: state => {
// return state.todos.filter(todo => todo.done)
// },
// doneTodosCount: (state, getters) => {
// //state :可以访问数据
// //getters访问其他函数等同于 store.getters
// return getters.doneTodos.length
// },
// getTodoById: (state) => (id) => {
// return state.todos.find(todo => todo.id === id)
// }
}
}

1
store/mutations.js Normal file
View File

@ -0,0 +1 @@
// 根级别的 mutation

119
store/readme.md Normal file
View File

@ -0,0 +1,119 @@
#引入vuex状态机
在根目录创建store目录
#在main.js引入store、注册store、挂载store在程序上
import Vue from 'vue';
import App from './App';
#import store from './store'
#Vue.prototype.$store = store
const app = new Vue({
# store,
...App
})
app.$mount()
#在页面内使用store的属性
<view @tap="add"></view>
import { mapState,mapGetters,mapMutations } from 'vuex'//引入mapState
export default {
data() {
return {}
},
#单纯访问属性值
computed:{
tokenEv() {
return this.$store.state.token;
}
},
<!--
需要引入 import { mapState } from 'vuex'//引入mapState
-->
computed:mapState({
// 从state中拿到数据 箭头函数可使代码更简练
token: state => state.token,
}),
computed:mapState(['token']),
computed: {
...mapState({
token: function (state) {
return '追加的' + state.token
},
userInfo: state => state.userInfo,
})
},
computed:{
...mapState([
'token',
'userInfo',
'count',
'obj'
])
},
computed: {
...mapState({
token: state => state.moduleA.token,
count: state => state.moduleB.count
}),
},
#单纯访问方法
computed: {
todos() {
return this.$store.getters.doneTodos
}
},
computed: {
doneTodosCount() {
return this.$store.getters.doneTodosCount
}
},
<!-- 方法传值 -->
computed: {
getTodoById() {
return this.$store.getters.getTodoById(1)
}
},
<!--
需要引入 import { mapGetters } from 'vuex'//引入mapState
-->
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodos',
'doneTodosCount',
'getTodoById'
// ...
])
},
onLoad(options) {
#改变状态机里面的值
<!-- 传递字符串改变 -->
this.$store.commit('setToken', 'token已改变');
<!-- 传递对象 -->
this.$store.commit('updateUserInfo',{userInfo:'用户信息'})
this.$store.commit({
type: 'updateUserInfo',
userInfo: '新方式更新用户信息'
})
this.$store.commit('newProp',{c:'吃火锅'})
<!-- 输出值 -->
console.log(this.token);
<!-- 调用方法 -->
this.add();
<!-- 必须是同步方法 -->
this.$store.dispatch('addCountAction')
this.$store.dispatch('addCountAction2',{amount:10})
<!-- 异步方法 -->
this.$store.dispatch('addCountAction3',{amount:30})
setTimeout(()=>{
console.log(this.count,388);
},3000)
},
methods: {
<!--
需要引入 import { mapMutations } from 'vuex'//引入mapState
-->
...mapMutations(['add']),//对象展开运算符直接拿到add
}
}

76
uni.scss Normal file
View File

@ -0,0 +1,76 @@
/**
* uni-app
*
* uni-app https://ext.dcloud.net.cn使
* 使scss使 import 便App
*
*/
/**
* App使
*
* 使scss scss 使 import
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//
$uni-text-color-inverse:#fff;//
$uni-text-color-grey:#999;//
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:24upx;
$uni-font-size-base:28upx;
$uni-font-size-lg:32upx;
/* 图片尺寸 */
$uni-img-size-sm:40upx;
$uni-img-size-base:52upx;
$uni-img-size-lg:80upx;
/* Border Radius */
$uni-border-radius-sm: 4upx;
$uni-border-radius-base: 6upx;
$uni-border-radius-lg: 12upx;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20upx;
$uni-spacing-row-lg: 30upx;
/* 垂直间距 */
$uni-spacing-col-sm: 8upx;
$uni-spacing-col-base: 16upx;
$uni-spacing-col-lg: 24upx;
/* 透明度 */
$uni-opacity-disabled: 0.3; //
/* 文章场景相关 */
$uni-color-title: #2C405A; //
$uni-font-size-title:40upx;
$uni-color-subtitle: #555555; //
$uni-font-size-subtitle:36upx;
$uni-color-paragraph: #3F536E; //
$uni-font-size-paragraph:30upx;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More