feat: 添加静态资源文件及基础组件

- 新增大量图片资源,包括图标、背景图、海报等,用于页面展示
- 添加字体文件及样式配置,支持自定义字体
- 引入 uni-ui 组件库,包括图标、弹窗、日期选择器等常用组件
- 添加网络状态监听、加密工具等基础工具函数
- 配置 Vuex 状态管理,包括购物车数量、热门搜索词等
- 增加页面组件,如用户协议、分销信息、提现状态等
- 配置项目构建和忽略文件,优化开发体验
This commit is contained in:
2026-02-26 17:59:51 +08:00
commit a5c5d753b6
720 changed files with 178840 additions and 0 deletions

381
pages/users/agent/apply.vue Normal file
View File

@@ -0,0 +1,381 @@
<template>
<view>
<view class="w-full fixed-lt z-20" :style="{ 'padding-top': sysHeight + 'px' }">
<view class="h-80 px-20 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-fff" @tap="pageBack"></text>
</view>
</view>
<view class="header-top relative" :style="[headerBg]">
<!-- <view class="rule-btn w-124 flex-center fs-24 text--w111-fff" :style="{ top: 100 + sysHeight + 'px' }" @tap="goRecord">申请记录</view> -->
</view>
<view class="bg-v-gradient pl-20 pr-20 pb-24" :style="{ minHeight: mainHeight + 'px' }">
<view class="bg--w111-fff rd-24rpx content-box">
<view class="fs-30 fw-500 lh-42rpx">请填写以下信息</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">代理商名称</view>
<input type="text" v-model="form.division_name" placeholder="请输入代理商名称" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">用户姓名</view>
<input type="text" v-model="form.name" placeholder="请输入姓名" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">邀请码</view>
<input type="number" v-model="form.division_invite" placeholder="请输入邀请码" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">联系电话</view>
<input type="number" v-model="form.phone" placeholder="请输入手机号" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view v-if="divisionApplyPhoneVerify" class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">验证码</view>
<view class="flex-y-center">
<input type="number" v-model="form.code" placeholder="请输入验证码" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
<button class="code-btn w-168 h-56 flex-center fs-24 ml-20" :disabled="disabled" @tap="code">{{ text }}</button>
</view>
</view>
<view class="fs-28 lh-40rpx mt-64">请上传营业执照及相关资质证明图片</view>
<view class="fs-24 lh-34rpx text--w111-ccc mt-12">(图片最多可上传8张,图片格式支持JPG、PNG、JPEG)</view>
<view class="grid-column-4 grid-gap-24rpx mt-24">
<view class="relative h-148" v-for="(item, index) in form.images" :key="index">
<image :src="item" mode="aspectFill" class="w-148 h-148 rd-16rpx"></image>
<view class="abs-rt w-32 h-32 del-pic flex-center fs-24" @click="DelPic(index)">
<text class="iconfont icon-ic_close text--w111-fff"></text>
</view>
</view>
<view class="h-148 flex-col flex-center upload bg--w111-f5f5f5 text--w111-999 rd-16rpx" @click="uploadpic" v-if="form.images.length < 8">
<text class="iconfont icon-ic_camera fs-42"></text>
<text class="fs-24 lh-34rpx pt-8">上传图片</text>
</view>
</view>
<view class="cell mt-64">
<view class="fs-28 lh-40rpx">申请说明</view>
<view class="text--w111-ccc mt-12">
{{ division_apply_explain }}
</view>
</view>
<view class="flex-y-center mt-32">
<text class="iconfont fs-30" :class="isSelect ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'" @tap="proviceSelect"></text>
<text class="fs-24 text--w111-999 pl-12">已阅读并同意</text>
<text class="font-red" @tap="getAgreement">《代理商协议》</text>
</view>
<view class="w-full h-88 rd-44rpx flex-center text--w111-fff fs-28 mt-48" :class="isSelectStar ? 'bg-red' : 'bg-disabled'" @tap="submitSupply">提交申请</view>
</view>
</view>
<Verify @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }" ref="verify"></Verify>
<tui-modal :show="showModal" maskClosable custom @cancel="hideModal">
<view class="tui-modal-custom">
<view class="fs-32 fw-500 lh-44rpx text-center">代理商协议</view>
<view class="fs-28 text--w111-666 lh-44rpx mt-24 desc-box">
<!-- #ifdef MP-WEIXIN -->
<rich-text :nodes="supplierAgreement"></rich-text>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view v-html="supplierAgreement"></view>
<!-- #endif -->
</view>
<view class="w-full h-72 rd-36rpx flex-center bg-red fs-26 text--w111-fff mt-32" @tap="hideModal">知道了</view>
</view>
</tui-modal>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import { agentCreateApi, getCodeApi, registerVerify, userAgentInfo, getUserAgreement } from '@/api/user.js';
import colors from '@/mixins/color';
import sendVerifyCode from '@/mixins/SendVerifyCode';
import { HTTP_REQUEST_URL, CAPTCHA_TYPE } from '@/config/app';
import Verify from '../components/verify/verify.vue';
import tuiModal from '@/components/tui-modal/index.vue';
export default {
data() {
return {
captchaType: CAPTCHA_TYPE,
sysHeight: sysHeight,
form: {
division_name: '',
name: '',
phone: '',
code: '',
division_invite: '',
images: []
},
canvasWidth: '',
canvasHeight: '',
canvasStatus: false,
isSelect: false,
keyCode: '',
id: 0,
showModal: false,
supplierAgreement: '',
tagStyle: {
img: 'width:100%;display:block;'
},
division_apply_explain: ''
};
},
components: {
Verify,
tuiModal
},
mixins: [sendVerifyCode, colors],
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
// #ifndef MP
this.getOrderProduct();
// #endif
}
},
deep: true
}
},
computed: {
...mapGetters(['isLogin', 'divisionApplyPhoneVerify']),
isSelectStar() {
if (this.form.division_name && this.form.name && this.form.phone && this.form.division_invite && this.form.images.length) {
if (this.divisionApplyPhoneVerify && !this.form.code) {
return false;
}
return true;
}
},
headerBg() {
return {
backgroundImage: 'url(' + HTTP_REQUEST_URL + '/statics/images/agent/apply_header.png' + ')'
};
},
mainHeight() {
let { windowHeight } = uni.getWindowInfo();
return windowHeight - 90 - this.sysHeight;
}
},
onLoad(options) {
this.getInfo();
},
methods: {
/*** 删除图片* */
DelPic: function (index) {
let that = this,
pic = this.form.images[index];
that.form.images.splice(index, 1);
that.$set(that.form, 'images', that.form.images);
},
/*** 上传文件 **/
uploadpic: function () {
let that = this;
this.canvasStatus = true;
that.$util.uploadImageChange(
{ count: 8, url: 'upload/image' },
function (res) {
if (that.form.images.length < 8) that.form.images.push(res.data.url);
},
(res) => {
this.canvasStatus = false;
},
(res) => {
this.canvasWidth = res.w;
this.canvasHeight = res.h;
}
);
},
code() {
if (!this.form.phone)
return this.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.form.phone))
return this.$util.Tips({
title: '请输入正确的手机号码'
});
this.$refs.verify.show();
},
success(data) {
this.$refs.verify.hide();
if (this.divisionApplyPhoneVerify) {
getCodeApi()
.then((res) => {
this.keyCode = res.data.key;
this.getCode(data);
})
.catch((res) => {
this.$util.Tips({
title: res
});
});
} else {
this.agentRequest();
}
},
async getCode(data) {
let that = this;
if (!this.form.phone)
return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.form.phone))
return this.$util.Tips({
title: '请输入正确的手机号码'
});
await registerVerify({
phone: that.form.phone,
type: 'agent',
key: that.keyCode,
captchaType: CAPTCHA_TYPE,
captchaVerification: data.captchaVerification
})
.then((res) => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
})
.catch((res) => {
this.$refs.verify.refresh();
that.$util.Tips({
title: res
});
});
},
proviceSelect() {
this.isSelect = !this.isSelect;
},
getInfo() {
userAgentInfo()
.then((res) => {
// if (res.status !== -1) {
// uni.navigateTo({
// url: '/pages/users/agent/state'
// });
// }
let data = res.data;
this.id = data.id || 0;
this.form.division_name = data.division_name || '';
this.form.name = data.name || '';
this.form.phone = data.phone || '';
this.form.division_invite = data.division_invite || '';
this.form.images = data.images || [];
this.division_apply_explain = this.$store.state.app.division_apply_explain;
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
submitSupply() {
if (!this.isSelectStar)
return this.$util.Tips({
title: '请完整填写表单信息'
});
if (!this.isSelect)
return this.$util.Tips({
title: '请阅读并同意协议'
});
if (this.divisionApplyPhoneVerify) {
this.agentRequest();
} else {
this.code();
}
},
agentRequest() {
agentCreateApi(this.id, this.form)
.then((res) => {
uni.navigateTo({
url: '/pages/users/agent/state'
});
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
pageBack() {
uni.reLaunch({
url: '/pages/user/index'
});
},
goRecord() {
uni.navigateTo({
url: '/pages/users/agent/record'
});
},
getAgreement() {
getUserAgreement('agent')
.then((res) => {
this.supplierAgreement = res.data.content;
this.showModal = true;
})
.catch((err) => {
that.$util.Tips({
title: err.msg
});
});
},
hideModal() {
this.showModal = false;
}
}
};
</script>
<style>
.header-top {
width: 100%;
height: 358rpx;
background-size: cover;
}
.rule-btn {
height: 48rpx;
background: rgba(0, 0, 0, 0.15);
border-radius: 24rpx 0 0 24rpx;
position: absolute;
right: 0;
}
.bg-v-gradient {
background: linear-gradient(180deg, #fe7015 0%, #eb3b26 100%);
}
.content-box {
padding: 48rpx 32rpx 40rpx;
}
.code-btn {
border: 1px solid #e93323;
color: #e93323;
border-radius: 28rpx;
}
.upload {
border: 1rpx dashed #ccc;
}
.del-pic {
background-color: #999;
border-radius: 0 16rpx 0 16rpx;
}
.icon-a-ic_CompleteSelect,
.font-red {
color: #e93323;
}
.icon-ic_unselect {
color: #ccc;
}
.bg-red {
background-color: #e93323;
}
.bg-disabled {
background-color: rgba(233, 51, 35, 0.5);
}
.desc-box {
max-height: 700rpx;
overflow-y: auto;
}
.modal-bottom {
height: 136rpx;
border-radius: 0 0 32rpx 32rpx;
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,121 @@
<template>
<view>
<view class="px-20">
<view class="w-full bg--w111-fff rd-24rpx flex-between-center mt-24 p-32"
v-for="(item,index) in list" :key="index">
<view>
<view class="flex-y-center">
<text class="fs-30 lh-42rpx max-300 line1">{{item.system_name}}</text>
<text class="tag tag0 fs-22 ml-16" :class="'tag' + item.status">{{item.status | typeFilter}}</text>
</view>
<view class="fs-24 text--w111-999 mt-20">提交时间:{{item.add_time}}</view>
<view class="fs-24 text--w111-999 mt-20" v-if="item.status==2">原因:{{item.fail_msg}}</view>
</view>
<text class="btn info-btn fs-24" @tap="lookUp(item)" v-if="item.status==1">查看</text>
<text class="btn danger-btn fs-24" @tap="resubmit(item)" v-else-if="item.status==2">重新提交</text>
<text class="btn info-btn fs-24" @tap="edit(item)" v-else>编辑</text>
</view>
<view class="mt-20" v-if="list.length == 0">
<emptyPage title="暂无申请记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
import { recordList } from '@/api/user.js';
import colors from '@/mixins/color.js';
import emptyPage from '@/components/emptyPage.vue';
export default{
mixins: [colors],
components: {
emptyPage,
},
data(){
return{
list:[]
}
},
filters:{
typeFilter(val){
let obj = {
0: '待审核',
1: '审核通过',
2: '审核未通过'
};
return obj[val]
},
},
onLoad(){
this.getList();
},
methods:{
getList(){
recordList().then(res=>{
this.list = res.data;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
edit(item){
uni.navigateTo({
url: '/pages/users/supplier/index?id='+ item.id
})
},
resubmit(item){
uni.navigateTo({
url: '/pages/users/supplier/state?id='+ item.id+'&type=2'
})
},
lookUp(item){
uni.navigateTo({
url: '/pages/users/supplier/state?id='+ item.id+'&type=1'
})
}
}
}
</script>
<style>
.max-300{
max-width: 300rpx;
}
.tag{
height: 38rpx;
padding: 0 8rpx;
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 8rpx;
}
.tag0{
color: rgba(0, 122, 255, 1);
background-color: rgba(0, 122, 255, 0.1);
}
.tag1{
color: rgba(0, 180, 42, 1);
background-color: rgba(0, 180, 42, 0.1);
}
.tag2{
color: rgba(245, 63, 63, 1);
background-color: rgba(245, 63, 63, 0.1);
}
.btn{
height: 56rpx;
padding: 0 24rpx;
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 30rpx;
}
.info-btn{
border: 1px solid #ccc;
color: #333;
}
.danger-btn{
border: 1px solid #e93323;
color: #e93323;
}
</style>

View File

@@ -0,0 +1,564 @@
<template>
<view :style="colorStyle">
<view class="promoter-list">
<view class="header">
<view class='search acea-row row-middle'>
<text class="iconfont icon-ic_search"></text>
<input placeholder='搜索用户名称' placeholder-class='placeholder' v-model="keyword" @confirm="submitForm" confirm-type='search' name="search"></input>
</view>
<!-- <view class='nav acea-row row-around' v-if="brokerageLevel == 2">
<view :class="grade == 0 ? 'item on' : 'item'" @click='setType(0)'>一级({{total}})</view>
<view :class="grade == 1 ? 'item on' : 'item'" @click='setType(1)'>二级({{totalLevel}})</view>
</view> -->
<timeSlot @changeTime="changeTime"></timeSlot>
</view>
<view class='list' v-if="recordList.length">
<view class="top_num">
共 <text class="main_color">{{count}}</text> 位员工,获得佣金<text class="main_color">¥{{price}}</text>
</view>
<view class="itemCon">
<view class='item acea-row row-between-wrapper' v-for="(item,index) in recordList" :key="index">
<view class="picTxt acea-row row-between-wrapper">
<view class='pictrue'>
<image :src='item.avatar'></image>
</view>
<view class='text'>
<view class='name line1'>{{item.nickname}}</view>
<view>加入时间:{{item.spread_time}}</view>
</view>
</view>
<view class="right">
<view><text class='num font-nums'>{{item.childCount ? item.childCount : 0}}</text>人</view>
<view><text class="num">{{item.orderCount ? item.orderCount : 0}}</text>单</view>
<view><text class="num">{{item.numberCount ? item.numberCount : 0}}</text>元</view>
</view>
<view class="item-btn">
<view class="division-percent">
分佣比例:{{ item.division_percent }}%
</view>
<view class="action">
<view class="clear" @click="del(item, index)">删除</view>
<view class="change" @click="changeData(item)">修改分佣比例</view>
</view>
</view>
</view>
</view>
</view>
<view class="empty" v-if="recordList.length == 0">
<emptyPage title="暂无数据~"></emptyPage>
</view>
</view>
<view class="refund-input" :class="refund_close ? 'on' : ''">
<view class="input-msg">
<view class="close">
<text class="iconfont icon-ic_close" @tap="refund_close = false"></text>
</view>
<view class="refund-input-title">修改分佣比例(%)</view>
<view class="refund-input-sty">
<input type="number" v-model="agent_percent" placeholder="请输入百分比" />
</view>
<view class="refund-bth">
<!-- <view class="close-refund" @click="refund_close = false">取消</view> -->
<view class="submit-refund" @click="refundSubmit()">提交</view>
</view>
</view>
</view>
<view class="mask invoice-mask" v-if="refund_close" @click="refund_close = false"></view>
<view class="mark" v-show="isCancellation"></view>
<tui-modal :show="isCancellation" maskClosable custom @cancel="isCancellation = false">
<view class="tui-modal-custom">
<view class="fs-32 fw-500 lh-44rpx text-center">删除员工</view>
<view class="fs-30 text--w111-666 lh-42rpx text-center mt-22">确定删除该员工?</view>
<view class="flex-y-center">
<view class="w-full h-72 rd-36rpx flex-center border b-solid b--w111-ccc text-primary-con fs-26 mt-32 mr-16 clear-btn" @tap="isCancellation = false">取消</view>
<view class="w-full h-72 rd-36rpx flex-center bg-red fs-26 text--w111-fff mt-32 ml-16" @tap="clear">确定</view>
</view>
</view>
</tui-modal>
</view>
</template>
<script>
import {
agentStaffList,
agentDelStaff,
agentStaffPercent
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import emptyPage from '@/components/emptyPage.vue'
import timeSlot from '../components/timeSlot/index.vue'
import colors from '@/mixins/color.js';
import tuiModal from '@/components/tui-modal/index.vue';
export default {
components: {
timeSlot,
emptyPage,
tuiModal
},
mixins: [colors],
data() {
return {
total: 0,
totalLevel: 0,
teamCount: 0,
page: 1,
limit: 20,
keyword: '',
sort: '',
grade: 0,
status: false,
recordList: [],
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
start: 0,
stop: 0,
count: 0,
price: 0,
brokerageLevel: 0,
refund_close:false,
isCancellation:false,
agent_percent: null,
delIndex: 0,
uid: null
};
},
computed: mapGetters(['isLogin']),
onLoad() {
if (this.isLogin) {
this.userSpreadNewList();
} else {
toLogin()
}
},
onShow: function() {
uni.removeStorageSync('form_type_cart');
if (this.is_show) this.userSpreadNewList();
},
onHide: function() {
this.is_show = true;
},
methods: {
changeData(data) {
this.refund_close = true;
this.uid = data.uid;
},
del(data,index){
this.uid = data.uid
this.delIndex = index
this.isCancellation = true
},
clear() {
let that = this;
agentDelStaff(this.uid)
.then((res) => {
that.recordList.splice(this.delIndex, 1);
that.$set(that, 'recordList', that.recordList);
// that.userSpreadNewList();
that.isCancellation = false;
that.teamCount -= 1;
return that.$util.Tips({
title: '删除成功',
icon: 'success'
});
})
.catch((err) => {
return that.$util.Tips({
title: err
});
});
},
refundSubmit() {
if (this.agent_percent < 0) {
return this.$util.Tips({
title: '请输入比例'
});
}
agentStaffPercent({
division_percent: this.agent_percent,
uid: this.uid
})
.then((res) => {
this.$util.Tips(
{
title: res.msg,
icon: 'success'
},
() => {
this.refund_close = false;
this.page = 1;
this.limit = 20;
this.keyword = '';
// this.sort = '';
this.status = false;
this.agent_percent = null;
this.$set(this, 'recordList', []);
this.userSpreadNewList();
}
);
})
.catch((err) => {
this.$util.Tips({
title: err
});
});
},
changeTime(time) {
console.log(time)
this.start = time.start
this.stop = time.stop
this.submitForm()
},
onLoadFun(e) {
this.userSpreadNewList();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
setSort(sort) {
let that = this;
that.sort = sort;
that.page = 1;
that.limit = 20;
that.status = false;
that.$set(that, 'recordList', []);
that.userSpreadNewList();
},
// setKeyword: function(e) {
// this.keyword = e.detail.value;
// },
submitForm: function() {
this.page = 1;
this.limit = 20;
this.status = false;
this.$set(this, 'recordList', []);
this.userSpreadNewList();
},
setType: function(grade) {
if (this.grade != grade) {
this.grade = grade;
this.page = 1;
this.limit = 20;
this.keyword = '';
this.sort = '';
this.status = false;
this.$set(this, 'recordList', []);
this.userSpreadNewList();
}
},
userSpreadNewList: function() {
let that = this;
let page = that.page;
let limit = that.limit;
let status = that.status;
let keyword = that.keyword;
let sort = that.sort;
let grade = that.grade;
let recordList = that.recordList;
let recordListNew = [];
if (status == true) return;
agentStaffList({
start: this.start,
stop: this.stop,
page: page,
limit: limit,
keyword: keyword,
}).then(res => {
let len = res.data.list.length;
let recordListData = res.data.list;
recordListNew = recordList.concat(recordListData);
that.total = res.data.count;
that.teamCount = res.data.count;
that.status = limit > len;
that.page = page + 1;
that.$set(that, 'recordList', recordListNew);
that.count = res.data.count;
that.price = res.data.brokerage;
});
}
},
onReachBottom: function() {
this.userSpreadNewList();
}
}
</script>
<style scoped lang="scss">
.empty{
margin: 20rpx;
}
.font-nums{
color: #E93323;
}
.promoter-list .nav {
background-color: #fff;
height: 92rpx;
line-height: 86rpx;
font-size: 28rpx;
color: #666;
font-family: PingFang SC;
}
.promoter-list .nav .item.on {
color: #E93323;
position: relative;
font-size: 32rpx;
&::after {
position: absolute;
content: '';
width: 38rpx;
height: 30rpx;
border: 2px solid #E93323;
border-left: 2px solid transparent !important;
border-top: 2px solid transparent !important;
border-right: 2px solid transparent !important;
border-radius: 50%;
left: 50%;
margin-left: -24rpx;
bottom: 16rpx;
}
}
.promoter-list .header {
background-color: #fff;
padding-top: 24rpx;
}
.promoter-list .search {
width: 710rpx;
height: 72rpx;
padding: 0 32rpx;
box-sizing: border-box;
background-color: #F5F5F5;
border-radius: 50rpx;
margin: 0 auto 10rpx auto;
.placeholder {
color: #ccc;
font-size: 28rpx;
}
}
.promoter-list .search .iconfont {
font-size: 32rpx;
color: #999;
margin-right: 18rpx;
}
.promoter-list .list {
margin-top: 12rpx;
}
.promoter-list .list .sortNav {
background-color: #fff;
height: 76rpx;
border-bottom: 1rpx solid #eee;
color: #333;
font-size: 28rpx;
}
.promoter-list .list .sortNav .sortItem {
text-align: center;
flex: 1;
}
.promoter-list .list .sortNav .sortItem image {
width: 24rpx;
height: 24rpx;
margin-left: 6rpx;
vertical-align: -3rpx;
}
.promoter-list .list .itemCon {
background-color: #fff;
margin: 0 20rpx;
border-radius: 24rpx;
padding-top: 10rpx;
}
.promoter-list .list .item {
height: 290rpx;
font-size: 24rpx;
color: #666;
margin: 0 24rpx;
}
.promoter-list .list .item .picTxt {
width: 440rpx;
}
.promoter-list .list .item .picTxt .pictrue {
width: 112rpx;
height: 112rpx;
border-radius: 50%;
}
.promoter-list .list .item .picTxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 50%;
}
.promoter-list .list .item .picTxt .text {
width: 304rpx;
font-size: 24rpx;
color: #999;
}
.promoter-list .list .item .picTxt .text .name {
font-size: 28rpx;
color: #333;
margin-bottom: 13rpx;
}
.promoter-list .list .item .right {
width: 190rpx;
text-align: right;
font-size: 24rpx;
color: #333;
}
.promoter-list .list .item .right .num {
margin-right: 7rpx;
}
.top_num {
padding: 14rpx 20rpx 28rpx 20rpx;
font-size: 24rpx;
color: #666;
}
.main_color {
color: #E93323;
margin: 0 6rpx;
}
.item-btn {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fff;
border-top: 1rpx solid #EEEEEE;
padding: 26rpx 0 16rpx 0;
font-size: 24rpx;
.division-percent{
color: #999999;
}
.action{
display: flex;
align-items: center;
}
.clear,
.change {
padding: 10rpx 24rpx;
border-radius: 30rpx;
}
.clear {
border: 1rpx solid #CCCCCC;
color: #333333;
}
.change {
background-color: #E93323;
color: #fff;
margin-left: 16rpx;
}
}
.refund-input {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
border-radius: 40rpx 40rpx 0 0;
background-color: #fff;
z-index: 99;
padding: 40rpx 0 70rpx 0;
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
transform: translate3d(0, 100%, 0);
.refund-input-title {
font-weight: 500;
font-size: 16px;
color: #333333;
font-size: 32rpx;
margin-bottom: 60rpx;
}
.refund-input-sty {
background-color: #F5F5F5;
padding: 20rpx 20rpx;
border-radius: 50rpx;
color: #BBBBBB;
width: 100%;
margin: 0rpx 20rpx 0rpx 20rpx;
text-align: center;
}
/deep/ .uni-input-placeholder,
/deep/ .uni-input-input{
color: #bbb;
text-align: center;
}
.input-msg {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
margin: 0 65rpx;
.close{
position: absolute;
top: 8rpx;
color: #aaa;
font-size: 32rpx;
right: -30rpx;
width: 36rpx;
height: 36rpx;
border-radius: 50%;
margin-top: -18rpx;
background: #EEEEEE;
text-align: center;
line-height: 36rpx;
}
}
.refund-bth {
display: flex;
margin: 0 65rpx;
margin-top: 20rpx;
justify-content: space-around;
width: 100%;
.close-refund {
padding: 24rpx 80rpx;
border-radius: 80rpx;
color: #fff;
background-color: #ccc;
}
.submit-refund {
width: 100%;
padding: 24rpx 0rpx;
text-align: center;
border-radius: 80rpx;
color: #fff;
background-color: #E93323;
}
}
}
.refund-input.on {
transform: translate3d(0, 0, 0);
}
</style>

198
pages/users/agent/state.vue Normal file
View File

@@ -0,0 +1,198 @@
<template>
<view>
<view class="px-20 mt-40">
<view class="bg--w111-fff rd-24rpx card-bg">
<view class="h-244 pt-72">
<view class="px-122 flex-between-center">
<text class="iconfont icon-a-ic_CompleteSelect font-red fs-28"></text>
<view class="line bg-red mx-8"></view>
<text class="iconfont icon-a-ic_CompleteSelect font-red fs-28"></text>
<view class="line mx-8" :class="type > 0 ? 'bg-red' : 'bg-gray'"></view>
<text class="iconfont fs-28" :class="type > 0 ? 'icon-a-ic_CompleteSelect font-red' : 'icon-ic_unselect text--w111-ccc'"></text>
</view>
<view class="flex-between-center px-74 fs-28 lh-40rpx mt-24">
<text>提交成功</text>
<text>正在审核</text>
<text>审核结果</text>
</view>
<view class="flex-between-center px-40 mt-8 fs-22 text--w111-999">
<text>{{ add_time }}</text>
<text>{{ add_time }}</text>
<text v-if="status_time">{{ status_time }}</text>
<text v-else class="w-180"></text>
</view>
</view>
<view class="flex-col flex-center content-box" v-if="!loading">
<image :src="imgHost + '/statics/images/supplier/verify_fail_icon.png'" class="status-pic" v-if="type == 2"></image>
<image :src="imgHost + '/statics/images/supplier/verify_ing_icon.png'" class="status-pic" v-else-if="type == 0"></image>
<image :src="imgHost + '/statics/images/supplier/verify_ok_icon.png'" class="status-pic" v-else-if="type == 1"></image>
<text class="fs-36 lh-50rpx pt-32">{{ type | typeFilter }}</text>
<text class="fs-26 lh-36rpx text--w111-999 pt-12">{{ type | descFilter }}</text>
<text class="fs-26 lh-36rpx text--w111-999 pt-12 pl-24 pr-24" v-if="refusal_reason">{{ refusal_reason }}</text>
<view class="primary-btn flex-center fs-28 mt-40" @tap="edit">{{ type == 2 ? '重新填写' : '返回上一页' }}</view>
<view class="border-btn flex-center fs-28 mt-24" v-if="type == 2" @tap="pageBack">返回上一页</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { HTTP_REQUEST_URL } from '@/config/app';
import colors from '@/mixins/color.js';
import { userAgentInfo, userPromoterInfo } from '@/api/user.js';
export default {
mixins: [colors],
data() {
return {
imgHost: HTTP_REQUEST_URL,
id: 0,
type: 2,
url: '',
account: '',
pwd: '',
status_time: '',
add_time: '',
refusal_reason: '',
ftype: '',
loading: true
};
},
filters: {
typeFilter(val) {
let obj = {
0: '正在审核',
1: '审核通过',
2: '审核失败'
};
return obj[val];
},
descFilter(val) {
let obj = {
0: '正在审核当中,请耐心等待',
1: '恭喜您,审核通过',
2: '请按提示修改您所填写的信息'
};
return obj[val];
}
},
onLoad(options) {
this.id = options.id;
this.ftype = options.type || 0;
this.supplierApply();
},
methods: {
copyWb: function () {
let that = this;
uni.setClipboardData({
data: '网址:' + this.url + '\n账号:' + this.account + '\n密码:' + this.pwd
});
},
supplierApply() {
let api;
this.loading = true;
if (this.ftype === 'promoter') {
// 分销员
api = userPromoterInfo();
} else {
// 代理商
api = userAgentInfo();
}
api
.then((res) => {
let data = this.ftype === 'promoter' ? res.data.user : res.data;
this.type = data.status;
this.add_time = data.add_time;
this.status_time = data.status_time;
this.refusal_reason = data.refusal_reason;
this.loading = false;
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
pageBack() {
uni.switchTab({
url: '/pages/user/index'
})
},
edit() {
if (this.type == 0 || this.type == 1) {
uni.switchTab({
url: '/pages/user/index'
})
} else {
if (this.ftype === 'promoter') {
uni.reLaunch({
url: '/pages/users/distributor/apply?id=' + this.id
});
} else {
uni.reLaunch({
url: '/pages/users/agent/apply?id=' + this.id
});
}
}
}
}
};
</script>
<style scoped>
.card-bg {
-webkit-mask: radial-gradient(circle at 16rpx 240rpx, transparent 16rpx, red 0) -16rpx;
}
.font-red {
color: #e93323;
}
.h-244 {
height: 244rpx;
border-bottom: 1px dashed #ccc;
}
.px-74 {
padding: 0 74rpx;
}
.px-122 {
padding: 0 122rpx;
}
.pt-72 {
padding-top: 72rpx;
}
.line {
width: 186rpx;
height: 1rpx;
}
.bg-red {
background-color: #e93323;
}
.bg-gray {
background-color: #dddddd;
}
.status-pic {
width: 172rpx;
height: 154rpx;
}
.content-box {
padding: 48rpx 0 72rpx;
}
.primary-btn {
width: 502rpx;
height: 88rpx;
background: linear-gradient(90deg, #ff7931 0%, #e93323 100%);
color: #fff;
border-radius: 50rpx;
}
.border-btn {
width: 502rpx;
height: 88rpx;
background: #fff;
border: 1px solid #e93323;
color: #e93323;
border-radius: 50rpx;
}
.copy-btn {
width: 64rpx;
height: 32rpx;
background: #f5f5f5;
border-radius: 20rpx;
}
</style>

View File

@@ -0,0 +1,529 @@
<template>
<view class="wrapper" :style="colorStyle">
<view class="bag">
<img :src="imgHost+'/statics/images/users/login-bg.jpg'" alt="" srcset="">
</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 src="../static/left.png"></image>
</view>
<view class="icon" @click="home" v-else>
<image src="../static/home.png"></image>
</view>
{{pageTitle}}
</view>
<!-- #endif -->
<view class="page-msg">
<view class="title">
{{pageType == 1?'绑定手机号':'手机号登录'}}
</view>
<view class="tip">
{{pageType == 1?'登录注册需绑定手机号':'首次登录会自动注册'}}
</view>
</view>
<view class="page-form">
<view class="item">
<input type='number' placeholder='填写手机号码' placeholder-class='placeholder' v-model="phone"
:maxlength="11"></input>
</view>
<view class="item acea-row row-between-wrapper">
<input type='number' placeholder='填写验证码' placeholder-class='placeholder' :maxlength="6"
class="codeIput" v-model="captcha"></input>
<view class="line">
</view>
<button class="code font-num" :class="disabled === true ? 'on' : ''" :disabled='disabled' @click="code">
{{ text }}
</button>
</view>
<view class="btn" @click="submitData">
{{pageType == 1 ? '绑定手机号' : '立即登录'}}
</view>
</view>
<view class="protocol" >
<checkbox-group @click.stop='ChangeIsDefault'>
<checkbox :class="inAnimation?'trembling':''" @animationend='inAnimation=false'
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="var(--view-theme)" activeBorderColor="var(--view-theme)"
:checked="protocol ? true : false" /> <text @click.stop='ChangeIsDefault'>已阅读并同意</text>
<text class="main-color" @click.stop="privacy('user')">《用户协议》</text>
与<text class="main-color" @click.stop="privacy('privacy')">《隐私协议》</text>
</checkbox-group>
</view>
<Verify @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }"
ref="verify"></Verify>
<!-- #ifdef MP -->
<editUserModal :isShow="isShow" @closeEdit="closeEdit" @editSuccess="editSuccess">
</editUserModal>
<!-- <privacyAgreementPopup v-if="canGetPrivacySetting" @onReject="onReject" @onAgree="onAgree">
</privacyAgreementPopup> -->
<!-- #endif -->
</view>
</template>
<script>
const app = getApp();
let statusBarHeight = uni.getWindowInfo().statusBarHeight + 'px';
import { HTTP_REQUEST_URL, CAPTCHA_TYPE } from '@/config/app';
import sendVerifyCode from "@/mixins/SendVerifyCode";
import colors from '@/mixins/color.js';
import editUserModal from '@/components/eidtUserModal/index.vue'
import privacyAgreementPopup from '@/components/privacyAgreementPopup/index.vue'
import {
bindingUserPhone,
verifyCode,
registerVerify,
updatePhone
} from '@/api/api.js';
import {
getCodeApi,
getUserInfo,
phoneSilenceAuth
} from "@/api/user.js";
import {
phoneLogin,
wechatBindingPhone
} from '@/api/public.js'
import Routine from '@/libs/routine';
import Verify from '../components/verify/verify.vue';
import Cache from '@/utils/cache';
export default {
mixins: [sendVerifyCode, colors],
components: {
Verify,
editUserModal,
privacyAgreementPopup
},
data() {
return {
captchaType: CAPTCHA_TYPE,
imgHost: HTTP_REQUEST_URL,
statusBarHeight: statusBarHeight,
pageType: 1, // 0 登录 1 绑定手机
phone: '',
captcha: '',
text: '获取验证码',
isShow: false,
protocol: false,
inAnimation: false,
authKey: "",
backUrl: "",
pageTitle: '绑定手机号',
configData: Cache.get('BASIC_CONFIG'),
canGetPrivacySetting: false,
}
},
onLoad(options) {
// #ifdef MP
if (wx.getPrivacySetting) {
this.canGetPrivacySetting = true
}
// #endif
if (options.authKey) {
this.authKey = options.authKey
}
this.backUrl = options.backUrl || ''
if (options.pageType) {
this.pageType = options.pageType || 1
this.pageTitle = options.pageType == 1 ? '绑定手机号' : '手机号登录'
}
let pages = getCurrentPages();
let prePage = pages[pages.length - 2];
if (prePage && prePage.route == 'pages/order_addcart/order_addcart') {
this.isHome = true;
} else {
this.isHome = false;
}
},
methods: {
// onAgree() {
// this.protocol = true
// },
submitData() {
let that = this;
if (this.pageType == 0) {
this.isLogin()
return
}
if (!this.rules()) return
if (!this.authKey) {
let key = this.$Cache.get('snsapiKey');
this.phoneAuth(key)
} else {
this.phoneAuth(this.authKey)
}
},
rules() {
let that = this;
if (!this.protocol && this.pageType == 0) {
this.$util.Tips({
title: '请先阅读并同意协议'
});
return false
}
if (!that.phone) {
this.$util.Tips({
title: '请填写手机号码'
});
return false
}
if (!(/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.phone))) {
this.$util.Tips({
title: '请输入正确的手机号码'
});
return false
}
if (!that.captcha) {
this.$util.Tips({
title: '请填写验证码'
});
return false
}
return true
},
isLogin() {
if (!this.rules()) return
uni.showLoading({
title: '正在登录中'
});
Routine.getCode()
.then(code => {
phoneLogin({
code,
spread_spid: app.globalData.spid,
spread_code: app.globalData.code,
phone: this.phone,
captcha: this.captcha,
}).then(res => {
uni.hideLoading();
let time = res.data.expires_time - this.$Cache.time();
this.$store.commit('LOGIN', {
token: res.data.token,
time: time
});
this.getUserInfo(res.data.store_user_avatar);
})
.catch(err => {
uni.hideLoading();
uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
});
})
.catch(err => {
console.log(err)
});
},
phoneAuth(key) {
uni.showLoading({
title: '正在登录中'
});
let met
// #ifdef MP
met = phoneLogin
// #endif
// #ifndef MP
met = wechatBindingPhone
// #endif
met({
phone: this.phone,
captcha: this.captcha,
key
}).then(res => {
let time = res.data.expires_time - this.$Cache.time();
this.$store.commit('LOGIN', {
token: res.data.token,
time: time
});
this.getUserInfo(res.data.store_user_avatar);
}).catch(error => {
uni.hideLoading()
this.$util.Tips({
title: error
})
})
},
/**
* 获取个人用户信息
*/
getUserInfo(new_user) {
let that = this;
getUserInfo().then(res => {
uni.hideLoading();
that.userInfo = res.data;
that.$store.commit('SETUID', res.data.uid);
that.$store.commit('UPDATE_USERINFO', res.data);
if (new_user) {
this.isShow = true
} else {
// #ifdef MP
that.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3,
url: this.configData.wechat_auth_switch ? 2 : 1
});
// #endif
// #ifndef MP
// that.$util.Tips({
// title: '登录成功',
// icon: 'success'
// }, {
// tab: 4,
// url: this.backUrl || '/pages/user/index'
// });
that.wechatPhone();
// #endif
}
});
},
wechatPhone() {
this.$Cache.clear('snsapiKey');
uni.reLaunch({
url: '/pages/user/index'
})
},
success(data) {
this.$refs.verify.hide()
let that = this;
verifyCode().then(res => {
let obj ={
phone: that.phone,
type: 'reset',
key: res.data.key,
captchaType: CAPTCHA_TYPE,
captchaVerification: data.captchaVerification
}
registerVerify(obj)
.then(res => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
}).catch(err => {
this.$refs.verify.refresh()
return that.$util.Tips({
title: err
});
});
});
},
/**
* 发送验证码
*
*/
async code() {
let that = this;
if (!that.phone) return that.$util.Tips({
title: '请填写手机号码'
});
if (!(/^1(3|4|5|7|8|9|6)\d{9}$/i.test(that.phone))) return that.$util.Tips({
title: '请输入正确的手机号码'
});
this.$refs.verify.show();
return;
},
ChangeIsDefault() {
this.$set(this, 'protocol', !this.protocol);
},
closeEdit() {
this.isShow = false
this.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3,
url: 2
});
},
editSuccess() {
this.isShow = false
},
back() {
uni.navigateBack({
delta: this.configData.wechat_auth_switch ? 2 : 1
})
},
privacy(type) {
uni.navigateTo({
url: "/pages/users/privacy/index?type=" + type
})
},
}
}
</script>
<style lang="scss" scoped>
/deep/ checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid var(--view-theme) !important;
background-color: var(--view-theme) !important;
width: 28rpx;
height: 28rpx;
font-size: 24rpx;
color: #fff !important;
}
.wrapper {
background-color: #fff;
min-height: 100vh;
position: relative;
.bag {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 0;
/* #ifdef H5 */
z-index: 0;
/* #endif */
img {
width: 100%;
height: 544rpx;
}
}
.page-msg {
padding-top: 160rpx;
margin-left: 72rpx;
z-index: 2;
position: relative;
.title {
font-size: 48rpx;
font-weight: 500;
color: #333333;
line-height: 68rpx;
}
.tip {
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 40rpx;
}
}
.page-form {
width: 606rpx;
margin: 100rpx auto 0 auto;
z-index: 2;
position: relative;
.item {
width: 100%;
height: 88rpx;
background: #F5F5F5;
border-radius: 45rpx;
padding: 24rpx 48rpx;
margin-bottom: 32rpx;
input {
width: 100%;
height: 100%;
font-size: 32rpx;
}
.placeholder {
color: #BBBBBB;
font-size: 28rpx;
}
input.codeIput {
width: 300rpx;
}
.line {
width: 2rpx;
height: 28rpx;
background: #CCCCCC;
}
.code {
font-size: 28rpx;
color: var(--view-theme);
background-color: rgba(255, 255, 255, 0);
}
.code.on {
color: #BBBBBB !important;
}
}
.btn {
width: 606rpx;
height: 88rpx;
background: var(--view-theme);
border-radius: 200rpx 200rpx 200rpx 200rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 44rpx;
margin-top: 48rpx;
letter-spacing: 1px;
}
}
}
.title-bar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
font-weight: 500;
color: #333333;
line-height: 48rpx;
}
.icon {
position: absolute;
left: 30rpx;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 86rpx;
height: 86rpx;
image {
width: 40rpx;
height: 40rpx;
}
}
.protocol {
position: fixed;
bottom: 52rpx;
left: 0;
width: 100%;
margin: 0 auto;
color: #999999;
font-size: 24rpx;
line-height: 22rpx;
text-align: center;
bottom: calc(52rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
bottom: calc(52rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
.main-color {
color: var(--view-theme);
}
.trembling {
animation: shake 0.6s;
}
}
</style>

View File

@@ -0,0 +1,344 @@
<template>
<view :style="colorStyle">
<view class="CommissionRank">
<!-- #ifdef MP -->
<view
class="accountTitle"
:style="{ 'background-image': 'url(' + imgHost + '/statics/images/brokerage_rank_bg1.png)', height: getHeight.barTop + getHeight.barHeight + 'px' }"
>
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{ height: getHeight.barHeight + 'px' }">
<view>佣金排行</view>
<text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
</view>
</view>
<view :style="{ height: getHeight.barTop + getHeight.barHeight + 'px' }"></view>
<!-- #endif -->
<view class="header" :style="'background-image: url(' + imgHost + '/statics/images/brokerage_rank_bg2.png);'">
<view class="acea-row row-middle">
<view class="left">
<view class="tips" v-if="rankInfo.position">
您目前的排名
<text class="num">{{ rankInfo.position }}</text>
名
</view>
<view class="tips" v-else>您目前暂无排名</view>
</view>
</view>
</view>
<view class="wrapper">
<view class="nav acea-row row-around">
<view class="item" :class="active == index ? 'on' : ''" v-for="(item, index) in navList" :key="index" @click="switchTap(index)">
{{ item }}
</view>
</view>
<view class="list" v-if="rankList.length">
<view class="item acea-row row-between-wrapper" v-for="(item, index) in rankList" :key="index">
<view class="acea-row row-middle">
<view class="num" v-if="index <= 2">
<image :src="'../static/no' + (index + 1) + '.png'"></image>
</view>
<view class="num" v-else>
{{ index + 1 }}
</view>
<view class="pictrue">
<image :src="item.avatar"></image>
</view>
<view class="text line1">{{ item.nickname }}</view>
</view>
<view class="people">¥{{ item.brokerage_price }}</view>
</view>
</view>
<view v-if="!rankList.length">
<emptyPage title="暂无排行榜数据哦~"></emptyPage>
</view>
</view>
<view style="height: 130rpx" v-if="rankInfo.position > 0"></view>
<view class="footer acea-row row-between-wrapper" v-if="rankInfo.position > 0">
<view class="acea-row row-middle">
<view class="me">我</view>
<view class="pictrue">
<image :src="rankInfo.avatar"></image>
</view>
<view class="name line1">{{ rankInfo.nickname }}</view>
<view class="ranking">第{{ rankInfo.position }}名</view>
</view>
<view class="num">¥{{ rankInfo.brokerage_price }}</view>
</view>
</view>
<!-- #ifdef MP -->
<authorize v-if="isShowAuth" @authColse="authColse" @onLoadFun="onLoadFun"></authorize>
<!-- #endif -->
</view>
</template>
<script>
import emptyPage from '@/components/emptyPage.vue';
import { getBrokerageRank } from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import colors from '@/mixins/color';
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
components: {
emptyPage
},
mixins: [colors],
data() {
return {
imgHost: HTTP_REQUEST_URL,
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
navList: ['周排行', '月排行'],
active: 0,
rankInfo: {
position: 0,
avatar: '',
brokerage_price: '',
nickname: ''
},
rankList: [],
page: 1,
limit: 20,
loadend: false,
loading: false,
loadTitle: '加载更多',
type: 'week',
isAuto: false, //没有授权的不会自动授权
isShowAuth: false //是否隐藏授权
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
//#ifndef MP
this.getBrokerageRankList();
//#endif
}
},
deep: true
}
},
onLoad() {
if (this.isLogin) {
this.getBrokerageRankList();
} else {
toLogin();
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
onLoadFun: function () {
this.getBrokerageRankList();
this.isShowAuth = false;
},
// 授权关闭
authColse: function (e) {
this.isShowAuth = e;
},
goarrow(){
uni.navigateBack()
},
switchTap: function (index) {
this.active = index;
this.type = index ? 'month' : 'week';
this.page = 1;
this.loadend = false;
this.$set(this, 'rankList', []);
this.getBrokerageRankList();
},
getBrokerageRankList: function () {
if (this.loadend) return;
if (this.loading) return;
this.loading = true;
this.loadTitle = '';
getBrokerageRank({
page: this.page,
limit: this.limit,
type: this.type
})
.then((res) => {
let list = res.data.rank;
let loadend = list.length < this.limit;
this.rankInfo.avatar = res.data.avatar;
this.rankInfo.brokerage_price = res.data.brokerage_price;
this.rankInfo.nickname = res.data.nickname;
this.rankInfo.position = res.data.position;
this.rankList.push.apply(this.rankList, list);
this.loading = false;
this.loadend = loadend;
this.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
this.$set(this, 'rankList', this.rankList);
this.page += 1;
})
.catch((err) => {
this.loading = false;
this.loadTitle = '加载更多';
});
}
},
onReachBottom() {
this.getBrokerageRankList();
}
};
</script>
<style scoped lang="scss">
.accountTitle {
background-repeat: no-repeat;
background-size: 100% 100%;
position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 99;
.sysTitle {
width: 100%;
position: relative;
font-weight: 500;
color: #fff;
font-size: 30rpx;
.iconfont {
position: absolute;
font-size: 36rpx;
left: 11rpx;
width: 60rpx;
}
}
}
.CommissionRank {
padding-bottom: 30rpx;
.footer {
position: fixed;
height: 128rpx;
background-color: #fff;
font-size: 28rpx;
width: 100%;
bottom: 0;
left: 0;
border-top: 1px solid #eeeeee;
padding: 0 64rpx;
.me {
color: #ff7d00;
}
.pictrue {
width: 80rpx;
height: 80rpx;
margin-left: 48rpx;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.name {
max-width: 164rpx;
margin-left: 24rpx;
}
.ranking {
color: #ff7d00;
margin-left: 16rpx;
}
}
.header {
height: 434rpx;
padding-top: 26rpx;
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
.left {
.tips {
font-size: 28rpx;
font-weight: 400;
color: #ffcb99;
margin: 164rpx 0 0 46rpx;
.num {
font-family: 'SemiBold';
font-size: 40rpx;
margin: 0 8rpx;
}
}
}
}
.wrapper {
width: 710rpx;
background-color: #fff;
border-radius: 20rpx;
margin: -154rpx auto 0 auto;
.nav {
font-size: 28rpx;
font-weight: 400;
color: #999;
.item {
color: #999999;
padding: 32rpx 0 12rpx 0;
&.on {
color: #333;
font-size: 32rpx;
position: relative;
font-weight: 600;
&::after {
position: absolute;
content: '';
width: 56rpx;
height: 4rpx;
background: #e93323;
border-radius: 2rpx;
left: 50%;
margin-left: -28rpx;
bottom: 0;
}
}
}
}
.list {
padding: 0 44rpx 72rpx 28rpx;
.item {
margin-top: 48rpx;
.num {
font-weight: 400;
color: #999;
font-size: 28rpx;
width: 64rpx;
height: 64rpx;
text-align: center;
line-height: 64rpx;
image {
width: 100%;
height: 100%;
display: block;
}
}
.pictrue {
width: 80rpx;
height: 80rpx;
margin-left: 28rpx;
image {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.text {
font-weight: 400;
color: #333333;
font-size: 28rpx;
margin-left: 24rpx;
width: 180rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,47 @@
<template>
<!-- 头部占位 -->
<view>
<!-- #ifdef APP-PLUS || MP -->
<view class="sys-head" :style="{height:sysHeight}"></view>
<!-- #endif -->
<!-- #ifdef MP || APP-PLUS -->
<view class="sys-title">{{title}}</view>
<!-- #endif -->
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight + 'px';
export default {
props: {
title:{
type:String,
default:''
}
},
data() {
return {
sysHeight: sysHeight
}
},
}
</script>
<style scoped>
.sys-title {
z-index: 10;
position: relative;
height: 40px;
line-height: 40px;
font-size: 30rpx;
color: #fff;
background-color: var(--view-theme);
// #ifdef MP || APP-PLUS
text-align: center;
// #endif
}
.sys-head {
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,204 @@
<template>
<!-- 日期组件 -->
<view>
<view class="dataList">
<view class="times">
<view class="item" :class="time == 'all' ? 'on' : ''" @click="setTime('all')">全部</view>
<view class="item" :class="time == 'today' ? 'on' : ''" @click="setTime('today')">今日</view>
<view class="item" :class="time == 'yesterday' ? 'on' : ''" @click="setTime('yesterday')">昨日</view>
<view class="item" :class="time == 'seven' ? 'on' : ''" @click="setTime('seven')">近7日</view>
</view>
<view class="item" :class="time == 'date' ? 'on' : ''" @click="dateTitle">自定义时间 <text
class="iconfont icon-ic_downarrow downarrow"></text></view>
</view>
<uni-calendar ref="calendar" :date="info.date" :insert="info.insert" :lunar="info.lunar"
:startDate="info.startDate" :endDate="info.endDate" :range="info.range" @confirm="confirm"
:showMonth="info.showMonth" />
<view class="mask" @touchmove.prevent v-show="current === true" @click="close"></view>
<Loading :loaded="loaded" :loading="loading"></Loading>
</view>
</template>
<script>
import Loading from '@/components/Loading/index.vue'
import uniCalendar from '../uni-calendar/uni-calendar.vue'
const year = new Date().getFullYear();
const month = new Date().getMonth() + 1;
const day = new Date().getDate();
export default {
components: {
uniCalendar,
Loading
},
data() {
return {
time:'all',
current: false,
loaded: false,
loading: false,
info: {
startDate: '',
endDate: '',
lunar: false,
range: true,
insert: false,
selected: [],
showMonth: false
},
where: {
start: "",
stop: "",
},
}
},
methods: {
close() {
this.current = false;
},
// 日历确定
confirm(e) {
let self = this
let star, stop;
if (e.range.after && e.range.before) {
if (e.range.before > e.range.after) {
star = new Date(e.range.after + ' 00:00:00').getTime() / 1000
stop = new Date(e.range.before + ' 23:59:59').getTime() / 1000
} else {
star = new Date(e.range.before + ' 00:00:00').getTime() / 1000
stop = new Date(e.range.after + ' 23:59:59').getTime() / 1000
}
self.where.start = star
self.where.stop = stop
self.loaded = false;
self.loading = false;
// Promise.all();
this.$emit('changeTime', this.where)
}else{
star = new Date(e.fulldate + ' 00:00:00').getTime() / 1000
stop = new Date(e.fulldate + ' 23:59:59').getTime() / 1000
self.where.start = star
self.where.stop = stop
self.loaded = false;
self.loading = false;
this.$emit('changeTime', this.where)
}
},
dateTitle() {
this.$refs.calendar.open()
this.time = 'date'
},
setTime(time) {
let self = this
this.time = time;
var year = new Date().getFullYear(),
month = new Date().getMonth() + 1,
day = new Date().getDate();
this.tip = 1
this.loaded = false;
this.loading = false;
switch (time) {
case "all":
this.where.start = 0
this.where.stop = 0
this.title = "全部";
this.$emit('changeTime', this.where)
break;
case "today":
this.where.start =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000;
this.where.stop =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
1;
this.title = "今日";
this.$emit('changeTime', this.where)
break;
case "yesterday":
this.where.start =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 -
24 * 60 * 60;
this.where.stop =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 -
1;
this.title = "昨日";
this.$emit('changeTime', this.where)
break;
case "month":
this.where.start =
new Date(year, new Date().getMonth(), 1).getTime() / 1000;
this.where.stop = new Date(year, month, 1).getTime() / 1000 - 1;
this.title = "本月";
this.$emit('changeTime', this.where)
break;
case "seven":
this.where.start =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
7 * 3600 * 24;
this.where.stop =
new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
1;
this.title = "七日";
this.$emit('changeTime', this.where)
break;
// #ifdef MP
case "date":
let star = new Date(self.before).getTime() / 1000
let stop = new Date(self.after).getTime() / 1000
self.where.start = star
self.where.stop = stop
Promise.all([self.getList()]);
this.$emit('changeTime', this.where)
break;
// #endif
}
},
}
}
</script>
<style lang="scss" scoped>
.dataList {
display: flex;
justify-content: space-between;
padding: 24rpx 20rpx;
background-color: #fff;
color: #999;
font-size: 24rpx;
width: 100%;
box-sizing: border-box;
.times {
display: flex;
.item {
margin-right: 20rpx;
background: #F5F5F5;
padding: 8rpx 24rpx;
border-radius: 30rpx;
}
.item.on {
color: #E93323;
background-color: #FCEAE9;
}
}
.item{
padding: 10rpx 0rpx;
}
}
.downarrow {
padding-left: 10rpx;
font-size: 26rpx !important;
}
</style>

View File

@@ -0,0 +1,546 @@
/**
* @1900-2100区间内的公历、农历互转
* @charset UTF-8
* @github https://github.com/jjonline/calendar.js
* @Author Jea杨(JJonline@JJonline.Cn)
* @Time 2014-7-21
* @Time 2016-8-13 Fixed 2033hex、Attribution Annals
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
* @Version 1.0.3
* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
/* eslint-disable */
var calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
/** Add By JJonline@JJonline.Cn**/
0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
0x0d520], // 2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:var count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays: function (y) {
var i; var sum = 348
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
return (sum + this.leapDays(y))
},
/**
* 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth: function (y) { // 闰字编码 \u95f0
return (this.lunarInfo[y - 1900] & 0xf)
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (0、29、30)
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays: function (y) {
if (this.leapMonth(y)) {
return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
}
return (0)
},
/**
* 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-1、29、30)
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays: function (y, m) {
if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-1、28、29、30、31)
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays: function (y, m) {
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
var ms = m - 1
if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
} else {
return (this.solarMonth[ms])
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear: function (lYear) {
var ganKey = (lYear - 3) % 10
var zhiKey = (lYear - 3) % 12
if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
},
/**
* 公历月、日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro: function (cMonth, cDay) {
var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi: function (offset) {
return this.Gan[offset % 10] + this.Zhi[offset % 12]
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
* @return day Number
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm: function (y, n) {
if (y < 1900 || y > 2100) { return -1 }
if (n < 1 || n > 24) { return -1 }
var _table = this.sTermInfo[y - 1900]
var _info = [
parseInt('0x' + _table.substr(0, 5)).toString(),
parseInt('0x' + _table.substr(5, 5)).toString(),
parseInt('0x' + _table.substr(10, 5)).toString(),
parseInt('0x' + _table.substr(15, 5)).toString(),
parseInt('0x' + _table.substr(20, 5)).toString(),
parseInt('0x' + _table.substr(25, 5)).toString()
]
var _calday = [
_info[0].substr(0, 1),
_info[0].substr(1, 2),
_info[0].substr(3, 1),
_info[0].substr(4, 2),
_info[1].substr(0, 1),
_info[1].substr(1, 2),
_info[1].substr(3, 1),
_info[1].substr(4, 2),
_info[2].substr(0, 1),
_info[2].substr(1, 2),
_info[2].substr(3, 1),
_info[2].substr(4, 2),
_info[3].substr(0, 1),
_info[3].substr(1, 2),
_info[3].substr(3, 1),
_info[3].substr(4, 2),
_info[4].substr(0, 1),
_info[4].substr(1, 2),
_info[4].substr(3, 1),
_info[4].substr(4, 2),
_info[5].substr(0, 1),
_info[5].substr(1, 2),
_info[5].substr(3, 1),
_info[5].substr(4, 2)
]
return parseInt(_calday[n - 1])
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth: function (m) { // 月 => \u6708
if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
var s = this.nStr3[m - 1]
s += '\u6708'// 加上月字
return s
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay: function (d) { // 日 => \u65e5
var s
switch (d) {
case 10:
s = '\u521d\u5341'; break
case 20:
s = '\u4e8c\u5341'; break
break
case 30:
s = '\u4e09\u5341'; break
break
default :
s = this.nStr2[Math.floor(d / 10)]
s += this.nStr1[d % 10]
}
return (s)
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
* @param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function (y) {
return this.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
// 年份限定、上限
if (y < 1900 || y > 2100) {
return -1// undefined转换为数字变为NaN
}
// 公历传参最下限
if (y == 1900 && m == 1 && d < 31) {
return -1
}
// 未传参 获得当天
if (!y) {
var objDate = new Date()
} else {
var objDate = new Date(y, parseInt(m) - 1, d)
}
var i; var leap = 0; var temp = 0
// 修正ymd参数
var y = objDate.getFullYear()
var m = objDate.getMonth() + 1
var d = objDate.getDate()
var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
for (i = 1900; i < 2101 && offset > 0; i++) {
temp = this.lYearDays(i)
offset -= temp
}
if (offset < 0) {
offset += temp; i--
}
// 是否今天
var isTodayObj = new Date()
var isToday = false
if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
isToday = true
}
// 星期几
var nWeek = objDate.getDay()
var cWeek = this.nStr1[nWeek]
// 数字表示周几顺应天朝周一开始的惯例
if (nWeek == 0) {
nWeek = 7
}
// 农历年
var year = i
var leap = this.leapMonth(i) // 闰哪个月
var isLeap = false
// 效验闰月
for (i = 1; i < 13 && offset > 0; i++) {
// 闰月
if (leap > 0 && i == (leap + 1) && isLeap == false) {
--i
isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
} else {
temp = this.monthDays(year, i)// 计算农历普通月天数
}
// 解除闰月
if (isLeap == true && i == (leap + 1)) { isLeap = false }
offset -= temp
}
// 闰月导致数组下标重叠取反
if (offset == 0 && leap > 0 && i == leap + 1) {
if (isLeap) {
isLeap = false
} else {
isLeap = true; --i
}
}
if (offset < 0) {
offset += temp; --i
}
// 农历月
var month = i
// 农历日
var day = offset + 1
// 天干地支处理
var sm = m - 1
var gzY = this.toGanZhiYear(year)
// 当月的两个节气
// bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
// 依据12节气修正干支月
var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
if (d >= firstNode) {
gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
}
// 传入的日期的节气与否
var isTerm = false
var Term = null
if (firstNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 2]
}
if (secondNode == d) {
isTerm = true
Term = this.solarTerm[m * 2 - 1]
}
// 日柱 当月一日与 1900/1/1 相差天数
var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
var gzD = this.toGanZhi(dayCyclical + d - 1)
// 该日期所属的星座
var astro = this.toAstro(m, d)
return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
var isLeapMonth = !!isLeapMonth
var leapOffset = 0
var leapMonth = this.leapMonth(y)
var leapDay = this.leapDays(y)
if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
var day = this.monthDays(y, m)
var _day = day
// bugFix 2016-9-25
// if month is leap, _day use leapDays method
if (isLeapMonth) {
_day = this.leapDays(y, m)
}
if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
// 计算农历的时间差
var offset = 0
for (var i = 1900; i < y; i++) {
offset += this.lYearDays(i)
}
var leap = 0; var isAdd = false
for (var i = 1; i < m; i++) {
leap = this.leapMonth(y)
if (!isAdd) { // 处理闰月
if (leap <= i && leap > 0) {
offset += this.leapDays(y); isAdd = true
}
}
offset += this.monthDays(y, i)
}
// 转换闰月农历 需补充该年闰月的前一个月的时差
if (isLeapMonth) { offset += day }
// 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
var calObj = new Date((offset + d - 31) * 86400000 + stmap)
var cY = calObj.getUTCFullYear()
var cM = calObj.getUTCMonth() + 1
var cD = calObj.getUTCDate()
return this.solar2lunar(cY, cM, cD)
}
}
export default calendar

View File

@@ -0,0 +1,152 @@
<template>
<view class="uni-calendar-item__weeks-box" :class="{
'uni-calendar-item--disable':weeks.disable,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
'uni-calendar-item--multiple': weeks.multiple
}"
@click="choiceDate(weeks)">
<view class="uni-calendar-item__weeks-box-item">
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text" :class="{
'uni-calendar-item--isDay-text': weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.date}}</text>
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
}">今天</text>
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--extra':weeks.extraInfo.info,
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.extraInfo.info}}</text>
</view>
</view>
</template>
<script>
export default {
props: {
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
}
.uni-calendar-item__weeks-box-text {
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar-item__weeks-lunar-text {
font-size: $uni-font-size-sm;
color: $uni-text-color;
}
.uni-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 100rpx;
height: 100rpx;
}
.uni-calendar-item__weeks-box-circle {
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: $uni-color-error;
}
.uni-calendar-item--disable {
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
color: $uni-text-color-disable;
}
.uni-calendar-item--isDay-text {
color: $uni-color-primary;
}
.uni-calendar-item--isDay {
background-color: $uni-color-primary;
opacity: 0.8;
color: #fff;
}
.uni-calendar-item--extra {
color: $uni-color-error;
opacity: 0.8;
}
.uni-calendar-item--checked {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--multiple {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
</style>

View File

@@ -0,0 +1,435 @@
<template>
<view class="uni-calendar" @touchmove.stop.prevent="clean">
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="close"></view>
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
<view class="uni-calendar__header-btn-box" @click="close">
<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
</view>
<view class="uni-calendar__header-btn-box" @click="confirm">
<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
</view>
</view>
<view class="uni-calendar__header">
<view class="uni-calendar__header-btn-box" @click="pre">
<view class="iconfont icon-ic_leftarrow"></view>
</view>
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
<view class="uni-calendar__header-btn-box" @click="next">
<view class="iconfont icon-ic_rightarrow"></view>
</view>
<text class="uni-calendar__backtoday" @click="backtoday">回到今天</text>
</view>
<view class="uni-calendar__box">
<view v-if="showMonth" class="uni-calendar__box-bg">
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
</view>
<view class="uni-calendar__weeks">
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">日</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">一</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">二</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">三</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">四</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">五</text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text">六</text>
</view>
</view>
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<uni-calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></uni-calendar-item>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import Calendar from './util.js';
import uniCalendarItem from './uni-calendar-item.vue'
export default {
components: {
uniCalendarItem
},
props: {
/**
* 当前日期
*/
date: {
type: String,
default: ''
},
/**
* 打点日期
*/
selected: {
type: Array,
default () {
return []
}
},
/**
* 是否开启阴历日期
*/
lunar: {
type: Boolean,
default: false
},
/**
* 开始时间
*/
startDate: {
type: String,
default: ''
},
/**
* 结束时间
*/
endDate: {
type: String,
default: ''
},
/**
* 范围
*/
range: {
type: Boolean,
default: false
},
/**
* 插入
*/
insert: {
type: Boolean,
default: true
},
/**
* 是否显示月份背景
*/
showMonth: {
type: Boolean,
default: true
}
},
data() {
return {
show: false,
weeks: [],
calendar: {},
nowDate: '',
aniMaskShow: false
}
},
watch: {
selected(newVal) {
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
this.weeks = this.cale.weeks
}
},
created() {
// 获取日历方法实例
this.cale = new Calendar({
date: this.date,
selected: this.selected,
startDate: this.startDate,
endDate: this.endDate,
range: this.range,
})
this.init(this.cale.date.fullDate)
},
methods: {
// 取消穿透
clean() {},
init(date) {
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(date)
},
open() {
this.show = true
this.$nextTick(() => {
setTimeout(()=>{
this.aniMaskShow = true
},50)
})
},
close() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
}, 300)
})
},
confirm() {
this.setEmit('confirm')
this.close()
},
change() {
if (!this.insert) return
this.setEmit('change')
},
monthSwitch() {
let {
year,
month
} = this.nowDate
this.$emit('monthSwitch', {
year,
month: Number(month)
})
},
setEmit(name) {
let {
year,
month,
date,
fullDate,
lunar,
extraInfo
} = this.calendar
this.$emit(name, {
range: this.cale.multipleStatus,
year,
month,
date,
fulldate: fullDate,
lunar,
extraInfo: extraInfo || {}
})
},
choiceDate(weeks) {
if (weeks.disable) return
this.calendar = weeks
// 设置多选
this.cale.setMultiple(this.calendar.fullDate)
this.weeks = this.cale.weeks
this.change()
},
backtoday() {
this.cale.setMultiple('')
this.cale.setDate(this.date)
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(this.date)
this.change()
},
pre() {
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
this.setDate(preDate)
this.monthSwitch()
},
next() {
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
this.setDate(nextDate)
this.monthSwitch()
},
setDate(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-calendar__mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--mask-show {
opacity: 1
}
.uni-calendar--fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460px);
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--ani-show {
transform: translateY(0);
}
.uni-calendar__content {
background-color: #fff;
}
.uni-calendar__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
height: 50px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 1px;
}
.uni-calendar--fixed-width {
width: 50px;
// padding: 0 15px;
}
.uni-calendar__backtoday {
position: absolute;
right: 0;
top: 25rpx;
padding: 0 5px;
padding-left: 10px;
height: 25px;
line-height: 25px;
font-size: 12px;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
color: $uni-text-color;
background-color: $uni-bg-color-hover;
}
.uni-calendar__header-text {
text-align: center;
width: 100px;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.uni-calendar__header-btn {
width: 10px;
height: 10px;
border-left-color: $uni-text-color-placeholder;
border-left-style: solid;
border-left-width: 2px;
border-top-color: $uni-color-subtitle;
border-top-style: solid;
border-top-width: 2px;
}
.uni-calendar--left {
transform: rotate(-45deg);
}
.uni-calendar--right {
transform: rotate(135deg);
}
.uni-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-calendar__weeks-item {
flex: 1;
}
.uni-calendar__weeks-day {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
height: 45px;
border-bottom-color: #F5F5F5;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar__weeks-day-text {
font-size: 14px;
}
.uni-calendar__box {
position: relative;
}
.uni-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.uni-calendar__box-bg-text {
font-size: 200px;
font-weight: bold;
color: $uni-text-color-grey;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}
</style>

View File

@@ -0,0 +1,327 @@
import CALENDAR from './calendar.js'
class Calendar {
constructor({
date,
selected,
startDate,
endDate,
range
} = {}) {
// 当前日期
this.date = this.getDate(date) // 当前初入日期
// 打点信息
this.selected = selected || [];
// 范围开始
this.startDate = startDate
// 范围结束
this.endDate = endDate
this.range = range
// 多选状态
this.multipleStatus = {
before: '',
after: '',
data: []
}
// 每周日期
this.weeks = {}
this._getWeek(this.date.fullDate)
}
/**
* 获取任意时间
*/
getDate(date, AddDayCount = 0, str = 'day') {
if (!date) {
date = new Date()
}
if (typeof date !== 'object') {
date = date.replace(/-/g, '/')
}
const dd = new Date(date)
switch (str) {
case 'day':
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
break
case 'month':
if (dd.getDate() === 31) {
dd.setDate(dd.getDate() + AddDayCount)
} else {
dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
}
break
case 'year':
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
break
}
const y = dd.getFullYear()
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
return {
fullDate: y + '-' + m + '-' + d,
year: y,
month: m,
date: d,
day: dd.getDay()
}
}
/**
* 获取上月剩余天数
*/
_getLastMonthDays(firstDay, full) {
let dateArr = []
for (let i = firstDay; i > 0; i--) {
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
dateArr.push({
date: beforeDate,
month: full.month - 1,
lunar: this.getlunar(full.year, full.month - 1, beforeDate),
disable: true
})
}
return dateArr
}
/**
* 获取本月天数
*/
_currentMonthDys(dateData, full) {
let dateArr = []
let fullDate = this.date.fullDate
for (let i = 1; i <= dateData; i++) {
let isinfo = false
let nowDate = full.year + '-' + (full.month < 10 ?
full.month : full.month) + '-' + (i < 10 ?
'0' + i : i)
// 是否今天
let isDay = fullDate === nowDate
// 获取打点信息
let info = this.selected && this.selected.find((item) => {
if (this.dateEqual(nowDate, item.date)) {
return item
}
})
// 日期禁用
let disableBefore = true
let disableAfter = true
if (this.startDate) {
let dateCompBefore = this.dateCompare(this.startDate, fullDate)
disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
}
if (this.endDate) {
let dateCompAfter = this.dateCompare(fullDate, this.endDate)
disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
}
let multiples = this.multipleStatus.data
let checked = false
let multiplesStatus = -1
if (this.range) {
if (multiples) {
multiplesStatus = multiples.findIndex((item) => {
return this.dateEqual(item, nowDate)
})
}
if (multiplesStatus !== -1) {
checked = true
}
}
let data = {
fullDate: nowDate,
year: full.year,
date: i,
multiple: this.range ? checked : false,
month: full.month,
lunar: this.getlunar(full.year, full.month, i),
disable: !disableBefore || !disableAfter,
isDay
}
if (info) {
data.extraInfo = info
}
dateArr.push(data)
}
return dateArr
}
/**
* 获取下月天数
*/
_getNextMonthDays(surplus, full) {
let dateArr = []
for (let i = 1; i < surplus + 1; i++) {
dateArr.push({
date: i,
month: Number(full.month) + 1,
lunar: this.getlunar(full.year, Number(full.month) + 1, i),
disable: true
})
}
return dateArr
}
/**
* 设置日期
* @param {Object} date
*/
setDate(date) {
this._getWeek(date)
}
/**
* 获取当前日期详情
* @param {Object} date
*/
getInfo(date) {
if (!date) {
date = new Date()
}
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
return dateInfo
}
/**
* 比较时间大小
*/
dateCompare(startDate, endDate) {
// 计算截止时间
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
if (startDate <= endDate) {
return true
} else {
return false
}
}
/**
* 比较时间是否相等
*/
dateEqual(before, after) {
// 计算截止时间
before = new Date(before.replace('-', '/').replace('-', '/'))
// 计算详细项的截止时间
after = new Date(after.replace('-', '/').replace('-', '/'))
if (before.getTime() - after.getTime() === 0) {
return true
} else {
return false
}
}
/**
* 获取日期范围内所有日期
* @param {Object} begin
* @param {Object} end
*/
geDateAll(begin, end) {
var arr = []
var ab = begin.split('-')
var ae = end.split('-')
var db = new Date()
db.setFullYear(ab[0], ab[1] - 1, ab[2])
var de = new Date()
de.setFullYear(ae[0], ae[1] - 1, ae[2])
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
for (var k = unixDb; k <= unixDe;) {
k = k + 24 * 60 * 60 * 1000
arr.push(this.getDate(new Date(parseInt(k))).fullDate)
}
return arr
}
/**
* 计算阴历日期显示
*/
getlunar(year, month, date) {
return CALENDAR.solar2lunar(year, month, date)
}
/**
* 设置打点
*/
setSelectInfo(data, value) {
this.selected = value
this._getWeek(data)
}
/**
* 获取多选状态
*/
setMultiple(fullDate) {
let {
before,
after
} = this.multipleStatus
if (!this.range) return
if (before && after) {
this.multipleStatus.before = ''
this.multipleStatus.after = ''
this.multipleStatus.data = []
this._getWeek(fullDate)
} else {
if (!before) {
this.multipleStatus.before = fullDate
} else {
this.multipleStatus.after = fullDate
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
} else {
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
}
this._getWeek(fullDate)
}
}
}
/**
* 获取每周数据
* @param {Object} dateData
*/
_getWeek(dateData) {
const {
fullDate,
year,
month,
date,
day
} = this.getDate(dateData)
let firstDay = new Date(year, month - 1, 1).getDay()
let currentDay = new Date(year, month, 0).getDate()
let dates = {
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
nextMonthDays: [], // 下个月开始几天
weeks: []
}
let canlender = []
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
let weeks = {}
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
for (let i = 0; i < canlender.length; i++) {
if (i % 7 === 0) {
weeks[parseInt(i / 7)] = new Array(7)
}
weeks[parseInt(i / 7)][i % 7] = canlender[i]
}
this.canlender = canlender
this.weeks = weeks
}
//静态方法
// static init(date) {
// if (!this.instance) {
// this.instance = new Calendar(date);
// }
// return this.instance;
// }
}
export default Calendar

View File

@@ -0,0 +1,11 @@
import CryptoJS from './crypto-js.js'
/**
* @word 要加密的内容
* @keyWord String 服务器随机返回的关键字
* */
export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
var key = CryptoJS.enc.Utf8.parse(keyWord);
var srcs = CryptoJS.enc.Utf8.parse(word);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,335 @@
<template>
<view class="warp">
<view class="w-full fixed-lt z-20" :style="{ 'padding-top': sysHeight + 'px' }">
<view class="h-80 px-20 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-000" @tap="pageBack"></text>
</view>
</view>
<view class="header-top relative">
<image :src="headerBg" mode=""></image>
<!-- <view class="rule-btn w-124 flex-center fs-24 text--w111-fff" :style="{ top: 100 + sysHeight + 'px' }" @tap="goRecord">申请记录</view> -->
</view>
<view class="bg-v-gradient pl-20 pr-20 pb-24 relative">
<view class="bg--w111-fff rd-24rpx content-box">
<view class="fs-30 fw-500 lh-42rpx">请填写以下信息</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">用户昵称</view>
<view class="fs-28 text-right">{{ form.nickname }}</view>
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">用户ID</view>
<view class="fs-28 text-right">{{ form.uid }}</view>
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">分销员姓名</view>
<input type="text" v-model="form.real_name" placeholder="请输入分销员姓名" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">手机号</view>
<input type="number" v-model="form.phone" placeholder="请输入手机号" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view v-if="brokerageApplyPhoneVerify" class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">验证码</view>
<view class="flex-y-center">
<input type="number" v-model="form.code" placeholder="请输入验证码" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
<button class="code-btn w-168 h-56 flex-center fs-24 ml-20" :disabled="disabled" @tap="code">{{ text }}</button>
</view>
</view>
<view class="cell mt-64">
<view class="fs-28 lh-40rpx">申请说明</view>
<view class="text--w111-ccc mt-12">
{{ brokerage_apply_explain }}
</view>
</view>
<view class="flex-y-center mt-100rpx mb-24">
<text class="iconfont fs-30" :class="isSelect ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'" @tap="proviceSelect"></text>
<text class="fs-24 text--w111-999 pl-12">已阅读并同意</text>
<text class="fs-24 font-red" @tap="getAgreement">《分销说明》</text>
</view>
<view class="w-full h-88 rd-44rpx flex-center text--w111-fff fs-28" :class="isSelectStar ? 'bg-red' : 'bg-disabled'" @tap="submitSupply">提交申请</view>
</view>
</view>
<Verify @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }" ref="verify"></Verify>
<tui-modal :show="showModal" maskClosable custom @cancel="hideModal">
<view class="tui-modal-custom">
<view class="fs-32 fw-500 lh-44rpx text-center">分销说明</view>
<view class="fs-28 text--w111-666 lh-44rpx mt-24 desc-box">
<!-- #ifdef MP-WEIXIN -->
<rich-text :nodes="supplierAgreement"></rich-text>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view v-html="supplierAgreement"></view>
<!-- #endif -->
</view>
<view class="w-full h-72 rd-36rpx flex-center bg-red fs-26 text--w111-fff mt-32" @tap="hideModal">知道了</view>
</view>
</tui-modal>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import { promoterCreateApi, getCodeApi, registerVerify, userPromoterInfo, getUserAgreement } from '@/api/user.js';
import colors from '@/mixins/color';
import sendVerifyCode from '@/mixins/SendVerifyCode';
import { HTTP_REQUEST_URL, CAPTCHA_TYPE } from '@/config/app';
import Verify from '../components/verify/verify.vue';
import tuiModal from '@/components/tui-modal/index.vue';
export default {
data() {
return {
captchaType: CAPTCHA_TYPE,
sysHeight: sysHeight,
form: {
nickname: '',
uid: '',
phone: '',
code: '',
real_name: ''
},
canvasWidth: '',
canvasHeight: '',
canvasStatus: false,
isSelect: false,
keyCode: '',
id: 0,
showModal: false,
supplierAgreement: '',
tagStyle: {
img: 'width:100%;display:block;'
},
brokerage_apply_explain: ''
};
},
components: {
Verify,
tuiModal
},
mixins: [sendVerifyCode, colors],
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
// #ifndef MP
this.getOrderProduct();
// #endif
}
},
deep: true
}
},
computed: {
...mapGetters(['isLogin', 'brokerageApplyPhoneVerify']),
isSelectStar() {
if (this.form.nickname && this.form.uid && this.form.phone && this.form.real_name) {
if (this.brokerageApplyPhoneVerify && !this.form.code) {
return false;
}
return true;
}
},
headerBg() {
return HTTP_REQUEST_URL + '/statics/images/promoter_apply.png';
},
mainHeight() {
let { windowHeight } = uni.getWindowInfo();
return windowHeight - 90 - this.sysHeight;
}
},
onLoad(options) {
this.getInfo();
},
methods: {
code() {
if (!this.form.phone)
return this.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.form.phone))
return this.$util.Tips({
title: '请输入正确的手机号码'
});
this.$refs.verify.show();
},
success(data) {
this.$refs.verify.hide();
if (this.brokerageApplyPhoneVerify) {
getCodeApi()
.then((res) => {
this.keyCode = res.data.key;
this.getCode(data);
})
.catch((res) => {
this.$util.Tips({
title: res
});
});
} else {
this.promoterRequest();
}
},
async getCode(data) {
let that = this;
if (!this.form.phone)
return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.form.phone))
return this.$util.Tips({
title: '请输入正确的手机号码'
});
await registerVerify({
phone: that.form.phone,
type: 'agent',
key: that.keyCode,
captchaType: CAPTCHA_TYPE,
captchaVerification: data.captchaVerification
})
.then((res) => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
})
.catch((res) => {
this.$refs.verify.refresh();
that.$util.Tips({
title: res
});
});
},
proviceSelect() {
this.isSelect = !this.isSelect;
},
getInfo() {
userPromoterInfo()
.then((res) => {
let data = res.data.user;
this.id = data.id || 0;
this.form.nickname = data.nickname || '';
this.form.uid = data.uid || '';
this.form.phone = data.phone || '';
this.form.real_name = data.real_name || '';
this.supplierAgreement = res.data.agreement.content;
this.brokerage_apply_explain = this.$store.state.app.brokerage_apply_explain;
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
submitSupply() {
if (!this.isSelectStar)
return this.$util.Tips({
title: '请完整填写表单信息'
});
if (!this.isSelect)
return this.$util.Tips({
title: '请阅读并同意协议'
});
if (this.brokerageApplyPhoneVerify) {
this.promoterRequest();
} else {
this.code();
}
},
promoterRequest() {
promoterCreateApi(this.id, this.form)
.then((res) => {
uni.navigateTo({
url: '/pages/users/agent/state?type=promoter&id=' + res.data.id
});
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
pageBack() {
uni.reLaunch({
url: '/pages/user/index'
});
},
goRecord() {
uni.navigateTo({
url: '/pages/users/agent/record'
});
},
getAgreement() {
this.showModal = true;
},
hideModal() {
this.showModal = false;
}
}
};
</script>
<style lang="scss" scoped>
.warp {
background: #ffe5d5;
min-height: 100vh;
.bg-v-gradient {
margin-top: -150rpx;
z-index: 11;
}
}
.header-top {
width: 100%;
height: 552rpx;
image {
width: 100%;
height: 100%;
}
}
.rule-btn {
height: 48rpx;
background: rgba(0, 0, 0, 0.15);
border-radius: 24rpx 0 0 24rpx;
position: absolute;
right: 0;
}
.content-box {
padding: 48rpx 32rpx 40rpx;
}
.code-btn {
border: 1px solid #e93323;
color: #e93323;
border-radius: 28rpx;
}
.upload {
border: 1rpx dashed #ccc;
}
.del-pic {
background-color: #999;
border-radius: 0 16rpx 0 16rpx;
}
.icon-a-ic_CompleteSelect,
.font-red {
color: #e93323;
}
.icon-ic_unselect {
color: #ccc;
}
.bg-red {
background-color: #e93323;
}
.bg-disabled {
background-color: rgba(233, 51, 35, 0.5);
}
.desc-box {
max-height: 700rpx;
overflow-y: auto;
}
.modal-bottom {
height: 136rpx;
border-radius: 0 0 32rpx 32rpx;
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,215 @@
<template>
<view>
<NavBar textSize="34rpx" :isScrolling="isScrolling" iconColor="#333333" textColor="#333333" :showEmpty="false" showBack></NavBar>
<view class="w-full cover relative" :style="[topCardStyle]">
<text class="full-text fs-26 fw-500">商城消费满{{brokeragePrice}}元,即可成为分销员~</text>
</view>
<view class="w-full cover content-box" :style="[contentBg]">
<view class="cover fuli-card relative px-24" :style="[fuliBg]">
<view class="desc flex-y-center text--w111-fff fs-24 lh-40rpx" @tap="lookInfo">
<text class="iconfont icon-icon_tip fs-24"></text>
<text class="pl-8">分销说明</text>
</view>
<view class="grid-column-4 grid-gap-30rpx">
<view class="w-full h-180 rd-16rpx grid-item flex-col flex-center"
v-for="(item,index) in menus" :key="index">
<view class="w-80 h-80 rd-24rpx bg--w111-fff flex-center">
<image :src="item.pic" class="w-58 h-58"></image>
</view>
<text class="pt-24 fs-24 fw-500 lh-36rpx">{{item.label}}</text>
</view>
</view>
</view>
<view class="relative man-card rd-32rpx bg--w111-fff">
<view class="w-full cover h-152 flex-x-center pt-42" :style="[colorBox]">
<image class="text-pic" :src="imgHost + '/statics/images/promoter/promoter_text.png'" mode="aspectFill"></image>
</view>
<view class="w-full relative px-24 pro-box">
<view class="w-full grid-column-3 grid-gap-24rpx" v-if="hostProduct.length">
<view class="w-full" v-for="item in hostProduct" :key="item.id"
@tap="goDetail(item)">
<easy-loadimage
:image-src="item.image"
width="100%"
height="202rpx"
borderRadius="16rpx"></easy-loadimage>
<view class="w-200 line1 mt-16 mb-10">{{item.store_name}}</view>
<BaseMoney :money="item.price" symbolSize="20" integerSize="36" decimalSize="24" color="#e93323"></BaseMoney>
</view>
</view>
<view v-else>
<emptyPage title="暂无数据哦~"></emptyPage>
</view>
</view>
</view>
<view class="h-200"></view>
</view>
<view class="pb-safe w-full fixed-lb flex-center">
<view class="home-btn cover flex-center text--w111-fff fs-28 fw-500" :style="[btnBgStyle]"
@tap="goHomePage">
<text>进入商城,挑选更多商品</text>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
</view>
</view>
</template>
<script>
import { getProductHot } from '@/api/store.js';
import {HTTP_REQUEST_URL} from '@/config/app';
import { mapGetters } from 'vuex';
import { goShopDetail } from '@/libs/order.js'
import NavBar from "@/components/NavBar.vue";
import home from '@/components/home/index.vue';
import emptyPage from '@/components/emptyPage.vue'
let sysHeight = uni.getWindowInfo().statusBarHeight;
export default {
data(){
return {
imgHost: HTTP_REQUEST_URL,
isScrolling: false,
menus:[
{label: '零成本', pic: HTTP_REQUEST_URL + '/statics/images/promoter/promoter_group3.png'},
{label: '高佣金', pic: HTTP_REQUEST_URL + '/statics/images/promoter/promoter_group6.png'},
{label: '持续收入', pic: HTTP_REQUEST_URL + '/statics/images/promoter/promoter_group1.png'},
{label: '佣金提现', pic: HTTP_REQUEST_URL + '/statics/images/promoter/promoter_group2.png'},
],
hotPage:1,
hotLimit:10,
hotScroll: false,
hostProduct: []
}
},
components: { home, NavBar, emptyPage },
computed:{
...mapGetters(['isLogin']),
brokeragePrice(){
return this.$store.state.app.store_brokerage_price
},
topCardStyle(){
return {
height: '646rpx',
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/promoter_group5.png'+')'
}
},
contentBg(){
return {
height: '1474rpx',
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/promoter_group4.png'+')'
}
},
fuliBg(){
return {
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/promoter_card.png'+')'
}
},
colorBox(){
return {
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/promoter_color1.png'+')'
}
},
btnBgStyle(){
return {
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/promoter_button.png'+')'
}
}
},
onPageScroll(option) {
uni.$emit('scroll');
if (option.scrollTop > 50) {
this.isScrolling = true;
} else if (option.scrollTop < 50) {
this.isScrolling = false;
}
},
onLoad() {
this.getRecommendList();
},
methods:{
getRecommendList(){
let that = this;
if (that.hotScroll) return
getProductHot(
that.hotPage,
that.hotLimit,
).then(res => {
that.hotPage++
that.hotScroll = res.data.length < that.hotLimit
that.hostProduct = that.hostProduct.concat(res.data)
});
},
goDetail(item){
goShopDetail(item, this.uid).catch(res => {
uni.navigateTo({
url: `/pages/goods_details/index?id=${item.id}`
});
});
},
lookInfo(){
uni.navigateTo({
url: '/pages/users/user_distribution_info/index'
})
},
goHomePage(){
uni.switchTab({
url: '/pages/goods_cate/goods_cate'
})
}
},
onReachBottom() {
this.getRecommendList();
}
}
</script>
<style>
page{
background: #FBE7D8;
}
</style>
<style scoped lang="scss">
.cover{
background-size: cover;
}
.full-text{
position: absolute;
bottom: 220rpx;
left: 44rpx;
color: #FF6270;
}
.content-box{
position: relative;
margin-top: -204rpx;
padding-top: 78rpx;
}
.fuli-card{
width: 702rpx;
height: 316rpx;
margin: auto;
padding-top: 105rpx;
.desc{
position: absolute;
top: 24rpx;
right: 40rpx;
}
}
.man-card{
width: 702rpx;
margin: 20rpx auto;
}
.text-pic{
width: 256rpx;
height: 40rpx;
}
.grid-item{
background: #FFF6EF;
border: 2rpx solid #FFF2DE;
color: #6A251F;
}
.pro-box{
top: -38rpx;
}
.home-btn{
width: 480rpx;
height: 80rpx;
margin-bottom: 24rpx;
}
</style>

885
pages/users/login/index.vue Normal file
View File

@@ -0,0 +1,885 @@
<template>
<view class="wrapper" :style="colorStyle">
<view class="bag">
<img :src="imgHost+'/statics/images/users/login-bg.jpg'" alt="" srcset="">
</view>
<!-- #ifdef MP -->
<view class="title-bar" style="height: 43px;">
<view class="icon" @click="back" v-if="!isHome">
<image src="../static/left.png"></image>
</view>
<view class="icon" @click="home" v-else>
<image src="../static/home.png"></image>
</view>
{{pageTitle}}
</view>
<!-- #endif -->
<view class="page-msg">
<view class="title">
{{current ? '快速登录' :'账号登录'}}
</view>
<view class="tip">
首次登录会自动注册
</view>
</view>
<view class="page-form">
<view class="item">
<input type='number' placeholder='请输入手机号码' placeholder-class='placeholder' v-model="account"
:maxlength="11" :adjust-position="false"></input>
</view>
<view class="item acea-row row-between-wrapper" v-if="!current">
<input type='password' placeholder='请输入密码' placeholder-class='placeholder'
class="codeIput" v-model="password" :adjust-position="false"></input>
<view class="line"></view>
<navigator class="code font-num" hover-class="none" url="/pages/users/retrievePassword/index">
忘记密码
</navigator>
</view>
<view class="item acea-row row-between-wrapper" v-else>
<input type='number' placeholder='请输入验证码' placeholder-class='placeholder' :maxlength="6"
class="codeIput" v-model="captcha"></input>
<view class="line">
</view>
<button class="code font-num" :class="disabled === true ? 'on' : ''" :disabled='disabled' @click="code">
{{ text }}
</button>
</view>
<view class="btn" @click="submitData">
立即登录
</view>
<view class="text-center fs-32 text--w111-999 mt-32" @click="current = !current">{{current ? '账号登录' :'手机号登录'}}</view>
<!-- #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-ic_wechat"></span>
</view>
<view class="btn pingguo" @click="appleLogin" v-if="appleShow">
<view class="iconfont icon-ic_apple"></view>
</view>
</view>
</view>
<!-- #endif -->
</view>
<view class="protocol">
<checkbox-group @click.stop='ChangeIsDefault'>
<checkbox :class="inAnimation?'trembling':''"
@animationend='inAnimation=false'
:checked="protocol ? true : false"
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="var(--view-theme)"
activeBorderColor="var(--view-theme)"/> <text @click.stop='ChangeIsDefault'>已阅读并同意</text>
<text class="main-color" @click.stop="privacy('user')">《用户协议》</text>
与<text class="main-color" @click.stop="privacy('privacy')">《隐私协议》</text>
</checkbox-group>
</view>
<Verify v-if="!disabled" @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }"
ref="verify"></Verify>
</view>
</template>
<script>
import sendVerifyCode from "@/mixins/SendVerifyCode";
import {
loginH5,
loginMobile,
registerVerify,
register,
getCodeApi,
getUserInfo,
appleLogin
} from "@/api/user";
import attrs, {
required,
alpha_num,
chs_phone
} from "@/utils/validate";
import {
getLogo
} from "@/api/public";
// import cookie from "@/utils/store/cookie";
import {
VUE_APP_API_URL
} from "@/utils";
// #ifdef APP-PLUS
import {
wechatAppAuth
} from '@/api/api.js'
// #endif
const BACK_URL = "login_back_url";
import colors from '@/mixins/color.js';
import Verify from '../components/verify/verify.vue';
import { HTTP_REQUEST_URL, CAPTCHA_TYPE } from '@/config/app';
export default {
name: "Login",
components: {
Verify
},
mixins: [sendVerifyCode, colors],
data: function() {
return {
captchaType: CAPTCHA_TYPE,
inAnimation: false,
protocol: false,
imgHost: HTTP_REQUEST_URL,
navList: ["快速登录", "账号登录"],
current: true,
account: "",
password: "",
captcha: "",
formItem: 1,
type: "login",
logoUrl: "",
keyCode: "",
codeUrl: "",
codeVal: "",
isShowCode: false,
appLoginStatus: false, // 微信登录强制绑定手机号码状态
appUserInfo: null, // 微信登录保存的用户信息
appleLoginStatus: false, // 苹果登录强制绑定手机号码状态
appleUserInfo: null,
appleShow: false, // 苹果登录版本必须要求ios13以上的
keyLock: true,
copyrightContext:'',
};
},
watch: {
formItem: function(nval, oVal) {
if (nval == 1) {
this.type = 'login'
} else {
this.type = 'register'
}
}
},
onLoad() {
let self = this
uni.getSystemInfo({
success: (res) => {
if (res.platform.toLowerCase() == 'ios' && this.getSystem(res.system)) {
self.appleShow = true
}
}
});
},
mounted() {
// this.getCode();
this.getLogoImage();
},
methods: {
domainTap(url){
// #ifdef H5
location.href = url
// #endif
// #ifdef MP || APP-PLUS
uni.navigateTo({
url: `/pages/annex/web_view/index?url=${url}`
});
// #endif
},
changeMsg() {
this.inAnimation = true;
},
ChangeIsDefault(e) {
this.$set(this, 'protocol', !this.protocol);
},
// IOS 版本号判断
getSystem(system) {
let str
system.toLowerCase().indexOf('ios') === -1 ? str = system : str = system.split(' ')[1]
if (str.indexOf('.'))
return str.split('.')[0] >= 13
return str >= 13
},
// 苹果登录
appleLogin() {
let self = this
this.account = ''
this.captcha = ''
if (!self.protocol) {
this.inAnimation = true
return self.$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.showToast({
title: '获取用户信息失败',
icon: 'none',
duration: 2000
})
},
complete() {
uni.hideLoading()
}
});
},
fail(error) {
console.log(error)
}
})
},
// 苹果登录Api
appleLoginApi() {
let self = this
appleLogin({
openId: self.appleUserInfo.openId,
email: self.appleUserInfo.email || '',
phone: this.account,
captcha: this.captcha
}).then(({
data
}) => {
if (data.isbind) {
uni.showModal({
title: '提示',
content: '请绑定手机号后,继续操作',
showCancel: false,
success: function(res) {
if (res.confirm) {
self.current = true
self.appleLoginStatus = true
}
}
});
} else {
self.$store.commit("LOGIN", {
'token': data.token,
'time': data.expires_time - self.$Cache.time()
});
let backUrl = self.$Cache.get(BACK_URL) || "/pages/index/index";
self.$Cache.clear(BACK_URL);
self.$store.commit("SETUID", data.userInfo.uid);
self.$store.commit("UPDATE_USERINFO", data.userInfo);
uni.reLaunch({
url: backUrl
});
}
}).catch(error => {
uni.showModal({
title: '提示',
content: `错误信息${error}`,
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
})
},
// App微信登录
wxLogin() {
if (!this.protocol) {
this.inAnimation = true
return this.$util.Tips({
title: '请先阅读并同意协议'
});
}
let self = this
this.account = ''
this.captcha = ''
uni.showLoading({
title: '登录中'
})
uni.login({
provider: 'weixin',
success: function(loginRes) {
// 获取用户信息
uni.getUserInfo({
provider: 'weixin',
success: function(infoRes) {
self.appUserInfo = infoRes.userInfo
self.wxLoginApi()
},
fail() {
uni.showToast({
title: '获取用户信息失败',
icon: 'none',
duration: 2000
})
},
complete() {
uni.hideLoading()
}
});
},
fail() {
uni.showToast({
title: '登录失败',
icon: 'none',
duration: 2000
})
}
});
},
submitData(){
if(this.current){
this.loginMobile()
}else{
this.submit()
}
},
wxLoginApi() {
let self = this
wechatAppAuth({
userInfo: self.appUserInfo,
phone: this.account,
code: this.captcha
}).then(({
data
}) => {
if (data.isbind) {
uni.showModal({
title: '提示',
content: '请绑定手机号后,继续操作',
showCancel: false,
success: function(res) {
if (res.confirm) {
self.current = true
self.appLoginStatus = true
}
}
});
} else {
self.$store.commit("LOGIN", {
'token': data.token,
'time': data.expires_time - self.$Cache.time()
});
let backUrl = self.$Cache.get(BACK_URL) || "/pages/index/index";
self.$Cache.clear(BACK_URL);
self.$store.commit("SETUID", data.userInfo.uid);
self.$store.commit("UPDATE_USERINFO", data.userInfo);
uni.reLaunch({
url: backUrl
});
}
}).catch(error => {
uni.showModal({
title: '提示',
content: `错误信息${error}`,
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
})
},
again() {
this.codeUrl =
VUE_APP_API_URL +
"/sms_captcha?" +
"key=" +
this.keyCode +
Date.parse(new Date());
},
success(data) {
this.$refs.verify.hide()
getCodeApi()
.then(res => {
this.keyCode = res.data.key;
this.getCode(data);
})
.catch(res => {
this.$util.Tips({
title: res
});
});
},
code() {
let that = this
if (!that.protocol) {
this.inAnimation = true
return that.$util.Tips({
title: '请先阅读并同意协议'
});
}
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: '请输入正确的手机号码'
});
// getCodeApi()
// .then(res => {
// that.keyCode = res.data.key;
// that.getCode();
// })
// .catch(res => {
// that.$util.Tips({
// title: res
// });
// });
this.$refs.verify.show()
},
async getLogoImage() {
let that = this;
getLogo(2).then(res => {
that.logoUrl = res.data.logo_url;
that.copyrightContext = res.data.copyrightContext;
});
},
async loginMobile() {
let that = this;
if (!that.protocol) {
this.inAnimation = true
return that.$util.Tips({
title: '请先阅读并同意协议'
});
}
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.appLoginStatus) {
that.wxLoginApi()
} else if (that.appleLoginStatus) {
that.appleLoginApi()
} else {
if (this.keyLock) {
this.keyLock = !this.keyLock
} else {
return that.$util.Tips({
title: '请勿重复点击'
});
}
loginMobile({
phone: that.account,
captcha: that.captcha,
spread_spid: that.$Cache.get("spread")
})
.then(res => {
let data = res.data;
that.$store.commit("LOGIN", {
'token': data.token,
'time': data.expires_time - this.$Cache.time()
});
let backUrl = that.$Cache.get(BACK_URL) || "/pages/index/index";
that.$Cache.clear(BACK_URL);
getUserInfo().then(res => {
this.keyLock = true
that.$store.commit("SETUID", res.data.uid);
that.$store.commit("UPDATE_USERINFO", res.data);
if (backUrl.indexOf('/pages/users/login/index') !== -1) {
backUrl = '/pages/index/index';
}
uni.reLaunch({
url: backUrl
});
})
})
.catch(res => {
this.keyLock = true
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.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-z]|[A-Z]){0,6}$/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")
})
.then(res => {
that.$util.Tips({
title: res
});
that.formItem = 1;
})
.catch(res => {
that.$util.Tips({
title: res
});
});
},
async getCode(data){
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.formItem == 2) that.type = "register";
await registerVerify({
phone: that.account,
type: that.type,
key: that.keyCode,
captchaType: CAPTCHA_TYPE,
captchaVerification: data.captchaVerification
})
.then(res => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
})
.catch(res => {
this.$refs.verify.refresh()
that.$util.Tips({
title: res
});
});
},
async submit() {
let that = this;
if (!that.protocol) {
this.inAnimation = true
return that.$util.Tips({
title: '请先阅读并同意协议'
});
}
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 (this.keyLock) {
this.keyLock = !this.keyLock
} else {
return that.$util.Tips({
title: '请勿重复点击'
});
}
loginH5({
account: that.account,
password: that.password,
spread_spid: that.$Cache.get("spread")
})
.then(({
data
}) => {
that.$store.commit("LOGIN", {
'token': data.token,
'time': data.expires_time - this.$Cache.time()
});
let backUrl = that.$Cache.get(BACK_URL) || "/pages/index/index";
that.$Cache.clear(BACK_URL);
getUserInfo().then(res => {
this.keyLock = true
that.$store.commit("SETUID", res.data.uid);
that.$store.commit("UPDATE_USERINFO", res.data);
uni.reLaunch({
url: backUrl
});
}).catch(error => {
this.keyLock = true
})
})
.catch(e => {
this.keyLock = true
that.$util.Tips({
title: e
});
});
},
privacy(type) {
uni.navigateTo({
url: "/pages/users/privacy/index?type=" + type
})
}
}
};
</script>
<style lang="scss" scoped>
/deep/ checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid var(--view-theme) !important;
background-color: var(--view-theme) !important;
width: 28rpx;
height: 28rpx;
font-size: 24rpx;
color: #fff !important;
}
.wrapper {
background-color: #fff;
min-height: 100vh;
position: relative;
.bag {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 0;
/* #ifdef H5 */
z-index: 0;
/* #endif */
img {
width: 100%;
height: 544rpx;
}
}
.page-msg {
padding-top: 160rpx;
margin-left: 72rpx;
z-index: 2;
position: relative;
.title {
font-size: 48rpx;
font-weight: 500;
color: #333333;
line-height: 68rpx;
}
.tip {
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 40rpx;
}
}
.page-form {
width: 606rpx;
margin: 100rpx auto 0 auto;
z-index: 2;
position: relative;
.item {
width: 100%;
height: 88rpx;
background: #F5F5F5;
border-radius: 45rpx;
padding: 24rpx 48rpx;
margin-bottom: 32rpx;
input {
width: 100%;
height: 100%;
font-size: 32rpx;
}
.placeholder {
color: #BBBBBB;
font-size: 28rpx;
}
input.codeIput {
width: 300rpx;
}
.line {
width: 2rpx;
height: 28rpx;
background: #CCCCCC;
}
.code {
font-size: 28rpx;
color: var(--view-theme);
background-color: rgba(255, 255, 255, 0);
}
.code.on {
color: #BBBBBB !important;
}
}
.btn {
width: 606rpx;
height: 88rpx;
background: var(--view-theme);
border-radius: 200rpx 200rpx 200rpx 200rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 44rpx;
margin-top: 48rpx;
letter-spacing: 1px;
}
}
}
.title-bar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
font-weight: 500;
color: #333333;
line-height: 48rpx;
}
.icon {
position: absolute;
left: 30rpx;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 80rpx;
height: 80rpx;
image {
width: 35rpx;
height: 35rpx;
}
}
.protocol {
position: fixed;
bottom: 52rpx;
left: 0;
width: 100%;
margin: 0 auto;
color: #999999;
font-size: 24rpx;
line-height: 22rpx;
text-align: center;
bottom: calc(52rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
bottom: calc(52rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
.main-color {
color: var(--view-theme);
}
.trembling {
animation: shake 0.6s;
}
}
.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;
width: 246rpx;
height: 66rpx;
margin-left: 30rpx;
background: #EAEAEA;
border-radius: 34rpx;
font-size: 24rpx;
.icon-s-pingguo {
color: #333;
margin-right: 10rpx;
font-size: 34rpx;
}
}
.iconfont {
font-size: 40rpx;
color: #fff;
}
.wx {
background-color: #61C64F;
}
.mima {
background-color: #28B3E9;
}
.yanzheng {
background-color: #F89C23;
}
.pingguo {
margin-left: 60rpx;
background-color: #000;
}
}
}
</style>

View File

@@ -0,0 +1,212 @@
<template>
<!-- 消息中心 -->
<view class="main">
<view class="px-20">
<view class="w-full bg--w111-fff rd-24rpx mt-24 p-32 flex-between-center" v-if="system.id" @tap="goDetail(0)">
<view class="left-pic w-88 h-88 rd-50-p111- flex-center">
<text class="iconfont icon-ic_message1 fs-48 text--w111-fff"></text>
</view>
<view class="flex-1 pl-24">
<view class="flex-between-center">
<view class="fs-32 lh-44rpx w-200 line1">{{ system.title }}</view>
<text class="fs-22 text--w111-999 lh-30rpx">{{ system.add_time }}</text>
</view>
<view class="flex-between-center mt-8">
<view class="fs-24 text--w111-999 lh-34rpx w-430 line1">{{ system.content }}</view>
<view class="dot" v-if="system.message_num > 0"></view>
</view>
</view>
</view>
<view class="w-full bg--w111-fff rd-24rpx mt-24 p-32 flex-between-center" @tap="goDetail(1)" v-if="community.id">
<image src="../static/discover_msg.png" class="w-88 h-88 rd-50-p111- block"></image>
<view class="flex-1 pl-24">
<view class="flex-between-center">
<view class="fs-32 lh-44rpx w-200 line1">互动消息</view>
<text class="fs-22 text--w111-999 lh-30rpx"></text>
</view>
<view class="flex-between-center mt-8">
<view class="fs-24 text--w111-999 lh-34rpx w-430 line1">用户{{ community.relation_author }}{{ community.type | typeFilter }}了你</view>
<view class="dot" v-if="community.is_viewed == 0"></view>
</view>
</view>
</view>
<tui-swipe-action v-for="(item, index) in list" :key="index" :operateWidth="64" class="mt-24 rd-24rpx">
<template v-slot:content>
<view class="w-full bg--w111-fff rd-24rpx p-32 flex-between-center" @tap="goChat(item.to_uid)">
<image :src="item.avatar" class="w-88 h-88 rd-50-p111-"></image>
<view class="flex-1 pl-24">
<view class="flex-between-center">
<view class="fs-32 lh-44rpx w-200 line1">{{ item.nickname }}</view>
<view class="fs-22 text--w111-999 lh-30rpx">{{ item._update_time }}</view>
</view>
<view class="flex-between-center mt-8">
<view class="fs-24 text--w111-999 lh-34rpx w-430 line1" v-if="[1, 2].includes(item.message_type)" v-html="item.message"></view>
<view v-else>{{ item.message_type | messageType }}</view>
<text class="badge" v-if="item.mssage_num > 0">{{ item.mssage_num > 99 ? '99+' : item.mssage_num }}</text>
</view>
</view>
</view>
</template>
<template v-slot:button>
<view class="delete-btn flex-center text--w111-fff fs-24" @tap="deleteMsg(index)">删除</view>
</template>
</tui-swipe-action>
<view class="empty mt-20" v-if="list.length == 0 && !system.id && !community.id">
<emptyPage title="暂无数据~"></emptyPage>
</view>
</view>
<home></home>
</view>
</template>
<script>
import { serviceRecord } from '@/api/user.js';
import colors from '@/mixins/color.js';
import { HTTP_REQUEST_URL } from '@/config/app';
import tuiSwipeAction from '@/components/tui-swipe-action/index.vue';
import emptyPage from '@/components/emptyPage.vue';
export default {
data() {
return {
list: [], //客服消息
system: {}, //站内信
community: {}, //社区消息
page: 1,
type: 0,
limit: 20,
loading: false,
finished: false,
imgHost: HTTP_REQUEST_URL
};
},
components: {
tuiSwipeAction,
emptyPage
},
filters: {
messageType(val) {
let obj = {
3: '[图片]',
4: '[语音]',
5: '[商品]',
6: '[订单]'
};
return obj[val];
},
typeFilter(val) {
let obj = {
1: '点赞',
2: '评论',
3: '关注'
};
return obj[val];
}
},
onShow() {
this.page = 1;
this.list = [];
this.finished = false;
this.getList();
},
onReachBottom() {
this.getList();
},
onPullDownRefresh() {
this.page = 1;
this.list = [];
this.finished = false;
this.getList();
},
methods: {
// 站内信
getList() {
if (this.loading || this.finished) {
return;
}
this.loading = true;
uni.showLoading({
title: '加载中'
});
serviceRecord({
page: this.page,
limit: this.limit
})
.then((res) => {
uni.hideLoading();
uni.stopPullDownRefresh();
let data = res.data.service;
this.system = res.data.system;
this.community = res.data.community;
this.loading = false;
data.forEach((item) => {
if ([1, 2].includes(item.message_type)) {
item.message = this.replace_em(item.message);
}
});
this.list = this.list.concat(data);
this.finished = data.length < this.limit;
this.page += 1;
})
.catch((err) => {
uni.showToast({
title: err.msg,
icon: 'none'
});
});
},
replace_em(str) {
str = str.replace(/\[em-([a-z_]*)\]/g, "<span class='em em-$1'/></span>");
return str;
},
goChat(id) {
uni.navigateTo({
url: '/pages/extension/customer_list/chat?to_uid=' + id + '&type=1'
});
},
goDetail(type) {
if (type == 0) {
uni.navigateTo({
url: '/pages/users/message_center/messageDetail'
});
} else {
uni.navigateTo({
url: '/pages/discover/discoverMessage/index'
});
}
},
deleteMsg(index) {
this.list.splice(index, 1);
}
}
};
</script>
<style lang="scss" scoped>
.left-pic {
background: linear-gradient(180deg, #ffc657 0%, #fe653b 100%);
}
.dot {
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background-color: #e93323;
}
.badge {
min-width: 32rpx;
max-width: 56rpx;
height: 32rpx;
font-size: 22rpx;
line-height: 32rpx;
text-align: center;
padding: 0 8rpx;
border-radius: 20rpx;
color: #fff;
background-color: #e93323;
}
.delete-btn {
width: 128rpx;
height: 152rpx;
background: #e93323;
border-radius: 0 24rpx 24rpx 0;
}
</style>

View File

@@ -0,0 +1,77 @@
<template>
<view class="msg">
<view class="pt-32 pl-20 pr-20">
<view class="item" v-for="(item,index) in messageList" :key="index">
<view class="flex-x-center fs-22 lh-30rpx text--w111-999">{{ item.add_time }}</view>
<view class="w-full bg--w111-fff rd-24rpx mt-24 p-32">
<view class="fs-32 lh-44rpx">{{item.title}}</view>
<view class="fs-28 lh-44rpx mt-24">{{item.content}}</view>
</view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import { messageSystem } from '@/api/user.js';
export default {
data() {
return {
page: 1,
limit: 20,
loading: false,
finished: false,
messageList: []
}
},
onLoad() {
this.getMessageList()
},
onReachBottom() {
this.getMessageList()
},
methods: {
getMessageList() {
if (this.loading || this.finished) return
this.loading = true;
uni.showLoading({
title: '加载中'
});
messageSystem({
page: this.page,
limit: this.limit
})
.then(res => {
let data = res.data.list;
uni.hideLoading();
this.loading = false;
this.messageList = this.messageList.concat(data);
this.finished = data.length < this.limit;
this.page += 1;
})
.catch(err => {
uni.showToast({
title: err.msg,
icon: 'none'
})
})
},
}
}
</script>
<style scoped lang="scss">
.left-pic{
background: linear-gradient(180deg, #FFC657 0%, #FE653B 100%);
}
.dot{
width: 20rpx;
height: 20rpx;
border-radius: 50%;
background-color: #e93323;
}
.item ~ .item{
margin-top: 40rpx;
}
</style>

View File

@@ -0,0 +1,96 @@
<template>
<view :style="colorStyle">
<view class="w-full relative z-99 bg-gradient">
<NavBar titleText="好友代付"
textSize="34rpx"
:isScrolling="isScrolling"
:iconColor="isScrolling ? '#333333' : '#ffffff'"
:textColor="isScrolling ? '#333333' : '#ffffff'"
showBack></NavBar>
<view class="flex-col flex-center">
<image src="../static/logo2.png" class="w-92 h-96 rd-50-p111-"></image>
<view class="text--w111-fff fs-28 lh-40rpx pt-24">代付订单创建成功,发给好友帮你付款吧~</view>
<view class="h-152"></view>
</view>
</view>
<view class="flex-x-center px-20 content-box relative z-100">
<view class="w-full bg--w111-fff rd-24rpx flex-col flex-center pt-52">
<view class="fs-30 lh-42rpx pb-22">代付金额</view>
<baseMoney money="199.00" symbolSize="40" integerSize="72" decimalSize="72" color="#333333" weight></baseMoney>
<view class="w-full px-24 flex-between-center my-40">
<view class="w-320 h-80 rd-40rpx flex-center view-border font-num fs-28">查看订单详情</view>
<view class="w-320 h-80 rd-40rpx flex-center bg-color text--w111-fff fs-28">发给微信好友</view>
</view>
</view>
</view>
<view class="flex-x-center px-20 mt-20">
<view class="w-full bg--w111-fff rd-24rpx pt-32 pr-24 pb-32 pl-24">
<view class="fs-28 lh-40rpx mb-26">共4件商品</view>
<view class="flex-between-center pro-card">
<image src="https://test-pro30.crmeb.net/uploads/attach/2024/10/20241031/7b3ba8ff404a8ab53b3e1bcef12d774d.png" class="w-136 h-136 rd-16rpx" mode="aspectFill"></image>
<view class="ml-20 flex-1">
<view class="w-508 fs-28 lh-40rpx line1">兰蔻唇香礼盒是香水口红兰蔻唇香礼盒礼盒</view>
<view class="fs-24 text--w111-999 lh-34rpx pt-8">兰蔻唇香礼盒是香水口红兰蔻唇香礼盒...</view>
<view class="w-full flex-between-center mt-20">
<baseMoney money="199.00" symbolSize="20" integerSize="32" decimalSize="20" color="#333333" weight></baseMoney>
<text class="fs-24 text--w111-999">x1</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import colors from '@/mixins/color.js';
import { HTTP_REQUEST_URL } from '@/config/app.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import home from '@/components/home/index.vue';
import NavBar from "@/components/NavBar.vue"
let sysHeight = uni.getWindowInfo().statusBarHeight;
export default {
data() {
return {
sysHeight,
isScrolling: false,
}
},
mixins: [colors],
components: { home, NavBar },
computed: mapGetters(['isLogin']),
onPageScroll(option) {
uni.$emit('scroll');
if (option.scrollTop > 50) {
this.isScrolling = true;
} else if (option.scrollTop < 50) {
this.isScrolling = false;
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.bg-gradient{
background: linear-gradient(180deg, var(--view-theme) 0%, var(--view-theme) 52%, rgba(233,51,35,0) 100%);
}
.h-152{
height: 152rpx;
}
.content-box{
margin-top: -120rpx;
}
.pt-52{
padding-top: 52rpx;
}
.view-border{
border: 1px solid var(--view-theme);
}
.pro-card ~ .pro-card{
margin-top: 26rpx;
}
</style>

View File

@@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

View File

@@ -0,0 +1,108 @@
<template>
<view>
<view class="content">
<!-- #ifdef MP-WEIXIN -->
<rich-text :nodes="content"></rich-text>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view v-html="content"></view>
<!-- #endif -->
</view>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { getUserAgreement, getPayVipInfoApi } from '@/api/user.js';
export default {
data() {
return {
content: ``,
sysHeight: sysHeight || 0,
type: ''
};
},
computed: {
pageName() {
let list = {
privacy: '隐私协议',
cancel: '注销协议',
user: '用户协议',
supplier: '供应商入驻协议'
};
uni.setNavigationBarTitle({
title: list[this.type]
});
return list[this.type];
}
},
onLoad(e) {
this.type = e.type;
if (e) {
if(e.type == 'payVip'){
getPayVipInfoApi().then(res=>{
this.content = res.data.member_explain.content;
}).catch((err) => {
that.$util.Tips({
title: err.msg
});
});
}else{
getUserAgreement(e.type).then((res) => {
this.content = res.data.content;
})
.catch((err) => {
that.$util.Tips({
title: err.msg
});
});
}
} else {
getUserAgreement('privacy').then((res) => {
this.content = res.data.content;
})
.catch((err) => {
that.$util.Tips({
title: err.msg
});
});
}
},
mounted() {},
methods: {
goBack() {
uni.navigateBack({
delta: 1
});
}
}
};
</script>
<style scoped lang="scss">
page {
background-color: #fff;
}
.content {
padding: 0 30rpx 40rpx 30rpx;
}
.sys-head {
position: fixed;
width: 100%;
background-color: #fff;
top: 0;
left: 0;
z-index: 9;
.sys-title {
height: 43px;
line-height: 43px;
text-align: center;
position: relative;
.iconfont {
position: absolute;
left: 20rpx;
}
}
}
</style>

View File

@@ -0,0 +1,346 @@
<template>
<view :style="colorStyle">
<view class="promoter-list">
<view class="header">
<view class='search acea-row row-middle'>
<text class="iconfont icon-ic_search"></text>
<input placeholder='搜索用户名称' placeholder-class='placeholder' v-model="keyword" @confirm="submitForm" confirm-type='search' name="search"></input>
</view>
<view class='nav acea-row row-around' v-if="brokerageLevel == 2 || type == 1">
<view :class="grade == 0 ? 'item on' : 'item'" @click='setType(0)'>{{ type ? '代理商' : '一级' }}({{total}})</view>
<view :class="grade == 1 ? 'item on' : 'item'" @click='setType(1)'>{{ type ? '员工' : '二级' }}({{totalLevel}})</view>
</view>
<timeSlot @changeTime="changeTime"></timeSlot>
</view>
<view class='list' v-if="recordList.length">
<view class="top_num">
共 <text class="main_color">{{count}}</text> 位推广人,获得佣金<text class="main_color">¥{{price}}</text>
</view>
<view class="itemCon">
<view class='item acea-row row-between-wrapper' v-for="(item,index) in recordList" :key="index">
<view class="picTxt acea-row row-between-wrapper">
<view class='pictrue'>
<image :src='item.avatar'></image>
</view>
<view class='text'>
<view class='name line1'>{{item.nickname}}</view>
<view>加入时间:{{item.time}}</view>
</view>
</view>
<view class="right">
<view><text class='num font-nums'>{{item.childCount ? item.childCount : 0}}</text>人</view>
<view><text class="num">{{item.orderCount ? item.orderCount : 0}}</text>单</view>
<view><text class="num">{{item.numberCount ? item.numberCount : 0}}</text>元</view>
</view>
</view>
</view>
</view>
<view class="empty" v-if="recordList.length == 0">
<emptyPage title="暂无数据~"></emptyPage>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
spreadPeople
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import emptyPage from '@/components/emptyPage.vue'
import timeSlot from '../components/timeSlot/index.vue'
import colors from '@/mixins/color.js';
export default {
components: {
timeSlot,
emptyPage
},
mixins: [colors],
data() {
return {
total: 0,
totalLevel: 0,
teamCount: 0,
page: 1,
limit: 20,
keyword: '',
sort: '',
grade: 0,
status: false,
recordList: [],
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
start: 0,
stop: 0,
count: 0,
price: 0,
brokerageLevel: 0,
type: 0
};
},
computed: mapGetters(['isLogin']),
onLoad(options) {
if (this.isLogin) {
// type = 1 为事业部团队跳转进入
if(options.type) this.type = options.type
this.userSpreadNewList();
} else {
toLogin()
}
},
onShow: function() {
uni.removeStorageSync('form_type_cart');
if (this.is_show) this.userSpreadNewList();
},
onHide: function() {
this.is_show = true;
},
methods: {
changeTime(time) {
console.log(time)
this.start = time.start
this.stop = time.stop
this.submitForm()
},
onLoadFun(e) {
this.userSpreadNewList();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
setSort(sort) {
let that = this;
that.sort = sort;
that.page = 1;
that.limit = 20;
that.status = false;
that.$set(that, 'recordList', []);
that.userSpreadNewList();
},
// setKeyword: function(e) {
// this.keyword = e.detail.value;
// },
submitForm: function() {
this.page = 1;
this.limit = 20;
this.status = false;
this.$set(this, 'recordList', []);
this.userSpreadNewList();
},
setType: function(grade) {
if (this.grade != grade) {
this.grade = grade;
this.page = 1;
this.limit = 20;
this.keyword = '';
this.sort = '';
this.status = false;
this.$set(this, 'recordList', []);
this.userSpreadNewList();
}
},
userSpreadNewList: function() {
let that = this;
let page = that.page;
let limit = that.limit;
let status = that.status;
let keyword = that.keyword;
let sort = that.sort;
let grade = that.grade;
let recordList = that.recordList;
let recordListNew = [];
if (status == true) return;
spreadPeople({
start: this.start,
stop: this.stop,
page: page,
limit: limit,
keyword: keyword,
grade: grade,
sort: sort,
}).then(res => {
let len = res.data.list.length;
let recordListData = res.data.list;
recordListNew = recordList.concat(recordListData);
that.total = res.data.total;
that.totalLevel = res.data.totalLevel;
that.teamCount = res.data.count;
that.brokerageLevel = res.data.brokerage_level;
that.status = limit > len;
that.page = page + 1;
that.$set(that, 'recordList', recordListNew);
that.count = res.data.count;
that.price = res.data.price;
});
}
},
onReachBottom: function() {
this.userSpreadNewList();
},
onPageScroll(object) {
uni.$emit('scroll');
},
}
</script>
<style scoped lang="scss">
.empty{
margin: 20rpx;
}
.font-nums{
color: #E93323;
}
.promoter-list .nav {
background-color: #fff;
height: 92rpx;
line-height: 86rpx;
font-size: 28rpx;
color: #666;
font-family: PingFang SC;
}
.promoter-list .nav .item.on {
color: #E93323;
position: relative;
font-size: 32rpx;
&::after {
position: absolute;
content: '';
width: 38rpx;
height: 30rpx;
border: 2px solid #E93323;
border-left: 2px solid transparent !important;
border-top: 2px solid transparent !important;
border-right: 2px solid transparent !important;
border-radius: 50%;
left: 50%;
margin-left: -24rpx;
bottom: 16rpx;
}
}
.promoter-list .header {
background-color: #fff;
padding-top: 24rpx;
}
.promoter-list .search {
width: 710rpx;
height: 72rpx;
padding: 0 32rpx;
box-sizing: border-box;
background-color: #F5F5F5;
border-radius: 50rpx;
margin: 0 auto 10rpx auto;
.placeholder {
color: #ccc;
font-size: 28rpx;
}
}
.promoter-list .search .iconfont {
font-size: 32rpx;
color: #999;
margin-right: 18rpx;
}
.promoter-list .list {
margin-top: 12rpx;
}
.promoter-list .list .sortNav {
background-color: #fff;
height: 76rpx;
border-bottom: 1rpx solid #eee;
color: #333;
font-size: 28rpx;
}
.promoter-list .list .sortNav .sortItem {
text-align: center;
flex: 1;
}
.promoter-list .list .sortNav .sortItem image {
width: 24rpx;
height: 24rpx;
margin-left: 6rpx;
vertical-align: -3rpx;
}
.promoter-list .list .itemCon {
background-color: #fff;
margin: 0 20rpx;
border-radius: 24rpx;
}
.promoter-list .list .item {
height: 176rpx;
font-size: 24rpx;
color: #666;
margin: 0 24rpx;
border-bottom: 1px solid #EEEEEE;
}
.promoter-list .list .item .picTxt {
width: 440rpx;
}
.promoter-list .list .item .picTxt .pictrue {
width: 112rpx;
height: 112rpx;
border-radius: 50%;
}
.promoter-list .list .item .picTxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 50%;
}
.promoter-list .list .item .picTxt .text {
width: 304rpx;
font-size: 24rpx;
color: #999;
}
.promoter-list .list .item .picTxt .text .name {
font-size: 28rpx;
color: #333;
margin-bottom: 13rpx;
}
.promoter-list .list .item .right {
width: 190rpx;
text-align: right;
font-size: 24rpx;
color: #333;
}
.promoter-list .list .item .right .num {
margin-right: 7rpx;
}
.top_num {
padding: 14rpx 20rpx 28rpx 20rpx;
font-size: 24rpx;
color: #666;
}
.main_color {
color: #E93323;
margin: 0 6rpx;
}
</style>

View File

@@ -0,0 +1,356 @@
<template>
<view :style="colorStyle">
<view class="promoter-order">
<view class='header acea-row row-center-wrapper'>
<view class='acea-row row-between-wrapper input'>
<text class='iconfont icon-ic_search'></text>
<input type='text' placeholder='搜索商品名称' @confirm="searchSubmitValue" confirm-type='search'
name="search" placeholder-class='placeholder'></input>
</view>
</view>
<timeSlot @changeTime="changeTime"></timeSlot>
<view class='list' v-if="recordList.length>0">
<view class="top_num">
共 <text class="main_color">{{total}}</text> 笔订单,获得佣金<text class="main_color">¥{{sum_brokerage}}</text>
</view>
<block v-for="(item,index) in recordList" :key="index">
<view class='item'>
<view class='listn'>
<block v-for="(child,indexn) in item.child" :key="indexn">
<view class='itenm'>
<view class='top acea-row row-between-wrapper'>
<view class='pictxt acea-row row-between-wrapper'>
<view class='pictrue'>
<image :src='child.avatar'></image>
</view>
<view class='text line1'>{{child.nickname}}</view>
</view>
<view class="acea-row row-middle">
<view class="freeze acea-row row-center-wrapper" v-if="child.is_frozen">冻结</view>
<view class='money' v-if="child.type == 'brokerage'">返佣:<text
class='font-color'>¥{{child.number}}</text></view>
<view class='money' v-else>暂未返佣:<text
class='font-color'>¥{{child.number}}</text></view>
</view>
</view>
<view class='bottom'>
<view class="msg">
<text class='name'>订单编号:</text>
<text>{{child.order_id}}</text>
<text class="copy_btn fs-22" @tap="copy(child.order_id)">复制</text>
</view>
<!-- <view class="msg">
<text class='name'>宝贝名称:</text>
<view class="store_name line1">
{{child.store_name}}
</view>
</view> -->
<view v-if="child.type == 'brokerage'">
<text class='name'>返佣时间:</text>
<text class="text--w111-666">{{child.time}}</text>
</view>
<view v-else>
<text class='name'>下单时间:</text>
<text class="text--w111-666">{{child.time}}</text>
</view>
</view>
</view>
</block>
</view>
</view>
</block>
</view>
<view class="empty" v-if="recordList.length == 0">
<emptyPage title="暂无推广订单~"></emptyPage>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
spreadOrder
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import timeSlot from '../components/timeSlot/index.vue'
import emptyPage from '@/components/emptyPage.vue'
import colors from '@/mixins/color.js';
let sysHeight = uni.getWindowInfo().statusBarHeight + 'px';
export default {
components: {
emptyPage,
timeSlot
},
mixins: [colors],
data() {
return {
sysHeight: sysHeight,
page: 1,
limit: 10,
status: false,
loading: false,
recordList: [],
times: [],
time: '',
recordCount: 0,
count: 0,
total:0,
sum_brokerage:0,
keyword: '',
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
start: 0,
stop: 0
};
},
computed: mapGetters(['isLogin']),
onLoad() {
if (this.isLogin) {
this.getRecordOrderList();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
copy: function (code) {
let that = this;
uni.setClipboardData({
data: code
});
},
searchSubmitValue(e) {
this.keyword = e ? e.detail.value : ''
this.page = 1;
this.limit = 20;
this.status = false;
this.$set(this, 'recordList', []);
this.$set(this, 'times', []);
this.getRecordOrderList()
},
changeTime(time) {
this.start = time.start
this.stop = time.stop
this.searchSubmitValue()
},
getRecordOrderList() {
let that = this;
let page = that.page;
let limit = that.limit;
let status = that.status;
if (that.loading) return
if (status == true) return;
that.loading = true;
spreadOrder({
start: this.start,
stop: this.stop,
keyword: this.keyword,
page: page,
limit: limit
}).then(res => {
this.total = res.data.count;
this.sum_brokerage = res.data.sum_brokerage;
for (let i = 0; i < res.data.time.length; i++) {
if (!this.times.includes(res.data.time[i].time)) {
this.times.push(res.data.time[i].time)
this.recordList.push({
time: res.data.time[i].time,
count: res.data.time[i].count,
child: []
})
}
}
for (let x = 0; x < this.times.length; x++) {
for (let j = 0; j < res.data.list.length; j++) {
if (this.times[x] === res.data.list[j].time_key) {
this.recordList[x].child.push(res.data.list[j])
}
}
}
that.count = res.data.count || 0;
that.status = res.data.list.length < 5;
that.page += 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
});
}
},
onReachBottom: function() {
this.getRecordOrderList();
},
onPageScroll(object) {
uni.$emit('scroll');
},
}
</script>
<style scoped lang="scss">
.empty{
margin: 20rpx;
}
.sys-title {
z-index: 10;
position: relative;
height: 40px;
line-height: 40px;
font-size: 30rpx;
color: #fff;
background-color: var(--view-theme);
// #ifdef MP || APP-PLUS
text-align: center;
// #endif
}
.sys-head {
background-color: #fff;
}
.promoter-order .header {
width: 100%;
height: 96rpx;
background-color: #fff;
padding-top: 24rpx;
}
.promoter-order .header .input {
width: 710rpx;
height: 72rpx;
background-color: #f5f5f5;
border-radius: 50rpx;
box-sizing: border-box;
padding: 0 32rpx;
}
.promoter-order .header .input .iconfont {
font-size: 32rpx;
color: #999;
}
.promoter-order .header .input .placeholder {
color: #ccc;
}
.promoter-order .header .input input {
font-size: 26rpx;
height: 100%;
width: 597rpx;
}
.promoter-order .list .item .title {
height: 133rpx;
padding: 0 30rpx;
font-size: 26rpx;
color: #999;
}
.promoter-order .list .item .title .data {
font-size: 28rpx;
color: #282828;
margin-bottom: 5rpx;
}
.promoter-order .list .item .listn .itenm {
background-color: #fff;
margin: 0 20rpx 20rpx 20rpx;
border-radius: 14rpx;
}
.promoter-order .list .item .listn .itenm~.itenm {
margin-top: 12rpx;
}
.promoter-order .list .item .listn .itenm .top {
margin-left: 20rpx;
padding-right: 20rpx;
border-bottom: 1rpx solid #eee;
height: 128rpx;
.freeze{
width: 72rpx;
height: 40rpx;
background: #FFF1E5;
border-radius: 8rpx;
font-size: 24rpx;
color: #FF7D00;
margin-right: 16rpx;
}
}
.promoter-order .list .item .listn .itenm .top .pictxt {
width: 320rpx;
}
.promoter-order .list .item .listn .itenm .top .pictxt .text {
width: 240rpx;
font-size: 30rpx;
color: #333;
}
.promoter-order .list .item .listn .itenm .top .pictxt .pictrue {
width: 64rpx;
height: 64rpx;
}
.promoter-order .list .item .listn .itenm .top .pictxt .pictrue image {
width: 100%;
height: 100%;
border-radius: 50%;
}
.promoter-order .list .item .listn .itenm .top .money {
font-size: 28rpx;
.font-color{
font-size: 32rpx;
font-family: "Regular";
}
}
.promoter-order .list .item .listn .itenm .bottom {
padding: 28rpx 20rpx;
font-size: 28rpx;
color: #666;
line-height: 1.6;
.msg{
display: flex;
align-items: center;
margin-bottom: 6rpx;
}
}
.promoter-order .list .item .listn .itenm .bottom .name {
color: #999999;
}
.promoter-order .list .item .listn .itenm .bottom .store_name {
width: 450rpx;
color: #666666;
}
.top_num{
padding: 28rpx 20rpx;
font-size: 24rpx;
color: #999;
}
.main_color{
color: #E93323;
margin: 0 6rpx;
}
.copy_btn {
width: 68rpx;
height: 36rpx;
background: #f5f5f5;
border-radius: 20rpx;
text-align: center;
line-height: 36rpx;
margin-left: 12rpx;
}
</style>

View File

@@ -0,0 +1,357 @@
<template>
<view :style="colorStyle">
<view class="PromoterRank">
<!-- #ifdef MP -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>推广人排行</view>
<text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<!-- #endif -->
<view class="header">
<view class="acea-row row-middle row-right">
<view class="left">
<view class="pictrue">
<image src="../static/ranking.png"></image>
</view>
<view class="tips" v-if="rankInfo.rank">您目前的排名<text class="num">{{rankInfo.rank}}</text>名</view>
<view class="tips" v-else>您目前暂无排名</view>
</view>
<view class="trophy">
<image :src="imgHost+'/statics/images/users/trophy.png'"></image>
</view>
</view>
</view>
<view class="wrapper">
<view class="nav acea-row row-around">
<view class="item" :class="active == index ? 'on' : ''" v-for="(item,index) in navList"
:key="index" @click="switchTap(index)">
{{ item }}
</view>
</view>
<view class="list" v-if="rankList.length">
<view class="item acea-row row-between-wrapper" v-for="(item,index) in rankList" :key="index">
<view class="acea-row row-middle">
<view class="num" v-if="index <= 2">
<image :src="'../static/no'+(index+1)+'.png'"></image>
</view>
<view class="num" v-else>
{{index+1}}
</view>
<view class="pictrue">
<image :src="item.avatar"></image>
</view>
<view class="text line1">{{item.nickname}}</view>
</view>
<view class="people">{{item.count}}人</view>
</view>
</view>
<view v-if="!rankList.length">
<emptyPage title="暂无排行榜数据哦~"></emptyPage>
</view>
</view>
<view style="height: 130rpx;" v-if="rankInfo.position>0"></view>
<view class="footer acea-row row-between-wrapper" v-if="rankInfo.position>0">
<view class="acea-row row-middle">
<view class="me">我</view>
<view class="pictrue">
<image :src="rankInfo.avatar"></image>
</view>
<view class="name line1">{{rankInfo.nickname}}</view>
<view class="ranking">第{{rankInfo.position}}名</view>
</view>
<view class="num">¥{{rankInfo.brokerage_price}}</view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
getRankList
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import emptyPage from '@/components/emptyPage.vue'
import {
mapGetters
} from "vuex";
import colors from '@/mixins/color.js';
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
components: {
emptyPage
},
mixins: [colors],
data() {
return {
imgHost: HTTP_REQUEST_URL,
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
navList: ["周排行", "月排行"],
active: 0,
page: 1,
limit: 20,
type: 'week',
loading: false,
loadend: false,
rankInfo:{
position:0,
avatar:'',
brokerage_price:'',
nickname:''
},
rankList: [],
isShowAuth: false
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
this.getRanklist();
}
},
deep: true
}
},
onLoad() {
if (this.isLogin) {
this.getRanklist();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
onLoadFun() {
this.getRanklist();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
goarrow(){
uni.navigateBack()
},
getRanklist: function() {
let that = this;
if (that.loadend) return;
if (that.loading) return;
that.loading = true;
getRankList({
page: that.page,
limit: that.limit,
type: that.type
}).then(res => {
let list = res.data.list;
that.rankInfo = res.data;
that.rankList.push.apply(that.rankList, list);
that.loadend = list.length < that.limit;
that.loading = false;
that.$set(that, 'rankList', that.rankList);
that.page = that.page + 1;
}).catch(err => {
that.loading = false;
})
},
switchTap: function(index) {
if (this.active === index) return;
this.active = index;
this.type = index ? 'month' : 'week';
this.page = 1;
this.loadend = false;
this.$set(this, 'rankList', []);
this.getRanklist();
},
},
onReachBottom: function() {
this.getRanklist();
},
onPageScroll(object) {
uni.$emit('scroll');
},
}
</script>
<style scoped lang="scss">
.accountTitle{
background: linear-gradient(180deg, #FFC48D 0%, #FCCEA4 100%);
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #333333;
font-size: 30rpx;
.iconfont{
position: absolute;
font-size: 36rpx;
left:11rpx;
width: 60rpx;
}
}
}
.PromoterRank{
padding-bottom: 30rpx;
.footer{
position: fixed;
height: 128rpx;
background-color: #fff;
font-size: 28rpx;
width: 100%;
bottom: 0;
left:0;
border-top: 1px solid #EEEEEE;
padding: 0 64rpx;
.me{
color: #FF7D00;
}
.pictrue{
width: 80rpx;
height: 80rpx;
margin-left: 48rpx;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.name{
max-width: 164rpx;
margin-left: 24rpx;
}
.ranking{
color: #FF7D00;
margin-left: 16rpx;
}
}
.header{
background: linear-gradient(180deg, #FCCEA4 50%, #F5F5F5 100%);
height: 560rpx;
padding-top: 26rpx;
.left{
.pictrue{
width: 352rpx;
height: 76rpx;
image{
width: 100%;
height: 100%;
}
}
.tips{
font-size: 28rpx;
font-weight: 400;
color: #D25F00;
margin-top: 30rpx;
.num{
font-family: 'SemiBold';
font-size: 40rpx;
margin: 0 8rpx;
}
}
}
.trophy{
width: 324rpx;
height: 260rpx;
margin-left: 38rpx;
image{
width: 100%;
height: 100%;
}
}
}
.wrapper{
width: 710rpx;
background-color: #fff;
border-radius: 20rpx;
margin: -278rpx auto 0 auto;
.nav{
font-size: 28rpx;
font-weight: 400;
color: #999;
.item{
color: #999999;
padding: 32rpx 0 12rpx 0;
&.on{
color: #333;
font-size: 32rpx;
position: relative;
font-weight: 600;
&::after{
position: absolute;
content: '';
width: 56rpx;
height: 4rpx;
background: #E93323;
border-radius: 2rpx;
left:50%;
margin-left: -28rpx;
bottom: 0;
}
}
}
}
.list{
padding: 0 44rpx 72rpx 28rpx;
.item{
margin-top: 48rpx;
.num{
font-weight: 400;
color: #999;
font-size: 28rpx;
width: 64rpx;
height: 64rpx;
text-align: center;
line-height: 64rpx;
image{
width: 100%;
height: 100%;
display: block;
}
}
.pictrue{
width: 80rpx;
height: 80rpx;
margin-left: 28rpx;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.text{
font-weight: 400;
color: #333333;
font-size: 28rpx;
margin-left: 24rpx;
width: 180rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,316 @@
<template>
<view class="wrapper" :style="colorStyle">
<view class="bag">
<img :src="imgHost+'/statics/images/users/login-bg.jpg'" alt="" srcset="">
</view>
<!-- #ifdef MP -->
<view class="title-bar" style="height: 43px;">
<view class="icon" @click="back" v-if="!isHome">
<image src="../static/left.png"></image>
</view>
<view class="icon" @click="home" v-else>
<image src="../static/home.png"></image>
</view>
{{pageTitle}}
</view>
<!-- #endif -->
<view class="page-msg">
<view class="title">
找回密码
</view>
<view class="tip"></view>
</view>
<view class="page-form">
<view class="item">
<input type='number' placeholder='请输入手机号码' placeholder-class='placeholder' v-model="account"
:maxlength="11"></input>
</view>
<view class="item acea-row row-between-wrapper">
<input type='number' placeholder='请输入验证码' placeholder-class='placeholder' :maxlength="6"
class="codeIput" v-model="captcha"></input>
<view class="line">
</view>
<button class="code font-num" :class="disabled === true ? 'on' : ''" :disabled='disabled' @click="code">
{{ text }}
</button>
</view>
<view class="item">
<input type='password' placeholder='请输入密码' placeholder-class='placeholder' v-model="password"
:maxlength="28"></input>
</view>
<view class="item">
<input type='password' placeholder='请再次确认密码' placeholder-class='placeholder' v-model="passwordAgain"
:maxlength="28"></input>
</view>
<view class="btn" @click="registerReset">
确认
</view>
<view class="text-center fs-32 text--w111-999 mt-32" @click="back">立即登录</view>
</view>
<Verify @success="success" :captchaType="'blockPuzzle'" :imgSize="{ width: '330px', height: '155px' }"
ref="verify"></Verify>
</view>
</template>
<script>
import sendVerifyCode from "@/mixins/SendVerifyCode";
import colors from '@/mixins/color.js';
import Verify from '../components/verify/verify.vue';
import {
registerVerify,
registerReset,
getCodeApi
} from "@/api/user";
import { HTTP_REQUEST_URL } from '@/config/app';
export default {
name: "RetrievePassword",
components: {
Verify
},
data: function() {
return {
account: "",
password: "",
passwordAgain:'',
captcha: "",
keyCode: "",
codeUrl: "",
codeVal: "",
isShowCode: false,
imgHost: HTTP_REQUEST_URL,
type:'login'
};
},
mixins: [sendVerifyCode,colors],
mounted: function() {
// this.getCode();
},
methods: {
back() {
uni.navigateBack();
},
again() {
this.codeUrl =
VUE_APP_API_URL + "/captcha?" + this.keyCode + Date.parse(new Date());
},
async registerReset() {
var 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 (!that.password) return that.$util.Tips({
title: '请填写新密码'
});
if (that.password != that.passwordAgain) return that.$util.Tips({
title: '两次密码不一致'
});
registerReset({
account: that.account,
captcha: that.captcha,
password: that.password,
code: that.codeVal
})
.then(res => {
that.$util.Tips({
title: res.msg
}, {
tab: 3
})
})
.catch(res => {
that.$util.Tips({
title: res
})
});
},
success(data) {
console.log(data,'data');
this.$refs.verify.hide()
getCodeApi()
.then(res => {
this.keyCode = res.data.key;
this.getCode(data);
})
.catch(res => {
this.$util.Tips({
title: res
});
});
},
code(data) {
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: '请输入正确的手机号码'
});
this.$refs.verify.show()
},
async getCode(data){
console.log('data-------',data);
let that = this;
await registerVerify({
phone: that.account,
type: that.type,
key: that.keyCode,
captchaType: 'blockPuzzle',
captchaVerification: data.captchaVerification,
})
.then(res => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
})
.catch(res => {
this.$refs.verify.refresh()
that.$util.Tips({
title: res
});
});
},
}
};
</script>
<style lang="scss" scoped>
.wrapper {
background-color: #fff;
min-height: 100vh;
position: relative;
.bag {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 0;
/* #ifdef H5 */
z-index: 0;
/* #endif */
img {
width: 100%;
height: 544rpx;
}
}
.page-msg {
padding-top: 160rpx;
margin-left: 72rpx;
z-index: 2;
position: relative;
.title {
font-size: 48rpx;
font-weight: 500;
color: #333333;
line-height: 68rpx;
}
.tip {
font-size: 28rpx;
font-weight: 400;
color: #333333;
line-height: 40rpx;
}
}
.page-form {
width: 606rpx;
margin: 100rpx auto 0 auto;
z-index: 2;
position: relative;
.item {
width: 100%;
height: 88rpx;
background: #F5F5F5;
border-radius: 45rpx;
padding: 24rpx 48rpx;
margin-bottom: 32rpx;
input {
width: 100%;
height: 100%;
font-size: 32rpx;
}
.placeholder {
color: #BBBBBB;
font-size: 28rpx;
}
input.codeIput {
width: 300rpx;
}
.line {
width: 2rpx;
height: 28rpx;
background: #CCCCCC;
}
.code {
font-size: 28rpx;
color: var(--view-theme);
background-color: rgba(255, 255, 255, 0);
}
.code.on {
color: #BBBBBB !important;
}
}
.btn {
width: 606rpx;
height: 88rpx;
background: var(--view-theme);
border-radius: 200rpx 200rpx 200rpx 200rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #FFFFFF;
line-height: 44rpx;
margin-top: 48rpx;
letter-spacing: 1px;
}
}
}
.title-bar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 34rpx;
font-weight: 500;
color: #333333;
line-height: 48rpx;
}
.icon {
position: absolute;
left: 30rpx;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 80rpx;
height: 80rpx;
image {
width: 35rpx;
height: 35rpx;
}
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<view class="scan_login">
<view class="head">
<image :src="userInfo.avatar" mode=""></image>
<view class="big">{{userInfo.nickname}}</view>
<view class="small">点击授权登录您的客服工作台</view>
<view class="sub_btn btn" @click="scanLogin">授权登录</view>
<view class="out btn" @click="closePage">取消</view>
</view>
</view>
</template>
<script>
import {
getUserInfo,
} from '@/api/user.js';
import { codeStauts,kefuScanLogin } from '@/api/kefu.js'
export default{
name:'scan_login',
data(){
return {
code:'',
userInfo:{}
}
},
onLoad(optios) {
this.code = optios.key
this.codeStauts()
this.getUserInfo()
},
methods:{
codeStauts(){
codeStauts({
code:this.code
}).then(res=>{
}).catch(error=>{
this.openModel(error)
})
},
// 确认
scanLogin(){
if(this.code){
kefuScanLogin({
code:this.code
}).then(res=>{
uni.showToast({
title:res.msg,
icon:'success'
})
setTimeout(res=>{
WeixinJSBridge.call('closeWindow');
},2000)
}).catch(error=>{
this.openModel(error)
})
}else{
this.openModel('没有登录的code,请重新扫码')
}
},
openModel(data){
uni.showModal({
title:'提示',
content:data,
success: function (res) {
if (res.confirm) {
WeixinJSBridge.call('closeWindow');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
},
closePage(){
WeixinJSBridge.call('closeWindow');
},
// 获取用户信息
getUserInfo(){
getUserInfo().then(res=>{
this.userInfo = res.data
})
}
}
}
</script>
<style lang="stylus">
page{
height: 100%;
background: #fff;
}
.scan_login
.head
display flex
flex-direction column
align-items center
padding-top 96rpx
image
width 178rpx
height 178rpx
border-radius 50%
.big
margin 20rpx 0 10rpx
font-size 32rpx
color #282828
.small
color #9f9f9f
font-size 28rpx
.btn
display flex
align-items center
justify-content center
width 594rpx
height 86rpx
margin 28rpx auto 0
font-size 30rpx
color #fff
border-radius 43rpx
background: linear-gradient(90deg, #3875EA 0%, #1890FC 100%);
&.out
border 1px solid #3875EA
background none
color #3875EA
&.sub_btn
margin-top 96rpx
</style>

View File

@@ -0,0 +1,199 @@
<template>
<view>
<view class="top-card w-full relative" :style="[topCardStyle]">
<NavBar
class="TopBar"
titleText="用户贡献榜"
textSize="34rpx"
:isScrolling="isScrolling"
iconColor="#333333"
textColor="#333333"
showBack></NavBar>
<view class="h-100 flex-around-center fs-28 text--w111-666 relative z-20">
<text class="w-112 text-center" :class="{'tab-active': contributeType == 'order_count'}" @tap="toggleContribute('order_count')">订单数</text>
<text class="w-112" :class="{'tab-active': contributeType == 'order_price'}" @tap="toggleContribute('order_price')">订单金额</text>
<text class="w-112 text-center" :class="{'tab-active': contributeType == 'brokerage'}" @tap="toggleContribute('brokerage')">收益</text>
</view>
<view class="abs-lb w-full h-192 gradient-white"></view>
</view>
<view class="px-20 w-full relative z-10 empty-card" :style="[cardTop]">
<view class="w-full bg--w111-fff rd-24rpx">
<view class="py-32" v-if="contributeData.length">
<view class="flex-between-center fs-22 lh-30rpx text--w111-666 pl-38 mb-28">
<text class="w-44">排名</text>
<text class="w-168">用户</text>
<text class="w-72">订单数</text>
<text class="w-108">订单金额</text>
<text class="w-108">收益</text>
</view>
<view class="flex-between-center rank-cell fs-22 lh-30rpx text--w111-666 pl-38"
v-for="(item,index) in contributeData" :key="index">
<view class="w-44">
<text class="SemiBold rank-1" v-show="index == 0">1</text>
<text class="SemiBold rank-2" v-show="index == 1">2</text>
<text class="SemiBold rank-3" v-show="index == 2">3</text>
<text class="SemiBold text--w111-ccc" v-show="index > 2">{{ index + 1 }}</text>
</view>
<view class="w-168 flex-y-center">
<image class="w-44 h-44 rd-50-p111- block mr-8" :src="item.avatar"></image>
<view class="w-116 line1">{{ item.nickname || '微信用户' }}</view>
</view>
<text class="w-72">{{ item.total_order_count }}</text>
<text class="w-108">¥{{ item.total_order_price }}</text>
<text class="w-108">¥{{ item.total_brokerage }}</text>
</view>
</view>
<view class="py-32 empty-card" v-else>
<emptyPage title="暂无贡献榜单数据~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
</view>
</view>
</template>
<script>
import colors from '@/mixins/color.js';
import { spreadContributeApi } from "@/api/user.js"
import { HTTP_REQUEST_URL } from '@/config/app.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import home from '@/components/home/index.vue';
import NavBar from "@/components/NavBar.vue";
import emptyPage from '@/components/emptyPage.vue'
let sysHeight = uni.getWindowInfo().statusBarHeight;
export default {
data() {
return {
sysHeight,
isScrolling: false,
berHeight: 40,
active: 0,
params:{
page:1,
limit:10
},
loading: false,
contributeType: 'order_count',
contributeData:[],
}
},
mixins: [colors],
components: { home, NavBar, emptyPage },
computed: {
...mapGetters(['isLogin']),
topCardStyle(){
return {
height: 145 + this.berHeight + 'px'
}
},
cardTop(){
return {
'top': `-${this.sysHeight + 96}px`
}
},
},
onPageScroll(option) {
uni.$emit('scroll');
if (option.scrollTop > 50) {
this.isScrolling = true;
} else if (option.scrollTop < 50) {
this.isScrolling = false;
}
},
onLoad() {
setTimeout(()=>{
this.getHeight();
},100)
if(this.isLogin){
this.getContribute();
}else{
toLogin();
}
},
methods: {
changeTab(type){
this.active = type;
},
getHeight() {
let that = this;
uni.createSelectorQuery().select('.TopBar').boundingClientRect(function(rect) {
this.berHeight = rect.height;
}).exec();
},
toggleContribute(val){
this.contributeType = val;
this.params.page = 1;
this.contributeData = [];
this.loading = false;
this.getContribute();
},
getContribute(){
if (this.loading) return;
this.loading = true;
spreadContributeApi(this.contributeType, this.params).then(res=>{
let list = res.data;
let loading = list.length < this.params.limit;
this.contributeData = this.contributeData.concat(list);
this.params.page++;
this.loading = loading;
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
},
onReachBottom() {
this.getContribute();
},
}
</script>
<style lang="scss">
.top-card{
background: #FFEEC7;
}
.tab-active{
font-weight: bold;
color: #333333;
position: relative;
&:after{
content: "";
position: absolute;
left: 50%;
bottom: -12rpx;
transform: translateX(-50%);
width: 40rpx;
height: 10rpx;
background-image: url("../static/rank_tab_fix.png");
background-size: cover;
}
}
.gradient-white{
background: linear-gradient( 180deg, rgba(245,245,245,0) 0%, #F5F5F5 100%);
}
.content-card{
top: -192rpx;
}
.rank-1{
color: #E73E05;
}
.rank-2{
color: #E26F04;
}
.rank-3{
color: #F4BB00;
}
.rank-cell ~ .rank-cell{
margin-top: 40rpx;
}
.empty-card{
/* #ifdef MP */
margin-top: 192rpx;
/* #endif */
}
.w-44{
width: 44rpx;
}
</style>

View File

@@ -0,0 +1,658 @@
<template>
<view>
<view class="top-card relative">
<NavBar titleText="分销数据"
textSize="34rpx"
:isScrolling="isScrolling"
:iconColor="isScrolling ? '#333333' : '#ffffff'"
:textColor="isScrolling ? '#333333' : '#ffffff'"
showBack></NavBar>
<view class="pt-24">
<view class="flex items-start pl-66">
<image :src="userInfo.avatar" class="w-104 h-104 rd-50-p111-"></image>
<view class="flex-1 flex-between-center pl-16 pt-8">
<view class="flex-y-center">
<text class="fs-32 lh-44rpx text-color1 max-w-200 line1">{{userInfo.nickname}}</text>
<view class="flex-y-center h-40 rd-20rpx fs-20 text--w111-f7f0df opacity-tag px-12"
@tap="jumbPath(10)">
<text class="iconfont icon-huiyuandengji fs-24"></text>
<text class="pl-6">{{ levelInfo.name || '等级未解锁' }}</text>
</view>
</view>
<view class="flex-center qrcode-btn" @tap="createCode(5)" v-if="userInfo.division_type == 2">
<text class="iconfont icon-a-ic_QRcode fs-28"></text>
<text class="fs-20 pl-4">推广码</text>
</view>
<view class="flex-center qrcode-btn" @tap="jumbPath(5)" v-else>
<text class="iconfont icon-a-ic_QRcode fs-28"></text>
<text class="fs-20 pl-4">推广码</text>
</view>
</view>
</view>
<view class="px-20">
<view class="w-full relative vip-card px-32" :style="[vipCardStyle]">
<view class="flex-between-center pt-60">
<view class="text-color1">
<view class="fs-28 lh-40rpx flex-y-center">可提现金额(元)
<text class="iconfont icon-icon_question_2 fs-28" @tap="jumbPath(11)"></text>
</view>
<view class="flex-y-center pt-18" @tap="jumbPath(6)">
<view class="fs-60 SemiBold">{{ userInfo.commissionCount || '0.00' }}</view>
<text class="iconfont icon-ic_rightarrow fs-28 pl-10"></text>
</view>
</view>
<view class="gradient-gold w-128 h-58 flex-center rd-30rpx fs-24 fw-500" @tap="jumbPath(0)">去提现</view>
</view>
<view class="pt-40 flex-between-center">
<view class="flex-col">
<text class="fs-24 text--w111-fff lh-34rpx op-60">累计佣金(元)</text>
<text class="SemiBold fs-34 pt-8 text-color1">{{ userInfo.accumulate || '0.00' }}</text>
</view>
<view class="flex-col">
<text class="fs-24 text--w111-fff lh-34rpx op-60">已提现(元)</text>
<text class="SemiBold fs-34 pt-8 text-color1">{{withdraw}}</text>
</view>
<view class="flex-col">
<text class="fs-24 text--w111-fff lh-34rpx op-60">冻结佣金(元)</text>
<text class="SemiBold fs-34 pt-8 text-color1">{{ userInfo.broken_commission || '0.00' }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="px-20 relative content-box mt-20">
<view class="w-full bg--w111-fff rd-24rpx px-24">
<view class="flex-between-center pt-32" @tap="jumbPath(8)">
<view class="fs-28 fw-500 lh-40rpx">订单收益明细</view>
<text class="iconfont icon-ic_rightarrow fs-22 text--w111-666"></text>
</view>
<view class="mt-28 w-full h-60 rd-30rpx flex-between-center bg-gold-1">
<view class="tab-item tab-item1 flex-center" :class="orderActive == 0 ? 'tab-active' : 'have-line'" @tap="setTime('all',1)">全部</view>
<view class="tab-item tab-item1 flex-center" :class="orderActive == 1 ? 'tab-active' : 'have-line'" @tap="setTime('today',1)">今日</view>
<view class="tab-item tab-item1 flex-center" :class="orderActive == 2 ? 'tab-active' : 'have-line'" @tap="setTime('yesterday',1)">昨日</view>
<view class="tab-item tab-item1 flex-center" :class="orderActive == 3 ? 'tab-active' : 'have-line'" @tap="setTime('seven',1)">近七天</view>
</view>
<view class="mt-8 pl-12">
<view class="data-cell w-full flex-between-center py-32">
<view>已返佣</view>
<view class="flex-col">
<text class="fs-36 SemiBold">{{orderData.order_count}}</text>
<text class="fs-22 lh-30rpx pt-12 text--w111-666">订单数</text>
</view>
<view class="flex-col w-120">
<text class="fs-36 SemiBold">{{orderData.brokerage}}</text>
<text class="fs-22 lh-30rpx pt-12 text--w111-666">获得佣金</text>
</view>
<text></text>
<!-- <text class="iconfont icon-ic_rightarrow fs-22 text--w111-666"></text> -->
</view>
<view class="data-cell w-full flex-between-center py-32">
<view>未返佣</view>
<view class="flex-col">
<text class="fs-36 SemiBold">{{orderData.no_order_count}}</text>
<text class="fs-22 lh-30rpx pt-12 text--w111-666">订单数</text>
</view>
<view class="flex-col w-120">
<text class="fs-36 SemiBold">{{orderData.no_brokerage}}</text>
<text class="fs-22 lh-30rpx pt-12 text--w111-666">获得佣金</text>
</view>
<text></text>
<!-- <text class="iconfont icon-ic_rightarrow fs-22 text--w111-666"></text> -->
</view>
</view>
</view>
<view class="w-full bg--w111-fff rd-24rpx px-24 mt-20">
<view class="pt-32 fs-28 fw-500 lh-40rpx">数据统计</view>
<view class="mt-28 w-full h-60 rd-30rpx flex-between-center bg-gold-1">
<view class="tab-item tab-item1 flex-center" :class="viewActive == 0 ? 'tab-active' : 'have-line'" @tap="setTime('all',2)">全部</view>
<view class="tab-item tab-item1 flex-center" :class="viewActive == 1 ? 'tab-active' : 'have-line'" @tap="setTime('today',2)">今日</view>
<view class="tab-item tab-item1 flex-center" :class="viewActive == 2 ? 'tab-active' : 'have-line'" @tap="setTime('yesterday',2)">昨日</view>
<view class="tab-item tab-item1 flex-center" :class="viewActive == 3 ? 'tab-active' : 'have-line'" @tap="setTime('seven',2)">近七天</view>
</view>
<view class="mt-40 grid-column-3 grid-gap-y-48rpx pb-32">
<view class="w-full flex-col pl-12" v-for="(item, index) in statistics" :key="index">
<text class="fs-36 SemiBold" >{{item.value}}</text>
<!-- <baseMoney :money="item.value" symbolSize="24" integerSize="36" decimalSize="36" color="#333333" weight v-else></baseMoney> -->
<view class="flex-y-center text--w111-666 pt-12">
<text class="fs-22 lh-30rpx">{{item.name}}</text>
<!-- <text class="iconfont icon-ic_rightarrow fs-22"></text> -->
</view>
</view>
</view>
</view>
<view class="w-full bg--w111-fff rd-24rpx px-24 mt-20">
<view class="pt-32 fs-28 fw-500 lh-40rpx">用户贡献榜单</view>
<view class="mt-28 w-full h-60 rd-30rpx flex-between-center bg-gold-1">
<!-- -->
<view class="tab-item tab-item2 flex-center"
:class="contributeType == 'order_count' ? 'tab-active' : 'have-line'" @tap="toggleContribute('order_count')">订单数</view>
<view class="tab-item tab-item2 flex-center"
:class="contributeType == 'order_price' ? 'tab-active' : 'have-line'" @tap="toggleContribute('order_price')">订单金额</view>
<view class="tab-item tab-item2 flex-center"
:class="contributeType == 'brokerage' ? 'tab-active' : 'have-line'" @tap="toggleContribute('brokerage')">收益</view>
</view>
<view class="py-32" v-show="contributeData.length">
<view class="flex-between-center fs-22 lh-30rpx text--w111-666 pl-12 mb-28">
<text class="w-44">排名</text>
<text class="w-128">用户</text>
<text class="w-66">订单数</text>
<text class="w-108">订单金额</text>
<text class="w-108">收益</text>
</view>
<view class="flex-between-center rank-cell fs-22 lh-30rpx text--w111-333 pl-12"
v-for="(item,index) in contributeData" :key="index">
<view class="fs-26 w-44">
<text class="w-44 SemiBold rank-1" v-show="index == 0">1</text>
<text class="w-44 SemiBold rank-2" v-show="index == 1">2</text>
<text class="w-44 SemiBold rank-3" v-show="index == 2">3</text>
<text class="w-44 SemiBold text--w111-ccc" v-show="index > 2">{{ index + 1 }}</text>
</view>
<text class="w-128 line1">{{ item.nickname || '微信用户' }}</text>
<text class="w-66">{{ item.total_order_count }}</text>
<text class="w-108">¥{{ item.total_order_price }}</text>
<text class="w-108">¥{{ item.total_brokerage }}</text>
</view>
<view class="flex-center pt-40 text--w111-333" @tap="jumbPath(13)">
<text class="fs-24">查看更多</text>
<text class="iconfont icon-ic_rightarrow fs-24"></text>
</view>
</view>
<view class="py-32" v-show="!contributeData.length">
<emptyPage title="暂无贡献榜单数据~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
<view class="w-full bg--w111-fff rd-24rpx px-24 mt-20">
<view class="pt-32 fs-28 fw-500 lh-40rpx">我的团队</view>
<!-- 团队 代理商 员工 我的推广 -->
<!-- 代理商 员工 我的团队 -->
<!-- 普通用户 员工 一级分销 二级分销 -->
<view class="mt-28 w-full h-60 rd-30rpx flex-between-center bg-gold-1" v-if="brokerageLevel == 2 || promoterType == 1">
<view class="tab-item tab-item3 flex-center"
:class="{'tab-active': teamParams.grade == 0}"
@tap="toggleTeam(0)">{{ promoterType ? '代理商' : '一级分销' }}</view>
<view class="tab-item tab-item3 flex-center"
:class="{'tab-active': teamParams.grade == 1}"
@tap="toggleTeam(1)">{{ promoterType ? '员工' : '二级分销' }}</view>
</view>
<view class="mt-28 w-full h-70 rd-12rpx team-grident pl-20 flex-y-center">
<text class="title-line"></text>
<text class="fs-24 fw-500 lh-34rpx pl-16">团队数据</text>
</view>
<view class="mt-32 grid-column-4">
<view class="w-full flex-col pl-16" v-for="(item, index) in teamStatistics" :key="index">
<text class="fs-36 SemiBold" v-if="item.type == 1">{{item.num}}</text>
<baseMoney :money="item.num" symbolSize="24" integerSize="36" decimalSize="36" color="#333333" weight v-else></baseMoney>
<view class="text--w111-666 pt-12 fs-22 lh-30rpx">{{item.label}}</view>
</view>
</view>
<view class="mt-32 w-full h-70 rd-12rpx team-grident pl-20 flex-y-center">
<text class="title-line"></text>
<text class="fs-24 fw-500 lh-34rpx pl-16">团队成员</text>
</view>
<view class="py-32" v-show="teamList.length">
<view class="flex-between-center fs-22 lh-30rpx text--w111-666 pl-12 mb-28">
<text class="w-176">成员</text>
<text class="w-88">推广人数</text>
<text class="w-108">订单数</text>
<text class="w-108">消费金额</text>
</view>
<view class="flex-between-center rank-cell fs-22 lh-30rpx text--w111-666 pl-12"
v-for="(item,index) in teamList" :key="index">
<view class="w-176 flex-y-center">
<image class="w-40 h-40 rd-50-p111- block mr-8" :src="item.avatar"></image>
<text class="w-128 line1">{{item.nickname}}</text>
</view>
<text class="w-88">{{item.childCount ? item.childCount : 0}}</text>
<text class="w-108">{{item.orderCount ? item.orderCount : 0}}</text>
<text class="w-108">{{item.numberCount ? item.numberCount : 0}}</text>
</view>
<view class="flex-center pt-40" @tap="jumbPath(9)">
<text class="fs-24">查看更多</text>
<text class="iconfont icon-ic_rightarrow fs-24"></text>
</view>
</view>
<view v-show="!teamList.length">
<emptyPage title="暂无团队据~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
<view class="w-full bg--w111-fff rd-24rpx px-24 mt-20">
<view class="pt-32 fs-28 fw-500 lh-40rpx">分销榜单</view>
<view class="mt-28 w-full h-60 rd-30rpx flex-between-center bg-gold-1">
<view class="tab-item tab-item3 flex-center" :class="{'tab-active': rankTab == 0}" @tap="toggleRank(0)">佣金榜单</view>
<view class="tab-item tab-item3 flex-center" :class="{'tab-active': rankTab == 1}" @tap="toggleRank(1)">推广人榜单</view>
</view>
<view v-if="rankList.length">
<view class="mt-32">
<view class="flex-between-center rank2-cell" v-for="(item,index) in rankList" :key="index">
<view class="flex-y-center">
<image :src="'../static/no'+(index + 1)+'.png'" class="w-64 h-64 block mr-28"></image>
<image :src="item.avatar" class="w-80 h-80 rd-50-p111-"></image>
<view class="w-164 line1 lh-40rpx fs-28 lh-40rpx ml-24">{{item.nickname}}</view>
</view>
<view class="fs-28 lh-40rpx" v-show="rankTab == 0">¥{{item.brokerage_price || ''}}</view>
<view class="fs-28 lh-40rpx" v-show="rankTab == 1">{{item.count || ''}}人</view>
</view>
</view>
<view class="flex-center py-32" @tap="jumbPath(rankTab ? 1 : 2)">
<text class="fs-24">查看更多</text>
<text class="iconfont icon-ic_rightarrow fs-24"></text>
</view>
</view>
<view v-else>
<emptyPage title="暂无排行榜数据哦~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
</view>
<BaseCode v-if="isCode" :code="code" :codeImg="codeImg" :isShowCode.sync="isCode"></BaseCode>
</view>
</template>
<script>
import colors from '@/mixins/color.js';
import {
agentLevelList,
spreadPeople,
getBrokerageRank,
getRankList,
spreadOrderIncomeApi,
spreadOverviewApi,
spreadContributeApi,
getAgentCode
} from "@/api/user.js"
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import {HTTP_REQUEST_URL} from '@/config/app';
import home from '@/components/home/index.vue';
import NavBar from "@/components/NavBar.vue";
import emptyPage from '@/components/emptyPage.vue';
import BaseCode from '@/components/BaseCode.vue';
let sysHeight = uni.getWindowInfo().statusBarHeight;
export default {
data() {
return {
imgHost: HTTP_REQUEST_URL,
sysHeight,
isScrolling: false,
userInfo:{
avatar:'',
nickname:'',
uid: 0,
},
viewActive: 0,
statistics:[],
teamStatistics:[
{ label: '团队人数',num:0,type:1},
{ label: '推广人数',num:0,type:1},
{ label: '推广订单数',num:0,type:1},
{ label: '返佣金额',num:'0.00',type:2},
],
levelInfo:{},
levelList:[],
teamList: [], //我的团队
teamParams:{
page:1,
limit:10,
grade: 0
},
rankTab: 0,
rankList: [],
brokerageLevel: 1, //后台开启的分销等级
promoterType: 0, //普通分销用户或者事业部成员
orderActive: 0,
orderData:{},
contributeType: 'order_count',
contributeData:[],
withdraw: "",
isCode: false,
code: "",
codeImg: ""
}
},
mixins: [colors],
components: { home, NavBar, emptyPage, BaseCode },
computed: {
...mapGetters(['isLogin']),
vipCardStyle(){
return {
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/spread_data_bg.png'+')'
}
},
cardBgStyle(){
return {
backgroundImage: 'url('+this.imgHost+'/statics/images/promoter/spread_black_card.png'+')'
}
},
},
onPageScroll(option) {
uni.$emit('scroll');
if (option.scrollTop > 50) {
this.isScrolling = true;
} else if (option.scrollTop < 50) {
this.isScrolling = false;
}
},
onShow() {
this.getUserData();
},
onLoad() {
if(this.isLogin){
// this.getUserData();
this.getTeamList();
this.getRankList(0);
this.getOrderIncome(0,0);
this.getOverviewData(0,0);
this.getContribute();
}else{
toLogin();
}
},
methods: {
getUserData() {
agentLevelList().then((res) => {
this.userInfo = res.data.user;
this.promoterType = res.data.user.division_type;
this.levelInfo = res.data.level_info;
this.levelList = res.data.level_list;
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
toggleTeam(val){
this.teamParams.grade = val;
this.teamList = [];
this.getTeamList();
},
getTeamList(){
spreadPeople(this.teamParams).then(res => {
this.brokerageLevel = res.data.brokerage_level;
this.teamList = res.data.list;
this.teamStatistics[0].num = res.data.count;
this.teamStatistics[1].num = this.teamParams.grade ? res.data.totalLevel : res.data.total;
this.teamStatistics[2].num = res.data.order_count;
this.teamStatistics[3].num = res.data.price.toString();
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
getRankList(val){
let funApi = val == 1 ? getRankList : getBrokerageRank;
funApi({page:1,limit:3,type:'week'}).then(res=>{
this.rankList = val ? res.data.list : res.data.rank;
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
toggleRank(val){
this.rankTab = val;
this.getRankList(val);
},
getOrderIncome(start, stop){
spreadOrderIncomeApi({
page:1,
limit:10,
start,stop
}).then(res=>{
this.orderData = res.data;
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
setTime(time,type) {
let self = this
this.time = time;
let start = '';
let stop = '';
let year = new Date().getFullYear(), month = new Date().getMonth() + 1, day = new Date().getDate();
switch (time) {
case "all":
if(type == 1){
this.orderActive = 0;
this.getOrderIncome(0,0);
}else{
this.viewActive = 0;
this.getOverviewData(0,0)
}
break;
case "today":
start = new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /1000;
stop = new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /1000 + 24 * 60 * 60 - 1;
if(type == 1){
this.orderActive = 1;
this.getOrderIncome(start, stop);
}else{
this.viewActive = 1;
this.getOverviewData(start, stop)
}
break;
case "yesterday":
start = new Date(Date.parse(year + "/" + month + "/" + day)).getTime() / 1000 - 24 * 60 * 60;
stop = new Date(Date.parse(year + "/" + month + "/" + day)).getTime() / 1000 - 1;
if(type == 1){
this.orderActive = 2;
this.getOrderIncome(start, stop);
}else{
this.viewActive = 2;
this.getOverviewData(start, stop)
}
break;
case "seven":
start = new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
7 * 3600 * 24;
stop = new Date(Date.parse(year + "/" + month + "/" + day)).getTime() /
1000 +
24 * 60 * 60 -
1;
if(type == 1){
this.orderActive = 3;
this.getOrderIncome(start, stop);
}else{
this.viewActive = 3;
this.getOverviewData(start, stop)
}
break;
}
},
getOverviewData(start,stop){
spreadOverviewApi({
page:1,
limit:10,
start,stop
}).then(res=>{
this.withdraw = res.data[2].value;
this.statistics = res.data.map(item=>({
...item,
type: typeof item.value === 'number' ? 1 : 2
}));
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
getContribute(){
let params = {
page:1,
limit: 5,
type: this.contributeType
};
spreadContributeApi(this.contributeType, params).then(res=>{
this.contributeData = res.data;
}).catch((err) => {
this.$util.Tips({
title: err
});
});
},
toggleContribute(val){
this.contributeType = val;
this.getContribute();
},
//跳转
jumbPath(type) {
if (type == 'code') {
// #ifdef MP
getAgentCode().then((res) => {
this.codeImg = res.data.url;
this.isCode = true;
});
// #endif
// #ifndef MP
this.code = HTTP_REQUEST_URL + '/pages/users/user_spread_user/index?agent_id=' + this.userInfo.agent_id;
this.$nextTick((e) => {
this.isCode = true;
});
// #endif
}
let path = [
'/pages/users/user_cash/index',
'/pages/users/promoter_rank/index',
'/pages/users/commission_rank/index',
'/pages/users/user_spread_code/index',
'/pages/users/user_vip/index',
'/pages/users/user_spread_code/index',
'/pages/users/user_spread_money/index?type=1',
'/pages/users/user_spread_money/index?type=4',
'/pages/users/promoter-order/index',
`/pages/users/promoter-list/index${this.userInfo.division_type == 1?'?type=1': ''}`,
'/pages/users/user_distribution_level/index',
'/pages/users/user_distribution_info/index',
'/pages/users/agent/staff_list',
'/pages/users/spreadData/contributionRank'
];
uni.navigateTo({
url: path[type]
});
},
createCode(){
// #ifdef MP
getAgentCode().then((res) => {
this.codeImg = res.data.url;
this.isCode = true;
});
// #endif
// #ifndef MP
this.code = HTTP_REQUEST_URL + '/pages/users/user_spread_user/index?agent_id=' + this.userInfo.agent_id;
this.$nextTick((e) => {
this.isCode = true;
});
// #endif
}
}
}
</script>
<style scoped lang="scss">
.top-card{
background: linear-gradient(360deg, #F5F5F5 0%, rgba(28, 26, 27, 0.72) 16%, #353334 28%, #1C1A1B 53%);
}
.text-color1{
color: #FCF0C6;
}
.text--w111-f7f0df{
color: #F7F0DF;
}
.max-w-200{
max-width: 200rpx;
}
.op-60{
opacity: 0.6;
}
.opacity-tag{
background: rgba(255,255,255,0.1);
margin-left: 8rpx;
}
.qrcode-btn{
width: 126rpx;
height: 48rpx;
background: rgba(252,240,198,0.2);
border-radius: 92rpx 0rpx 0rpx 92rpx;
color: #FCDD92;
}
.vip-card{
margin-top: -32rpx;
width: 100%;
height: 326rpx;
background-size: contain;
background-repeat: no-repeat;
}
.gradient-gold{
background: linear-gradient( 270deg, #F7DDA2 0%, #FFF2C3 100%);
}
.bg-gold-1{
background-color: rgba(247, 221, 162, 0.2);
}
.tab-item{
height: 60rpx;
font-size: 22rpx;
color: #666666;
}
.tab-item1{
width: 164rpx;
}
.tab-item2{
width: 220rpx;
}
.tab-item3{
width: 331rpx;
}
.tab-active{
border-radius: 30rpx;
background: #F9D47C;
color: #333333;
font-weight: 500;
}
.grid-gap-y-48rpx{
row-gap: 48rpx;
}
.data-cell ~ .data-cell{
border-top: 2rpx solid #F5F5F5;
}
.rank-1{
color: #E73E05;
}
.rank-2{
color: #E26F04;
}
.rank-3{
color: #F4BB00;
}
.rank-cell ~ .rank-cell{
margin-top: 40rpx;
}
.rank2-cell ~ .rank2-cell{
margin-top: 48rpx;
}
.team-grident{
background: linear-gradient( to right, #F9F9F9 0%, rgba(249,249,249,0) 100%);
}
.title-line{
width: 6rpx;
height: 22rpx;
background: #F9D47C;
border-radius: 3rpx;
}
.have-line{
position: relative;
}
.have-line + .have-line::before {
content: '';
width: 1px;
height: 28rpx;
background-color: rgba(196, 186, 157, 1);
position: absolute;
left: -1px;
top: 16rpx;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
pages/users/static/fxbg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
pages/users/static/gz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
pages/users/static/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
pages/users/static/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
pages/users/static/lock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
pages/users/static/no1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
pages/users/static/no2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
pages/users/static/no3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
pages/users/static/sj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 940 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1018 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,372 @@
<template>
<view>
<view class="w-full fixed-lt z-20" :style="{ 'padding-top': sysHeight + 'px' }">
<view class="h-80 px-20 flex-between-center">
<text class="iconfont icon-ic_leftarrow fs-40 text--w111-fff" @tap="pageBack"></text>
</view>
</view>
<view class="header-top relative" :style="[headerBg]">
<view class="rule-btn w-124 flex-center fs-24 text--w111-fff" :style="{ top: 100 + sysHeight + 'px' }" @tap="goRecord">申请记录</view>
</view>
<view class="bg-v-gradient pl-20 pr-20 pb-24" :style="{ minHeight: mainHeight + 'px' }">
<view class="bg--w111-fff rd-24rpx content-box">
<view class="fs-30 fw-500 lh-42rpx">请填写以下信息</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">供应商名称</view>
<input type="text" v-model="form.system_name" placeholder="请输入供应商名称" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">用户姓名</view>
<input type="text" v-model="form.name" placeholder="请输入姓名" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">联系电话</view>
<input type="number" v-model="form.phone" placeholder="请输入手机号" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
</view>
<view v-if="supplierApplyPhoneVerify" class="cell flex-between-center mt-64">
<view class="fs-28 lh-40rpx">验证码</view>
<view class="flex-y-center">
<input type="number" v-model="form.captcha" placeholder="请输入验证码" placeholder-class="text--w111-ccc" class="fs-28 text-right" />
<button class="code-btn w-168 h-56 flex-center fs-24 ml-20" :disabled="disabled" @tap="code">{{ text }}</button>
</view>
</view>
<view class="fs-28 lh-40rpx mt-64">请上传营业执照及相关资质证明图片</view>
<view class="fs-24 lh-34rpx text--w111-ccc mt-12">(图片最多可上传8张,图片格式支持JPG、PNG、JPEG)</view>
<view class="grid-column-4 grid-gap-24rpx mt-24">
<view class="relative h-148" v-for="(item, index) in form.images" :key="index">
<image :src="item" mode="aspectFill" class="w-148 h-148 rd-16rpx"></image>
<view class="abs-rt w-32 h-32 del-pic flex-center fs-24" @click="DelPic(index)">
<text class="iconfont icon-ic_close text--w111-fff"></text>
</view>
</view>
<view class="h-148 flex-col flex-center upload bg--w111-f5f5f5 text--w111-999 rd-16rpx" @click="uploadpic" v-if="form.images.length < 8">
<text class="iconfont icon-ic_camera fs-42"></text>
<text class="fs-24 lh-34rpx pt-8">上传图片</text>
</view>
</view>
<view class="cell mt-64">
<view class="fs-28 lh-40rpx">申请说明</view>
<view class="text--w111-ccc mt-12">
{{ supplier_apply_explain }}
</view>
</view>
<view class="flex-y-center mt-32">
<text class="iconfont fs-30" :class="isSelect ? 'icon-a-ic_CompleteSelect' : 'icon-ic_unselect'" @tap="proviceSelect"></text>
<text class="fs-24 text--w111-999 pl-12">已阅读并同意</text>
<text class="font-red" @tap="getAgreement">《供应商协议》</text>
</view>
<view class="w-full h-88 rd-44rpx flex-center text--w111-fff fs-28 mt-48" :class="isSelectStar ? 'bg-red' : 'bg-disabled'" @tap="submitSupply">提交申请</view>
</view>
</view>
<Verify @success="success" :captchaType="captchaType" :imgSize="{ width: '330px', height: '155px' }" ref="verify"></Verify>
<tui-modal :show="showModal" maskClosable custom @cancel="hideModal">
<view class="tui-modal-custom">
<view class="fs-32 fw-500 lh-44rpx text-center">供应商协议</view>
<view class="fs-28 text--w111-666 lh-44rpx mt-24 desc-box">
<!-- #ifdef MP-WEIXIN -->
<rich-text :nodes="supplierAgreement"></rich-text>
<!-- #endif -->
<!-- #ifdef H5 || APP-PLUS -->
<view v-html="supplierAgreement"></view>
<!-- #endif -->
</view>
<view class="w-full h-72 rd-36rpx flex-center bg-red fs-26 text--w111-fff mt-32" @tap="hideModal">知道了</view>
</view>
</tui-modal>
</view>
</template>
<script>
let sysHeight = uni.getWindowInfo().statusBarHeight;
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import { spplyCreateApi, getCodeApi, registerVerify, userApply, getUserAgreement } from '@/api/user.js';
import colors from '@/mixins/color';
import sendVerifyCode from '@/mixins/SendVerifyCode';
import { HTTP_REQUEST_URL, CAPTCHA_TYPE } from '@/config/app';
import Verify from '../components/verify/verify.vue';
import tuiModal from '@/components/tui-modal/index.vue';
export default {
data() {
return {
captchaType: CAPTCHA_TYPE,
sysHeight: sysHeight,
form: {
system_name: '',
name: '',
phone: '',
captcha: '',
images: []
},
canvasWidth: '',
canvasHeight: '',
canvasStatus: false,
isSelect: false,
keyCode: '',
id: 0,
showModal: false,
supplierAgreement: '',
tagStyle: {
img: 'width:100%;display:block;'
},
supplier_apply_explain: ''
};
},
components: {
Verify,
tuiModal
},
mixins: [sendVerifyCode, colors],
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
// #ifndef MP
this.getOrderProduct();
// #endif
}
},
deep: true
}
},
computed: {
...mapGetters(['isLogin', 'supplierApplyPhoneVerify']),
isSelectStar() {
if (this.form.system_name && this.form.name && this.form.phone && this.form.images.length) {
if (this.supplierApplyPhoneVerify && !this.form.captcha) return false;
return true;
}
},
headerBg() {
return {
backgroundImage: 'url(' + HTTP_REQUEST_URL + '/statics/images/supplier/apply_header.png' + ')'
};
},
mainHeight() {
let { windowHeight } = uni.getWindowInfo();
return windowHeight - 90 - this.sysHeight;
}
},
onLoad(options) {
this.id = options.id || 0;
if (options.id) {
this.getInfo();
}
this.supplier_apply_explain = this.$store.state.app.supplier_apply_explain;
},
methods: {
/*** 删除图片* */
DelPic: function (index) {
let that = this,
pic = this.form.images[index];
that.form.images.splice(index, 1);
that.$set(that.form, 'images', that.form.images);
},
/*** 上传文件 **/
uploadpic: function () {
let that = this;
this.canvasStatus = true;
that.$util.uploadImageChange(
{ count: 8, url: 'upload/image' },
function (res) {
if (that.form.images.length < 8) that.form.images.push(res.data.url);
},
(res) => {
this.canvasStatus = false;
},
(res) => {
this.canvasWidth = res.w;
this.canvasHeight = res.h;
}
);
},
code() {
if (!this.form.phone)
return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.form.phone))
return this.$util.Tips({
title: '请输入正确的手机号码'
});
this.$refs.verify.show();
},
success(data) {
this.$refs.verify.hide();
if (this.supplierApplyPhoneVerify) {
getCodeApi()
.then((res) => {
this.keyCode = res.data.key;
this.getCode(data);
})
.catch((res) => {
this.$util.Tips({
title: res
});
});
} else {
this.supplierRequset();
}
},
async getCode(data) {
let that = this;
if (!this.form.phone)
return that.$util.Tips({
title: '请填写手机号码'
});
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.form.phone))
return this.$util.Tips({
title: '请输入正确的手机号码'
});
await registerVerify({
phone: that.form.phone,
type: 'supplier',
key: that.keyCode,
captchaType: CAPTCHA_TYPE,
captchaVerification: data.captchaVerification
})
.then((res) => {
that.$util.Tips({
title: res.msg
});
that.sendCode();
})
.catch((res) => {
this.$refs.verify.refresh();
that.$util.Tips({
title: res
});
});
},
proviceSelect() {
this.isSelect = !this.isSelect;
},
getInfo() {
userApply(this.id)
.then((res) => {
let data = res.data;
this.form.system_name = data.system_name;
this.form.name = data.name;
this.form.phone = data.phone;
this.form.images = data.images;
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
submitSupply() {
if (!this.isSelectStar)
return this.$util.Tips({
title: '请完整填写表单信息'
});
if (!this.isSelect)
return this.$util.Tips({
title: '请阅读并同意协议'
});
if (this.supplierApplyPhoneVerify) {
this.supplierRequset();
} else {
this.code()();
}
},
supplierRequset() {
spplyCreateApi(this.id, this.form)
.then((res) => {
uni.showToast({
title: res.msg
});
uni.navigateTo({
url: '/pages/users/supplier/state?id=' + res.data.id
});
})
.catch((err) => {
return this.$util.Tips({
title: err
});
});
},
pageBack() {
uni.navigateBack();
},
goRecord() {
uni.navigateTo({
url: '/pages/users/supplier/record'
});
},
getAgreement() {
getUserAgreement('supplier')
.then((res) => {
this.supplierAgreement = res.data.content;
this.showModal = true;
})
.catch((err) => {
that.$util.Tips({
title: err.msg
});
});
},
hideModal() {
this.showModal = false;
}
}
};
</script>
<style>
.header-top {
width: 100%;
height: 358rpx;
background-size: cover;
}
.rule-btn {
height: 48rpx;
background: rgba(0, 0, 0, 0.15);
border-radius: 24rpx 0 0 24rpx;
position: absolute;
right: 0;
}
.bg-v-gradient {
background: linear-gradient(180deg, #fe7015 0%, #eb3b26 100%);
}
.content-box {
padding: 48rpx 32rpx 40rpx;
}
.code-btn {
border: 1px solid #e93323;
color: #e93323;
border-radius: 28rpx;
}
.upload {
border: 1rpx dashed #ccc;
}
.del-pic {
background-color: #999;
border-radius: 0 16rpx 0 16rpx;
}
.icon-a-ic_CompleteSelect,
.font-red {
color: #e93323;
}
.icon-ic_unselect {
color: #ccc;
}
.bg-red {
background-color: #e93323;
}
.bg-disabled {
background-color: rgba(233, 51, 35, 0.5);
}
.desc-box {
max-height: 700rpx;
overflow-y: auto;
}
.modal-bottom {
height: 136rpx;
border-radius: 0 0 32rpx 32rpx;
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,121 @@
<template>
<view>
<view class="px-20">
<view class="w-full bg--w111-fff rd-24rpx flex-between-center mt-24 p-32"
v-for="(item,index) in list" :key="index">
<view>
<view class="flex-y-center">
<text class="fs-30 lh-42rpx max-300 line1">{{item.system_name}}</text>
<text class="tag tag0 fs-22 ml-16" :class="'tag' + item.status">{{item.status | typeFilter}}</text>
</view>
<view class="fs-24 text--w111-999 mt-20">提交时间:{{item.add_time}}</view>
<view class="fs-24 text--w111-999 mt-20" v-if="item.status==2">原因:{{item.fail_msg}}</view>
</view>
<text class="btn info-btn fs-24" @tap="lookUp(item)" v-if="item.status==1">查看</text>
<text class="btn danger-btn fs-24" @tap="resubmit(item)" v-else-if="item.status==2">重新提交</text>
<text class="btn info-btn fs-24" @tap="edit(item)" v-else>编辑</text>
</view>
<view class="mt-20" v-if="list.length == 0">
<emptyPage title="暂无申请记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
</view>
</template>
<script>
import { recordList } from '@/api/user.js';
import colors from '@/mixins/color.js';
import emptyPage from '@/components/emptyPage.vue';
export default{
mixins: [colors],
components: {
emptyPage,
},
data(){
return{
list:[]
}
},
filters:{
typeFilter(val){
let obj = {
0: '待审核',
1: '审核通过',
2: '审核未通过'
};
return obj[val]
},
},
onLoad(){
this.getList();
},
methods:{
getList(){
recordList().then(res=>{
this.list = res.data;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
edit(item){
uni.navigateTo({
url: '/pages/users/supplier/index?id='+ item.id
})
},
resubmit(item){
uni.navigateTo({
url: '/pages/users/supplier/state?id='+ item.id+'&type=2'
})
},
lookUp(item){
uni.navigateTo({
url: '/pages/users/supplier/state?id='+ item.id+'&type=1'
})
}
}
}
</script>
<style>
.max-300{
max-width: 300rpx;
}
.tag{
height: 38rpx;
padding: 0 8rpx;
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 8rpx;
}
.tag0{
color: rgba(0, 122, 255, 1);
background-color: rgba(0, 122, 255, 0.1);
}
.tag1{
color: rgba(0, 180, 42, 1);
background-color: rgba(0, 180, 42, 0.1);
}
.tag2{
color: rgba(245, 63, 63, 1);
background-color: rgba(245, 63, 63, 0.1);
}
.btn{
height: 56rpx;
padding: 0 24rpx;
display: inline-flex;
justify-content: center;
align-items: center;
border-radius: 30rpx;
}
.info-btn{
border: 1px solid #ccc;
color: #333;
}
.danger-btn{
border: 1px solid #e93323;
color: #e93323;
}
</style>

View File

@@ -0,0 +1,198 @@
<template>
<view>
<view class="px-20 mt-40">
<view class="bg--w111-fff rd-24rpx card-bg">
<view class="h-244 pt-72">
<view class="px-122 flex-between-center">
<text class="iconfont icon-a-ic_CompleteSelect font-red fs-28"></text>
<view class="line bg-red mx-8"></view>
<text class="iconfont icon-a-ic_CompleteSelect font-red fs-28"></text>
<view class="line mx-8" :class="type > 0 ? 'bg-red' : 'bg-gray'"></view>
<text class="iconfont fs-28" :class="type > 0 ? 'icon-a-ic_CompleteSelect font-red' : 'icon-ic_unselect text--w111-ccc'"></text>
</view>
<view class="flex-between-center px-74 fs-28 lh-40rpx mt-24">
<text>提交成功</text>
<text>正在审核</text>
<text>审核结果</text>
</view>
<view class="flex-between-center px-40 mt-8 fs-22 text--w111-999">
<text>{{add_time}}</text>
<text>{{add_time}}</text>
<text v-if="status_time">{{status_time}}</text>
<text v-else class="w-180"></text>
</view>
</view>
<view class="flex-col flex-center content-box">
<image :src="imgHost + '/statics/images/supplier/verify_fail_icon.png'" class="status-pic" v-if="type == 2"></image>
<image :src="imgHost + '/statics/images/supplier/verify_ing_icon.png'" class="status-pic" v-else-if="type == 0"></image>
<image :src="imgHost + '/statics/images/supplier/verify_ok_icon.png'" class="status-pic" v-else-if="type == 1"></image>
<text class="fs-36 lh-50rpx pt-32">{{type | typeFilter}}</text>
<text class="fs-26 lh-36rpx text--w111-999 pt-12">{{type | descFilter}}</text>
<view class="primary-btn flex-center fs-28 mt-40" @tap="edit">{{type == 2 ? '重新填写' : '返回上一页'}}</view>
<view class="border-btn flex-center fs-28 mt-24" v-if="type == 2" @tap="pageBack">返回上一页</view>
</view>
</view>
<view class="bg--w111-fff rd-24rpx mt-20 pt-40 pr-24 pb-40 pl-24 fs-28 lh-40rpx" v-if="type == 1">
<view class="flex-between-center">
<text>后台网址</text>
<text>{{url}}</text>
</view>
<view class="flex-between-center mt-40">
<text>后台账号</text>
<text>{{account}}</text>
</view>
<view class="flex-between-center mt-40">
<text>登录密码</text>
<view class="flex-y-center">
<text class="pr-12">{{pwd}}</text>
<view class="copy-btn flex-center fs-20" @tap="copyWb">复制</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { HTTP_REQUEST_URL } from '@/config/app';
import colors from '@/mixins/color.js';
import { userApply } from '@/api/user.js';
export default{
mixins: [colors],
data(){
return{
imgHost:HTTP_REQUEST_URL,
id:0,
type:2,
url:'',
account:'',
pwd:'',
status_time:'',
add_time:''
}
},
filters:{
typeFilter(val){
let obj = {
0: '正在审核',
1: '审核通过',
2: '审核失败'
};
return obj[val]
},
descFilter(val){
let obj = {
0: '正在审核当中,请耐心等待',
1: '恭喜您,审核通过',
2: '请按提示修改您所填写的信息'
};
return obj[val]
}
},
onLoad(options){
this.id = options.id;
this.type = options.type || 0;
if(options.id){
this.supplierApply();
}
},
methods:{
copyWb: function() {
let that = this;
uni.setClipboardData({
data: '网址:'+this.url+'\n账号:'+this.account+'\n密码:'+this.pwd
});
},
supplierApply(){
userApply(this.id).then(res=>{
let data = res.data;
this.url = data.url;
this.add_time = data.add_time;
this.status_time = data.status_time;
this.account = data.account;
this.type = data.status;
this.pwd = data.pwd;
}).catch(err=>{
return this.$util.Tips({
title: err
});
})
},
pageBack(){
uni.switchTab({
url: '/pages/user/index'
})
},
edit(){
if(this.type ==0 || this.type == 1){
uni.switchTab({
url: '/pages/user/index'
})
}else{
uni.reLaunch({
url: '/pages/users/supplier/index?id=' + this.id
})
}
},
}
}
</script>
<style scoped>
.card-bg{
-webkit-mask: radial-gradient(circle at 16rpx 240rpx, transparent 16rpx, red 0) -16rpx;
}
.font-red{
color: #e93323;
}
.h-244{
height:244rpx;
border-bottom: 1px dashed #ccc;
}
.px-74{
padding: 0 74rpx;
}
.px-122{
padding: 0 122rpx;
}
.pt-72{
padding-top: 72rpx;
}
.line{
width: 186rpx;
height: 1rpx;
}
.bg-red{
background-color: #e93323;
}
.bg-gray{
background-color: #DDDDDD;
}
.status-pic{
width: 172rpx;
height: 154rpx;
}
.content-box{
padding: 48rpx 0 72rpx;
}
.primary-btn{
width: 502rpx;
height: 88rpx;
background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
color: #fff;
border-radius: 50rpx;
}
.border-btn{
width: 502rpx;
height: 88rpx;
background: #fff;
border: 1px solid #E93323;
color: #E93323;
border-radius: 50rpx;
}
.copy-btn{
width: 64rpx;
height: 32rpx;
background: #F5F5F5;
border-radius: 20rpx;
}
</style>

View File

@@ -0,0 +1,301 @@
<template>
<!-- 添加新地址 -->
<view :style="colorStyle">
<form @submit="formSubmit">
<view class='addAddress'>
<view class="rd-16rpx bg--w111-fff p-24 mb-20">
<textarea class="w-full fs-30 h-140"
v-model="addressValue"
placeholder="粘贴地址信息,自动拆分姓名、电话和地址"
wrap-style="wrap"
:always-embed="true"
:adjust-position="true"
cursor-spacing="85rpx"
:maxlength="200"
name="desc"
@blur="identify()"/>
</view>
<view class="input-wrapper">
<view class='list'>
<view class='item acea-row row-between-wrapper'>
<view class='name'>姓名</view>
<input type='text' placeholder='请输入姓名' name='real_name' :value="userAddress.real_name" placeholder-class='placeholder'></input>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>联系电话</view>
<input type='number' maxlength="11" placeholder='请输入联系电话' name="phone" :value='userAddress.phone' placeholder-class='placeholder' pattern="\d*"></input>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>所在地区</view>
<view class="address acea-row row-between-wrapper">
<view class="addressCon acea-row" @click="changeRegion">
<text class="picker color-add" v-if="!addressInfo.length">请选择地址</text>
<view v-else>
<text class="picker">{{addressText}}</text>
</view>
</view>
<view class="location1" @click="chooseLocation">
<text class="iconfont icon-ic_location1 text-primary"></text>定位
</view>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>详细地址</view>
<view class="address">
<input type='text' placeholder='请填写具体地址' name='detail' placeholder-class='placeholder' :value='userAddress.detail' class="detail"></input>
</view>
</view>
</view>
</view>
<button class='keepBnt' form-type="submit">立即保存</button>
</view>
</form>
<areaWindow ref="areaWindow" :display="display" :address="addressInfo" @submit="OnChangeAddress" @changeClose="changeClose"></areaWindow>
</view>
</template>
<script>
import {getGeocoder,getCityList} from '@/api/user.js';
import {mapGetters} from "vuex";
import colors from '@/mixins/color.js';
import areaWindow from '@/components/areaWindow';
import AddressParse from '../components/zh-address-parse.min.js'
export default {
components: {
areaWindow,
},
mixins: [colors],
data() {
return {
id: 0, //地址id
userAddress: {}, //地址详情
district: [],
display: false,
addressInfo: [],
addressVal: '',
latitude: '',
longitude: '',
city_id: 0,
addressValue: "",
};
},
computed: {
...mapGetters(['isLogin']),
addressText() {
return this.addressInfo.map(v => v.label).join('/');
}
},
onLoad(options) {
},
methods: {
changeRegion() {
this.display = true;
},
OnChangeAddress(address) {
this.latitude = ''
this.longitude = ''
this.addressInfo = address;
},
// 关闭地址弹窗;
changeClose: function() {
this.display = false;
},
// 获取选中位置
chooseLocation: function() {
let self = this;
uni.chooseLocation({
success: (res) => {
let latitude, longitude;
latitude = res.latitude.toString();
longitude = res.longitude.toString();
this.latitude = res.latitude
this.longitude = res.longitude
getGeocoder({
lat: latitude,
long: longitude
}).then(res => {
const data = res.data;
getCityList(data.address_component.province + '/' + data.address_component.city + '/' + data.address_component.district + '/' + (!data
.address_reference.town ? '' : data.address_reference.town.title)).then(res => {
self.addressInfo = res.data;
self.userAddress.detail = data.formatted_addresses.recommend;
}).catch(err => {
self.$util.Tips({
title: err
});
});
})
},
fail: (err) => {
console.log(err)
}
})
},
/**
* 提交用户添加地址
*
*/
formSubmit: function(e) {
let that = this,
value = e.detail.value;
if (!value.real_name) 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.addressInfo.length) return that.$util.Tips({
title: '请选择所在地区'
});
if (that.addressInfo.length < 3) return that.$util.Tips({
title: '请补全所在地区信息'
});
if (!value.detail) return that.$util.Tips({
title: '请填写详细地址'
});
value.id = 0;
let regionArray = that.addressInfo;
value.address = {
province: regionArray[0].label,
city: regionArray[1].label,
district: regionArray[2].label,
street: regionArray[3] ? regionArray[3].label : '',
city_id: regionArray[regionArray.length - 1].id ? regionArray[regionArray.length - 1].id : that.city_id,
};
uni.$emit("refresh", value)
uni.navigateBack()
},
identify() {
const options = {
type: 0, // 哪种方式解析,0:正则,1:树查找
textFilter: [], // 预清洗的字段
nameMaxLength: 4, // 查找最大的中文名字长度
}
const parseResult = AddressParse(this.addressValue.trim(), options)
// type参数0表示使用正则解析,1表示采用树查找, textFilter地址预清洗过滤字段。
if (this.addressValue.trim()) {
getCityList(parseResult.province + '/' + parseResult.city + '/' + parseResult.area).then(res => {
this.addressInfo = res.data;
this.userAddress.phone = parseResult.phone;
this.userAddress.real_name = parseResult.name;
this.userAddress.detail = parseResult.detail;
}).catch(err => {
return this.$util.Tips({
title: err
});
})
}
}
}
}
</script>
<style scoped lang="scss">
.color-add {
color: #cdcdcd;
}
.location1 {
.iconfont {
margin-right: 8rpx;
}
}
.text-primary {
color: $primary-admin;
}
.addAddress {
padding: 24rpx 20rpx;
}
.addAddress .input-wrapper {
margin-bottom: 20rpx;
}
.addAddress .list {
padding: 8rpx 0;
border-radius: 16rpx;
background-color: #fff;
}
.addAddress .list .item {
padding: 32rpx 24rpx;
position: relative;
}
.addAddress .list .item .detail {
width: 368rpx;
}
.addAddress .list .item .location {
position: absolute;
right: 46rpx;
top: 50%;
margin-top: -40rpx !important;
font-size: 24rpx;
text-align: center;
}
.addAddress .list .item .icon-dizhi {
font-size: 36rpx !important;
}
.addAddress .list .item .name {
width: 195rpx;
font-size: 30rpx;
color: #333;
}
.addAddress .list .item .address {
// width: 412rpx;
flex: 1;
// margin-left: 20rpx;
}
.addAddress .list .item .address .addressCon {
width: 360rpx;
}
.addAddress .list .item .address .addressCon .tip {
font-size: 21rpx;
margin-top: 4rpx;
}
.addAddress .list .item input {
flex: 1;
font-size: 30rpx;
}
.placeholder {
color: #ccc;
}
.addAddress .list .item .picker {
width: 430rpx;
font-size: 30rpx;
}
.addAddress .list .item .iconfont {
font-size: 30rpx;
margin-top: 4rpx;
}
.addAddress .keepBnt {
position: fixed;
right: 20rpx;
bottom: 40rpx;
left: 20rpx;
height: 80rpx;
border-radius: 40rpx;
text-align: center;
line-height: 80rpx;
font-size: 28rpx;
color: #fff;
background-color: $primary-admin;
}
</style>

View File

@@ -0,0 +1,669 @@
<template>
<!-- 添加新地址 -->
<view :style="colorStyle">
<form @submit="formSubmit">
<view class='addAddress'>
<!-- #ifdef MP -->
<view v-if="!id" class="wechatAddress acea-row row-between-wrapper" @click="getWxAddress">
<view class="acea-row row-middle"><text class="iconfont icon-ic_wechat"></text>获取微信收货地址</view>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
<!-- #endif -->
<!-- #ifdef H5 -->
<view v-if="this.$wechat.isWeixin() && !id" class="wechatAddress acea-row row-between-wrapper" @click="getAddress">
<view class="acea-row row-middle"><text class="iconfont icon-ic_wechat"></text>获取微信收货地址</view>
<text class="iconfont icon-ic_rightarrow"></text>
</view>
<!-- #endif -->
<view class="rd-16rpx bg--w111-fff p-24 mb-20">
<textarea class="w-full fs-30 h-140"
v-model="addressValue"
placeholder="粘贴地址信息,自动拆分姓名、电话和地址"
wrap-style="wrap"
:always-embed="true"
:adjust-position="true"
cursor-spacing="85rpx"
:maxlength="200"
name="desc"
@blur="identify()"/>
</view>
<view class="input-wrapper">
<view class='list'>
<view class='item acea-row row-between-wrapper'>
<view class='name'>姓名</view>
<input type='text' placeholder='请输入姓名' name='real_name' :value="userAddress.real_name" placeholder-class='placeholder' />
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>联系电话</view>
<input type='number' maxlength="11" placeholder='请输入联系电话' name="phone" :value='userAddress.phone' placeholder-class='placeholder' pattern="\d*" />
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>所在地区</view>
<view class="address acea-row row-between-wrapper">
<view class="addressCon acea-row" @click="changeRegion">
<text class="picker color-add" v-if="!addressInfo.length">请选择地址</text>
<view v-else>
<text class="picker">{{addressText}}</text>
</view>
</view>
<view class="location1" @click="chooseLocation">
<text class="iconfont icon-ic_location1 fontcolor"></text>定位
</view>
</view>
</view>
<view class='item acea-row row-between'>
<view class='name'>详细地址</view>
<view class="address">
<textarea :value="userAddress.detail" name="detail" auto-height placeholder="请填写具体地址" placeholder-class="placeholder" class="lh-42rpx w-full" />
<!-- <input type='text' placeholder='请填写具体地址' name='detail' placeholder-class='placeholder' :value='userAddress.detail' class="w-full"></input> -->
</view>
</view>
</view>
</view>
<view class="default acea-row row-between-wrapper">
<view>设置为默认地址</view>
<view :class="{ on: userAddress.is_default }" class="switch" @click="ChangeIsDefault">
<view class="inner"></view>
</view>
</view>
<view class="fixed-btn">
<button class='keepBnt btn bg-color' form-type="submit">立即保存</button>
<view v-if="id" class='delbtn btn mt-12' @click="delAddress">删除</view>
</view>
</view>
</form>
<areaWindow ref="areaWindow" :display="display" :address="addressInfo" @submit="OnChangeAddress" @changeClose="changeClose"></areaWindow>
<home></home>
<tuiModal :show="showModal" title="提示" content="确认删除地址?" :maskClosable="false" @click="handleClick"></tuiModal>
</view>
</template>
<script>
import {
editAddress,
getAddressDetail,
getGeocoder,
getCityList,
delAddress
} from '@/api/user.js';
import {
getCityData
} from '@/api/api.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import colors from '@/mixins/color.js';
import areaWindow from '@/components/areaWindow';
import AddressParse from '../components/zh-address-parse.min.js'
import tuiModal from '@/components/tui-modal/index.vue';
export default {
components: {
areaWindow,
tuiModal
},
mixins: [colors],
data() {
return {
cartId: '', //购物车id
pinkId: 0, //拼团id
couponId: 0, //优惠券id
id: 0, //地址id
userAddress: {
is_default: false
}, //地址详情
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
district: [],
news: '',
noCoupon: 0,
display: false,
showModal: false,
addressInfo: [],
addressVal: '',
latitude: '',
longitude: '',
city_id: 0,
addressValue: "",
deliveryType: 1, //配送方式
store_name: '', //门店名称
storeId: 0, //门店id
product_id: 0 //商品id
};
},
computed: {
...mapGetters(['isLogin']),
addressText() {
return this.addressInfo.map(v => v.label).join('/');
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
//#ifndef MP
this.getUserAddress();
//#endif
}
},
deep: true
}
},
onLoad(options) {
this.cartId = options.cartId || '';
this.pinkId = options.pinkId || 0;
this.couponId = options.couponId || 0;
this.id = options.id || 0;
this.noCoupon = options.noCoupon || 0;
this.news = options.new || '';
this.deliveryType = options.delivery_type || 1;
this.store_name = options.store_name;
this.storeId = options.store_id;
this.product_id = options.product_id;
uni.setNavigationBarTitle({
title: options.id ? '修改地址' : '添加地址'
})
if (this.isLogin) {
this.getUserAddress();
// this.getCityList();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
onLoadFun() {
this.getUserAddress();
this.isShowAuth = false;
},
/**
* 删除地址
*/
handleClick(e){
let index = e.index;
if (index == 1) {
delAddress(this.id).then(res => {
this.$util.Tips({
title: '删除成功',
icon: 'success'
}, function() {
uni.navigateBack()
});
}).catch(err => {
return this.$util.Tips({
title: err
});
});
} else {
this.showModal = false;
}
},
delAddress() {
this.showModal = true
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
changeRegion() {
this.display = true;
},
OnChangeAddress(address) {
this.latitude = ''
this.longitude = ''
this.addressInfo = address;
},
// 地址数据
// getCityList: function() {
// let that = this;
// getCityData(0).then(res => {
// this.district = res.data
// })
// },
// 关闭地址弹窗;
changeClose: function() {
this.display = false;
},
getUserAddress: function() {
if (!this.id) return false;
let that = this;
getAddressDetail(this.id).then(res => {
let region = [{
label: res.data.province
}, {
label: res.data.city
}, {
label: res.data.district
}, {
label: res.data.street
}];
that.$set(that, 'userAddress', res.data);
that.addressInfo = res.data.city_list;
that.latitude = res.data.latitude;
that.longitude = res.data.longitude;
that.city_id = res.data.city_id;
});
},
// 获取选中位置
chooseLocation: function() {
let self = this;
uni.chooseLocation({
success: (res) => {
let latitude, longitude;
latitude = res.latitude.toString();
longitude = res.longitude.toString();
this.latitude = res.latitude
this.longitude = res.longitude
getGeocoder({
lat: latitude,
long: longitude
}).then(res => {
const data = res.data;
getCityList(data.address_component.province + '/' + data.address_component.city + '/' + data.address_component.district + '/' + (!data
.address_reference.town ? '' : data.address_reference.town.title)).then(res => {
self.addressInfo = res.data;
self.userAddress.detail = data.formatted_addresses.recommend;
}).catch(err => {
return self.$util.Tips({
title: err
});
});
}).catch(err=>{
return self.$util.Tips({
title: err
});
})
},
fail: (err) => {
console.log(err)
}
})
},
// 自动定位
selfLocation() {
let self = this
uni.showLoading({
title: '定位中',
mask: true,
});
uni.getLocation({
type: 'gcj02',
success: (res) => {
let latitude, longitude;
latitude = res.latitude.toString();
longitude = res.longitude.toString();
this.latitude = res.latitude
this.longitude = res.longitude
getGeocoder({
lat: latitude,
long: longitude
}).then(res => {
const data = res.data;
getCityList(data.address_component.province + '/' + data.address_component.city + '/' + data.address_component.district + '/' + (!data.address_reference
.town ? '' : data.address_reference.town.title)).then(res => {
self.addressInfo = res.data;
self.userAddress.detail = data.formatted_addresses.recommend;
uni.hideLoading();
})
})
},
fail: (res) => {
uni.hideLoading();
uni.showToast({
title: res,
icon: 'none',
duration: 1000
});
}
});
},
// 导入共享地址(小程序)
getWxAddress: function() {
let that = this;
uni.authorize({
scope: 'scope.address',
success: function(res) {
uni.chooseAddress({
success: function(res) {
getCityList(res.provinceName + '/' + res.cityName + '/' + res.countyName + '/' + res.streetName).then(res => {
that.addressInfo = res.data;
}).catch(err=>{
return that.$util.Tips({
title: err
});
})
that.userAddress.real_name = res.userName;
that.userAddress.phone = res.telNumber;
that.userAddress.detail = res.detailInfo;
},
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(res => {
getCityList(res.provinceName + '/' + res.cityName + '/' + res.countryName + '/' + res.streetName).then(res => {
that.addressInfo = res.data;
})
that.userAddress.real_name = res.userName;
that.userAddress.phone = res.telNumber;
that.userAddress.detail = res.detailInfo;
}).catch(err => {
that.$util.Tips({
title: err
});
});
},
/**
* 提交用户添加地址
*
*/
formSubmit: function(e) {
let that = this,
value = e.detail.value;
if (!value.real_name) 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.addressInfo.length) return that.$util.Tips({
title: '请选择所在地区'
});
if (that.addressInfo.length < 3) return that.$util.Tips({
title: '请补全所在地区信息'
});
// if (that.region[0] == '省') return that.$util.Tips({
// title: '请选择所在地区'
// });
if (!value.detail) return that.$util.Tips({
title: '请填写详细地址'
});
// if(!that.longitude && !that.latitude) return that.$util.Tips({title:'请定位你的经纬度'})
value.id = that.id;
let regionArray = that.addressInfo;
value.address = {
province: regionArray[0].label,
city: regionArray[1].label,
district: regionArray[2].label,
street: regionArray[3] ? regionArray[3].label : '',
city_id: regionArray[regionArray.length - 1].id ? regionArray[regionArray.length - 1].id : that.city_id,
};
value.is_default = that.userAddress.is_default ? 1 : 0;
// 经度
value.longitude = that.longitude;
// 纬度
value.latitude = that.latitude;
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.cartId) {
uni.$emit("handClick", {addressId: that.id ? that.id : res.data.id})
}
uni.navigateBack()
}, 500);
}).catch(err => {
return that.$util.Tips({
title: err
});
})
},
ChangeIsDefault: function(e) {
this.$set(this.userAddress, 'is_default', !this.userAddress.is_default);
},
identify() {
const options = {
type: 0, // 哪种方式解析,0:正则,1:树查找
textFilter: [], // 预清洗的字段
nameMaxLength: 4, // 查找最大的中文名字长度
}
const parseResult = AddressParse(this.addressValue.trim(), options)
// type参数0表示使用正则解析,1表示采用树查找, textFilter地址预清洗过滤字段。
if (this.addressValue.trim()) {
getCityList(parseResult.province + '/' + parseResult.city + '/' + parseResult.area).then(res => {
this.addressInfo = res.data;
this.userAddress.phone = parseResult.phone;
this.userAddress.real_name = parseResult.name;
this.userAddress.detail = parseResult.detail;
}).catch(err => {
return this.$util.Tips({
title: err
});
})
}
}
}
}
</script>
<style scoped lang="scss">
.color-add {
color: #cdcdcd;
}
.location1 {
.iconfont {
margin-right: 8rpx;
}
}
.fontcolor {
color: var(--view-theme);
}
.addAddress {
padding: 24rpx 20rpx;
}
.addAddress .input-wrapper {
margin-bottom: 20rpx;
}
.addAddress .list {
padding: 8rpx 0;
border-radius: 16rpx;
background-color: #fff;
}
.addAddress .list .item {
padding: 32rpx 24rpx;
// border-top: 1rpx solid #eee;
position: relative;
}
.addAddress .list .item .detail {
width: 368rpx;
}
.addAddress .list .item .location {
position: absolute;
right: 46rpx;
top: 50%;
margin-top: -40rpx !important;
font-size: 24rpx;
text-align: center;
}
.addAddress .list .item .icon-dizhi {
font-size: 36rpx !important;
}
.addAddress .list .item .name {
width: 182rpx;
font-size: 30rpx;
color: #333;
}
.addAddress .list .item .address {
// width: 412rpx;
flex: 1;
// margin-left: 20rpx;
}
.addAddress .list .item .address .addressCon {
width: 360rpx;
}
.addAddress .list .item .address .addressCon .tip {
font-size: 21rpx;
margin-top: 4rpx;
}
.addAddress .list .item input {
// width: 475rpx;
flex: 1;
font-size: 30rpx;
}
.placeholder {
color: #ccc;
}
// .addAddress .list .item {
// width: 475rpx;
// }
.addAddress .list .item .picker {
width: 430rpx;
font-size: 30rpx;
}
.addAddress .list .item .iconfont {
font-size: 30rpx;
margin-top: 4rpx;
}
.addAddress .default {
padding: 0 25rpx;
height: 128rpx;
border-radius: 16rpx;
background-color: #fff;
}
.addAddress .default .switch {
position: relative;
width: 79rpx;
height: 46rpx;
border: 2rpx solid #DDDDDD;
border-radius: 46rpx;
background-color: #DDDDDD;
transition: background-color 0.3s;
box-sizing: content-box;
&.on {
border-color: var(--view-theme);
background-color: var(--view-theme);
.inner {
transform: translateX(33rpx);
}
}
}
.addAddress .default .switch .inner {
position: absolute;
top: 2rpx;
left: 2rpx;
width: 42rpx;
height: 42rpx;
border-radius: 100%;
background-color: #FFFFFF;
box-shadow: 0rpx 3rpx 6rpx 0rpx rgba(0, 0, 0, 0.08);
transition: transform 0.3s cubic-bezier(0.3, 1.05, 0.4, 1.05);
}
.addAddress .default checkbox {
margin-right: 15rpx;
}
.addAddress .keepBnt {
color: #fff;
}
.fixed-btn{
position: fixed;
right: 20rpx;
bottom: 40rpx;
left: 20rpx;
.btn{
height: 80rpx;
border-radius: 40rpx;
text-align: center;
line-height: 80rpx;
font-size: 28rpx;
}
}
.addAddress .delbtn{
color: var(--view-theme);
border: 1px solid var(--view-theme);
}
.addAddress .wechatAddress {
// width: 690rpx;
height: 100rpx;
padding: 0 24rpx;
border-radius: 24rpx;
background-color: #FFFFFF;
text-align: center;
line-height: 100rpx;
margin: 0 0 20rpx;
font-size: 30rpx;
color: #3D3D3D;
// border: 1px solid var(--view-theme);
.icon-ic_wechat {
margin-right: 20rpx;
font-size: 48rpx;
color: #00C800;
}
}
.mt-22 {
margin-top: 22rpx;
}
</style>

View File

@@ -0,0 +1,616 @@
<template>
<!-- 地址管理 -->
<view :style="colorStyle">
<view class="address-management" :class="addressList.length < 1 && page > 1 ? 'fff' : ''">
<view class="swipe-action-wrapper">
<tui-swipe-action v-for="(item, index) in addressList" :key="item.id" :operateWidth="128" class="item">
<template v-slot:content>
<view class="content acea-row row-middle">
<view class="address" @click="goOrder(item.id)">
<view class="consignee acea-row row-middle">
{{ item.real_name }}
<text class="phone">{{ item.phone }}</text>
<text v-if="item.is_default" class="badge">默认</text>
</view>
<view>{{ item.province }}{{ item.city }}{{ item.district }}{{ item.street }}{{ item.detail }}</view>
</view>
<view @click="editAddress(item.id)"><text class="iconfont icon-ic_edit"></text></view>
</view>
</template>
<template v-slot:button>
<view class="button acea-row row-center-wrapper" @click="radioChange(index)">设为默认</view>
<view class="button delete acea-row row-center-wrapper" @click="delAddress(index)">删除</view>
</template>
</tui-swipe-action>
</view>
<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 v-if="!addressList.length">
<emptyPage title="暂无地址信息~" src="/statics/images/noAddress.gif"></emptyPage>
</view>
<view class="height-add"></view>
<view class="footer acea-row row-between-wrapper">
<view class="addressBnt on" @click="addAddress">新增收货地址</view>
<view class=""></view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import { getAddressList, setAddressDefault, delAddress, editAddress, postAddress } from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from 'vuex';
import colors from '@/mixins/color.js';
import { HTTP_REQUEST_URL } from '@/config/app';
import tuiSwipeAction from '@/components/tui-swipe-action/index.vue';
import emptyPage from '@/components/emptyPage.vue';
export default {
components: {
tuiSwipeAction,
emptyPage
},
mixins: [colors],
data() {
return {
addressList: [],
cartId: '',
pinkId: 0,
couponId: 0,
loading: false,
loadend: false,
loadTitle: '加载更多',
page: 1,
limit: 20,
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
news: '',
noCoupon: 0,
imgHost: HTTP_REQUEST_URL,
deliveryType: 1, //配送方式
store_name: '', //门店名称
storeId: 0, //门店id
product_id: 0, //商品id
orderId: 0,
send_gift_type: 0
};
},
computed: mapGetters(['isLogin']),
onLoad(options) {
this.cartId = options.cartId || '';
this.noCoupon = options.noCoupon || 0;
this.pinkId = options.pinkId || 0;
this.couponId = options.couponId || 0;
this.news = options.news || 0;
this.deliveryType = options.delivery_type || 1;
this.store_name = options.store_name;
this.storeId = options.store_id;
this.product_id = options.product_id;
this.orderId = options.order_id || 0;
this.send_gift_type = options.is_send_gift || 0;
if (this.isLogin) {
this.getAddressList(true);
} else {
toLogin();
}
},
onShow: function () {
uni.removeStorageSync('form_type_cart');
if (this.isLogin) {
this.getAddressList(true);
}
},
methods: {
onLoadFun() {
this.getAddressList(true);
this.isShowAuth = false;
},
// 授权关闭
authColse: function (e) {
this.isShowAuth = e;
},
/*
* 导入微信地址(小程序)
*/
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;
editAddress({
address: addressP,
is_default: 1,
real_name: res.userName,
post_code: res.postalCode,
phone: res.telNumber,
detail: res.detailInfo,
id: 0,
type: 1
})
.then((res) => {
that.$util.Tips(
{
title: '添加成功',
icon: 'success'
},
function () {
that.getAddressList(true);
}
);
})
.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({
real_name: userInfo.userName,
phone: userInfo.telNumber,
address: {
province: userInfo.provinceName,
city: userInfo.cityName,
district: userInfo.countryName
},
detail: userInfo.detailInfo,
post_code: userInfo.postalCode,
is_default: 1,
type: 1
})
.then(() => {
that.$util.Tips(
{
title: '添加成功',
icon: 'success'
},
function () {
// close();
that.getAddressList(true);
}
);
})
.catch((err) => {
// close();
return that.$util.Tips({
title: err || '添加失败'
});
});
});
},
/**
* 获取地址列表
*
*/
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;
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 (index) {
let 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].is_default = true;
else that.addressList[i].is_default = 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 = '';
if (this.send_gift_type) {
uni.navigateTo({
url: `/pages/users/user_address/index?is_send_gift=${this.send_gift_type}&order_id=${this.orderId}`
});
} else {
uni.navigateTo({
url:
'/pages/users/user_address/index?id=' +
id +
'&cartId=' +
cartId +
'&pinkId=' +
pinkId +
'&couponId=' +
couponId +
'&new=' +
this.news +
'&delivery_type=' +
this.deliveryType +
'&store_id=' +
this.storeId +
'&store_name=' +
this.store_name +
'&product_id=' +
this.product_id
});
}
},
/**
* 删除地址
*/
delAddress: function (index) {
let that = this,
address = this.addressList[index];
if (address == undefined)
return that.$util.Tips({
title: '您删除的地址不存在!'
});
delAddress(address.id)
.then((res) => {
that.$util.Tips(
{
title: '删除成功',
icon: 'success'
},
function () {
that.addressList.splice(index, 1);
that.$set(that, 'addressList', that.addressList);
}
);
})
.catch((err) => {
return that.$util.Tips({
title: err
});
});
},
/**
* 新增地址
*/
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?cartId=' +
cartId +
'&pinkId=' +
pinkId +
'&couponId=' +
couponId +
'&new=' +
this.news +
'&delivery_type=' +
this.deliveryType +
'&store_id=' +
this.storeId +
'&store_name=' +
this.store_name +
'&product_id=' +
this.product_id
});
},
goOrder: function (id) {
let cartId = '';
let pinkId = '';
let couponId = '';
if ((this.cartId && id) || this.send_gift_type) {
cartId = this.cartId;
pinkId = this.pinkId;
couponId = this.couponId;
this.cartId = '';
this.pinkId = '';
this.couponId = '';
if (this.send_gift_type) {
uni.redirectTo({
url: `/pages/goods/order_confirm/index?is_send_gift=${this.send_gift_type}&order_id=${this.orderId}&addressId=${id}`
});
} else {
uni.redirectTo({
url:
'/pages/goods/order_confirm/index?is_address=1&new=' +
this.news +
'&cartId=' +
cartId +
'&addressId=' +
id +
'&pinkId=' +
pinkId +
'&couponId=' +
couponId +
'&noCoupon=' +
this.noCoupon +
'&delivery_type=' +
this.deliveryType +
'&store_id=' +
this.storeId +
'&store_name=' +
this.store_name +
'&product_id=' +
this.product_id
});
}
}
}
},
onReachBottom: function () {
this.getAddressList();
},
onPageScroll(object) {
uni.$emit('scroll');
}
};
</script>
<style lang="scss" scoped>
.height-add {
height: 120rpx;
}
.noCommodity {
height: calc(100vh - 123rpx);
background-color: #fff;
}
.address-management {
padding: 24rpx 20rpx;
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
}
.address-management.fff {
background-color: #fff;
height: 1300rpx;
}
.address-management .wechat {
height: 100rpx;
padding: 0 32rpx;
border-radius: 24rpx;
background-color: #ffffff;
font-weight: 500;
font-size: 30rpx;
color: #3d3d3d;
}
.address-management .line {
width: 100%;
height: 3rpx;
}
.address-management .line image {
width: 100%;
height: 100%;
display: block;
}
.address-management .item::before {
content: '';
position: absolute;
top: 0;
right: 24rpx;
left: 24rpx;
height: 1rpx;
background-color: #f5f5f5;
}
.address-management .item:first-child::before {
display: none;
}
.address-management .item .content {
padding: 32rpx 32rpx 24rpx;
}
.address-management .item .address {
flex: 1;
min-width: 0;
white-space: normal;
font-size: 24rpx;
line-height: 34rpx;
color: #999999;
}
.address-management .item .address .consignee {
font-size: 30rpx;
line-height: 42rpx;
font-weight: bold;
margin-bottom: 12rpx;
color: #333333;
}
.address-management .item .address .consignee .phone {
font-weight: normal;
margin-left: 22rpx;
}
.address-management .item .address .consignee .badge {
height: 34rpx;
padding: 0 8rpx;
border-radius: 8rpx;
margin-left: 20rpx;
background-color: var(--view-minorColorT);
font-weight: normal;
font-size: 22rpx;
line-height: 34rpx;
color: var(--view-theme);
}
.address-management .item .operation {
height: 83rpx;
font-size: 28rpx;
color: #282828;
}
.address-management .item .operation .radio text {
margin-left: 13rpx;
}
.address-management .item .iconfont {
font-size: 32rpx;
color: #333333;
}
.address-management .item .button {
position: absolute;
top: 0;
left: 0;
bottom: 0;
display: inline-flex;
width: 64px;
// height: 100%;
background: var(--view-bntColor);
font-size: 24rpx;
color: #fff;
}
.address-management .item .delete {
left: 64px;
background-color: var(--view-theme);
color: #ffffff;
}
.address-management .footer {
position: fixed;
width: 100%;
bottom: 0;
left: 0;
height: 120rpx;
padding: 0 20rpx;
box-sizing: border-box;
height: calc(106rpx + constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
height: calc(106rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding-bottom: constant(safe-area-inset-bottom); ///兼容 IOS<11.2/
padding-bottom: env(safe-area-inset-bottom); ///兼容 IOS>11.2/
}
.address-management .footer .addressBnt {
width: 330rpx;
height: 80rpx;
border-radius: 40rpx;
text-align: center;
line-height: 80rpx;
font-weight: 500;
font-size: 28rpx;
color: #fff;
background-color: var(--view-theme);
}
.address-management .footer .addressBnt.on {
width: 710rpx;
margin: 0 auto;
}
.address-management .footer .addressBnt .iconfont {
font-size: 35rpx;
margin-right: 8rpx;
vertical-align: -1rpx;
}
.address-management .footer .addressBnt.wxbnt {
background-color: #fe960f;
}
.wechat + .swipe-action-wrapper {
margin-top: 20rpx;
}
.swipe-action-wrapper {
border-radius: 24rpx;
background-color: #ffffff;
overflow: hidden;
}
</style>

View File

@@ -0,0 +1,104 @@
<template>
<!-- 个人资料 -->
<view>
<form @submit="formSubmit">
<view class="personal-data" :style="colorStyle">
<view class="list rd-24rpx mx-20">
<view class="item acea-row row-between-wrapper">
<view>用户协议</view>
<navigator url="/pages/users/privacy/index?type=user" hover-class="none" class="input grab">
<text class="iconfont icon-ic_rightarrow"></text>
</navigator>
</view>
<view class="item acea-row row-between-wrapper">
<view>隐私协议</view>
<navigator url="/pages/users/privacy/index?type=privacy" hover-class="none" class="input grab">
<text class="iconfont icon-ic_rightarrow"></text>
</navigator>
</view>
<view class="item acea-row row-between-wrapper">
<view>注销协议</view>
<navigator url="/pages/users/privacy/index?type=cancel" hover-class="none" class="input grab">
<text class="iconfont icon-ic_rightarrow"></text>
</navigator>
</view>
</view>
</view>
</form>
</view>
</template>
<script>
import colors from '@/mixins/color.js';
export default {
components: {},
mixins: [colors],
data() {
return {};
},
watch: {
isLogin: {
handler: function (newV, oldV) {
if (newV) {
// #ifndef MP
this.getUserInfo();
// #endif
}
},
deep: true
}
},
onLoad() {},
onShow() {},
methods: {}
};
</script>
<style scoped lang="scss">
.personal-data {
padding-bottom: 50rpx;
}
.dater {
width: 400rpx;
}
.grab {
color: #ccc !important;
}
.personal-data .wrapper {
margin: 10rpx 0;
background-color: #fff;
padding: 36rpx 30rpx 13rpx 30rpx;
}
.personal-data .wrapper .title {
margin-bottom: 30rpx;
font-size: 32rpx;
color: #282828;
}
.personal-data .list {
margin-top: 15rpx;
background-color: #fff;
}
.personal-data .list .item {
padding: 32rpx 20rpx 24rpx 0;
margin-left: 30rpx;
font-size: 30rpx;
color: #282828;
.label {
margin-right: 30rpx;
}
}
.personal-data .list .item .input .id {
width: 414rpx;
}
.personal-data .list .item .input .iconfont {
font-size: 35rpx;
color: #868686;
}
</style>

View File

@@ -0,0 +1,243 @@
<template>
<view :style="colorStyle">
<view class='bill-details'>
<view class='nav acea-row'>
<view class='item' :class='type==0 ? "on":""' @click='changeType(0)'>全部</view>
<view class='item' :class='type==1 ? "on":""' @click='changeType(1)'>消费</view>
<view class='item' :class='type==2 ? "on":""' @click='changeType(2)'>储值</view>
</view>
<view class='sign-record'>
<view class='list' v-for="(item,index) in userBillList" :key="index">
<view class='item'>
<view class='data'>{{item.time}}</view>
<view class='listn'>
<view class='itemn acea-row row-between-wrapper' v-for="(vo,indexn) in item.child" :key="indexn">
<view>
<view class='name line1'>{{vo.title}}</view>
<view>{{vo.add_time}}</view>
</view>
<view class='num' 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 class="px-20 mt-20" v-if="userBillList.length == 0">
<emptyPage title="暂无记录~" src="/statics/images/noOrder.gif"></emptyPage>
</view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
getCommissionInfo,
moneyList
} from '@/api/user.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import emptyPage from '@/components/emptyPage.vue';
import colors from "@/mixins/color";
export default {
components: {
emptyPage,
},
mixins: [colors],
data() {
return {
loadTitle: '加载更多',
loading: false,
loadend: false,
page: 1,
limit: 15,
type: 0,
userBillList: [],
times:[],
isAuto: false, //没有授权的不会自动授权
isShowAuth: false //是否隐藏授权
};
},
computed: mapGetters(['isLogin']),
onShow() {
uni.removeStorageSync('form_type_cart');
if (this.isLogin) {
this.getUserBillList();
} else {
toLogin()
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.type = options.type || 0;
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
this.getUserBillList();
},
onPageScroll(object) {
uni.$emit('scroll');
},
methods: {
/**
* 授权回调
*/
onLoadFun: function() {
this.getUserBillList();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
/**
* 获取账户明细
*/
getUserBillList: function() {
let that = this;
let page = that.page;
let limit = that.limit;
if (that.loading) return;
if (that.loadend) return;
that.loading = true;
that.loadTitle = '';
moneyList({
page: page,
limit: limit
},that.type).then(res => {
for (let i = 0; i < res.data.time.length; i++) {
if (!this.times.includes(res.data.time[i])) {
this.times.push(res.data.time[i])
this.userBillList.push({
time: res.data.time[i],
child: []
})
}
}
for (let x = 0; x < this.times.length; x++) {
for (let j = 0; j < res.data.list.length; j++) {
if (this.times[x] === res.data.list[j].time_key) {
this.userBillList[x].child.push(res.data.list[j])
}
}
}
let loadend = res.data.list.length < that.limit;
that.loadend = loadend;
that.loadTitle = loadend ? '没有更多内容啦~' : '加载更多';
that.page += 1;
that.loading = false;
}).catch(err=>{
that.loading = false;
that.loadTitle = '加载更多';
})
},
// 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
// }
// getCommissionInfo(data, that.type).then(function(res) {
// let list = res.data,
// loadend = list.length < that.limit;
// that.userBillList = that.$util.SplitArray(list, that.userBillList);
// that.$set(that, 'userBillList', that.userBillList);
// that.loadend = loadend;
// that.loading = false;
// that.loadTitle = loadend ? "没有更多内容啦~" : "加载更多";
// that.page = that.page + 1;
// }, function(res) {
// that.loading = false;
// that.loadTitle = '加载更多';
// });
// },
/**
* 切换导航
*/
changeType: function(type) {
this.type = type;
this.loadend = false;
this.page = 1;
this.times = [];
this.$set(this, 'userBillList', []);
this.getUserBillList();
},
}
}
</script>
<style scoped lang='scss'>
.sign-record .list .item .data{
color: #999;
}
.sign-record .list .item .listn{
width: 710rpx;
margin: 0 auto;
border-radius: 24rpx;
}
.sign-record .list .item .listn .itemn{
padding: 0;
margin: 0 30rpx;
height: 150rpx;
}
.sign-record .list .item .listn .itemn:nth-last-child(1){
border-bottom: 0;
}
.sign-record .list .item .listn .itemn .name{
color: #333;
}
.sign-record .list .item .listn .itemn .num{
color: #333333;
font-family: 'Regular';
}
.bill-details .nav {
background-color: #fff;
height: 80rpx;
width: 100%;
line-height: 80rpx;
}
.bill-details .nav .item {
flex: 1;
text-align: center;
font-size: 28rpx;
color: #333;
}
.bill-details .nav .item.on {
color: var(--view-theme);
/* border-bottom: 3rpx solid var(--view-theme); */
font-size: 30rpx;
position: relative;
}
.bill-details .nav .item.on::after{
position: absolute;
width: 64rpx;
height: 6rpx;
border-radius: 20px;
content: ' ';
background: var(--view-theme);
bottom: 0;
left:50%;
margin-left: -32rpx;
}
</style>

View File

@@ -0,0 +1,176 @@
<template>
<view class="agreement" :style="colorStyle">
<view class="flex-center">
<text class="iconfont icon-a-ic_tanhao1"></text>
</view>
<view class="name text-center">账号注销风险</view>
<view class="content" v-html="agreementData.content"></view>
<view class="footerH"></view>
<view class="footer">
<view class="trip">
<checkbox-group @change="ChangeIsDefault">
<checkbox :class="inAnimation ? 'trembling' : ''" @animationend="inAnimation = false" :checked="protocol ? true : false"
color="#ffffff" backgroundColor="#ffffff"
activeBackgroundColor="var(--view-theme)"
activeBorderColor="var(--view-theme)"/>
我已阅读并同意
<text class="red" @click="privacy('privacy ')">《隐私协议》</text>
</checkbox-group>
</view>
<view class="cancellation flex-aj-center" @click="next">下一步</view>
</view>
<view class="mark" v-show="isCancellation"></view>
<tui-modal :show="isCancellation" maskClosable custom @cancel="isCancellation = false">
<view class="tui-modal-custom">
<view class="fs-32 fw-500 lh-44rpx text-center">是否确认注销</view>
<view class="fs-30 text--w111-666 lh-42rpx text-center mt-22">注销后无法恢复,请谨慎操作</view>
<view class="flex-y-center">
<view class="w-full h-72 rd-36rpx flex-center border b-solid b--w111-ccc text-primary-con fs-26 mt-32 mr-16 clear-btn" @tap="cancelUser">注销</view>
<view class="w-full h-72 rd-36rpx flex-center bg-red fs-26 text--w111-fff mt-32 ml-16" @tap="isCancellation = false">取消</view>
</view>
</view>
</tui-modal>
</view>
</template>
<script>
import colors from '@/mixins/color.js';
import { getUserAgreement, cancelUser, getLogout } from '@/api/user.js';
import tuiModal from '@/components/tui-modal/index.vue';
export default {
mixins: [colors],
components: { tuiModal },
data() {
return {
isCancellation: false,
agreementData: '',
protocol: false,
inAnimation: false,
};
},
onLoad() {
this.getAgreement();
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
methods: {
ChangeIsDefault(e) {
this.$set(this, 'protocol', !this.protocol);
},
getAgreement() {
getUserAgreement('cancel').then((res) => {
this.agreementData = res.data;
});
},
next() {
if (this.protocol) {
this.isCancellation = true;
} else {
this.$util.Tips({
title: '请先阅读隐私协议'
});
}
},
cancelUser() {
cancelUser()
.then((res) => {
this.$store.commit('LOGOUT');
uni.reLaunch({
url: '/pages/index/index'
});
})
.catch((msg) => {
return this.$util.Tips({
title: msg
});
});
},
privacy(type) {
uni.navigateTo({
url: '/pages/users/privacy/index?type=' + type
});
}
}
};
</script>
<style lang="scss" scoped>
/deep/ checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: 1px solid var(--view-theme) !important;
background-color: var(--view-theme) !important;
width: 28rpx;
height: 28rpx;
font-size: 24rpx;
color: #fff !important;
}
.footerH {
height: 250rpx;
}
.agreement {
background-color: #fff;
padding-top: 84rpx;
.content {
padding: 0 30rpx;
}
.name {
padding: 30rpx 0 48rpx;
font-size: 36rpx;
font-weight: 500;
color: #333333;
line-height: 50rpx;
}
}
.top-msg {
display: flex;
align-items: center;
background-color: #fff;
padding: 40rpx 30rpx 40rpx 30rpx;
}
.icon-a-ic_tanhao1 {
font-size: 68rpx;
color: #e93323;
}
.footer {
text-align: center;
z-index: 99;
width: 100%;
background-color: #fafafa;
position: fixed;
padding: 0 30rpx 36rpx 30rpx;
box-sizing: border-box;
border-top: 1rpx solid #eee;
bottom: 0rpx;
.red {
color: #e93323;
}
.trip {
color: #999999;
font-size: 24rpx;
margin: 24rpx 0;
}
.cancellation {
height: 45px;
color: #fff;
font-size: 32rpx;
background: #e93323;
border-radius: 23px;
}
}
.mark {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 99;
}
.clear-btn{
border: 1px solid #E93323;
color: #E93323;
}
</style>

View File

@@ -0,0 +1,888 @@
<template>
<view :style="colorStyle">
<view class='cash-withdrawal'>
<!-- #ifdef MP -->
<view class="accountTitle">
<view :style="{height:getHeight.barTop+'px'}"></view>
<view class="sysTitle acea-row row-center-wrapper" :style="{height:getHeight.barHeight+'px'}">
<view>提现</view>
<text class="iconfont icon-ic_leftarrow" @click="goarrow"></text>
</view>
</view>
<view :style="{height:(getHeight.barTop+getHeight.barHeight)+'px'}"></view>
<!-- #endif -->
<view class="header">
<view class="headerCon">
<view class="money">{{userInfo.commissionCount}}</view>
<view>可提现金额</view>
</view>
</view>
<view class='wrapper'>
<view class="nav acea-row" v-if="navList.length == 4">
<view class="item" :class="[currentIndex==0?'on6':currentIndex==1?'on7':currentIndex==2?'on8':'on9',currentIndex==index?'items':'']"
v-for="(item,index) in navList" :key="index" @click="swichNav(item.id,index)">
{{item.name}}
</view>
<view class="navBg" :class="currentIndex==0?'on6':currentIndex==1?'on7':currentIndex==2?'on8':'on9'"></view>
</view>
<view class="nav acea-row" v-if="navList.length == 3">
<view class="item" :class="[currentIndex==0?'on1':currentIndex==1?'on2':'on3',currentIndex==index?'items':'']"
v-for="(item,index) in navList" :key="index" @click="swichNav(item.id,index)">
{{item.name}}
</view>
<view class="navBg" :class="currentIndex==0?'on1':currentIndex==1?'on2':'on3'"></view>
</view>
<view class="nav acea-row" v-if="navList.length == 2">
<view class="item on" :class="currentTab == item.id ? 'ons':''"
v-for="(item,index) in navList" :key="index" @click="swichNav(item.id,index)">
{{item.name}}
</view>
<view class="navBg" :class="currentIndex==0?'on4':'on5'"></view>
</view>
<view class="nav on" v-if="navList.length == 1">
<view class="item" v-for="(item,index) in navList" :key="index">
{{item.id==0?'提现至银行卡':item.id==1?'提现至余额':item.id==2?'提现至微信':'提现至支付宝'}}
</view>
</view>
<view :hidden="currentTab != 0">
<form @submit="subCash">
<view class='list'>
<view class="itemCon">
<view class='item acea-row row-between-wrapper'>
<view class='name'>持卡人</view>
<view class='input'><input placeholder='请输入持卡人姓名' placeholder-class='placeholder'
name="name" onKeypress="javascript:if(event.keyCode == 32)event.returnValue = false;"></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="cardnum"></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">
<view class="acea-row row-between-wrapper">
<text class='Bank'>{{array[index]}}</text>
<text class='iconfont icon-ic_rightarrow'></text>
</view>
</picker>
</view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input acea-row row-between-wrapper'>
<input @input='inputNum' :value='cashVal' :maxlength="moneyMaxLeng" :placeholder='"最低提现金额:¥"+minPrice' placeholder-class='placeholder'
name="money" type='digit'></input>
<view class="all" @click="allCash">全部提现</view>
</view>
</view>
</view>
<view class='tip'>
当前可提现金额: <text
class="price">¥{{userInfo.commissionCount}}</text>,冻结佣金:¥{{userInfo.broken_commission}}
</view>
<view class='tip'>
提现手续费: <text class="price">{{withdraw_fee}}%</text>,实际到账:<text class="price">¥{{true_money}}</text>
</view>
<view class='tip'>
说明: <text class="num">每笔佣金的冻结期为{{userInfo.broken_day}}天,到期后可提现</text>
</view>
</view>
<button formType="submit" class='bnt bg-color'>立即提现</button>
</form>
</view>
<view :hidden="currentTab != 1">
<form @submit="subCash">
<view class='list'>
<view class="itemCon">
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input acea-row row-between-wrapper'>
<input @input='inputNum' :value='cashVal' :maxlength="moneyMaxLeng" :placeholder='"最低提现金额:¥"+minPrice' placeholder-class='placeholder'
name="money" type='digit'></input>
<view class="all" @click="allCash">全部提现</view>
</view>
</view>
</view>
<view class='tip'>
当前可提现金额: <text
class="price">¥{{userInfo.commissionCount}}</text>,冻结佣金:¥{{userInfo.broken_commission}}
</view>
<view class='tip'>
说明: <text class="num">每笔佣金的冻结期为{{userInfo.broken_day}}天,到期后可提现</text>
</view>
</view>
<button formType="submit" class='bnt bg-color'>立即提现</button>
</form>
</view>
<view :hidden="currentTab != 2">
<form @submit="subCash">
<view class='list'>
<view class="itemCon">
<view class='item acea-row row-between-wrapper' v-if="extract_wechat_type == 0">
<view class='name'>账号</view>
<view class='input'><input placeholder='请输入您的微信账号' placeholder-class='placeholder'
name="name" onKeypress="javascript:if(event.keyCode == 32)event.returnValue = false;"></input></view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input acea-row row-between-wrapper'>
<input @input='inputNum' :value='cashVal' :maxlength="moneyMaxLeng" :placeholder='"最低提现金额:¥"+minPrice' placeholder-class='placeholder'
name="money" type='digit'></input>
<view class="all" @click="allCash">全部提现</view>
</view>
</view>
<view class='item acea-row row-top row-between' v-if="extract_wechat_type == 0">
<view class='name'>收款码</view>
<view class="input acea-row">
<view class="picEwm" v-if="qrcodeUrlW">
<image :src="qrcodeUrlW"></image>
<text class='iconfont icon-ic_close fontcolor' @click='DelPicW'></text>
</view>
<view class='pictrue acea-row row-center-wrapper row-column' @click='uploadpic("W")'
v-else>
<text class='iconfont icon-ic_camera'></text>
<view>上传图片</view>
</view>
</view>
</view>
</view>
<view class='tip'>
当前可提现金额: <text
class="price">¥{{userInfo.commissionCount}}</text>,冻结佣金:¥{{userInfo.broken_commission}}
</view>
<view class='tip'>
提现手续费: <text class="price">{{withdraw_fee}}%</text>,实际到账:<text class="price">¥{{true_money}}</text>
</view>
<view class='tip'>
说明: <text class="num">每笔佣金的冻结期为{{userInfo.broken_day}}天,到期后可提现</text>
</view>
</view>
<button formType="submit" class='bnt bg-color'>立即提现</button>
</form>
</view>
<view :hidden='currentTab != 3'>
<form @submit="subCash">
<view class='list'>
<view class="itemCon">
<view class='item acea-row row-between-wrapper'>
<view class='name'>姓名</view>
<view class='input'><input placeholder='请输入姓名' placeholder-class='placeholder'
name="name" onKeypress="javascript:if(event.keyCode == 32)event.returnValue = false;"></input></view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>账号</view>
<view class='input'><input placeholder='请输入您的支付宝账号' placeholder-class='placeholder'
name="alipay_code" onKeypress="javascript:if(event.keyCode == 32)event.returnValue = false;"></input></view>
</view>
<view class='item acea-row row-between-wrapper'>
<view class='name'>提现</view>
<view class='input acea-row row-between-wrapper'>
<input @input='inputNum' :value='cashVal' :maxlength="moneyMaxLeng" :placeholder='"最低提现金额:¥"+minPrice' placeholder-class='placeholder'
name="money" type='digit'></input>
<view class="all" @click="allCash">全部提现</view>
</view>
</view>
<!-- real_name -->
<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-ic_close fontcolor' @click='DelPicZ'></text>
</view>
<view class='pictrue acea-row row-center-wrapper row-column' @click='uploadpic("Z")'
v-else>
<text class='iconfont icon-ic_camera'></text>
<view>上传图片</view>
</view>
</view>
</view>
</view>
<view class='tip'>
当前可提现金额: <text
class="price">¥{{userInfo.commissionCount}}</text>,冻结佣金:¥{{userInfo.broken_commission}}
</view>
<view class='tip'>
提现手续费: <text class="price">{{withdraw_fee}}%</text>,实际到账:<text class="price">¥{{true_money}}</text>
</view>
<view class='tip'>
说明: <text class="num">每笔佣金的冻结期为{{userInfo.broken_day}}天,到期后可提现</text>
</view>
</view>
<button formType="submit" class='bnt bg-color'>立即提现</button>
</form>
</view>
</view>
</view>
<home></home>
</view>
</template>
<script>
import {
extractCash,
extractBank,
getUserInfo
} from '@/api/user.js';
import { toLogin } from '@/libs/login.js';
import { mapGetters } from "vuex";
import colors from '@/mixins/color.js';
import { openExtrctSubscribe } from '@/utils/SubscribeMessage.js';
import { Debounce } from '@/utils/validate.js'
export default {
mixins:[colors],
data() {
return {
// #ifdef MP
getHeight: this.$util.getWXStatusHeight(),
// #endif
navList: [],
currentTab: '', //当前支付方式编号;
currentIndex:0, //索引值;
index: 0,
array: [], //提现银行
minPrice: 0.00, //最低提现金额
userInfo: [],
isClone: false,
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
qrcodeUrlW: "",
qrcodeUrlZ: "",
prevent: true, //避免重复提交成功多次
moneyMaxLeng: 8,
withdraw_fee: '0',
true_money: 0,
extract_wechat_type:0,
cashVal: '',
copyIndex:null,
platform: ''
};
},
computed: {
...mapGetters(['isLogin']),
disabled(){
return true
// if(this.navList[this.currentTab].status == 0){
// return true
// }else{
// return false
// }
}
},
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
// #ifndef MP
// this.getUserInfo();
// this.getUserExtractBank();
// #endif
}
},
deep: true
}
},
onPageScroll(object) {
uni.$emit('scroll');
},
onLoad() {
if (this.isLogin) {
this.navList = [];
this.currentIndex = 0;
this.prevent = true;
this.cashVal = 0;
this.$nextTick(()=>{
this.cashVal = '';
})
this.getUserInfo();
this.getUserExtractBank();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
// #ifdef H5
if(this.$wechat.isWeixin()){
this.platform = 'wechat'
}
// #endif
// #ifdef APP-PLUS
this.platform = 'app'
// #endif
// #ifdef MP-WEIXIN
this.platform = 'routine'
// #endif
},
methods: {
goarrow(){
uni.navigateBack()
},
allCash(){
this.cashVal = '';
this.$nextTick(()=>{
this.cashVal = this.userInfo.commissionCount;
this.inputNum();
})
},
inputNum: function(e) {
let val = e?e.detail.value:this.cashVal;
let dot = val.indexOf('.');
if(dot>-1){
this.moneyMaxLeng = dot+3;
}else{
this.moneyMaxLeng = 8
}
this.true_money = Math.floor((this.$util.$h.Mul(val,this.$util.$h.Div(this.$util.$h.Sub(100,this.withdraw_fee),100)))*100)/100 || 0;
},
/**
* 上传文件
*
*/
uploadpic: function(type) {
let that = this;
// this.copyIndex = this.currentIndex;
this.$util.uploadImageOne('upload/image', (res)=> {
if (type === 'W') {
this.qrcodeUrlW = res.data.url;
} else {
this.qrcodeUrlZ = res.data.url;
}
});
},
/**
* 删除图片
*
*/
DelPicW: function() {
this.qrcodeUrlW = "";
},
DelPicZ: function() {
this.qrcodeUrlZ = "";
},
onLoadFun: function() {
this.getUserInfo();
this.getUserExtractBank();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
getUserExtractBank: function() {
let that = this;
extractBank().then(res => {
let array = res.data.extractBank;
array.unshift("请选择银行");
that.$set(that, 'array', array);
that.minPrice = res.data.minPrice;
that.withdraw_fee = res.data.withdraw_fee;
that.extract_wechat_type = res.data.extract_wechat_type;
});
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
that.userInfo = res.data;
if(res.data.user_extract_bank_status){
this.navList.push(
{
'name': '银行卡',
'id': 0
}
)
}
if(res.data.user_extract_balance_status){
this.navList.push(
{
'name': '余额',
'id': 1
}
)
}
if(res.data.user_extract_wechat_status){
this.navList.push(
{
'name': '微信',
'id': 2
}
)
}
if(res.data.user_extract_alipay_status){
this.navList.push(
{
'name': '支付宝',
'id': 3
}
)
}
this.currentTab = this.navList[0].id;
})
},
swichNav: function(current,index) {
this.currentTab = current;
this.currentIndex = index;
},
bindPickerChange: function(e) {
this.index = e.detail.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.cardnum.length == 0) return this.$util.Tips({
title: '请填写卡号'
});
if (that.index == 0) return this.$util.Tips({
title: "请选择银行"
});
value.extract_type = 'bank';
value.bankname = that.array[that.index];
} else if (that.currentTab == 1) { //余额
value.extract_type = 'balance';
} else if (that.currentTab == 2) { //微信
value.extract_type = 'weixin';
if(that.extract_wechat_type == 0){
if (value.name.length == 0) return this.$util.Tips({
title: '请填写微信号'
});
if (that.qrcodeUrlW == '') return this.$util.Tips({
title: '请上传图片'
});
value.weixin = value.name;
value.qrcode_url = that.qrcodeUrlW;
}
} else if (that.currentTab == 3) { //支付宝
value.extract_type = 'alipay';
if (value.name.length == 0) return this.$util.Tips({
title: '请填写账号'
});
if (value.name.length == 0) return this.$util.Tips({
title: '请填写收款人姓名'
});
if (that.qrcodeUrlZ == '') return this.$util.Tips({
title: '请上传图片'
});
value.qrcode_url = that.qrcodeUrlZ;
}
if (value.money.length == 0) return this.$util.Tips({
title: '请填写提现金额'
});
if (Number(value.money) < Number(that.minPrice)) return this.$util.Tips({
title: '提现金额不能低于:¥' + that.minPrice
});
if (this.prevent) {
this.prevent = false
} else {
return
}
that.$set(value,'channel_type',this.platform);
// #ifdef MP-WEIXIN
uni.showLoading({
title: '正在加载'
});
openExtrctSubscribe().then((res) => {
uni.hideLoading();
extractCash(value).then(res => {
if(that.currentTab == 1){
return this.$util.Tips({
title: res.msg,
icon: 'success'
}, {
url: '/pages/users/user_money/index',
tab: 2
});
}else{
return this.$util.Tips({
title: res.msg,
icon: 'success'
}, {
url: '/pages/users/user_spread_money/index',
tab: 2
});
}
}).catch(err => {
setTimeout(e => {
this.prevent = true
}, 1500)
return this.$util.Tips({
title: err
});
});
}).catch(() => {
uni.hideLoading();
});
// #endif
// #ifdef H5 || APP-PLUS
extractCash(value).then(res => {
if(that.currentTab == 1){
return this.$util.Tips({
title: res.msg,
icon: 'success'
}, {
url: '/pages/users/user_money/index',
tab: 2
});
}else{
return this.$util.Tips({
title: res.msg,
icon: 'success'
}, {
url: '/pages/users/user_cash/status',
tab: 2
});
}
}).catch(err => {
setTimeout(e => {
this.prevent = true
}, 1500)
return this.$util.Tips({
title: err
});
});
// #endif
})
}
}
</script>
<style lang="scss">
.cash-withdrawal{
.accountTitle{
background: linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%);
position: fixed;
left:0;
top:0;
width: 100%;
z-index: 99;
.sysTitle{
width: 100%;
position: relative;
font-weight: 500;
color: #fff;
font-size: 34rpx;
.iconfont{
position: absolute;
font-size: 36rpx;
left:11rpx;
width: 60rpx;
}
}
}
.header{
width: 100%;
height: 380rpx;
background: linear-gradient(90deg, var(--view-theme) 0%, var(--view-gradient) 100%);
font-size: 30rpx;
font-weight: 400;
color: #F5F5F5;
text-align: center;
padding-top: 88rpx;
position: relative;
&::after{
position: absolute;
content: ' ';
width: 50%;
height: 160rpx;
background: linear-gradient(180deg, var(--view-theme) 0%, #F5F5F5 100%);
left: 0;
}
&:before{
position: absolute;
content: ' ';
width: 50%;
height: 160rpx;
background: linear-gradient(180deg, var(--view-gradient) 0%, #F5F5F5 100%);
right: 0;
bottom: -146rpx;
}
.headerCon{
background-image: url('../static/cashBg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: 278rpx;
}
.money{
font-size: 76rpx;
font-weight: 600;
color: #FFFFFF;
font-family: 'Regular';
margin-bottom: 16rpx;
}
}
}
.cash-withdrawal .wrapper{
width: 710rpx;
margin: -100rpx auto 0 auto;
position: relative;
z-index: 9;
.nav{
width: 100%;
height: 110rpx;
background-color: rgba(255, 255, 255, 0.9);
border-radius: 24rpx 24rpx 0 0;
position: relative;
z-index: 9;
&.on{
height: unset;
padding: 18rpx 0 8rpx 0;
background-color: #fff;
.item{
padding-top: 0;
padding-left: 30rpx;
font-weight: 500;
color: #333;
}
}
.item{
width: 33.33%;
height: 84rpx;
line-height: 84rpx;
color: #666666;
font-size: 26rpx;
position: relative;
z-index: 9;
&.items{
font-size: 28rpx;
color: var(--view-theme);
font-weight: 500 !important;
}
&.on{
width: 50%;
padding-left: 0;
text-align: center;
}
&.ons{
color: var(--view-theme);
font-weight: 500;
font-size: 28rpx;
}
&.on1,&.on2,&.on3{
font-weight: 400;
padding-left: 0;
text-align: center;
}
&.on6,&.on7,&.on8,&.on9{
width: 25%;
font-weight: 400;
padding-left: 0;
text-align: center;
}
}
.navBg{
position: absolute;
background-repeat: no-repeat;
background-size: 100% 100%;
width: 710rpx;
height: 122rpx;
left:0;
bottom: 0;
box-sizing: border-box;
&.on1{
background-image: url('../static/tixian01.png');
}
&.on2{
background-image: url('../static/tixian02.png');
}
&.on3{
background-image: url('../static/tixian03.png');
}
&.on4{
background-image: url('../static/tixian04.png');
}
&.on5{
background-image: url('../static/tixian05.png');
}
&.on6{
background-image: url('../static/tixian06.png');
}
&.on7{
background-image: url('../static/tixian07.png');
}
&.on8{
background-image: url('../static/tixian08.png');
}
&.on9{
background-image: url('../static/tixian09.png');
}
}
}
.bnt {
font-size: 28rpx;
color: #fff;
width: 710rpx;
height: 88rpx;
text-align: center;
border-radius: 50rpx;
line-height: 88rpx;
margin: 48rpx auto;
}
}
.cash-withdrawal .wrapper .list {
padding: 0 30rpx 48rpx 30rpx;
background-color: #fff;
border-radius: 0 0 24rpx 24rpx;
.itemCon{
border-bottom: 1px solid #EEEEEE;
padding-bottom: 15rpx;
margin-bottom: 42rpx;
}
}
.cash-withdrawal .wrapper .list .item {
font-size: 28rpx;
color: #333;
padding: 28rpx 0;
}
.cash-withdrawal .wrapper .list .item .name {
width: 130rpx;
}
.cash-withdrawal .wrapper .list .item .input {
width: 505rpx;
input{
font-size: 28rpx;
}
.iconfont{
color: #ccc;
}
.icon-ic_camera{
font-size: 38rpx;
margin-bottom: 6rpx;
}
.all{
font-size: 26rpx;
color: var(--view-theme);
}
}
.cash-withdrawal .wrapper .list .item .input .placeholder {
color: #ccc;
}
.cash-withdrawal .wrapper .list .item .picEwm,
.cash-withdrawal .wrapper .list .item .pictrue {
width: 128rpx;
height: 128rpx;
border-radius: 14rpx;
position: relative;
margin-right: 23rpx;
background: #F5F5F5;
}
.cash-withdrawal .wrapper .list .item .picEwm image {
width: 100%;
height: 100%;
border-radius: 3rpx;
}
.cash-withdrawal .wrapper .list .item .picEwm .icon-ic_close {
position: absolute;
right: 0;
top: 0;
font-size: 24rpx;
width: 32rpx;
height: 32rpx;
background: #999999;
border-radius: 0 16rpx 0 16rpx;
color: #fff;
text-align: center;
line-height: 32rpx;
}
.cash-withdrawal .wrapper .list .item .pictrue {
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: 24rpx;
color: #999;
margin-top: 16rpx;
.price{
color: var(--view-theme);
margin: 0 16rpx;
}
.num{
margin-left: 16rpx;
}
}
.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;
}
.bg-gray{
background-color: var(--view-theme);
opacity: 0.4;
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<view :style="colorStyle">
<view class="px-20 mt-40">
<view class="bg--w111-fff rd-24rpx flex-col flex-center box">
<text class="iconfont icon-a-ic_CompleteSelect"></text>
<view class="fs-32 lh-44rpx mt-64">提现申请已提交,等待人工审核</view>
<view class="fs-26 lh-36rpx text--w111-999 mt-8">{{new Date().getTime() | dateFormat}}</view>
<view class="w-498 h-88 rd-44rpx flex-center fs-28 text--w111-fff bg-color mt-30" @tap="goPage">好的</view>
</view>
</view>
</view>
</template>
<script>
import colors from '@/mixins/color.js';
import dayjs from '@/plugin/dayjs/dayjs.min.js';
export default {
name: 'status',
filters: {
dateFormat(value) {
return dayjs(value).format('YYYY/MM/DD hh:mm:ss');
}
},
mixins:[colors],
methods:{
goPage(){
uni.navigateTo({
url: '/pages/users/user_spread_money/index?type=1'
})
}
}
}
</script>
<style scoped>
.box{
padding: 88rpx 0 64rpx;
}
.icon-a-ic_CompleteSelect{
font-size: 112rpx;
color: #00B42A;
}
</style>

View File

@@ -0,0 +1,500 @@
<template>
<!-- 我的有优惠券模块 -->
<view :style="colorStyle">
<view class="header">
<view class="navbar acea-row">
<view class="item acea-row row-center-wrapper" :class="{ on: navOn === 0 }" @click="onNav(0)">
<view>待使用({{ not_used }}张)</view>
</view>
<view class="item acea-row row-center-wrapper" :class="{ on: navOn === 1 }" @click="onNav(1)">
<view>已使用({{ used }}张)</view>
</view>
<view class="item acea-row row-center-wrapper" :class="{ on: navOn === 2 }" @click="onNav(2)">
<view>已失效({{ expired }}张)</view>
</view>
</view>
<view class="subnavbar px-32 flex-y-center">
<scroll-view scroll-x="true" class="white-nowrap vertical-middle w-full" show-scrollbar="false">
<view class="inline-block h-52 rd-28rpx px-28 lh-52rpx text-center fs-24 bg--w111-f5f5f5 mr-24"
v-for="(item, index) in navList" :key="index"
:class="type === item.type ? 'on' : ''"
@tap="onSubNav(item.type)">{{item.name}}</view>
</scroll-view>
</view>
</view>
<view class="header-shadow"></view>
<view class='coupon-list'>
<view class="item" :class="{ gray: navOn }" v-for='(item,index) in couponsList' :key="index">
<view class="item-box acea-row" :class="{svip: item.receive_type === 4}">
<view class="moneyCon acea-row row-center-wrapper">
<view class='money'>
<BaseMoney
v-if="item.coupon_type==1"
:money="item.coupon_price"
symbolSize="28"
integerSize="52"
isCoupon
:color="item.is_use ? '#cccccc' : item.receive_type === 4 ? '#FACC7D' : '#ffffff'"></BaseMoney>
<view v-else-if="item.coupon_type==2" class="SemiBold">{{ parseFloat(item.coupon_price)/10 }}<text class="fs-28 pingfang pl-4">折</text></view>
<view class="pic-num" v-if="item.use_min_price > 0">满{{item.use_min_price}}可用</view>
<view class="pic-num" v-else>无门槛券</view>
</view>
</view>
<view class="text acea-row row-column row-center">
<view class='condition'>
<view class="name line1">
{{ item.coupon_title }}
</view>
</view>
<view class='data acea-row row-between-wrapper'>
<view>{{item.add_time}}-{{item.end_time}}</view>
</view>
<view class="text-bottom acea-row row-middle">
<view v-if="item.applicable_type === 0">通用优惠券</view>
<view v-else-if="item.applicable_type === 1">品类优惠券</view>
<view v-else-if="item.applicable_type === 3">品牌优惠券</view>
<view v-else>商品优惠券</view>
<view v-show="item.rule">丨</view>
<view class="" v-show="item.rule" @click="openRule(index)">查看用券规则<text class="iconfont icon-ic_downarrow"></text></view>
</view>
</view>
<view class="btn-box acea-row row-middle">
<view class="btn disabled" v-if="navOn == 1">已使用</view>
<view class="btn disabled" v-else-if="navOn == 2">已失效</view>
<view class="btn" v-else @click="useCoupon(item)">去使用</view>
</view>
</view>
<view class="rule-desc" v-if="item.ruleShow">
<view v-for="(ruleItem, idx) in item.rules" :key="idx">{{ ruleItem }}</view>
</view>
</view>
</view>
<view class='px-20' v-if="!couponsList.length && !loading">
<emptyPage title="暂无优惠券,去看点别的吧~" src="/statics/images/noCoupon.gif"></emptyPage>
</view>
</view>
</template>
<script>
import {
getCouponsNum,
getUserCoupons
} from '@/api/api.js';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from "vuex";
import colors from '@/mixins/color.js';
import emptyPage from '@/components/emptyPage.vue';
import {
HTTP_REQUEST_URL
} from '@/config/app';
export default {
components: {
emptyPage
},
mixins: [colors],
data() {
return {
couponsList: [],
loading: false,
isAuto: false, //没有授权的不会自动授权
isShowAuth: false, //是否隐藏授权
navOn: 0,
type: '',
page: 1,
limit: 15,
finished: false,
imgHost: HTTP_REQUEST_URL,
expired: 0,
not_used: 0,
used: 0,
navList: [
{name: '全部',type: ''},
{name: '快过期',type: -1},
{name: '通用券',type: 0},
{name: '品类券',type: 1},
{name: '商品券',type: 2},
{name: '品牌券',type: 3},
],
};
},
computed: mapGetters(['isLogin']),
watch: {
isLogin: {
handler: function(newV, oldV) {
if (newV) {
// #ifdef H5 || APP-PLUS
this.getUseCoupons();
// #endif
}
},
deep: true
}
},
onLoad() {
if (this.isLogin) {
this.getCouponsNum();
this.getUseCoupons();
} else {
toLogin()
}
},
onShow() {
uni.removeStorageSync('form_type_cart');
},
onReachBottom() {
this.getUseCoupons();
},
methods: {
getCouponsNum() {
getCouponsNum().then(res => {
this.used = res.data.used;
this.not_used = res.data.not_used;
this.expired = res.data.expired;
});
},
onNav: function(type) {
this.navOn = type;
// if (this.navOn) {
// this.type = 0;
// } else {
// this.type = -1;
// }
this.couponsList = [];
this.page = 1;
this.finished = false;
this.getUseCoupons();
},
onSubNav(type) {
this.type = type;
this.couponsList = [];
this.page = 1;
this.finished = false;
this.getUseCoupons();
},
useCoupon(item) {
let url = '';
// 通用券
if (item.category_id == 0 && item.product_id == '' && item.brand_id == 0) {
url = '/pages/goods/goods_list/index?title=默认'
}
// 品类券
if (item.category_id != 0) {
if (item.category_type == 1) {
url = '/pages/goods/goods_list/index?cid=' + item.category_id + '&title=' + item.category_name
} else {
url = '/pages/goods/goods_list/index?sid=' + item.category_id + '&title=' + item.category_name
}
}
//商品券
if (item.product_id != '') {
let arr = item.product_id.split(',');
let num = arr.length;
if (num == 1) {
url = '/pages/goods_details/index?id=' + item.product_id
} else {
url = '/pages/goods/goods_list/index?productId=' + item.product_id + '&title=默认'
}
}
//品牌券
if (item.brand_id != 0) {
url = '/pages/goods/goods_list/index?brandId=' + item.brand_id + '&title=默认'
}
uni.navigateTo({
url: url
});
},
/**
* 授权回调
*/
onLoadFun: function() {
this.getUseCoupons();
this.isShowAuth = false;
},
// 授权关闭
authColse: function(e) {
this.isShowAuth = e
},
/**
* 获取领取优惠券列表
*/
getUseCoupons: function() {
let that = this;
if (that.loading || that.finished) {
return;
}
that.loading = true;
uni.showLoading({
title: '正在加载…'
});
getUserCoupons(this.navOn, {
type: this.type,
page: this.page,
limit: this.limit
}).then(res => {
that.loading = false;
uni.hideLoading();
res.data.forEach(item => {
item.ruleShow = false;
item.rules = item.rule ? item.rule.split('\n') : [];
});
that.couponsList = that.couponsList.concat(res.data);
that.finished = res.data.length < that.limit;
that.page += 1;
}).catch(err => {
that.loading = false;
uni.showToast({
title: err,
icon: 'none'
});
});
},
openRule(index) {
this.couponsList[index].ruleShow = !this.couponsList[index].ruleShow
},
}
}
</script>
<style lang="scss" scoped>
.money {
display: flex;
flex-direction: column;
justify-content: center;
}
.pic-num {
color: #ffffff;
font-size: 24rpx;
}
.coupon-list .item .text .condition {
display: flex;
align-items: center;
}
.coupon-list .item .text .condition .name {
width: 312rpx;
font-size: 28rpx;
line-height: 40rpx;
font-weight: 500;
}
.coupon-list .item .text .condition .pic {
width: 30rpx;
height: 30rpx;
display: block;
margin-right: 10rpx;
display: inline-block;
vertical-align: sub;
}
.condition .line-title {
/* width: 70rpx; */
padding: 0 12rpx;
height: 32rpx !important;
/* #ifndef APP */
line-height: 28rpx;
/* #endif */
/* #ifdef APP */
line-height: 30rpx;
/* #endif */
text-align: center;
box-sizing: border-box;
background: var(--view-minorColorT);
border: 1px solid var(--view-theme);
opacity: 1;
border-radius: 20rpx;
font-size: 18rpx !important;
color: var(--view-theme);
margin-right: 12rpx;
text-align: center;
display: inline-block;
vertical-align: middle;
}
.condition .title {
vertical-align: middle;
}
.condition .line-title.bg-color-huic {
border-color: #BBB !important;
color: #bbb !important;
background-color: #F5F5F5 !important;
}
.header-shadow {
height: 194rpx;
}
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #FFFFFF;
z-index: 9;
}
.subnavbar {
height: 92rpx;
.on {
border-color: var(--view-theme);
background-color: var(--view-minorColorT);
font-weight: 500;
font-size: 24rpx;
color: var(--view-theme);
}
}
.navbar {
height: 82rpx;
.item {
flex: 1;
position: relative;
font-size: 26rpx;
color: #666666;
.number {
height: 34rpx;
padding: 0 16rpx;
border-radius: 17rpx;
margin-top: 8rpx;
background-color: transparent;
font-size: 24rpx;
line-height: 34rpx;
color: #666666;
}
&.on {
font-weight: 500;
font-size: 28rpx;
color: var(--view-theme);
.number {
background-color: var(--view-theme);
color: #FFFFFF;
}
}
}
}
.coupon-list {
padding: 0 20rpx;
margin-top: 0;
.item {
height: auto;
background: none;
}
.item-box {
height: 170rpx;
border-radius: 24rpx;
background: #FFFFFF;
}
.moneyCon {
border-radius: 24rpx 0 0 24rpx;
background: linear-gradient(270deg, var(--view-gradient) 0%, var(--view-theme) 100%);
color: #FFFFFF;
}
.money {
position: relative;
background-image: radial-gradient(circle at left, #F5F5F5 16rpx, transparent 0);
color: #FFFFFF;
font-size: 52rpx;
font-family: Regular;
&::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: 6rpx;
background-image: radial-gradient(circle at 6rpx, #FFFFFF 6rpx, transparent 6rpx);
background-size: 6rpx 18rpx;
}
}
.pic-num {
margin-top: 8rpx;
font-weight: 400;
font-size: 22rpx;
line-height: 28rpx;
}
.text-bottom {
margin-top: 20rpx;
font-size: 20rpx;
line-height: 28rpx;
color: #999999;
.iconfont {
margin-left: 6rpx;
font-size: 20rpx;
}
}
.btn-box {
padding: 0 20rpx;
}
.btn {
height: 52rpx;
padding: 0 24rpx;
border-radius: 26rpx;
background-color: var(--view-minorColorT);
font-weight: 500;
font-size: 22rpx;
line-height: 52rpx;
color: var(--view-theme);
}
.disabled {
background-color: #ccc;
color: #fff;
}
.rule-desc {
padding: 42rpx 24rpx 24rpx;
border-radius: 0 0 24rpx 24rpx;
background: linear-gradient(180deg, #F7F7F7 0%, #FFFFFF 100%);
font-size: 20rpx;
line-height: 28rpx;
color: #999999;
}
.gray {
.moneyCon {
background: #CCCCCC;
}
.item-right {
background-color: #CCCCCC;
color: #FFFFFF;
}
}
}
.svip .btn{
background: linear-gradient(90deg, #584834 0%, #32302D 100%);
color: #FACC7D;
}
.svip .moneyCon{
background: linear-gradient(90deg, #584834 0%, #32302D 100%);
color: #FACC7D;
}
.svip .pic-num{
color: #FACC7D;
}
</style>

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