miao33: 从 main 同步 single_uniapp22miao,dart-sass 兼容修复,DEPLOY.md 更新

- 从 main 获取 single_uniapp22miao 子项目
- dart-sass: /deep/ -> ::v-deep,calc 运算符加空格
- DEPLOY.md 采用 shccd159 版本(4 子项目架构说明)

Made-with: Cursor
This commit is contained in:
apple
2026-03-16 11:16:42 +08:00
parent 9c29721dc4
commit 079076a70e
356 changed files with 569762 additions and 129 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,237 @@
<template>
<view :data-theme="theme">
<view class='payment-status'>
<!--失败时 用icon-iconfontguanbi fail替换icon-duihao2 bg-color-->
<view class='iconfont icons icon-duihao2 bg_color'
v-if="order_pay_info.paid === 1"></view>
<view v-if="order_pay_info.paid === 2" class='iconfont icons icon-iconfontguanbi'></view>
<!-- 失败时订单支付失败 -->
<view class='status'>{{payResult}}</view>
<view class='wrapper'>
<view class='item acea-row row-between-wrapper'>
<view>订单编号</view>
<view class='itemCom'>{{orderId}}</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view>下单时间</view>
<view class='itemCom'>{{order_pay_info.createTime?order_pay_info.createTime:'-'}}</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view>支付方式</view>
<view class='itemCom'>支付宝支付</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view>支付金额</view>
<view class='itemCom'>{{order_pay_info.payPrice}}</view>
</view>
<!--失败时加上这个 -->
<view class='item acea-row row-between-wrapper'
v-if="order_pay_info.paid === 2">
<view>失败原因</view>
<view class='itemCom'>{{msg}}</view>
</view>
</view>
<!--失败时 重新购买 -->
<view @tap="goOrderDetails">
<button formType="submit" class='returnBnt bg_color' hover-class='none'>查看订单</button>
</view>
<button @click="goIndex" class='returnBnt cart-color' formType="submit" hover-class='none'>返回首页</button>
</view>
</view>
</template>
<script>
import {getOrderDetail,alipayQueryPayResult} from '@/api/order.js';
let app = getApp();
export default{
data() {
return {
orderId: '',
payPrice:'',
order_pay_info: {
paid: 0,
_status: {}
},
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
status: 0,
msg: '',
payResult: '订单查询中...',
payTime:'',
theme:app.globalData.theme,
};
},
onLoad(e){
// #ifdef H5
var url = window.location.search;
if(url){
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
var strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1]);
}
}
this.orderId = theRequest.out_trade_no; //返回的订单号
this.getOrderPayInfo();
}else{
let that = this;
uni.getStorage({
key: 'orderNo',
success: function (res) {
that.orderId = res.data; //如果是支付宝中途放弃支付跳转到这个页面,就从缓存读取订单号查询订单详情和支付结果
setTimeout(()=>{
that.getOrderPayInfo();
},200)
}
});
}
// #endif
// #ifdef APP-PLUS
console.log(e);
this.orderId = e.out_trade_no;
this.getOrderPayInfo();
// #endif
},
methods:{
getOrderPayInfo: function() {
let that = this;
uni.showLoading({
title: '正在加载中'
});
getOrderDetail(that.orderId).then(res => {
that.$set(that, 'order_pay_info', res.data);
that.alipayQueryPay();
uni.hideLoading();
}).catch(err => {
uni.hideLoading();
});
},
alipayQueryPay() {
alipayQueryPayResult(this.orderId).then(res => {
this.payResult = '支付成功';
uni.setNavigationBarTitle({
title: '支付成功'
});
this.order_pay_info.paid = 1;
uni.hideLoading();
}).catch(err => {
this.order_pay_info.paid = 2;
this.payResult = err;
this.msg = err;
uni.hideLoading();
return this.$util.Tips({
title: err
});
})
},
goOrderDetails(){
uni.navigateTo({
url: '/pages/order/order_details/index?order_id=' + this.orderId
})
},
goIndex(){
uni.switchTab({
url: '/pages/index/index'
});
}
}
}
</script>
<style lang="scss">
.icon-iconfontguanbi {
background-color: #999 !important;
text-shadow: none !important;
}
.bg_color{
@include main_bg_color(theme);
}
.cart_color{
@include main_color(theme);
@include coupons_border_color(theme);
}
.payment-status {
background-color: #fff;
margin: 195rpx 30rpx 0 30rpx;
border-radius: 10rpx;
padding: 1rpx 0 28rpx 0;
}
.payment-status .icons {
font-size: 70rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
color: #fff;
text-align: center;
line-height: 140rpx;
text-shadow: 0px 4px 0px #df1e14;
border: 6rpx solid #f5f5f5;
margin: -76rpx auto 0 auto;
background-color: #999;
}
.payment-status .iconfont {
font-size: 70rpx;
width: 140rpx;
height: 140rpx;
border-radius: 50%;
color: #fff;
text-align: center;
line-height: 140rpx;
text-shadow: 0px 4px 0px #df1e14;
border: 6rpx solid #f5f5f5;
margin: -76rpx auto 0 auto;
background-color: #999;
}
.payment-status .iconfont.fail {
text-shadow: 0px 4px 0px #7a7a7a;
}
.payment-status .status {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin: 25rpx 0 37rpx 0;
}
.payment-status .wrapper {
border: 1rpx solid #eee;
margin: 0 30rpx 47rpx 30rpx;
padding: 35rpx 0;
border-left: 0;
border-right: 0;
}
.payment-status .wrapper .item {
font-size: 28rpx;
color: #282828;
}
.payment-status .wrapper .item~.item {
margin-top: 20rpx;
}
.payment-status .wrapper .item .itemCom {
color: #666;
}
.payment-status .returnBnt {
width: 630rpx;
height: 86rpx;
border-radius: 50rpx;
color: #fff;
font-size: 30rpx;
text-align: center;
line-height: 86rpx;
margin: 0 auto 20rpx auto;
}
.cart-color {
@include main_color(theme);
@include coupons_border_color(theme);
}
</style>

View File

@@ -0,0 +1,331 @@
<template>
<view class="wrapper" :data-theme="theme">
<view class="bag"></view>
<view class="system-height" :style="{height:statusBarHeight}"></view>
<!-- #ifdef MP -->
<view class="title-bar" style="height: 43px;">
<view class="icon" @click="back" v-if="!isHome">
<image class="img" :src="urlDomain+'crmebimage/perset/usersImg/left.png'"></image>
</view>
<view class="icon" @click="home" v-else>
<image class="img" :src="urlDomain+'crmebimage/perset/usersImg/home.png'"></image>
</view>
账户登录
</view>
<!-- #endif -->
<view class="appBox">
<view class="phone_name">绑定手机号</view>
<view class="phone_tips">登录注册需绑定手机号</view>
<mobileLogin :isUp="isUp" :isShow="isShow" :platform="platform" :isPos="isPos" :appleShow="appleShow"
:authKey="authKey" @wechatPhone="wechatPhone" :wxCode="wxCode"></mobileLogin>
</view>
</view>
</template>
<script>
const app = getApp();
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
import sendVerifyCode from "@/mixins/SendVerifyCode";
import Routine from '@/libs/routine';
import {
loginMobile,
registerVerify,
getCodeApi,
getUserInfo
} from "@/api/user";
import {
bindingPhone
} from '@/api/api.js'
import {
getUserPhone
} from '@/api/public';
import mobileLogin from '@/components/login_mobile/index.vue'
export default {
name: 'login_mobile',
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
theme: app.globalData.theme,
options: '',
keyCode: '',
account: '',
codeNum: '',
isUp: true,
authKey: '',
logoUrl: '',
isShow: false,
isPos: false,
platform: '', // 手机平台
appleShow: '', //是否是苹果登录
statusBarHeight: statusBarHeight,
wxCode: '' //小程序code值
}
},
components: {
mobileLogin
},
mixins: [sendVerifyCode],
mounted() {
//this.getCode();
},
onLoad: function(options) {
let that = this;
// 获取系统信息
uni.getSystemInfo({
success(res) {
that.platform = res.platform;
}
});
const {
code,
state,
scope,
back_url,
appleShow
} = options;
that.options = options
if (options.authKey) that.authKey = options.authKey
if (options.appleShow) that.appleShow = options.appleShow
if (options.code) that.wxCode = options.code
},
methods: {
// 返回
back() {
uni.navigateBack();
},
// 跳入首页
home() {
uni.switchTab({
url: '/pages/index/index'
})
},
wechatPhone() {
this.$Cache.clear('snsapiKey');
if (this.options.back_url) {
let url = uni.getStorageSync('snRouter');
url = url.indexOf('/pages/index/index') != -1 ? '/' : url;
if (url.indexOf('/pages/users/wechat_login/index') !== -1) {
url = '/';
}
if (!url) {
url = '/pages/index/index';
}
this.isUp = false
uni.showToast({
title: '登录成功',
icon: 'none'
})
setTimeout(res => {
location.href = url
}, 800)
} else {
uni.navigateBack()
}
},
// 获取验证码
async code() {
let that = this;
if (!that.account) return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
title: '请输入正确的手机号码'
});
await registerVerify(that.account).then(res => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
}).catch(err => {
return that.$util.Tips({
title: err
})
})
},
// 获取验证码api
getCode() {
let that = this
getCodeApi().then(res => {
that.keyCode = res.data.key;
}).catch(res => {
that.$util.Tips({
title: res
});
});
},
close() {
this.$emit('close', false)
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
uni.hideLoading();
that.userInfo = res.data
that.$store.commit("UPDATE_USERINFO", res.data);
// #ifdef MP
that.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
that.close()
// #endif
// #ifdef H5
that.$emit('wechatPhone', true)
// #endif
});
},
}
}
</script>
<style>
page {
background: #fff;
height: 100%;
}
</style>
<style lang="scss" scoped>
.wrapper {
background: #fff;
height: 100%;
position: relative;
.bag {
position: absolute;
top: 0;
left: 0;
width: 750rpx;
height: 460rpx;
@include logn-gradient(theme);
}
}
.title-bar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
}
.icon {
position: absolute;
left: 30rpx;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 86rpx;
height: 86rpx;
.img {
width: 50rpx;
height: 50rpx;
}
}
.phone {
&_name {
padding: 0 72rpx;
font-size: 48rpx;
font-weight: 500;
color: #333333;
line-height: 68rpx;
margin-bottom: 16rpx;
}
&_tips {
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 40rpx;
padding: 0 72rpx;
}
}
.appBox {
background-color: #fff;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
margin-top: 146rpx;
}
.shading {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
image {
width: 180rpx;
height: 180rpx;
}
}
page {
background-color: #fff !important;
}
.ChangePassword .phone {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-top: 55rpx;
}
.ChangePassword .list {
width: 580rpx;
margin: 53rpx auto 0 auto;
}
.ChangePassword .list .item {
width: 100%;
height: 110rpx;
border-bottom: 2rpx solid #f0f0f0;
}
.ChangePassword .list .item input {
width: 100%;
height: 100%;
font-size: 32rpx;
}
.ChangePassword .list .item .placeholder {
color: #b9b9bc;
}
.ChangePassword .list .item input.codeIput {
width: 340rpx;
}
.ChangePassword .list .item .code {
font-size: 32rpx;
background-color: #fff;
}
.ChangePassword .list .item .code.on {
color: #b9b9bc !important;
}
.ChangePassword .confirmBnt {
font-size: 32rpx;
width: 580rpx;
height: 90rpx;
border-radius: 45rpx;
color: #fff;
margin: 92rpx auto 0 auto;
text-align: center;
line-height: 90rpx;
}
</style>

View File

@@ -0,0 +1,126 @@
<template>
<view class="app_update">
<view class="logo_box">
<image :src="urlDomain+'crmebimage/perset/staticImg/crmeb_java.png'"></image>
<view class="title">crmeb</view>
<view class="version">Version {{appUpdate.versionCode}}</view>
</view>
<view class="jiancha" @click="appVersionConfig()">
<text>检查新版本</text>
<text class="iconfont icon-you"></text>
</view>
</view>
</template>
<script>
import {getAppVersion} from '@/api/api.js';
export default {
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
appUpdate:{}
}
},
onLoad() {
let that = this;
plus.runtime.getProperty(plus.runtime.appid,function(inf){
that.$set(that.appUpdate,'versionCode',inf.version);
})
},
methods: {
appVersionConfig(){
var that = this;
//app升级
// 获取本地应用资源版本号
getAppVersion().then(res=>{
that.$set(that.appUpdate,'androidAddress',res.data.androidAddress);
that.$set(that.appUpdate,'appVersion',res.data.appVersion);
that.$set(that.appUpdate,'iosAddress',res.data.iosAddress);
that.$set(that.appUpdate,'openUpgrade',res.data.openUpgrade);
plus.runtime.getProperty(plus.runtime.appid,function(inf){
let nowVersion = (inf.version).split('.').join('');
let appVersion = (res.data.appVersion).split('.').join('');
uni.getSystemInfo({
success:(res) => {
if(appVersion > nowVersion){
uni.showModal({
title: '更新提示',
content: '发现新版本,是否前去下载?',
showCancel:that.appUpdate.openUpgrade == 'false' ? true : false,
cancelColor: '#eeeeee',
confirmColor: '#FF0000',
success(response) {
if (response.confirm) {
switch (res.platform){
case "android":
plus.runtime.openURL(that.appUpdate.androidAddress);
break;
case "ios":
plus.runtime.openURL(encodeURI(that.appUpdate.iosAddress));
break;
}
}
}
});
}else if(appVersion <= nowVersion){
uni.showToast({
title:'已是最新版本',
icon:'none'
})
}
}
})
});
})
},
}
}
</script>
<style>
.app_update{
background-color: #fff;
height: 100vh;
}
.logo_box{
height: 500rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.logo_box image{
display: block;
margin-top:80rpx;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
.title{
font-size: 34rpx;
font-family: PingFang SC;
font-weight: 600;
color: #333333;
margin: 20rpx auto 20rpx;
}
.version{
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #333333;
}
.jiancha{
width: 690rpx;
margin: 20rpx auto 0;
padding: 0 20rpx 0;
height: 100rpx;
line-height: 100rpx;
color: #333333;
font-size: 30rpx;
border-top:1px solid #f5f5f5;
border-bottom:1px solid #f5f5f5;
display: flex;
justify-content: space-between;
}
</style>

View File

@@ -0,0 +1,27 @@
/**
* 此处可直接引用自己项目封装好的 axios 配合后端联调
*/
import request from '../utils/axios'; // 组件内部封装的axios
//import request from "@/api/axios.js" //调用项目封装的axios
/**
* 滑块验证
* @param {Object} data
*/
export function ajcaptchaCheck(data) {
return request.post("safety/check", data, {
noAuth: true
});
}
/**
* 滑块信息
* @param {Object} data
*/
export function getAjcaptcha(data) {
return request.post("safety/get", data, {
noAuth: true
});
}

View File

@@ -0,0 +1,70 @@
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
import {
HTTP_REQUEST_URL,
HEADER,
TOKENNAME,
HEADERPARAMS
} from '@/config/app';
import {
toLogin,
checkLogin
} from '@/libs/login';
import store from '@/store';
/**
* 发送请求
*/
function baseRequest(url, method, data, {
noAuth = false,
noVerify = false
}, params) {
let Url = HTTP_REQUEST_URL,
header = HEADER
// if (params != undefined) {
// header = HEADERPARAMS;
// }
if (!noAuth) {
//登录过期自动登录
if (!store.state.app.token && !checkLogin()) {
toLogin();
return Promise.reject({
msg: '未登录'
});
}
}
if (store.state.app.token) header[TOKENNAME] = store.state.app.token;
return new Promise((reslove, reject) => {
uni.request({
url: Url + '/api/public/' + url,
method: method || 'GET',
header: header,
data: data || {},
success: (res) => {
reslove(res.data, res);
},
fail: (msg) => {
reject('请求失败');
}
})
});
}
const request = {};
['options', 'get', 'post', 'put', 'head', 'delete', 'trace', 'connect'].forEach((method) => {
request[method] = (api, data, opt, params) => baseRequest(api, method, data, opt || {}, params)
});
export default request;

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

View File

@@ -0,0 +1,34 @@
<template>
<web-view class="web-view" :webview-styles="webviewStyles" :src="url" :style="{width: windowW + 'px', height: windowH + 'px'}"></web-view>
</template>
<script>
import {
mapGetters
} from "vuex";
export default {
computed: mapGetters(['chatUrl']),
data() {
return {
windowH: 0,
windowW: 0,
webviewStyles: {
progress: {
color: 'transparent'
}
},
url: ''
}
},
onLoad(option) {
this.url = this.chatUrl;
try {
const res = uni.getSystemInfoSync();
this.windowW = res.windowWidth;
this.windowH = res.windowHeight;
} catch (e) {
// error
}
}
}
</script>

View File

@@ -0,0 +1,690 @@
<template>
<div class="login-wrapper" :data-theme="theme">
<div class="shading">
<image :src="mobileLoginLogo"/>
</div>
<div class="whiteBg" v-if="formItem === 1">
<div class="list" v-if="current !== 1">
<form @submit.prevent="submit">
<div class="item">
<div class="acea-row row-middle">
<image :src="urlDomain+'crmebimage/perset/staticImg/phone_1.png'" style="width: 24rpx; height: 34rpx;"></image>
<input type="number" class="texts" placeholder="输入手机号码" v-model="account" maxlength="11" required/>
</div>
</div>
<div class="item">
<div class="acea-row row-middle">
<image :src="urlDomain+'crmebimage/perset/staticImg/code_2.png'" style="width: 28rpx; height: 32rpx;"></image>
<input type="password" class="texts" placeholder="填写登录密码" maxlength="18" v-model="password" required />
</div>
</div>
</form>
</div>
<div class="list" v-if="current !== 0 || appLoginStatus || appleLoginStatus">
<div class="item">
<div class="acea-row row-middle">
<image :src="urlDomain+'crmebimage/perset/staticImg/phone_1.png'" style="width: 24rpx; height: 34rpx;"></image>
<input type="number" class="texts" placeholder="输入手机号码" v-model="account" maxlength="11"/>
</div>
</div>
<div class="item">
<div class="acea-row row-middle">
<image :src="urlDomain+'crmebimage/perset/staticImg/code_2.png'" style="width: 28rpx; height: 32rpx;"></image>
<input type="number" placeholder="填写验证码" class="codeIput" v-model="captcha" maxlength="6" />
<button class="code main_color" :disabled="disabled" :class="disabled === true ? 'on' : ''" @click="code">
{{ text }}
</button>
</div>
</div>
<div class="item" v-if="isShowCode">
<div class="acea-row row-middle">
<image :src="urlDomain+'crmebimage/perset/staticImg/code_2.png'" style="width: 28rpx; height: 32rpx;"></image>
<input type="number" placeholder="填写验证码" class="codeIput" v-model="codeVal" maxlength="6"/>
<div class="code" @click="again"><img :src="codeUrl" /></div>
</div>
</div>
</div>
<view class="protocol acea-row row-between-wrapper">
<checkbox-group class="checkgroup acea-row" @change='isAgree=!isAgree' style="align-items: end;">
<checkbox class="checkbox" :checked="isAgree ? true : false" />
<text class="protocol_text">我已阅读并同意<text @click="userAgree('userinfo')"
class="font_pro">用户协议</text><text @click="userAgree('userprivacyinfo')"
class="font_pro">隐私政策</text></text>
</checkbox-group>
</view>
<div class="logon bg_color" @click="loginMobile" v-if="current !== 0">登录</div>
<div class="logon bg_color" @click="submit" v-if="current === 0">登录</div>
<!-- #ifndef APP-PLUS -->
<div class="tips">
<div v-if="current==0" @click="current = 1">快速登录</div>
<div v-if="current==1" @click="current = 0">账号登录</div>
</div>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="appLogin" v-if="!appLoginStatus && !appleLoginStatus">
<view class="hds">
<span class="line"></span>
<p>其他方式登录</p>
<span class="line"></span>
</view>
<view class="btn-wrapper">
<view class="btn wx" @click="wxLogin">
<span class="iconfont icon-s-weixindenglu1"></span>
</view>
<view class="btn mima" v-if="current == 1" @click="current =0">
<span class="iconfont icon-s-mimadenglu1"></span>
</view>
<view class="btn yanzheng" v-if="current == 0" @click="current =1">
<span class="iconfont icon-s-yanzhengmadenglu1"></span>
</view>
<view class="btn apple-btn" @click="appleLogin" v-if="appleShow">
<view class="iconfont icon-s-pingguo"></view>
</view>
</view>
</view>
<!-- #endif -->
</div>
<div class="bottom"></div>
<Verify @success="handlerOnVerSuccess" :captchaType="'clickWord'" :imgSize="{ width: '330px', height: '155px' }"
ref="verify"></Verify>
</div>
</template>
<script>
import dayjs from "@/plugin/dayjs/dayjs.min.js";
import sendVerifyCode from "@/mixins/SendVerifyCode";
import Verify from '../components/verifition/verify.vue';
import {
loginH5,
loginMobile,
registerVerify,
register,
// getCodeApi,
getUserInfo
} from "@/api/user";
let app = getApp();
import attrs, {required,alpha_num,chs_phone} from "@/utils/validate";
import {validatorDefaultCatch} from "@/utils/dialog";
import {appAuth, appleLogin} from "@/api/public";
import {VUE_APP_API_URL} from "@/utils";
import Routine from '@/libs/routine';
import {Debounce} from '@/utils/validate.js'
import {
goToAgreement
} from "@/libs/order";
const BACK_URL = "login_back_url";
export default {
name: "Login",
mixins: [sendVerifyCode],
components: {
Verify,
},
data: function() {
return {
isAgree: false,
urlDomain: this.$Cache.get("imgHost"),
navList: ["快速登录", "账号登录"],
current: 1,
account: "",
password: "",
captcha: "",
formItem: 1,
type: "login",
keyCode: "",
codeUrl: "",
codeVal: "",
isShowCode: false,
platform: '',
appLoginStatus: false, // 微信登录强制绑定手机号码状态
appUserInfo: null, // 微信登录保存的用户信息
appleLoginStatus: false, // 苹果登录强制绑定手机号码状态
appleUserInfo: null,
appleShow: false ,// 苹果登录版本必须要求ios13以上的
theme:app.globalData.theme,
mobileLoginLogo: app.globalData.mobileLoginLogo // 登录页logo
};
},
watch:{
formItem:function(nval,oVal){
if(nval == 1){
this.type = 'login'
}else{
this.type = 'register'
}
}
},
mounted: function() {
},
onLoad() {
let self = this
uni.getSystemInfo({
success: function(res) {
if (res.platform.toLowerCase() == 'ios' && res.system.split(' ')[1] >= '13') {
self.appleShow = true
}
}
});
},
methods: {
//滑块验证成功后
handlerOnVerSuccess(data) {
this.$refs.verify.hide();
this.codeSend();
},
//发送验证码
codeSend() {
let that = this;
if (!that.account) return that.$util.Tips({
title: '请填写手机号码'
});
if (!this.isAgree) return this.$util.Tips({
title: '请勾选用户隐私协议'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
title: '请输入正确的手机号码'
});
registerVerify(that.account)
.then(res => {
that.$util.Tips({
title: res.message
});
that.sendCode();
})
.catch(err => {
return that.$util.Tips({
title: err
});
});
},
userAgree(type) {
goToAgreement(type)
},
// 苹果登录
appleLogin() {
let self = this
this.account = ''
this.captcha = ''
if (!that.isAgree) return that.$util.Tips({
title: '请勾选用户隐私协议'
});
uni.showLoading({
title: '登录中'
})
uni.login({
provider: 'apple',
timeout: 10000,
success(loginRes) {
uni.getUserInfo({
provider: 'apple',
success: function(infoRes) {
self.appleUserInfo = infoRes.userInfo
self.appleLoginApi()
},
fail() {
uni.hideLoading()
uni.showToast({
title: '获取用户信息失败',
icon: 'none',
duration: 2000
})
},
complete() {
uni.hideLoading()
}
});
},
fail(error) {
uni.hideLoading()
console.log(error)
}
})
},
// 苹果登录Api
appleLoginApi() {
let self = this
appleLogin({
openId: self.appleUserInfo.openId,
email: self.appleUserInfo.email == undefined ? '' :self.appleUserInfo.email,
identityToken: self.appleUserInfo.identityToken || ''
}).then((res) => {
this.$store.commit("LOGIN", {
'token': res.data.token
});
this.getUserInfo(res.data);
}).catch(error => {
uni.hideLoading();
uni.showModal({
title: '提示',
content: `错误信息${error}`,
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
})
},
// App微信登录
wxLogin:Debounce(function() {
let self = this
this.account = ''
this.captcha = ''
if (!self.isAgree) return self.$util.Tips({
title: '请勾选用户隐私协议'
});
uni.showLoading({
title: '登录中'
})
uni.login({
provider: 'weixin',
success: function(loginRes) {
// 获取用户信息
uni.getUserInfo({
provider: 'weixin',
success: function(infoRes) {
uni.hideLoading();
self.appUserInfo = infoRes.userInfo
self.appUserInfo.type = self.platform === 'ios' ? 'iosWx' : 'androidWx'
self.wxLoginGo(self.appUserInfo)
},
fail() {
uni.hideLoading();
uni.showToast({
title: '获取用户信息失败',
icon: 'none',
duration: 2000
})
},
complete() {
uni.hideLoading()
}
});
},
fail() {
uni.hideLoading()
uni.showToast({
title: '登录失败',
icon: 'none',
duration: 2000
})
}
});
}),
wxLoginGo(userInfo) {
appAuth(userInfo).then(res => {
if (res.data.type === 'register') {
uni.navigateTo({
url: '/pages/users/app_login/index?authKey='+res.data.key
})
}
if (res.data.type === 'login') {
this.$store.commit("LOGIN", {
'token': res.data.token
});
this.getUserInfo(res.data);
}
}).catch(res => {
this.$util.Tips({
title: res
});
});
},
again() {
this.codeUrl =
VUE_APP_API_URL +
"/sms_captcha?" +
"key=" +
this.keyCode +
Date.parse(new Date());
},
//手机号验证码登录
loginMobile:Debounce(function() {
let that = this;
if (!that.account) return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
title: '请输入正确的手机号码'
});
if (!that.captcha) return that.$util.Tips({
title: '请填写验证码'
});
if (!/^[\w\d]+$/i.test(that.captcha)) return that.$util.Tips({
title: '请输入正确的验证码'
});
if (!that.isAgree) return that.$util.Tips({
title: '请勾选用户隐私协议'
});
uni.showLoading({
title: '登录中'
})
loginMobile({
phone: that.account,
captcha: that.captcha,
spread_spid: that.$Cache.get("spread")
// spread_spid: uni.getStorageSync('spid')
})
.then(res => {
let data = res.data;
let newTime = Math.round(new Date() / 1000);
this.$store.commit("LOGIN", {
'token': res.data.token
});
uni.hideLoading();
that.getUserInfo(data);
})
.catch(res => {
uni.hideLoading();
that.$util.Tips({
title: res
});
});
}),
async register() {
let that = this;
if (!that.account) return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
title: '请输入正确的手机号码'
});
if (!that.isAgree) return that.$util.Tips({
title: '请勾选用户隐私协议'
});
if (!that.captcha) return that.$util.Tips({
title: '请填写验证码'
});
if (!/^[\w\d]+$/i.test(that.captcha)) return that.$util.Tips({
title: '请输入正确的验证码'
});
if (!that.password) return that.$util.Tips({
title: '请填写密码'
});
if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/i.test(that.password)) return that.$util.Tips({
title: '您输入的密码过于简单'
});
register({
account: that.account,
captcha: that.captcha,
password: that.password,
spread_spid: that.$Cache.get("spread")
// spread_spid: uni.getStorageSync('spid') || 0
})
.then(res => {
that.$util.Tips({
title: res
});
that.formItem = 1;
})
.catch(res => {
that.$util.Tips({
title: res
});
});
},
async code() {
let that = this;
if (!that.account) return that.$util.Tips({
title: '请填写手机号码'
});
if (!that.isAgree) return that.$util.Tips({
title: '请勾选用户隐私协议'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.account)) return that.$util.Tips({
title: '请输入正确的手机号码'
});
if (that.formItem == 2) that.type = "register";
that.$refs.verify.show();
},
navTap: function(index) {
this.current = index;
},
//账号密码登录
submit:Debounce(function() {
let that = this;
if (!that.account) return that.$util.Tips({
title: '请填写账号'
});
if (!/^[\w\d]{5,16}$/i.test(that.account)) return that.$util.Tips({
title: '请输入正确的账号'
});
if (!that.password) return that.$util.Tips({
title: '请填写密码'
});
if (!that.isAgree) return that.$util.Tips({
title: '请勾选用户隐私协议'
});
uni.showLoading({
title: '登录中'
})
loginH5({
account: that.account,
password: that.password,
spread_spid: that.$Cache.get("spread")
}).then(({data}) => {
this.$store.commit("LOGIN", {
'token': data.token
});
uni.hideLoading();
that.getUserInfo(data);
})
.catch(e => {
uni.hideLoading();
that.$util.Tips({
title: e
});
});
}),
getUserInfo(data){
this.$store.commit("SETUID", data.uid);
getUserInfo().then(res => {
this.$store.commit("UPDATE_USERINFO", res.data);
let backUrl = this.$Cache.get(BACK_URL) || "/pages/index/index";
if (backUrl.indexOf('/pages/sub-pages/login/index') !== -1) {
backUrl = '/pages/index/index';
}
uni.reLaunch({
url: backUrl
});
})
},
}
};
</script>
<style lang="scss" scoped>
page {
background: #fff;
}
.appLogin {
margin-top: 60rpx;
.hds {
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
color: #B4B4B4;
.line {
width: 68rpx;
height: 1rpx;
background: #CCCCCC;
}
p {
margin: 0 20rpx;
}
}
.btn-wrapper {
display: flex;
align-items: center;
justify-content: center;
margin-top: 30rpx;
.btn {
display: flex;
align-items: center;
justify-content: center;
width: 68rpx;
height: 68rpx;
border-radius: 50%;
}
.apple-btn {
display: flex;
align-items: center;
justify-content: center;
margin-left: 30rpx;
background: #000;
border-radius: 34rpx;
font-size: 40rpx;
.icon-s-pingguo {
color: #fff;
font-size: 40rpx;
}
}
.iconfont {
font-size: 40rpx;
color: #fff;
}
.wx {
margin-right: 30rpx;
background-color: #61C64F;
}
.mima {
background-color: #28B3E9;
}
.yanzheng {
background-color: #F89C23;
}
}
}
.main_color{
@include main_color(theme);
}
.bg_color{
@include main_bg_color(theme);
}
.code img {
width: 100%;
height: 100%;
}
.acea-row.row-middle {
input {
margin-left: 20rpx;
display: block;
}
}
.login-wrapper {
padding: 30rpx;
.shading {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
/* #ifdef APP-VUE */
margin-top: 50rpx;
/* #endif */
/* #ifndef APP-VUE */
margin-top: 200rpx;
/* #endif */
image {
width: 180rpx;
height: 180rpx;
}
}
.whiteBg {
margin-top: 100rpx;
.list {
border-radius: 16rpx;
overflow: hidden;
.item {
border-bottom: 1px solid #F0F0F0;
background: #fff;
.row-middle {
position: relative;
padding: 16rpx 45rpx;
.texts{
flex: 1;
font-size: 28rpx;
height: 80rpx;
line-height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
input {
flex: 1;
font-size: 28rpx;
height: 80rpx;
line-height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
.code {
position: absolute;
right: 30rpx;
top: 50%;
color: $theme-color;
font-size: 26rpx;
transform: translateY(-50%);
}
}
}
}
.logon {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 86rpx;
margin-top: 80rpx;
background-color: $theme-color;
border-radius: 120rpx;
color: #FFFFFF;
font-size: 30rpx;
}
.tips {
margin: 30rpx;
text-align: center;
color: #999;
}
}
}
.protocol {
margin: 30rpx 0;
padding-left: 44rpx;
.protocol_text {
.font_pro {
@include main_color(theme);
}
}
}
</style>

View File

@@ -0,0 +1,617 @@
<template>
<view :data-theme="theme">
<!-- #ifndef APP-PLUS -->
<nav-bar :navTitle='navTitle' @getNavH='getNavH'></nav-bar>
<!-- #endif -->
<view class='my-order' :style="'margin-top:'+(marTop)+'rpx;'">
<view class='header bg_color'>
<view class='picTxt acea-row row-between-wrapper'>
<view class='text'>
<view class='name'>订单信息</view>
<view>消费订单{{orderData.orderCount || 0}} 总消费{{orderData.sumPrice ? Number(orderData.sumPrice).toFixed(2) : 0}}</view>
</view>
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/orderTime.png'"></image>
</view>
</view>
</view>
<view class='nav acea-row row-around'>
<view class='item' :class='orderStatus==0 ? "on": ""' @click="statusClick(0)">
<view>待付款</view>
<view class='num'>{{orderData.unPaidCount || 0}}</view>
</view>
<view class='item' :class='orderStatus==1 ? "on": ""' @click="statusClick(1)">
<view>待发货</view>
<view class='num'>{{orderData.unShippedCount || 0}}</view>
</view>
<view class='item' :class='orderStatus==2 ? "on": ""' @click="statusClick(2)">
<view>待收货</view>
<view class='num '>{{orderData.receivedCount || 0}}</view>
</view>
<view class='item' :class='orderStatus==3 ? "on": ""' @click="statusClick(3)">
<view>待评价</view>
<view class='num'>{{orderData.evaluatedCount || 0}}</view>
</view>
<view class='item' :class='orderStatus==4 ? "on": ""' @click="statusClick(4)">
<view>已完成</view>
<view class='num'>{{orderData.completeCount || 0}}</view>
</view>
</view>
<view class='list'>
<view class='item' v-for="(item,index) in orderList" :key="index">
<view @click='goOrderDetails(item.orderId)'>
<view class='title acea-row row-between-wrapper'>
<view class="acea-row row-middle">
<text class="sign cart-color acea-row row-center-wrapper" v-if="item.activityType !== '普通' && item.activityType !== '核销'">{{item.activityType}}</text>
<view>{{item.createTime}}</view>
</view>
<view class='font_color'>{{item.orderStatus}}</view>
</view>
<view class='item-info acea-row row-between row-top' v-for="(items,index) in item.orderInfoList" :key="index">
<view class='pictrue'>
<image :src='items.image'></image>
</view>
<view class='text acea-row row-between'>
<view class='name line2'>{{items.storeName}}</view>
<view class='money'>
<view :style="[{'font-size':items.price.length>8?'24rpx':'28rpx'}]" >{{items.price}}</view>
<view>x{{items.cartNum}}</view>
</view>
</view>
</view>
<view class='totalPrice'>{{item.totalNum}}件商品总金额
<text class='money'>{{item.payPrice}}</text>
</view>
</view>
<view class='bottom acea-row row-right row-middle'>
<view class='bnt cancelBnt' v-if="!item.paid" @click='cancelOrder(index,item.id)'>取消订单</view>
<view class='bnt bg_color' v-if="!item.paid" @click='goPay(item.payPrice,item.orderId)'>立即付款</view>
<view class='bnt bg_color' v-else-if="item.status== 0 || item.status== 1 || item.status== 3" @click='goOrderDetails(item.orderId)'>查看详情</view>
<view class='bnt bg_color' v-else-if="item.status==2" @click='goComment(item)'>去评价</view>
<view class='bnt cancelBnt' v-if="item.status == 3" @click='delOrder(item.id,index)'>删除订单</view>
</view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper'>
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{orderList.length>0?loadTitle:''}}
</view>
<view class='noCart' v-if="orderList.length == 0 && isShow && !loading">
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/noOrder.png'"></image>
</view>
</view>
</view>
<payment :pay_close="pay_close" @onChangeFun='onChangeFun' :order_id="pay_order_id" :totalPrice='totalPrice'></payment>
</view>
</template>
<script>
import {
getOrderList,
orderData,
orderCancel,
orderDel
} from '@/api/order.js';
import {openOrderSubscribe} from '@/utils/SubscribeMessage.js';
import payment from '@/components/payment';
import navBar from '@/components/navBar';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import emptyPage from '@/components/emptyPage.vue'
import {setThemeColor} from '@/utils/setTheme.js'
import animationType from '@/utils/animationType.js'
const app = getApp();
export default {
components: {
payment,
emptyPage,
navBar
},
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
navTitle: '我的订单',
loading: false, //是否加载中
loadend: false, //是否加载完毕
loadTitle: '加载更多', //提示语
orderList: [], //订单数组
orderData: {}, //订单详细统计
orderStatus: 0, //订单状态
page: 1,
limit: 20,
payMode: [{
name: "微信支付",
icon: "icon-weixinzhifu",
value: 'weixin',
title: '微信快捷支付',
payStatus: 1,
},
{
name: "余额支付",
icon: "icon-yuezhifu",
value: 'yue',
title: '可用余额:',
number: 0,
payStatus: 1,
},
// #ifndef MP
{
"name": "支付宝支付",
"icon": "icon-zhifubao",
value: 'alipay',
title: '支付宝快捷支付',
payStatus: 1,
}
// #endif
],
pay_close: false,
pay_order_id: '',
totalPrice: '0',
isShow: false,
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
theme:app.globalData.theme,
bgColor:'#e93323',
marTop: 0
};
},
computed: mapGetters(['isLogin', 'userInfo']),
onShow() {
let that = this;
that.bgColor = setThemeColor();
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor:that.bgColor,
});
if (this.isLogin) {
this.loadend = false;
this.page = 1;
this.$set(this, 'orderList', []);
this.getOrderData();
this.getOrderList();
this.payMode[1].number = this.userInfo.nowMoney;
this.$set(this, 'payMode', this.payMode);
} else {
toLogin();
}
},
mounted:function(){
// #ifdef H5
if(this.$wechat.isWeixin()) this.payMode.pop();
// #endif
},
methods: {
getNavH(marTop){
this.marTop = marTop;
},
onLoadFun() {
this.getOrderData();
this.getOrderList();
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
/**
* 事件回调
*
*/
onChangeFun: function(e) {
let opt = e;
let action = opt.action || null;
let value = opt.value != undefined ? opt.value : null;
(action && this[action]) && this[action](value);
},
/**
* 关闭支付组件
*
*/
payClose: function() {
this.pay_close = false;
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
if (options.status) this.orderStatus = options.status;
},
/**
* 获取订单统计数据
*
*/
getOrderData: function() {
let that = this;
orderData().then(res => {
that.$set(that, 'orderData', res.data);
})
},
/**
* 取消订单
*
*/
cancelOrder: function(index, order_id) {
let that = this;
if (!order_id) return that.$util.Tips({
title: '缺少订单号无法取消订单'
});
uni.showModal({
content: '确定取消该订单',
cancelText: "取消",
confirmText: "确定",
showCancel: true,
confirmColor: '#f55850',
success: (res) => {
if(res.confirm) {
uni.showLoading({
title: '正在取消中'
});
orderCancel(order_id).then(res => {
uni.hideLoading();
return that.$util.Tips({
title: '取消成功',
icon: 'success'
}, function() {
that.orderList.splice(index, 1);
that.$set(that, 'orderList', that.orderList);
that.$set(that.orderData, 'unpaid_count', that.orderData.unpaid_count - 1);
that.getOrderData();
});
}).catch(err => {
return that.$util.Tips({
title: err
});
});
} else {
}
} ,
})
},
/**
* 打开支付组件
*
*/
goPay(pay_price, order_id) {
// this.$set(this, 'pay_close', true);
// this.$set(this, 'pay_order_id', order_id);
// this.$set(this, 'totalPrice', pay_price);
uni.navigateTo({
url:`/pages/order/order_payment/index?orderNo=${order_id}&payPrice=${pay_price}`
})
},
/**
* 支付成功回调
*
*/
pay_complete: function() {
this.loadend = false;
this.page = 1;
this.$set(this, 'orderList', []);
this.$set(this, 'pay_close', false);
this.getOrderData();
this.getOrderList();
},
/**
* 支付失败回调
*
*/
pay_fail: function() {
this.pay_close = false;
},
//去评价
goComment(item){
uni.navigateTo({
url:`/pages/goods/goods_comment_con/index?unique=${item.orderInfoList[0].attrId}&orderId=${item.orderId}&id=${item.id}`
})
},
/**
* 去订单详情
*/
goOrderDetails: function(order_id,status) {
if (!order_id) return that.$util.Tips({
title: '缺少订单号无法查看订单详情'
});
// #ifdef MP
// uni.showLoading({
// title: '正在加载',
// })
// if(status == 0 || this.orderStatus ==3 || this.orderStatus ==4){
// uni.navigateTo({
// url: '/pages/order_details/index?order_id=' + order_id
// })
// }else{
// openOrderSubscribe().then(() => {
// uni.hideLoading();
// uni.navigateTo({
// url: '/pages/order_details/index?order_id=' + order_id
// })
// }).catch(() => {
// uni.hideLoading();
// })
// }
uni.navigateTo({
url: '/pages/order/order_details/index?order_id=' + order_id
})
// #endif
// #ifndef MP
uni.navigateTo({
animationType: animationType.type, animationDuration: animationType.duration,
url: '/pages/order/order_details/index?order_id=' + order_id
})
// #endif
},
/**
* 切换类型
*/
statusClick: function(status) {
if (status == this.orderStatus) return;
this.orderStatus = status;
this.loadend = false;
this.page = 1;
this.$set(this, 'orderList', []);
this.getOrderList();
},
/**
* 获取订单列表
*/
getOrderList: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
that.loadTitle = "加载更多";
getOrderList({
type: that.orderStatus,
page: that.page,
limit: that.limit,
}).then(res => {
let list = res.data.list || [];
let loadend = list.length < that.limit;
that.orderList = that.$util.SplitArray(list, that.orderList);
that.$set(that, 'orderList', that.orderList);
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? "哼😕~我也是有底线的~" : '加载更多';
that.page = that.page + 1;
that.isShow = true;
}).catch(err => {
that.loading = false;
that.loadTitle = "加载更多";
})
},
/**
* 删除订单
*/
delOrder: function(order_id, index) {
uni.showModal({
content: '确定删除该订单',
cancelText: "取消",
confirmText: "确定",
showCancel: true,
confirmColor: '#f55850',
success: (res) => {
if(res.confirm) {
let that = this;
orderDel(order_id).then(res => {
that.orderList.splice(index, 1);
that.$set(that, 'orderList', that.orderList);
that.$set(that.orderData, 'unpaid_count', that.orderData.unpaid_count - 1);
that.getOrderData();
return that.$util.Tips({
title: '删除成功',
icon: 'success'
});
}).catch(err => {
return that.$util.Tips({
title: err
});
})
} else {
}
} ,
})
},
},
onReachBottom: function() {
this.getOrderList();
}
}
</script>
<style scoped lang="scss">
.my-order .header {
height: 250rpx;
padding: 0 30rpx;
}
.bg_color{
@include main_bg_color(theme);
}
.my-order .header .picTxt {
height: 190rpx;
}
.my-order .header .picTxt .text {
color: rgba(255, 255, 255, 0.8);
font-size: 26rpx;
font-family: 'Guildford Pro';
}
.my-order .header .picTxt .text .name {
font-size: 34rpx;
font-weight: bold;
color: #fff;
margin-bottom: 20rpx;
}
.my-order .header .picTxt .pictrue {
width: 122rpx;
height: 109rpx;
}
.my-order .header .picTxt .pictrue image {
width: 100%;
height: 100%;
}
.my-order .nav {
background-color: #fff;
width: 690rpx;
height: 140rpx;
border-radius: 14rpx;
margin: -60rpx auto 0 auto;
}
.my-order .nav .item {
text-align: center;
font-size: 26rpx;
color: #282828;
padding: 26rpx 0;
}
.my-order .nav .item.on {
/* #ifdef H5 || MP */
font-weight: bold;
/* #endif */
/* #ifdef APP-PLUS */
color: #000;
/* #endif */
position: relative;
}
.my-order .nav .item.on ::after{
content: '';
width: 78rpx;
height: 4rpx;
@include main_bg_color(theme);
position: absolute;
bottom: 2rpx;
left: 0;
}
.my-order .nav .item .num {
margin-top: 18rpx;
}
.my-order .list {
width: 690rpx;
margin: 14rpx auto 0 auto;
}
.my-order .list .item {
background-color: #fff;
border-radius: 14rpx;
margin-bottom: 14rpx;
}
.my-order .list .item .title {
height: 84rpx;
padding: 0 24rpx;
border-bottom: 1rpx solid #eee;
font-size: 28rpx;
color: #282828;
}
.my-order .list .item .title .sign {
font-size: 24rpx;
padding: 0 13rpx;
height: 36rpx;
margin-right: 15rpx;
border-radius: 18rpx;
@include coupons_border_color(theme);
@include main_color(theme);
}
.my-order .list .item .item-info {
padding: 0 24rpx;
margin-top: 22rpx;
}
.my-order .list .item .item-info .pictrue {
width: 120rpx;
height: 120rpx;
}
.my-order .list .item .item-info .pictrue image {
width: 100%;
height: 100%;
border-radius: 14rpx;
}
.my-order .list .item .item-info .text {
width: 500rpx;
font-size: 28rpx;
color: #999;
}
.my-order .list .item .item-info .text .name {
width: 350rpx;
color: #282828;
}
.my-order .list .item .item-info .text .money {
text-align: right;
}
.font_color{
@include main_color(theme);
}
.my-order .list .item .totalPrice {
font-size: 26rpx;
color: #282828;
text-align: right;
margin: 27rpx 0 0 30rpx;
padding: 0 30rpx 30rpx 0;
border-bottom: 1rpx solid #eee;
}
.my-order .list .item .totalPrice .money {
font-size: 28rpx;
font-weight: bold;
@include price_color(theme);
}
.my-order .list .item .bottom {
height: 107rpx;
padding: 0 30rpx;
}
.my-order .list .item .bottom .bnt {
width: 176rpx;
height: 60rpx;
text-align: center;
line-height: 60rpx;
color: #fff;
border-radius: 50rpx;
font-size: 27rpx;
}
.my-order .list .item .bottom .bnt.cancelBnt {
border: 1rpx solid #ddd;
color: #aaa;
}
.my-order .list .item .bottom .bnt~.bnt {
margin-left: 17rpx;
}
.noCart {
margin-top: 171rpx;
padding-top: 0.1rpx;
}
.noCart .pictrue {
width: 414rpx;
height: 336rpx;
margin: 78rpx auto 56rpx auto;
}
.noCart .pictrue image {
width: 100%;
height: 100%;
}
</style>

View File

@@ -0,0 +1,615 @@
<template>
<view :data-theme="theme">
<form @submit="formSubmit" report-submit='true'>
<view class='addAddress pad30'>
<view class='list borRadius14'>
<view class='item acea-row row-between-wrapper' style="border: none;">
<view class='name'>姓名</view>
<input type='text' placeholder='请输入姓名' placeholder-style="color:#ccc;" name='realName'
:value="userAddress.realName" placeholder-class='placeholder' maxlength="20"></input>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>联系电话</view>
<input type='number' placeholder='请输入联系电话' placeholder-style="color:#ccc;" name="phone"
:value='userAddress.phone' placeholder-class='placeholder' maxlength="11"></input>
</view>
<view class='item acea-row row-between-wrapper relative'>
<view class='name'>所在地区</view>
<view class="address">
<picker mode="multiSelector" @change="bindRegionChange"
@columnchange="bindMultiPickerColumnChange" :value="valueRegion" :range="multiArray">
<view class='acea-row'>
<view class="picker line1">{{region[0]}}{{region[1]}}{{region[2]}}</view>
<view class='iconfont icon-xiangyou abs_right'></view>
</view>
</picker>
</view>
</view>
<view class='item acea-row row-between-wrapper relative'>
<view class='name'>详细地址</view>
<input type='text' placeholder='请填写具体地址' placeholder-style="color:#ccc;" name='detail'
placeholder-class='placeholder' v-model='userAddress.detail' maxlength="100"></input>
<view class='iconfont icon-dizhi font_color abs_right' @tap="chooseLocation"></view>
</view>
</view>
<view class='default acea-row row-middle borRadius14'>
<checkbox-group @change='ChangeIsDefault'>
<checkbox :checked="userAddress.isDefault" />设置为默认地址
</checkbox-group>
</view>
<button class='keepBnt bg_color' form-type="submit">立即保存</button>
<!-- #ifdef MP -->
<view class="wechatAddress" v-if="!id" @click="getWxAddress">导入微信地址</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view class="wechatAddress" v-if="this.$wechat.isWeixin() && !id" @click="getAddress">导入微信地址</view>
<!-- #endif -->
</view>
</form>
<view v-show="showLoading" class="bg-fixed"></view>
</view>
</template>
<script>
import {
editAddress,
getAddressDetail
} from '@/api/user.js';
import {
getCityList
} from "@/utils";
import {
getCity
} from '@/api/api.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import {
Debounce
} from '@/utils/validate.js'
import atModel from '@/components/accredit/index.vue';
let app = getApp();
export default {
components: {
atModel
},
data() {
return {
cartId: '', //购物车id
pinkId: 0, //拼团id
couponId: 0, //优惠券id
id: 0, //地址id
userAddress: {
isDefault: false
}, //地址详情
region: ['省', '市', '区'],
valueRegion: [0, 0, 0],
district: [],
multiArray: [],
multiIndex: [0, 0, 0],
cityId: 0,
bargain: false, //是否是砍价
combination: false, //是否是拼团
secKill: false, //是否是秒杀
theme: app.globalData.theme,
showLoading: false
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getUserAddress();
}
},
deep: true
}
},
onLoad(options) {
if (this.$Cache.getItem('cityList')) {
//检测城市数据缓存是否过期,有的话从缓存取,没有的话请求接口
this.district = this.$Cache.getItem('cityList');
this.initialize();
} else {
this.showLoading = true;
uni.showLoading({
title: '数据加载中...'
});
getCityList().then(res=>{
this.district = res
this.initialize();
uni.hideLoading();
this.showLoading = false;
})
}
if (this.isLogin) {
this.preOrderNo = options.preOrderNo || 0;
this.id = options.id || 0;
uni.setNavigationBarTitle({
title: options.id ? '修改地址' : '添加地址'
})
this.getUserAddress();
} else {
toLogin();
}
},
methods: {
// #ifdef APP-PLUS
// 获取选择的地区
handleGetRegion(region) {
this.region = region
},
// #endif
getUserAddress: function() {
if (!this.id) return false;
let that = this;
getAddressDetail(this.id).then(res => {
if(res.data){
let region = [res.data.province, res.data.city, res.data.district];
that.$set(that, 'userAddress', res.data);
that.$set(that, 'region', region);
that.city_id = res.data.cityId;
}
});
},
initialize: function() {
let that = this,province = [],city = [],area = [];
if (that.district.length) {
let cityChildren = that.district[0].child || [];
let areaChildren = cityChildren.length ? (cityChildren[0].child || []) : [];
that.district.forEach(function(item,i) {
province.push(item.name);
if (item.name === that.region[0]) {
that.valueRegion[0] = i
that.multiIndex[0] = i
}
});
that.district[this.valueRegion[0]].child.forEach((item,i)=>{
city.push(item.name);
if (that.region[1] == item.name) {
that.valueRegion[1] = i
that.multiIndex[1] = i
}
})
that.district[this.valueRegion[0]].child[this.valueRegion[1]].child.forEach((item,i)=>{
area.push(item.name);
if (that.region[2] == item.name) {
that.valueRegion[2] = i
that.multiIndex[2] = i
}
})
this.multiArray = [province, city, area]
}
},
bindRegionChange: function(e) {
let multiIndex = this.multiIndex,
province = this.district[multiIndex[0]] || {
child: []
},
city = province.child[multiIndex[1]] || {
child: []
},
area = city.child[multiIndex[2]] || {
cityId: 0
},
multiArray = this.multiArray,
value = e.detail.value;
this.region = [multiArray[0][value[0]], multiArray[1][value[1]], multiArray[2][value[2]]]
this.cityId = area.cityId;
this.valueRegion = [0, 0, 0]
this.initialize();
},
bindMultiPickerColumnChange: function(e) {
let that = this,
column = e.detail.column,
value = e.detail.value,
currentCity = this.district[value] || {
child: []
},
multiArray = that.multiArray,
multiIndex = that.multiIndex;
multiIndex[column] = value;
switch (column) {
case 0:
let areaList = currentCity.child[0] || {
child: []
};
multiArray[1] = currentCity.child.map((item) => {
return item.name;
});
multiArray[2] = areaList.child.map((item) => {
return item.name;
});
break;
case 1:
let cityList = that.district[multiIndex[0]].child[multiIndex[1]].child || [];
multiArray[2] = cityList.map((item) => {
return item.name;
});
break;
case 2:
break;
}
// #ifdef MP || APP-PLUS
this.$set(this.multiArray, 0, multiArray[0]);
this.$set(this.multiArray, 1, multiArray[1]);
this.$set(this.multiArray, 2, multiArray[2]);
// #endif
// #ifdef H5
this.multiArray = multiArray;
// #endif
this.multiIndex = multiIndex
// this.setData({ multiArray: multiArray, multiIndex: multiIndex});
},
toggleTab(str) {
this.$refs[str].show();
},
onConfirm(val) {
this.region = val.checkArr[0] + '-' + val.checkArr[1] + '-' + val.checkArr[2];
},
//选择地位地址
chooseLocation: function() {
this.$util.$L.getLocation().then(res=>{
uni.chooseLocation({
latitude: uni.getStorageSync('user_latitude'),
longitude: uni.getStorageSync('user_longitude'),
success: (res) => {
this.$set(this.userAddress, 'detail', res.name);
}
})
})
},
// 导入共享地址(小程序)
getWxAddress: function() {
let that = this;
uni.authorize({
scope: 'scope.address',
success: function(res) {
uni.chooseAddress({
success: function(res) {
let addressP = {};
addressP.province = res.provinceName;
addressP.city = res.cityName;
addressP.district = res.countyName;
addressP.cityId = 0;
editAddress({
address: addressP,
isDefault: 1,
realName: res.userName,
postCode: res.postalCode,
phone: res.telNumber,
detail: res.detailInfo,
id: 0
}).then(res => {
setTimeout(function() {
if (that.cartId) {
let cartId = that.cartId;
let pinkId = that.pinkId;
let couponId = that.couponId;
that.cartId = '';
that.pinkId = '';
that.couponId = '';
uni.navigateTo({
url: '/pages/order/order_confirm/index?cartId=' +
cartId +
'&addressId=' + (
that.id ? that
.id :
res.data
.id) +
'&pinkId=' +
pinkId +
'&couponId=' +
couponId +
'&secKill=' + that
.secKill +
'&combination=' +
that.combination +
'&bargain=' + that
.bargain
});
} else {
uni.navigateBack({
delta: 1
});
}
}, 1000);
return that.$util.Tips({
title: "添加成功",
icon: 'success'
});
}).catch(err => {
return that.$util.Tips({
title: err
});
});
},
fail: function(res) {
if (res.errMsg == 'chooseAddress:cancel') return that.$util
.Tips({
title: '取消选择'
});
},
})
},
fail: function(res) {
uni.showModal({
title: '您已拒绝导入微信地址权限',
content: '是否进入权限管理,调整授权?',
success(res) {
if (res.confirm) {
uni.openSetting({
success: function(res) {}
});
} else if (res.cancel) {
return that.$util.Tips({
title: '已取消!'
});
}
}
})
},
})
},
// 导入共享地址(微信);
getAddress() {
let that = this;
that.$wechat.openAddress().then(userInfo => {
// open();
editAddress({
id: this.id,
realName: userInfo.userName,
phone: userInfo.telNumber,
address: {
province: userInfo.provinceName,
city: userInfo.cityName,
district: userInfo.countryName,
cityId: 0
},
detail: userInfo.detailInfo,
isDefault: 1,
postCode: userInfo.postalCode
})
.then(() => {
setTimeout(function() {
if (that.cartId) {
let cartId = that.cartId;
let pinkId = that.pinkId;
let couponId = that.couponId;
that.cartId = '';
that.pinkId = '';
that.couponId = '';
uni.navigateTo({
url: '/pages/order/order_confirm/index?cartId=' +
cartId + '&addressId=' + (that.id ? that.id :
res.data
.id) + '&pinkId=' + pinkId + '&couponId=' +
couponId + '&secKill=' + that.secKill +
'&combination=' + that.combination + '&bargain=' +
that.bargain
});
} else {
uni.navigateTo({
url: '/pages/users/user_address_list/index'
})
// history.back();
}
}, 1000);
// close();
that.$util.Tips({
title: "添加成功",
icon: 'success'
});
})
.catch(err => {
// close();
return that.$util.Tips({
title: err || "添加失败"
});
});
}).catch(err => {
console.log(err);
});
},
/**
* 提交用户添加地址
*
*/
formSubmit: Debounce(function(e) {
let that = this,
value = e.detail.value;
if (!value.realName) return that.$util.Tips({
title: '请填写收货人姓名'
});
if (!value.phone) return that.$util.Tips({
title: '请填写联系电话'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(value.phone)) return that.$util.Tips({
title: '请输入正确的手机号码'
});
if (that.region == '省-市-区') return that.$util.Tips({
title: '请选择所在地区'
});
if (!value.detail) return that.$util.Tips({
title: '请填写详细地址'
});
value.id = that.id;
let regionArray = that.region;
value.address = {
province: regionArray[0],
city: regionArray[1],
district: regionArray[2],
cityId: that.cityId,
};
value.isDefault = that.userAddress.isDefault;
uni.showLoading({
title: '保存中',
mask: true
})
editAddress(value).then(res => {
if (that.id)
that.$util.Tips({
title: '修改成功',
icon: 'success'
});
else
that.$util.Tips({
title: '添加成功',
icon: 'success'
});
setTimeout(function() {
if (that.preOrderNo > 0) {
uni.redirectTo({
url: '/pages/order/order_confirm/index?preOrderNo=' + that
.preOrderNo + '&addressId=' + (that.id ? that.id : res
.data.id)
})
} else {
// #ifdef H5
return history.back();
// #endif
// #ifndef H5
return uni.navigateBack({
delta: 1,
})
// #endif
}
}, 1000);
}).catch(err => {
return that.$util.Tips({
title: err
});
})
}),
ChangeIsDefault: function(e) {
this.$set(this.userAddress, 'isDefault', !this.userAddress.isDefault);
}
}
}
</script>
<style scoped lang="scss">
.bg-fixed{
width: 100%;
height: 750rpx;
position: absolute;
top: 0;
}
.addAddress {
padding-top: 20rpx;
}
.bg_color {
@include main_bg_color(theme);
}
.addAddress .list {
background-color: #fff;
padding: 0 24rpx;
}
.addAddress .list .item {
border-top: 1rpx solid #eee;
height: 90rpx;
line-height: 90rpx;
}
.addAddress .list .item .name {
// width: 195rpx;
font-size: 30rpx;
color: #333;
}
.addAddress .list .item .address {
flex: 1;
margin-left: 50rpx;
}
.addAddress .list .item input {
width: 475rpx;
font-size: 30rpx;
font-weight: 400;
}
.addAddress .list .item .placeholder {
color: #ccc;
}
.addAddress .list .item picker .picker {
width: 410rpx;
font-size: 30rpx;
}
.addAddress .default {
padding: 0 30rpx;
height: 90rpx;
background-color: #fff;
margin-top: 23rpx;
}
.addAddress .default checkbox {
margin-right: 15rpx;
}
.addAddress .keepBnt {
width: 690rpx;
height: 86rpx;
border-radius: 50rpx;
text-align: center;
line-height: 86rpx;
margin: 80rpx auto 24rpx auto;
font-size: 32rpx;
color: #fff;
}
.addAddress .wechatAddress {
width: 690rpx;
height: 86rpx;
border-radius: 50rpx;
text-align: center;
line-height: 86rpx;
margin: 0 auto;
font-size: 32rpx;
// color: #E93323 ;
@include main_color(theme);
@include coupons_border_color(theme);
}
.font_color {
@include main_color(theme);
}
.relative {
position: relative;
}
.icon-dizhi {
font-size: 44rpx;
z-index: 100;
}
.abs_right {
position: absolute;
right: 0;
}
::v-deep checkbox .uni-checkbox-input.uni-checkbox-input-checked {
@include main_bg_color(theme);
@include coupons_border_color(theme);
color: #fff !important
}
::v-deep checkbox .wx-checkbox-input.wx-checkbox-input-checked {
@include main_bg_color(theme);
@include coupons_border_color(theme);
color: #fff !important;
margin-right: 0 !important;
}
</style>

View File

@@ -0,0 +1,509 @@
<template>
<view :data-theme="theme">
<view class='line'>
<image :src="urlDomain+'crmebimage/perset/staticImg/line.jpg'" v-if="addressList.length"></image>
</view>
<view class='address-management' :class='addressList.length < 1 && page > 1 ? "fff":""'>
<radio-group class="radio-group" @change="radioChange" v-if="addressList.length">
<view class='item borRadius14' v-for="(item,index) in addressList" :key="index">
<view class='address' @click='goOrder(item)'>
<view class='consignee'>收货人{{item.realName}}<text class='phone'>{{item.phone}}</text></view>
<view>收货地址{{item.province}}{{item.city}}{{item.district}}{{item.detail}}</view>
</view>
<view class='operation acea-row row-between-wrapper'>
<!-- #ifndef MP -->
<radio class="radio" :value="index.toString()" :checked="item.isDefault">
<text>设为默认</text>
</radio>
<!-- #endif -->
<!-- #ifdef MP -->
<radio class="radio" :value="index" :checked="item.isDefault">
<text>设为默认</text>
</radio>
<!-- #endif -->
<view class='acea-row row-middle'>
<view @click='editAddress(item.id)'><text class='iconfont icon-bianji'></text>编辑</view>
<view @click='delAddress(index)'><text class='iconfont icon-shanchu'></text>删除</view>
</view>
</view>
</view>
</radio-group>
<view class='loadingicon acea-row row-center-wrapper' v-if="addressList.length">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view class='noCommodity' v-if="addressList.length < 1 && page > 1">
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/noAddress.png'"></image>
</view>
</view>
<view style='height:120rpx;'></view>
</view>
<view class='footer acea-row row-between-wrapper'>
<!-- #ifdef APP-PLUS -->
<view class='addressBnt bg_color on' @click='addAddress'><text
class='iconfont icon-tianjiadizhi'></text>添加新地址</view>
<!-- #endif -->
<!-- #ifdef MP-->
<view class='addressBnt bg_color' @click='addAddress'><text class='iconfont icon-tianjiadizhi'></text>添加新地址
</view>
<view class='addressBnt wxbnt' @click='getWxAddress'><text class='iconfont icon-weixin2'></text>导入微信地址
</view>
<!-- #endif -->
<!-- #ifdef H5-->
<view class='addressBnt bg_color' :class="this.$wechat.isWeixin()?'':'on'" @click='addAddress'><text
class='iconfont icon-tianjiadizhi'></text>添加新地址</view>
<view v-if="this.$wechat.isWeixin()" class='addressBnt wxbnt' @click='getAddress'><text
class='iconfont icon-weixin2'></text>导入微信地址</view>
<!-- #endif -->
</view>
<!-- #ifdef MP -->
<atModel v-if="locationStatus" :locationType="true" @closeModel="modelCancel" @confirmModel="confirmModel"
:content="locationContent"></atModel>
<!-- #endif -->
</view>
</template>
<script>
import {
getAddressList,
setAddressDefault,
delAddress,
editAddress,
postAddress
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import atModel from '@/components/accredit/index.vue';
import {
mapGetters
} from "vuex";
let app = getApp();
export default {
components: {
atModel
},
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
addressList: [],
cartId: '',
pinkId: 0,
couponId: 0,
loading: false,
loadend: false,
loadTitle: '加载更多',
page: 1,
limit: 20,
bargain: false, //是否是砍价
combination: false, //是否是拼团
secKill: false, //是否是秒杀
theme: app.globalData.theme,
locationContent: '授权位置信息,提供完整服务',
locationStatus: false
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getUserAddress(true);
}
},
deep: true
}
},
onLoad(options) {
if (this.isLogin) {
this.preOrderNo = options.preOrderNo || 0;
this.getAddressList(true);
} else {
toLogin();
}
},
onShow: function() {
let that = this;
that.getAddressList(true);
},
methods: {
modelCancel() {
this.locationStatus = false;
},
confirmModel() {
uni.getLocation({
type: 'gcj02',
altitude: true,
geocode: true,
success: function(res) {
try {
uni.setStorageSync('user_latitude', res.latitude);
uni.setStorageSync('user_longitude', res.longitude);
} catch {}
}
});
this.locationStatus = false;
},
/*
* 导入微信地址(小程序)
*/
getWxAddress: function() {
let that = this;
uni.authorize({
scope: 'scope.address',
success: function(res) {
uni.chooseAddress({
success: function(res) {
let addressP = {};
addressP.province = res.provinceName;
addressP.city = res.cityName;
addressP.district = res.countyName;
addressP.cityId = 0;
editAddress({
address: addressP,
isDefault: false,
realName: res.userName,
postCode: res.postalCode,
phone: res.telNumber,
detail: res.detailInfo,
id: 0
//type: 1//区别城市id导入微信地址无城市id需要后台自己查找;
}).then(res => {
setTimeout(() => {
that.getAddressList(true);
that.$util.Tips({
title: "添加成功",
icon: 'success'
});
}, 0)
}).catch(err => {
return that.$util.Tips({
title: err
});
});
},
fail: function(res) {
if (res.errMsg == 'chooseAddress:cancel') return that.$util
.Tips({
title: '取消选择'
});
},
})
},
fail: function(res) {
uni.showModal({
title: '您已拒绝导入微信地址权限',
content: '是否进入权限管理,调整授权?',
success(res) {
if (res.confirm) {
uni.openSetting({
success: function(res) {
console.log(res.authSetting)
}
});
} else if (res.cancel) {
return that.$util.Tips({
title: '已取消!'
});
}
}
})
}
})
},
/*
* 导入微信地址(公众号)
*/
getAddress() {
let that = this;
that.$wechat.openAddress().then(userInfo => {
// open();
editAddress({
realName: userInfo.userName,
phone: userInfo.telNumber,
address: {
province: userInfo.provinceName,
city: userInfo.cityName,
district: userInfo.countryName,
cityId: 0
},
detail: userInfo.detailInfo,
postCode: userInfo.postalCode,
isDefault: false,
})
.then(() => {
setTimeout(() => {
that.getAddressList(true);
that.$util.Tips({
title: "添加成功",
icon: 'success'
});
}, 0)
})
.catch(err => {
// close();
return that.$util.Tips({
title: err || "添加失败"
});
});
}).catch(err => {
that.$util.Tips({
title: err.errMsg || "添加失败"
});
});
},
/**
* 获取地址列表
*
*/
getAddressList: function(isPage) {
let that = this;
if (isPage) {
that.loadend = false;
that.page = 1;
that.$set(that, 'addressList', []);
};
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
getAddressList({
page: that.page,
limit: that.limit
}).then(res => {
let list = res.data.list;
let loadend = list.length < that.limit;
that.addressList = that.$util.SplitArray(list, that.addressList);
that.$set(that, 'addressList', that.addressList);
that.loadend = loadend;
that.loadTitle = loadend ? '哼😕~我也是有底线的~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err => {
that.loading = false;
that.loadTitle = '加载更多';
});
},
/**
* 设置默认地址
*/
radioChange: function(e) {
let index = parseInt(e.detail.value),
that = this;
let address = this.addressList[index];
if (address == undefined) return that.$util.Tips({
title: '您设置的默认地址不存在!'
});
setAddressDefault(address.id).then(res => {
for (let i = 0, len = that.addressList.length; i < len; i++) {
if (i == index) that.addressList[i].isDefault = true;
else that.addressList[i].isDefault = false;
}
that.$util.Tips({
title: '设置成功',
icon: 'success'
}, function() {
that.$set(that, 'addressList', that.addressList);
});
}).catch(err => {
return that.$util.Tips({
title: err
});
});
},
/**
* 编辑地址
*/
editAddress: function(id) {
let cartId = this.cartId,
pinkId = this.pinkId,
couponId = this.couponId;
this.cartId = '';
this.pinkId = '';
this.couponId = '';
uni.navigateTo({
url: '/pages/users/user_address/index?id=' + id + '&cartId=' + cartId + '&pinkId=' +
pinkId + '&couponId=' +
couponId + '&secKill' + this.secKill + '&combination=' + this.combination +
'&bargain=' + this.bargain
})
},
/**
* 删除地址
*/
delAddress: function(index) {
let that = this,
address = this.addressList[index];
if (address == undefined) return that.$util.Tips({
title: '您删除的地址不存在!'
});
uni.showModal({
content: '确定删除该地址',
cancelText: "取消", // 取消按钮的文字
confirmText: "确定", // 确认按钮文字
showCancel: true, // 是否显示取消按钮,默认为 true
confirmColor: '#f55850',
success: (res) => {
if (res.confirm) {
delAddress(address.id).then(res => {
that.addressList.splice(index, 1);
that.$set(that, 'addressList', that.addressList);
that.$util.Tips({
title: '删除成功',
icon: 'success'
});
}).catch(err => {
return that.$util.Tips({
title: err
});
});
} else {
}
},
})
},
/**
* 新增地址
*/
addAddress: function() {
let cartId = this.cartId,
pinkId = this.pinkId,
couponId = this.couponId;
this.cartId = '';
this.pinkId = '';
this.couponId = '';
uni.navigateTo({
url: '/pages/users/user_address/index?preOrderNo=' + this.preOrderNo
})
},
goOrder: function(item) {
if (this.preOrderNo) {
uni.redirectTo({
url: '/pages/order/order_confirm/index?is_address=1&preOrderNo=' + this.preOrderNo +
'&addressId=' + item.id
})
}
},
},
onReachBottom: function() {
this.getAddressList();
}
}
</script>
<style lang="scss" scoped>
.address-management {
padding: 20rpx 30rpx;
}
.address-management.fff {
background-color: #fff;
height: 1300rpx
}
.bg_color {
@include main_bg_color(theme);
}
.line {
width: 100%;
height: 3rpx;
image {
width: 100%;
height: 100%;
display: block;
}
}
.address-management .item {
background-color: #fff;
padding: 0 20rpx;
margin-bottom: 20rpx;
}
.address-management .item .address {
padding: 35rpx 0;
border-bottom: 1rpx solid #eee;
font-size: 28rpx;
color: #282828;
}
.address-management .item .address .consignee {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 8rpx;
}
.address-management .item .address .consignee .phone {
margin-left: 25rpx;
}
.address-management .item .operation {
height: 83rpx;
font-size: 28rpx;
color: #282828;
}
.address-management .item .operation .radio text {
margin-left: 13rpx;
}
.address-management .item .operation .iconfont {
color: #2c2c2c;
font-size: 35rpx;
vertical-align: -2rpx;
margin-right: 10rpx;
}
.address-management .item .operation .iconfont.icon-shanchu {
margin-left: 35rpx;
font-size: 38rpx;
}
.footer {
position: fixed;
width: 100%;
background-color: #fff;
bottom: 0;
height: 106rpx;
padding: 0 30rpx;
box-sizing: border-box;
}
.footer .addressBnt {
width: 330rpx;
height: 76rpx;
border-radius: 50rpx;
text-align: center;
line-height: 76rpx;
font-size: 30rpx;
color: #fff;
}
.footer .addressBnt.on {
width: 690rpx;
margin: 0 auto;
}
.footer .addressBnt .iconfont {
font-size: 35rpx;
margin-right: 8rpx;
vertical-align: -1rpx;
}
.footer .addressBnt.wxbnt {
@include left_color(theme);
}
::v-deep radio .wx-radio-input.wx-radio-input-checked {
@include main_bg_color(theme);
@include coupons_border_color(theme);
}
::v-deep radio .uni-radio-input.uni-radio-input-checked {
@include main_bg_color(theme);
border: none !important;
}
</style>

View File

@@ -0,0 +1,172 @@
<template>
<view :data-theme="theme">
<view class='bill-details'>
<view class='nav acea-row'>
<view class='item' :class='type==="all" ? "on":""' @click='changeType("all")'>全部</view>
<view class='item' :class='type==="expenditure" ? "on":""' @click='changeType("expenditure")'>消费</view>
<view class='item' :class='type==="income" ? "on":""' @click='changeType("income")'>充值</view>
</view>
<view class='sign-record'>
<view class='list pad30' v-for="(item,index) in userBillList" :key="index">
<view class='item'>
<view class='data'>{{item.date}}</view>
<view class='listn borRadius14'>
<view class='itemn acea-row row-between-wrapper' v-for="(vo,indexn) in item.list"
:key="indexn">
<view>
<view class='name line1'>{{vo.title}}</view>
<view>{{vo.add_time}}</view>
</view>
<view class='num font_color' v-if="vo.pm">+{{vo.number}}</view>
<view class='num' v-else>-{{vo.number}}</view>
</view>
</view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper' v-if="userBillList.length>0">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view v-if="userBillList.length == 0">
<emptyPage title="暂无账单的记录哦~"></emptyPage>
</view>
</view>
</view>
</view>
</template>
<script>
import {
getBillList
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import emptyPage from '@/components/emptyPage.vue';
let app = getApp();
export default {
components: {
emptyPage
},
data() {
return {
loadTitle: '加载更多',
loading: false,
loadend: false,
page: 1,
limit: 12,
type: 'all',
userBillList: [],
theme:app.globalData.theme,
};
},
computed: mapGetters(['isLogin']),
onShow() {
if (this.isLogin) {
this.getUserBillList();
} else {
toLogin();
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.type = options.type?options.type:'all';
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getUserBillList();
},
methods: {
/**
* 获取账户明细
*/
getUserBillList: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
that.loadTitle = "";
let data = {
page: that.page,
limit: that.limit,
type: that.type
}
getBillList(data).then(function(res) {
let list = res.data.list ? res.data.list : [],
loadend = res.data.totalPage <= that.page;
for (let i = 0; i < list.length; i++) {
let time1 = list[i].date;
let array1 = list[i].list;
let isEquals = false;
for (let j = 0; j < that.userBillList.length; j++) {
let time2 = that.userBillList[j].date;
let array2 = that.userBillList[j].list;
if (time1 == time2) {
array2.push.apply(array2, array1);
that.userBillList[j].list = array2;
isEquals = true;
break;
}
}
if (!isEquals) {
that.userBillList.push({
date: time1,
list: array1
})
}
}
that.$set(that, 'userBillList', that.userBillList);
that.page += 1;
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? "哼😕~我也是有底线的~" : "加载更多";
}, function(res) {
that.loading = false;
that.loadTitle = '加载更多';
});
},
/**
* 切换导航
*/
changeType: function(type) {
this.type = type;
this.loadend = false;
this.page = 1;
this.$set(this, 'userBillList', []);
this.getUserBillList();
},
}
}
</script>
<style scoped lang='scss'>
.sign-record {}
.bill-details .nav {
background-color: #fff;
height: 90rpx;
width: 100%;
line-height: 90rpx;
}
.bill-details .nav .item {
flex: 1;
text-align: center;
font-size: 30rpx;
color: #282828;
}
.bill-details .nav .item.on {
@include main_color(theme);
@include tab_border_bottom(theme);
}
.font_color{
color: #E93323 !important;
}
</style>

View File

@@ -0,0 +1,462 @@
<template>
<view :data-theme="theme">
<view class='cash-withdrawal'>
<view class='nav acea-row'>
<view v-for="(item,index) in navList" :key="index" class='item font-color' @click="swichNav(index)">
<view class='line bg_color' :class='currentTab==index ? "on":""'></view>
<view class='iconfont' :class='item.icon+" "+(currentTab==index ? "on":"")'></view>
<view class="tab_text">{{item.name}}</view>
</view>
</view>
<view class='wrapper'>
<view :hidden='currentTab != 0' class='list'>
<form @submit="subCash" report-submit='true'>
<view class='item acea-row row-between-wrapper'>
<view class='name'>持卡人</view>
<view class='input'>
<input placeholder='请输入持卡人姓名' placeholder-class='placeholder' name="name" maxlength="20"></input>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>卡号</view>
<view class='input'>
<input type='number' placeholder='请填写卡号' placeholder-class='placeholder' name="cardum" maxlength="19"></input>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>银行</view>
<view class='input'>
<picker @change="bindPickerChange" :value="index" :range="array">
<text class='Bank'>{{array[index]}}</text>
<text class='iconfont icon-qiepian38'></text>
</picker>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input'><input :placeholder='"最低提现金额"+minPrice' placeholder-class='placeholder' name="money" type='digit'></input></view>
</view>
<view class='tip'>
当前可提现金额: <text class="price">{{commission.commissionCount}},</text>冻结佣金{{commission.brokenCommission}}
</view>
<view class='tip'>
说明: 每笔佣金的冻结期为{{commission.brokenDay}}到期后可提现
</view>
<button formType="submit" class='bnt bg-color'>提现</button>
</form>
</view>
<view :hidden='currentTab != 1' class='list'>
<form @submit="subCash" report-submit='true'>
<view class='item acea-row row-between-wrapper'>
<view class='name'>账号</view>
<view class='input'>
<input placeholder='请填写您的微信账号' placeholder-class='placeholder' name="name" maxlength="20"></input>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input'>
<input :placeholder='"最低提现金额"+minPrice' placeholder-class='placeholder' name="money" type='digit' maxlength="5"></input>
</view>
</view>
<view class='item acea-row row-top row-between'>
<view class='name'>收款码</view>
<view class="input acea-row">
<view class="picEwm" v-if="qrcodeUrlW">
<image :src="qrcodeUrlW"></image>
<text class='iconfont icon-guanbi1 font-color' @click='DelPicW'></text>
</view>
<view class='pictrue acea-row row-center-wrapper row-column' @click='uploadpic("W")' v-else>
<text class='iconfont icon-icon25201'></text>
<view>上传图片</view>
</view>
</view>
</view>
<view class='tip'>
当前可提现金额: <text class="price">{{commission.commissionCount}},</text>冻结佣金{{commission.brokenCommission}}
</view>
<view class='tip'>
说明: 每笔佣金的冻结期为{{commission.brokenDay}}到期后可提现
</view>
<button formType="submit" class='bnt bg-color'>提现</button>
</form>
</view>
<view :hidden='currentTab != 2' class='list'>
<form @submit="subCash" report-submit='true'>
<view class='item acea-row row-between-wrapper'>
<view class='name'>账号</view>
<view class='input'>
<input placeholder='请填写您的支付宝账号' placeholder-class='placeholder' name="name" maxlength="20"></input>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input'>
<input :placeholder='"最低提现金额"+minPrice' placeholder-class='placeholder' name="money" type='digit' maxlength="5"></input>
</view>
</view>
<view class='item acea-row row-top row-between'>
<view class='name'>收款码</view>
<view class="input acea-row">
<view class="picEwm" v-if="qrcodeUrlZ">
<image :src="qrcodeUrlZ"></image>
<text class='iconfont icon-guanbi1 font-color' @click='DelPicZ'></text>
</view>
<view class='pictrue acea-row row-center-wrapper row-column' @click='uploadpic("Z")' v-else>
<text class='iconfont icon-icon25201'></text>
<view>上传图片</view>
</view>
</view>
</view>
<view class='tip'>
当前可提现金额: <text class="price">{{commission.commissionCount}},</text>冻结佣金{{commission.brokenCommission}}
</view>
<view class='tip'>
说明: 每笔佣金的冻结期为{{commission.brokenDay}}到期后可提现
</view>
<button formType="submit" class='bnt'>提现</button>
</form>
</view>
</view>
</view>
</view>
</template>
<script>
import {
extractCash,
extractBank,
extractUser
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import {Debounce} from '@/utils/validate.js'
let app = getApp();
export default {
data() {
return {
navList: [{
'name': '银行卡',
'icon': 'icon-yinhangqia'
},
{
'name': '微信',
'icon': 'icon-weixin2'
},
{
'name': '支付宝',
'icon': 'icon-icon34'
}
],
currentTab: 0,
index: 0,
array: [], //提现银行
minPrice: 0.00, //最低提现金额
userInfo: [],
isClone: false,
commission:{},
qrcodeUrlW:"",
qrcodeUrlZ:"",
isCommitted: false, //防止多次提交
theme:app.globalData.theme,
};
},
computed: mapGetters(['isLogin']),
watch:{
isLogin:{
handler:function(newV,oldV){
if(newV){
this.getUserExtractBank();
this.getExtractUser();
}
},
deep:true
}
},
onLoad() {
if (this.isLogin) {
this.getUserExtractBank();
this.getExtractUser();
} else {
toLogin();
}
},
methods: {
uploadpic: function (type) {
let that = this;
that.$util.uploadImageOne({
url: 'upload/image',
name: 'multipart',
model: "user",
pid: 1
}, function(res) {
if(type==='W'){
that.qrcodeUrlW = res.data.url;
}else{
that.qrcodeUrlZ = res.data.url;
}
});
},
/**
* 删除图片
*
*/
DelPicW: function () {
this.qrcodeUrlW = "";
},
DelPicZ: function () {
this.qrcodeUrlZ = "";
},
getExtractUser(){
extractUser().then(res=>{
this.commission = res.data;
this.minPrice = res.data.minPrice;
})
},
getUserExtractBank: function() {
let that = this;
extractBank().then(res => {
let array = res.data;
array.unshift("请选择银行");
that.$set(that, 'array', array);
});
},
swichNav: function(current) {
this.currentTab = current;
},
bindPickerChange: function(e) {
this.index = e.detail.value;
},
moneyInput(e) {
//正则表达试
e.target.value = (e.target.value.match(/^\d*(\.?\d{0,2})/g)[0]) || null
//重新赋值给input
this.$nextTick(() => {
this.money= e.target.value
})
},
subCash: Debounce(function(e) {
let that = this,
value = e.detail.value;
if (that.currentTab == 0) { //银行卡
if (value.name.length == 0) return this.$util.Tips({
title: '请填写持卡人姓名'
});
if (value.cardum.length == 0) return this.$util.Tips({
title: '请填写卡号'
});
if (that.index == 0) return this.$util.Tips({
title: "请选择银行"
});
value.extractType = 'bank';
value.bankName = that.array[that.index];
} else if (that.currentTab == 1) { //微信
value.extractType = 'weixin';
if (value.name.length == 0) return this.$util.Tips({
title: '请填写微信号'
});
value.wechat = value.name;
value.qrcodeUrl = that.qrcodeUrlW;
} else if (that.currentTab == 2) { //支付宝
value.extractType = 'alipay';
if (value.name.length == 0) return this.$util.Tips({
title: '请填写账号'
});
value.alipayCode = value.name;
value.qrcodeUrl = that.qrcodeUrlZ;
}
if (value.money.length == 0) return this.$util.Tips({
title: '请填写提现金额'
});
if (!(/^(\d?)+(\.\d{0,2})?$/.test(value.money))) return this.$util.Tips({
title: '提现金额保留2位小数'
});
if (value.money < that.minPrice) return this.$util.Tips({
title: '提现金额不能低于' + that.minPrice
});
if(this.isCommitted==false){
this.isCommitted=true;
extractCash(value).then(res => {
return this.$util.Tips({
title: "提现成功",
icon: 'success'
},{ tab: 2, url: '/pages/promoter/user_spread_user/index' });
this.isCommitted=false;
}).catch(err => {
this.isCommitted=false;
return this.$util.Tips({
title: err
});
});
}
})
}
}
</script>
<style lang="scss">
page {
background-color: #fff !important;
}
.cash-withdrawal .nav {
height: 130rpx;
box-shadow: 0 10rpx 10rpx #f8f8f8;
}
.cash-withdrawal .nav .item {
font-size: 26rpx;
flex: 1;
text-align: center;
}
.cash-withdrawal .nav .item~.item {
border-left: 1px solid #f0f0f0;
}
.cash-withdrawal .nav .item .iconfont {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
@include coupons_border_color(theme);
@include main_color(theme);
text-align: center;
line-height: 37rpx;
margin: 0 auto 6rpx auto;
font-size: 22rpx;
box-sizing: border-box;
}
.cash-withdrawal .nav .item .iconfont.on {
@include main_bg_color(theme);
color: #fff !important;
@include coupons_border_color(theme);
// border-color: $theme-color;
}
.cash-withdrawal .nav .item .line {
width: 2rpx;
height: 20rpx;
margin: 0 auto;
transition: height 0.3s;
}
.tab_text{
@include main_color(theme);
}
.bg_color{
@include main_bg_color(theme);
}
.cash-withdrawal .nav .item .line.on {
height: 39rpx;
}
.cash-withdrawal .wrapper .list {
padding: 0 30rpx;
}
.cash-withdrawal .wrapper .list .item {
border-bottom: 1rpx solid #eee;
min-height: 28rpx;
font-size: 30rpx;
color: #333;
padding: 39rpx 0;
}
.cash-withdrawal .wrapper .list .item .name {
width: 130rpx;
}
.cash-withdrawal .wrapper .list .item .input {
width: 505rpx;
}
.cash-withdrawal .wrapper .list .item .input .placeholder {
color: #bbb;
}
.cash-withdrawal .wrapper .list .item .picEwm,.cash-withdrawal .wrapper .list .item .pictrue{
width:140rpx;
height:140rpx;
border-radius:3rpx;
position: relative;
margin-right: 23rpx;
}
.cash-withdrawal .wrapper .list .item .picEwm image{
width:100%;
height:100%;
border-radius:3rpx;
}
.cash-withdrawal .wrapper .list .item .picEwm .icon-guanbi1{
position:absolute;
right: -14rpx;
top: -16rpx;
font-size:40rpx;
}
.cash-withdrawal .wrapper .list .item .pictrue{
border:1px solid rgba(221,221,221,1);
font-size:22rpx;
color: #BBBBBB;
}
.cash-withdrawal .wrapper .list .item .pictrue .icon-icon25201{
font-size: 47rpx;
color: #DDDDDD;
margin-bottom: 3px;
}
.cash-withdrawal .wrapper .list .tip {
font-size: 26rpx;
color: #999;
margin-top: 25rpx;
}
.cash-withdrawal .wrapper .list .bnt {
font-size: 32rpx;
color: #fff;
width: 690rpx;
height: 90rpx;
text-align: center;
border-radius: 50rpx;
line-height: 90rpx;
margin: 64rpx auto;
@include main_bg_color(theme);
}
.cash-withdrawal .wrapper .list .tip2 {
font-size: 26rpx;
color: #999;
text-align: center;
margin: 44rpx 0 20rpx 0;
}
.cash-withdrawal .wrapper .list .value {
height: 135rpx;
line-height: 135rpx;
border-bottom: 1rpx solid #eee;
width: 690rpx;
margin: 0 auto;
}
.cash-withdrawal .wrapper .list .value input {
font-size: 80rpx;
color: #282828;
height: 135rpx;
text-align: center;
}
.cash-withdrawal .wrapper .list .value .placeholder2 {
color: #bbb;
}
.price {
@include price_color(theme);
}
</style>

View File

@@ -0,0 +1,195 @@
<template>
<view :data-theme="theme">
<view class="navbar acea-row row-around">
<view class="item acea-row row-center-wrapper" :class="{ on: navOn === 'usable' }" @click="onNav('usable')">未使用</view>
<view class="item acea-row row-center-wrapper" :class="{ on: navOn === 'unusable' }" @click="onNav('unusable')">已使用/过期</view>
</view>
<view class='coupon-list' v-if="couponsList.length">
<view class='item acea-row row-center-wrapper' v-for='(item,index) in couponsList' :key="index">
<view class='money' :class="item.validStr==='unusable'||item.validStr==='overdue'||item.validStr==='notStart' ? 'moneyGray' : 'main_bg'">
<view><text class='num':style="[{'font-size':item.money.length>=7?'42rpx':'60rpx'}]" >{{item.money?Number(item.money):''}}</text></view>
<view class="pic-num">{{ item.minPrice?Number(item.minPrice):'' }}元可用</view>
</view>
<view class='text'>
<view class='condition line2'>
<span class="line-title" :class="item.validStr==='unusable'||item.validStr==='overdue'||item.validStr==='notStart' ? 'bg-color-huic' : 'bg-color-check'" v-if="item.useType === 1">通用</span>
<span class="line-title" :class="item.validStr==='unusable'||item.validStr==='overdue'||item.validStr==='notStart' ? 'bg-color-huic' : 'bg-color-check'" v-else-if="item.useType === 2">商品</span>
<span class="line-title" :class="item.validStr==='unusable'||item.validStr==='overdue'||item.validStr==='notStart' ? 'bg-color-huic' : 'bg-color-check'" v-else-if="item.useType === 3">品类</span>
<span>{{item.name}}</span>
</view>
<view class='data acea-row row-between-wrapper'>
<view>{{item.useStartTimeStr}}~{{item.useEndTimeStr}}</view>
<view class='bnt' :class="item.validStr==='unusable'||item.validStr==='overdue'||item.validStr==='notStart'?'gray':'bg_color'">{{item.validStr | validStrFilter}}</view>
</view>
</view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper' v-if="couponsList.length">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view class='noCommodity' v-if="!couponsList.length">
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/noCoupon.png'"></image>
</view>
</view>
</view>
</template>
<script>
import {
getUserCoupons
} from '@/api/api.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
let app = getApp();
export default {
filters: {
validStrFilter(status) {
const statusMap = {
'usable': '可用',
'unusable': '已用',
'overdue': '过期',
'notStart': '未开始'
}
return statusMap[status]
}
},
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
couponsList: [],
loading: false,
loadend: false,
loadTitle: '加载更多',//提示语
page: 1,
limit: 20,
navOn: 'usable',
theme:app.globalData.theme,
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getUseCoupons();
}
},
deep: true
}
},
onLoad() {
if (this.isLogin) {
this.getUseCoupons();
} else {
toLogin();
}
},
methods: {
onNav: function(type) {
this.navOn = type;
this.couponsList = [];
this.page = 1;
this.loadend = false;
this.getUseCoupons();
},
/**
* 获取领取优惠券列表
*/
getUseCoupons: function() {
let that = this;
if(this.loadend) return false;
if(this.loading) return false;
getUserCoupons({ page: that.page, limit: that.limit, type: that.navOn}).then(res => {
let list= res.data ? res.data.list : [],loadend=list.length < that.limit;
let couponsList = that.$util.SplitArray(list, that.couponsList);
that.$set(that,'couponsList',couponsList);
that.loadend = loadend;
that.loadTitle = loadend ? '哼😕~我也是有底线的~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = '加载更多';
});
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
this.getUseCoupons();
}
}
</script>
<style lang="scss" scoped>
.navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 106rpx;
background-color: #FFFFFF;
z-index: 9;
.item {
border-top: 5rpx solid transparent;
border-bottom: 5rpx solid transparent;
font-size: 30rpx;
color: #999999;
&.on{
@include tab_border_bottom(theme);
@include main_color(theme);
}
}
}
.money {
display: flex;
flex-direction: column;
justify-content: center;
}
.bg_color{
@include main_bg_color(theme);
}
.pic-num {
color: #ffffff;
font-size: 24rpx;
}
.coupon-list {
margin-top: 122rpx;
}
.coupon-list .item .text{
height: 100%;
}
.coupon-list .item .text .condition{
/* display: flex;
align-items: center; */
}
.condition .line-title {
width: 90rpx;
height: 40rpx !important;
line-height: 40rpx !important;
padding: 2rpx 10rpx;
-webkit-box-sizing: border-box;
box-sizing: border-box;
@include coupons_border_color(theme);
opacity: 1;
border-radius: 20rpx;
font-size: 18rpx !important;
@include main_color(theme);
margin-right: 12rpx;
}
.noCommodity {
margin-top: 300rpx;
}
.main_bg{
@include main_bg_color(theme);
}
</style>

View File

@@ -0,0 +1,213 @@
<template>
<view :data-theme="theme">
<view class="acea-row row-around nav">
<template v-for="item in navList">
<view :key="item.type" :class="['acea-row', 'row-middle', type === item.type ? 'on' : '']" >
<text @click="setType(item.type)">{{ item.name }}</text>
</view>
</template>
</view>
<view style="height: 106rpx;"></view>
<view class='coupon-list' v-if="couponsList.length">
<view class='item acea-row row-center-wrapper' v-for="(item,index) in couponsList" :key="index">
<view class='money' :class='item.isUse ? "moneyGray" : "main_bg" '>
<view ><text class='num' :style="[{'font-size':item.money.length>=7?'42rpx':'60rpx'}]" >{{item.money?Number(item.money):''}}</text></view>
<view class="pic-num">{{item.minPrice?Number(item.minPrice):''}}元可用</view>
</view>
<view class='text'>
<view class='condition line2'>
<span class='line-title' :class='(item.isUse==true || item.isUse==2)?"gray":"select"' v-if='item.useType===1'>通用</span>
<span class='line-title' :class='(item.isUse==true || item.isUse==2)?"gray":"select"' v-else-if='item.useType===3'>品类</span>
<span class='line-title' :class='(item.isUse==true || item.isUse==2)?"gray":"select"' v-else>商品</span>
<span>{{item.name}}</span>
</view>
<view class='data acea-row row-between-wrapper'>
<view v-if="item.day>0">领取后{{item.day}}天内可用</view>
<view v-else>{{ item.useStartTimeStr&& item.useEndTimeStr ? item.useStartTimeStr + " - " + item.useEndTimeStr : ""}}</view>
<view class='bnt gray' v-if="item.isUse==true">已领取</view>
<view class='bnt main_bg' v-else @click='getCoupon(item.id,index)'>立即领取</view>
</view>
</view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper'>
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{couponsList.length?loadTitle:''}}
</view>
<view class='noCommodity' v-if="!couponsList.length && isShow && !loading">
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/noCoupon.png'"></image>
</view>
</view>
</view>
</template>
<script>
import {
getCoupons,
setCouponReceive
} from '@/api/api.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
let app = getApp();
export default {
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
couponsList:[],
loading: false,
loadend: false,
loadTitle: '加载更多',//提示语
page: 1,
limit: 20,
type: 1,
isShow: false,
navList: [{
type: 1,
name: '通用券',
count: 0
},
{
type: 2,
name: '商品券',
count: 0
},
{
type: 3,
name: '品类券',
count: 0
},
],
count: 0,
theme:app.globalData.theme,
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getUseCoupons();
}
},
deep: true
}
},
onLoad(){
if(this.isLogin){
this.getUseCoupons();
}else{
toLogin();
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
this.getUseCoupons();
},
methods: {
getCoupon:function(id,index){
let that = this;
let list = that.couponsList;
let ids = [];
ids.push(id);
//领取优惠券
setCouponReceive(id).then(function (res) {
list[index].isUse = true;
that.$set(that,'couponsList',list);
that.$util.Tips({ title: '领取成功' });
},function(res){
return that.$util.Tips({title:res});
})
},
/**
* 获取领取优惠券列表
*/
getUseCoupons:function(){
let that=this
if(that.loadend) return false;
if(that.loading) return false;
that.loading = true;
getCoupons({ page: that.page, limit: that.limit, type: that.type }).then(res=>{
let list=res.data.list,loadend=list.length < that.limit;
let couponsList = that.$util.SplitArray(list, that.couponsList);
that.$set(that,'couponsList',couponsList);
that.loadend = loadend;
that.loadTitle = loadend ? '哼😕~我也是有底线的~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
that.isShow = true;
}).catch(err=>{
that.loading = false;
that.loadTitle = '加载更多';
});
},
setType: function(type) {
if (this.type !== type) {
this.type = type;
this.couponsList = [];
this.page = 1;
this.loadend = false;
this.getUseCoupons();
}
}
}
}
</script>
<style scoped lang="scss">
.nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 106rpx;
background-color: #FFFFFF;
font-size: 30rpx;
color: #999999;
z-index: 9;
}
.nav .acea-row {
border-top: 5rpx solid transparent;
border-bottom: 5rpx solid transparent;
cursor: pointer;
}
.nav .acea-row.on {
@include tab_border_bottom(theme);
@include main_color(theme);
}
.condition .line-title{
width:90rpx;
padding: 0 10rpx;
box-sizing: border-box;
background:#fff;
opacity:1;
border-radius:20rpx;
font-size:20rpx;
margin-right: 12rpx;
}
.condition .line-title.gray{
border:1px solid #BBB;
color:#bbb;
background-color:#F5F5F5;
}
.coupon-list .pic-num{
color: #FFFFFF;
font-size: 24rpx;
}
.main_bg{
@include main_bg_color(theme);
}
.select{
@include main_color(theme);
@include coupons_border_color(theme);
}
</style>

View File

@@ -0,0 +1,420 @@
<template>
<view :data-theme="theme">
<view class='collectionGoods' v-if="collectProductList.length">
<!-- #ifdef H5 || MP-->
<view class='nav acea-row row-between-wrapper'>
<view>当前共 <text class='num font_color'>{{ totals }}</text>件商品</view>
<view class='administrate acea-row row-center-wrapper' @click='manage'>{{ footerswitch ? '管理' : '取消'}}
</view>
</view>
<!-- #endif -->
<view class="list">
<checkbox-group @change="checkboxChange" class="centent">
<!-- #ifndef APP-PLUS-->
<view v-for="(item,index) in collectProductList" :key="index" class='item acea-row row-middle'>
<checkbox :value="item.id.toString()" :checked="item.checked" v-if="!footerswitch"
style="margin-right: 10rpx;" />
<navigator :url='"/pages/goods/goods_details/index?id="+item.productId' hover-class='none'
class="acea-row">
<view class='pictrue'>
<image :src="item.image"></image>
</view>
<view>
<view class='name line1'>{{item.storeName}}</view>
<view class='money'>{{item.price}}</view>
</view>
</navigator>
</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view v-for="(item,index) in collectProductList" :key="index" :data-index="index"
class='item acea-row row-middle order-item'>
<navigator :url='"/pages/goods/goods_details/index?id="+item.productId' hover-class='none' class="acea-row">
<view class='pictrue'>
<image :src="item.image"></image>
</view>
<view>
<view class='name line1'>{{item.storeName}}</view>
<view class='money'>{{item.price}}</view>
</view>
</navigator>
<view class="remove borRadius14" @tap="delCollection(item.id)">删除</view>
</view>
<!-- #endif -->
</checkbox-group>
</view>
<view class='loadingicon acea-row row-center-wrapper'>
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view v-if="!footerswitch" class='footer acea-row row-between-wrapper'>
<view>
<checkbox-group @change="checkboxAllChange">
<checkbox value="all" :checked="!!isAllSelect" />
<text class='checkAll'>全选</text>
</checkbox-group>
</view>
<view class='button acea-row row-middle'>
<form @submit="delCollectionAll" report-submit='true'>
<button class='bnt cart-color' formType="submit">取消收藏</button>
</form>
</view>
</view>
</view>
<view class='noCommodity' v-else-if="!collectProductList.length && page > 1">
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/usersImg/noCollection.png'"></image>
</view>
<recommend ref="recommendIndex"></recommend>
</view>
</view>
</template>
<script>
import {
getCollectUserList,
getProductHot,
collectDelete
} from '@/api/store.js';
import {
mapGetters
} from "vuex";
import {
toLogin
} from '@/libs/login.js';
import recommend from '@/components/recommend';
let app = getApp();
export default {
components: {
recommend
},
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
footerswitch: true,
loadTitle: '加载更多',
loading: false,
loadend: false,
collectProductList: [],
limit: 8,
page: 1,
isAllSelect: false, //全选
selectValue: [], //选中的数据
delBtnWidth: 80, //左滑默认宽度
totals: 0,
theme:app.globalData.theme,
};
},
computed: mapGetters(['isLogin']),
onLoad() {
let that = this;
if (this.isLogin) {
this.loadend = false;
this.page = 1;
this.collectProductList = [];
} else {
toLogin();
}
},
onShow() {
this.loadend = false;
this.page = 1;
this.collectProductList = [];
this.get_user_collect_product();
},
methods: {
manage: function() {
this.footerswitch = !this.footerswitch;
},
checkboxChange: function(event) {
var items = this.collectProductList,
values = event.detail.value;
for (var i = 0, lenI = items.length; i < lenI; ++i) {
const item = items[i]
if (values.includes(item.id.toString())) {
this.$set(item, 'checked', true)
} else {
this.$set(item, 'checked', false)
}
}
this.selectValue = values.toString();
this.isAllSelect = items.length === values.length;
},
checkboxAllChange: function(event) {
let value = event.detail.value;
if (value.length > 0) {
this.setAllSelectValue(1)
} else {
this.setAllSelectValue(0)
}
},
setAllSelectValue: function(status) {
let selectValue = [];
if (this.collectProductList.length > 0) {
this.collectProductList.map(item => {
if (status) {
this.$set(item, 'checked', true)
selectValue.push(item.id);
this.isAllSelect = true;
} else {
this.$set(item, 'checked', false)
this.isAllSelect = false;
}
});
this.selectValue = selectValue.toString();
}
},
/**
* 获取收藏产品
*/
get_user_collect_product: function() {
let that = this;
if (this.loading) return;
if (this.loadend) return;
that.loading = true;
that.loadTitle = "";
getCollectUserList({
page: that.page,
limit: that.limit
}).then(res => {
res.data.list.map(item => {
that.$set(item, 'right', 0);
});
that.totals = res.data.total;
let collectProductList = res.data.list;
let loadend = collectProductList.length < that.limit;
that.collectProductList = that.$util.SplitArray(collectProductList, that
.collectProductList);
that.$set(that, 'collectProductList', that.collectProductList);
that.loadend = loadend;
that.loadTitle = loadend ? '哼😕~我也是有底线的~' : '加载更多';
that.page = that.page + 1;
that.loading = false;
}).catch(err => {
that.loading = false;
that.loadTitle = "加载更多";
});
},
/**
* 取消收藏
*/
delCollection: function(id, index) {
this.selectValue = id;
this.del({
ids: this.selectValue.toString()
});
},
delCollectionAll: function() {
if (!this.selectValue || this.selectValue.length == 0) return this.$util.Tips({
title: '请选择商品'
});
this.del({
ids: this.selectValue
});
},
del: function(data) {
collectDelete(data).then(res => {
this.$util.Tips({
title: '取消收藏成功',
icon: 'success'
});
this.selectValue = [];
this.collectProductList = [];
this.loadend = false;
this.page = 1;
this.get_user_collect_product();
}).catch(err => {
return this.$util.Tips({
title: err
})
});
},
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
this.get_user_collect_product();
this.$refs.recommendIndex.get_host_product();
}
}
</script>
<style scoped lang="scss">
.money{
font-size: 26rpx;
@include price_color(theme);
}
.order-item {
width: 100%;
display: flex;
position: relative;
align-items: right;
flex-direction: row;
}
.remove {
width: 120rpx;
height: 40rpx;
@include main_bg_color(theme);
color: #fff;
position: absolute;
bottom: 30rpx;
right: 60rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
}
.collectionGoods {
.nav {
width: 92%;
height: 90rpx;
background-color: #fff;
padding: 0 24rpx;
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-size: 28rpx;
color: #282828;
position: fixed;
left: 30rpx;
z-index: 5;
top: 30rpx;
border-bottom: 1px solid #EEEEEE;
border-top-left-radius: 14rpx;
border-top-right-radius: 14rpx;
}
.list {
padding: 30rpx;
/* #ifndef APP-PLUS*/
margin-top: 90rpx;
/* #endif */
/* #ifdef MP */
//margin-top: 0rpx;
/* #endif */
.name {
width: 434rpx;
/* #ifdef APP-PLUS */
width: 486rpx;
/* #endif */
margin-bottom: 56rpx;
}
}
.centent {
/* #ifdef H5 || MP */
background-color: #fff;
/* #endif */
border-bottom-left-radius: 14rpx;
border-bottom-right-radius: 14rpx;
}
}
.collectionGoods .item {
background-color: #fff;
padding-left: 24rpx;
height: 180rpx;
margin-bottom: 15rpx;
border-radius: 14rpx;
}
.collectionGoods .item .pictrue {
width: 130rpx;
height: 130rpx;
margin-right: 20rpx;
}
.collectionGoods .item .pictrue image {
width: 100%;
height: 100%;
border-radius: 14rpx;
}
.collectionGoods .item .text {
width: 535rpx;
height: 130rpx;
font-size: 28rpx;
color: #282828;
}
.collectionGoods .item .text .name {
width: 100%;
}
.collectionGoods .item .text .delete {
font-size: 26rpx;
color: #282828;
width: 144rpx;
height: 46rpx;
border: 1px solid #bbb;
border-radius: 4rpx;
text-align: center;
line-height: 46rpx;
}
.noCommodity {
background-color: #fff;
padding-top: 1rpx;
border-top: 0;
}
.footer {
z-index: 9;
width: 100%;
height: 96rpx;
background-color: #fff;
position: fixed;
padding: 0 30rpx;
box-sizing: border-box;
border-top: 1rpx solid #eee;
border-bottom: 1px solid #EEEEEE;
/* #ifdef H5 || MP */
bottom: 0rpx;
/* #endif */
/* #ifdef APP-PLUS */
bottom: 0;
/* #endif */
/* #ifndef MP || APP-PLUS */
// bottom: 98rpx;
// bottom: calc(98rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
// bottom: calc(98rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
/* #endif */
.checkAll {
font-size: 28rpx;
color: #282828;
margin-left: 16rpx;
}
.button .bnt {
font-size: 28rpx;
color: #999;
border-radius: 30rpx;
border: 1px solid #999;
width: 160rpx;
height: 60rpx;
text-align: center;
line-height: 60rpx;
}
}
.font_color{
@include main_color(theme);
}
::v-deep checkbox .uni-checkbox-input.uni-checkbox-input-checked {
@include main_bg_color(theme);
@include coupons_border_color(theme);
color: #fff!important
}
::v-deep checkbox .wx-checkbox-input.wx-checkbox-input-checked {
@include main_bg_color(theme);
@include coupons_border_color(theme);
color: #fff!important;
margin-right: 0 !important;
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,395 @@
<template>
<view :data-theme="theme">
<view class='my-account'>
<view class='wrapper'>
<view class='header'>
<view class='headerCon'>
<view class='account acea-row row-top row-between'>
<view class='assets'>
<view>总资产()</view>
<view class='money'>{{statistics.nowMoney || 0}}</view>
</view>
<view v-if="userInfo.rechargeSwitch" @click="openSubscribe('/pages/users/user_payment/index')" class='recharge font_color'>充值</view>
</view>
<view class='cumulative acea-row row-top'>
<view class='item' v-if="userInfo.rechargeSwitch">
<view>累计充值()</view>
<view class='money'>{{statistics.recharge || 0}}</view>
</view>
<view class='item'>
<view>累计消费()</view>
<view class='money'>{{statistics.orderStatusSum || 0}}</view>
</view>
</view>
</view>
</view>
<view class='nav acea-row row-middle'>
<navigator class='item' hover-class='none' url='/pages/users/user_bill/index?type=all'>
<view class='pictrue'>
<text class="iconfont icon-s-zhangdanjilu icon_txt"></text>
</view>
<view>账单记录</view>
</navigator>
<navigator class='item' hover-class='none' url='/pages/users/user_bill/index?type=expenditure'>
<view class='pictrue'>
<text class="iconfont icon-s-xiaofeijilu icon_txt"></text>
</view>
<view>消费记录</view>
</navigator>
<navigator class='item' hover-class='none' url='/pages/users/user_bill/index?type=income' v-if="userInfo.rechargeSwitch">
<view class='pictrue'>
<text class="iconfont icon-s-chongzhijilu icon_txt"></text>
</view>
<view>充值记录</view>
</navigator>
<navigator class='item' hover-class='none' url='/pages/users/user_integral/index'>
<view class='pictrue'>
<text class="iconfont icon-jifenzhongxin icon_txt"></text>
</view>
<view>积分中心</view>
</navigator>
</view>
<view class='advert acea-row row-between-wrapper'>
<navigator class='item acea-row row-between-wrapper' hover-class='none' url='/pages/users/user_sgin/index'>
<view class='text'>
<view class='name'>签到领积分</view>
<view>赚积分抵现金</view>
</view>
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/gift.png'"></image>
</view>
</navigator>
<navigator class='item on acea-row row-between-wrapper' hover-class='none' url='/pages/users/user_get_coupon/index'>
<view class='text'>
<view class='name'>领取优惠券</view>
<view>满减享优惠</view>
</view>
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/money.png'"></image>
</view>
</navigator>
</view>
</view>
<recommend ref="recommendIndex" @getRecommendLength="getRecommendLength"></recommend>
<view class='noCommodity' v-if="isNoCommodity">
<view class='pictrue'>
<image :src="urlDomain+'crmebimage/perset/staticImg/noSearch.png'"></image>
</view>
</view>
</view>
</view>
</template>
<script>
import {userActivity,getuserDalance} from '@/api/user.js';
import {toLogin} from '@/libs/login.js';
import {mapGetters} from "vuex";
import { alipayQueryPayResult } from '@/api/order.js';
import recommend from '@/components/recommend/index';
let app = getApp();
export default {
components: {
recommend
},
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
hostProduct: [],
isClose: false,
activity: {},
statistics:{},
theme:app.globalData.theme,
isNoCommodity: false // 是否显示缺省图
};
},
computed: mapGetters(['isLogin', 'userInfo']),
watch:{
isLogin:{
handler:function(newV,oldV){
if(newV){
this.get_activity();
this.userDalance();
}
},
deep:true
}
},
onLoad() {
if (this.isLogin) {
// #ifdef H5
var url = window.location.search;
if(url){
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
var strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split('=')[0]] = decodeURI(strs[i].split('=')[1]);
}
}
this.orderId = theRequest.out_trade_no; //返回的订单号
this.alipayQueryPay();
}
// #endif
this.get_activity();
this.userDalance();
} else {
toLogin();
}
},
methods: {
getRecommendLength(e) {
this.isNoCommodity = e == 0 ? true : false;
},
/**
* 支付宝充值结果查询
*/
alipayQueryPay() {
uni.showLoading({
title: '查询中...'
});
alipayQueryPayResult(this.orderId).then(res => {
this.userDalance();
return this.$util.Tips({
title: '充值成功'
});
uni.hideLoading();
}).catch(err => {
uni.hideLoading();
return this.$util.Tips({
title: err
});
})
},
onLoadFun: function() {
this.get_activity();
this.userDalance();
},
userDalance(){
getuserDalance().then(res=>{
this.statistics = res.data;
})
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
openSubscribe: function(page) {
uni.navigateTo({
url: page,
});
},
/**
* 获取活动可参与否
*/
get_activity: function() {
// let that = this;
// userActivity().then(res => {
// that.$set(that, "activity", res.data);
// })
}
},
onReachBottom() {
this.$refs.recommendIndex.get_host_product();
}
}
</script>
<style scoped lang="scss">
.my-account .wrapper {
background-color: #fff;
padding: 32rpx 0 15rpx 0;
margin-bottom: 14rpx;
}
.my-account .wrapper .header {
width: 690rpx;
height: 330rpx;
@include main_bg_color(theme);
border-radius: 16rpx;
margin: 0 auto;
box-sizing: border-box;
color: rgba(255, 255, 255, 0.6);
font-size: 24rpx;
}
.my-account .wrapper .header .headerCon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArIAAAFKCAYAAADhULxpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkEzMUM4RDlEM0YxNTExRTk4OUJFQ0Q4Qjg0RDBCMzQ1IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkEzMUM4RDlFM0YxNTExRTk4OUJFQ0Q4Qjg0RDBCMzQ1Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QTMxQzhEOUIzRjE1MTFFOTg5QkVDRDhCODREMEIzNDUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QTMxQzhEOUMzRjE1MTFFOTg5QkVDRDhCODREMEIzNDUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6ymvxvAAAIhklEQVR42uzd0W6bQBCG0QWMwfj9nzfNKNBYVSq1iXH443MkXzfdGz6hYbZ7eXlpAACQpncEAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgAgZAEAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAACELAABCFgAAhCwAAEIWAACELAAACFkAABCyAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgAgZAEAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAACELAABCFgAAhCwAAEIWAACELAAACFkAABCyAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgAgZAEAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAACELAABCFgAAhCwAAEIWAACELAAACFkAABCyAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgCAkAUAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAACELAABCFgAAhCwAAAhZAACELAAACFkAABCyAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgCAkAUAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAACELAABCFgAAhCwAAAhZAACELAAACFkAABCyAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgCAkAUAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAACELAABCFgAAhCwAAAhZAACELAAACFkAABCyAAAIWQAAELIAACBkAQAQsgAAIGQBAEDIAgCAkAUAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAAIQsAABCFgAAhCwAAAhZAACELAAACFkAABCyAAAIWQAAELIAACBkAQBAyAIAIGQBAEDIAgCAkAUAQMgCAICQBQAAIQsAgJAFAAAhCwAAQhYAAIQsAABCFgAAhCwAAAhZAACELAAACFkAABCyAAAIWQAAELIAACBkAQBAyAIAIGQBAEDIAgCAkAUA4Ec7OQIAAIJ0r7/h9dcLWQAAjh6tt7/fEwVCFgCAw0frR4QsAADfoV9b9DZc/4uQBQDgkeG6xeuXlw4IWQAA9g7X+nX3/geELAAA99D9Ea67r3kVsgAAfFaNCIztfVzgoYQsAAD/6vat69h2GBcQsgAA3Et/E66HakchCwDAR/G6hethe1HIAgBwG6/1GxL+YCELAPC8ujVczynxKmQBAMTr4WZehSwAAH/rvnPb6XICIQsAwD31a7yO7QEXFAhZAAC+InruVcgCADyfob2/fe2e4T8sZAEAsm1vX5+u64QsAECebfa1ft2zHoKQBQDIUeMDU3t7C/v0hCwAwPGNa8AOjkLIAgAcXY0MbOMDveMQsgAAR2f+VcgCAMQF7LQGLEIWAODwfMAlZAEABKyQBQBgz4CddZiQBQAQsEIWAICdAtYIgZAFAIhRWwhmAStkAQBSdGvAWqMlZAEAYgJ22wPrIgMhCwAQoeJ1FrBCFgAgqaUqYAdHIWQBABLUh1wXLSVkAQBSbHOwk6MQsgAAKczBClkAgCg1/3pp5mCFLABACPtghSwAQJy6jevSjBEIWQCAELYRCFkAgDjbNgJvYYUsAEAEH3MJWQCAKHbCClkAgMgGqrewvaMQsgAACazUErIAAJHd4y2skAUAiFJvYc3CClkAgBg2EghZAIA49QZ2dgxCFgAghdu5hCwAQJxxjVi3cwlZAIAYFbDWaglZAIAYNUqwNB90CVkAgCD1BrY+6DJKIGQBACK4oQshCwDEMUqAkAUA4thKgJAFAOK4ZhYhCwBEqbevi25ByAIASYY1YntHgZAFAFLURoKLY0DIAgBJzMMiZAGAKOZhEbIAQJyag70287AIWQAgrEnqTaz9sAhZACCGj7oQsgBAHB91IWQBgDg1SjA6BoQsAJCi5mDro67BUSBkAYAUNhMgZAGAOMMasTYTIGQBgKjmsF4LIQsARBnXiAUhCwDEsCMWIQsAxKn9sLNjQMgCAElcdICQBQDi1CjB2TEgZAGAJG7r4mEsIwYARCxCFgAQsfAoRgsAgK+6agqELACQpG7pWvQE38VoAQDwWSIWIQsAxDFOgJAFAOJ4E4uQBQAiI9Z2AoQsACBiQcgCAHu6iFiELACQZn79nR0DQhYASDKtPxCyAECMegs7OwaELACQpOZhL44BIQsAJKkdsYtjQMgCAEkGEYuQBQASu6AitnMUCFkAIEXF61UbIGQBABELQhYA2FltJxgcA0IWAEhSe2JdPYuQBQCi1IUHbu1CyAIAUWpXrAsPELIAQNzz365YhCwAEGXbUGBXLEIWAIiyeP4jZAGANLWh4OQYELIAQBIbChCyAECcuuxgdgwIWQAgSX3UtTQfdyFkAYAwPu5CyAIAcXzchZAFAOKMzcddCFkAIPD57vpZhCwAEMXHXQhZACBSzcUOjgEhCwAkOa8/ELIAQNQz3aUHCFkAII65WIQsABCnNhSYi0XIAgBRal+suViELAAQ9xy3LxYhCwDEqYg1F4uQBQCi1PWzJ8eAkAUAktSHXVZtIWQdAQDEMRcLQhYA4riCFoQsAMSpmdjJMYCQBYAktZ3ASAEIWQCIM3tug5AFgDQ1UuD2LhCyABDFSAEIWQCINHleg5AFgDRDs6UAhCwABFocAQhZAEhjpACELABEPp9nxwBCFgDS2FIAQhYA4oztbW8sIGQBIIadsSBkASDSvMYsIGQBIEbtjHUNLQhZAIhjpACELADEqTexg2MAIQsASWom1s5YELIAEGdqPvACIQsAgc/hyTGAkAWAND7wAiELAHFOzQ1eIGQBIJAPvEDIAkAc67ZAyAJAHOu2QMgCQCTrtkDIAkCcCtizYwAhCwBp5uZtLAhZAAh85nobC0IWAOL4wAuELADEqVVbo2MAIQsAaSZHAEIWANJ4GwtCFgAimY2FnfwSYABJ5w5fwq1SbwAAAABJRU5ErkJggg==');
background-repeat: no-repeat;
background-size: 100%;
height: 100%;
width: 100%;
padding: 36rpx 0 29rpx 0;
box-sizing: border-box;
}
.my-account .wrapper .header .headerCon .account {
padding: 0 35rpx;
}
.my-account .wrapper .header .headerCon .account .assets .money {
font-size: 72rpx;
color: #fff;
font-family: 'Guildford Pro';
}
.my-account .wrapper .header .headerCon .account .recharge {
font-size: 28rpx;
width: 150rpx;
height: 54rpx;
border-radius: 27rpx;
background-color: #fff9f8;
text-align: center;
line-height: 54rpx;
}
.font_color{
@include main_color(theme);
}
.icon_txt{
font-size: 43rpx;
@include main_color(theme);
}
.my-account .wrapper .header .headerCon .cumulative {
margin-top: 46rpx;
}
.my-account .wrapper .header .headerCon .cumulative .item {
flex: 1;
padding-left: 35rpx;
}
.my-account .wrapper .header .headerCon .cumulative .item .money {
font-size: 48rpx;
font-family: 'Guildford Pro';
color: #fff;
margin-top: 6rpx;
}
.my-account .wrapper .nav {
height: 155rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.my-account .wrapper .nav .item {
flex: 1;
text-align: center;
font-size: 26rpx;
color: #999;
}
.my-account .wrapper .nav .item .pictrue {
width: 44rpx;
height: 44rpx;
margin: 0 auto;
margin-bottom: 20rpx;
}
.my-account .wrapper .nav .item .pictrue image {
width: 100%;
height: 100%;
}
.my-account .wrapper .advert {
padding: 0 30rpx;
margin-top: 30rpx;
}
.my-account .wrapper .advert .item {
background-color: #fff6d1;
width: 332rpx;
height: 118rpx;
border-radius: 10rpx;
padding: 0 27rpx 0 25rpx;
box-sizing: border-box;
font-size: 24rpx;
color: #e44609;
}
.my-account .wrapper .advert .item.on {
background-color: #fff3f3;
color: #e96868;
}
.my-account .wrapper .advert .item .pictrue {
width: 78rpx;
height: 78rpx;
}
.my-account .wrapper .advert .item .pictrue image {
width: 100%;
height: 100%;
}
.my-account .wrapper .advert .item .text .name {
font-size: 30rpx;
font-weight: bold;
color: #f33c2b;
margin-bottom: 7rpx;
}
.my-account .wrapper .advert .item.on .text .name {
color: #f64051;
}
.my-account .wrapper .list {
padding: 0 30rpx;
}
.my-account .wrapper .list .item {
margin-top: 44rpx;
}
.my-account .wrapper .list .item .picTxt .iconfont {
width: 82rpx;
height: 82rpx;
border-radius: 50%;
background-image: linear-gradient(to right, #ff9389 0%, #f9776b 100%);
text-align: center;
line-height: 82rpx;
color: #fff;
font-size: 40rpx;
}
.my-account .wrapper .list .item .picTxt .iconfont.yellow {
background-image: linear-gradient(to right, #ffccaa 0%, #fea060 100%);
}
.my-account .wrapper .list .item .picTxt .iconfont.green {
background-image: linear-gradient(to right, #a1d67c 0%, #9dd074 100%);
}
.my-account .wrapper .list .item .picTxt {
width: 428rpx;
font-size: 30rpx;
color: #282828;
}
.my-account .wrapper .list .item .picTxt .text {
width: 317rpx;
}
.my-account .wrapper .list .item .picTxt .text .infor {
font-size: 24rpx;
color: #999;
margin-top: 5rpx;
}
.my-account .wrapper .list .item .bnt {
font-size: 26rpx;
color: #282828;
width: 156rpx;
height: 52rpx;
border: 1rpx solid #ddd;
border-radius: 26rpx;
text-align: center;
line-height: 52rpx;
}
.my-account .wrapper .list .item .bnt.end {
font-size: 26rpx;
color: #aaa;
background-color: #f2f2f2;
border-color: #f2f2f2;
}
</style>

View File

@@ -0,0 +1,749 @@
<template>
<view :data-theme="theme" class="user_payment">
<form @submit="submitSub" report-submit='true'>
<view class="payment-top acea-row row-column row-center-wrapper">
<span class="name1">我的余额</span>
<view class="pic">
<span class="pic-font">{{ userInfo.nowMoney || 0 }}</span>
</view>
</view>
<view class="payment">
<view class="nav acea-row row-around row-middle">
<view class="item" :class="active==index?'on':''" v-for="(item,index) in navRecharge" :key="index" @click="navRecharges(index)">{{item}}</view>
</view>
<view class='tip picList' v-if='!active'>
<view class="pic-box pic-box-color acea-row row-center-wrapper row-column" :class="activePic === index ? 'pic-box-color-active' : ''"
v-for="(item, index) in picList" :key="index" @click="picCharge(index, item)">
<view class="pic-number-pic">
{{ item.price }}<span class="pic-number"> </span>
</view>
<view class="pic-number">赠送{{ item.giveMoney }} </view>
</view>
<view class="pic-box pic-box-color acea-row row-center-wrapper" :class="parseFloat(activePic)===parseFloat(picList.length)?'pic-box-color-active':''" @click="picCharge(picList.length)">
<input type="number" placeholder="其他" v-model="money" maxlength="5" class="pic-box-money pic-number-pic uni-input" :class="parseFloat(activePic) === parseFloat(picList.length) ? 'pic-box-color-active' : ''" @blur="addMoney()" />
</view>
<view class="tips-box">
<view class="tips mt-30">注意事项</view>
<view class="tips-samll" v-for="item in rechargeAttention" :key="item">
{{ item }}
</view>
</view>
</view>
<view class="tip" v-else>
<view class='input'><text></text>
<input placeholder="0.00" type='number' placeholder-class='placeholder' :value="number"
name="number"></input></view>
<view class="tips-title">
<view style="font-weight: bold; font-size: 26rpx;">提示</view>
<view style="margin-top: 10rpx;">当前佣金为 <text class='font-color'>{{userInfo.brokeragePrice || 0}}</text></view>
</view>
<view class="tips-box">
<view class="tips mt-30">注意事项</view>
<view class="tips-samll" v-for="item in rechargeAttention" :key="item">
{{ item }}
</view>
</view>
</view>
<!-- #ifndef MP-->
<view class='wrapper borRadius14 px-30' v-if='!active'>
<view class='item'>
<view>支付方式</view>
<view class='list'>
<view class='payItem acea-row row-middle' :class='curActive==index ?"on":""'
@tap='payItem(index)' v-for="(item,index) in cartArr" :key='index'
v-if="item.payStatus===1">
<view class='name acea-row row-center-wrapper'>
<view class='iconfont animated'
:class='(item.icon) + " " + (animated==true&&active==index ?"bounceIn":"")'>
</view>
{{item.name}}
</view>
<view class='tip'>{{item.title}}</view>
</view>
</view>
</view>
</view>
<!-- #endif -->
<button class='but' formType="submit"> {{active ? '立即转入': '立即充值' }}</button>
<view class="alipaysubmit" v-html="formContent"></view>
</view>
</form>
</view>
</template>
<script>
import {
rechargeRoutine,
rechargeWechat,
getRechargeApi,
transferIn,
appWechat,
alipayFull
} from '@/api/user.js';
import { wechatQueryPayResult,getOrderPayConfig} from '@/api/order.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import {Debounce} from '@/utils/validate.js'
let app = getApp();
export default {
data() {
let that = this;
return {
now_money: 0,
navRecharge: ['账户充值', '佣金转入'],
active: 0,
number: '',
placeholder: "0.00",
from: '',
picList: [],
activePic: 0,
money: "",
numberPic: '',
rechar_id: 0,
rechargeAttention: [],
theme:app.globalData.theme,
//支付方式
cartArr: [{
"name": "微信支付",
"icon": "icon-weixin2",
value: 'weixin',
title: '微信快捷支付',
payStatus: 1,
},
// #ifndef MP
{
"name": "支付宝支付",
"icon": "icon-zhifubao",
value: 'alipay',
title: '支付宝快捷支付',
payStatus: 1,
}
// #endif
],
payType: 'weixin', //支付方式
openType: 1, //优惠券打开方式 1=使用
curActive: 0, //支付方式切换
animated: false,
formContent:''
};
},
computed: mapGetters(['isLogin', 'systemPlatform','userInfo']),
watch:{
isLogin:{
handler:function(newV,oldV){
if(newV){
this.getRecharge();
}
},
deep:true
}
},
onLoad(options) {
// #ifdef H5
this.from = this.$wechat.isWeixin() ? "public" : "weixinh5";
// #endif
// #ifdef APP-PLUS
this.from = this.systemPlatform === 'ios' ? 'weixinAppIos' : 'weixinAppAndroid';
// #endif
if (this.isLogin) {
this.getRecharge();
this.payConfig();
} else {
toLogin();
}
},
methods: {
/**
* 选择金额
*/
picCharge(idx, item) {
this.activePic = idx;
if (item === undefined) {
this.rechar_id = 0;
this.numberPic = "";
} else {
this.money = "";
this.rechar_id = item.id;
this.numberPic = item.price;
}
},
/**
* 充值额度选择
*/
getRecharge() {
getRechargeApi()
.then(res => {
this.picList = res.data.rechargeQuota;
if (this.picList[0]) {
this.rechar_id = this.picList[0].id;
this.numberPic = this.picList[0].price;
}
this.rechargeAttention = res.data.rechargeAttention || [];
})
.catch(res => {
this.$dialog.toast({
mes: res
});
});
},
// 支付配置
payConfig(){
getOrderPayConfig().then(res=>{
this.cartArr[0].payStatus = res.data.payWechatOpen ? 1 : 0;
// #ifndef MP
this.cartArr[1].payStatus = res.data.aliPayStatus ? 1 : 0;
// #endif
if(this.$wechat.isWeixin()) this.cartArr.pop();
})
},
navRecharges: function(index) {
this.active = index;
},
payItem: function(e) {
let that = this;
let active = e;
that.curActive = active;
that.animated = true;
that.payType = that.cartArr[active].value;
},
/*
* 用户充值
*/
submitSub: Debounce(function(e) {
let that = this
let value = e.detail.value.number ? e.detail.value.number :that.numberPic;
// 转入余额
if (that.active) {
if (parseFloat(value) < 0 || parseFloat(value) == NaN || value == undefined || value == "") {
return that.$util.Tips({
title: '请输入金额'
});
}
uni.showModal({
title: '转入余额',
content: '转入余额后无法再次转出,确认是否转入余额',
success(res) {
if (res.confirm) {
transferIn({
price: parseFloat(value)
}).then(res => {
that.$store.commit("changInfo", {
amount1: 'brokeragePrice',
amount2: that.$util.$h.Sub(that.userInfo.brokeragePrice, parseFloat(value))
});
return that.$util.Tips({
title: '转入成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_money/index'
});
}).catch(err=>{
return that.$util.Tips({
title: err
});
})
} else if (res.cancel) {
return that.$util.Tips({
title: '已取消'
});
}
},
})
} else {
uni.showLoading({
title: '正在支付',
})
let money = parseFloat(this.money);
if (this.rechar_id == 0) {
if (Number.isNaN(money)) {
return that.$util.Tips({
title: '充值金额必须为数字'
});
}
if (money <= 0) {
return that.$util.Tips({
title: '充值金额不能为0'
});
}
if (money > 50000) {
return that.$util.Tips({
title: '充值金额最大值为50000'
});
}
} else {
money = this.numberPic
}
switch (that.payType){
case 'weixin':
// #ifdef APP-PLUS
appWechat({
from: that.from,
price: money,
type: 0,
rechar_id: this.rechar_id
}).then(res => {
uni.hideLoading();
let jsConfig = res.data.jsConfig;
uni.requestPayment({
provider: 'wxpay',
orderInfo: {
"appid": jsConfig.appId, // 微信开放平台 - 应用 - AppId注意和微信小程序、公众号 AppId 可能不一致
"noncestr": jsConfig.nonceStr, // 随机字符串
"package": "Sign=WXPay", // 固定值
"partnerid": jsConfig.partnerid, // 微信支付商户号
"prepayid": jsConfig.packages, // 统一下单订单号
"timestamp": Number(jsConfig.timeStamp), // 时间戳(单位:秒)
"sign": this.systemPlatform === 'ios' ? 'MD5' : jsConfig.paySign // 签名,这里用的 MD5 签名
}, //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
success: function(res) {
that.$store.commit("changInfo", {
amount1: 'nowMoney',
amount2: that.$util.$h.Add(value, that.userInfo.nowMoney)
});
return that.$util.Tips({
title: '支付成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_money/index'
});
},
fail: function(err) {
return that.$util.Tips({
title: '支付失败'
});
},
complete: function(res) {
if (res.errMsg == 'requestPayment:cancel') return that.$util.Tips({
title: '取消支付'
});
}
})
}).catch(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
})
});
// #endif
// #ifdef MP
rechargeRoutine({
price: money,
type: 0,
rechar_id: this.rechar_id
}).then(res => {
uni.hideLoading();
let jsConfig = res.data.data.jsConfig;
uni.requestPayment({
timeStamp: jsConfig.timeStamp,
nonceStr: jsConfig.nonceStr,
package: jsConfig.packages,
signType: jsConfig.signType,
paySign: jsConfig.paySign,
success: function(res) {
that.$store.commit("changInfo", {
amount1: 'nowMoney',
amount2: that.$util.$h.Add(value, that.userInfo.nowMoney)
});
return that.$util.Tips({
title: '支付成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_money/index'
});
},
fail: function(err) {
return that.$util.Tips({
title: '支付失败'
});
},
complete: function(res) {
if (res.errMsg == 'requestPayment:cancel') return that.$util.Tips({
title: '取消支付'
});
}
})
}).catch(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
})
});
// #endif
// #ifdef H5
rechargeWechat({
price: money,
from: that.from,
rechar_id: that.rechar_id,
payType: 0
}).then(res => {
let jsConfig = res.data.jsConfig;
let orderNo = res.data.orderNo;
let data = {
timestamp:jsConfig.timeStamp,
nonceStr:jsConfig.nonceStr,
package:jsConfig.packages,
signType:jsConfig.signType,
paySign:jsConfig.paySign
};
if (that.from == "weixinh5") {
uni.hideLoading();
that.$util.Tips({
title: '支付成功'
}, {
tab: 5,
url:'/pages/users/user_money/index'
});
setTimeout(() => {
location.href = jsConfig.mwebUrl;
}, 100)
} else {
that.$wechat.pay(data)
.finally(() => {
that.$store.commit("changInfo", {
amount1: 'nowMoney',
amount2: that.$util.$h.Add(value, that.userInfo.nowMoney)
});
return that.$util.Tips({
title: '支付成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_money/index'
});
})
.catch(function(err) {
return that.$util.Tips({
title: '支付失败'
});
});
}
}).catch(res=>{
uni.hideLoading();
return that.$util.Tips({
title: res
});
})
// #endif
break;
case 'alipay':
// alipayFull
// #ifdef APP-PLUS
alipayFull({
from: 'appAliPay',
price: money,
payType: 'alipay',
rechar_id: this.rechar_id
}).then(res => {
uni.hideLoading();
let alipayRequest = res.data.alipayRequest;
uni.requestPayment({
provider: 'alipay',
orderInfo: alipayRequest,
success: (e) => {
return that.$util.Tips({
title: '支付成功',
icon: 'success'
}, {
tab: 5,
url: '/pages/users/user_money/index'
});
},
fail: (e) => {
return that.$util.Tips({
title: '支付失败'
});
},
complete: () => {
uni.hideLoading();
},
});
}).catch(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
})
});
// #endif
// #ifdef H5
if (this.$wechat.isWeixin()) {
uni.redirectTo({
url: `/pages/users/alipay_invoke/index?price=${money}&rechar_id=${this.rechar_id}&type=users`
});
} else{
alipayFull({
from: 'alipay',
price: money,
payType: 'alipay',
rechar_id: this.rechar_id
}).then(res => {
//h5支付
uni.hideLoading();
that.formContent = res.data.alipayRequest;
that.$nextTick(() => {
document.forms['punchout_form'].submit();
})
}).catch(res=>{
uni.hideLoading();
return that.$util.Tips({
title: res
});
})
}
// #endif
break;
}
}
}),
addMoney(){
this.money = this.money.replace(/[^\d]/g,'').replace(/^0{1,}/g,'');
}
}
}
</script>
<style lang="scss">
.user_payment{
height: 100vh;
background-color: #fff;
}
.payment {
position: relative;
top: -60rpx;
width: 100%;
background-color: #fff;
border-radius: 10rpx;
padding-top: 25rpx;
border-top-right-radius: 14rpx;
border-top-left-radius: 14rpx;
}
.payment .nav {
height: 75rpx;
line-height: 75rpx;
padding: 0 100rpx;
}
.payment .nav .item {
font-size: 30rpx;
color: #333;
}
.payment .nav .item.on {
font-weight: bold;
@include tab_border_bottom(theme);
}
.payment .input {
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px dashed #dddddd;
margin: 60rpx auto 0 auto;
padding-bottom: 20rpx;
font-size: 56rpx;
color: #333333;
flex-wrap: nowrap;
}
.payment .input text {
padding-left: 106rpx;
}
.payment .input input {
padding-right: 106rpx;
width: 300rpx;
height: 94rpx;
text-align: center;
font-size: 70rpx;
}
.payment .placeholder {
color: #d0d0d0;
height: 100%;
line-height: 94rpx;
}
.payment .tip {
font-size: 26rpx;
color: #888888;
padding: 0 30rpx;
// margin-top: 25rpx;
}
.payment .but {
color: #fff;
font-size: 30rpx;
width: 700rpx;
height: 86rpx;
border-radius: 43rpx;
margin: 50rpx auto 0 auto;
@include linear-gradient(theme);
line-height: 86rpx;
}
.payment-top {
width: 100%;
height: 350rpx;
@include main_bg_color(theme);
.name1 {
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
margin-top: -38rpx;
margin-bottom: 30rpx;
}
.pic {
font-size: 32rpx;
color: #fff;
}
.pic-font {
font-size: 78rpx;
color: #fff;
}
}
.picList {
display: flex;
flex-wrap: wrap;
margin: 30rpx 0;
.pic-box {
width: 32%;
height: auto;
border-radius: 20rpx;
margin-top: 21rpx;
padding: 20rpx 0;
margin-right: 12rpx;
&:nth-child(3n) {
margin-right: 0;
}
}
.pic-box-color {
background-color: #f4f4f4;
color: #656565;
}
.pic-number {
font-size: 22rpx;
}
.pic-number-pic {
font-size: 38rpx;
margin-right: 10rpx;
text-align: center;
}
}
.pic-box-color-active {
@include linear-gradient(theme);
color: #fff !important;
}
.tips-box {
.tips {
font-size: 28rpx;
color: #333333;
font-weight: 800;
margin-bottom: 14rpx;
margin-top: 20rpx;
}
.tips-samll {
font-size: 24rpx;
color: #333333;
margin-bottom: 14rpx;
}
.tip-box {
margin-top: 30rpx;
}
}
.tips-title {
margin-top: 20rpx;
font-size: 24rpx;
color: #333;
}
.wrapper .item textarea {
background-color: #f9f9f9;
width: auto !important;
height: 140rpx;
border-radius: 14rpx;
margin-top: 30rpx;
padding: 15rpx;
box-sizing: border-box;
font-weight: 400;
}
.px-30{
padding-left: 30rpx;
padding-rigt: 30rpx;
}
.wrapper .item .placeholder {
color: #ccc;
}
.wrapper .item .list {
margin-top: 35rpx;
}
.wrapper .item .list .payItem {
border: 1px solid #eee;
border-radius: 14rpx;
height: 86rpx;
width: 95%;
box-sizing: border-box;
margin-top: 20rpx;
font-size: 28rpx;
color: #282828;
}
.wrapper .item .list .payItem.on {
// border-color: #fc5445;
@include coupons_border_color(theme);
color: $theme-color;
}
.name {
width: 50%;
text-align: center;
border-right: 1px solid #eee;
}
.name .iconfont {
width: 44rpx;
height: 44rpx;
border-radius: 50%;
text-align: center;
line-height: 44rpx;
background-color: #fe960f;
color: #fff;
font-size: 30rpx;
margin-right: 15rpx;
}
.name .iconfont.icon-weixin2 {
background-color: #41b035;
}
.name .iconfont.icon-zhifubao {
background-color: #00AAEA;
}
.payItem .tip {
width: 49%;
text-align: center;
font-size: 26rpx;
color: #aaa;
}
</style>

View File

@@ -0,0 +1,171 @@
<template>
<view>
<view class='return-list pad30' v-if="orderList.length">
<view class='goodWrapper borRadius14' v-for="(item,index) in orderList" :key="index" @click='goOrderDetails(item.orderId)'>
<view class='iconfont icon-tuikuanzhong powder' v-if="item.refundStatus==1 || item.refundStatus==3"></view>
<view class='iconfont icon-yituikuan' v-if="item.refundStatus==2"></view>
<view class='orderNum'>订单号{{item.orderId}}</view>
<view class='item acea-row row-between-wrapper' v-for="(items,index) in item.orderInfoList" :key="index">
<view class='pictrue'>
<image :src='items.image'></image>
</view>
<view class='text'>
<view class='acea-row row-between-wrapper'>
<view class='name line1'>{{items.storeName}}</view>
<view class='num'>x {{items.cartNum}}</view>
</view>
<view class='attr line1' v-if="items.sku">{{items.sku}}</view>
<view class='money'>{{items.price}}</view>
</view>
</view>
<view class='totalSum'>{{item.totalNum || 0}}件商品总金额 <text class=' price'>{{item.payPrice}}</text></view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper' v-if="orderList.length">
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadTitle}}
</view>
<view v-if="orderList.length == 0 && !loading">
<emptyPage title="暂无订单~"></emptyPage>
</view>
</view>
</template>
<script>
import emptyPage from '@/components/emptyPage.vue'
import {
getOrderList
} from '@/api/order.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
export default {
components: {
emptyPage
},
data() {
return {
loading: false,
loadend: false,
loadTitle: '加载更多', //提示语
orderList: [], //订单数组
orderStatus: -3, //订单状态
page: 1,
limit: 20
};
},
computed: mapGetters(['isLogin']),
watch:{
isLogin:{
handler:function(newV,oldV){
if(newV){
this.getOrderList();
}
},
deep:true
}
},
onLoad() {
if (this.isLogin) {
this.getOrderList();
} else {
toLogin();
}
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getOrderList();
},
methods: {
/**
* 去订单详情
*/
goOrderDetails: function(order_id) {
if (!order_id) return that.$util.Tips({
title: '缺少订单号无法查看订单详情'
});
uni.navigateTo({
url: '/pages/order/order_details/index?order_id=' + order_id + '&isReturen=1'
})
},
/**
* 获取订单列表
*/
getOrderList: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
that.loadTitle = "";
getOrderList({
type: that.orderStatus,
page: that.page,
limit: that.limit,
}).then(res => {
let list = res.data.list || [];
let loadend = list.length < that.limit;
that.orderList = that.$util.SplitArray(list, that.orderList);
that.$set(that,'orderList',that.orderList);
that.loadend = loadend;
that.loading = false;
that.loadTitle = loadend ? "哼😕~我也是有底线的~" : '加载更多';
that.page = that.page + 1;
}).catch(err => {
that.loading = false;
that.loadTitle = "加载更多";
});
}
}
}
</script>
<style lang="scss" scoped>
.return-list .goodWrapper {
background-color: #fff;
margin-top: 20rpx;
position: relative;
padding: 0rpx 24rpx;
}
.return-list .goodWrapper .orderNum {
border-bottom: 1px solid #eee;
height: 87rpx;
line-height: 87rpx;
font-size: 30rpx;
color: #333333;
}
.return-list .goodWrapper .item {
border-bottom: 0;
}
.return-list .goodWrapper .totalSum {
padding: 0 30rpx 32rpx 30rpx;
text-align: right;
font-size: 26rpx;
color: #282828;
}
.return-list .goodWrapper .totalSum .price {
font-size: 28rpx;
font-weight: bold;
@include price_color(theme);
}
.return-list .goodWrapper .iconfont {
position: absolute;
font-size: 109rpx;
top: 7rpx;
right: 22rpx;
color: #ccc;
}
.return-list .goodWrapper .iconfont.powder {
color: #f8c1bd;
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,94 @@
<template>
<view :data-theme="theme">
<view class='sign-record'>
<view class='list pad30' v-for="(item,index) in signList" :key="index">
<view class='item'>
<view class='data'>{{item.month}}</view>
<view class='listn borRadius14'>
<view class='itemn acea-row row-between-wrapper' v-for="(itemn,indexn) in item.list" :key="indexn">
<view>
<view class='name line1'>{{itemn.title}}</view>
<view>{{itemn.createDay}}</view>
</view>
<view class='num font_color'>+{{itemn.number}}</view>
</view>
</view>
</view>
</view>
<view class='loadingicon acea-row row-center-wrapper'>
<text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>{{loadtitle}}
</view>
</view>
</view>
</template>
<script>
import { getSignMonthList } from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
let app = getApp();
export default {
data() {
return {
loading:false,
loadend:false,
loadtitle:'加载更多',
page:1,
limit:8,
signList:[],
theme:app.globalData.theme,
};
},
computed: mapGetters(['isLogin']),
watch:{
isLogin:{
handler:function(newV,oldV){
if(newV){
this.getSignMoneList();
}
},
deep:true
}
},
onLoad(){
if(this.isLogin){
this.getSignMoneList();
}else{
toLogin();
}
},
onReachBottom: function () {
this.getSignMoneList();
},
methods: {
/**
* 获取签到记录列表
*/
getSignMoneList:function(){
let that=this;
if(that.loading) return;
if(that.loadend) return;
that.loading = true;
that.loadtitle = "";
getSignMonthList({ page: that.page, limit: that.limit }).then(res=>{
let list = res.data.list;
let loadend = list.length < that.limit;
that.signList = that.$util.SplitArray(list, that.signList);
that.$set(that,'signList',that.signList);
that.loadend = loadend;
that.loading = false;
that.loadtitle = loadend ? "哼😕~我也是有底线的~" : "加载更多"
}).catch(err=>{
that.loading = false;
that.loadtitle = '加载更多';
});
},
}
}
</script>
<style lang="scss">
.font_color{
@include main_color(theme);
}
</style>

View File

@@ -0,0 +1,40 @@
<template>
<web-view class="web-view" :webview-styles="webviewStyles" :src="url" :style="{width: windowW + 'px', height: windowH + 'px'}"></web-view>
</template>
<script>
import {
mapGetters
} from "vuex";
export default {
//computed: mapGetters(['chatUrl']),
data() {
return {
windowH: 0,
windowW: 0,
webviewStyles: {
progress: {
color: 'transparent'
}
},
url: ''
}
},
onLoad(option) {
if(option.webUel) this.url = option.webUel;
// 蚂蚁智能客服场景参数
if(option.tntInstId) this.url += `?tntInstId=${option.tntInstId}`;
if(option.scene) this.url += `&scene=${option.scene}`;
uni.setNavigationBarTitle({
title: option.title
})
try {
const res = uni.getSystemInfoSync();
this.windowW = res.windowWidth;
this.windowH = res.windowHeight;
} catch (e) {
// error
}
}
}
</script>

View File

@@ -0,0 +1,455 @@
<template>
<view class="page" :data-theme="theme" :style="{'background-image': `url(${backBg})`}">
<view class="system-height" :style="{height:statusBarHeight}"></view>
<!-- #ifdef MP -->
<view class="title-bar" style="height: 43px;">
<view class="icon" @click="back" v-if="!isHome">
<image :src="urlDomain+'crmebimage/perset/usersImg/left.png'"></image>
</view>
<view class="icon" @click="home" v-else>
<image :src="urlDomain+'crmebimage/perset/usersImg/home.png'"></image>
</view>
账户登录
</view>
<!-- #endif -->
<view class="wechat_login">
<view class="img acea-row row-center">
<image :src="mobileLoginLogo" mode="widthFix" class="image"></image>
</view>
<view class="company">{{companyName}}</view>
<view class="btn-wrapper">
<!-- #ifdef H5 -->
<button hover-class="none" @click="wechatLogin" class="btn1 bg-color"><text
class='iconfont icon-weixin2'></text>立即登录</button>
<!-- #endif -->
<!-- #ifdef MP -->
<button v-if="wxLogin" hover-class="none"
@click="getUserProfile" class="btn1 bg-color">立即登录</button>
<view v-else>
<button v-if="routinePhoneVerification == 1 || routinePhoneVerification.length===3" hover-class="none"
@click="onUserPhone" class="btn1 bg-color"><text
class='iconfont'></text>一键绑定手机号</button>
<button v-if="routinePhoneVerification == 2 || routinePhoneVerification.length===3" hover-class="none"
@click="onUserPhone('isPhone')" class="btn2">手动绑定手机号</button>
</view>
<!-- #endif -->
</view>
</view>
<block v-if="isUp">
<mobileLogin :isUp="isUp" :loginConfig="loginConfig" @close="maskClose" :authKey="authKey" @wechatPhone="wechatPhone"></mobileLogin>
</block>
<atModel v-if="isPhoneBox" :userPhoneType="true" :isPhoneBox="isPhoneBox" :authKey="authKey"
:content="getPhoneContent" @closeModel="bindPhoneClose" @confirmModel="confirmModel"></atModel>
</view>
</template>
<script>
const app = getApp();
let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
import mobileLogin from '@/components/login_mobile/index.vue'
import atModel from '@/components/accredit/index.vue'
import {
mapGetters
} from "vuex";
import {
getUserPhone
} from '@/api/public';
import {
LOGO_URL,
EXPIRES_TIME,
USER_INFO,
STATE_R_KEY
} from '@/config/cache';
import {
HTTP_REQUEST_URL
} from '@/config/app';
import {
getUserInfo,
spread
} from '@/api/user.js'
import Routine from '@/libs/routine';
import wechat from "@/libs/wechat";
export default {
data() {
return {
urlDomain: this.$Cache.get("imgHost"),
isUp: false, // 绑定手机号手动输入弹窗
phone: '',
statusBarHeight: statusBarHeight,
isHome: false,
isPhoneBox: false, //授权手机号弹窗
code: '',
authKey: '',
options: '',
userInfo: {},
codeNum: 0,
pageStyle: {}, //背景图
theme: app.globalData.theme,
// urlDomain: this.$GLOBAL.urlDomain,
backBg: '', //背景图片
getPhoneContent: '申请获取您的手机号用于注册,完成后可使用商城更多功能',
wxCode: '', //小程序code值
companyName: app.globalData.companyName, //公司名称
routinePhoneVerification: app.globalData.routinePhoneVerification, //小程序手机号校验类型多选1微信小程序验证 2短信验证
loginConfig: '' ,//小程序绑定手机号isPhone其他手机号绑定
wxLogin: true ,//登录显示
mobileLoginLogo: app.globalData.mobileLoginLogo // 登录页logo
}
},
components: {
mobileLogin,
atModel
},
onLoad(options) {
//背景图片
switch (app.globalData.theme) {
case 'theme1':
this.backBg = `${this.urlDomain}crmebimage/perset/usersImg/wxbj1.png`;
break;
case 'theme2':
this.backBg = `${this.urlDomain}crmebimage/perset/usersImg/wxbj2.png`;
break;
case 'theme3':
this.backBg = `${this.urlDomain}crmebimage/perset/usersImg/wxbj3.png`;
break;
case 'theme4':
this.backBg = `${this.urlDomain}crmebimage/perset/usersImg/wxbj4.png`;
break;
case 'theme5':
this.backBg = `${this.urlDomain}crmebimage/perset/usersImg/wxbj5.png`;
break;
}
let that = this
// #ifdef H5
document.body.addEventListener("focusout", () => {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop ||
0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 100);
});
const {
code,
state,
scope
} = options;
this.options = options
// 获取确认授权code
this.code = code || ''
//if(!code) location.replace(decodeURIComponent(decodeURIComponent(option.query.back_url)));
if (code && this.options.scope !== 'snsapi_base') {
let spread = app.globalData.spread ? app.globalData.spread : 0;
//公众号授权登录回调 wechatAuth(code, Cache.get("spread"), loginType)
wechat.auth(code, spread).then(res => {
if (res.type === 'register') {
this.authKey = res.key;
this.isUp = true
}
if (res.type === 'login') {
this.$store.commit('LOGIN', {
token: res.token
});
this.$store.commit("SETUID", res.uid);
this.getUserInfo();
//this.wechatPhone();
//location.replace(decodeURIComponent(decodeURIComponent(option.query.back_url)));
}
}).catch(error => {});
}
// #endif
let pages = getCurrentPages();
// let prePage = pages[pages.length - 2];
// if (prePage.route == 'pages/order_addcart/order_addcart') {
// this.isHome = true
// } else {
// this.isHome = false
// }
},
methods: {
//绑定手机号弹窗回调
confirmModel() {
this.isPhoneBox = false;
this.isUp = true
},
back() {
uni.navigateBack();
},
home() {
uni.switchTab({
url: '/pages/index/index'
})
},
modelCancel() {
this.isPhoneBox = false;
},
// 弹窗关闭
maskClose() {
// this.isUp = false //点击模态框会关闭登录弹框,防止用户误触而关闭
},
bindPhoneClose(data) {
if (data.isStatus) {
this.isPhoneBox = false
this.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
} else {
this.isPhoneBox = false
}
},
// #ifdef MP
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
uni.hideLoading();
that.userInfo = res.data
that.$store.commit("UPDATE_USERINFO", res.data);
that.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
});
},
//绑定手机号
onUserPhone(type) {
this.loginConfig = type;
//如果是其他手机号绑定,调整页面。否则授权本机手机号登录
if (this.loginConfig === 'isPhone') {
uni.navigateTo({
url: `/pages/users/app_login/index?code=${this.wxCode}&authKey=${this.authKey}`
})
} else {
this.isPhoneBox = true
}
},
//wx小程序立即登录
getUserProfile() {
let self = this;
uni.showLoading({
title: '正在登录中'
});
const hostSDKVersion = uni.getSystemInfoSync().hostSDKVersion; //小程序基础库版本号
if (Routine.compareVersion(hostSDKVersion, '2.21.2') >= 0) {
Routine.getCode()
.then(code => {
let userInfo = {};
userInfo.code = code;
userInfo.spread_spid = app.globalData.spread; //获取推广人ID
userInfo.avatar = '';
userInfo.nickName = '微信用户';
userInfo.type = 'routine'
self.getWxUser(code, userInfo);
})
.catch(res => {
uni.hideLoading();
});
} else {
Routine.getUserProfile().then(res => {
Routine.getCode()
.then(code => {
let userInfo = res.userInfo;
userInfo.code = code;
userInfo.spread_spid = app.globalData.spread; //获取推广人ID
userInfo.avatar = userInfo.userInfo.avatarUrl;
userInfo.city = userInfo.userInfo.city;
userInfo.country = userInfo.userInfo.country;
userInfo.nickName = userInfo.userInfo.nickName;
userInfo.province = userInfo.userInfo.province;
userInfo.sex = userInfo.userInfo.gender;
userInfo.type = 'routine'
self.getWxUser(code, userInfo);
})
.catch(res => {
uni.hideLoading();
});
})
.catch(res => {
uni.hideLoading();
});
}
},
// 登录调用方法
getWxUser(code, userInfo) {
this.wxCode = code;
let self = this;
Routine.authUserInfo(userInfo.code, userInfo)
.then(res => {
self.authKey = res.data.key;
if (res.data.type === 'register') {
uni.hideLoading();
self.wxLogin = false;
}
if (res.data.type === 'login') {
uni.hideLoading();
self.$store.commit('LOGIN', {
token: res.data.token
});
self.$store.commit("SETUID", res.data.uid);
self.getUserInfo();
if (app.globalData.spread) {
spread(app.globalData.spread).then(res => {}) //登录成功后读取spread绑定分销关系
}
self.$util.Tips({
title: res,
icon: 'success'
}, {
tab: 3
})
}
})
.catch(res => {
uni.hideLoading();
uni.showToast({
title: res,
icon: 'none',
duration: 2000
});
});
},
// #endif
// #ifdef H5
// 获取url后面的参数
getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var reg_rewrite = new RegExp("(^|/)" + name + "/([^/]*)(/|$)", "i");
var r = window.location.search.substr(1).match(reg);
var q = window.location.pathname.substr(1).match(reg_rewrite);
if (r != null) {
return unescape(r[2]);
} else if (q != null) {
return unescape(q[2]);
} else {
return null;
}
},
// 公众号登录
wechatLogin() {
if (!this.code && this.options.scope !== 'snsapi_base') {
this.$wechat.oAuth('snsapi_userinfo', '/pages/users/wechat_login/index');
} else {
// if (this.authKey) {
// this.isUp = true;
// }
this.isUp = true;
}
},
// 输入手机号后的回调
wechatPhone() {
this.$Cache.clear('snsapiKey');
if (this.options.back_url) {
let url = uni.getStorageSync('snRouter');
url = url.indexOf('/pages/index/index') != -1 ? '/' : url;
if (url.indexOf('/pages/users/wechat_login/index') !== -1) {
url = '/';
}
if (!url) {
url = '/pages/index/index';
}
this.isUp = false
uni.showToast({
title: '登录成功',
icon: 'none'
})
setTimeout(res => {
location.href = url
}, 800)
} else {
uni.navigateBack()
}
}
// #endif
}
}
</script>
<style lang="scss">
page {
background: #fff;
height: 100%;
}
</style>
<style lang="scss" scoped>
.icon-weixin2{
margin-right: 10rpx;
}
.company {
font-size: 40rpx;
color: #333;
text-align: center;
font-weight: 500;
margin: 32rpx 0 96rpx 0;
}
.page {
background: #fff;
height: 100%;
background-size: contain;
background-repeat: no-repeat;
}
.wechat_login {
padding-top: 238rpx;
.img .image {
width: 152rpx;
height: 152rpx;
}
.btn-wrapper {
margin-top: 86rpx;
padding: 0 66rpx;
button {
width: 100%;
height: 86rpx;
line-height: 84rpx;
margin-bottom: 32rpx;
border-radius: 120rpx;
font-size: 32rpx;
&.btn1 {
color: #fff;
}
&.btn2 {
color: #666666;
border: 2px solid #E4E4E4;
}
}
}
}
.title-bar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
}
.icon {
position: absolute;
left: 30rpx;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 86rpx;
height: 86rpx;
image {
width: 50rpx;
height: 50rpx;
}
}
</style>