tmp: 部分代码与UnishopV5结合,但是代码有严重缺陷

This commit is contained in:
2025-12-20 15:30:39 +08:00
parent ed5181b382
commit e263a616f6
183 changed files with 31316 additions and 18590 deletions

View File

@@ -1,159 +1,165 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="page">
<view class="help-title">{{ detail.article_title }}</view>
<view class="help-meta" v-if="detail.is_show_release_time == 1">
<text class="help-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text>
</view>
<view class="help-content"><rich-text :nodes="content"></rich-text></view>
<view class="bottom-area">
<view v-if="detail.is_show_read_num == 1">
阅读
<text class="price-font">{{ detail.read_num + detail.initial_read_num }}</text>
</view>
<view v-if="detail.is_show_dianzan_num == 1">
<text class="price-font">{{ detail.dianzan_num + detail.initial_dianzan_num }}</text>
人已赞
</view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import htmlParser from '@/common/js/html-parser';
export default {
data() {
return {
articleId: 0,
detail: {},
content: ''
};
},
onLoad(options) {
this.articleId = options.article_id || 0;
// 小程序扫码进入
if (options.scene) {
var sceneParams = decodeURIComponent(options.scene);
this.articleId = sceneParams.split('-')[1];
}
if (this.articleId == 0) {
this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo');
}
},
onShow() {
this.getData();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/api/article/info',
data: {
article_id: this.articleId
},
success: res => {
if (res.code == 0 && res.data) {
this.detail = res.data;
this.$langConfig.title(this.detail.article_title);
this.content = htmlParser(this.detail.article_content);
this.setPublicShare();
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo');
}, 2000);
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
// 设置公众号分享
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_tool/article/detail?article_id=' + this.articleId;
this.$util.setPublicShare({
title: this.detail.article_title,
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},
onShareAppMessage(res) {
var title = this.detail.article_title;
var path = '/pages_tool/article/detail?article_id=' + this.articleId;
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
},
//分享到朋友圈
onShareTimeline() {
var title = this.detail.article_title;
var query = 'article_id=' + this.articleId;
return {
title: title,
query: query,
imageUrl: ''
};
}
};
</script>
<style lang="scss">
.page {
width: 100%;
height: 100%;
padding: 30rpx;
box-sizing: border-box;
background: #ffffff;
}
.help-title {
font-size: $font-size-toolbar;
text-align: left;
font-weight: bold;
}
.help-content {
margin-top: $margin-updown;
word-break: break-all;
}
.help-meta {
text-align: left;
margin-top: $margin-updown;
color: $color-tip;
.help-time {
font-size: $font-size-tag;
}
}
.bottom-area {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 40rpx;
.price-font {
font-weight: normal !important;
}
view {
color: #999;
font-size: 24rpx;
}
}
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="page">
<view class="help-title">{{ detail.article_title }}</view>
<view class="help-meta" v-if="detail.is_show_release_time == 1">
<text class="help-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text>
</view>
<view class="help-content">
<!-- <rich-text :nodes="content"></rich-text> -->
<ns-mp-html :content="content"></ns-mp-html>
</view>
<view class="bottom-area">
<view v-if="detail.is_show_read_num == 1">
阅读
<text class="price-font">{{ detail.read_num + detail.initial_read_num }}</text>
</view>
<view v-if="detail.is_show_dianzan_num == 1">
<text class="price-font">{{ detail.dianzan_num + detail.initial_dianzan_num }}</text>
人已赞
</view>
</view>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import htmlParser from '@/common/js/html-parser';
export default {
data() {
return {
articleId: 0,
detail: {},
content: ''
};
},
onLoad(options) {
this.articleId = options.article_id || 0;
// 小程序扫码进入
if (options.scene) {
var sceneParams = decodeURIComponent(options.scene);
this.articleId = sceneParams.split('-')[1];
}
if (this.articleId == 0) {
this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo');
}
},
onShow() {
this.getData();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/api/article/info',
data: {
article_id: this.articleId
},
success: res => {
if (res.code == 0 && res.data) {
this.detail = res.data;
this.$langConfig.title(this.detail.article_title);
// this.content = htmlParser(this.detail.article_content);
this.content = this.detail.article_content;
this.setPublicShare();
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/article/list', {}, 'redirectTo');
}, 2000);
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
// 设置公众号分享
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_tool/article/detail?article_id=' + this.articleId;
this.$util.setPublicShare({
title: this.detail.article_title,
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},
onShareAppMessage(res) {
var title = this.detail.article_title;
var path = '/pages_tool/article/detail?article_id=' + this.articleId;
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
},
//分享到朋友圈
onShareTimeline() {
var title = this.detail.article_title;
var query = 'article_id=' + this.articleId;
return {
title: title,
query: query,
imageUrl: ''
};
}
};
</script>
<style lang="scss">
.page {
width: 100%;
height: 100%;
padding: 30rpx;
box-sizing: border-box;
background: #ffffff;
}
.help-title {
font-size: $font-size-toolbar;
text-align: left;
font-weight: bold;
}
.help-content {
margin-top: $margin-updown;
word-break: break-all;
}
.help-meta {
text-align: left;
margin-top: $margin-updown;
color: $color-tip;
.help-time {
font-size: $font-size-tag;
}
}
.bottom-area {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 40rpx;
.price-font {
font-weight: normal !important;
}
view {
color: #999;
font-size: 24rpx;
}
}
</style>

View File

@@ -1,7 +1,21 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<mescroll-uni @getData="getData" ref="mescroll">
<scroll-view class="catrgory-nav" scroll-x="true" :scroll-left="scrollLeft" :show-scrollbar="false" scroll-with-animation="true">
<view class="navs">
<view v-for="(categoryItem, categoryIndex) in categoryList" :key="categoryIndex" class="uni-tab-item" :id="categoryItem.category_id" :data-current="categoryIndex" @click="ontabtap">
<text class="uni-tab-item-title" :class="categoryItem.category_id == categoryId ? 'uni-tab-item-title-active color-base-text' : ''">
{{ categoryItem.category_name }}
</text>
</view>
</view>
</scroll-view>
<!-- #ifdef MP -->
<mescroll-uni ref="mescroll" @getData="getData" top="60rpx" >
<!-- #endif -->
<!-- #ifndef MP -->
<mescroll-uni ref="mescroll" @getData="getData" top="86rpx" >
<!-- #endif -->
<block slot="list">
<view class="article-wrap" v-if="list.length">
<ns-adv keyword="NS_ARTICLE" class-name="adv-wrap"></ns-adv>
@@ -16,7 +30,7 @@
<text class="category-icon"></text>
<text>{{ item.category_name }}</text>
</block>
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'date') }}</text>
<text class="date">{{ $util.timeStampTurnTime(item.create_time, 'Y-m-d') }}</text>
</view>
</view>
</view>
@@ -25,6 +39,8 @@
<loading-cover ref="loadingCover"></loading-cover>
</block>
</mescroll-uni>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
@@ -38,22 +54,71 @@
export default {
data() {
return {
list: []
list: [],
categoryList: [],
categoryId: '',
scrollLeft: 0,
contentScrollW: 0, // 导航区宽度
};
},
components: {
nsAdv
},
onShow() {
this.getArticleCategory()
this.setPublicShare();
},
methods: {
getScrollW() {
const query = uni.createSelectorQuery().in(this);
query.select('.catrgory-nav').boundingClientRect(data => {
// 拿到 scroll-view 组件宽度
this.contentScrollW = data.width
}).exec();
query.selectAll('.uni-tab-item').boundingClientRect(data => {
let dataLen = data.length;
for (let i = 0; i < dataLen; i++) {
// scroll-view 子元素组件距离左边栏的距离
this.categoryList[i].left = data[i].left;
// scroll-view 子元素组件宽度
this.categoryList[i].width = data[i].width
}
}).exec()
},
ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current;
this.categoryId = this.categoryList[index].category_id;
this.scrollLeft = this.categoryList[index].left - this.contentScrollW / 2 + this.categoryList[index].width / 2;
this.$refs.loadingCover.show();
this.$refs.mescroll.refresh();
},
/**
* 获取文章分类
*/
getArticleCategory() {
this.$api.sendRequest({
url: '/api/article/category',
success: res => {
if (res.code >= 0) {
this.categoryList = [{ category_id: '',category_name: '全部' }]
this.categoryList.push(...res.data);
this.$nextTick(()=>{
this.getScrollW()
})
}
},
});
},
getData(mescroll) {
this.$api.sendRequest({
url: '/api/article/page',
data: {
page_size: mescroll.size,
page: mescroll.num
page: mescroll.num,
category_id: this.categoryId
},
success: res => {
let newArr = [];
@@ -128,7 +193,60 @@
.empty-wrap {
padding-top: 200rpx;
}
.catrgory-nav {
height: 80rpx;
background: #fff;
position: fixed;
left: 0;
z-index: 998;
border-radius: 0px 0px 24rpx 24rpx;
.navs {
flex-direction: row;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
display: flex;
justify-content: space-around;
}
.uni-tab-item {
padding: 0 30rpx;
text-align: center;
}
.uni-tab-item-title {
display: inline-block;
height: 80rpx;
line-height: 80rpx;
border-bottom: 1px solid #fff;
flex-wrap: nowrap;
/* #ifndef APP-PLUS */
white-space: nowrap;
/* #endif */
text-align: center;
font-size: 30rpx;
position: relative;
}
.uni-tab-item-title-active::after {
content: ' ';
display: block;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 6rpx;
background: linear-gradient(270deg, var(--base-color-light-9) 0%, var(--base-color) 100%);
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
}
.article-wrap {
background: #f8f8f8;

896
pages_tool/chat/room.vue Normal file
View File

@@ -0,0 +1,896 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="container" id="container">
<view class="room" :class="keyWordsConfig.is_open == 1 ? 'active' : ''" @click="closePopWindow">
<view class="tips" :class="{ show: isLoading }">正在获取消息</view>
<view class="room-content-box">
<view :id="'chat' + index" v-for="(item, index) in messageList" :key="index">
<chat-message :message="item" @sendGood="sendGood($event, index)" @sendOrder="sendOrder($event, index)" :send="send"></chat-message>
</view>
</view>
<view class="paddingbottom" id="paddingbottom" v-if="chatBottom"></view>
</view>
<view class="input-content" :class="keyWordsConfig.is_open == 1 ? 'active' : ''">
<view class="keyWords" v-if="keyWordsConfig.is_open == 1">
<text v-for="(item, index) in keyWordsConfig.keyword_list" :key="index" @click="
formData.content = item.keyword;
sendMsg('message');
">
{{ item.keyword }}
</text>
</view>
<view class="input-box">
<view class="iconfont icon-biaoqing padding-right " @click="openEmjoy()"></view>
<editor id="editor" class="message-edit" v-model="formData.content" @ready="onEditorReady" @focus="inputFocus" @input="onEditorinput()" @blur="closePopWindow()"></editor>
<view class="iconfont icon-jiahao01 padding-right" @click="openChatMore()"></view>
<view class="send_btn color-base-bg" @click="sendMsg('message')">发送</view>
</view>
<view class="inputShow" v-if="inputShow && inputFirst"></view>
<view v-if="emjoyShow" @touchmove.prevent.stop>
<view class="emjoy-box">
<scroll-view scroll-y="true" class="emjoy-content">
<view class="emjoy-item" v-for="(item, index) in emjoyList" :key="index" @click="addEmjoy(item, index)">
<image :src="$util.img(item)"></image>
</view>
</scroll-view>
</view>
</view>
<view class="more_send" v-if="chatMore">
<view class="more_send-item" @click="addImg()">
<text class="iconfont icon-tupian "></text>
<view>图片</view>
</view>
</view>
</view>
<!-- 加载动画 -->
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
import SocketTask from '@/common/js/socketTest.js';
import chatMessage from '@/pages_tool/components/chat-message/chat-message.vue';
import emjoy from '@/common/js/emjoy.js';
export default {
components: {
chatMessage
},
data() {
return {
emjoyList: emjoy.emjoyList,
emjoyShow: false,
chatMore: false,
formData: {
content: '',
goods_id: 0,
order_id: 0,
image: ''
},
isNetWork: false,
send: false,
messageList: [],
page: 1,
isAll: false,
isLoading: false,
showLoading: false, //显示正在加载
jumpBottom: null,
scrollTop: 0,
scrollPosition: 0,
siteId: 0, //店铺id
skuId: 0, //商品id
orderId: 0, //订单id
siteName: '', //店铺名称
orderdetail: {},
style: {}, //聊天框的高度
inputFirst: 0,
inputShow: false,
inputOffsetBottom: 0,
goodsDetails: {},
// 定位ID
startId: 0,
goods_type: {
promotion_name: '',
promotion_id: ''
},
keyWordsConfig: {
is_open: 0
}
};
},
mixins: [SocketTask],
computed: {
chatBottom() {
return this.emjoyShow || this.chatMore || this.inputShow;
}
},
onLoad(info) {
if (info.sku_id) {
this.skuId = info.sku_id;
this.getGoodsDetails(info.sku_id);
}
if (info.order_id) {
this.orderId = info.order_id;
this.getOrderInfo(info.order_id);
}
if (this.skuId || this.orderId) {
this.send = true;
}
this.$on('upDOM', () => {
this.setPageScrollTo();
});
if (info.type) {
this.goods_type.promotion_name = info.type;
} else {
this.goods_type.promotion_name = '';
}
if (info.type_id) {
this.goods_type.promotion_id = info.type_id;
} else {
this.goods_type.promotion_id = '';
}
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
return;
}
this.inputFirst = 0;
this.inputShow = false;
this.inputOffsetBottom = 0;
// this.getChatList();
this.getKeyWordsConfig();
uni.setNavigationBarTitle({
title: '商家客服'
});
},
onReady() {
// 监听键盘高度变化,以便设置输入框的高度
uni.onKeyboardHeightChange(res => {
this.inputOffsetBottom = res.height;
if (res.height === 0) {
this.focus = false;
}
});
},
methods: {
// 初次渲染输入框
onEditorReady() {
uni.createSelectorQuery()
.select('#editor')
.context(res => {})
.exec();
},
// 输入时,边输入边保存
onEditorinput() {
uni.createSelectorQuery()
.select('#editor')
.context(res => {
this.editorCtx = res.context;
this.editorCtx.getContents({
success: res => {
this.formData.content = res.html;
}
});
})
.exec();
},
// 加号
openChatMore() {
if (this.$util.isAndroid) {
this.inputShow = false;
this.inputFirst = 1;
}
this.chatMore = !this.chatMore;
this.emjoyShow = false;
this.$nextTick(() => {
this.setPageScrollTo();
});
},
// 获取快捷回复设置
getKeyWordsConfig() {
this.$api.sendRequest({
url: '/servicer/api/chat/keyword',
success: res => {
if (res.code >= 0 && res.data) {
this.keyWordsConfig = res.data;
}
}
});
},
// 获取商品信息,用于推送的商品详情
getGoodsDetails(sku_id) {
this.$api.sendRequest({
url: '/api/goodssku/detail',
data: {
sku_id
},
success: res => {
if (res.code >= 0) {
this.goodsDetails = res.data.goods_sku_detail;
}
}
});
},
// 获取订单信息,用于推送订单
getOrderInfo(id) {
this.$api.sendRequest({
url: '/api/order/detail',
data: {
order_id: id
},
success: res => {
if (res.code >= 0) {
this.orderdetail = res.data;
}
}
});
},
chatListInit(){
this.isAll = false;
this.isLoading = false;
this.page = 1;
},
//获取聊天记录
getChatList() {
// 如果已经获取完了数据,直接返回不进行请求
if (this.isAll) {
this.isLoading = false;
return;
}
// 防重复
if (this.isLoading) return;
this.isLoading = true;
// 如果是第一次请求,手动置空数据
if (this.page == 1) this.messageList = [];
// 用于获取聊天记录时,进行拼接数据,同步定位的位置
let oldStartId = 0;
oldStartId = this.messageList.length;
// 改变this指向
let that = this;
this.$api.sendRequest({
url: '/servicer/api/chat/dialogs',
data: {
servicer_id: this.servicer_id,
page: this.page,
limit: 15,
site_id: that.siteId
},
success(res) {
if (res.code >= 0 && res.data) {
that.page += 1;
// 判定是否获取完数据
if (res.data.list && res.data.list.length < 15) that.isAll = true;
// 处理后的数据容器
let newArr = [];
//如果获取到历史聊天信息 转换为需要的格式 添加到数组内
let arr = res.data.list;
if (arr.length) {
for (let i = 0; i < arr.length; i++) {
let obj = {};
if (arr[i].content_type == 0) {
obj.id = that.startId;
obj.content = arr[i].type == 0 ? arr[i].consumer_say : arr[i].servicer_say;
obj.isItMe = arr[i].type == 0 ? true : false;
obj.contentType = 'string';
obj.sendStatus = true;
obj.avatar = arr[i].avatar;
} else if (arr[i].content_type == 1) {
obj.id = that.startId;
obj.isItMe = arr[i].type == 0 ? true : false;
obj.sku_id = arr[i].goods_sku_id;
obj.sendStatus = true;
if (arr[i].type == 0) {
obj.contentType = 'sendGood';
} else {
obj.contentType = 'goodssku';
}
} else if (arr[i].content_type == 2) {
obj.id = that.startId;
obj.isItMe = arr[i].type == 0 ? true : false;
obj.contentType = 'order';
obj.order_id = arr[i].order_id;
obj.sendStatus = true;
} else if (arr[i].content_type == 3) {
obj.id = that.startId;
obj.isItMe = arr[i].type == 0 ? true : false;
obj.contentType = 'image';
obj.image = arr[i].type == 0 ? arr[i].consumer_say : arr[i].servicer_say;
obj.sendStatus = true;
}
newArr.push(obj);
that.startId += 1;
}
}
setTimeout(() => {
// 如果请求的是第一页并且有订单id或商品id;添加发送信息
if (that.page - 1 == 1) {
if (that.skuId && Object.keys(that.goodsDetails).length > 0) {
let obj = {
id: that.startId,
isItMe: true,
contentType: 'sendGood',
goodsDetail: that.goodsDetails
};
newArr.push(obj);
that.startId += 1;
}
if (that.orderId && Object.keys(that.orderdetail).length > 0) {
let obj = {
id: that.startId,
isItMe: true,
contentType: 'sendOrder',
orderDetail: that.orderdetail
};
newArr.push(obj);
that.startId += 1;
}
// 是否展示客服在线不在线
// let _obj = {};
// _obj.id = that.startId;
// if(that.servicer_id > 0){
// _obj.contentType = 'online';
// } else {
// _obj.contentType = 'noline';
// }
// newArr.push(_obj);
// that.startId += 1;
}
if (newArr.length) {
that.messageList = newArr.concat(that.messageList);
// 同步处理DOM实现聊天记录的无缝对接
that.$nextTick(() => {
if (that.page - 1 == 1) {
setTimeout(() => {
that.setPageScrollTo();
}, 1000);
that.isLoading = false;
} else {
that.setPageScrollTo(
`#chat${that.messageList.length - oldStartId}`);
that.isLoading = false;
}
});
}
}, 500);
} else {
this.$util.showToast({
title: res.message
});
}
that.isLoading = false;
if (that.$refs.loadingCover){
that.$refs.loadingCover.hide();
}
}
});
},
// 设置页面滚动位置
setPageScrollTo(id) {
if (id) {
let view = uni
.createSelectorQuery()
.in(this)
.select(id);
view.boundingClientRect(res => {
uni.pageScrollTo({
scrollTop: res.top - 30, // 为多显示出大半个消息的高度,示意上面还有信息。
duration: 0
});
}).exec();
} else {
let query = uni.createSelectorQuery().in(this);
query.select('.room').boundingClientRect(data => {
uni.pageScrollTo({
scrollTop: data.height - 30, // 为多显示出大半个消息的高度,示意上面还有信息。
duration: 0
});
}).exec();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
},
//发送商品
sendGood(e, index) {
this.sendMsg('goods');
this.messageList.splice(index, 1);
},
//发送订单
sendOrder(e, index) {
this.sendMsg('order');
this.messageList.splice(index, 1);
},
//发送消息
sendMsg(data) {
if (this.isNetWork) return;
this.isNetWork = true;
let that = this;
if (data == 'goods') {
let _type = {};
if (this.goods_type.promotion_id != '') {
_type.promotion_id = this.goods_type.promotion_id;
_type.promotion_name = this.goods_type.promotion_name;
}
this.$api.sendRequest({
url: '/servicer/api/chat/say',
data: {
goods_id: this.skuId,
servicer_id: this.servicer_id,
content_type: 1,
site_id: this.siteId,
relate_data: JSON.stringify(_type)
},
success(res) {
that.send = false;
that.joinData('send', 'goods');
},
complete() {
that.isNetWork = false;
// uni.hideKeyboard();
}
});
} else if (data == 'order') {
this.$api.sendRequest({
url: '/servicer/api/chat/say',
data: {
order_id: this.orderId,
servicer_id: this.servicer_id,
site_id: this.siteId,
content_type: 2
},
success(res) {
that.send = false;
that.joinData('send', 'order');
},
complete() {
that.isNetWork = false;
// uni.hideKeyboard();
}
});
} else if (data == 'image') {
that.joinData('send', 'image');
this.$api.sendRequest({
url: '/servicer/api/chat/say',
data: {
message: this.formData.image.trim(),
servicer_id: this.servicer_id,
site_id: this.siteId,
content_type: 3
},
success(res) {
console.log(res, '图片上传成功');
},
error() {
that.messageList[that.messageList.length - 1].sendStatus = false;
uni.createSelectorQuery().select('#editor').context(res => {
this.editorCtx = res.context;
this.editorCtx.clear();
}).exec();
},
complete() {
that.isNetWork = false;
}
});
} else {
let _text = this.formData.content;
let _testText = _text.replace(/<p>/, '');
let _testText2 = _testText.replace(/<\/p>/, '');
let _testText3 = _testText2.replace(/<br>/, '');
if (_text == '<p></p>' || _text == '<p><br></p>' || !_testText3.trim()) {
this.$util.showToast({
title: '发送内容不能为空'
});
uni.createSelectorQuery().select('#editor').context(res => {
that.editorCtx = res.context;
that.editorCtx.clear();
}).exec();
that.isNetWork = false;
return;
}
that.joinData('send', 'string');
this.$api.sendRequest({
url: '/servicer/api/chat/say',
data: {
message: this.formData.content,
servicer_id: this.servicer_id,
content_type: 0
},
success(res) {
if (res.code == 0) {
console.log(res, '文字上传成功');
that.formData.content = '<p></p>';
uni.createSelectorQuery()
.select('#editor')
.context(res => {
this.editorCtx = res.context;
this.editorCtx.clear();
})
.exec();
}
},
error() {
that.messageList[that.messageList.length - 1].sendStatus = false;
uni.createSelectorQuery().select('#editor').context(res => {
this.editorCtx = res.context;
this.editorCtx.clear();
}).exec();
},
complete() {
that.isNetWork = false;
}
});
}
},
//拼接消息 处理滚动
async joinData(addType, contentType) {
if (addType == 'send') {
let data = {
isItMe: true,
contentType: contentType,
sendStatus: true
};
if (contentType == 'string') {
data.content = this.formData.content;
} else if (contentType == 'order') {
data.order_id = this.orderId;
} else if (contentType == 'goods') {
data.sku_id = this.skuId;
} else if (contentType == 'image') {
data.image = this.formData.image;
}
this.messageList.push(data);
this.$nextTick(() => {
setTimeout(() => {
this.setPageScrollTo();
}, 500);
});
}
},
// 隐藏加载提示
hideLoadTips(flag) {
if (flag) {
this.ajax.loadText = '消息获取成功';
setTimeout(() => {
this.ajax.loading = false;
}, 300);
} else {
this.ajax.loading = true;
this.ajax.loadText = '正在获取消息';
}
},
onPageScroll(e) {
if (e.scrollTop == 0) {
this.getChatList();
}
},
inputFocus(e) {
if (this.$util.isAndroid() && this.inputFirst) {
this.inputShow = true;
}
this.chatMore = false;
// this.$nextTick(() => {
// this.setPageScrollTo();
// });
},
closePopWindow() {
this.inputFirst = 0;
this.chatMore = false;
this.inputShow = false;
// uni.hideKeyboard();
},
// 展开表情
openEmjoy() {
console.log(this.emjoyShow, 'this.emjoyShow');
// if (this.$util.isAndroid()) {
// this.inputFirst = 1;
// this.inputShow = !this.inputShow;
// }
// uni.hideKeyboard();
this.chatMore = false;
this.emjoyShow = !this.emjoyShow;
this.$nextTick(() => {
this.setPageScrollTo();
});
},
// 添加表情
addEmjoy(emjoy, index) {
uni.createSelectorQuery()
.select('#editor')
.context(res => {
this.editorCtx = res.context;
this.editorCtx.getContents({
success: res => {
if (res.html == '<p><br></p>') {
res.html = '<p></p>';
}
let _src = this.$util.img(emjoy);
let text = '<img src="' + _src + '" style="height=20px; width=20px; margin-left=20px;">';
let html2 = res.html.replace(/<\/p>$/, text + '</p>');
this.editorCtx.setContents({
html: html2
});
this.formData.content = html2;
this.emjoyShow = false;
}
});
})
.exec();
},
// 发送图片
addImg() {
this.$util.upload(
1, {
path: 'chatimg'
},
res => {
if (res[0]) {
this.formData.image = res[0];
this.sendMsg('image');
} else {
this.$util.showToast({
title: '上传失败!'
});
return false;
}
},
'/servicer/api/chat/chatimg'
);
}
},
beforeDestroy() {
clearInterval(this.timeoutObj);
this.timeoutObj = null;
this.$api.sendRequest({
url: '/servicer/api/chat/bye',
data: {
servicer_id: this.servicer_id,
site_id: this.siteId
},
success(res) {
uni.closeSocket();
}
});
}
};
</script>
<style lang="scss">
//处理H5端弹出覆盖输入框的问题
.more_send {
display: flex;
border-top: 2rpx solid #e5e5e5;
height: 390rpx;
flex-wrap: wrap;
>view {
padding-top: 16rpx;
width: 25%;
height: 156rpx;
text-align: center;
.iconfont {
display: inline;
font-size: 60rpx;
color: #333;
background-color: #fff;
border-radius: 20rpx;
padding: 20rpx;
}
>view {
color: #909399;
font-size: $font-size-goods-tag;
}
}
}
.chat_send {
display: flex;
height: 90rpx;
justify-content: space-between;
position: relative;
.send {
position: absolute;
right: 30rpx;
bottom: 30rpx;
color: #fff;
align-self: flex-end;
font-size: 28rpx;
padding: 10rpx 20rpx;
border-radius: 8rpx;
}
.emjoy_list {
flex: 1;
}
}
/* 加载数据提示 */
.tips {
position: fixed;
left: 0;
top: var(--window-top);
width: 100%;
z-index: 9;
background-color: rgba(0, 0, 0, 0);
height: 72rpx;
transform: translateY(-80rpx);
transition: transform 0.3s ease-in-out 0s;
font-size: 24rpx;
text-align: center;
line-height: 72rpx;
&.show {
transform: translateY(0);
}
}
.room {
width: 100%;
/* #ifdef H5 */
min-height: calc(100vh - 48rpx);
padding-bottom: calc(110rpx + 88rpx);
padding-bottom: calc(110rpx + 88rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(110rpx + 88rpx + env(safe-area-inset-bottom));
/* #endif */
/* #ifndef H5 */
min-height: calc(100vh + 20rpx);
padding-bottom: 110rpx;
padding-bottom: calc(110rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
&.active {
padding-bottom: 180rpx;
padding-bottom: calc(180rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
}
/* #endif */
box-sizing: border-box;
.room-content-box {
width: 100%;
min-height: calc(100% + 20rpx);
padding-top: $padding;
box-sizing: border-box;
}
}
.paddingbottom {
height: calc(280rpx + 88rpx);
}
.emjoy-box {
width: 100%;
height: 300rpx;
padding: 20rpx 25rpx;
box-sizing: border-box;
background: #f4f4f4;
border-top: 1rpx solid #e5e5e5;
.emjoy-content {
width: 100%;
height: 100%;
.emjoy-item {
display: inline-block;
width: 100rpx;
height: 70rpx;
text-align: center;
line-height: 70rpx;
image {
display: inline-block;
width: 40rpx;
height: 40rpx;
}
}
}
}
.input-content {
background: #f4f4f4;
width: 100%;
min-height: 110rpx;
position: fixed;
left: 0;
bottom: 0;
padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
&.active {
min-height: 180rpx !important;
}
.keyWords {
height: 60rpx;
line-height: 60rpx;
padding: $padding 0 0;
overflow-x: scroll;
display: flex;
margin-left: 20rpx;
margin-right: 20rpx;
text {
font-size: 24rpx;
margin-right: 20rpx;
height: 28rpx;
line-height: 28rpx;
padding: 10rpx 16rpx;
background-color: #fff;
border-radius: $border-radius;
white-space: nowrap;
}
}
.input-box {
width: 100%;
height: auto;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx $padding;
box-sizing: border-box;
.iconfont {
line-height: 1;
font-size: 52rpx;
padding: 15rpx;
}
.send_btn {
font-size: 24rpx;
min-width: 80rpx;
text-align: center;
background-color: #e8e8e8;
color: #fff;
border-radius: 8rpx;
height: 50rpx;
line-height: 50rpx;
}
.message-edit {
padding: 4rpx 15rpx;
line-height: 1.5;
background-color: #ffffff;
// height: 90rpx;
min-height: 60rpx !important;
// max-height: 200rpx;
height: auto !important;
border-radius: 30rpx;
font-size: $font-size-base;
}
// input {
// margin-left: 20rpx;
// margin-right: 20rpx;
// width: 630rpx;
// height: 100%;
// height: 72rpx;
// padding: 0 20rpx;
// font-size: $font-size-tag;
// background-color: #fff;
// border-radius: 8rpx;
// }
}
}
</style>

View File

@@ -1,342 +1,335 @@
<template>
<view class="chat-message">
<block v-if="message.contentType == 'sendGood'">
<ns-chat-goods :skuId="message.sku_id" :goodsDetail="message.goodsDetail" @sendMsg="sendGood"></ns-chat-goods>
</block>
<block v-if="message.contentType == 'sendOrder'">
<ns-chat-order :orderId="message.order_id" :orderdetails="message.orderDetail" @sendMsg="sendOrder"></ns-chat-order>
</block>
<block v-if="message.contentType == 'goodssku'">
<ns-chat-receiveGoods :skuId="message.sku_id"></ns-chat-receiveGoods>
</block>
<view class="message" v-if="message.contentType == 'string'">
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
<block v-if="message.isItMe">
<view class="head_img">
<image class="img" :src="myHeadImg" v-if="myHeadImg" @error="myHeadImgError" mode="aspectFit"/>
<image class="img" :src="defaultHead" mode="aspectFit" v-else/>
</view>
</block>
<block v-else>
<view class="head_img">
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
</view>
</block>
<view class="chat_text">
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
<view class="content"><rich-text :nodes="stringToEmjoy(message.content)"></rich-text></view>
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
</view>
</view>
</view>
<view class="message" v-if="message.contentType == 'image'">
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
<block v-if="message.isItMe">
<view class="head_img">
<image class="img" :src="myHeadImg" v-if="myHeadImg" mode="aspectFit"></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
</view>
</block>
<block v-else>
<view class="head_img">
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
</view>
</block>
<view class="chat_img">
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
<view class="content_img" @click="previewMedia($util.img(message.image))" :style="{ backgroundImage: 'url(' + $util.img(message.image) + ')' }">
<!-- <image class="img_img" :src="$util.img(message.image)" mode="aspectFit"></image> -->
</view>
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
</view>
</view>
</view>
<view v-else-if="message.contentType == 'goods'"><ns-chat-goods :isCanSend="false" :skuId="message.sku_id"></ns-chat-goods></view>
<view v-else-if="message.contentType == 'order'"><ns-chat-order :isCanSend="false" :orderId="message.order_id"></ns-chat-order></view>
<view class="no-connect-box" v-if="message.contentType == 'noline'">
<view class="no-connect">客服不在线</view>
</view>
<view class="no-connect-box" v-if="message.contentType == 'online'">
<view class="no-connect">客服在线</view>
</view>
<uni-popup ref="imgPopup" type="center">
<view class="imagePop">
<image :src="$util.img(currImg)" mode="aspectFit"></image>
</view>
</uni-popup>
</view>
</template>
<script>
import nsChatGoods from '@/pages_tool/components/ns-chat/ns-chat-goods.vue';
import nsChatOrder from '@/pages_tool/components/ns-chat/ns-chat-order.vue';
import nsChatReceiveGoods from '@/pages_tool/components/ns-chat/ns-chat-receiveGoods.vue';
import htmlParser from '@/common/js/html-parser';
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import emjoy from '@/common/js/emjoy.js';
export default {
name: 'chat-message',
props: {
message: {
type: Object
},
send: {
type: Boolean
}
},
data() {
return {
avatar: '', //店铺头像
defaultAvatar: this.$util.getDefaultImage().store,
myHeadImg: '', //我的头像
defaultHead: this.$util.getDefaultImage().head,
emjoyList: emjoy.emjoyList,
currImg: ''
};
},
components: {
nsChatGoods,
nsChatOrder,
uniPopup,
nsChatReceiveGoods
},
mounted() {
this.avatar = this.$util.img(this.siteInfo.logo_square);
this.myHeadImg = this.$util.img(this.memberInfo.headimg);
},
methods: {
// 预览图片
previewMedia(img_url) {
var paths = [img_url];
uni.previewImage({
current: 0,
urls: paths
});
},
sendGood() {
this.$emit('sendGood', 'goods');
},
sendOrder() {
this.$emit('sendOrder', 'order');
},
// 处理图片错误
myHeadImgError() {
this.myHeadImg = this.defaultHead;
},
stringToEmjoy(value) {
if (!value) return;
// 兼容旧版本图片
var reg = RegExp(/\[/);
if (reg.test(value)) {
let string = value; // 需要把和匹配出来
let reg = new RegExp('\\[emjoy_(.+?)\\]', 'g');
let emjoyString = string.replace(reg, v => {
let emjoy = '';
for (let index in this.emjoyList) {
if (v == index) {
let _url = this.$util.img(this.emjoyList[index]);
emjoy = "<img class='message-img' src='" + _url + "'/>";
break;
}
}
if (emjoy) {
return emjoy;
} else {
return v;
}
});
let content = htmlParser(emjoyString);
content.forEach(v => {
if (v.name == 'img') {
v.attrs.style = 'display: inline-block;width: 32rpx !important;height: 32rpx !important;padding:0 2rpx;';
}
});
return content;
} else {
let content = value;
return content;
}
}
}
};
</script>
<style lang="scss">
/deep/.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background-color: #000;
}
/deep/.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
max-width: 100%;
width: 100%;
}
.imagePop {
height: 50vh;
width: 100vw;
text-align: center;
image {
width: 100%;
height: 100%;
}
}
.chat-message {
width: 100%;
height: 100%;
.message {
padding: 13rpx 20rpx;
position: relative;
}
.left .content {
padding: 20rpx;
max-width: 450rpx;
border-radius: 10rpx;
font-size: 30rpx;
}
.right .content {
padding: 20rpx;
max-width: 450rpx;
border-radius: 10rpx;
font-size: 30rpx;
}
.content_img {
height: 200rpx;
width: 100%;
overflow: hidden;
text-align: right;
margin-left: 28rpx;
background-position: center right;
background-repeat: no-repeat;
background-size: contain;
image {
min-height: 80rpx;
min-width: 80rpx;
height: 100%;
width: 100%;
}
}
.right .content_img {
margin-right: 28rpx;
margin-left: 0;
}
.message-item {
display: flex;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
flex-wrap: nowrap;
flex-direction: row;
.head_img {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
overflow: hidden;
position: relative;
.img {
width: 100%;
height: 100%;
}
}
//图片
.contentType3 {
padding: 0;
border-radius: 2rpx;
background-color: transparent !important;
.img {
width: 200rpx;
height: auto;
max-width: 300rpx;
max-height: 400rpx;
}
}
.contentType3::after {
border: none !important;
display: none !important;
}
.content-type-right {
flex-direction: row-reverse;
}
&.right {
flex-direction: row-reverse;
.content {
background-color: #4cd964;
margin-right: 28rpx;
word-break: break-all;
line-height: 36rpx;
position: relative;
}
}
&.left {
.content {
background-color: #ffffff;
margin-left: 28rpx;
word-break: break-all;
line-height: 36rpx;
position: relative;
}
}
}
.next {
width: 100%;
height: 20rpx;
}
}
.no-connect-box {
width: 100%;
text-align: center;
margin: 20rpx 0 50rpx;
.no-connect {
display: inline-block;
padding: 0 20rpx;
height: 40rpx;
background: red;
margin: 0 auto;
background: rgba(0, 0, 0, 0.5);
border-radius: 9rpx;
text-align: center;
line-height: 40rpx;
font-size: 22rpx;
color: #ffffff;
}
}
.chat_text,
.chat_img {
display: flex;
align-items: center;
.iconfont {
font-size: 36rpx;
}
}
.chat_img {
width: 30%;
height: 200rpx;
}
<template>
<view class="chat-message">
<block v-if="message.contentType == 'sendGood'">
<ns-chat-goods :skuId="message.sku_id" :goodsDetail="message.goodsDetail" @sendMsg="sendGood"></ns-chat-goods>
</block>
<block v-if="message.contentType == 'sendOrder'">
<ns-chat-order :orderId="message.order_id" :orderdetails="message.orderDetail" @sendMsg="sendOrder"></ns-chat-order>
</block>
<block v-if="message.contentType == 'goodssku'">
<ns-chat-receiveGoods :skuId="message.sku_id"></ns-chat-receiveGoods>
</block>
<view class="message" v-if="message.contentType == 'string'">
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
<view class="head_img" v-if="message.isItMe">
<image class="img" :src="myHeadImg" v-if="myHeadImg" @error="myHeadImgError" mode="aspectFill"/>
<image class="img" :src="defaultHead" mode="aspectFill" v-else/>
</view>
<view class="head_img" v-else>
<image class="img" :src="$util.img(message.avatar)" mode="aspectFill" v-if="$util.img(message.avatar)"></image>
<image class="img" :src="avatar" mode="aspectFill" v-else-if="avatar"></image>
<image class="img" :src="defaultHead" mode="aspectFill" v-else></image>
</view>
<view class="chat_text">
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
<view class="content"><rich-text :nodes="stringToEmjoy(message.content)"></rich-text></view>
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
</view>
</view>
</view>
<view class="message" v-if="message.contentType == 'image'">
<view class="message-item " :class="message.isItMe ? 'right' : 'left'">
<view class="head_img" v-if="message.isItMe">
<image class="img" :src="myHeadImg" v-if="myHeadImg" mode="aspectFit"></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
</view>
<view class="head_img" v-else>
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image>
</view>
<view class="chat_img">
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
<view class="content_img" @click="previewMedia($util.img(message.image))" :style="{ backgroundImage: 'url(' + $util.img(message.image) + ')' }">
<!-- <image class="img_img" :src="$util.img(message.image)" mode="aspectFit"></image> -->
</view>
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
</view>
</view>
</view>
<view v-else-if="message.contentType == 'goods'"><ns-chat-goods :isCanSend="false" :skuId="message.sku_id"></ns-chat-goods></view>
<view v-else-if="message.contentType == 'order'"><ns-chat-order :isCanSend="false" :orderId="message.order_id"></ns-chat-order></view>
<view class="no-connect-box" v-if="message.contentType == 'noline'">
<view class="no-connect">客服不在线</view>
</view>
<view class="no-connect-box" v-if="message.contentType == 'online'">
<view class="no-connect">客服在线</view>
</view>
<uni-popup ref="imgPopup" type="center">
<view class="imagePop">
<image :src="$util.img(currImg)" mode="aspectFit"></image>
</view>
</uni-popup>
</view>
</template>
<script>
import nsChatGoods from '@/pages_tool/components/ns-chat/ns-chat-goods.vue';
import nsChatOrder from '@/pages_tool/components/ns-chat/ns-chat-order.vue';
import nsChatReceiveGoods from '@/pages_tool/components/ns-chat/ns-chat-receiveGoods.vue';
import htmlParser from '@/common/js/html-parser';
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import emjoy from '@/common/js/emjoy.js';
export default {
name: 'chat-message',
props: {
message: {
type: Object
},
send: {
type: Boolean
}
},
data() {
return {
avatar: '', //店铺头像
defaultAvatar: this.$util.getDefaultImage().store,
myHeadImg: '', //我的头像
defaultHead: this.$util.getDefaultImage().head,
emjoyList: emjoy.emjoyList,
currImg: ''
};
},
components: {
nsChatGoods,
nsChatOrder,
uniPopup,
nsChatReceiveGoods
},
mounted() {
this.avatar = this.$util.img(this.siteInfo.logo_square);
this.myHeadImg = this.$util.img(this.memberInfo.headimg);
},
methods: {
// 预览图片
previewMedia(img_url) {
var paths = [img_url];
uni.previewImage({
current: 0,
urls: paths
});
},
sendGood() {
this.$emit('sendGood', 'goods');
},
sendOrder() {
this.$emit('sendOrder', 'order');
},
// 处理图片错误
myHeadImgError() {
this.myHeadImg = this.defaultHead;
},
stringToEmjoy(value) {
if (!value) return;
// 兼容旧版本图片
var reg = RegExp(/\[/);
if (reg.test(value)) {
let string = value; // 需要把和匹配出来
let reg = new RegExp('\\[emjoy_(.+?)\\]', 'g');
let emjoyString = string.replace(reg, v => {
let emjoy = '';
for (let index in this.emjoyList) {
if (v == index) {
let _url = this.$util.img(this.emjoyList[index]);
emjoy = "<img class='message-img' src='" + _url + "'/>";
break;
}
}
if (emjoy) {
return emjoy;
} else {
return v;
}
});
let content = htmlParser(emjoyString);
content.forEach(v => {
if (v.name == 'img') {
v.attrs.style = 'display: inline-block;width: 32rpx !important;height: 32rpx !important;padding:0 2rpx;';
}
});
return content;
} else {
let content = value;
return content;
}
}
}
};
</script>
<style lang="scss">
/deep/.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background-color: #000;
}
/deep/.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
max-width: 100%;
width: 100%;
}
.imagePop {
height: 50vh;
width: 100vw;
text-align: center;
image {
width: 100%;
height: 100%;
}
}
.chat-message {
width: 100%;
height: 100%;
.message {
padding: 13rpx 20rpx;
position: relative;
}
.left .content {
padding: 20rpx;
max-width: 450rpx;
border-radius: 10rpx;
font-size: 30rpx;
}
.right .content {
padding: 20rpx;
max-width: 450rpx;
border-radius: 10rpx;
font-size: 30rpx;
}
.content_img {
height: 200rpx;
width: 100%;
overflow: hidden;
text-align: right;
margin-left: 28rpx;
background-position: center right;
background-repeat: no-repeat;
background-size: contain;
image {
min-height: 80rpx;
min-width: 80rpx;
height: 100%;
width: 100%;
}
}
.right .content_img {
margin-right: 28rpx;
margin-left: 0;
}
.message-item {
display: flex;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
flex-wrap: nowrap;
flex-direction: row;
.head_img {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
overflow: hidden;
position: relative;
.img {
width: 100%;
height: 100%;
}
}
//图片
.contentType3 {
padding: 0;
border-radius: 2rpx;
background-color: transparent !important;
.img {
width: 200rpx;
height: auto;
max-width: 300rpx;
max-height: 400rpx;
}
}
.contentType3::after {
border: none !important;
display: none !important;
}
.content-type-right {
flex-direction: row-reverse;
}
&.right {
flex-direction: row-reverse;
.content {
background-color: #4cd964;
margin-right: 28rpx;
word-break: break-all;
line-height: 36rpx;
position: relative;
}
}
&.left {
.content {
background-color: #ffffff;
margin-left: 28rpx;
word-break: break-all;
line-height: 36rpx;
position: relative;
}
}
}
.next {
width: 100%;
height: 20rpx;
}
}
.no-connect-box {
width: 100%;
text-align: center;
margin: 20rpx 0 50rpx;
.no-connect {
display: inline-block;
padding: 0 20rpx;
height: 40rpx;
background: red;
margin: 0 auto;
background: rgba(0, 0, 0, 0.5);
border-radius: 9rpx;
text-align: center;
line-height: 40rpx;
font-size: 22rpx;
color: #ffffff;
}
}
.chat_text,
.chat_img {
display: flex;
align-items: center;
.iconfont {
font-size: 36rpx;
}
}
.chat_img {
width: 30%;
height: 200rpx;
}
</style>

View File

@@ -388,7 +388,6 @@ export default {
data: this.rtn,
base64: this.base64 || null
});
return;
});
// #endif
// #ifndef H5

View File

@@ -6,10 +6,8 @@
<view :class="['item', { active: codeIndex === item, middle: type === 'middle', bottom: type === 'bottom', box: type === 'box' }]">
<view class="line" v-if="type !== 'middle'"></view>
<view v-if="type === 'middle' && codeIndex <= item" class="bottom-line"></view>
<block v-if="isPwd && codeArr.length >= item"><text class="dot"></text></block>
<block v-else>
<text class="number">{{ codeArr[index] ? codeArr[index] : '' }}</text>
</block>
<text v-if="isPwd && codeArr.length >= item" class="dot"></text>
<text v-else class="number">{{ codeArr[index] ? codeArr[index] : '' }}</text>
</view>
</block>
</view>

View File

@@ -1,142 +1,142 @@
<template>
<view class="message">
<view class="goods-item" v-if="goodsInfo.goods_name">
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill"></image>
<view class="goods-info">
<view class="goods-name">{{ goodsInfo.sku_name ? goodsInfo.sku_name : goodsInfo.goods_name }}</view>
<view class="goods-bottom">
<view class="goods-price">
<text class="goods-price-sign color-base-text"></text>
<text class="color-base-text">{{ goodsInfo.price }}</text>
</view>
<view class="goods-option font-size-goods-tag disabled">已发送</view>
</view>
</view>
</view>
<view class="goods-item" v-else-if="goodsDetail">
<image :src="$util.img(goodsDetail.sku_image)" mode="aspectFill"></image>
<view class="goods-info">
<view class="goods-name">{{ goodsDetail.sku_name ? goodsDetail.sku_name : goodsDetail.goods_name }}</view>
<view class="goods-bottom">
<view class="goods-price">
<text class="goods-price-sign color-base-text"></text>
<text class="color-base-text">{{ goodsDetail.price }}</text>
</view>
<view class="goods-option font-size-goods-tag color-base-bg" @click="sendMsg('goods')">发送</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'ns-chat-goods',
props: {
skuId: {
type: [Number, String]
},
goodsDetail: {
type: [Object]
}
},
data() {
return {
goodsInfo: {}
};
},
mounted() {
this.getGoodsInfo();
},
methods: {
getGoodsInfo() {
this.$api.sendRequest({
url: '/api/goodssku/detail',
data: {
sku_id: this.skuId
},
success: res => {
if (res.code >= 0) {
this.goodsInfo = res.data.goods_sku_detail;
}
}
});
},
sendMsg() {
this.$emit('sendMsg', 'goods');
}
}
};
</script>
<style lang="scss">
.message {
padding: 13rpx 20rpx;
box-sizing: border-box;
width: 100vw;
position: relative;
.goods-item {
width: 100%;
height: 220rpx;
background: #ffffff;
position: relative;
display: flex;
align-items: center;
border-radius: 20rpx;
margin: 0 auto;
padding: $padding;
box-sizing: border-box;
image {
width: 180rpx;
height: 180rpx;
min-width: 180rpx;
}
.goods-info {
width: 100%;
height: 180rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20rpx;
box-sizing: border-box;
.goods-name {
width: 100%;
line-height: 1.4;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-bottom {
display: flex;
justify-content: space-between;
align-items: flex-end;
text {
line-height: 1;
}
.goods-price {
display: flex;
align-items: flex-end;
padding-bottom: 10rpx;
font-weight: 500;
.goods-price-sign {
font-size: $font-size-activity-tag;
}
}
.goods-option {
width: 150rpx;
height: 50rpx;
line-height: 50rpx;
text-align: center;
border-radius: $border-radius;
color: #ffffff;
}
}
}
.disabled {
background: #e5e5e5;
}
}
}
</style>
<template>
<view class="message">
<view class="goods-item" v-if="goodsInfo && goodsInfo.goods_name">
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill"></image>
<view class="goods-info">
<view class="goods-name">{{ goodsInfo.sku_name ? goodsInfo.sku_name : goodsInfo.goods_name }}</view>
<view class="goods-bottom">
<view class="goods-price">
<text class="goods-price-sign color-base-text"></text>
<text class="color-base-text">{{ goodsInfo.price }}</text>
</view>
<view class="goods-option font-size-goods-tag disabled">已发送</view>
</view>
</view>
</view>
<view class="goods-item" v-else-if="goodsDetail">
<image :src="$util.img(goodsDetail.sku_image)" mode="aspectFill"></image>
<view class="goods-info">
<view class="goods-name">{{ goodsDetail.sku_name ? goodsDetail.sku_name : goodsDetail.goods_name }}</view>
<view class="goods-bottom">
<view class="goods-price">
<text class="goods-price-sign color-base-text"></text>
<text class="color-base-text">{{ goodsDetail.price }}</text>
</view>
<view class="goods-option font-size-goods-tag color-base-bg" @click="sendMsg('goods')">发送</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'ns-chat-goods',
props: {
skuId: {
type: [Number, String]
},
goodsDetail: {
type: [Object]
}
},
data() {
return {
goodsInfo: {}
};
},
mounted() {
this.getGoodsInfo();
},
methods: {
getGoodsInfo() {
this.$api.sendRequest({
url: '/api/goodssku/detail',
data: {
sku_id: this.skuId
},
success: res => {
if (res.code >= 0) {
this.goodsInfo = res.data.goods_sku_detail;
}
}
});
},
sendMsg() {
this.$emit('sendMsg', 'goods');
}
}
};
</script>
<style lang="scss">
.message {
padding: 13rpx 20rpx;
box-sizing: border-box;
width: 100vw;
position: relative;
.goods-item {
width: 100%;
height: 220rpx;
background: #ffffff;
position: relative;
display: flex;
align-items: center;
border-radius: 20rpx;
margin: 0 auto;
padding: $padding;
box-sizing: border-box;
image {
width: 180rpx;
height: 180rpx;
min-width: 180rpx;
}
.goods-info {
width: 100%;
height: 180rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20rpx;
box-sizing: border-box;
.goods-name {
width: 100%;
line-height: 1.4;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.goods-bottom {
display: flex;
justify-content: space-between;
align-items: flex-end;
text {
line-height: 1;
}
.goods-price {
display: flex;
align-items: flex-end;
padding-bottom: 10rpx;
font-weight: 500;
.goods-price-sign {
font-size: $font-size-activity-tag;
}
}
.goods-option {
width: 150rpx;
height: 50rpx;
line-height: 50rpx;
text-align: center;
border-radius: $border-radius;
color: #ffffff;
}
}
}
.disabled {
background: #e5e5e5;
}
}
}
</style>

View File

@@ -1,23 +1,29 @@
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar"><slot /></view>
</template>
<script>
var statusBarHeight = uni.getSystemInfoSync().statusBarHeight * 2 + 'rpx';
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: statusBarHeight
};
}
};
</script>
<style lang="scss" scoped>
.uni-status-bar {
width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar"><slot /></view>
</template>
<script>
var statusBarHeight = 0;
try {
statusBarHeight = uni.getWindowInfo().statusBarHeight * 2 + 'rpx';
} catch (e) {
// 兼容旧版本
statusBarHeight = uni.getSystemInfoSync().statusBarHeight * 2 + 'rpx';
}
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: statusBarHeight
};
}
};
</script>
<style lang="scss" scoped>
.uni-status-bar {
width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>

View File

@@ -1,148 +1,148 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<view class="page" v-if="detail">
<view class="form-banner">
<image :src="$util.img('public/uniapp/form/banner.png')" mode="widthFix"></image>
</view>
<view class="system-form-wrap">
<view class="form-title">请填写表单所需信息</view>
<ns-form :data="detail.json_data" ref="form"></ns-form>
<button type="primary" size="mini" class="button mini" @click="create()">提交</button>
</view>
</view>
<ns-empty :text="complete ? '提交成功' : '未获取到表单信息'" v-else></ns-empty>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
export default {
data() {
return {
id: 0,
detail: null,
isRepeat: false,
complete: false,
scroll:true
};
},
onLoad(data) {
// #ifdef MP-ALIPAY
let options = my.getLaunchOptionsSync();
options.query && Object.assign(data, options.query)
// #endif
this.id = data.id || 0;
if (data.scene) {
var sceneParams = decodeURIComponent(data.scene);
sceneParams = sceneParams.split('&');
if (sceneParams.length) {
sceneParams.forEach(item => {
if (item.indexOf('id') != -1) this.id = item.split('-')[1];
});
}
}
if (this.storeToken) {
this.getData();
} else {
this.$nextTick(() => {
this.$refs.login.open('/pages_tool/form/form?id=' + this.id)
})
}
},
watch: {
storeToken: function(nVal, oVal) {
if (nVal) this.getData();
}
},
methods: {
getData() {
this.$api.sendRequest({
url: '/form/api/form/info',
data: {
form_id: this.id
},
success: res => {
if (res.code == 0 && res.data) {
this.detail = res.data;
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
create() {
if (this.$refs.form.verify()) {
if (this.isRepeat) return;
this.isRepeat = true;
this.$api.sendRequest({
url: '/form/api/form/create',
data: {
form_id: this.id,
form_data: JSON.stringify(this.$refs.form.formData)
},
success: res => {
if (res.code == 0) {
this.$util.showToast({ title: '提交成功' })
setTimeout(() => {
this.complete = true;
this.detail = null;
}, 1500)
} else {
this.isRepeat = false;
this.$util.showToast({ title: res.message })
}
}
});
}
},
}
};
</script>
<style lang="scss">
.form-banner {
width: 100vw;
line-height: 1;
image {
width: 100%;
line-height: 1;
}
}
.system-form-wrap {
background: $color-bg;
border-radius: 32rpx;
overflow: hidden;
margin: 0 0 60rpx 0;
padding: 0 26rpx;
transform: translateY(-40rpx);
.form-title {
line-height: 100rpx;
padding-top: 20rpx;
}
.button {
height: 80rpx;
line-height: 80rpx !important;
margin-top: 30rpx !important;
width: 100%;
border-radius: 80rpx;
}
/deep/ .form-wrap {
background: #fff;
padding: 30rpx;
border-radius: 32rpx;
}
}
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<view class="page" v-if="detail">
<view class="form-banner">
<image :src="$util.img('public/uniapp/form/banner.png')" mode="widthFix"></image>
</view>
<view class="system-form-wrap">
<view class="form-title">请填写表单所需信息</view>
<ns-form :data="detail.json_data" ref="form"></ns-form>
<button type="primary" size="mini" class="button mini" @click="create()">提交</button>
</view>
</view>
<ns-empty :text="complete ? '提交成功' : '未获取到表单信息'" v-else></ns-empty>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
export default {
data() {
return {
id: 0,
detail: null,
isRepeat: false,
complete: false,
scroll:true
};
},
onLoad(data) {
// #ifdef MP-ALIPAY
let options = my.getLaunchOptionsSync();
options.query && Object.assign(data, options.query)
// #endif
this.id = data.id || 0;
if (data.scene) {
var sceneParams = decodeURIComponent(data.scene);
sceneParams = sceneParams.split('&');
if (sceneParams.length) {
sceneParams.forEach(item => {
if (item.indexOf('id') != -1) this.id = item.split('-')[1];
});
}
}
if (this.storeToken) {
this.getData();
} else {
this.$nextTick(() => {
this.$refs.login.open('/pages_tool/form/form?id=' + this.id)
})
}
},
watch: {
storeToken: function(nVal, oVal) {
if (nVal) this.getData();
}
},
methods: {
getData() {
this.$api.sendRequest({
url: '/form/api/form/info',
data: {
form_id: this.id
},
success: res => {
if (res.code == 0 && res.data) {
this.detail = res.data;
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
create() {
if (this.$refs.form.verify()) {
if (this.isRepeat) return;
this.isRepeat = true;
this.$api.sendRequest({
url: '/form/api/form/create',
data: {
form_id: this.id,
form_data: JSON.stringify(this.$refs.form.formData)
},
success: res => {
if (res.code == 0) {
this.$util.showToast({ title: '提交成功' })
setTimeout(() => {
this.complete = true;
this.detail = null;
}, 1500)
} else {
this.isRepeat = false;
this.$util.showToast({ title: res.message })
}
}
});
}
},
}
};
</script>
<style lang="scss">
.form-banner {
width: 100vw;
line-height: 1;
image {
width: 100%;
line-height: 1;
}
}
.system-form-wrap {
background: $color-bg;
border-radius: 32rpx;
overflow: hidden;
margin: 0 0 60rpx 0;
padding: 0 26rpx;
transform: translateY(-40rpx);
.form-title {
line-height: 100rpx;
padding-top: 20rpx;
}
.button {
height: 80rpx;
line-height: 80rpx !important;
margin-top: 30rpx !important;
width: 90%;
border-radius: 80rpx;
}
/deep/ .form-wrap {
background: #fff;
padding: 30rpx;
border-radius: 32rpx;
}
}
</style>

View File

@@ -1,125 +1,127 @@
<template>
<view :data-theme="themeStyle">
<mescroll-uni @getData="getBrandList" ref="mescroll" size="20">
<block slot="list">
<ns-adv keyword="NS_BRAND" class-name="adv-wrap"></ns-adv>
<view class="brand-content" v-if="brandList.length > 0">
<uni-grid :column="3" @change="change" :showBorder="!1">
<uni-grid-item v-for="(item, index) in brandList" :key="index" index="index">
<image class="brand-pic" :src="$util.img(item.image_url)" mode="widthFix"></image>
<view class="brand_name">{{ item.brand_name }}</view>
</uni-grid-item>
</uni-grid>
</view>
<view v-if="brandList.length == 0"><ns-empty text="暂无更多品牌,去首页看看吧"></ns-empty></view>
</block>
</mescroll-uni>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import uniGrid from '@/components/uni-grid/uni-grid.vue';
import uniGridItem from '@/components/uni-grid-item/uni-grid-item.vue';
import nsAdv from '@/components/ns-adv/ns-adv.vue';
export default {
components: {
uniGrid,
uniGridItem,
nsAdv
},
data() {
return {
brandList: [],
siteId: 0
};
},
onLoad(options) {
if (options.site_id) this.siteId = options.site_id;
},
onShow() {},
methods: {
change(e) {
this.$util.redirectTo('/pages/goods/list', {
brand_id: this.brandList[e.detail.index].brand_id
});
},
getBrandList(mescroll) {
this.$api.sendRequest({
url: '/api/goodsbrand/page',
data: {
page_size: mescroll.size,
page: mescroll.num,
site_id: this.siteId
},
success: res => {
let newArr = [];
let msg = res.message;
if (res.code == 0 && res.data) {
newArr = res.data.list;
} else {
this.$util.showToast({
title: msg
});
}
mescroll.endSuccess(newArr.length);
//设置列表数据
if (mescroll.num == 1) this.brandList = []; //如果是第一页需手动制空列表
this.brandList = this.brandList.concat(newArr); //追加新数据
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail() {
mescroll.endErr();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
}
},
onShareAppMessage(res) {
var title = '你想要的大牌都在这里';
var path = '/pages_tool/goods/brand';
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
}
};
</script>
<style lang="scss">
/deep/ .uni-grid-item {
width: calc((100vw - (#{$margin-both} * 2)) / 3) !important;
}
.adv-wrap {
margin: $margin-updown $margin-both;
width: auto;
}
.brand-content {
padding: $padding 0;
box-sizing: border-box;
background: #ffffff;
margin: $margin-updown $margin-both 0;
.brand-pic {
width: 60%;
height: 50%;
}
.brand_name {
width: 70%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
}
}
<template>
<view :data-theme="themeStyle">
<mescroll-uni @getData="getBrandList" ref="mescroll" size="20">
<block slot="list">
<ns-adv keyword="NS_BRAND" class-name="adv-wrap"></ns-adv>
<view class="brand-content" v-if="brandList.length > 0">
<uni-grid :column="3" @change="change" :showBorder="!1">
<uni-grid-item v-for="(item, index) in brandList" :key="index" index="index">
<image class="brand-pic" :src="$util.img(item.image_url)" mode="widthFix"></image>
<view class="brand_name">{{ item.brand_name }}</view>
</uni-grid-item>
</uni-grid>
</view>
<view v-if="brandList.length == 0"><ns-empty text="暂无更多品牌,去首页看看吧"></ns-empty></view>
</block>
</mescroll-uni>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import uniGrid from '@/components/uni-grid/uni-grid.vue';
import uniGridItem from '@/components/uni-grid-item/uni-grid-item.vue';
import nsAdv from '@/components/ns-adv/ns-adv.vue';
export default {
components: {
uniGrid,
uniGridItem,
nsAdv
},
data() {
return {
brandList: [],
siteId: 0
};
},
onLoad(options) {
if (options.site_id) this.siteId = options.site_id;
},
onShow() {},
methods: {
change(e) {
this.$util.redirectTo('/pages/goods/list', {
brand_id: this.brandList[e.detail.index].brand_id
});
},
getBrandList(mescroll) {
this.$api.sendRequest({
url: '/api/goodsbrand/page',
data: {
page_size: mescroll.size,
page: mescroll.num,
site_id: this.siteId
},
success: res => {
let newArr = [];
let msg = res.message;
if (res.code == 0 && res.data) {
newArr = res.data.list;
} else {
this.$util.showToast({
title: msg
});
}
mescroll.endSuccess(newArr.length);
//设置列表数据
if (mescroll.num == 1) this.brandList = []; //如果是第一页需手动制空列表
this.brandList = this.brandList.concat(newArr); //追加新数据
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail() {
mescroll.endErr();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
}
},
onShareAppMessage(res) {
var title = '你想要的大牌都在这里';
var path = '/pages_tool/goods/brand';
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
}
};
</script>
<style lang="scss">
/deep/ .uni-grid-item {
width: calc((100vw - (#{$margin-both} * 2)) / 3) !important;
}
.adv-wrap {
margin: $margin-updown $margin-both;
width: auto;
}
.brand-content {
padding: $padding 0;
box-sizing: border-box;
background: #ffffff;
margin: $margin-updown $margin-both 0;
.brand-pic {
width: 60%;
height: 50%;
}
.brand_name {
width: 70%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
}
}
</style>

View File

@@ -6,7 +6,7 @@
<view @click="changeSort(1)"><text :class="sort == 1 ? 'color-base-text active color-base-border-bottom' : ''">全部</text></view>
<view @click="changeSort(2, 'reward')"><text :class="sort == 2 ? 'color-base-text active color-base-border-bottom' : ''">满减券</text></view>
<view @click="changeSort(3, 'discount')"><text :class="sort == 3 ? 'color-base-text active color-base-border-bottom' : ''">折扣券</text></view>
<!-- <view @click="changeSort(4, 'no_threshold')"><text :class="sort == 4 ? 'color-base-text active color-base-border-bottom' : ''">无门槛券</text></view> -->
<view @click="changeSort(4, 'no_threshold')"><text :class="sort == 4 ? 'color-base-text active color-base-border-bottom' : ''">无门槛券</text></view>
</view>
</view>
@@ -32,28 +32,31 @@
<view class="item-info">
<view class="use_title">
<view class="title">{{ item.coupon_name }}</view>
<view class="max_price" v-if="item.goods_type == 2 || item.goods_type == 3" :class="{ disabled: item.useState == 2 }">指定商品</view>
<view class="max_price" v-else :class="{ disabled: item.useState == 2 }">全场商品</view>
<view class="max_price" :class="{ disabled: item.useState == 2 }">{{item.goods_type_name}}</view>
<view class="max_price" v-if="item.discount_limit != '0.00'">
(最大优惠{{ item.discount_limit }})
</view>
<view class="max_price" :class="{ disabled: item.useState == 2 }">{{ item.use_channel_name }}</view>
<!-- <view class="max_price truncate" v-if="item.use_channel!='online'" :class="{ disabled: item.useState == 2 }">
<view class="max_price truncate" v-if="item.use_channel!='online'" :class="{ disabled: item.useState == 2 }">
{{ item.use_store==='all'?'适用门店全部门店': '适用门店'+item.use_store_name}}
</view> -->
</view>
</view>
<view class="use_time" v-if="item.validity_type == 0">
有效期{{ $util.timeStampTurnTime(item.end_time) }}</view>
<view class="use_time" v-else-if="item.validity_type == 1">
有效期领取之日起{{ item.fixed_term }}日内有效</view>
<view class="use_time" v-if="item.validity_type == 0">有效期{{ $util.timeStampTurnTime(item.end_time) }}</view>
<view class="use_time" v-else-if="item.validity_type == 1">有效期领取之日起{{ item.fixed_term }}日内有效</view>
<view class="use_time" v-else>有效期长期有效</view>
</view>
<view class="item-btn">
<view v-if="item.useState == 0" @click.stop="receiveCoupon(item, index)">领取</view>
<view v-if="item.useState == 0" @click.stop="receiveCoupon(item, index)">领取</view>
<view class="to-use" v-if="item.useState == 1" @click.stop="toGoodsList(item, index)">去使用</view>
<view v-if="item.useState == 2" class="disabled">已抢光</view>
<view v-if="item.useState == 3" class="disabled">已失效</view>
<view v-if="item.useState == 4" class="disabled">已使用</view>
<!-- <view v-if="item.useState == 0" @click.stop="receiveCoupon(item, index)">领取</view>
<view v-if="item.useState == 1" @click.stop="toGoodsList(item, index)">去使用</view>
<view v-if="item.receivedType == 'out'" class="disabled">已抢光</view>
<view v-if="item.receivedType == 'expire'" class="disabled">过期</view>
<view v-if="item.receivedType == 'limit'" class="disabled">达上限</view>
<view v-if="!item.received_type && item.useState == 2" class="disabled">已抢光</view>
<view v-if="item.received_type == 'out'" class="disabled">抢光</view>
<view v-if="item.received_type == 'expire'" class="disabled">过期</view>
<view v-if="item.received_type == 'limit'" class="disabled">已达上限</view> -->
</view>
</view>
</view>
@@ -62,6 +65,8 @@
</mescroll-uni>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
@@ -142,11 +147,12 @@
this.$refs.mescroll.refresh(false);
},
liClick(item, index) {
if(['limit', 'expire', 'out'].includes(item.receivedType)) return false;
// if(['limit', 'expire', 'out'].includes(item.received_type)) return false;
if(item.useState == 2) return false;
if (item.useState == 0) this.receiveCoupon(item, index);
else if(item.useState == 3 || item.useState == 4) this.$util.redirectTo('/pages_tool/member/coupon',{state: item.useState == 4 ? 2 : item.useState})
else this.toGoodsList(item, index);
},
//领取优惠券
receiveCoupon(item, index) {
if (this.couponBtnSwitch) return;
@@ -173,7 +179,7 @@
} else {
for (let i = 0; i < list.length; i++) {
if (list[i].coupon_type_id == item.coupon_type_id) {
list[i].receivedType = res.data.type;
list[i].received_type = res.data.type;
list[i].useState = 2;
}
}
@@ -214,9 +220,20 @@
mescroll.endSuccess(newArr.length);
if (newArr.length) {
newArr.forEach(v => {
// if (v.count == v.lead_count) v.useState = 2;
// else if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v.max_fetch) v.useState = 1;
// else v.useState = 0;
// if(v.received_type && v.received_type == 'expire'){
// v.useState = 2;
// }
if (v.count == v.lead_count) v.useState = 2;
else if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v.max_fetch) v.useState = 1;
else v.useState = 0;
else if (v.max_fetch == 0 || (v.max_fetch != 0 && !v.member_coupon_num) || (v.max_fetch != 0 && v.member_coupon_num && v.max_fetch > v.member_coupon_num)) v.useState = 0;
else if (v.wait_coupon_num) v.useState = 1
else if (v.lose_coupon_num) v.useState = 3;
else if (v.use_coupon_num) v.useState = 4;
});
}
//设置列表数据
@@ -367,6 +384,12 @@
background: #dedede !important;
color: #909399 !important;
}
&.to-use{
border: 2rpx solid var(--bg-color);
background: transparent;
color: var(--bg-color);
}
}
&::after {

View File

@@ -30,6 +30,8 @@
</view>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->

View File

@@ -4,7 +4,7 @@
<view class="content">
<view class="cate-search">
<view class="search-box">
<input class="uni-input" maxlength="50" v-model="inputValue" confirm-type="search" @focus="inputFocus" focus @confirm="search()" :placeholder="searchWords ? searchWords : ''" />
<input class="uni-input" maxlength="50" v-model="inputValue" confirm-type="search" @focus="inputFocus" focus @confirm="search()" :placeholder="searchWords ? searchWords : $lang('inputPlaceholder')" />
<text class="iconfont icon-sousuo3" @click="search()"></text>
</view>
</view>
@@ -13,7 +13,7 @@
<view class="history" v-if="historyList.length">
<view class="history-box">
<view class="history-top">
<view class="title">历史搜索</view>
<view class="title">{{ $lang('history') }}</view>
<view class="icon iconfont icon-icon7" @click="deleteHistoryList"></view>
</view>
<view class="history-bottom " id="history-list" :style="{ maxHeight: !isAllHistory ? '100%' : '168rpx' }">
@@ -31,7 +31,7 @@
<view class="history" v-if="hotList.length">
<view class="history-box">
<view class="history-top">
<view class="title">热门搜索</view>
<view class="title">{{ $lang('hot') }}</view>
</view>
<view class="history-bottom">
<view class="history-li" v-for="(item, index) in hotList" :key="index" @click="otherSearch(item)" @longtap="deleteItem(item)">
@@ -137,7 +137,6 @@
},
//搜索
search() {
if (this.inputValue.trim() != '') {
// 对历史搜索处理,判断有无,最近搜索显示在最前
@@ -163,7 +162,7 @@
});
} else {
this.$util.redirectTo('/pages/goods/list', {
//keyword: this.searchWords
keyword: this.searchWords
});
}
}
@@ -171,12 +170,11 @@
// 获取元素高度
getHistoryHeight() {
const query = uni.createSelectorQuery().in(this);
query.select('#history-list')
.boundingClientRect(data => {
if (data && data.height > uni.upx2px(70) * 2 + uni.upx2px(35) * 2) {
this.isAllHistory = true;
}
}).exec();
query.select('#history-list').boundingClientRect(data => {
if (data && data.height > uni.upx2px(70) * 2 + uni.upx2px(35) * 2) {
this.isAllHistory = true;
}
}).exec();
}
}
};

View File

@@ -1,141 +1,147 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="page">
<view class="help-title">{{ detail.title }}</view>
<view class="help-content"><rich-text :nodes="content"></rich-text></view>
<view class="help-meta">
<text class="help-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import htmlParser from '@/common/js/html-parser';
export default {
data() {
return {
id: 0,
detail: {},
content: ''
};
},
onLoad(options) {
this.id = options.id || 0;
// 小程序扫码进入
if (options.scene) {
var sceneParams = decodeURIComponent(options.scene);
this.id = sceneParams.split('-')[1];
}
if (this.id == 0) {
this.$util.redirectTo('/pages_tool/help/list', {}, 'redirectTo');
}
},
onShow() {
this.getData();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/api/help/info',
data: {
id: this.id
},
success: res => {
if (res.code == 0) {
if (res.data) {
this.detail = res.data;
this.$langConfig.title(this.detail.title);
this.content = htmlParser(res.data.content);
this.setPublicShare();
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/help/list', {}, 'redirectTo');
}, 2000);
}
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/help/list', {}, 'redirectTo');
}, 2000);
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
// 设置公众号分享
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_tool/help/detail?id=' + this.id;
this.$util.setPublicShare({
title: this.detail.title,
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},
onShareAppMessage(res) {
var title = this.detail.title;
var path = '/pages_tool/help/detail?id=' + this.id;
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
},
//分享到朋友圈
onShareTimeline() {
var title = this.detail.title;
var query = 'id=' + this.id;
return {
title: title,
query: query,
imageUrl: ''
};
}
};
</script>
<style lang="scss">
.page {
width: 100%;
height: 100%;
padding: 30rpx;
box-sizing: border-box;
background: #ffffff;
}
.help-title {
font-size: $font-size-toolbar;
text-align: center;
}
.help-content {
margin-top: $margin-updown;
word-break: break-all;
}
.help-meta {
text-align: right;
margin-top: $margin-updown;
color: $color-tip;
.help-time {
font-size: $font-size-tag;
}
}
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="page">
<view class="help-title">{{ detail.title }}</view>
<view class="help-content">
<!-- <rich-text :nodes="content"></rich-text> -->
<ns-mp-html :content="content"></ns-mp-html>
</view>
<view class="help-meta">
<text class="help-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text>
</view>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import htmlParser from '@/common/js/html-parser';
export default {
data() {
return {
id: 0,
detail: {},
content: ''
};
},
onLoad(options) {
this.id = options.id || 0;
// 小程序扫码进入
if (options.scene) {
var sceneParams = decodeURIComponent(options.scene);
this.id = sceneParams.split('-')[1];
}
if (this.id == 0) {
this.$util.redirectTo('/pages_tool/help/list', {}, 'redirectTo');
}
},
onShow() {
this.getData();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/api/help/info',
data: {
id: this.id
},
success: res => {
if (res.code == 0) {
if (res.data) {
this.detail = res.data;
this.$langConfig.title(this.detail.title);
// this.content = htmlParser(res.data.content);
this.content = res.data.content;
this.setPublicShare();
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/help/list', {}, 'redirectTo');
}, 2000);
}
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/help/list', {}, 'redirectTo');
}, 2000);
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
// 设置公众号分享
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_tool/help/detail?id=' + this.id;
this.$util.setPublicShare({
title: this.detail.title,
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},
onShareAppMessage(res) {
var title = this.detail.title;
var path = '/pages_tool/help/detail?id=' + this.id;
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
},
//分享到朋友圈
onShareTimeline() {
var title = this.detail.title;
var query = 'id=' + this.id;
return {
title: title,
query: query,
imageUrl: ''
};
}
};
</script>
<style lang="scss">
.page {
width: 100%;
height: 100%;
padding: 30rpx;
box-sizing: border-box;
background: #ffffff;
}
.help-title {
font-size: $font-size-toolbar;
text-align: center;
}
.help-content {
margin-top: $margin-updown;
word-break: break-all;
}
.help-meta {
text-align: right;
margin-top: $margin-updown;
color: $color-tip;
.help-time {
font-size: $font-size-tag;
}
}
</style>

View File

@@ -1,135 +1,136 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="help">
<block v-if="dataList.length">
<view class="help-item" v-for="(item, index) in dataList" :key="index">
<view :class="['item-title', item.child_list.length == 0 ? 'empty' : '']">{{ item.class_name }}</view>
<view class="item-content" v-for="(s_item, s_index) in item.child_list" :key="s_index" @click="helpDetail(s_item)">{{ s_item.title }}</view>
</view>
</block>
<block v-else><ns-empty text="暂无帮助信息" :isIndex="false"></ns-empty></block>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
export default {
data() {
return {
dataList: []
};
},
onLoad() {},
onShow() {
this.setPublicShare();
this.getData();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/api/helpclass/lists',
data: {},
success: res => {
if (res.code == 0 && res.data) {
this.dataList = res.data;
} else {
this.$util.showToast({
title: res.message
});
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
helpDetail(e) {
// #ifndef MP-WEIXIN
if (e.link_address) {
uni.redirectTo({
url: '/pages_tool/webview/webview?src=' + encodeURIComponent(e.link_address)
});
} else {
this.$util.redirectTo('/pages_tool/help/detail', {
id: e.id
});
}
// #endif
// #ifdef MP-WEIXIN
this.$util.redirectTo('/pages_tool/help/detail', {
id: e.id
});
// #endif
},
// 设置公众号分享
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_tool/help/list';
this.$util.setPublicShare({
title: '帮助中心',
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},
onShareAppMessage(res) {
var title = '帮助中心使你更加方便';
var path = '/pages_tool/help/list';
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
}
};
</script>
<style lang="scss" scoped>
.help {
height: 100%;
box-sizing: border-box;
padding-top: 20rpx;
.help-item {
width: calc(100% - 60rpx);
margin: 0 auto;
padding: 32rpx 35rpx;
box-sizing: border-box;
background-color: #fff;
margin-bottom: 18rpx;
border-radius: 10rpx;
.item-title {
padding-bottom: 15rpx;
font-size: 30rpx;
color: #000;
border-bottom: 2rpx solid #f1f1f1;
&.empty {
padding-bottom: 0;
border-bottom: none;
}
}
.item-content {
padding: 24rpx 0;
border-bottom: 2rpx solid #f1f1f1;
font-size: $font-size-base;
color: $color-sub;
&:last-child {
border-bottom: none;
padding-bottom: 0;
}
}
}
}
</style>
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="help">
<block v-if="dataList.length">
<view class="help-item" v-for="(item, index) in dataList" :key="index">
<view :class="['item-title', item.child_list.length == 0 ? 'empty' : '']">{{ item.class_name }}</view>
<view class="item-content" v-for="(s_item, s_index) in item.child_list" :key="s_index" @click="helpDetail(s_item)">{{ s_item.title }}</view>
</view>
</block>
<block v-else><ns-empty text="暂无帮助信息" :isIndex="false"></ns-empty></block>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
export default {
data() {
return {
dataList: []
};
},
onLoad() {},
onShow() {
this.setPublicShare();
this.getData();
},
methods: {
getData() {
this.$api.sendRequest({
url: '/api/helpclass/lists',
data: {},
success: res => {
if (res.code == 0 && res.data) {
this.dataList = res.data;
} else {
this.$util.showToast({
title: res.message
});
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
helpDetail(e) {
// #ifndef MP-WEIXIN
if (e.link_address) {
uni.redirectTo({
url: '/pages_tool/webview/webview?src=' + encodeURIComponent(e.link_address)
});
} else {
this.$util.redirectTo('/pages_tool/help/detail', {
id: e.id
});
}
// #endif
// #ifdef MP-WEIXIN
this.$util.redirectTo('/pages_tool/help/detail', {
id: e.id
});
// #endif
},
// 设置公众号分享
setPublicShare() {
let shareUrl = this.$config.h5Domain + '/pages_tool/help/list';
this.$util.setPublicShare({
title: '帮助中心',
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},
onShareAppMessage(res) {
var title = '帮助中心使你更加方便';
var path = '/pages_tool/help/list';
return {
title: title,
path: path,
success: res => {},
fail: res => {}
};
}
};
</script>
<style lang="scss" scoped>
.help {
height: 100%;
box-sizing: border-box;
padding-top: 20rpx;
.help-item {
width: calc(100% - 60rpx);
margin: 0 auto;
padding: 32rpx 35rpx;
box-sizing: border-box;
background-color: #fff;
margin-bottom: 18rpx;
border-radius: 10rpx;
.item-title {
padding-bottom: 15rpx;
font-size: 30rpx;
color: #000;
border-bottom: 2rpx solid #f1f1f1;
&.empty {
padding-bottom: 0;
border-bottom: none;
}
}
.item-content {
padding: 24rpx 0;
border-bottom: 2rpx solid #f1f1f1;
font-size: $font-size-base;
color: $color-sub;
&:last-child {
border-bottom: none;
padding-bottom: 0;
}
}
}
}
</style>

View File

@@ -0,0 +1,46 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<view class="aggrement-info" v-if="aggrement && aggrement.content">
<ns-mp-html :content="aggrement.content"></ns-mp-html>
</view>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
export default {
data() {
return {
aggrement: null,
type: 'SERVICE'
}
},
onLoad(option) {
this.type = option.type || ''
this.getaggrementInfo();
},
methods: {
getaggrementInfo() {
this.$api.sendRequest({
url: '/api/register/aggrement',
data: {
type: this.type
},
success: res => {
if (res.code >= 0) {
this.aggrement = res.data;
}
if(this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
}
},
}
</script>
<style lang="scss" scoped>
.aggrement-info{
padding: 20rpx;
}
</style>

View File

@@ -1,439 +1,439 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="find">
<view class="iconfont icon-close" @click="navigateBack()"></view>
<view class="header-wrap">
<block v-if="stepShow == 0">
<view class="title">请输入手机号</view>
<view><text class="color-tip">请确认您的账号已绑定此手机号</text></view>
</block>
<block v-if="stepShow == 1">
<view class="title">请输入验证码</view>
<view>
<text class="color-tip">已将验证码发送至手机号{{ formData.mobile }}</text>
</view>
</block>
<block v-if="stepShow == 2">
<view class="title">请设置新的密码</view>
<view><text class="color-tip">建议您的新密码以简单好记为标准</text></view>
</block>
</view>
<view class="find-form">
<!-- 输入手机号和验证码 -->
<block v-if="stepShow == 0">
<view class="form-input">
<input
class="uni-input"
placeholder-class="placeholder-class"
type="text"
maxlength="17"
v-model="formData.mobile"
:placeholder="$lang('accountPlaceholder')"
/>
</view>
<view class="form-input align-type">
<input
class="uni-input info-content"
placeholder-class="placeholder-class"
type="number"
maxlength="4"
:placeholder="$lang('captchaPlaceholder')"
v-model="formData.captcha"
/>
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image>
</view>
<button type="primary" class="find-btn" @click="nextStep()">{{ $lang('next') }}</button>
</block>
<!-- 输入动态码 -->
<block v-if="stepShow == 1">
<myp-one :maxlength="4" @input="input" ref="input" :auto-focus="true"></myp-one>
<button type="primary" class="find-btn" :disabled="isSend" @click="sendDynaCode">{{ codeText }}</button>
</block>
<!-- 输入新密码 -->
<block v-if="stepShow == 2">
<view class="form-input">
<input
class="uni-input"
placeholder-class="placeholder-class"
type="text"
maxlength="30"
password="true"
:placeholder="$lang('passwordPlaceholder')"
v-model="formData.password"
/>
</view>
<view class="form-input">
<input
class="uni-input"
placeholder-class="placeholder-class"
type="text"
maxlength="30"
password="true"
:placeholder="$lang('rePasswordPlaceholder')"
v-model="formData.rePassword"
/>
</view>
<button type="primary" class="find-btn" @click="save">{{ $lang('save') }}</button>
</block>
</view>
</view>
</template>
<script>
import validate from 'common/js/validate.js';
import mypOne from '@/pages_tool/components/myp-one/myp-one.vue';
export default {
components: {
mypOne
},
data() {
return {
findMode: 'mobile',
codeText: '重新获取',
seconds: 120,
timer: null,
formData: {
mobile: '',
password: '',
rePassword: '',
dynacode: '',
captcha: ''
},
stepShow: 0,
isSend: false,
captcha: {
id: '',
img: ''
},
registerConfig: {}
};
},
onLoad() {
this.getCaptcha();
},
onShow() {
this.getRegisterConfig();
},
methods: {
input(val) {
if (val.length == 4) {
this.formData.dynacode = val;
this.stepShow += 1;
}
},
// 导航跳转
navigateBack() {
if (this.stepShow > 0) {
this.stepShow -= 1;
} else {
this.$util.redirectTo('/pages_tool/login/login', '', 'redirectTo');
}
},
// 下一步
async nextStep() {
let step0Rule = [
{
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
},
{
name: 'captcha',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
}
], //手机验证
step0CheckRes;
step0CheckRes = validate.check(this.formData, step0Rule);
if (step0CheckRes) {
this.findMode = 'mobile';
let res = await this.$api.sendRequest({
url: '/api/member/checkmobile',
data: {
mobile: this.formData.mobile
},
async: false
});
if (res.code == 0) {
this.$util.showToast({
title: '该手机号未注册'
});
return false;
}
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
this.sendDynaCode();
},
// 注册表单验证
vertify() {
let regConfig = this.registerConfig;
let rule = [
{
name: 'password',
checkType: 'required',
errorMsg: '请输入密码'
}
];
if (regConfig.pwd_len > 0) {
rule.push({
name: 'password',
checkType: 'lengthMin',
checkRule: regConfig.pwd_len,
errorMsg: '密码长度不能小于' + regConfig.pwd_len + '位'
});
}
if (regConfig.pwd_complexity != '') {
let passwordErrorMsg = '密码需包含',
reg = '';
if (regConfig.pwd_complexity.indexOf('number') != -1) {
reg += '(?=.*?[0-9])';
passwordErrorMsg += '数字';
}
if (regConfig.pwd_complexity.indexOf('letter') != -1) {
reg += '(?=.*?[a-z])';
passwordErrorMsg += '、小写字母';
}
if (regConfig.pwd_complexity.indexOf('upper_case') != -1) {
reg += '(?=.*?[A-Z])';
passwordErrorMsg += '、大写字母';
}
if (regConfig.pwd_complexity.indexOf('symbol') != -1) {
reg += '(?=.*?[#?!@$%^&*-])';
passwordErrorMsg += '、特殊字符';
}
rule.push({
name: 'password',
checkType: 'reg',
checkRule: reg,
errorMsg: passwordErrorMsg
});
}
var checkRes = validate.check(this.formData, rule);
if (checkRes) {
if (this.formData.password != this.formData.rePassword) {
this.$util.showToast({
title: '两次密码不一致'
});
return false;
}
return true;
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
},
// 获取验证码
getCaptcha() {
this.$api.sendRequest({
url: '/api/captcha/captcha',
data: {
captcha_id: this.captcha.id
},
success: res => {
if (res.code >= 0) {
this.captcha = res.data;
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
}
}
});
},
// 发送动态验证码
async sendDynaCode() {
if (this.formData.captcha.length == 0) {
this.$util.showToast({
title: this.$lang('captchaPlaceholder')
});
return;
}
if (this.isSend) return;
this.isSend = true;
var url,
data = {
captcha_id: this.captcha.id,
captcha_code: this.formData.captcha
};
data[this.findMode] = this.formData.mobile;
url = '/api/findpassword/mobilecode';
this.$api.sendRequest({
url: url,
data: data,
success: res => {
let data = res.data;
if (data.key) {
if (this.seconds == 120 && this.timer == null) {
this.timer = setInterval(() => {
this.seconds--;
this.codeText = '重新获取(' + this.seconds + 's)';
}, 1000);
}
uni.setStorageSync('forgot_password_token', data.key);
this.stepShow += 1;
} else {
this.$util.showToast({
title: res.message
});
this.isSend = false;
this.getCaptcha();
}
},
fail: res => {
this.isSend = false;
this.getCaptcha();
}
});
},
save() {
if (this.vertify()) {
var url,
data = {
code: this.formData.dynacode,
key: uni.getStorageSync('forgot_password_token'),
password: this.formData.password
};
data[this.findMode] = this.formData.mobile;
url = '/api/findpassword/mobile';
this.$api.sendRequest({
url: url,
data: data,
success: res => {
this.$util.showToast({
title: res.message
});
if (res.code == 0) {
setTimeout(() => {
uni.removeStorage({
key: 'forgot_password_token'
});
this.$util.redirectTo('/pages_tool/login/login', {}, 'redirectTo');
}, 1000);
} else {
this.stepShow -= 1;
}
}
});
}
},
/**
* 获取注册配置
*/
getRegisterConfig() {
this.$api.sendRequest({
url: '/api/register/config',
success: res => {
if (res.code >= 0) {
this.registerConfig = res.data.value;
}
}
});
}
},
watch: {
seconds(value) {
if (value == 0) {
this.seconds = 120;
this.codeText = '重新获取';
this.isSend = false;
clearInterval(this.timer);
}
}
}
};
</script>
<style lang="scss">
page {
background: #ffffff !important;
overflow: hidden;
}
.captcha {
width: 170rpx;
height: 50rpx;
}
.find-form {
padding: 100rpx 80rpx 0;
.form-input {
margin-top: 60rpx;
height: 60rpx;
border-bottom: 2rpx solid $color-line;
input {
padding: 0;
font-size: $font-size-base;
}
}
.find-btn {
margin: 374rpx 0 0;
border-radius: $border-radius;
color: #fff;
&[disabled] {
background-color: #f7f7f7 !important;
}
}
}
.forget-section {
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
margin-top: 10rpx;
height: 70rpx;
line-height: 70rpx;
}
.align-type {
display: flex;
justify-content: space-between;
}
.header-wrap {
width: 80%;
height: 100%;
margin: calc(120rpx + 88rpx) auto 0;
background-repeat: no-repeat;
background-size: contain;
background-position: bottom;
position: relative;
.title {
font-size: 50rpx;
font-weight: bold;
}
}
.icon-close {
font-size: 52rpx;
position: fixed;
left: 24rpx;
top: 72rpx;
z-index: 9;
color: #000;
}
.placeholder-class {
color: #bfbfbf;
}
</style>
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="find">
<view class="iconfont icon-close" @click="navigateBack()"></view>
<view class="header-wrap">
<block v-if="stepShow == 0">
<view class="title">请输入手机号</view>
<view><text class="color-tip">请确认您的账号已绑定此手机号</text></view>
</block>
<block v-if="stepShow == 1">
<view class="title">请输入验证码</view>
<view>
<text class="color-tip">已将验证码发送至手机号{{ formData.mobile }}</text>
</view>
</block>
<block v-if="stepShow == 2">
<view class="title">请设置新的密码</view>
<view><text class="color-tip">建议您的新密码以简单好记为标准</text></view>
</block>
</view>
<view class="find-form">
<!-- 输入手机号和验证码 -->
<block v-if="stepShow == 0">
<view class="form-input">
<input
class="uni-input"
placeholder-class="placeholder-class"
type="text"
maxlength="17"
v-model="formData.mobile"
:placeholder="$lang('accountPlaceholder')"
/>
</view>
<view class="form-input align-type">
<input
class="uni-input info-content"
placeholder-class="placeholder-class"
type="number"
maxlength="4"
:placeholder="$lang('captchaPlaceholder')"
v-model="formData.captcha"
/>
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image>
</view>
<button type="primary" class="find-btn" @click="nextStep()">{{ $lang('next') }}</button>
</block>
<!-- 输入动态码 -->
<block v-if="stepShow == 1">
<myp-one :maxlength="4" @input="input" ref="input" :auto-focus="true"></myp-one>
<button type="primary" class="find-btn" :disabled="isSend" @click="sendDynaCode">{{ codeText }}</button>
</block>
<!-- 输入新密码 -->
<block v-if="stepShow == 2">
<view class="form-input">
<input
class="uni-input"
placeholder-class="placeholder-class"
type="text"
maxlength="30"
password="true"
:placeholder="$lang('passwordPlaceholder')"
v-model="formData.password"
/>
</view>
<view class="form-input">
<input
class="uni-input"
placeholder-class="placeholder-class"
type="text"
maxlength="30"
password="true"
:placeholder="$lang('rePasswordPlaceholder')"
v-model="formData.rePassword"
/>
</view>
<button type="primary" class="find-btn" @click="save">{{ $lang('save') }}</button>
</block>
</view>
</view>
</template>
<script>
import validate from 'common/js/validate.js';
import mypOne from '@/pages_tool/components/myp-one/myp-one.vue';
export default {
components: {
mypOne
},
data() {
return {
findMode: 'mobile',
codeText: '重新获取',
seconds: 120,
timer: null,
formData: {
mobile: '',
password: '',
rePassword: '',
dynacode: '',
captcha: ''
},
stepShow: 0,
isSend: false,
captcha: {
id: '',
img: ''
},
registerConfig: {}
};
},
onLoad() {
this.getCaptcha();
},
onShow() {
this.getRegisterConfig();
},
methods: {
input(val) {
if (val.length == 4) {
this.formData.dynacode = val;
this.stepShow += 1;
}
},
// 导航跳转
navigateBack() {
if (this.stepShow > 0) {
this.stepShow -= 1;
} else {
this.$util.redirectTo('/pages_tool/login/login', '', 'redirectTo');
}
},
// 下一步
async nextStep() {
let step0Rule = [
{
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
},
{
name: 'captcha',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
}
], //手机验证
step0CheckRes;
step0CheckRes = validate.check(this.formData, step0Rule);
if (step0CheckRes) {
this.findMode = 'mobile';
let res = await this.$api.sendRequest({
url: '/api/member/checkmobile',
data: {
mobile: this.formData.mobile
},
async: false
});
if (res.code == 0) {
this.$util.showToast({
title: '该手机号未注册'
});
return false;
}
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
this.sendDynaCode();
},
// 注册表单验证
vertify() {
let regConfig = this.registerConfig;
let rule = [
{
name: 'password',
checkType: 'required',
errorMsg: '请输入密码'
}
];
if (regConfig.pwd_len > 0) {
rule.push({
name: 'password',
checkType: 'lengthMin',
checkRule: regConfig.pwd_len,
errorMsg: '密码长度不能小于' + regConfig.pwd_len + '位'
});
}
if (regConfig.pwd_complexity != '') {
let passwordErrorMsg = '密码需包含',
reg = '';
if (regConfig.pwd_complexity.indexOf('number') != -1) {
reg += '(?=.*?[0-9])';
passwordErrorMsg += '数字';
}
if (regConfig.pwd_complexity.indexOf('letter') != -1) {
reg += '(?=.*?[a-z])';
passwordErrorMsg += '、小写字母';
}
if (regConfig.pwd_complexity.indexOf('upper_case') != -1) {
reg += '(?=.*?[A-Z])';
passwordErrorMsg += '、大写字母';
}
if (regConfig.pwd_complexity.indexOf('symbol') != -1) {
reg += '(?=.*?[#?!@$%^&*-])';
passwordErrorMsg += '、特殊字符';
}
rule.push({
name: 'password',
checkType: 'reg',
checkRule: reg,
errorMsg: passwordErrorMsg
});
}
var checkRes = validate.check(this.formData, rule);
if (checkRes) {
if (this.formData.password != this.formData.rePassword) {
this.$util.showToast({
title: '两次密码不一致'
});
return false;
}
return true;
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
},
// 获取验证码
getCaptcha() {
this.$api.sendRequest({
url: '/api/captcha/captcha',
data: {
captcha_id: this.captcha.id
},
success: res => {
if (res.code >= 0) {
this.captcha = res.data;
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
}
}
});
},
// 发送动态验证码
async sendDynaCode() {
if (this.formData.captcha.length == 0) {
this.$util.showToast({
title: this.$lang('captchaPlaceholder')
});
return;
}
if (this.isSend) return;
this.isSend = true;
var url,
data = {
captcha_id: this.captcha.id,
captcha_code: this.formData.captcha
};
data[this.findMode] = this.formData.mobile;
url = '/api/findpassword/mobilecode';
this.$api.sendRequest({
url: url,
data: data,
success: res => {
let data = res.data;
if (data.key) {
if (this.seconds == 120 && this.timer == null) {
this.timer = setInterval(() => {
this.seconds--;
this.codeText = '重新获取(' + this.seconds + 's)';
}, 1000);
}
uni.setStorageSync('forgot_password_token', data.key);
this.stepShow += 1;
} else {
this.$util.showToast({
title: res.message
});
this.isSend = false;
this.getCaptcha();
}
},
fail: res => {
this.isSend = false;
this.getCaptcha();
}
});
},
save() {
if (this.vertify()) {
var url,
data = {
code: this.formData.dynacode,
key: uni.getStorageSync('forgot_password_token'),
password: this.formData.password
};
data[this.findMode] = this.formData.mobile;
url = '/api/findpassword/mobile';
this.$api.sendRequest({
url: url,
data: data,
success: res => {
this.$util.showToast({
title: res.message
});
if (res.code == 0) {
setTimeout(() => {
uni.removeStorage({
key: 'forgot_password_token'
});
this.$util.redirectTo('/pages_tool/login/login', {}, 'redirectTo');
}, 1000);
} else {
this.stepShow -= 1;
}
}
});
}
},
/**
* 获取注册配置
*/
getRegisterConfig() {
this.$api.sendRequest({
url: '/api/register/config',
success: res => {
if (res.code >= 0) {
this.registerConfig = res.data.value;
}
}
});
}
},
watch: {
seconds(value) {
if (value == 0) {
this.seconds = 120;
this.codeText = '重新获取';
this.isSend = false;
clearInterval(this.timer);
}
}
}
};
</script>
<style lang="scss">
page {
background: #ffffff !important;
overflow: hidden;
}
.captcha {
width: 170rpx;
height: 50rpx;
}
.find-form {
padding: 100rpx 80rpx 0;
.form-input {
margin-top: 60rpx;
height: 60rpx;
border-bottom: 2rpx solid $color-line;
input {
padding: 0;
font-size: $font-size-base;
}
}
.find-btn {
margin: 374rpx 0 0;
border-radius: $border-radius;
color: #fff;
&[disabled] {
background-color: #f7f7f7 !important;
}
}
}
.forget-section {
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
margin-top: 10rpx;
height: 70rpx;
line-height: 70rpx;
}
.align-type {
display: flex;
justify-content: space-between;
}
.header-wrap {
width: 80%;
height: 100%;
margin: calc(120rpx + 88rpx) auto 0;
background-repeat: no-repeat;
background-size: contain;
background-position: bottom;
position: relative;
.title {
font-size: 50rpx;
font-weight: bold;
}
}
.icon-close {
font-size: 52rpx;
position: fixed;
left: 24rpx;
top: 72rpx;
z-index: 9;
color: #000;
}
.placeholder-class {
color: #bfbfbf;
}
</style>

153
pages_tool/login/index.vue Normal file
View File

@@ -0,0 +1,153 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="auth-index" :style="warpStyle">
<view class="website-logo">
<image class="logo" v-if="siteInfo.logo" :src="$util.img(siteInfo.logo)" mode="aspectFit"></image>
<view v-else class="logo"></view>
</view>
<view class="login-desc">{{registerConfig.wap_desc}}</view>
<view class="login-area">
<!-- #ifdef H5 -->
<view class="btn quick-login" v-if="$util.isWeiXin() && wechatConfigStatus && registerConfig && Number(registerConfig.third_party)" @click="quickLogin">快捷登录/注册</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="btn quick-login" v-if="registerConfig && Number(registerConfig.third_party)" @click="quickLogin">快捷登录/注册</view>
<!-- #endif -->
<view class="btn" :class="isQuickLogin ? '':'quick-login'" @click="toLogin('mobile')" v-if="registerConfig.login.indexOf('mobile') != -1">手机号登录</view>
<view class="btn" :class="isQuickLogin ? '':'quick-login'" @click="toLogin('account')" v-if="registerConfig.login.indexOf('mobile') == -1 && registerConfig.login.indexOf('username') != -1">账号密码登录</view>
<view class="agreement" v-if="registerConfig.agreement_show">
<text class="iconfont agree" :class=" isAgree ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox' " @click="isAgree = !isAgree"></text>
<view class="tips-text">
<text class="tips">请阅读并同意</text>
<text class="agreement-name color-base-text" @click="toAggrement('PRIVACY')">隐私协议</text>
<text class="tips"></text>
<text class="agreement-name color-base-text" @click="toAggrement('SERVICE')">用户协议</text>
</view>
</view>
<view class="footer" v-if="registerConfig.login.indexOf('mobile') != -1 && registerConfig.login.indexOf('username') != -1">
<view class="text">其他方式登录</view>
<view class="mine icondiy icon-system-wodi2" @click="toLogin('account')"></view>
<view class="mode-name">账号密码登录</view>
</view>
</view>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
import auth from 'common/js/auth.js';
export default {
mixins: [auth],
data() {
return {
back: '',
registerConfig: {
register: '',
login: '',
},
isAgree: false
}
},
computed: {
isQuickLogin() {
// #ifdef H5
return this.$util.isWeiXin() && this.wechatConfigStatus && this.registerConfig && Number(this.registerConfig.third_party);
// #endif
// #ifdef MP-WEIXIN
return this.registerConfig && Number(this.registerConfig.third_party);
// #endif
},
warpStyle() {
var style = '';
if(this.registerConfig.wap_bg){
style += 'background-image:url(' + this.$util.img(this.registerConfig.wap_bg) + ');';
style += 'background-size: 100%;';
style += 'background-position: top;';
style += 'background-repeat: no-repeat;';
}
return style
},
wechatConfigStatus() {
return this.$store.state.wechatConfigStatus;
}
},
onLoad(option) {
this.back = option.back || '';
// #ifdef MP-WEIXIN
this.back = option.back ? decodeURIComponent(option.back) : '';
// #endif
if(this.back) uni.setStorageSync('initiateLogin',this.back)
// #ifdef MP-WEIXIN
this.getCode(authData => {
uni.setStorageSync('authInfo', authData);
});
// #endif
if(!uni.getStorageSync('authInfo')){
// #ifdef H5
if(this.$util.isWeiXin() && !option.code){
this.getCode(authData => {
uni.setStorageSync('authInfo', authData);
});
}
if(option.code){
this.$api.sendRequest({
url: '/wechat/api/wechat/authcodetoopenid',
data: {
code: urlParams.code
},
success: res => {
if (res.code >= 0) {
let data = {};
if (res.data.openid) data.wx_openid = res.data.openid;
if (res.data.unionid) data.wx_unionid = res.data.unionid;
if (res.data.userinfo) Object.assign(data, res.data.userinfo);
uni.setStorageSync('authInfo', data);
}
}
});
}
// #endif
}
},
onShow() {
this.getRegisterConfig();
},
methods: {
toAggrement(type){
this.$util.redirectTo('/pages_tool/login/aggrement',{type:type})
},
quickLogin(){
if(this.registerConfig.agreement_show && !this.isAgree){
this.$util.showToast({title:'请先阅读并同意协议'})
return;
}
this.$refs.login.open(this.back,true);
},
toLogin(loginMode){
this.$util.redirectTo('/pages_tool/login/login',{loginMode:loginMode})
},
/**
* 获取注册配置
*/
getRegisterConfig() {
this.$api.sendRequest({
url: '/api/register/config',
success: res => {
if (res.code >= 0) {
this.registerConfig = res.data.value;
}
}
});
},
},
}
</script>
<style lang="scss">
@import './public/css/common.scss';
</style>

View File

@@ -1,484 +1,496 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<scroll-view scroll-y="false" class="container">
<view class="header-wrap" :style="{backgroundImage: 'url('+$util.img('public/uniapp/member/head.png')+')'}">
<view class="t-b">
您好
<br />
欢迎使用
</view>
</view>
<view class="body-wrap">
<view class="form-wrap">
<view class="input-wrap" v-show="loginMode == 'mobile'">
<view class="content">
<!-- <view class="area-code">+86</view> -->
<input type="number" placeholder="请输入您的手机号" placeholder-class="input-placeholder" class="input" maxlength="11" v-model="formData.mobile" />
</view>
</view>
<view class="input-wrap" v-show="loginMode == 'account'">
<view class="content">
<input type="text" placeholder="请输入账号" placeholder-class="input-placeholder" class="input" v-model="formData.account" />
</view>
</view>
<view class="input-wrap" v-show="loginMode == 'account'">
<view class="content">
<input type="password" placeholder="请输入密码" placeholder-class="input-placeholder" class="input" v-model="formData.password" />
<view class="align-right" v-show="loginMode == 'account'">
<text @click="forgetPassword">忘记密码?</text>
</view>
</view>
</view>
<view class="input-wrap" v-show="loginMode == 'mobile'">
<view class="content">
<input type="text" placeholder="请输入动态码" placeholder-class="input-placeholder" class="input" v-model="formData.dynacode" />
<view class="dynacode" :class="dynacodeData.seconds == 120 ? 'color-base-text' : 'color-tip'"
@click="sendMobileCode">{{ dynacodeData.codeText }}</view>
</view>
</view>
</view>
<view class="btn_view">
<button type="primary" @click="login" class="login-btn color-base-border color-base-bg" style="background: #2796f2 !important;border: none;">登录</button>
</view>
<view class="regisiter-agreement" style="margin: 0 50rpx;padding-top: 40rpx;line-height: 1.5;display: flex;">
<view style="" class="iconfont" :class=" isAgree ? 'icon-fuxuankuang1 color-base-text' : 'icon-fuxuankuang2' " @click="isAgree = !isAgree"></view>
<view style="text-align: left;margin-left: 10rpx;padding-top: 2rpx;">若您未注册则登录后将自动帮您注册注册即视为同意 <text @click="tourl('/pages_tool/agreement/contenr?type=0')" style="color:#4395ff">隐私条款</text> <text @click="tourl('/pages_tool/agreement/contenr?type=1')" style="color:#4395ff">用户服务协议</text></view>
</view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<register-reward ref="registerReward"></register-reward>
</scroll-view>
</template>
<script>
import validate from 'common/js/validate.js';
import registerReward from '@/components/register-reward/register-reward.vue';
export default {
data() {
return {
isAgree: false,
// loginMode: 'account',
loginMode: 'mobile',
formData: {
mobile: '',
account: '',
password: '',
vercode: '',
dynacode: '',
key: ''
},
captcha: {
id: '',
img: ''
},
isSub: false, // 提交防重复
back: '', // 返回页
redirect: 'redirectTo', // 跳转方式
dynacodeData: {
seconds: 120,
timer: null,
codeText: '获取动态码',
isSend: false
},
registerConfig: {
register: 'mobile',
login: ''
},
captchaConfig: 0,
authInfo: null
};
},
components: {
registerReward
},
onLoad(option) {
if (option.back) this.back = option.back;
this.getRegisterConfig();
// this.getCaptchaConfig();
this.authInfo = uni.getStorageSync('authInfo');
},
onShow() {},
onReady() {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
methods: {
/**
* 获取验证码配置
*/
getCaptchaConfig() {
this.$api.sendRequest({
url: '/api/config/getCaptchaConfig',
success: res => {
if (res.code >= 0) {
this.captchaConfig = res.data.shop_reception_login;
if (this.captchaConfig == 1) this.getCaptcha();
}
}
});
},
/**
* 获取注册配置
*/
getRegisterConfig() {
this.$api.sendRequest({
url: '/api/register/config',
success: res => {
if (res.code >= 0) {
// this.registerConfig = res.data.value;
// if (this.registerConfig.login.indexOf('mobile') != -1) this.loginMode = 'mobile';
// else this.loginMode = 'account';
}
}
});
},
/**
* 切换登录方式
*/
switchLoginMode() {
this.loginMode = this.loginMode == 'mobile' ? 'account' : 'mobile';
},
/**
* 获取验证码
*/
getCaptcha() {
if (this.captchaConfig == 0) return;
this.$api.sendRequest({
url: '/api/captcha/captcha',
data: {
captcha_id: this.captcha.id
},
success: res => {
if (res.code >= 0) {
this.captcha = res.data;
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
}
}
});
},
/**
* 去注册
*/
toRegister() {
if (this.back) this.$util.redirectTo('/pages_tool/login/register', {
back: encodeURIComponent(this.back)
});
else this.$util.redirectTo('/pages_tool/login/register');
},
/**
* 忘记密码
*/
forgetPassword() {
if (this.back) this.$util.redirectTo('/pages_tool/login/find', {
back: encodeURIComponent(this.back)
});
else this.$util.redirectTo('/pages_tool/login/find');
},
tourl(url){
this.$util.redirectTo(url);
},
/**
* 登录
*/
login() {
if (!this.isAgree) {
this.$util.showToast({
title: '请先阅读并同意协议'
});
return false;
}
if (this.loginMode == 'account') {
var url = '/api/login/login';
data = {
username: this.formData.account,
password: this.formData.password
};
} else {
var url = '/api/login/mobile',
data = {
mobile: this.formData.mobile,
key: this.formData.key,
code: this.formData.dynacode
};
}
if (this.captcha.id != '') {
data.captcha_id = this.captcha.id;
data.captcha_code = this.formData.vercode;
}
if (this.authInfo) Object.assign(data, this.authInfo);
if (uni.getStorageSync('source_member')) data.source_member = uni.getStorageSync('source_member');
if (this.verify(data)) {
if (this.isSub) return;
this.isSub = true;
this.$api.sendRequest({
url,
data,
success: res => {
if (res.code >= 0) {
var can_receive_registergift = res.data.can_receive_registergift;
this.$store.commit('setToken', res.data.token);
this.$store.dispatch('getCartNumber');
this.getMemberInfo(() => {
if (can_receive_registergift == 1) {
this.$util.showToast({
title: '登录成功'
});
let back = this.back ? this.back : '/pages/member/index';
if(this.$refs.registerReward) this.$refs.registerReward.open(back);
} else {
if (this.back != '') {
this.$util.redirectTo(decodeURIComponent(this.back), {}, 'reLaunch');
} else {
this.$util.redirectTo('/pages/member/index', {}, 'reLaunch');
}
}
});
} else {
this.isSub = false;
this.getCaptcha();
this.$util.showToast({
title: res.message
});
}
},
fail: res => {
this.isSub = false;
this.getCaptcha();
}
});
}
},
/**
* 登录验证
* @param {Object} data
*/
verify(data) {
let rule = [];
// 手机号验证
if (this.loginMode == 'mobile') {
rule = [{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
}, {
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}];
if (this.captchaConfig == 1) {
if (this.captcha.id != '') rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
});
}
rule.push({
name: 'code',
checkType: 'required',
errorMsg: this.$lang('dynacodePlaceholder')
});
}
// 账号验证
if (this.loginMode == 'account') {
rule = [{
name: 'username',
checkType: 'required',
errorMsg: this.$lang('accountPlaceholder')
},
{
name: 'password',
checkType: 'required',
errorMsg: this.$lang('passwordPlaceholder')
}
];
if (this.captchaConfig == 1) {
if (this.captcha.id != '') rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
});
}
}
var checkRes = validate.check(data, rule);
if (checkRes) {
return true;
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
},
mobileAuthLogin(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
var data = {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
};
if (Object.keys(this.authInfo).length) {
Object.assign(data, this.authInfo);
if (this.authInfo.nickName) data.nickname = this.authInfo.nickName;
if (this.authInfo.avatarUrl) data.headimg = this.authInfo.avatarUrl;
}
if (uni.getStorageSync('source_member')) data.source_member = uni.getStorageSync('source_member');
if (this.isSub) return;
this.isSub = true;
this.$api.sendRequest({
url: '/api/tripartite/mobileauth',
data,
success: res => {
if (res.code >= 0) {
var can_receive_registergift = res.data.can_receive_registergift;
this.$store.commit('setToken', res.data.token);
this.$store.dispatch('getCartNumber');
this.getMemberInfo(() => {
if (can_receive_registergift == 1) {
let back = this.back ? this.back : '/pages/member/index';
if(this.$refs.registerReward) this.$refs.registerReward.open(back);
} else {
if (this.back != '') {
this.$util.redirectTo(decodeURIComponent(this.back), {}, this.redirect);
} else {
this.$util.redirectTo('/pages/member/index', {}, this.redirect);
}
}
})
} else {
this.isSub = false;
this.$util.showToast({
title: res.message
});
}
},
fail: res => {
this.isSub = false;
this.$util.showToast({
title: 'request:fail'
});
}
});
}
},
/**
* 发送手机动态码
*/
sendMobileCode() {
if (this.dynacodeData.seconds != 120 || this.dynacodeData.isSend) return;
var data = {
mobile: this.formData.mobile,
captcha_id: this.captcha.id,
captcha_code: this.formData.vercode
};
var rule = [{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
}, {
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}];
if (this.captchaConfig == 1) {
rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: '请输入验证码'
});
}
var checkRes = validate.check(data, rule);
if (!checkRes) {
this.$util.showToast({
title: validate.error
});
return;
}
this.dynacodeData.isSend = true;
this.dynacodeData.timer = setInterval(() => {
this.dynacodeData.seconds--;
this.dynacodeData.codeText = this.dynacodeData.seconds + 's后可重新获取';
}, 1000);
this.$api.sendRequest({
url: '/api/login/mobileCode',
data: data,
success: res => {
if (res.code >= 0) {
this.formData.key = res.data.key;
} else {
this.refreshDynacodeData();
this.$util.showToast({
title: res.message
});
}
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
this.refreshDynacodeData();
}
});
},
refreshDynacodeData() {
this.getCaptcha();
clearInterval(this.dynacodeData.timer);
this.dynacodeData = {
seconds: 120,
timer: null,
codeText: '获取动态码',
isSend: false
};
},
getMemberInfo(callback) {
this.$api.sendRequest({
url: '/api/member/info',
success: (res) => {
if (res.code >= 0) {
// 登录成功,存储会员信息
this.$store.commit('setMemberInfo', res.data);
if (callback) callback();
}
}
});
}
},
watch: {
'dynacodeData.seconds': {
handler(newValue, oldValue) {
if (newValue == 0) {
this.refreshDynacodeData();
}
},
immediate: true,
deep: true
}
}
};
</script>
<style lang="scss">
@import './public/css/common.scss';
.color-base-text{
color:#2796f2 !important
}
</style>
<style scoped>
/deep/ .reward-popup .uni-popup__wrapper-box {
background: none !important;
max-width: unset !important;
max-height: unset !important;
overflow: unset !important;
}
/deep/ uni-toast .uni-simple-toast__text {
background: red !important;
}
<template>
<page-meta :page-style="themeColor"></page-meta>
<scroll-view scroll-y="true" class="container">
<!-- <view class="iconfont icon-close back-btn" @click="$util.redirectTo('/pages/member/index')"></view> -->
<view class="header-wrap">
<view class="title">登录</view>
<view class="regisiter-agreement" v-if="registerConfig.register != ''">
<text class="color-tip">还没有账号,</text>
<text class="color-base-text" @click="toRegister">立即注册</text>
</view>
</view>
<view class="body-wrap">
<view class="form-wrap">
<view class="input-wrap" v-show="loginMode == 'mobile'">
<view class="content">
<view class="area-code">+86</view>
<input type="number" placeholder="仅限中国大陆手机号登录" placeholder-class="input-placeholder" class="input" maxlength="11" v-model="formData.mobile" />
</view>
</view>
<view class="input-wrap" v-show="loginMode == 'account'">
<view class="content">
<input type="text" placeholder="请输入账号" placeholder-class="input-placeholder" class="input" v-model="formData.account" />
</view>
</view>
<view class="input-wrap" v-show="loginMode == 'account'">
<view class="content">
<input type="password" placeholder="请输入密码" placeholder-class="input-placeholder" class="input" v-model="formData.password" />
<view class="align-right" v-show="loginMode == 'account'">
<text @click="forgetPassword">忘记密码?</text>
</view>
</view>
</view>
<view class="input-wrap" v-if="captchaConfig == 1">
<view class="content">
<input type="text" placeholder="请输入验证码" placeholder-class="input-placeholder" class="input" v-model="formData.vercode" />
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image>
</view>
</view>
<view class="input-wrap" v-show="loginMode == 'mobile'">
<view class="content">
<input type="text" placeholder="请输入动态码" placeholder-class="input-placeholder" class="input" v-model="formData.dynacode" />
<view class="dynacode" :class="dynacodeData.seconds == 120 ? 'color-base-text' : 'color-tip'" @click="sendMobileCode">{{ dynacodeData.codeText }}</view>
</view>
</view>
</view>
<view class="login-mode-box">
<text @click="switchLoginMode" v-show="loginMode == 'mobile' && registerConfig.login.indexOf('username') != -1">使用账号登录</text>
<text @click="switchLoginMode" v-show="loginMode == 'account' && registerConfig.login.indexOf('mobile') != -1">使用手机号登录</text>
</view>
<view class="btn_view">
<button type="primary" @click="login" class="login-btn color-base-border color-base-bg">登录</button>
<!-- #ifdef MP -->
<!-- <button open-type="getPhoneNumber" class="auth-login color-base-border" v-if="Number(registerConfig.third_party)" @getphonenumber="mobileAuthLogin">
<text class="color-base-text color-base-border">一键授权手机号快捷登录</text>
</button> -->
<!-- #endif -->
</view>
<view class="regisiter-agreement" v-if="registerConfig.agreement_show">
<text class="iconfont is-agree" :class=" isAgree ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox' " @click="isAgree = !isAgree"></text>
<text class="tips">请阅读并同意</text>
<text class="color-base-text" @click="toAggrement('PRIVACY')">隐私协议</text>
<text class="tips"></text>
<text class="color-base-text" @click="toAggrement('SERVICE')">用户协议</text>
</view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<register-reward ref="registerReward"></register-reward>
</scroll-view>
</template>
<script>
import validate from 'common/js/validate.js';
import registerReward from '@/components/register-reward/register-reward.vue';
export default {
data() {
return {
isAgree: false,
loginMode: '',
formData: {
mobile: '',
account: '',
password: '',
vercode: '',
dynacode: '',
key: ''
},
captcha: {
id: '',
img: ''
},
isSub: false, // 提交防重复
back: '', // 返回页
redirect: 'redirectTo', // 跳转方式
dynacodeData: {
seconds: 120,
timer: null,
codeText: '获取动态码',
isSend: false
},
registerConfig: {
register: '',
login: ''
},
captchaConfig: 1,
authInfo: null
};
},
components: {
registerReward
},
onLoad(option) {
if(option.loginMode) this.loginMode = option.loginMode;
if (option.back) this.back = option.back;
this.getRegisterConfig();
this.getCaptchaConfig();
this.authInfo = uni.getStorageSync('authInfo');
},
onShow() {},
onReady() {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
methods: {
toAggrement(type){
this.$util.redirectTo('/pages_tool/login/aggrement',{type:type})
},
/**
* 获取验证码配置
*/
getCaptchaConfig() {
this.$api.sendRequest({
url: '/api/config/getCaptchaConfig',
success: res => {
if (res.code >= 0) {
this.captchaConfig = res.data.shop_reception_login;
if (this.captchaConfig == 1) this.getCaptcha();
}
}
});
},
/**
* 获取注册配置
*/
getRegisterConfig() {
this.$api.sendRequest({
url: '/api/register/config',
success: res => {
if (res.code >= 0) {
this.registerConfig = res.data.value;
if(!this.loginMode){
if (this.registerConfig.login.indexOf('mobile') != -1) this.loginMode = 'mobile';
else this.loginMode = 'account';
}
}
}
});
},
/**
* 切换登录方式
*/
switchLoginMode() {
this.loginMode = this.loginMode == 'mobile' ? 'account' : 'mobile';
},
/**
* 获取验证码
*/
getCaptcha() {
if (this.captchaConfig == 0) return;
this.$api.sendRequest({
url: '/api/captcha/captcha',
data: {
captcha_id: this.captcha.id
},
success: res => {
if (res.code >= 0) {
this.captcha = res.data;
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
}
}
});
},
/**
* 去注册
*/
toRegister() {
if (this.back) this.$util.redirectTo('/pages_tool/login/register', {
back: encodeURIComponent(this.back)
});
else this.$util.redirectTo('/pages_tool/login/register');
},
/**
* 忘记密码
*/
forgetPassword() {
if (this.back) this.$util.redirectTo('/pages_tool/login/find', {
back: encodeURIComponent(this.back)
});
else this.$util.redirectTo('/pages_tool/login/find');
},
/**
* 登录
*/
login() {
if (this.loginMode == 'account') {
var url = '/api/login/login';
data = {
username: this.formData.account,
password: this.formData.password
};
} else {
var url = '/api/login/mobile',
data = {
mobile: this.formData.mobile,
key: this.formData.key,
code: this.formData.dynacode
};
}
if (this.captcha.id != '') {
data.captcha_id = this.captcha.id;
data.captcha_code = this.formData.vercode;
}
if (this.authInfo) Object.assign(data, this.authInfo);
if (uni.getStorageSync('source_member')) data.source_member = uni.getStorageSync('source_member');
if (this.verify(data)) {
if (this.isSub) return;
this.isSub = true;
this.$api.sendRequest({
url,
data,
success: res => {
if (res.code >= 0) {
var can_receive_registergift = res.data.can_receive_registergift;
this.$store.commit('setToken', res.data.token);
this.$store.dispatch('getCartNumber');
this.getMemberInfo(() => {
if (can_receive_registergift == 1) {
this.$util.showToast({
title: '登录成功'
});
this.$store.commit('setCanReceiveRegistergiftInfo',{status: true,path:this.$util.openRegisterRewardPath('/pages/member/index')});
// if(this.$refs.registerReward) this.$refs.registerReward.open(back);
}
this.$util.loginComplete('/pages/member/index',{},this.redirect);
});
} else {
this.isSub = false;
this.getCaptcha();
this.$util.showToast({
title: res.message
});
}
},
fail: res => {
this.isSub = false;
this.getCaptcha();
}
});
}
},
/**
* 登录验证
* @param {Object} data
*/
verify(data) {
if (this.registerConfig.agreement_show && !this.isAgree) {
this.$util.showToast({
title: '请先阅读并同意协议'
});
return;
}
let rule = [];
// 手机号验证
if (this.loginMode == 'mobile') {
rule = [{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
}, {
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}];
if (this.captchaConfig == 1) {
if (this.captcha.id != '') rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
});
}
rule.push({
name: 'code',
checkType: 'required',
errorMsg: this.$lang('dynacodePlaceholder')
});
}
// 账号验证
if (this.loginMode == 'account') {
rule = [{
name: 'username',
checkType: 'required',
errorMsg: this.$lang('accountPlaceholder')
},
{
name: 'password',
checkType: 'required',
errorMsg: this.$lang('passwordPlaceholder')
}
];
if (this.captchaConfig == 1) {
if (this.captcha.id != '') rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
});
}
}
var checkRes = validate.check(data, rule);
if (checkRes) {
return true;
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
},
mobileAuthLogin(e) {
if (e.detail.errMsg == 'getPhoneNumber:ok') {
var data = {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
};
if (Object.keys(this.authInfo).length) {
Object.assign(data, this.authInfo);
if (this.authInfo.nickName) data.nickname = this.authInfo.nickName;
if (this.authInfo.avatarUrl) data.headimg = this.authInfo.avatarUrl;
}
if (uni.getStorageSync('source_member')) data.source_member = uni.getStorageSync('source_member');
if (this.isSub) return;
this.isSub = true;
this.$api.sendRequest({
url: '/api/tripartite/mobileauth',
data,
success: res => {
if (res.code >= 0) {
var can_receive_registergift = res.data.can_receive_registergift;
this.$store.commit('setToken', res.data.token);
this.$store.dispatch('getCartNumber');
this.getMemberInfo(() => {
if (can_receive_registergift == 1) {
let back = this.back ? this.back : '/pages/member/index';
this.$store.commit('setCanReceiveRegistergiftInfo', {status: true,path:this.$util.openRegisterRewardPath(back)});
// if(this.$refs.registerReward) this.$refs.registerReward.open(back);
}
if (this.back != '') {
this.$util.loginComplete(this.back,{},this.redirect);
} else {
this.$util.loginComplete('/pages/member/index',{},this.redirect);
}
})
} else {
this.isSub = false;
this.$util.showToast({
title: res.message
});
}
},
fail: res => {
this.isSub = false;
this.$util.showToast({
title: 'request:fail'
});
}
});
}
},
/**
* 发送手机动态码
*/
sendMobileCode() {
if (this.dynacodeData.seconds != 120 || this.dynacodeData.isSend) return;
var data = {
mobile: this.formData.mobile,
captcha_id: this.captcha.id,
captcha_code: this.formData.vercode
};
var rule = [{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
}, {
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}];
if (this.captchaConfig == 1) {
rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: '请输入验证码'
});
}
var checkRes = validate.check(data, rule);
if (!checkRes) {
this.$util.showToast({
title: validate.error
});
return;
}
this.dynacodeData.isSend = true;
this.dynacodeData.timer = setInterval(() => {
this.dynacodeData.seconds--;
this.dynacodeData.codeText = this.dynacodeData.seconds + 's后可重新获取';
}, 1000);
this.$api.sendRequest({
url: '/api/login/mobileCode',
data: data,
success: res => {
if (res.code >= 0) {
this.formData.key = res.data.key;
} else {
this.refreshDynacodeData();
this.$util.showToast({
title: res.message
});
}
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
this.refreshDynacodeData();
}
});
},
refreshDynacodeData() {
this.getCaptcha();
clearInterval(this.dynacodeData.timer);
this.dynacodeData = {
seconds: 120,
timer: null,
codeText: '获取动态码',
isSend: false
};
},
getMemberInfo(callback) {
this.$api.sendRequest({
url: '/api/member/info',
success: (res) => {
if (res.code >= 0) {
// 登录成功,存储会员信息
this.$store.commit('setMemberInfo', res.data);
if (callback) callback();
}
}
});
}
},
watch: {
'dynacodeData.seconds': {
handler(newValue, oldValue) {
if (newValue == 0) {
this.refreshDynacodeData();
}
},
immediate: true,
deep: true
}
}
};
</script>
<style lang="scss">
@import './public/css/common.scss';
</style>
<style scoped>
/deep/ .reward-popup .uni-popup__wrapper-box {
background: none !important;
max-width: unset !important;
max-height: unset !important;
overflow: unset !important;
}
/deep/ uni-toast .uni-simple-toast__text {
background: red !important;
}
</style>

View File

@@ -1,209 +1,313 @@
/deep/.uni-scroll-view {
background-color: #fff;
}
/deep/.uni-scroll-view::-webkit-scrollbar {
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
display: none;
}
page {
width: 100%;
background: #fff !important;
}
.align-right {
color: #838383;
}
.container {
width: 100vw;
height: 100vh;
}
.t-b {
text-align: left;
font-size: 42rpx;
color: #ffffff;
padding: 130rpx 0 50rpx 70rpx;
font-weight: bold;
line-height: 70rpx;
}
.header-wrap {
// width: 80%;
// margin: calc(120rpx + 44px) auto 0;
background-repeat: no-repeat;
background-size: contain;
background-position: bottom;
position: relative;
// margin-top:80rpx;
background-size: 100% 100%;
.title {
font-size: 60rpx;
font-weight: bold;
}
}
.body-wrap {
margin-top: 100rpx;
padding-bottom: 100rpx;
.form-wrap {
width: 80%;
margin: 0 auto;
.input-wrap {
position: relative;
width: 100%;
box-sizing: border-box;
height: 60rpx;
margin-top: 60rpx;
.iconfont {
width: 60rpx;
height: 60rpx;
position: absolute;
left: 0;
right: 0;
line-height: 60rpx;
font-size: $font-size-toolbar;
color: $color-title;
font-weight: 600;
}
.content {
display: flex;
height: 60rpx;
border-bottom: 2rpx solid $color-line;
align-items: center;
.input {
flex: 1;
height: 60rpx;
line-height: 60rpx;
font-size: $font-size-base;
}
.input-placeholder {
font-size: $font-size-base;
color: #bfbfbf;
line-height: 60rpx;
}
.captcha {
margin: 4rpx;
height: 52rpx;
width: 140rpx;
}
.dynacode {
line-height: 60rpx;
font-size: $font-size-tag;
}
.area-code {
line-height: 60rpx;
margin-right: 20rpx;
font-size: $font-size-base;
}
}
}
}
.forget-section {
display: flex;
width: 80%;
margin: 40rpx auto;
view {
flex: 1;
font-size: $font-size-tag;
line-height: 1;
}
}
.btn_view {
width: 100%;
margin: 94rpx auto auto;
padding: 0 $margin-both;
box-sizing: border-box;
}
.login-btn {
height: 90rpx;
line-height: 90rpx;
border-radius: $border-radius;
text-align: center;
border: 2rpx solid;
width: 100%;
margin: 0;
}
.auth-login {
margin-top: 20rpx;
width: calc(100% - 4rpx);
height: 90rpx;
line-height: 90rpx;
border-radius: $border-radius;
border: 2rpx solid;
color: #fff;
text-align: center;
margin-left: 0;
background-color: #fff;
text {
color: #d0d0d0;
}
.iconfont {
font-size: 70rpx;
}
.icon-weixin {
color: #1aad19;
}
}
// .auth-login{
// background-color: #fff;
// display: flex;
// justify-content: center;
// align-items: center;
// text-align: center;
// padding: 0;
// text{
// color: #D0D0D0;
// }
// .iconfont{
// font-size: 70rpx;
// }
// }
.regisiter-agreement {
// text-align: center;
margin-top: 30rpx;
color: #838383;
line-height: 60rpx;
font-size: $font-size-tag;
.tips{
margin:0 10rpx;
}
}
}
.login-btn-box {
margin-top: 50rpx;
}
.login-btn-box.active {
margin: 30rpx 0 50rpx;
}
.back-btn {
font-size: 52rpx;
position: fixed;
left: 24rpx;
top: 72rpx;
z-index: 9;
color: #000;
}
.login-mode-box {
display: flex;
justify-content: flex-end;
color: $color-tip;
margin: auto;
margin-top: 44rpx;
font-size: 26rpx;
width: 80%;
}
/deep/.uni-scroll-view {
background-color: #fff;
}
/deep/.uni-scroll-view::-webkit-scrollbar {
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
display: none;
}
page {
width: 100%;
background: #fff !important;
}
.align-right {
color: #838383;
}
.container {
width: 100vw;
height: 100vh;
}
.header-wrap {
width: 80%;
margin: calc(120rpx + 44px) auto 0;
background-repeat: no-repeat;
background-size: contain;
background-position: bottom;
position: relative;
.title {
font-size: 60rpx;
font-weight: bold;
}
}
.body-wrap {
margin-top: 100rpx;
padding-bottom: 100rpx;
.form-wrap {
width: 80%;
margin: 0 auto;
.input-wrap {
position: relative;
width: 100%;
box-sizing: border-box;
height: 60rpx;
margin-top: 60rpx;
.iconfont {
width: 60rpx;
height: 60rpx;
position: absolute;
left: 0;
right: 0;
line-height: 60rpx;
font-size: $font-size-toolbar;
color: $color-title;
font-weight: 600;
}
.content {
display: flex;
height: 60rpx;
border-bottom: 2rpx solid $color-line;
align-items: center;
.input {
flex: 1;
height: 60rpx;
line-height: 60rpx;
font-size: $font-size-base;
}
.input-placeholder {
font-size: $font-size-base;
color: #bfbfbf;
line-height: 60rpx;
}
.captcha {
margin: 4rpx;
height: 52rpx;
width: 140rpx;
}
.dynacode {
line-height: 60rpx;
font-size: $font-size-tag;
}
.area-code {
line-height: 60rpx;
margin-right: 20rpx;
font-size: $font-size-base;
}
}
}
}
.forget-section {
display: flex;
width: 80%;
margin: 40rpx auto;
view {
flex: 1;
font-size: $font-size-tag;
line-height: 1;
}
}
.btn_view {
width: 100%;
margin: 94rpx auto auto;
padding: 0 $margin-both;
box-sizing: border-box;
}
.login-btn {
height: 90rpx;
line-height: 90rpx;
border-radius: 90rpx;
text-align: center;
border: 2rpx solid;
width: 100%;
margin: 0;
}
.auth-login {
margin-top: 20rpx;
width: calc(100% - 4rpx);
height: 90rpx;
line-height: 90rpx;
border-radius: $border-radius;
border: 2rpx solid;
color: #fff;
text-align: center;
margin-left: 0;
background-color: #fff;
text {
color: #d0d0d0;
}
.iconfont {
font-size: 70rpx;
}
.icon-weixin {
color: #1aad19;
}
}
// .auth-login{
// background-color: #fff;
// display: flex;
// justify-content: center;
// align-items: center;
// text-align: center;
// padding: 0;
// text{
// color: #D0D0D0;
// }
// .iconfont{
// font-size: 70rpx;
// }
// }
.regisiter-agreement {
text-align: center;
margin-top: 30rpx;
color: #838383;
line-height: 60rpx;
font-size: $font-size-tag;
.tips{
margin:0 10rpx;
}
.is-agree{
font-size: 26rpx;
}
}
}
.login-btn-box {
margin-top: 50rpx;
}
.login-btn-box.active {
margin: 30rpx 0 50rpx;
}
.back-btn {
font-size: 52rpx;
position: fixed;
left: 24rpx;
top: 72rpx;
z-index: 9;
color: #000;
}
.login-mode-box {
display: flex;
justify-content: flex-end;
color: $color-tip;
margin: auto;
margin-top: 44rpx;
font-size: 26rpx;
width: 80%;
}
.auth-index{
width: 100vw;
height: 100vh;
box-sizing: border-box;
padding: 0 44rpx;
.website-logo{
padding-top: 154rpx;
display: flex;
justify-content: center;
.logo{
width: 300rpx;
height: 90rpx;
display: block;
}
}
.login-desc{
color: #333;
font-size: 28rpx;
text-align: center;
line-height: 34rpx;
min-height: 34rpx;
margin-top: 40rpx;
}
.login-area{
margin-top: 181rpx;
display: flex;
flex-direction: column;
align-items: center;
.btn{
background-color: #fff;
border: 2rpx solid var(--base-color);
color: var(--base-color);
box-sizing: border-box;
width: 630rpx;
height: 88rpx;
font-size: 26rpx;
border-radius: 44rpx;
line-height: 86rpx;
font-weight: 500;
text-align: center;
margin-bottom: 40rpx;
&.quick-login{
color: #fff;
background-color: var(--base-color);
}
}
.agreement{
display: flex;
align-items: center;
justify-content: center;
width: 100%;
margin-top: 28rpx;
padding: 10rpx 0;
font-size: 24rpx;
line-height: 1;
.agree{
color: rgb(200, 201, 204);
font-size: 26rpx;
line-height: 22rpx;
margin-right: 12rpx;
}
.tips-text{
display: flex;
align-items: center;
line-height: 28rpx;
font-size: 24rpx;
.tips{
color: #666;
}
}
}
.footer{
margin-top: 200rpx;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
.text{
font-size: 26rpx;
line-height: 36rpx;
color: #333;
text-align: center;
margin-bottom: 30rpx;
font-weight: 400;
}
.mine{
width: 80rpx;
height: 80rpx;
line-height: 78rpx;
border: 2rpx solid #ddd;
border-radius: 50%;
font-size: 46rpx;
display: flex;
align-items: center;
justify-content: center;
color: var(--base-color);
}
.mode-name{
font-size: 24rpx;
line-height: 36rpx;
color: #999;
font-weight: 400;
margin-top: 30rpx;
}
}
}
}

View File

@@ -0,0 +1,567 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<scroll-view scroll-y="true" class="container">
<!-- <view class="iconfont icon-close back-btn" @click="$util.goBack()"></view> -->
<view class="header-wrap">
<view class="title">注册</view>
<view class="regisiter-agreement">
<text class="color-tip">已有账号,</text>
<text class="color-base-text" @click="toLogin">立即登录</text>
</view>
</view>
<view class="body-wrap">
<view class="form-wrap">
<view class="input-wrap" v-show="registerMode == 'mobile'">
<view class="content">
<view class="area-code">+86</view>
<input type="number" placeholder="仅限中国大陆手机号注册" placeholder-class="input-placeholder" class="input" maxlength="11" v-model="formData.mobile" />
</view>
</view>
<view class="input-wrap" v-show="registerMode == 'account'">
<view class="content">
<input type="text" placeholder="请输入账号" placeholder-class="input-placeholder" class="input" v-model="formData.account" />
</view>
</view>
<view class="input-wrap" v-show="registerMode == 'account'">
<view class="content">
<input type="password" placeholder="请输入密码" placeholder-class="input-placeholder" class="input" v-model="formData.password" />
</view>
</view>
<view class="input-wrap" v-show="registerMode == 'account'">
<view class="content">
<input type="password" placeholder="请确认密码" placeholder-class="input-placeholder" class="input" v-model="formData.rePassword" />
</view>
</view>
<view class="input-wrap" v-if="isOpenCaptcha">
<view class="content">
<input type="text" placeholder="请输入验证码" placeholder-class="input-placeholder" class="input" v-model="formData.vercode" />
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image>
</view>
</view>
<view class="input-wrap" v-show="registerMode == 'mobile'">
<view class="content">
<input type="text" placeholder="请输入动态码" placeholder-class="input-placeholder" class="input" v-model="formData.dynacode" />
<view class="dynacode" :class="dynacodeData.seconds == 120 ? 'color-base-text' : 'color-tip'" @click="sendMobileCode">{{ dynacodeData.codeText }}</view>
</view>
</view>
</view>
<view class="login-mode-box">
<text @click="switchRegisterMode" v-show="registerMode == 'mobile' && registerConfig.register.indexOf('username') != -1">使用用户名注册</text>
<text @click="switchRegisterMode" v-show="registerMode == 'account' && registerConfig.register.indexOf('mobile') != -1">使用手机号注册</text>
</view>
<view class="btn_view"><button type="primary" @click="register" class="login-btn color-base-border color-base-bg">注册</button></view>
<view class="regisiter-agreement" v-if="registerConfig.agreement_show">
<text class="iconfont is-agree" :class=" isAgree ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox' " @click="isAgree = !isAgree"></text>
<text class="tips">请阅读并同意</text>
<text class="color-base-text" @click="toAggrement('PRIVACY')">隐私协议</text>
<text class="tips"></text>
<text class="color-base-text" @click="toAggrement('SERVICE')">用户协议</text>
</view>
</view>
<view @touchmove.prevent>
<uni-popup ref="registerPopup" type="center" :maskClick="false">
<view class="conten-box">
<view class="close"><text class="iconfont icon-close" @click="toClose"></text></view>
<view class="title">{{ agreement.title }}</view>
<view class="con">
<scroll-view scroll-y="true" class="con">
<!-- <rich-text :nodes="agreement.content"></rich-text> -->
<ns-mp-html :content="agreement.content"></ns-mp-html>
</scroll-view>
</view>
</view>
</uni-popup>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<register-reward ref="registerReward"></register-reward>
</scroll-view>
</template>
<script>
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import validate from 'common/js/validate.js';
import registerReward from '@/components/register-reward/register-reward.vue';
import htmlParser from '@/common/js/html-parser';
export default {
components: {
uniPopup,
registerReward
},
data() {
return {
allowRegister: true, // 是否允许注册
registerMode: 'account',
formData: {
mobile: '',
account: '',
password: '',
rePassword: '',
vercode: '',
dynacode: '',
key: ''
},
agreement: {
// 注册协议
title: '',
content: ''
},
captcha: {
// 验证码
id: '',
img: ''
},
isSub: false,
back: '', // 返回页
dynacodeData: {
seconds: 120,
timer: null,
codeText: '获取动态码',
isSend: false
},
registerConfig: {
register: ''
},
authInfo: null,
isAgree: false,
isOpenCaptcha: 0, // 前台登录验证码0关闭1开启
};
},
onLoad(option) {
if (option.back) this.back = option.back;
this.getCaptchaConfig();
this.getRegisiterAggrement();
this.getRegisterConfig();
this.authInfo = uni.getStorageSync('authInfo');
},
onShow() {},
onReady() {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
methods: {
toAggrement(type){
this.$util.redirectTo('/pages_tool/login/aggrement',{type:type})
},
/**
* 切换注册方式
*/
switchRegisterMode() {
this.registerMode = this.registerMode == 'mobile' ? 'account' : 'mobile';
},
/**
* 展示注册协议
*/
openPopup() {
this.$refs.registerPopup.open();
},
/**
* 点击关闭协议
*/
toClose() {
this.$refs.registerPopup.close();
},
/**
* 获取注册协议
*/
getRegisiterAggrement() {
this.$api.sendRequest({
url: '/api/register/aggrement',
success: res => {
if (res.code >= 0) {
this.agreement = res.data;
// if (this.agreement.content) this.agreement.content = htmlParser(this.agreement.content);
}
}
});
},
/**
* 获取注册配置
*/
getRegisterConfig() {
this.$api.sendRequest({
url: '/api/register/config',
success: res => {
if (res.code >= 0) {
this.registerConfig = res.data.value;
if (this.registerConfig.register == '') {
this.$util.showToast({
title: '平台未启用注册!'
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 1000);
} else if (this.registerConfig.register.indexOf('username') != -1) {
this.registerMode = 'account';
} else {
this.registerMode = 'mobile';
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
}
});
},
/**
* 获取验证码配置
*/
getCaptchaConfig() {
this.$api.sendRequest({
url: '/api/config/getCaptchaConfig',
success: res => {
if (res.code >= 0) {
this.isOpenCaptcha = res.data.shop_reception_register;
if (this.isOpenCaptcha == 1) this.getCaptcha();
}
}
});
},
/**
* 获取验证码
*/
getCaptcha() {
if (this.isOpenCaptcha == 0) return;
this.$api.sendRequest({
url: '/api/captcha/captcha',
data: {
captcha_id: this.captcha.id
},
success: res => {
if (res.code >= 0) {
this.captcha = res.data;
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
}
}
});
},
/**
* 注册
*/
register() {
if (this.registerMode == 'account') {
var url = '/api/register/username';
data = {
username: this.formData.account,
password: this.formData.password
};
} else {
var url = '/api/register/mobile',
data = {
mobile: this.formData.mobile,
key: this.formData.key,
code: this.formData.dynacode
};
}
if (this.isOpenCaptcha == 1) {
if (this.captcha.id != '') {
data.captcha_id = this.captcha.id;
data.captcha_code = this.formData.vercode;
}
}
if (this.authInfo) {
Object.assign(data, this.authInfo);
if (this.authInfo.nickName) data.nickname = this.authInfo.nickName;
if (this.authInfo.avatarUrl) data.headimg = this.authInfo.avatarUrl;
}
if (uni.getStorageSync('source_member')) data.source_member = uni.getStorageSync('source_member');
if (this.verify(data)) {
if (this.isSub) return;
this.isSub = true;
this.$api.sendRequest({
url,
data,
success: res => {
if (res.code >= 0) {
this.$store.commit('setToken', res.data.token);
this.$store.dispatch('getCartNumber');
this.getMemberInfo(() => {
this.$util.showToast({
title: '注册成功'
});
let back = this.back ? this.back : '/pages/member/index';
// this.$refs.registerReward.open(back);
this.$store.commit('setCanReceiveRegistergiftInfo', {status: true,path:this.$util.openRegisterRewardPath(back)});
this.$util.loginComplete(back,'redirectTo');
})
} else {
this.isSub = false;
this.getCaptcha();
this.$util.showToast({
title: res.message
});
}
},
fail: res => {
this.isSub = false;
this.getCaptcha();
}
});
}
},
verify(data) {
if (this.registerConfig.agreement_show && !this.isAgree) {
this.$util.showToast({
title: '请先阅读并同意协议'
});
return false;
}
// 手机号注册
var user_test = /^[A-Za-z0-9]+$/;
if (this.registerMode == 'mobile') {
var rule = [{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
}, {
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}];
if (this.isOpenCaptcha == 1) {
if (this.captcha.id != '') {
rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
});
}
}
rule.push({
name: 'code',
checkType: 'required',
errorMsg: this.$lang('dynacodePlaceholder')
});
}
// 用户名注册
if (this.registerMode == 'account') {
var rule = [{
name: 'username',
checkType: 'required',
errorMsg: '请输入账号'
}, {
name: 'password',
checkType: 'required',
errorMsg: '请输入密码'
}],
regConfig = this.registerConfig;
if (!user_test.test(data.username)) {
this.$util.showToast({
title: '用户名只能输入数字跟英文'
});
return;
}
if (regConfig.pwd_len > 0) {
rule.push({
name: 'password',
checkType: 'lengthMin',
checkRule: regConfig.pwd_len,
errorMsg: '密码长度不能小于' + regConfig.pwd_len + '位'
});
}
if (regConfig.pwd_complexity != '') {
let passwordErrorMsg = '密码需包含',
reg = '';
if (regConfig.pwd_complexity.indexOf('number') != -1) {
reg += '(?=.*?[0-9])';
passwordErrorMsg += '数字';
}
if (regConfig.pwd_complexity.indexOf('letter') != -1) {
reg += '(?=.*?[a-z])';
passwordErrorMsg += '、小写字母';
}
if (regConfig.pwd_complexity.indexOf('upper_case') != -1) {
reg += '(?=.*?[A-Z])';
passwordErrorMsg += '、大写字母';
}
if (regConfig.pwd_complexity.indexOf('symbol') != -1) {
reg += '(?=.*?[#?!@$%^&*-])';
passwordErrorMsg += '、特殊字符';
}
rule.push({
name: 'password',
checkType: 'reg',
checkRule: reg,
errorMsg: passwordErrorMsg
});
}
if (this.formData.password != this.formData.rePassword) {
this.$util.showToast({
title: '两次密码不一致'
});
return false;
}
if (this.isOpenCaptcha == 1) {
if (this.captcha.id != '') {
rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: this.$lang('captchaPlaceholder')
});
}
}
}
var checkRes = validate.check(data, rule);
if (checkRes) {
return true;
} else {
this.$util.showToast({
title: validate.error
});
return false;
}
},
/**
* 去登录
*/
toLogin() {
if (this.back) this.$util.redirectTo('/pages_tool/login/login', {
back: encodeURIComponent(this.back)
});
else this.$util.redirectTo('/pages_tool/login/login');
},
/**
* 发送手机动态码
*/
sendMobileCode() {
if (this.dynacodeData.seconds != 120 || this.dynacodeData.isSend) return;
var data = {
mobile: this.formData.mobile
};
if (this.isOpenCaptcha == 1) {
if (this.captcha.id != '') {
data.captcha_id = this.captcha.id;
data.captcha_code = this.formData.vercode;
}
}
var rule = [{
name: 'mobile',
checkType: 'required',
errorMsg: '请输入手机号'
},
{
name: 'mobile',
checkType: 'phoneno',
errorMsg: '请输入正确的手机号'
}
];
if (this.isOpenCaptcha == 1) {
if (this.captcha.id != '') {
rule.push({
name: 'captcha_code',
checkType: 'required',
errorMsg: '请输入验证码'
});
}
}
var checkRes = validate.check(data, rule);
if (!checkRes) {
this.$util.showToast({
title: validate.error
});
return;
}
this.dynacodeData.isSend = true;
this.dynacodeData.timer = setInterval(() => {
this.dynacodeData.seconds--;
this.dynacodeData.codeText = this.dynacodeData.seconds + 's后可重新获取';
}, 1000);
this.$api.sendRequest({
url: '/api/register/mobileCode',
data: data,
success: res => {
if (res.code >= 0) {
this.formData.key = res.data.key;
} else {
this.$util.showToast({
title: res.message
});
this.refreshDynacodeData();
}
},
fail: () => {
this.$util.showToast({
title: 'request:fail'
});
this.refreshDynacodeData();
}
});
},
refreshDynacodeData() {
this.getCaptcha();
clearInterval(this.dynacodeData.timer);
this.dynacodeData = {
seconds: 120,
timer: null,
codeText: '获取动态码',
isSend: false
};
},
getMemberInfo(callback) {
this.$api.sendRequest({
url: '/api/member/info',
success: (res) => {
if (res.code >= 0) {
// 正常成功,存储会员信息
this.$store.commit('setMemberInfo', res.data);
if (callback) callback();
}
}
});
}
},
watch: {
'dynacodeData.seconds': {
handler(newValue, oldValue) {
if (newValue == 0) {
this.refreshDynacodeData();
}
},
immediate: true,
deep: true
}
}
};
</script>
<style lang="scss">
@import './public/css/common.scss';
</style>
<style scoped lang="scss">
.conten-box {
padding: 0 30rpx 30rpx;
.title {
text-align: center;
margin-top: 50rpx;
margin-bottom: 10rpx;
}
.close {
position: absolute;
right: 30rpx;
top: 10rpx;
}
.con {
height: 500rpx;
}
}
/deep/ .reward-popup .uni-popup__wrapper-box {
background: none !important;
max-width: unset !important;
max-height: unset !important;
overflow: unset !important;
}
</style>

View File

@@ -183,8 +183,7 @@
};
this.dataList.forEach(item => {
item.withdraw_type_name = withdrawType[item.withdraw_type] ? withdrawType[
item.withdraw_type] : '';
item.withdraw_type_name = withdrawType[item.withdraw_type] ? withdrawType[item.withdraw_type] : '';
});
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
@@ -195,8 +194,7 @@
});
},
getTransferType() {
let url = this.type == "member" ? "/api/memberwithdraw/transferType" :
"/fenxiao/api/withdraw/transferType";
let url = this.type == "member" ? "/api/memberwithdraw/transferType" : "/fenxiao/api/withdraw/transferType";
this.$api.sendRequest({
url: url,
success: res => {

View File

@@ -59,7 +59,7 @@ export default {
},
onShow() {
if (this.formData.id) {
this.getAccountDetail(this.formData.id);
this.getAccountDetail();
} else {
this.getTransferType();
}
@@ -74,7 +74,7 @@ export default {
}
},
methods: {
getAccountDetail(id) {
getAccountDetail() {
this.$api.sendRequest({
url: '/api/memberbankaccount/info',
data: {

View File

@@ -229,7 +229,11 @@
if (res.data > 0) {
this.$refs.mescroll.refresh();
if (this.back != '') {
this.$util.redirectTo(this.back, {}, 'redirectTo');
// this.$util.redirectTo(this.back, {}, 'redirectTo');
// 回退到上一个页面
uni.navigateBack({
delta: 1 // delta值为1时表示回退到上一级页面
});
} else {
if (this.$refs.loadingCover) this.$refs.loadingCover.show();
this.addressList = [];
@@ -333,7 +337,11 @@
if (res.code >= 0) {
if (this.back != '') {
this.$util.redirectTo(this.back, {}, 'redirectTo');
// this.$util.redirectTo(this.back, {}, 'redirectTo');
// 回退到上一个页面
uni.navigateBack({
delta: 1 // delta值为1时表示回退到上一级页面
});
} else {
this.$refs.mescroll.refresh();
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,14 +7,13 @@
<view class="tx-bank" v-if="bankAccountInfo.withdraw_type == 'wechatpay'">微信默认钱包</view>
<view class="tx-bank" v-else>{{ bankAccountInfo.bank_account }}</view>
<view class="tx-img" v-if="bankAccountInfo.withdraw_type == 'alipay'">
<image :src="$util.img('public/uniapp/member/apply_withdrawal/alipay.png')" mode="widthFix"></image>
<image :src="$util.img('public/uniapp/member/apply_withdrawal/alipay.png')" mode="widthFix"/>
</view>
<view class="tx-img" v-else-if="bankAccountInfo.withdraw_type == 'bank'">
<image :src="$util.img('public/uniapp/member/apply_withdrawal/bank.png')" mode="widthFix"></image>
<image :src="$util.img('public/uniapp/member/apply_withdrawal/bank.png')" mode="widthFix"/>
</view>
<view class="tx-img" v-else-if="bankAccountInfo.withdraw_type == 'wechatpay'">
<image :src="$util.img('public/uniapp/member/apply_withdrawal/wechatpay.png')" mode="widthFix">
</image>
<image :src="$util.img('public/uniapp/member/apply_withdrawal/wechatpay.png')" mode="widthFix"/>
</view>
</view>
<text class="tx-to" v-else>请添加提现方式</text>
@@ -192,9 +191,7 @@
title: '提现申请成功'
});
setTimeout(() => {
this.$util.redirectTo(
'/pages_tool/member/withdrawal', {},
'redirectTo');
this.$util.redirectTo('/pages_tool/member/withdrawal', {}, 'redirectTo');
}, 1500);
} else {
this.isSub = false;
@@ -228,8 +225,7 @@
title: '提现申请成功'
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/member/withdrawal', {},
'redirectTo');
this.$util.redirectTo('/pages_tool/member/withdrawal', {}, 'redirectTo');
}, 1500);
} else {
this.isSub = false;
@@ -246,41 +242,15 @@
}
},
goAccount() {
this.$util.redirectTo(
'/pages_tool/member/account', {
back: '/pages_tool/member/apply_withdrawal'
},
'redirectTo'
);
this.$util.redirectTo('/pages_tool/member/account', {
back: '/pages_tool/member/apply_withdrawal'
}, 'redirectTo');
},
/**
* 微信订阅消息
*/
subscribeMessage(callback) {
this.$api.sendRequest({
url: '/weapp/api/weapp/messagetmplids',
data: {
keywords: 'USER_WITHDRAWAL_SUCCESS'
},
success: res => {
if (res.code == 0 && res.data.length) {
uni.requestSubscribeMessage({
tmplIds: res.data,
fail: res => {
console.log('fail', res);
},
complete: () => {
callback();
}
});
} else {
callback();
}
},
fail: res => {
callback();
}
});
this.$util.subscribeMessage('USER_WITHDRAWAL_SUCCESS', callback);
}
},
};

View File

@@ -79,172 +79,182 @@
</template>
<script>
export default {
data() {
return {
accountInfo: {},
member_info: {},
fenxiao_info: {}
};
},
onLoad(option) {
if (option.back) this.back = option.back;
// 判断登录
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
} else {
this.getAccountInfo();
}
},
methods: {
getAccountInfo() {
this.$api.sendRequest({
url: '/membercancel/api/membercancel/accountInfo',
success: res => {
if (res.code >= 0) {
this.accountInfo = res.data;
this.member_info = res.data.member_info;
if (res.data.member_info.is_fenxiao == 1) {
this.fenxiao_info = res.data.fenxiao_info;
export default {
data() {
return {
member_info: {
point: 0,
balance_money: '0.00',
balance: '0.00'
},
accountInfo: {
member_coupon_count: 0,
order_pay_count: 0,
order_delivery_count: 0,
order_refund_count: 0
},
fenxiao_info: {
account: '0.00',
account_withdraw_apply: '0.00',
fenxiao_order_count: 0
}
};
},
onLoad(option) {
// 判断登录
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
} else {
this.getAccountInfo();
}
},
methods: {
getAccountInfo() {
this.$api.sendRequest({
url: '/membercancel/api/membercancel/accountInfo',
success: res => {
if (res.code >= 0) {
this.accountInfo = res.data;
this.member_info = res.data.member_info;
if (res.data.member_info.is_fenxiao == 1) {
this.fenxiao_info = res.data.fenxiao_info;
}
}
}
}
});
},
prev() {
this.$util.redirectTo('/pages_tool/member/cancellation');
},
submit() {
uni.showModal({
title: '风险提示',
content: '确定要注销当前账号吗?',
confirmColor: '#000000',
success: res => {
if (res.confirm) {
this.$api.sendRequest({
url: '/membercancel/api/membercancel/apply',
success: rres => {
let cancellation_condition = rres.data.is_audit;
if (rres.code >= 0) {
this.$util.redirectTo('/pages_tool/member/cancelstatus');
} else {
this.$util.showToast({
title: rres.message
});
});
},
prev() {
this.$util.redirectTo('/pages_tool/member/cancellation');
},
submit() {
uni.showModal({
title: '风险提示',
content: '确定要注销当前账号吗?',
confirmColor: '#000000',
success: res => {
if (res.confirm) {
this.$api.sendRequest({
url: '/membercancel/api/membercancel/apply',
success: rres => {
let cancellation_condition = rres.data.is_audit;
if (rres.code >= 0) {
this.$util.redirectTo('/pages_tool/member/cancelstatus');
} else {
this.$util.showToast({
title: rres.message
});
}
}
}
});
});
}
}
}
});
});
}
}
}
};
};
</script>
<style lang="scss" scoped>
.assets-wrap {
.assets-block {
padding: 0 24rpx;
padding-top: 30rpx;
}
.assets-tips {
width: 100%;
height: 56rpx;
background-color: rgba(250, 106, 0, 0.2);
border-radius: 6rpx;
line-height: 56rpx;
padding-left: 20rpx;
box-sizing: border-box;
text {
color: #fa6a00;
font-size: 28rpx;
.assets-wrap {
.assets-block {
padding: 0 24rpx;
padding-top: 30rpx;
}
}
.assets-box {
width: 100%;
margin-top: 30rpx;
background-color: #ffffff;
border-radius: 6rpx;
padding: 20rpx;
box-sizing: border-box;
.assets-tips {
width: 100%;
height: 56rpx;
background-color: rgba(250, 106, 0, 0.2);
border-radius: 6rpx;
line-height: 56rpx;
padding-left: 20rpx;
box-sizing: border-box;
.assets-title {
display: flex;
align-items: center;
text:nth-child(1) {
width: 6rpx;
height: 28rpx;
border-radius: 2rpx;
}
text:nth-child(2) {
margin-left: 20rpx;
text {
color: #fa6a00;
font-size: 28rpx;
line-height: 28rpx;
padding-top: 8rpx;
font-weight: 600;
}
}
.assets-list {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
padding: 0 26rpx 35rpx;
margin-top: 53rpx;
.assets-box {
width: 100%;
margin-top: 30rpx;
background-color: #ffffff;
border-radius: 6rpx;
padding: 20rpx;
box-sizing: border-box;
.assets-li {
text-align: center;
.assets-title {
display: flex;
align-items: center;
view:nth-child(1) {
font-size: 36rpx;
line-height: 36rpx;
text:nth-child(1) {
width: 6rpx;
height: 28rpx;
border-radius: 2rpx;
}
view:nth-child(2) {
text:nth-child(2) {
margin-left: 20rpx;
font-size: 28rpx;
line-height: 28rpx;
color: #666666;
margin-top: 30rpx;
padding-top: 8rpx;
font-weight: 600;
}
}
.assets-list {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
padding: 0 26rpx 35rpx;
margin-top: 53rpx;
.assets-li {
text-align: center;
view:nth-child(1) {
font-size: 36rpx;
line-height: 36rpx;
}
view:nth-child(2) {
font-size: 28rpx;
line-height: 28rpx;
color: #666666;
margin-top: 30rpx;
}
}
}
}
}
.assets-btn {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
width: 100%;
height: 150rpx;
.assets-btn {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
width: 100%;
height: 150rpx;
button {
width: 300rpx;
height: 80rpx;
font-size: 28rpx;
line-height: 80rpx;
margin: 0 15rpx;
}
button {
width: 300rpx;
height: 80rpx;
font-size: 28rpx;
line-height: 80rpx;
margin: 0 15rpx;
}
button[type='primary'] {
background-color: unset !important;
color: #333333;
border: 2rpx solid #dddddd;
}
button[type='primary'] {
background-color: unset !important;
color: #333333;
border: 2rpx solid #dddddd;
}
button:nth-child(2) {
color: var(--btn-text-color);
button:nth-child(2) {
color: var(--btn-text-color);
}
}
}
}
</style>
</style>

View File

@@ -2,24 +2,20 @@
<page-meta :page-style="themeColor"></page-meta>
<view class="balance">
<!-- #ifdef MP-WEIXIN -->
<view class="custom-navbar" :style="{
'padding-top': menuButtonBounding.top + 'px',
'height': menuButtonBounding.height + 'px'
}">
<view class="custom-navbar" :style="{ 'padding-top': menuButtonBounding.top + 'px', 'height': menuButtonBounding.height + 'px' }">
<view class="navbar-wrap">
<text class="iconfont icon-back_light back" @click="$util.redirectTo('/pages/member/index')"></text>
<view class="navbar-title">
账户余额
我的余额
</view>
</view>
</view>
<!-- #endif -->
<view class="head-wrap" :style="{ background: 'url(' + $util.img('public/uniapp/balance/balance-bg.png') + ')',backgroundSize:'100% 100%' }">
<!-- <view class="head-wrap" :style="{ background: 'url(' + $util.img('public/uniapp/balance/balance-bg.png') + ') no-repeat right bottom/ auto 380rpx, linear-gradient(314deg, #FE7849 0%, #FF1959 100%)' }"> -->
<view class="title">账户余额</view>
<view class="head-wrap" :style="{ background: 'url(' + $util.img('public/uniapp/balance/balance_bg.png') + ') no-repeat right bottom/ auto 340rpx, linear-gradient(314deg, #FE7849 0%, #FF1959 100%)' }">
<view class="balance price-font">{{ (parseFloat(balanceInfo.balance) + parseFloat(balanceInfo.balance_money)).toFixed(2) }}</view>
<!-- <view class="flex-box">
<view class="title">账户余额</view>
<view class="flex-box">
<view class="flex-item">
<view class="num price-font">{{ balanceInfo.balance_money|moneyFormat }}</view>
<view class="font-size-tag">现金余额</view>
@@ -28,45 +24,34 @@
<view class="num price-font">{{ balanceInfo.balance|moneyFormat }}</view>
<view class="font-size-tag">储值余额</view>
</view>
</view> -->
<view class="btns">
<view class="cash btn" @click="toWithdrawal">提现</view>
<view class="recharge btn" @click="toList">充值</view>
</view>
</view>
<view class="menu-wrap">
<view class="menu-item" @click="toApply" style="border-bottom: 0.5px solid #f2f2f2;">
<view class="icon">
<text class="iconfont icon-yuemingxi"></text>
</view>
<text class="title">提现记录</text>
<text class="iconfont icon-right"></text>
</view>
<view class="menu-item" @click="toBalanceDetail" style="border-bottom: 0.5px solid #f2f2f2;">
<view class="menu-item" @click="toBalanceDetail">
<view class="icon">
<text class="iconfont icon-yuemingxi"></text>
</view>
<text class="title">余额明细</text>
<text class="iconfont icon-right"></text>
</view>
<!-- <view class="menu-item" @click="toOrderList">
<view class="menu-item" @click="toOrderList" v-if="addonIsExist.memberrecharge && memberrechargeConfig && memberrechargeConfig.is_use">
<view class="icon">
<text class="iconfont icon-chongzhijilu"></text>
</view>
<text class="title">充值记录</text>
<text class="iconfont icon-right"></text>
</view> -->
</view>
</view>
<!-- <view class="action">
<view class="action">
<view @click="toList" class="recharge-withdraw" v-if="addonIsExist.memberrecharge && memberrechargeConfig && memberrechargeConfig.is_use">
{{ $lang('recharge') }}
</view>
<view class="withdraw" v-if="addonIsExist.memberwithdraw && withdrawConfig && withdrawConfig.is_use" @click="toWithdrawal">
{{ $lang('withdrawal') }}
</view>
</view> -->
</view>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
</view>
@@ -111,9 +96,6 @@ export default {
toBalanceDetail() {
this.$util.redirectTo('/pages_tool/member/balance_detail');
},
toApply(){
this.$util.redirectTo('/pages_tool/member/withdrawal');
},
toList() {
this.$util.redirectTo('/pages_tool/recharge/list');
},

View File

@@ -6,11 +6,11 @@
<text class="uni-tab-item-title" :class="statusIndex == orderStatus ? 'uni-tab-item-title-active' : ''">{{ statusItem.name }}</text>
</view>
</scroll-view> -->
<!-- <view class="tab color-bg">
<view class="tab color-bg">
<view class="tab-left">
<picker mode="date" :value="searchType.date" @change="bindDateChange" fields="month">
<picker :range="monthData" :value="monthIndex" @change="bindDateChange" >
<view class="uni-input">
{{ date }}
{{ monthData[monthIndex] }}
<text class="iconfont icon-iconangledown"></text>
</view>
</picker>
@@ -21,22 +21,22 @@
<text class="iconfont icon-iconangledown"></text>
</picker>
</view>
</view> -->
<mescroll-uni @getData="getData" ref="mescroll">
</view>
<mescroll-uni @getData="getData" ref="mescroll" v-if="monthData.length">
<block slot="list">
<!-- 明细列表 -->
<block v-if="dataList.length > 0">
<view class="detailed-wrap">
<view class="balances" v-for="(item, index) in dataList" :key="index">
<image :src="$util.img('public/uniapp/balance/recharge.png')" class="balances-img" v-if="item.account_data > 0"></image>
<image v-else :src="$util.img('public/uniapp/balance/shopping.png')" mode="widthFix"></image>
<!-- <image :src="$util.img('public/uniapp/member/balance_detail/income.png')" class="balances-img" v-if="item.account_data > 0"></image>
<image v-else :src="$util.img('public/uniapp/member/balance_detail/pay.png')" mode="widthFix"></image> -->
<view class="balances-info" @click="toFromDetail(item)">
<text class="title">{{ item.remark }}</text>
<!-- <text>{{ item.remark }}</text> -->
<text class="title">{{ item.type_name }}</text>
<text>{{ item.remark }}</text>
<text>{{ $util.timeStampTurnTime(item.create_time) }}</text>
</view>
<view class="balances-num">
<text :class="item.account_data > 0 ? 'color-base-text' : ''">{{ item.account_data > 0 ? '+' + item.account_data : item.account_data }}</text>
<text :class="item.account_data > 0 ? 'color-base-text' : ''">{{ item.account_data > 0 ? '+' + item.account_data : item.account_data }}</text>
</view>
</view>
</view>
@@ -53,9 +53,6 @@
<script>
export default {
data() {
const currentDate = this.getDate({
format: true
});
return {
dataList: [],
statusList: [{
@@ -70,7 +67,6 @@
}],
scrollInto: '',
orderStatus: '0',
date: currentDate,
searchType: {
from_type: 0,
date: ''
@@ -80,7 +76,9 @@
value: '0'
}], //积分类型
balanceIndex: 0,
related_id: 0
related_id: 0,
monthData:[],
monthIndex:0,
};
},
components: {},
@@ -90,6 +88,7 @@
if (option.related_id) this.related_id = option.related_id ? option.related_id : 0;
if (option.status) this.orderStatus = option.status;
this.getbalanceType();
this.getMonthData();
},
onShow() {
if (!this.storeToken) {
@@ -100,26 +99,19 @@
},
methods: {
bindDateChange: function(e) {
var temp = e.target.value;
var tempArr = temp.split('-');
this.date = tempArr[0] + '年' + tempArr[1] + '月';
this.searchType.date = e.target.value;
var index = e.target.value;
this.monthIndex = index;
this.searchType.date = this.monthData[index];
this.$refs.mescroll.refresh();
},
getDate(type) {
const date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
if (type === 'start') {
year = year - 60;
} else if (type === 'end') {
year = year + 2;
}
month = month > 9 ? month : '0' + month;
day = day > 9 ? day : '0' + day;
return `${year}${month}`;
getMonthData(){
this.$api.sendRequest({
url: '/api/memberaccount/monthData',
success: res => {
this.monthData = res.data;
this.searchType.date = res.data[0];
}
});
},
bindPickerChange(e) {
this.balanceIndex = e.detail.value;
@@ -204,9 +196,8 @@
<style lang="scss">
.detailed-wrap {
padding-top: 20rpx;
margin: 24rpx;
padding-top: 80rpx;
background: #fff;
}
.tab {
@@ -295,20 +286,17 @@
}
.balances {
padding: $margin-both 24rpx;
// margin: 0 $margin-both;
padding: $margin-both 0;
margin: 0 $margin-both;
box-sizing: border-box;
display: flex;
align-items: flex-start;
border-bottom: 2rpx solid $color-line;
background: #fff;
margin-bottom: 20rpx;
border-radius: 24rpx;
image {
width: 54rpx;
height: 54rpx;
border-radius: 50%;
padding-top: 10rpx;
}
.balances-info {
@@ -342,8 +330,6 @@
line-height: 1;
font-size: $font-size-toolbar;
font-weight: 500;
color:#09c15f;
font-weight: 700;
}
}
}

View File

@@ -4,7 +4,8 @@
<view class="agreement-box">
<view class="agreement-intro">
<view class="align-center agreement-title">{{ agreement.title }}</view>
<rich-text class="agreement-content" :nodes="agreement.content"></rich-text>
<!-- <rich-text class="agreement-content" :nodes="agreement.content"></rich-text> -->
<ns-mp-html class="agreement-content" :content="agreement.content"></ns-mp-html>
</view>
<view class="agreement-btn">
@@ -29,7 +30,6 @@ export default {
};
},
onLoad(option) {
if (option.back) this.back = option.back;
// 判断登录
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
@@ -44,7 +44,7 @@ export default {
success: res => {
if (res.code >= 0) {
this.agreement = res.data;
if (this.agreement.content) this.agreement.content = htmlParser(this.agreement.content);
// if (this.agreement.content) this.agreement.content = htmlParser(this.agreement.content);
}
}
});
@@ -66,6 +66,10 @@ export default {
</script>
<style lang="scss" scoped>
/deep/ .agreement-content view{
font-size: 24rpx;
line-height: 44rpx;
}
.agreement-box {
.align-center {
text-align: center;

View File

@@ -15,16 +15,12 @@
<script>
export default {
components: {},
data() {
return {
reason: ''
};
},
onLoad(option) {
if (option.back) this.back = option.back;
// 判断登录
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');

View File

@@ -20,9 +20,7 @@
<view class="cancelstatus-box-line color-base-bg" :class="{ 'opacity-4': state == 0 }"></view>
</view>
<view class="cancelstatus-box cancelstatus-box-last">
<view class="cancelstatus-box-sort color-base-bg" :class="[ state == 1 ? 'opacity': 'opacity-4' ]">
3
</view>
<view class="cancelstatus-box-sort color-base-bg" :class="[ state == 1 ? 'opacity': 'opacity-4' ]">3</view>
<view class="cancelstatus-box-con">
<view class="cancelstatus-box-name">审核通过注销完成</view>
<view class="cancelstatus-box-info">您已成功注销账号期待下一次与您相遇</view>
@@ -64,16 +62,15 @@
this.state = res.data.status;
if (this.state == -1) {
this.$util.redirectTo('/pages_tool/member/cancelrefuse');
} else if(this.state == 1){
this.$store.commit('setToken', '');
this.$store.commit('setMemberInfo', '');
this.$store.dispatch('emptyCart');
//uni.removeStorageSync('authInfo');
this.$util.redirectTo('/pages/index/index');
}
}
if (res.code == -1) {
this.$store.commit('setToken', '');
this.$store.commit('setMemberInfo', '');
this.$store.commit('setMemberInfo', '');
this.$store.dispatch('emptyCart');
this.$util.redirectTo('/pages/index/index');
}
}
});
},

View File

@@ -14,38 +14,24 @@
<script>
export default {
components: {},
data() {
return {
state: ''
};
return {};
},
onLoad(option) {
if (option.back) this.back = option.back;
// 判断登录
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
} else {
this.getStatus();
this.init();
}
},
methods: {
getStatus() {
this.$api.sendRequest({
success: res => {
if (res.code >= 0) {
this.state = res.data.state;
if (res.data.state == 1) {
this.$store.commit('setToken', '');
this.$store.commit('setMemberInfo', '');
this.$store.dispatch('emptyCart');
this.$util.redirectTo('/pages/index/index');
}
}
}
});
init() {
this.$store.commit('setToken', '');
this.$store.commit('setMemberInfo', '');
this.$store.dispatch('emptyCart');
//uni.removeStorageSync('authInfo');
this.$util.redirectTo('/pages/index/index');
}
}
};

View File

@@ -10,8 +10,7 @@
<image :src="$util.getDefaultImage().head" v-else mode="aspectFill"/>
<view class="member-desc">
<view class="font-size-toolbar">{{ memberInfo.nickname }}</view>
<view class="font-size-tag expire-time" v-if="memberInfo.level_expire_time > 0">
有效期至{{ $util.timeStampTurnTime(memberInfo.level_expire_time, true) }}</view>
<view class="font-size-tag expire-time" v-if="memberInfo.level_expire_time > 0">有效期至{{ $util.timeStampTurnTime(memberInfo.level_expire_time) }}</view>
</view>
</view>

View File

@@ -2,7 +2,10 @@
<page-meta :page-style="themeColor"></page-meta>
<view class="page">
<view class="agreement-title">{{ title }}</view>
<view class="agreement-content"><rich-text :nodes="content"></rich-text></view>
<view class="agreement-content">
<!-- <rich-text :nodes="content"></rich-text> -->
<ns-mp-html :content="content"></ns-mp-html>
</view>
</view>
</template>
@@ -26,7 +29,8 @@ export default {
success: res => {
if (res.data && res.code == 0) {
this.title = res.data.title;
this.content = htmlParser(res.data.content);
// this.content = htmlParser(res.data.content);
this.content = res.data.content;
uni.setNavigationBarTitle({
title: this.title
});

View File

@@ -11,9 +11,7 @@
<image :src="$util.getDefaultImage().head" v-else mode="aspectFill"></image>
<view class="member-desc">
<view class="font-size-toolbar">{{ memberInfo.nickname }}</view>
<view class="font-size-tag expire-time" v-if="memberInfo.level_expire_time > 0">
有效期至{{ $util.timeStampTurnTime(memberInfo.level_expire_time, true) }}
</view>
<view class="font-size-tag expire-time" v-if="memberInfo.level_expire_time > 0">有效期至{{ $util.timeStampTurnTime(memberInfo.level_expire_time) }}</view>
</view>
</view>
<swiper :style="{ width: '100vw', height: '390rpx' }" class="margin-bottom"
@@ -26,21 +24,25 @@
<swiper-item :class="levelList.length == 1 ? 'image-container-box' : ''" v-for="(item, i) in levelList" :key="i">
<view class="image-container" :class="[
curIndex === 0
? i === listLen - 1
? 'item-left'
: i === 1
? i === 1
? 'item-right'
: i === listLen - 1
? 'item-left'
: 'item-center'
: curIndex === listLen - 1
? i === 0
? i === curIndex - 1
? 'item-left'
: i === curIndex + 1
? 'item-right'
: i === 0
? 'item-right'
: i === listLen - 2
? 'item-left'
: 'item-center'
: i === curIndex - 1
? 'item-left'
: i === curIndex + 1
? 'item-right'
? 'item-left'
: i === curIndex + 1
? 'item-right'
: 'item-center'
]">
<view class="slide-image" style="background-size: 100% 100%;background-repeat:no-repeat"
@@ -51,14 +53,14 @@
}">
<view class="bg-border"></view>
<image v-if="levelList[curIndex] && levelList[curIndex]['level_picture']" :src="$util.img(levelList[curIndex]['level_picture'])"/>
<image v-else :style="{backgroundColor:levelList[curIndex]['bg_color']}"/>
<image v-if="item && item['level_picture']" :src="$util.img(item['level_picture'])"/>
<image v-else :style="{backgroundColor:item['bg_color']}"/>
<view class="info">
<view class="level-detail" :style="{color:levelList[curIndex]['level_text_color']}">{{ levelList[curIndex].level_name }}</view>
<view class="growr-name" :style="{color:levelList[curIndex]['level_text_color']}">{{ levelList[curIndex].level_name }}可享受消费折扣和</view>
<view class="growr-value" :style="{color:levelList[curIndex]['level_text_color']}">会员大礼包等权益</view>
<view class="growth-rules font-size-tag" @click="openExplainPopup" v-if="levelList[curIndex].remark != ''">
<view class="level-detail" :style="{color:item['level_text_color']}">{{ item.level_name }}</view>
<view class="growr-name" :style="{color:item['level_text_color']}">{{ item.level_name }}可享受消费折扣和</view>
<view class="growr-value" :style="{color:item['level_text_color']}">会员大礼包等权益</view>
<view class="growth-rules font-size-tag" @click="openExplainPopup" v-if="item.remark != ''">
<text class="iconfont icon-wenhao font-size-tag"></text>
</view>
</view>
@@ -93,8 +95,7 @@
</view>
</view>
<view class="card-content"
v-if="currCard.is_free_shipping || currCard.consume_discount < 100 || currCard.point_feedback > 0">
<view class="card-content" v-if="currCard.is_free_shipping || currCard.consume_discount < 100 || currCard.point_feedback > 0">
<view class="card-content-head">
<view class="line-box">
<view class="line right"></view>

View File

@@ -2,7 +2,8 @@
<page-meta :page-style="themeColor"></page-meta>
<view class="contact">
<image :src="$util.img('public/uniapp/member/contact_service.png')" mode="widthFix"></image>
<!--<ns-contact><button type="primary">联系客服</button></ns-contact>-->
<view class="tips">请点击下方按钮联系客服</view>
<ns-contact><button type="primary">联系客服</button></ns-contact>
</view>
</template>
@@ -20,10 +21,18 @@ export default {
<style lang="scss">
.contact {
width: 80%;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
margin: 0 auto;
margin: 150rpx auto 0;
image {
width: 500rpx;
}
.tips{
font-size: 24rpx;
color: #999;
margin-bottom: 20rpx;
}
}
</style>

View File

@@ -15,7 +15,7 @@
</view> -->
</view>
<mescroll-uni ref="mescroll" top="100" @getData="getMemberCounponList" v-if="storeToken">
<mescroll-uni ref="mescroll" top="100" @getData="getMemberCouponList" v-if="storeToken">
<block slot="list">
<view class="coupon-listone">
<view class="item" :class="['item',item.state != 1&&'item-disabled']" v-for="(item, index) in list" :key="index" @click="toGoodsList(item)" :style="{ backgroundColor: item.state != 1 ? '#FFF' : 'var(--main-color-shallow)' }">
@@ -42,12 +42,12 @@
<view class="item-info">
<view class="use_title">
<view class="title">{{ item.coupon_name }}</view>
<view class="max_price" v-if="item.goods_type == 2 || item.goods_type == 3" :class="{ disabled: item.state == 3 }">指定商品</view>
<view class="max_price" :class="{ disabled: item.state == 3 }">{{item.goods_type_name}}</view>
<view class="max_price" v-if="item.discount_limit != '0.00'">(最大优惠{{ item.discount_limit }})</view>
<view class="max_price" :class="{ disabled: item.useState == 2 }">{{ item.use_channel_name }}</view>
<!-- <view class="max_price truncate" v-if="item.use_channel!='online'" :class="{ disabled: item.useState == 2 }">
<view class="max_price truncate" v-if="item.use_channel!='online'" :class="{ disabled: item.useState == 2 }">
{{ item.use_store==='all'?'适用门店全部门店': '适用门店'+item.use_store_name}}
</view> -->
</view>
</view>
<view class="use_time" v-if="item.end_time">有效期{{ $util.timeStampTurnTime(item.end_time) }}
</view>
@@ -65,7 +65,7 @@
</view>
</block>
</mescroll-uni>
<ns-login ref="ns-login"></ns-login>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
@@ -97,7 +97,7 @@
}, 2000);
}
},1000);
if(data.state) this.state = data.state;
if (data.related_id) this.related_id = data.related_id ? data.related_id : 0;
this.isIphoneX = this.$util.uniappIsIPhoneX();
},
@@ -123,7 +123,7 @@
this.types = types;
this.$refs.mescroll.refresh(false);
},
getMemberCounponList(mescroll) {
getMemberCouponList(mescroll) {
this.showEmpty = false;
this.$api.sendRequest({
url: '/coupon/api/coupon/memberpage',

View File

@@ -162,11 +162,9 @@ export default {
},
goodsImg(imgStr) {
let imgs = imgStr.split(',');
return imgs[0]
? this.$util.img(imgs[0], {
size: 'mid'
})
: this.$util.getDefaultImage().goods;
return imgs[0] ? this.$util.img(imgs[0], {
size: 'mid'
}) : this.$util.getDefaultImage().goods;
},
imgError(index) {
dateList = [];

View File

@@ -2,88 +2,86 @@
<page-meta :page-style="themeColor"></page-meta>
<view>
<view v-if="indent == 'all' && memberInfo" class="info-wrap">
<!-- 头像@click="headImage" -->
<view class="info-list-cell info-item info-list-con" hover-class="cell-hover">
<text class="cell-tit">头像</text>
<!-- 头像 -->
<view @click="headImage" class="info-list-cell info-item info-list-con" hover-class="cell-hover">
<text class="cell-tit">{{ $lang('headImg') }}</text>
<view class="info-list-head cell-tip">
<image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head" @error="memberInfo.headimg = $util.getDefaultImage().head" mode="aspectFill" />
</view>
<text style="margin-right: 20rpx;"></text>
<text class="cell-more"></text>
</view>
<!-- 账号 -->
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover" v-if="memberInfo.is_edit_username == 1" @click="modifyInfo('username')">
<text class="cell-tit">账号</text>
<view class="info-list-cell info-list-con" hover-class="cell-hover" v-if="memberInfo.is_edit_username == 1" @click="modifyInfo('username')">
<text class="cell-tit">{{ $lang('account') }}</text>
<text class="cell-tip">{{ memberInfoformData.number }}</text>
<text class="cell-more"></text>
</view> -->
</view>
<!-- 账号 -->
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover" v-else>
<view class="info-list-cell info-list-con" hover-class="cell-hover" v-else>
<text class="cell-tit">{{ $lang('account') }}</text>
<text class="cell-tip cell-tip1">{{ memberInfoformData.number }}</text>
</view> -->
</view>
<!-- 昵称 -->
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('name')">
<text class="cell-tit">昵称</text>
<text class="cell-tit">{{ $lang('nickname') }}</text>
<text class="cell-tip">{{ memberInfoformData.nickName }}</text>
<text class="cell-more"></text>
</view>
<!-- 真实姓名 -->
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('realName')">
<text class="cell-tit">姓名</text>
<text class="cell-tit">{{ $lang('realName') }}</text>
<text class="cell-tip">{{ memberInfoformData.realName }}</text>
<text class="cell-more"></text>
</view>
<!-- 性别 -->
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('sex')">
<text class="cell-tit">性别</text>
<text class="cell-tit">{{ $lang('sex') }}</text>
<text class="cell-tip">{{ memberInfoformData.sex }}</text>
<text class="cell-more"></text>
</view>
<!-- 生日 -->
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('birthday')">
<text class="cell-tit">生日</text>
<text class="cell-tit">{{ $lang('birthday') }}</text>
<text class="cell-tip">{{ memberInfoformData.birthday }}</text>
<text class="cell-more"></text>
</view>
<!-- 手机号 -->
<view class="info-list-cell info-list-con" @click="modifyInfo('mobile')">
<text class="cell-tit">手机号</text>
<text v-if="memberInfoformData.user_tel == ''" class="cell-tip">密码</text>
<text class="cell-tit">{{ $lang('mobilePhone') }}</text>
<text v-if="memberInfoformData.user_tel == ''" class="cell-tip">{{ $lang('bindMobile') }}</text>
<text v-else class="cell-tip">{{ memberInfoformData.mobile }}</text>
<text class="cell-more"></text>
</view>
<!-- 密码 -->
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('password')">
<text class="cell-tit">密码</text>
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('password')">
<text class="cell-tit">{{ $lang('password') }}</text>
<!-- <text class="cell-tip">{{ memberInfo.password ? $lang('modify') : $lang('noset') }}</text> -->
<text class="cell-more"></text>
</view> -->
</view>
<!-- 支付密码 -->
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('paypassword')">
<text class="cell-tit">{{ $lang('paypassword') }}</text>
<text class="cell-more"></text>
</view> -->
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('address')">
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('address')">
<text class="cell-tit">所在地址</text>
<text class="cell-tip" v-if="memberInfo.full_address">{{ memberInfo.full_address }}
{{ memberInfo.address }}</text>
<text class="cell-tip" v-else>去设置</text>
<text class="cell-more"></text>
</view> -->
</view>
<!-- 注销 -->
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="cancellation()">
<text class="cell-tit">注销账号</text>
<view class="info-list-cell info-list-con" hover-class="cell-hover" @click="modifyInfo('cancellation')" v-if="addonIsExist.membercancel && memberConfig.is_enable == 1">
<text class="cell-tit">{{ $lang('cancellation') }}</text>
<!-- <text class="cell-tip">{{ $lang('modify') }}</text> -->
<text class="cell-more"></text>
</view>
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover" @click="cancellation()" v-if="addonIsExist.membercancel && memberConfig.is_enable == 1">
<text class="cell-tit">注销账号</text>
<text class="cell-more"></text>
</view> -->
<!-- <view class="info-list-cell info-list-con" hover-class="cell-hover">
<view class="info-list-cell info-list-con" hover-class="cell-hover">
<text class="cell-tit">版本号</text>
<text class="cell-tip cell-tip1">{{ version }}</text>
</view> -->
</view>
<!-- 语言 -->
<!-- <view class="info-list-cell info-item info-list-con" hover-class="cell-hover" @click="modifyInfo('language')">
@@ -99,7 +97,7 @@
<!-- #endif -->
<view class="save-item" @click="logout">
<button type="primary">退出登录</button>
<button type="primary">{{ $lang('logout') }}</button>
</view>
</view>
@@ -294,6 +292,7 @@
button {
font-size: 30rpx;
border-radius: 90rpx;
}
}

View File

@@ -5,38 +5,38 @@
<!-- 修改用户名 -->
<view v-if="indent == 'username'" class="edit-info">
<view class="edit-info-box">
<text class="info-name">用户名</text>
<input class="uni-input info-content input-len" type="text" maxlength="30" placeholder="请输入" v-model="formData.username" />
<text class="info-name">{{ $lang('username') }}</text>
<input class="uni-input info-content input-len" type="text" maxlength="30" :placeholder="$lang('usernamePlaceholder')" v-model="formData.username" />
</view>
<view class="color-tip font-size-goods-tag set-pass-tips">用户名仅可修改一次请谨慎设置</view>
<view class="save-item" @click="save('username')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
<!-- 修改昵称 -->
<view v-if="indent == 'name'" class="edit-info">
<view class="edit-info-box">
<text class="info-name">昵称</text>
<input class="uni-input info-content input-len" type="text" maxlength="30" placeholder="请输入" v-model="formData.nickName" />
<text class="info-name">{{ $lang('nickname') }}</text>
<input class="uni-input info-content input-len" type="text" maxlength="30" :placeholder="$lang('nickPlaceholder')" v-model="formData.nickName" />
</view>
<view class="save-item" @click="save('name')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
<!-- 修改真实姓名 -->
<view v-if="indent == 'realName'" class="edit-info">
<view class="edit-info-box">
<text class="info-name">姓名</text>
<input class="uni-input info-content input-len" type="text" maxlength="30" placeholder="请输入" v-model="formData.realName" />
<text class="info-name">{{ $lang('realName') }}</text>
<input class="uni-input info-content input-len" type="text" maxlength="30" :placeholder="$lang('pleaseRealName')" v-model="formData.realName" />
</view>
<view class="save-item" @click="save('realName')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
<!-- 修改性别 -->
<view v-if="indent == 'sex'" class="edit-info">
<view class="edit-info-box">
<text class="info-name">性别</text>
<text class="info-name">{{ $lang('sex') }}</text>
<radio-group @change="radioChange" class="edit-sex-list">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" :key="item.value">
<view>
@@ -47,19 +47,19 @@
</radio-group>
</view>
<view class="save-item" @click="save('sex')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
<!-- 修改生日 -->
<view v-if="indent == 'birthday'" class="edit-info edit-birthday-list">
<view class="edit-info-box">
<text class="info-name">生日</text>
<text class="info-name">{{ $lang('birthday') }}</text>
<picker mode="date" :value="formData.birthday" :start="startDate" :end="endDate" @change="bindDateChange">
<view class="uni-input">{{ formData.birthday ? formData.birthday : '请选择生日' }}</view>
</picker>
</view>
<view class="save-item" @click="save('birthday')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
<!-- 修改密码 -->
@@ -75,55 +75,55 @@
</block>
<block v-else>
<view class="edit-info-box" v-if="memberInfo.password">
<text class="info-name">原密码</text>
<input class="uni-input info-content input-len" type="password" maxlength="30" placeholder="请输入" v-model="formData.currentPassword" />
<text class="info-name">{{ $lang('nowPassword') }}</text>
<input class="uni-input info-content input-len" type="password" maxlength="30" :placeholder="$lang('nowPassword')" v-model="formData.currentPassword" />
</view>
<block v-else>
<view class="edit-info-box">
<text class="info-name">新密码</text>
<input class="uni-input info-content" type="number" maxlength="4" placeholder="请输入" v-model="formData.mobileVercode" />
<text class="info-name">{{ $lang('confirmCode') }}</text>
<input class="uni-input info-content" type="number" maxlength="4" :placeholder="$lang('confirmCode')" v-model="formData.mobileVercode" />
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image>
</view>
<view class="edit-info-box">
<text class="info-name">再次输入</text>
<input class="uni-input info-content" type="number" maxlength="6" placeholder="请输入" v-model="formData.mobileDynacode" />
<text class="info-name">{{ $lang('animateCode') }}</text>
<input class="uni-input info-content" type="number" maxlength="6" :placeholder="$lang('animateCode')" v-model="formData.mobileDynacode" />
<button type="primary" class="dynacode" @click="passwordMoblieCode()">{{ formData.mobileCodeText }}</button>
</view>
<view class="color-tip font-size-goods-tag set-pass-tips">
点击获取动态码将会向您已绑定的手机号{{ memberInfoformData.mobile | mobile }}发送验证码</view>
</block>
<view class="edit-info-box">
<text class="info-name">新密码</text>
<input class="uni-input info-content input-len" type="password" maxlength="30" placeholder="请输入" v-model="formData.newPassword" />
<text class="info-name">{{ $lang('newPassword') }}</text>
<input class="uni-input info-content input-len" type="password" maxlength="30" :placeholder="$lang('newPassword')" v-model="formData.newPassword" />
</view>
<view class="edit-info-box">
<text class="info-name">再次输入</text>
<input class="uni-input info-content input-len" type="password" maxlength="30" placeholder="请输入" v-model="formData.confirmPassword" />
<text class="info-name">{{ $lang('confirmPassword') }}</text>
<input class="uni-input info-content input-len" type="password" maxlength="30" :placeholder="$lang('confirmPassword')" v-model="formData.confirmPassword" />
</view>
<view class="save-item" @click="save('password')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</block>
</view>
<!-- 修改手机号 -->
<view v-if="indent == 'mobile'" class="edit-info">
<view class="edit-info-box">
<text class="info-name">手机号</text>
<input class="uni-input info-content" type="number" maxlength="11" placeholder="请输入" v-model="formData.mobile" />
<text class="info-name">{{ $lang('phoneNumber') }}</text>
<input class="uni-input info-content" type="number" maxlength="11" :placeholder="$lang('phoneNumber')" v-model="formData.mobile" />
</view>
<view class="edit-info-box">
<text class="info-name">验证码</text>
<input class="uni-input info-content" type="number" maxlength="4" placeholder="请输入" v-model="formData.mobileVercode" />
<text class="info-name">{{ $lang('confirmCode') }}</text>
<input class="uni-input info-content" type="number" maxlength="4" :placeholder="$lang('confirmCode')" v-model="formData.mobileVercode" />
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image>
</view>
<view class="edit-info-box">
<text class="info-name">短信验证码</text>
<input class="uni-input info-content" type="number" maxlength="6" placeholder="请输入" v-model="formData.mobileDynacode" />
<button type="primary" class="dynacode" @click="bindMoblieCode()">{{ formData.mobileCodeText }}</button>
<text class="info-name">{{ $lang('animateCode') }}</text>
<input class="uni-input info-content" type="number" maxlength="6" :placeholder="$lang('animateCode')" v-model="formData.mobileDynacode" />
<button type="primary" class="dynacode" @click="bindMobileCode()">{{ formData.mobileCodeText }}</button>
</view>
<view class="save-item" @click="save('mobile')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
<!-- 绑定手机号 -->
@@ -149,7 +149,7 @@
<input class="uni-input info-content" type="text" placeholder="详细地址" v-model="formData.address" />
</view>
<view class="save-item" @click="save('address')">
<button type="primary">保存</button>
<button type="primary">{{ $lang('save') }}</button>
</view>
</view>
</template>

View File

@@ -22,7 +22,7 @@
<block v-if="inviteList.length > 0">
<view class="invitelist_block">
<view class="invitelist">
<view class="list-item" v-for="(item, index) in inviteList">
<view class="list-item" v-for="(item, index) in inviteList" :key="index">
<view class="img color-base-border">
<image mode="aspectFit" :src="item.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(item.headimg)"/>
</view>
@@ -37,8 +37,7 @@
<block v-if="item.balance > 0">{{ item.balance }}元现金红包</block>
<block v-if="(item.point > 0 || item.coupon_num) && item.balance > 0">+</block>
<block v-if="item.point > 0">{{ parseInt(item.point) }}积分</block>
<block v-if="item.point > 0 && item.balance > 0 && item.coupon_num > 0">+
</block>
<block v-if="item.point > 0 && item.balance > 0 && item.coupon_num > 0">+</block>
<block v-if="item.coupon_num > 0">{{ item.coupon_num }}张优惠券</block>
</view>
</view>
@@ -98,24 +97,24 @@
<view class="desc">
<view class="title_desc color-tip">分享给好友让好友通过你的分享链接进入并注册登录可获得以下奖励</view>
<view class="desc_list">
<view class="" v-if="$util.inArray('balance', info.type) != -1">
<view v-if="$util.inArray('balance', info.type) != -1">
<text></text>
可得{{ info.balance }}元红包奖励
</view>
<view class="" v-if="$util.inArray('point', info.type) != -1">
<view v-if="$util.inArray('point', info.type) != -1">
<text></text>
可得{{ info.point }}积分
</view>
<view class="" v-if="$util.inArray('coupon', info.type) != -1">
<view v-if="$util.inArray('coupon', info.type) != -1">
<text></text>
可得{{ info.coupon.split(',').length }}张优惠券
</view>
<view class="" v-if="info.max_fetch == 0">
<view v-if="info.max_fetch == 0">
<text></text>
可得奖励不受限制
</view>
<view class="" v-else>
<view v-else>
<text></text>
奖励上限为{{ info.max_fetch }}
</view>

View File

@@ -23,25 +23,28 @@
:interval="swiperConfig.interval" :duration="swiperConfig.duration" :circular="swiperConfig.circular"
:previous-margin="swiperConfig.previousMargin" :next-margin="swiperConfig.nextMargin"
@change="swiperChange" @animationfinish="animationfinish" :current="curIndex">
<swiper-item :class="levelList.length == 1 ? 'image-container-box' : ''" v-for="(item, i) in levelList"
:key="i">
<swiper-item :class="levelList.length == 1 ? 'image-container-box' : ''" v-for="(item, i) in levelList" :key="i">
<view class="image-container" :class="[
curIndex === 0
? i === listLen - 1
? 'item-left'
: i === 1
? i === 1
? 'item-right'
: i === listLen - 1
? 'item-left'
: 'item-center'
: curIndex === listLen - 1
? i === 0
? i === curIndex - 1
? 'item-left'
: i === curIndex + 1
? 'item-right'
: i === 0
? 'item-right'
: i === listLen - 2
? 'item-left'
: 'item-center'
: i === curIndex - 1
? 'item-left'
: i === curIndex + 1
? 'item-right'
? 'item-left'
: i === curIndex + 1
? 'item-right'
: 'item-center'
]">
<view class="slide-image" style="background-size: 100% 100%;background-repeat:no-repeat" :style="{
@@ -49,34 +52,35 @@
transitionDuration: '.3s',
transitionTimingFunction: 'ease'
}">
<image v-if="levelList[curIndex]['level_picture']" :src="$util.img(levelList[curIndex]['level_picture'])"/>
<image v-else :style="{backgroundColor:levelList[curIndex]['bg_color']}"/>
<image v-if="item['level_picture']" :src="$util.img(item['level_picture'])"/>
<image v-else :style="{backgroundColor:item['bg_color']}"/>
<view class="info">
<view class="level-detail" :style="{color:levelList[curIndex]['level_text_color']}">
{{ levelList[curIndex].level_name }}
<text class="isnow " :style="{color:levelList[curIndex]['level_text_color']}" v-if="levelId == item.level_id">当前等级</text>
<view class="level-detail" :style="{color:item['level_text_color']}">
{{ item.level_name }}
<text class="isnow " :style="{color:item['level_text_color']}" v-if="levelId == item.level_id">当前等级</text>
</view>
<view class="growr-name" :style="{color:levelList[curIndex]['level_text_color']}">当前成长值</view>
<view class="growr-value" :style="{color:levelList[curIndex]['level_text_color']}">{{ growth }}</view>
<view class="growr-name" :style="{color:item['level_text_color']}">当前成长值</view>
<view class="growr-value" :style="{color:item['level_text_color']}">{{ growth }}</view>
<block v-if="levelId == item.level_id">
<block v-if="levelList[curIndex + 1] != undefined">
<ns-progress :progress="levelList[curIndex + 1].rate"></ns-progress>
<view class="residue-growr-value"
:style="{color:levelList[curIndex]['level_text_color']}">
再获得{{ levelList[curIndex + 1].needGrowth > 0 ? levelList[curIndex + 1].needGrowth : 0 }}成长值成为{{
<block v-if="levelList[i + 1] != undefined">
<ns-progress :progress="levelList[i + 1].rate"></ns-progress>
<view class="residue-growr-value" :style="{color:item['level_text_color']}">
再获得{{ levelList[i + 1].needGrowth > 0 ? levelList[i + 1].needGrowth : 0 }}成长值成为下一等级
<!-- {{
levelList[curIndex + 1].level_name
}}
}} -->
</view>
</block>
<block v-else>
<view class="residue-growr-value" :style="{color:levelList[curIndex]['level_text_color']}">您现在已经是最高等级</view>
<view class="residue-growr-value" :style="{color:item['level_text_color']}">您现在已经是最高等级</view>
</block>
</block>
<block v-else>
<ns-progress :progress="levelList[curIndex].rate" v-if="levelList[curIndex].needGrowth > 0"></ns-progress>
<view class="residue-growr-value" v-if="levelList[curIndex].needGrowth > 0" :style="{color:levelList[curIndex]['level_text_color']}">
再获得{{ levelList[curIndex].needGrowth }}成长值成为{{ levelList[curIndex].level_name }}
<ns-progress :progress="item.rate" v-if="item.needGrowth > 0"></ns-progress>
<view class="residue-growr-value" v-if="item.needGrowth > 0" :style="{color:item['level_text_color']}">
再获得{{ item.needGrowth }}成长值成为当前等级
<!-- {{ levelList[curIndex].level_name }} -->
</view>
</block>
</view>
@@ -97,7 +101,7 @@
<image :src="$util.img('public/uniapp/level/consumption_discount.png')" mode="aspectFit"></image>
<view class="equity-content" :class="{ active: levelList[curIndex].point_feedback > 0 }">
<text>享受消费折扣服务</text>
<text class="equity-desc" v-if="levelList[curIndex].is_default == 1">不享受任何消费折扣和其他权益</text>
<text class="equity-desc" v-if="levelList[curIndex].consume_discount == 10">不享受任何消费折扣</text>
<text class="equity-desc" v-else>提供{{ levelList[curIndex].consume_discount }}折消费折扣</text>
</view>
</view>
@@ -220,7 +224,6 @@
}
},
nextIndex() {
let num = 0;
if (this.curIndex == this.levelList.length - 1) {
return this.curIndex;
} else {
@@ -287,8 +290,7 @@
this.levelList = res.data;
for (var i = 0; i < this.levelList.length; i++) {
if (this.levelList[i].send_coupon) {
this.levelList[i].coupon_length = this.levelList[i].send_coupon.split(',')
.length;
this.levelList[i].coupon_length = this.levelList[i].send_coupon.split(',').length;
}
}
this.levelId = this.memberInfo.member_level;
@@ -306,8 +308,7 @@
v.needGrowth = 0;
v.rate = 100;
} else {
v.needGrowth = (parseFloat(v.growth) - parseFloat(this.growth))
.toFixed(2);
v.needGrowth = (parseFloat(v.growth) - parseFloat(this.growth)).toFixed(2);
v.rate = (this.growth / v.growth).toFixed(2) * 100;
}
});

View File

@@ -44,12 +44,9 @@
},
onShow() {
if (!this.storeToken) {
this.$util.redirectTo(
'/pages_tool/login/login', {
back: '/pages_tool/member/modify_face'
},
'redirectTo'
);
this.$util.redirectTo('/pages_tool/login/login', {
back: '/pages_tool/member/modify_face'
}, 'redirectTo');
return;
}
@@ -75,7 +72,8 @@
data: {
app_type: app_type,
app_type_name: app_type_name,
images: rsp.base64
images: rsp.base64,
token: this.$store.state.token || '',
},
header: {
'content-type': 'application/x-www-form-urlencoded;application/json'

View File

@@ -136,8 +136,7 @@
title: '修改成功'
});
setTimeout(() => {
if (this.back) this.$util.redirectTo(this.back, {},
'redirectTo');
if (this.back) this.$util.redirectTo(this.back, {}, 'redirectTo');
else this.$util.redirectTo('/pages/member/index');
}, 2000);
} else {
@@ -164,7 +163,6 @@
this.step = 1;
this.password = '';
this.repassword = '';
this.oldpassword = '';
this.isSub = false;
this.$refs.input.clear();
},

View File

@@ -2,16 +2,10 @@
<page-meta :page-style="themeColor"></page-meta>
<view class="point">
<!-- #ifdef MP-WEIXIN -->
<view class="custom-navbar" :style="{
'padding-top': menuButtonBounding.top + 'px',
'height': menuButtonBounding.height + 'px'
}"
>
<view class="custom-navbar" :style="{ 'padding-top': menuButtonBounding.top + 'px', 'height': menuButtonBounding.height + 'px' }">
<view class="navbar-wrap">
<text class="iconfont icon-back_light back" @click="$util.redirectTo('/pages/member/index')"></text>
<view class="navbar-title">
我的积分
</view>
<view class="navbar-title">我的积分</view>
</view>
</view>
<!-- #endif -->
@@ -49,7 +43,7 @@
<text class="title">积分商城</text>
</view>
</view>
<!--
<view class="task-wrap">
<view class="title">做任务赚积分</view>
<view class="task-item" @click="toSign">
@@ -68,7 +62,7 @@
</view>
<view class="btn">去下单</view>
</view>
</view> -->
</view>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
@@ -124,19 +118,6 @@ export default {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
/**
* 获取充值提现配置
*/
getMemberrechargeConfig() {
this.$api.sendRequest({
url: '/memberrecharge/api/memberrecharge/config',
success: res => {
if (res.code >= 0 && res.data) {
this.memberrechargeConfig = res.data;
}
}
});
}
},
onBackPress(options) {

View File

@@ -1,11 +1,11 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<!-- <view class="tab color-bg">
<view class="tab color-bg">
<view class="tab-left">
<picker mode="date" :value="searchType.date" @change="bindDateChange" fields="month">
<picker :range="monthData" :value="monthIndex" @change="bindDateChange" >
<view class="uni-input">
{{ date }}
{{ monthData[monthIndex] }}
<text class="iconfont icon-iconangledown"></text>
</view>
</picker>
@@ -16,7 +16,7 @@
<text class="iconfont icon-iconangledown"></text>
</picker>
</view>
</view> -->
</view>
<mescroll-uni @getData="getData" class="member-point" ref="mescroll">
<view slot="list">
@@ -48,15 +48,11 @@
<script>
export default {
data() {
const currentDate = this.getDate({
format: true
});
return {
memberAccount: {
point: 0
},
dataList: [],
date: currentDate,
searchType: {
from_type: 0,
date: ''
@@ -68,47 +64,39 @@ export default {
}
], //积分类型
pointIndex: 0,
related_id: 0
related_id: 0,
monthData:[],
monthIndex:0,
};
},
onShow() {
if (!this.storeToken) {
this.$util.redirectTo(
'/pages_tool/login/login',
{
back: '/pages_tool/member/point'
},
'redirectTo'
);
this.$util.redirectTo('/pages_tool/login/login', {
back: '/pages_tool/member/point'
}, 'redirectTo');
}
},
onLoad(option) {
if (option.related_id) this.related_id = option.related_id ? option.related_id : 0;
if (option.from_type) this.searchType.from_type = option.from_type;
this.getPointType();
this.getMonthData();
},
methods: {
bindDateChange: function(e) {
var temp = e.target.value;
var tempArr = temp.split('-');
this.date = tempArr[0] + '年' + tempArr[1] + '月';
this.searchType.date = e.target.value;
var index = e.target.value;
this.monthIndex = index;
this.searchType.date = this.monthData[index];
this.$refs.mescroll.refresh();
},
getDate(type) {
const date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
if (type === 'start') {
year = year - 60;
} else if (type === 'end') {
year = year + 2;
}
month = month > 9 ? month : '0' + month;
day = day > 9 ? day : '0' + day;
return `${year}${month}`;
getMonthData(){
this.$api.sendRequest({
url: '/api/memberaccount/monthData',
success: res => {
this.monthData = res.data;
this.searchType.date = res.data[0];
}
});
},
bindPickerChange(e) {
this.pointIndex = e.detail.value;
@@ -148,22 +136,9 @@ export default {
if (res.code >= 0) {
var data = res.data;
if (data.type == 1 && data.relate_order_id) {
switch (data.delivery_type) {
case 'store':
this.$util.redirectTo('/pages/order/detail_pickup', {
order_id: data.relate_order_id
});
break;
case 'local':
this.$util.redirectTo('/pages/order/detail_local_delivery', {
order_id: data.relate_order_id
});
break;
default:
this.$util.redirectTo('/pages/order/detail', {
order_id: data.relate_order_id
});
}
this.$util.redirectTo('/pages/order/detail', {
order_id: data.relate_order_id
});
} else {
this.$util.redirectTo('/pages/order/detail_point', {
order_id: data.order_id
@@ -276,7 +251,7 @@ export default {
background: #fff;
position: relative;
z-index: 9;
padding-top: 20rpx;
padding-top: 80rpx;
.head {
display: flex;

View File

@@ -39,23 +39,21 @@
}
.head-wrap {
// width: 100vw;
width: 100vw;
background-size: 100%;
padding: 32rpx 28rpx;
padding: 60rpx 68rpx 140rpx 68rpx;
box-sizing: border-box;
// border-radius: 0 0 100% 100%/0 0 70rpx 70rpx;
border-radius: 0 0 100% 100%/0 0 70rpx 70rpx;
overflow: hidden;
margin: 24rpx 28rpx;
border-radius: 24rpx;
// #ifdef MP-WEIXIN
padding-top: 160rpx;
// #endif
height: 352rpx;
.title {
text-align: left;
line-height: 1;
color: #F6F6F6;
margin-bottom: 24rpx;
}
.balance {
@@ -63,12 +61,7 @@
text-align: left;
line-height: 1;
margin-bottom: 20rpx;
// font-size: 64rpx;
font-size: 80rpx;
line-height: 112rpx;
font-weight: 500 !important;
font-family: PingFang SC;
font-size: 64rpx;
}
.flex-box {
@@ -94,65 +87,19 @@
}
}
}
.btns{
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: nowrap;
flex-wrap: nowrap;
position: relative;
gap: 22rpx;
margin-top: 32rpx;
.btn{
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
display: -webkit-box;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
height: 80rpx;
box-sizing: border-box;
font-size: 32rpx;
-webkit-flex-shrink: 0;
flex-shrink: 0;
text-align: center;
font-family: PingFang SC;
border-radius: 180rpx;
background: transparent;
color: #fff;
font-style: normal;
font-weight: 500;
line-height: normal;
border: 2rpx solid #fff;
:nth-child(2) {
background: #fff;
color: #4285f8;
}
}
.recharge{
background: #fff;
color: #4285f8;
}
}
}
.menu-wrap {
border-radius: 20rpx;
margin: 0 24rpx;
padding: 0 24rpx;
padding: 0 30rpx;
background: #fff;
// transform: translateY(-90rpx);
transform: translateY(-90rpx);
.menu-item {
display: flex;
align-items: center;
padding: 4rpx 0;
padding: 12rpx 0;
.icon {
height: 80rpx;

View File

@@ -15,10 +15,9 @@ export default {
//请求数据
getData(mescroll) {
this.isShowEmpty = false;
let url = "/api/goodscollect/page"
let array = []
this.$api.sendRequest({
url: url,
url: '/api/goodscollect/page',
data: {
page_size: mescroll.size,
page: mescroll.num,

View File

@@ -184,22 +184,20 @@ export default {
this.memberInfoformData.nickName = this.memberInfo.nickname; //昵称
this.memberInfoformData.realName = this.memberInfo.realname ? this.memberInfo.realname : '请输入真实姓名'; //真实姓名
this.memberInfoformData.sex = this.memberInfo.sex == 0 ? '未知' : this.memberInfo.sex == 1 ? '男' : '女'; //性别
this.memberInfoformData.birthday = this.memberInfo.birthday ? this.$util.timeStampTurnTime(this.memberInfo.birthday, 'YYYY-MM-DD') : '请选择生日'; //生日
this.memberInfoformData.birthday = this.memberInfo.birthday ? this.$util.timeStampTurnTime(this.memberInfo.birthday, 'Y-m-d') : '请选择生日'; //生日
this.memberInfoformData.mobile = this.memberInfo.mobile; //手机号
this.formData.username = this.memberInfo.username; //用户名
this.formData.nickName = this.memberInfo.nickname; //昵称
this.formData.realName = this.memberInfo.realname; //真实姓名
this.formData.sex = this.memberInfo.sex; //性别
this.formData.birthday = this.memberInfo.birthday ? this.$util.timeStampTurnTime(this.memberInfo.birthday, 'YYYY-MM-DD') : ''; //生日
this.formData.birthday = this.memberInfo.birthday ? this.$util.timeStampTurnTime(this.memberInfo.birthday, 'Y-m-d') : ''; //生日
this.formData.provinceId = this.memberInfo.province_id;
this.formData.cityId = this.memberInfo.city_id;
this.formData.districtId = this.memberInfo.district_id;
this.formData.fullAddress = this.memberInfo.full_address;
this.formData.address = this.memberInfo.address;
if (this.memberInfo.full_address) this.defaultRegions = [this.memberInfo
.province_id, this.memberInfo.city_id, this.memberInfo.district_id
];
if (this.memberInfo.full_address) this.defaultRegions = [this.memberInfo.province_id, this.memberInfo.city_id, this.memberInfo.district_id];
},
// 切换编辑项
modifyInfo(action) {
@@ -239,35 +237,6 @@ export default {
});
}
},
cancellation() {
uni.showModal({
title: '风险提示',
content: '确定要注销当前账号吗?',
confirmColor: '#000000',
success: res => {
if (res.confirm) {
this.$api.sendRequest({
url: '/membercancel/api/membercancel/apply',
success: rres => {
let cancellation_condition = rres.data.is_audit;
if (rres.code >= 0) {
this.$store.commit('setToken', '');
this.$store.commit('setMemberInfo', '');
this.$store.dispatch('emptyCart');
this.$store.dispatch('emptyCart');
uni.removeStorageSync('authInfo');
this.$util.redirectTo('/pages/member/index');
} else {
this.$util.showToast({
title: rres.message
});
}
}
});
}
}
});
},
getCancelStatus() {
this.$api.sendRequest({
url: '/membercancel/api/membercancel/info',
@@ -288,7 +257,7 @@ export default {
});
}
} else {
this.$util.redirectTo('/pages_tool/member/assets', {
this.$util.redirectTo('/pages_tool/member/cancellation', {
back: '/pages_tool/member/info'
});
}
@@ -327,8 +296,7 @@ export default {
this.$store.commit('setToken', '');
this.$store.commit('setMemberInfo', '');
this.$store.dispatch('emptyCart');
this.$store.dispatch('emptyCart');
uni.removeStorageSync('authInfo');
// uni.removeStorageSync('authInfo');
this.$util.redirectTo('/pages/member/index');
}
}
@@ -616,30 +584,25 @@ export default {
name: 'currentPassword',
checkType: 'required',
errorMsg: this.$lang("pleaseInputOldPassword")
},
{
name: 'newPassword',
checkType: 'required',
errorMsg: this.$lang("pleaseInputNewPassword")
}
];
}, {
name: 'newPassword',
checkType: 'required',
errorMsg: this.$lang("pleaseInputNewPassword")
}];
} else {
var rule = [{
name: 'mobileVercode',
checkType: 'required',
errorMsg: this.$lang("confirmCodeInput")
},
{
name: 'mobileDynacode',
checkType: 'required',
errorMsg: this.$lang("animateCodeInput")
},
{
name: 'newPassword',
checkType: 'required',
errorMsg: this.$lang("pleaseInputNewPassword")
}
];
}, {
name: 'mobileDynacode',
checkType: 'required',
errorMsg: this.$lang("animateCodeInput")
}, {
name: 'newPassword',
checkType: 'required',
errorMsg: this.$lang("pleaseInputNewPassword")
}];
}
let regConfig = this.registerConfig;
@@ -725,7 +688,7 @@ export default {
// ------------------------修改手机号------------------------------
// 验证手机号
vertifyMobile() {
verifyMobile() {
var rule = [{
name: 'mobile',
checkType: 'required',
@@ -746,7 +709,7 @@ export default {
},
// 检测手机号是否存在
async checkMobile() {
if (!this.vertifyMobile()) return;
if (!this.verifyMobile()) return;
let res = await this.$api.sendRequest({
url: '/api/member/checkmobile',
data: {
@@ -764,7 +727,7 @@ export default {
},
// 发送短信动态码
async bindMoblieCode() {
async bindMobileCode() {
if (this.seconds != 120) return;
var rule = [{
name: 'mobile',

View File

@@ -52,7 +52,7 @@ export default {
},
copyUrl() {
let text = this.$config.h5Domain + '/pages/index/index';
if (this.memberInf && this.memberInfo.member_id) text += '?source_member=' + this.memberInfo.member_id;
if (this.memberInfo && this.memberInfo.member_id) text += '?source_member=' + this.memberInfo.member_id;
this.$util.copy(text, () => {
this.closeSharePopup();
});

View File

@@ -52,8 +52,7 @@ export default {
}
this.headimg = this.memberInfo.headimg;
this.signDaysSeries = this.memberInfo.sign_days_series;
this.getMemberInfo();
this.getSignPointData();
this.getSignGrowthData();
this.setPublicShare();
@@ -61,6 +60,16 @@ export default {
this.getIsSign();
},
methods: {
getMemberInfo(){
this.$api.sendRequest({
url: '/api/member/info',
success: (res) => {
if (res.code >= 0) {
this.signDaysSeries = res.data.sign_days_series;
}
}
});
},
// 获取签到累积积分
getSignPointData() {
this.$api.sendRequest({

View File

@@ -0,0 +1,569 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="signin">
<block v-if="signState">
<!-- #ifdef H5 -->
<view class="head-nav color-base-bg"></view>
<!-- #endif -->
<view class="sigin-box">
<view class="sigin-bg"></view>
<view class="signin-wrap">
<view class="member-info">
<view class="headimg">
<view class="headimg-img">
<image :src="headimg ? $util.img(headimg) : $util.getDefaultImage().head" mode="aspectFill" @error="headimg = $util.getDefaultImage().head"/>
</view>
<view class="signin-info">
<view>
已连续签到
<text>{{ signDaysSeries }}</text>
</view>
<view>{{ hasSign ? '明日' : '今日' }}签到可获得{{ pointTomorrow }}积分</view>
</view>
</view>
<view class="point-box" @click="sign()">
<image :src="$util.img(hasSign == 1 ? 'public/uniapp/signin/sign-btn-res.png' : 'public/uniapp/signin/sign-btn.png')" mode="widthFix"/>
</view>
</view>
<view class="signin-days-wrap">
<view class="signin-desc">连续签到领好礼</view>
<view class="signin-day-list">
<view class="signin-day-con">
<view class="signin-day-scroll">
<block v-for="(item, index) in showSignDays">
<view v-if="!item.is_last" :id="'id_' + item.day" class="signin-day-item"
:class="{
signed: item.day < signDaysSeries || (item.day == signDaysSeries && hasSign == 0) || (item.day == signDaysSeries && hasSign == 1)
}">
<view class="day">{{ item.day }}</view>
<image :src="$util.img('public/uniapp/signin/sign-icon.png')"></image>
<view class="point">{{ item.point }}积分</view>
</view>
<view v-else :id="'id_' + item.day" class="signin-day-item last" :class="{
signed: item.day < signDaysSeries || (item.day == signDaysSeries && hasSign == 0) || (item.day == signDaysSeries && hasSign == 1)
}">
<view>
<view class="day">{{ item.day }}</view>
<view class="point">{{ item.point }}积分</view>
</view>
<image :src="$util.img('public/uniapp/signin/sign-box.png')" mode="widthFix"/>
</view>
</block>
</view>
</view>
</view>
</view>
<view class="my-signin">
<view class="my-signin-title">我的签到</view>
<view class="my-signin-con">
<view class="my-signin-item">
<image :src="$util.img('public/uniapp/signin/sign-bg-yellow.png')"></image>
<view class="my-signin-item-num">积分{{ signPoint }}</view>
<view>累计获得积分</view>
</view>
<view class="my-signin-item">
<image :src="$util.img('public/uniapp/signin/sign-bg-pink.png')"></image>
<view class="my-signin-item-num">成长值{{ signGrowth }}</view>
<view>累计获得成长值</view>
</view>
</view>
</view>
<view class="signin-rule" v-if="rule && rule.length">
<view class="signin-rule-title">签到规则</view>
<view class="signin-rule-con">
<view class="rule-item" v-for="(item, index) in rule" :key="index">
<block v-if="index == 0">1. 每日签到奖励</block>
<block v-else>{{ index + 1 + '. 连续签到' + item.day + '天额外奖励' }}</block>
<text v-if="item.point">{{ item.point + '积分 ' }}</text>
<text v-if="item.growth">{{ item.growth + '成长值' }}</text>
</view>
<view class="rule-item">
{{ rule.length + 1 }}.连续签到{{ cycle }}天为一个周期连续签到天数签满一个周期或者签到中断将清空连签天数重新计算签到天数
</view>
<view class="rule-item">
{{ rule.length + 2 }}. 用户可在签到页每日签到一次签到后可获得每日签到奖励连续签到天数达到连签奖励的当天可额外获得连签奖励
</view>
</view>
</view>
</view>
</view>
<view @touchmove.prevent.stop>
<uni-popup ref="uniPopup" type="center" class="wap-floating" :maskClick="false">
<view class="popup-box" @click="close()">
<text class="iconfont icon-close" @click="$refs.uniPopup.close()"></text>
<image class="pic" :src="$util.img('public/uniapp/signin/bg1.png')"></image>
<view class="popup-content">
<view class="popup-content-wrap">
<view class="title" v-if="successTip.point || successTip.growth">
<text>恭喜您获得</text>
<text v-if="successTip.point">
<text class="num color-base-text">{{ successTip.point }}</text>
积分
</text>
<text v-if="successTip.growth">
<text class="num color-base-text">{{ successTip.growth }}</text>
成长值
</text>
</view>
<view class="desc">连续签到可获得更多奖励</view>
</view>
<view class="other-info color-base-bg" @click="$refs.uniPopup.close()">知道了</view>
</view>
</view>
</uni-popup>
</view>
<!-- 悬浮按钮 -->
<hover-nav :need="true"></hover-nav>
</block>
<block v-else><ns-empty text="暂未开启签到奖励" subText="请到营销中心开启签到奖励" :isIndex="false"></ns-empty></block>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import uniCalender from '@/pages_tool/components/uni-calendar/uni-calendar.vue';
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import signIn from './public/js/signin.js';
export default {
components: {
uniPopup,
uniCalender
},
mixins: [signIn]
};
</script>
<style lang="scss">
uni-page-body,
uni-page-refresh {
height: 100%;
}
.signin {
position: relative;
height: 100%;
.head-nav {
width: 100%;
height: var(--status-bar-height);
}
.head-nav.active {
padding-top: 40rpx;
}
.sigin-box {
position: relative;
}
.sigin-bg {
width: 100%;
position: absolute;
top: 0;
z-index: 1;
background: linear-gradient(136deg, #fe7849 0%, #ff1959 100%);
height: 500rpx;
border-radius: 0 0 100% 100%/0 0 20% 20%;
image {
width: 100%;
}
}
.signin-wrap {
padding: 0 30rpx;
}
.member-info {
position: relative;
z-index: 9;
padding: 74rpx 0 55rpx;
display: flex;
align-items: center;
justify-content: space-between;
.headimg {
display: flex;
align-items: center;
.headimg-img {
width: 100rpx;
height: 100rpx;
background: #fff;
border: 0px solid #fff;
border-radius: 50%;
overflow: hidden;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.signin-info {
view {
color: #ffffff;
font-size: 24rpx;
line-height: 1;
&:first-child {
margin-bottom: 18rpx;
font-size: 32rpx;
font-weight: bold;
text {
margin: 0 9rpx;
}
}
}
}
}
.point-box {
display: flex;
align-items: center;
height: 68rpx;
padding: 13rpx 0 13rpx 0;
box-sizing: border-box;
image {
width: 160rpx;
height: 68rpx;
max-height: 80rpx;
margin-bottom: -6rpx;
}
.point {
margin-left: 14rpx;
font-size: $font-size-toolbar;
color: #ffffff;
}
}
}
.signin-days-wrap {
position: relative;
z-index: 9;
background-color: #ffffff;
border-radius: 18rpx;
padding: 30rpx 0 30rpx;
height: 468rpx;
.signin-desc {
font-size: 32rpx;
font-weight: bold;
line-height: 1;
padding: 0 30rpx;
}
.signin-day-list {
margin-top: 30rpx;
display: flex;
justify-content: space-between;
padding: 0 30rpx;
.signin-day-con {
width: 100%;
}
.signin-day-scroll {
display: flex;
flex-wrap: wrap;
width: 100%;
flex-direction: row;
white-space: nowrap;
line-height: 1;
.signin-day-item {
flex-shrink: 0;
background: #f5f6fa;
margin-right: 30rpx;
width: calc((100% - 90rpx) / 4);
height: 155rpx;
border-radius: 18rpx;
margin-bottom: 24rpx;
&:last-child {
margin-right: 0;
width: calc((100% - 30rpx) / 2);
}
&:nth-child(4n) {
margin-right: 0;
}
image {
width: 60rpx;
height: 60rpx;
margin-top: 10rpx;
}
&.signed {
background: linear-gradient(136deg, #fe7849 0%, #ff1959 100%);
view {
color: #ffffff;
}
}
&.last {
display: flex;
flex-direction: row;
>view {
width: 50%;
.point {
margin: 15rpx;
}
}
image {
width: 40%;
margin-top: 20rpx;
max-width: 130rpx;
}
}
}
.reward {
image {
width: 100%;
height: 100%;
margin-top: 0;
}
}
}
.signin-day-item {
display: inline-block;
width: 85rpx;
height: 103rpx;
border-radius: 4rpx;
text-align: center;
background-color: #f6f6fb;
flex-shrink: 0;
.day {
font-size: 24rpx;
line-height: 1;
margin-top: 18rpx;
font-weight: bold;
}
.point {
font-size: 20rpx;
line-height: 1;
margin-top: -4rpx;
color: #abb0c1;
}
image {
width: 100%;
height: 100%;
}
}
}
.signin-btn {
position: absolute;
width: 100%;
height: 80rpx;
bottom: 40rpx;
text-align: center;
button {
display: inline-block;
width: 442rpx;
height: 100%;
color: #ffffff;
background-color: #ff4544;
}
.btn-active {
color: $color-title;
background-color: #e1e1e1;
}
}
}
.my-signin {
padding: 30rpx;
margin-top: 30rpx;
background-color: #ffffff;
border-radius: 18rpx;
.my-signin-title {
font-size: 32rpx;
line-height: 1;
font-weight: bold;
}
.my-signin-con {
display: flex;
justify-content: space-between;
margin-top: 30rpx;
}
.my-signin-item {
width: 300rpx;
height: 155rpx;
position: relative;
image {
width: 300rpx;
height: 155rpx;
position: absolute;
top: 0;
left: 0;
}
.my-signin-item-num {
position: relative;
z-index: 9;
padding: 44rpx 28rpx 0;
line-height: $font-size-toolbar;
font-weight: bold;
}
view:last-child {
position: relative;
z-index: 9;
color: #abb0c1;
padding-left: 28rpx;
font-size: $font-size-activity-tag;
line-height: 1;
margin-top: 16rpx;
}
}
}
.signin-rule {
margin-top: 30rpx;
background-color: #ffffff;
border-radius: 18rpx;
padding: 30rpx;
.signin-rule-title {
display: flex;
align-items: center;
justify-content: flex-start;
line-height: $font-size-toolbar;
font-size: 32rpx;
font-weight: bold;
text-align: left;
}
.signin-rule-con {
margin-top: 30rpx;
padding: 0 0;
.rule-item {
font-size: 26rpx;
color: $color-sub;
}
}
}
}
.popup-box {
position: relative;
top: 0;
display: flex;
flex-direction: column;
align-items: center;
.icon-close {
width: 42rpx;
height: 42rpx;
border: 1px solid #fff;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
color: #fff;
position: absolute;
top: 70rpx;
right: 0;
}
.pic {
width: 274rpx;
height: 200rpx;
position: relative;
margin-bottom: -30rpx;
}
.popup-content {
background: #ffffff;
width: 70vw;
margin-top: -100rpx;
border-radius: 20rpx;
padding: 0 60rpx;
padding-bottom: 40rpx;
box-sizing: border-box;
background-size: 100% 100rpx;
}
.popup-content-wrap {
display: flex;
flex-direction: column;
align-items: center;
.title {
font-size: $font-size-base;
margin-top: 160rpx;
color: #999;
.num {
font-size: 32rpx;
}
}
.desc {
color: #999;
font-size: $font-size-tag;
}
}
.other-info {
width: 300rpx;
height: 70rpx;
border-radius: 10rpx;
margin: 0 auto;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
margin-top: 40rpx;
}
}
</style>
<style scoped>
.wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none !important;
display: flex !important;
flex-direction: column !important;
align-items: center !important;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view>
<mescroll-uni @getData="getData" class="member-point">
<mescroll-uni @getData="getData" ref="mescroll" class="member-point">
<view slot="list">
<block v-if="dataList.length">
<view class="detailed-wrap">
@@ -15,8 +15,29 @@
</view>
<view class="right-wrap">
<view class="num color-base-text">{{ item.apply_money }}</view>
<view class="status-name">{{ item.status_name }}</view>
<!-- #ifdef H5 -->
<view class="actions" v-if="$util.isWeiXin() && isWithdrawWechat && item.transfer_type == 'wechatpay' && item.status == 1" @click.stop="toTransfer(item.id)">
<view class="act-btn">收款</view>
</view>
<view class="status-name" v-else :style="item.status == -1 || item.status == -2 ? 'color:red;' : ''">{{ item.status_name }}</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="actions" v-if="isWithdrawWechat && item.transfer_type == 'wechatpay' && item.status == 1" @click.stop="toTransfer(item.id)">
<view class="act-btn">收款</view>
</view>
<view class="status-name" v-else :style="item.status == -1 || item.status == -2 ? 'color:red;' : ''">{{ item.status_name }}</view>
<!-- #endif -->
</view>
<view v-if="item.status == -1" class="fail-reason">
拒绝原因{{ item.refuse_reason }}
</view>
<view v-if="item.status == -2" class="fail-reason">
失败原因{{ item.fail_reason }}
</view>
</view>
</view>
</view>
@@ -34,21 +55,36 @@
export default {
data() {
return {
dataList: []
dataList: [],
isWithdrawWechat: 0
};
},
onShow() {
if (!this.storeToken) {
this.$util.redirectTo(
'/pages_tool/login/login',
{
back: '/pages_tool/member/point'
},
'redirectTo'
);
this.$util.redirectTo('/pages_tool/login/login', {
back: '/pages_tool/member/point'
}, 'redirectTo');
}
if(this.$refs.mescroll) this.$refs.mescroll.refresh();
this.getWithdrawConfig()
},
methods: {
toTransfer(id) {
this.$util.redirectTo('/pages_tool/member/withdrawal_detail', {
id: id,
action: 'transfer'
});
},
getWithdrawConfig() {
this.$api.sendRequest({
url: '/wechatpay/api/transfer/getWithdrawConfig',
success: res => {
if (res.code == 0){
this.isWithdrawWechat = res.data.transfer_type;
}
},
});
},
//获得列表数据
getData(mescroll) {
this.$api.sendRequest({
@@ -165,6 +201,22 @@ export default {
font-size: $font-size-toolbar;
}
}
.fail-reason{
font-size: $font-size-base;
color:$color-tip;
}
.actions{
display: flex;
justify-content: flex-end;
.act-btn{
color: #fff;
background-color: $base-color;
font-size: $font-size-base;
line-height: 1;
padding: 10rpx $padding;
border-radius: $border-radius;
}
}
}
}
}

View File

@@ -2,7 +2,7 @@
<page-meta :page-style="themeColor"></page-meta>
<view>
<view class="money-wrap">
<text>-{{ detail.apply_money }}</text>
<text>{{ detail.apply_money }}</text>
</view>
<!-- 状态0待审核1.待转账2已转账 -1拒绝' -->
@@ -48,37 +48,113 @@
<text class="value">{{ $util.timeStampTurnTime(detail.payment_time) }}</text>
</view>
</view>
<!-- #ifdef H5 -->
<view class="operations" v-if="$util.isWeiXin() && withdrawInfo.transfer_type && detail.transfer_type == 'wechatpay' && detail.status == 1">
<button class="operation" type="primary" @click="merchantTransfer()">收款</button>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view class="operations" v-if="withdrawInfo.transfer_type && detail.transfer_type == 'wechatpay' && detail.status == 1">
<button class="operation" type="primary" @click="merchantTransfer()">收款</button>
</view>
<!-- #endif -->
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
export default {
data() {
return {
id: 0,
detail: {}
detail: {},
withdrawInfo: {},
requestCount: 0
};
},
onLoad(option) {
async onLoad(option) {
this.id = option.id || 0;
await this.getWithdrawConfig()
if(option.action) this.merchantTransfer();
},
onShow() {
if (this.storeToken) {
this.getDetail();
} else {
this.$util.redirectTo(
'/pages_tool/login/login',
{
back: '/pages_tool/member/point'
},
'redirectTo'
);
this.$util.redirectTo('/pages_tool/login/login', {
back: '/pages_tool/member/point'
}, 'redirectTo');
}
},
onPullDownRefresh() {
this.getDetail();
},
methods: {
getDetail() {
merchantTransfer() {
uni.showLoading({})
var app_id = ''
// #ifdef MP
app_id = this.withdrawInfo.weapp_appid;
// #endif
// #ifdef H5
if(this.$util.isWeiXin()){
app_id = this.withdrawInfo.wechat_appid;
}
// #endif
this.$util.merchantTransfer(
{
transfer_type: 'member_withdraw',
id: this.id,
},
{
mch_id: this.withdrawInfo.mch_id,
app_id: app_id,
},
(res)=>{
if (res.err_msg === 'requestMerchantTransfer:ok') {
this.updateStatusToInProcess(()=>{
this.getDetail(true);
});
}
// #ifdef MP
if (res.errMsg === 'requestMerchantTransfer:ok') {
this.updateStatusToInProcess(()=>{
this.getDetail(true);
});
}
// #endif
}
);
},
async getWithdrawConfig() {
let res = await this.$api.sendRequest({
url: '/wechatpay/api/transfer/getWithdrawConfig',
async: false,
});
if (res.code == 0){
this.withdrawInfo = res.data;
}
},
//修改收款状态为收款中
updateStatusToInProcess(callback){
if (this.$refs.loadingCover) this.$refs.loadingCover.show();
this.$api.sendRequest({
url: '/wechatpay/api/transfer/inprocess',
data: {
from_type: 'member_withdraw',
relate_tag : this.id,
},
success: (res)=>{
if(res.code >= 0){
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
typeof callback == 'function' && callback();
}
}
});
},
getDetail(is_loop = false) {
this.$api.sendRequest({
url: '/api/memberwithdraw/detail',
data: {
@@ -87,6 +163,22 @@ export default {
success: res => {
if (res.data) {
this.detail = res.data;
if(is_loop && this.requestCount < 10 && this.detail.status == 3){
this.requestCount++;
setTimeout(()=>{
this.getDetail(true)
},1000)
}
// if(mode && this.detail.status == 1){
// // 提现状态还没有修改
// if(this.requestCount < 10 && this.detail.status == 1){
// this.requestCount++;
// setTimeout(()=>{
// this.getDetail('transferComplete')
// },1000)
// }
// }
uni.stopPullDownRefresh();
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
@@ -128,4 +220,30 @@ export default {
}
}
}
.operations {
margin-top: 60rpx;
bottom: 0;
width: 100%;
// background: #fff;
position: fixed;
padding: 0 30rpx;
box-sizing: border-box;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
z-index: 10;
.operation {
height: 80rpx;
line-height: 80rpx;
border-radius: 80rpx;
margin: 30rpx 0 30rpx;
font-size: $font-size-toolbar;
text {
margin-right: 10rpx;
font-size: $font-size-base;
}
}
}
</style>

View File

@@ -5,8 +5,12 @@
<view class="notice-meta">
<text class="notice-time">发表时间: {{ $util.timeStampTurnTime(detail.create_time) }}</text>
</view>
<view class="notice-content"><rich-text :nodes="content"></rich-text></view>
<view class="notice-content">
<!-- <rich-text :nodes="content"></rich-text> -->
<ns-mp-html :content="content"></ns-mp-html>
</view>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
@@ -51,7 +55,8 @@
if (res.code == 0) {
if (res.data) {
this.detail = res.data;
this.content = htmlParser(res.data.content);
// this.content = htmlParser(res.data.content);
this.content = res.data.content;
this.$langConfig.title(this.detail.title);
this.setPublicShare();
@@ -81,8 +86,7 @@
title: this.detail.title,
desc: '',
link: shareUrl,
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) :
''
imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : ''
});
}
},

View File

@@ -10,7 +10,7 @@
<text v-if="item.is_top == 1" class="color-base-bg tag">置顶</text>
<text class="txt using-hidden">{{ item.title }}</text>
</view>
<text class="release-time">{{ $util.timeStampTurnTime(item.create_time, 1) }}</text>
<text class="release-time">{{ $util.timeStampTurnTime(item.create_time, 'Y-m-d') }}</text>
<view class="iconfont icon-right"></view>
</view>
</view>
@@ -19,6 +19,8 @@
<loading-cover ref="loadingCover"></loading-cover>
</block>
</mescroll-uni>
<!-- 悬浮按钮 -->
<hover-nav></hover-nav>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->

View File

@@ -28,10 +28,10 @@
<view class="goods-btn">
<view class="btn-text">
<text>{{ item.num }}件商品</text>
<text>退款{{ item.refund_status == 3 ? item.refund_real_money : item.refund_apply_money }}</text>
<text>退款{{ (Number(item.refund_status == 3 ? item.refund_real_money : item.refund_apply_money) + Number(item.shop_active_refund_money)).toFixed(2) }}</text>
</view>
<view class="order-action">
<view class="order-box-btn" @click="refundDetail(item.order_goods_id)">查看详情</view>
<view class="order-box-btn" @click="refundDetail(item.order_goods_id)">{{ $lang('checkDetail') }}</view>
<block v-if="item.refund_action.length">
<view
class="order-box-btn"
@@ -72,6 +72,7 @@ export default {
back: '/pages_tool/order/activist'
});
}
if(this.$refs.mescroll) this.$refs.mescroll.refresh();
},
methods: {
getListData(mescroll) {
@@ -130,6 +131,11 @@ export default {
order_goods_id: data.order_goods_id
});
break;
case 'orderRefundApply':
this.$util.redirectTo('/pages_tool/order/refund', {
order_goods_id: data.order_goods_id
});
break;
}
},
imageError(index) {

View File

@@ -120,6 +120,54 @@
right: 0;
}
}
.other-info {
width: 100%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
margin-top: $margin-updown;
}
.other-info-box {
width: 145rpx;
height: 145rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-right: 30rpx;
margin-bottom: 30rpx;
position: relative;
image {
width: 100%;
border-radius: $border-radius;
}
.iconfont {
font-size: 60rpx;
color: #898989;
line-height: 1;
}
text {
line-height: 1;
}
.imgDel {
width: 40rpx;
height: 40rpx;
position: absolute;
right: -20rpx;
top: -20rpx;
display: flex;
justify-content: center;
align-items: center;
.iconfont {
font-size: $font-size-toolbar;
}
}
}
.other-info-box.active {
border: 1rpx dashed #898989;
}
}
.textarea-box{
position: relative;
@@ -139,7 +187,9 @@
box-sizing: border-box;
margin-top: 10rpx;
}
.sub-btn-empty{
height: 120rpx;
}
.sub-btn {
position: fixed;
width: 100%;

View File

@@ -140,7 +140,7 @@
.info {
margin-top: 20rpx;
.cell {
height: 50rpx;
line-height: 50rpx;
@@ -148,6 +148,32 @@
font-size: $font-size-tag;
color: $color-tip;
}
&.refund-images{
margin-top: 0;
.cell{
height: auto;
display: flex;
align-items: flex-start;
.cell-title{
font-size: $font-size-tag;
color: $color-tip;
}
.images{
flex: 1;
display: flex;
align-items: center;
flex-wrap: wrap;
image{
width: 130rpx;
height: 130rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
}
}
}
}
}
}
}

View File

@@ -3,7 +3,7 @@ export default {
return {
orderId: null,
orderNo: "",
isAnonymous: 1, //是否匿名发布 1.匿名0.公开
isAnonymous: 0, //是否匿名发布 1.匿名0.公开
goodsList: [], //订单列表
goodsEvalList: [], //评价列表

View File

@@ -68,6 +68,17 @@
v-model="refund_remark"
/>
<!-- #endif -->
<view class="other-info">
<view class="other-info-box" v-for="(i, t) in imgList" :key="t">
<image :src="$util.img(i)" mode="aspectFill" @click="preview(i)"></image>
<view class="imgDel" @click="deleteImg(i, t)"><text class=" icon iconfont icon-delete"></text></view>
</view>
<view class="other-info-box active" @click="addImg()" v-if="imgList.length < 5 || imgList.length == undefined">
<text class="icon iconfont icon-zhaoxiangji"></text>
<text>{{ imgList.length ? 5 - imgList.length : 0 }}/5</text>
</view>
</view>
</view>
<!-- <view class="sub-btn color-base-bg" :class="{ 'safe-area': isIphoneX }" @click="submit">{{ $lang('common.submit') }}</view> -->
@@ -116,6 +127,7 @@ export default {
refund_type: '',
refund_reason: '',
refund_remark: '',
imgList: [],
isIphoneX: false,
refund_data: {
refund_type: [],
@@ -139,6 +151,32 @@ export default {
}
},
methods: {
//添加图片
addImg(e) {
let size = this.imgList.length ? this.imgList.length : 0
this.$util.upload(5 - size, {
path: 'refundimg'
}, res => {
let arr = this.imgList
arr = arr.concat(res);
this.imgList = arr;
});
},
//删除图片
deleteImg(i, j) {
this.imgList.splice(j, 1);
},
// 图片预览
preview(i) {
let urls = this.imgList;
for (let k = 0; k < urls.length; k++) {
urls[k] = this.$util.img(urls[k])
}
uni.previewImage({
urls: urls,
current: i
});
},
/**
* 显示弹出层
* @param {Object} ref
@@ -201,7 +239,8 @@ export default {
order_goods_ids: this.order_goods_id,
refund_type: this.refund_type,
refund_reason: this.refund_reason,
refund_remark: this.refund_remark
refund_remark: this.refund_remark,
refund_images: this.imgList.toString()
},
success: res => {
this.$util.showToast({ title: res.message });
@@ -225,7 +264,8 @@ export default {
order_goods_ids: this.order_goods_id,
refund_type: this.refund_type,
refund_reason: this.refund_reason,
refund_remark: this.refund_remark
refund_remark: this.refund_remark,
refund_images: this.imgList.toString()
},
success: res => {
this.$util.showToast({ title: res.message });
@@ -259,30 +299,7 @@ export default {
* 微信订阅消息
*/
subscribeMessage(callback){
this.$api.sendRequest({
url: '/weapp/api/weapp/messagetmplids',
data: {
keywords: 'ORDER_REFUND_AGREE,ORDER_REFUND_REFUSE'
},
success: res => {
if (res.code == 0 && res.data.length) {
uni.requestSubscribeMessage({
tmplIds: res.data,
fail: (res) => {
console.log('fail', res)
},
complete: ()=> {
callback();
}
})
} else {
callback();
}
},
fail: res => {
callback();
}
})
this.$util.subscribeMessage('ORDER_REFUND_AGREE,ORDER_REFUND_REFUSE', callback);
}
}
};

View File

@@ -57,8 +57,19 @@
v-model="refund_remark"
/>
<!-- #endif -->
<view class="other-info">
<view class="other-info-box" v-for="(i, t) in imgList" :key="t">
<image :src="$util.img(i)" mode="aspectFill" @click="preview(i)"></image>
<view class="imgDel" @click="deleteImg(i, t)"><text class=" icon iconfont icon-delete"></text></view>
</view>
<view class="other-info-box active" @click="addImg()" v-if="imgList.length < 5 || imgList.length == undefined">
<text class="icon iconfont icon-zhaoxiangji"></text>
<text>{{ imgList.length ? 5 - imgList.length : 0 }}/5</text>
</view>
</view>
</view>
<view class="sub-btn-empty"></view>
<!-- <view class="sub-btn color-base-bg" :class="{ 'safe-area': isIphoneX }" @click="submit">{{ $lang('common.submit') }}</view> -->
<view class="sub-btn" :class="{ 'safe-area': isIphoneX }" @click="submit">
<!-- <button type="primary">提交</button> -->
@@ -106,6 +117,7 @@ export default {
refund_type: '',
refund_reason: '',
refund_remark: '',
imgList: [],
isIphoneX: false,
refund_data: {
refund_type: [],
@@ -131,6 +143,32 @@ export default {
}
},
methods: {
//添加图片
addImg(e) {
let size = this.imgList.length ? this.imgList.length : 0
this.$util.upload(5 - size, {
path: 'refundimg'
}, res => {
let arr = this.imgList
arr = arr.concat(res);
this.imgList = arr;
});
},
//删除图片
deleteImg(i, j) {
this.imgList.splice(j, 1);
},
// 图片预览
preview(i) {
let urls = this.imgList;
for (let k = 0; k < urls.length; k++) {
urls[k] = this.$util.img(urls[k])
}
uni.previewImage({
urls: urls,
current: i
});
},
/**
* 显示弹出层
* @param {Object} ref
@@ -171,7 +209,11 @@ export default {
} else {
this.$util.showToast({ title: '未获取到该订单项退款信息' });
setTimeout(() => {
this.$util.redirectTo('/pages/order/list');
if (getCurrentPages().length > 1) {
uni.navigateBack();
} else {
this.$util.redirectTo('/pages/order/list');
}
}, 1000);
}
},
@@ -193,7 +235,8 @@ export default {
order_goods_ids: this.order_goods_id,
refund_type: this.refund_type,
refund_reason: this.refund_reason,
refund_remark: this.refund_remark
refund_remark: this.refund_remark,
refund_images: this.imgList.toString()
},
success: res => {
this.$util.showToast({ title: res.message });
@@ -201,7 +244,7 @@ export default {
uni.removeStorage({
key:'refund_goods_data',
success:res=>{
this.$util.redirectTo('/pages_tool/order/activist');
this.$util.redirectTo('/pages_tool/order/activist',{}, 'redirectTo');
}
})
} else {
@@ -215,14 +258,15 @@ export default {
})
// #endif
// #ifndef MP-WEIXIN
// #ifndef MP
this.$api.sendRequest({
url: '/api/orderrefund/refund',
data: {
order_goods_ids: this.order_goods_id,
refund_type: this.refund_type,
refund_reason: this.refund_reason,
refund_remark: this.refund_remark
refund_remark: this.refund_remark,
refund_images: this.imgList.toString()
},
success: res => {
this.$util.showToast({ title: res.message });
@@ -230,7 +274,7 @@ export default {
uni.removeStorage({
key:'refund_goods_data',
success:res=>{
this.$util.redirectTo('/pages_tool/order/activist');
this.$util.redirectTo('/pages_tool/order/activist',{}, 'redirectTo');
}
})
} else {
@@ -261,30 +305,7 @@ export default {
* 微信订阅消息
*/
subscribeMessage(callback){
this.$api.sendRequest({
url: '/weapp/api/weapp/messagetmplids',
data: {
keywords: 'ORDER_REFUND_AGREE,ORDER_REFUND_REFUSE'
},
success: res => {
if (res.code == 0 && res.data.length) {
uni.requestSubscribeMessage({
tmplIds: res.data,
fail: (res) => {
console.log('fail', res)
},
complete: ()=> {
callback();
}
})
} else {
callback();
}
},
fail: res => {
callback();
}
})
this.$util.subscribeMessage('ORDER_REFUND_AGREE,ORDER_REFUND_REFUSE', callback);
}
}
};

View File

@@ -48,17 +48,32 @@
</view>
</view>
<!-- 退款信息 -->
<view class="info">
<view class="info" v-if="detail.refund_apply_money > 0">
<view class="cell">退款方式{{ detail.refund_type == 1 ? '仅退款' : '退款退货' }}</view>
<view class="cell" v-if="detail.refund_status == 3">退款途径{{ detail.refund_money_type == 1 ? '原路退款' : detail.refund_money_type == 2 ? '线下退款' : '退款到余额' }}</view>
<view class="cell">退款原因{{ detail.refund_reason }}</view>
<view class="cell" v-if="detail.refund_status == 3 && detail.refund_real_money>0">退款金额{{ $lang('common.currencySymbol') }}{{ detail.refund_real_money }}</view>
<view class="cell" v-else-if="detail.refund_apply_money>0">退款金额{{ $lang('common.currencySymbol') }}{{ detail.refund_apply_money }}</view>
<view class="cell">申请原因{{ detail.refund_reason }}</view>
<view class="cell" v-if="detail.refund_remark != ''">申请说明{{ detail.refund_remark }}</view>
<!-- <view class="cell">申请时间{{ $util.timeStampTurnTime(detail.refund_action_time) }}</view> -->
<view class="cell">申请金额{{ $lang('common.currencySymbol') }}{{ detail.refund_apply_money }}</view>
</view>
<view class="info refund-images" v-if="detail.refund_apply_money > 0">
<view class="cell" v-if="detail.refund_images">
<view class="cell-title">退款图片</view>
<view class="images">
<image v-for="(item, index) in detail.refund_images.split(',')" :key="index" :src="$util.img(item)" mode="aspectFill"></image>
</view>
</view>
</view>
<view class="info" v-if="detail.refund_apply_money > 0 && detail.refund_status == 3">
<view class="cell">退款金额{{ $lang('common.currencySymbol') }}{{ detail.refund_real_money }} ({{ detail.refund_money_type_name }})</view>
<view class="cell">退款说明{{ detail.shop_refund_remark || '--' }}</view>
<view class="cell">退款编号{{ detail.refund_no }}</view>
<view class="cell">申请时间{{ $util.timeStampTurnTime(detail.refund_action_time) }}</view>
<view class="cell" v-if="detail.refund_time">退款时间{{ $util.timeStampTurnTime(detail.refund_time) }}</view>
<view class="cell" v-if="detail.refund_remark != ''">退款说明{{ detail.refund_remark }}</view>
<view class="cell" v-if="detail.use_point>0">退款积分{{ detail.use_point }}</view>
<view class="cell">退款时间{{ $util.timeStampTurnTime(detail.refund_time) }}</view>
<view class="cell" v-if="detail.use_point > 0">退款积分{{ detail.use_point }}</view>
</view>
<view class="info" v-if="detail.shop_active_refund == 1">
<view class="cell">主动退款编号{{ detail.shop_active_refund_no }}</view>
<view class="cell">主动退款金额{{ detail.shop_active_refund_money }} ({{ detail.shop_active_refund_money_type_name }})</view>
<view class="cell">主动退款说明{{ detail.shop_active_refund_remark }}</view>
</view>
</view>
</view>
@@ -131,12 +146,12 @@
<view class="empty-box"></view>
</view>
<view class="history-bottom" :class="{ 'bottom-safe-area': isIphoneX }">
<!-- <ns-contact :niushop="{order_id: detail.order_id}">
<ns-contact :niushop="{order_id: detail.order_id}">
<view>
<text class="iconfont icon-ziyuan"></text>
<text>联系客服</text>
</view>
</ns-contact> -->
</ns-contact>
<view @click="switchAction('')">返回详情</view>
</view>
</view>
@@ -213,7 +228,10 @@ export default {
if (res.code >= 0) {
this.$util.showToast({ title: '撤销成功' });
setTimeout(() => {
this.$util.redirectTo('/pages/order/list');
// this.$util.redirectTo('/pages/order/list');
uni.navigateBack({
delta: 1
});
}, 1000);
}
});
@@ -224,6 +242,11 @@ export default {
case 'orderRefundAsk':
this.$util.redirectTo('/pages_tool/order/refund', { order_goods_id: this.detail.order_goods_id });
break;
case 'orderRefundApply':
this.$util.redirectTo('/pages_tool/order/refund', {
order_goods_id: this.detail.order_goods_id
});
break;
}
},
refurnGoods() {

View File

@@ -7,7 +7,7 @@
<view class="body">
<view class="item" v-for="(item,index) in refund_data" :key="index">
<view @click="single(index)" style="display:none">
<view @click="single(index)">
<text v-if="item.judge" class="iconfont icon-yuan_checked color-base-text"></text>
<text v-else class="iconfont icon-yuan_checkbox"></text>
</view>
@@ -19,10 +19,9 @@
</view>
<view class="bottom-all">
<view >
<!-- @click="all"
<view @click="all">
<text v-if="judge" class="iconfont icon-yuan_checked color-base-text"></text>
<text v-else class="iconfont icon-yuan_checkbox"></text> -->
<text v-else class="iconfont icon-yuan_checkbox"></text>
</view>
<view v-if="nexthover" class="next" @click="next">下一步</view>
@@ -55,7 +54,11 @@
icon:'none'
})
setTimeout(()=>{
this.$util.redirectTo('/pages/order/list');
if (getCurrentPages().length > 1) {
uni.navigateBack();
} else {
this.$util.redirectTo('/pages/order/list');
}
},1000)
}
},
@@ -133,14 +136,11 @@
* 跳转退款界面
*/
next(){
this.refund_data.forEach(item=>{
this.order_goods_id.push(item.order_goods_id)
})
if(this.order_goods_id.length == 0){
this.getOrderIdInfo();
}
this.$util.redirectTo('/pages_tool/order/refund_batch', { order_goods_id: this.order_goods_id.join(), refund_type:this.refund_type });
this.$util.redirectTo('/pages_tool/order/refund_batch', { order_goods_id: this.order_goods_id.join(), refund_type:this.refund_type },'redirectTo');
},
/**
* 默认图片处理

View File

@@ -10,7 +10,7 @@
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="option-item" @click="selectRefundType(2)" v-if="refund_data.order_status == 3">
<view class="option-item" @click="selectRefundType(2)" v-if="refund_data.delivery_status > 0">
<view>
<text>退货退款</text>
<text class="font-size-goods-tag color-tip">已收到货需退还收到的货物</text>
@@ -59,7 +59,7 @@
selectRefundType(type) {
this.$util.redirectTo('/pages_tool/order/refund_goods_select', {
refund_type: type
});
},'redirectTo');
},
/**
* 获取退款订单数据
@@ -83,7 +83,11 @@
title: '未获取到该订单项退款信息'
});
setTimeout(() => {
this.$util.redirectTo('/pages/order/list');
if (getCurrentPages().length > 1) {
uni.navigateBack();
} else {
this.$util.redirectTo('/pages/order/list');
}
}, 1000);
}
},

View File

@@ -1,133 +1,132 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<scroll-view scroll-y="true" class="pay-container">
<view class="payment-amount">
<text class="amount-tit">{{ $lang('paymentAmount') }}</text>
<view class="amount-num">
{{ $lang('common.currencySymbol') }}
<text>{{ payInfo.pay_money }}</text>
</view>
<view class="payment-name">{{ payInfo.pay_body }}</view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
</scroll-view>
</template>
<script>
export default {
components: {},
data() {
return {
isIphoneX: false,
payInfo: {},
outTradeNo: '',
};
},
onLoad(option) {
if (option.code) this.outTradeNo = option.code;
this.isIphoneX = this.$util.uniappIsIPhoneX();
},
onShow() {
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
} else {
this.getPayInfo();
}
},
methods: {
getPayInfo() {
this.$api.sendRequest({
url: '/api/pay/info',
data: {
out_trade_no: this.outTradeNo
},
success: res => {
if (res.code >= 0 && res.data) {
this.payInfo = res.data;
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
} else {
this.$util.showToast({
title: '未获取到支付信息!'
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 1500);
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
}
}
};
</script>
<style lang="scss">
.pay-container {
width: 100vw;
height: 100vh;
}
@mixin flex-column {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
@mixin flex-row {
display: flex;
align-items: center;
justify-content: space-between;
}
.payment-amount {
@include flex-column;
margin: $margin-updown $margin-both;
border-radius: 8rpx;
padding: 20rpx 0 58rpx 0;
background-color: #fff;
.amount-tit {
font-size: $font-size-base;
color: #838383;
line-height: 1;
margin-top: 44rpx;
}
.amount-num {
color: #000;
margin-top: 36rpx;
line-height: 1;
text {
font-size: $font-size-toolbar;
color: #000;
}
}
.amount-desc {
font-size: $font-size-tag;
color: #838383;
padding: 0 40rpx;
width: 100%;
box-sizing: border-box;
text-align: center;
line-height: 1;
text {
width: 100%;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.payment-name {
width: 90%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #838383;
margin-top: 30rpx;
text-align: center;
line-height: 1;
}
}
</style>
<template>
<page-meta :page-style="themeColor"></page-meta>
<scroll-view scroll-y="true" class="pay-container">
<view class="payment-amount">
<text class="amount-tit">{{ $lang('paymentAmount') }}</text>
<view class="amount-num">
{{ $lang('common.currencySymbol') }}
<text>{{ payInfo.pay_money }}</text>
</view>
<view class="payment-name">{{ payInfo.pay_body }}</view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
</scroll-view>
</template>
<script>
export default {
components: {},
data() {
return {
isIphoneX: false,
payInfo: {},
outTradeNo: '',
};
},
onLoad(option) {
if (option.code) this.outTradeNo = option.code;
this.isIphoneX = this.$util.uniappIsIPhoneX();
},
onShow() {
if (!this.storeToken) {
this.$util.redirectTo('/pages_tool/login/login');
} else {
this.getPayInfo();
}
},
methods: {
getPayInfo() {
this.$api.sendRequest({
url: '/api/pay/info',
data: {
out_trade_no: this.outTradeNo
},
success: res => {
if (res.code >= 0 && res.data) {
this.payInfo = res.data;
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
} else {
this.$util.showToast({
title: '未获取到支付信息!'
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index');
}, 1500);
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
}
}
};
</script>
<style lang="scss">
.pay-container {
width: 100vw;
height: 100vh;
}
@mixin flex-column {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
@mixin flex-row {
display: flex;
align-items: center;
justify-content: space-between;
}
.payment-amount {
@include flex-column;
margin: $margin-updown $margin-both;
border-radius: 8rpx;
padding: 20rpx 0 58rpx 0;
background-color: #fff;
.amount-tit {
font-size: $font-size-base;
color: #838383;
line-height: 1;
margin-top: 44rpx;
}
.amount-num {
color: #000;
margin-top: 36rpx;
line-height: 1;
text {
font-size: $font-size-toolbar;
color: #000;
}
}
.amount-desc {
font-size: $font-size-tag;
color: #838383;
padding: 0 40rpx;
width: 100%;
box-sizing: border-box;
text-align: center;
line-height: 1;
text {
width: 100%;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.payment-name {
width: 90%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #838383;
margin-top: 30rpx;
text-align: center;
line-height: 1;
}
}
</style>

View File

@@ -0,0 +1,571 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="offlinepay">
<view class="pay-info">
<view class="title">实付金额</view>
<view class="pay-price price-style">
<text class="icon"></text>
<text class="price">{{payInfo.pay_money?parseFloat(payInfo.pay_money).toFixed(2):'0.00'}}</text>
</view>
<view class="pay-time" v-if="actionStatus=='add'">
<view class="text">支付剩余时间</view>
<block v-if="payInfo.time">
<view class="time" v-if="parseInt(payInfo.time.h)">{{payInfo.time.h}}</view>
<view class="separator" v-if="parseInt(payInfo.time.h)">:</view>
<view class="time">{{payInfo.time.i||'00'}}</view>
<view class="separator">:</view>
<view class="time">{{payInfo.time.s||'00'}}</view>
</block>
<block v-else>
<view class="time">00</view>
<view class="separator">:</view>
<view class="time">00</view>
</block>
</view>
</view>
<view class="pay-type" v-if="config.length">
<view class="top">
<block v-for="(item,index) in config" :key="index">
<view class="item" @click.stop="offlinepayTypeChange(index)">
<view class="center":class="{'active':index===activeIndex}">
{{item.key=='bank'?'银行卡':item.key=='wechat'?'微信支付':'支付宝'}}
</view>
<block v-if="activeIndex ==index">
<image v-if="activeIndex==0" class="image left" :src="$util.img('public/uniapp/offlinepay/head_style_left.png')"></image>
<image v-if="activeIndex==1" class="image center" :src="$util.img('public/uniapp/offlinepay/head_style_center.png')"></image>
<image v-if="activeIndex==2" class="image right" :src="$util.img('public/uniapp/offlinepay/head_style_right.png')"></image>
</block>
</view>
</block>
</view>
<view v-if="config[activeIndex].key=='bank'" class="bank">
<view class="item">
<view class="label">银行名称</view>
<view class="center using-hidden">{{config[activeIndex].bank_name}}</view>
</view>
<view class="item">
<view class="label">账号名称</view>
<view class="center using-hidden">{{config[activeIndex].account_name}}</view>
</view>
<view class="item">
<view class="label">银行账号</view>
<view class="center using-hidden">
<text>{{config[activeIndex].account_number}}</text>
<text class="copy" @click.stop="copy(config[activeIndex].account_number)">复制</text>
</view>
</view>
<view class="item">
<view class="label">开户支行</view>
<view class="center using-hidden">{{config[activeIndex].branch_name}}</view>
</view>
</view>
<view class="code" v-else>
<view class="centent">
<image class="image" :src="$util.img(config[activeIndex].payment_code)"></image>
</view>
<view class="bottom">{{config[activeIndex].account_name}}</view>
</view>
</view>
<view class="pay-form" v-if="config.length">
<view class="title">支付凭证最多5张</view>
<view class="image-list">
<view class="image-info-box" v-for="(item, index) in offlinepayInfo.imgList" :key="index">
<image :src="$util.img(item)" mode="aspectFill" @click="preview(index)"></image>
<view class="imgDel" @click="deleteImg(index)"><text class=" icon iconfont icon-delete"></text></view>
</view>
<view class="image-info-box active" @click="addImg" v-if="offlinepayInfo.imgList.length < 5">
<text class="icon iconfont icon-zhaoxiangji"></text>
<text>{{ offlinepayInfo.imgList.length ? 5 - offlinepayInfo.imgList.length : 0 }}/5</text>
</view>
</view>
<view class="desc">
<textarea v-model="offlinepayInfo.desc" class="input" placeholder-style="color:#999;font-weight: 400;font-size: 24rpx;" placeholder="请详细说明您的支付情况" :maxlength="200"/>
</view>
</view>
<view class="pay-footer" v-if="config.length">
<button class="back" @click.stop="back">返回</button>
<button class="save" @click.stop="save">确定提交</button>
</view>
</view>
</template>
<script>
export default {
data(){
return{
config:[],
payInfo:{},
offlinepayInfo:{
out_trade_no:'',
imgs:'',
imgList:[],
desc:'',
},
actionStatus:'add',
outTradeNo:'',
time:null,
activeIndex:0,
repeat_flag:false,
routePath:''
}
},
onLoad(options) {
this.outTradeNo = options.outTradeNo;
this.offlinepayInfo.out_trade_no = options.outTradeNo;
this.getOfflinepayConfig()
this.getOfflinepayPayInfo(this.outTradeNo)
this.getPayInfo(this.outTradeNo)
// 获取当前页面栈实例数组
const pages = getCurrentPages();
// 数组中最后一个元素即为当前页面实例
if(pages.length<1){
this.getroutePath(this.outTradeNo)
}
},
methods:{
getOfflinepayConfig(){
this.$api.sendRequest({
url: '/offlinepay/api/pay/config',
success: res => {
if (res.code >= 0 && res.data) {
let data = res.data.value
Object.keys(data).forEach(key=>{
if(data[key].status=='1'){
data[key].key = key
this.config.push(data[key])
}
});
} else {
this.$util.showToast({
title: '未获取到支付配置!'
});
}
}
});
},
getPayInfo(out_trade_no){
this.$api.sendRequest({
url: '/api/pay/info',
data:{out_trade_no},
success: res => {
if (res.code >= 0 && res.data) {
this.payInfo = res.data;
this.payInfo.timestamp = res.timestamp
if(this.payInfo.timestamp<this.payInfo.auto_close_time){
this.payInfo.time = this.$util.countDown(this.payInfo.auto_close_time-this.payInfo.timestamp)
this.time = setInterval(()=>{
if(this.payInfo.timestamp>=this.payInfo.auto_close_time) clearInterval(this.time)
this.payInfo.timestamp+=1
this.payInfo.time = this.$util.countDown(this.payInfo.auto_close_time-this.payInfo.timestamp)
this.$forceUpdate();
},1000)
}
} else {
this.$util.showToast({
title: '未获取到支付信息!'
});
}
}
});
},
getOfflinepayPayInfo(out_trade_no){
this.$api.sendRequest({
url: '/offlinepay/api/pay/info',
data:{out_trade_no},
success: res => {
if (res.code >= 0 && res.data) {
this.actionStatus = 'edit'
this.offlinepayInfo = res.data
this.offlinepayInfo.imgList = this.offlinepayInfo.imgs?this.offlinepayInfo.imgs.split(','):[]
// this.offlinepayInfo.out_trade_no = this.outTradeNo
}
}
});
},
//获取路由
getroutePath(out_trade_no){
this.$api.sendRequest({
url: '/api/pay/outTradeNoToOrderDetailPath',
data:{out_trade_no},
success: res => {
if (res.code >= 0 && res.data) {
this.routePath = res.data
}
}
});
},
offlinepayTypeChange(index){
this.activeIndex = index
},
copy(text){
this.$util.copy(text);
},
//添加图片
addImg() {
let size = this.offlinepayInfo.imgList.length
this.$util.upload(5 - size, {
path: ''
}, res => {
this.offlinepayInfo.imgList = this.offlinepayInfo.imgList.concat(res);
this.offlinepayInfo.imgs = this.offlinepayInfo.imgList.toString()
},'/offlinepay/api/pay/uploadimg');
},
//删除图片
deleteImg(index, ) {
this.offlinepayInfo.imgList.splice(index, 1);
this.offlinepayInfo.imgs = this.offlinepayInfo.imgList.toString()
},
back(){
const pages = getCurrentPages();
// 数组中最后一个元素即为当前页面实例
if(pages.length>1){
uni.navigateBack({
delta: 1
});
}else{
this.$util.redirectTo(this.routePath,{},'redirectTo')
}
},
save(){
if(this.repeat_flag) return;
if(!this.offlinepayInfo.imgList.length){
uni.showToast({
title: '请至少上传一张凭证',
icon: 'none'
})
return;
}
this.repeat_flag = true
// #ifdef MP
this.$util.subscribeMessage('OFFLINEPAY_AUDIT_REFUSE', ()=>{
this.saveSubmit();
})
// #endif
// #ifndef MP
this.saveSubmit();
// #endif
},
saveSubmit(){
this.$api.sendRequest({
url: '/offlinepay/api/pay/pay',
data:this.offlinepayInfo,
success: res => {
this.repeat_flag = false
if (res.code >= 0) {
uni.setStorageSync('offlinepay','offlinepay')
this.back()
}else{
uni.showToast({
title: res.message,
icon: 'none'
})
}
}
});
},
}
}
</script>
<style lang="scss" scoped>
.offlinepay{
width: 100%;
min-height: 100vh;
box-sizing: border-box;
background: #F6F6F6;
padding-top: 20rpx;
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: calc(164rpx + constant(safe-area-inset-bottom)) !important;
padding-bottom: calc(164rpx + env(safe-area-inset-bottom)) !important;
.pay-info{
width: 100%;
padding: 40rpx 30rpx;
background-color: #fff;
border-radius: 16rpx;
box-sizing: border-box;
.title{
font-size: 24rpx;
color: #666;
line-height: 34rpx;
font-weight: 600;
text-align: center;
}
.pay-price{
width: 100%;
display: flex;
justify-content: center;
align-items: baseline;
color: #EF000C;
margin-top:6rpx;
.icon{
line-height: 33rpx;
font-weight: bold;
font-size: 26rpx;
}
.price{
line-height: 59rpx;
font-weight: bold;
font-size: 46rpx;
}
}
.pay-time{
display: flex;
justify-content: center;
align-items: center;
margin-top: 14rpx;
.text{
line-height: 36rpx;
font-weight: 400;
font-size: 26rpx;
color: #666666;
margin-right: 11rpx;
}
.time{
width: 34rpx;
height: 34rpx;
// padding: 0 3rpx;
background: #F0F0F3;
border-radius: 2rpx 2rpx 2rpx 2rpx;
font-weight: 500;
font-size: 26rpx;
color: #333333;
line-height: 34rpx;
text-align: center;
}
.separator{
font-weight: 500;
font-size: 28rpx;
margin: 0 10rpx;
height: 34rpx;
line-height: 28rpx;
}
}
}
.pay-type{
margin-top: 40rpx;
.top{
width: 100%;
display: flex;
align-items: center;
height: 80rpx;
background: #F1F2F5;
border-radius: 16rpx 16rpx 0rpx 0rpx;
.item{
width: 230rpx;
height: 80rpx;
position: relative;
.center{
width: 100%;
height: 100%;
position: absolute;
left: 0;
bottom: 0;
z-index: 9;
line-height: 80rpx;
text-align: center;
font-weight: 400;
font-size: 32rpx;
&.active{
color: var(--base-color);
font-weight: bold;
}
}
.image{
height: 104rpx;
width: 267rpx;
position: absolute;
bottom: 0;
z-index: 2;
&.left{
left: -2rpx;
}
&.center{
width: 315rpx;
left: 50%;
transform: translateX(-50%);
}
&.right{
right:-2rpx;
}
}
}
}
.bank{
padding: 30rpx;
background: #fff;
border-radius: 0 0 16rpx 16rpx;
.item{
display: flex;
align-items: center;
margin-top: 30rpx;
&:first-of-type{
margin-top: 0 !important;
}
.label{
line-height: 36rpx;
font-weight: 400;
font-size: 26rpx;
color: #666666;
}
.center{
width: 500rpx;
line-height: 36rpx;
font-weight: 500;
font-size: 26rpx;
.copy{
color: var(--base-color);
margin-left: 20rpx;
}
}
}
}
.code{
padding: 50rpx 0;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: #fff;
border-radius: 0 0 16rpx 16rpx;
.centent{
width: 360rpx;
height: 360rpx;
border-radius: 16rpx;
border: 1rpx solid #DEDEDE;
padding: 30rpx;
box-sizing: border-box;
.image{
width: 300rpx;
height: 300rpx;
}
}
.bottom{
height: 39rpx;
line-height: 39rpx;
font-weight: 500;
font-size: 28rpx;
margin-top: 30rpx;
}
}
}
.pay-form{
margin-top: 20rpx;
padding: 30rpx;
border-radius: 16rpx;
background-color: #fff;
.title{
line-height: 33rpx;
font-weight: 500;
font-size: 26rpx;
color: #333333;
}
.image-list{
display: flex;
align-items: center;
margin-top: 30rpx;
.image-info-box {
width: 110rpx;
height: 110rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-left: 20rpx;
position: relative;
-ms-flex-negative: 0;
-webkit-flex-shrink: 0;
flex-shrink: 0;
&:first-of-type{
margin-left: 0 !important;
}
image {
width: 100%;
border-radius: $border-radius;
}
.iconfont {
font-size: 60rpx;
color: #898989;
line-height: 1;
}
text {
line-height: 1;
}
.imgDel {
width: 40rpx;
height: 40rpx;
position: absolute;
right: -20rpx;
top: -20rpx;
display: flex;
justify-content: center;
align-items: center;
.iconfont {
font-size: $font-size-toolbar;
}
}
}
.image-info-box.active {
border: 1rpx dashed #898989;
}
.image-info-box.active:active {
background: rgba($color: #cccccc, $alpha: 0.6);
}
}
.desc{
margin-top: 40rpx;
border-top: 1rpx dashed #898989;
padding-top: 20rpx;
.input{
width: 100%;
font-weight: 400;
font-size: 24rpx;
}
}
}
.pay-footer{
position: fixed;
display: flex;
justify-content: space-between;
align-items: center;
left: 0;
right:0;
bottom: 0;
z-index: 10;
padding: 28rpx 30rpx;
padding-bottom: calc(28rpx + constant(safe-area-inset-bottom)) !important;
padding-bottom: calc(28rpx + env(safe-area-inset-bottom)) !important;
background: #F6F6F6;
.back{
width: 220rpx;
height: 88rpx;
line-height: 82rpx;
font-size: 32rpx;
font-weight: 500;
color: var(--base-color);
background: #FFFFFF;
border-radius: 50rpx 50rpx 50rpx 50rpx;
border: 3rpx solid var(--base-color);
box-sizing: border-box;
}
.save{
width: 430rpx;
height: 88rpx;
font-size: 32rpx;
font-weight: 500;
color: #fff;
background: var(--base-color);
border-radius: 50rpx 50rpx 50rpx 50rpx
}
}
}
</style>

View File

@@ -1,344 +1,336 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="container">
<template v-if="payInfo.pay_status != undefined">
<view class="result-box">
<template v-if="payInfo.pay_status">
<image :src="$util.img('public/uniapp/pay/pay_success.png')" mode="widthFix" lazy-load="true" class="result-image"/>
<view class="msg success">{{ $lang('paymentSuccess') }}</view>
<view class="pay-amount">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price-style large">{{ parseFloat(payInfo.pay_money).toFixed(2).split(".")[0] }}</text>
<text class="price-style small">.{{ parseFloat(payInfo.pay_money).toFixed(2).split(".")[1] }}</text>
</view>
</template>
<template v-else>
<image :src="$util.img('public/uniapp/pay/pay_fail.png')" mode="widthFix" class="result-image"/>
<view class="msg fail">{{ $lang('paymentFail') }}</view>
</template>
<view class="consume-box" v-if="addonIsExist.memberconsume && consumeStatus == 1 && payInfo.pay_status">
<view class="consume-head">
<view class="consume-head-text">恭喜您获得</view>
</view>
<view class="consume-list">
<view class="consume-item" v-if="consumeInfo.point_num > 0">
<image :src="$util.img('public/uniapp/pay/point.png')" mode="widthFix"></image>
<view class="consume-value color-base-text">{{ consumeInfo.point_num }}</view>
<view class="consume-type">积分</view>
</view>
<view class="consume-item" v-if="consumeInfo.growth_num > 0">
<image :src="$util.img('public/uniapp/pay/growth.png')" mode="widthFix"></image>
<view class="consume-value color-base-text">{{ consumeInfo.growth_num }}</view>
<view class="consume-type">成长值</view>
</view>
<view class="consume-item" v-if="consumeInfo.coupon_list.length > 0">
<image :src="$util.img('public/uniapp/pay/coupon.png')" mode="widthFix"></image>
<view class="consume-value color-base-text">{{ consumeInfo.coupon_list.length }}</view>
<view class="consume-type">张优惠券</view>
</view>
</view>
</view>
<view class="action">
<template v-if="storeToken">
<view v-if="paySource == 'recharge'" class="btn" @click="toRecharge()">充值记录</view>
<view v-else-if="paySource == 'membercard'" class="btn" @click="toCard()">会员卡</view>
<view v-else-if="paySource == 'presale'" class="btn" @click="toPresaleOrder()">查看订单</view>
<view v-else-if="paySource == 'giftcard'" class="btn" @click="toOrder()">查看订单</view>
<view v-else-if="paySource == 'pointexchange'" class="btn" @click="toExchangeOrder()">查看订单
</view>
<view v-else class="btn" @click="toOrderDetail(payInfo.order_id)">查看订单</view>
</template>
<view class="btn go-home" @click="goHome()">{{ $lang('goHome') }}</view>
</view>
</view>
<ns-goods-recommend route="pay"></ns-goods-recommend>
</template>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
export default {
data() {
return {
payInfo: {},
outTradeNo: '',
paySource: '',
consumeInfo: {},
consumeStatus: 0,
};
},
onLoad(option) {
if (option.code) this.outTradeNo = option.code;
this.paySource = uni.getStorageSync('paySource');
},
onShow() {
this.getPayInfo();
this.getConsume();
},
methods: {
consume(type) {
switch (type) {
case 'point':
this.$util.redirectTo('/pages_tool/member/point_detail', {});
break;
case 'growth':
this.$util.redirectTo('/pages_tool/member/level', {});
break;
case 'coupon':
this.$util.redirectTo('/pages_tool/member/coupon', {});
break;
default:
this.$util.redirectTo('/pages/member/index', {}, 'reLaunch');
break;
}
},
getConsume() {
this.$api.sendRequest({
url: '/memberconsume/api/config/info',
data: {
out_trade_no: this.outTradeNo
},
success: res => {
if (res.code >= 0 && res.data) {
let reward = res.data.value;
if (res.data.is_use && (reward.point_num > 0 || reward.growth_num > 0 || reward.coupon_list.length)) {
this.consumeStatus = res.data.is_use;
this.consumeInfo = res.data.value;
}
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
getPayInfo() {
this.$api.sendRequest({
url: '/api/pay/info',
data: {
out_trade_no: this.outTradeNo
},
success: res => {
if (res.code >= 0 && res.data) {
this.payInfo = res.data;
this.payInfo.pay_money = parseFloat(res.data.pay_money);
this.payInfo.pay_money += parseFloat(res.data.balance);
this.payInfo.pay_money += parseFloat(res.data.balance_money);
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
} else {
this.$util.showToast({
title: '未获取到支付信息!'
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index', {}, 'reLaunch');
}, 1500);
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
goHome() {
this.$util.redirectTo('/pages/index/index', {}, 'reLaunch');
},
toOrderDetail(id) {
if (this.payInfo.order_type == 2) {
this.$util.redirectTo('/pages/order/detail_pickup', {
order_id: id
}, 'redirectTo');
} else if (this.payInfo.order_type == 3) {
this.$util.redirectTo('/pages/order/detail_local_delivery', {
order_id: id
}, 'redirectTo');
} else if (this.payInfo.order_type == 4) {
this.$util.redirectTo('/pages_tool/order/detail_virtual', {
order_id: id
}, 'redirectTo');
} else {
this.$util.redirectTo('/pages/order/detail', {
order_id: id
}, 'redirectTo');
}
},
toOrder(id) {
this.$util.redirectTo('/pages_promotion/giftcard/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toRecharge() {
this.$util.redirectTo('/pages_tool/recharge/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toCard() {
this.$util.redirectTo('/pages_tool/member/card', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toPresaleOrder() {
this.$util.redirectTo('/pages_promotion/presale/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toExchangeOrder() {
this.$util.redirectTo('/pages_promotion/point/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
}
}
};
</script>
<style lang="scss">
.consume-box {
padding: $padding;
background: #F8F8F8;
width: calc(100% - 48rpx);
margin: 0 24rpx 0 24rpx;
box-sizing: border-box;
border-radius: 20rpx;
.consume-head {
display: flex;
justify-content: center;
font-weight: 500;
font-size: 26rpx;
.consume-head-text {
line-height: 1;
}
}
.consume-list {
display: flex;
}
.consume-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: $color-title;
font-size: $font-size-base;
margin-top: 10rpx;
image {
width: 24rpx;
margin-right: 4rpx;
}
.consume-value {
font-size: 26rpx;
}
}
.consume-remark {
color: $color-tip;
font-size: $font-size-tag;
padding: 10rpx 20rpx;
}
}
.clear {
clear: both;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
.result-box {
padding-top: 94rpx;
display: flex;
flex-direction: column;
align-items: center;
background-color: #FFFFFF;
width: 100%;
padding-bottom: 40rpx;
}
.result-image {
width: 80rpx;
height: auto;
will-change: transform;
}
.msg {
font-size: 32rpx;
margin-top: 25rpx;
&.success {
color: #09BB07;
}
&.fail {
color: #FF4646;
}
}
.pay-amount {
font-size: 30rpx;
margin: 40rpx 0 24rpx 0;
font-weight: 600;
line-height: 50rpx;
text {
color: #333333 !important;
font-weight: bold !important;
}
.unit {
margin-right: 4rpx;
}
.large {
font-size: 60rpx !important;
}
.small {
font-size: 36rpx !important;
}
}
.action {
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
box-sizing: border-box;
margin-top: 24rpx;
.btn {
font-size: 30rpx;
width: 200rpx;
height: 66rpx;
line-height: 66rpx;
text-align: center;
border-radius: 66rpx;
border: 1px solid $color-tip;
box-sizing: border-box;
&:last-child {
margin-left: 40rpx;
}
}
.go-home {
background-color: $base-color;
color: #fff;
border-color: $base-color;
}
}
}
/deep/ .goods-recommend {
margin-top: 30rpx;
}
</style>
<style scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important;
}
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="container">
<template v-if="payInfo.pay_status != undefined">
<view class="result-box">
<template v-if="payInfo.pay_status">
<image :src="$util.img('public/uniapp/pay/pay_success.png')" mode="widthFix" lazy-load="true" class="result-image"/>
<view class="msg success">{{ $lang('paymentSuccess') }}</view>
<view class="pay-amount">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price-style large">{{ parseFloat(payInfo.pay_money).toFixed(2).split(".")[0] }}</text>
<text class="price-style small">.{{ parseFloat(payInfo.pay_money).toFixed(2).split(".")[1] }}</text>
</view>
</template>
<template v-else>
<image :src="$util.img('public/uniapp/pay/pay_fail.png')" mode="widthFix" class="result-image"/>
<view class="msg fail">{{ $lang('paymentFail') }}</view>
</template>
<view class="consume-box" v-if="addonIsExist.memberconsume && consumeInfo.is_reward == 1 && payInfo.pay_status">
<view class="consume-head">
<view class="consume-head-text">恭喜您获得</view>
</view>
<view class="consume-list">
<view class="consume-item" v-if="consumeInfo.point_num > 0" @click="toMemberPoint()">
<image :src="$util.img('public/uniapp/pay/point.png')" mode="widthFix"></image>
<view class="consume-value color-base-text">{{ consumeInfo.point_num }}</view>
<view class="consume-type">积分</view>
</view>
<view class="consume-item" v-if="consumeInfo.growth_num > 0" @click="toMemberLevel()">
<image :src="$util.img('public/uniapp/pay/growth.png')" mode="widthFix"></image>
<view class="consume-value color-base-text">{{ consumeInfo.growth_num }}</view>
<view class="consume-type">成长值</view>
</view>
<view class="consume-item" v-if="consumeInfo.coupon_list.length > 0" @click="toMemberCoupon()">
<image :src="$util.img('public/uniapp/pay/coupon.png')" mode="widthFix"></image>
<view class="consume-value color-base-text">{{ consumeInfo.coupon_list.length }}</view>
<view class="consume-type">张优惠券</view>
</view>
</view>
</view>
<view class="action">
<template v-if="storeToken">
<view v-if="paySource == 'recharge'" class="btn" @click="toRecharge()">充值记录</view>
<view v-else-if="paySource == 'membercard'" class="btn" @click="toCard()">会员卡</view>
<view v-else-if="paySource == 'presale'" class="btn" @click="toPresaleOrder()">查看订单</view>
<view v-else-if="paySource == 'giftcard'" class="btn" @click="toOrder()">查看订单</view>
<view v-else-if="paySource == 'pointexchange'" class="btn" @click="toExchangeOrder()">查看订单
</view>
<view v-else class="btn" @click="toOrderDetail(payInfo.order_id)">查看订单</view>
</template>
<view class="btn go-home" @click="goHome()">{{ $lang('goHome') }}</view>
</view>
</view>
<ns-goods-recommend route="pay"></ns-goods-recommend>
</template>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
export default {
data() {
return {
payInfo: {},
outTradeNo: '',
paySource: '',
consumeInfo: {
is_reward:0,
},
};
},
onLoad(option) {
if (option.code) this.outTradeNo = option.code;
this.paySource = uni.getStorageSync('paySource');
},
onShow() {
this.getPayInfo();
this.getConsume();
},
methods: {
consume(type) {
switch (type) {
case 'point':
this.$util.redirectTo('/pages_tool/member/point_detail', {});
break;
case 'growth':
this.$util.redirectTo('/pages_tool/member/level', {});
break;
case 'coupon':
this.$util.redirectTo('/pages_tool/member/coupon', {});
break;
default:
this.$util.redirectTo('/pages/member/index', {}, 'reLaunch');
break;
}
},
getConsume() {
this.$api.sendRequest({
url: '/memberconsume/api/config/info',
data: {
out_trade_no: this.outTradeNo
},
success: res => {
if (res.code >= 0) {
this.consumeInfo = res.data;
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
getPayInfo() {
this.$api.sendRequest({
url: '/api/pay/info',
data: {
out_trade_no: this.outTradeNo
},
success: res => {
if (res.code >= 0 && res.data) {
this.payInfo = res.data;
this.payInfo.pay_money = parseFloat(res.data.pay_money);
this.payInfo.pay_money += parseFloat(res.data.balance);
this.payInfo.pay_money += parseFloat(res.data.balance_money);
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
} else {
this.$util.showToast({
title: '未获取到支付信息!'
});
setTimeout(() => {
this.$util.redirectTo('/pages/index/index', {}, 'reLaunch');
}, 1500);
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
goHome() {
this.$util.redirectTo('/pages/index/index', {}, 'reLaunch');
},
toOrderDetail(id) {
this.$util.redirectTo('/pages/order/detail', {
order_id: id
}, 'redirectTo');
},
toOrder(id) {
this.$util.redirectTo('/pages_promotion/giftcard/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toRecharge() {
this.$util.redirectTo('/pages_tool/recharge/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toCard() {
this.$util.redirectTo('/pages_tool/member/card', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toPresaleOrder() {
this.$util.redirectTo('/pages_promotion/presale/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toExchangeOrder() {
this.$util.redirectTo('/pages_promotion/point/order_list', {}, 'redirectTo');
uni.setStorageSync('paySource', '');
},
toMemberPoint() {
this.$util.redirectTo('/pages_tool/member/point');
},
toMemberCoupon() {
this.$util.redirectTo('/pages_tool/member/coupon');
},
toMemberLevel() {
this.$util.redirectTo('/pages_tool/member/level');
},
}
};
</script>
<style lang="scss">
.consume-box {
padding: $padding;
background: #F8F8F8;
width: calc(100% - 48rpx);
margin: 0 24rpx 0 24rpx;
box-sizing: border-box;
border-radius: 20rpx;
.consume-head {
display: flex;
justify-content: center;
font-weight: 500;
font-size: 26rpx;
.consume-head-text {
line-height: 1;
}
}
.consume-list {
display: flex;
}
.consume-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: $color-title;
font-size: $font-size-base;
margin-top: 10rpx;
image {
width: 24rpx;
margin-right: 4rpx;
}
.consume-value {
font-size: 26rpx;
}
}
.consume-remark {
color: $color-tip;
font-size: $font-size-tag;
padding: 10rpx 20rpx;
}
}
.clear {
clear: both;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
.result-box {
padding-top: 94rpx;
display: flex;
flex-direction: column;
align-items: center;
background-color: #FFFFFF;
width: 100%;
padding-bottom: 40rpx;
}
.result-image {
width: 80rpx;
height: auto;
will-change: transform;
}
.msg {
font-size: 32rpx;
margin-top: 25rpx;
&.success {
color: #09BB07;
}
&.fail {
color: #FF4646;
}
}
.pay-amount {
font-size: 30rpx;
margin: 40rpx 0 24rpx 0;
font-weight: 600;
line-height: 50rpx;
text {
color: #333333 !important;
font-weight: bold !important;
}
.unit {
margin-right: 4rpx;
}
.large {
font-size: 60rpx !important;
}
.small {
font-size: 36rpx !important;
}
}
.action {
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
box-sizing: border-box;
margin-top: 24rpx;
.btn {
font-size: 30rpx;
width: 200rpx;
height: 66rpx;
line-height: 66rpx;
text-align: center;
border-radius: 66rpx;
border: 1px solid $color-tip;
box-sizing: border-box;
&:last-child {
margin-left: 40rpx;
}
}
.go-home {
background-color: $base-color;
color: #fff;
border-color: $base-color;
}
}
}
/deep/ .goods-recommend {
margin-top: 30rpx;
}
</style>
<style scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,177 +1,179 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="order-container">
<mescroll-uni ref="mescroll" @getData="getListData">
<block slot="list">
<block v-if="orderList.length > 0">
<view class="order-item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
<view class="order-header">
<view>
<text class="color-tip font-size-tag">{{ orderItem.order_no }}</text>
</view>
<view class="align-right">
<text class="color-tip font-size-tag">{{ $util.timeStampTurnTime(orderItem.create_time) }}</text>
</view>
</view>
<view class="order-body">
<view class="goods_info_flex"><view class="goods-name font-size-base">充值成功</view></view>
<view class="goods-img color-base-text">
<text>{{ orderItem.buy_price }}</text>
</view>
<!-- <view class="goods-sub-section">
<view class="<strong>goods-name</strong> color-tip " v-if="orderItem.point > 0 || orderItem.growth > 0">赠送:</view>
<view class="goods-name color-tip " v-if="orderItem.point > 0">{{ orderItem.point }}积分</view>
<view class="goods-name color-tip " v-if="orderItem.point > 0 && orderItem.growth > 0"></view>
<view class="goods-name color-tip " v-if="orderItem.growth > 0">{{ orderItem.growth }}成长值</view>
<view class="goods-name color-tip " v-if="orderItem.point > 0 && orderItem.coupon_id"></view>
<view class="goods-name color-tip " v-if="orderItem.coupon_id">优惠券x{{ orderItem.coupon_id.split(',').length }}</view>
</view> -->
</view>
</view>
</block>
<view v-else><ns-empty :isIndex="false" text="暂无充值记录"></ns-empty></view>
</block>
</mescroll-uni>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
export default {
data() {
return {
orderList: []
};
},
onShow() {
if (this.$refs.mescroll) this.$refs.mescroll.refresh();
if (!this.storeToken) {
this.$nextTick(() => {
this.$refs.login.open('/pages_tool/recharge/order_list');
});
}
},
methods: {
getListData(mescroll) {
this.$api.sendRequest({
url: '/memberrecharge/api/order/page',
data: {
page: mescroll.num,
page_size: mescroll.size
},
success: res => {
let newArr = [];
let msg = res.message;
if (res.code == 0 && res.data) {
newArr = res.data.list;
} else {
this.$util.showToast({
title: msg
});
}
mescroll.endSuccess(newArr.length);
//设置列表数据
if (mescroll.num == 1) this.orderList = []; //如果是第一页需手动制空列表
this.orderList = this.orderList.concat(newArr); //追加新数据
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
mescroll.endErr();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
imageError(index) {
this.orderList[index].cover_img = this.$util.getDefaultImage().goods;
this.$forceUpdate();
}
}
};
</script>
<style lang="scss">
.order-container {
width: 100vw;
height: 100vh;
}
.align-right {
text-align: right;
}
.order-item {
margin: $margin-updown $margin-both;
padding: 0 30rpx;
border-radius: $border-radius;
background: #fff;
position: relative;
.order-header {
display: flex;
align-items: center;
position: relative;
height: 80rpx;
line-height: 80rpx;
border-bottom: 1px solid #e3e3e3;
& > view {
flex: 1;
line-height: 1;
font-weight: 500;
}
}
.order-body {
height: 155rpx;
position: relative;
.goods_info_flex {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 30rpx;
.goods-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
line-height: 1;
font-weight: 500;
}
}
.goods-img {
font-size: $font-size-tag;
font-weight: 500;
position: absolute;
right: 0;
top: 20rpx;
text {
font-size: $font-size-toolbar;
}
}
.goods-sub-section {
width: 100%;
line-height: 1;
display: flex;
margin-top: 39rpx;
font-size: $font-size-tag;
view {
line-height: 1;
text-align: right;
margin-right: 10rpx;
font-size: $font-size-tag;
}
}
}
}
</style>
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="order-container">
<mescroll-uni ref="mescroll" @getData="getListData">
<block slot="list">
<block v-if="orderList.length > 0">
<view class="order-item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
<view class="order-header">
<view>
<text class="color-tip font-size-tag">{{ orderItem.order_no }}</text>
</view>
<view class="align-right">
<text class="color-tip font-size-tag">{{ $util.timeStampTurnTime(orderItem.create_time) }}</text>
</view>
</view>
<view class="order-body">
<view class="goods_info_flex"><view class="goods-name font-size-base">充值成功</view></view>
<view class="goods-img color-base-text">
<text>{{ orderItem.buy_price }}</text>
</view>
<view class="goods-sub-section" v-if="isShowGift(orderItem)">
<view class="goods-name color-tip " v-if="orderItem.point > 0 || orderItem.growth > 0">赠送:</view>
<view class="goods-name color-tip " v-if="orderItem.point > 0">{{ orderItem.point }}积分</view>
<view class="goods-name color-tip " v-if="orderItem.point > 0 && orderItem.growth > 0"></view>
<view class="goods-name color-tip " v-if="orderItem.growth > 0">{{ orderItem.growth }}成长值</view>
<view class="goods-name color-tip " v-if="orderItem.point > 0 && orderItem.coupon_id"></view>
<view class="goods-name color-tip " v-if="Number(orderItem.coupon_id)">优惠券x{{ orderItem.coupon_id.split(',').length }}</view>
</view>
</view>
</view>
</block>
<view v-else><ns-empty :isIndex="false" text="暂无充值记录"></ns-empty></view>
</block>
</mescroll-uni>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
export default {
data() {
return {
orderList: []
};
},
onShow() {
if (this.$refs.mescroll) this.$refs.mescroll.refresh();
if (!this.storeToken) {
this.$nextTick(() => {
this.$refs.login.open('/pages_tool/recharge/order_list');
});
}
},
methods: {
isShowGift(data) {
return (data.point > 0 || data.growth > 0) || (data.point > 0) || (data.point > 0 && data.growth > 0) || (data.growth > 0) || (data.point > 0 && data.coupon_id) || (Number(data.coupon_id))
},
getListData(mescroll) {
this.$api.sendRequest({
url: '/memberrecharge/api/order/page',
data: {
page: mescroll.num,
page_size: mescroll.size
},
success: res => {
let newArr = [];
let msg = res.message;
if (res.code == 0 && res.data) {
newArr = res.data.list;
} else {
this.$util.showToast({
title: msg
});
}
mescroll.endSuccess(newArr.length);
//设置列表数据
if (mescroll.num == 1) this.orderList = []; //如果是第一页需手动制空列表
this.orderList = this.orderList.concat(newArr); //追加新数据
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
},
fail: res => {
mescroll.endErr();
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
imageError(index) {
this.orderList[index].cover_img = this.$util.getDefaultImage().goods;
this.$forceUpdate();
}
}
};
</script>
<style lang="scss">
.order-container {
width: 100vw;
height: 100vh;
}
.align-right {
text-align: right;
}
.order-item {
margin: $margin-updown $margin-both;
padding: 0 30rpx;
border-radius: $border-radius;
background: #fff;
position: relative;
.order-header {
display: flex;
align-items: center;
position: relative;
height: 80rpx;
line-height: 80rpx;
border-bottom: 1px solid #e3e3e3;
& > view {
flex: 1;
line-height: 1;
font-weight: 500;
}
}
.order-body {
// height: 155rpx;
position: relative;
padding-bottom: 39rpx;
.goods_info_flex {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 30rpx;
.goods-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
line-height: 1;
font-weight: 500;
}
}
.goods-img {
font-size: $font-size-tag;
font-weight: 500;
position: absolute;
right: 0;
top: 20rpx;
text {
font-size: $font-size-toolbar;
}
}
.goods-sub-section {
width: 100%;
line-height: 1;
display: flex;
margin-top: 39rpx;
font-size: $font-size-tag;
view {
line-height: 1;
text-align: right;
margin-right: 10rpx;
font-size: $font-size-tag;
}
}
}
}
</style>

412
pages_tool/store/detail.vue Normal file
View File

@@ -0,0 +1,412 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="store-detail" v-if="store">
<view class="detail-head" :style="{ height: swiperHeight }">
<swiper class="swiper" @change="swiperChange" autoplay="true" interval="4000" circular="true">
<swiper-item v-for="(item, index) in store.store_images.images" :key="index" :item-id="'store_id_' + index">
<view class="item" @click="previewMedia(index)">
<image :src="$util.img(item)" @error="swiperImageError(index)" mode="aspectFit" />
</view>
</swiper-item>
</swiper>
<view class="img-indicator-dots" v-if="store.store_images.images && store.store_images.images.length">
<text>{{ swiperCurrent }}</text>
<text>/{{ store.store_images.images.length }}</text>
</view>
</view>
<view class="detail-content">
<view class="content-item">
<view class="store-name multi-hidden">{{ store.store_name }}</view>
<view class="store-state" :class="store.is_frozen.is_frozen == 1 || store.status == 0 ? 'warning' : ''">
{{ (store.is_frozen.is_frozen == 1 && '已停业') || (store.status == 0 && '休息中') || (store.status == 1 && '营业中') || '--' }}
</view>
</view>
<view class="content-item store-time-wrap" v-if="store.open_date || store.is_default || store.is_pickup || store.is_o2o || store.is_express">
<view v-if="store.status == 0 && store.close_desc" class="close-desc">{{ store.close_desc }}</view>
<view class="store-time" v-if="store.open_date">{{ store.open_date }}</view>
<view class="tag-wrap" v-if="store.is_default || store.is_pickup || store.is_o2o || store.is_express">
<text class="tag-item" v-if="store.is_default == 1">总店</text>
<text class="tag-item" v-if="store.is_pickup == 1">门店自提</text>
<text class="tag-item" v-if="store.is_o2o == 1">同城配送</text>
<text class="tag-item" v-if="store.is_express == 1">物流配送</text>
</view>
</view>
<view class="content-item address-wrap" v-if="store.show_address || store.distance">
<view class="address-box">
<view class="address-name" v-if="store.show_address">{{ store.show_address }}</view>
<view class="address-location" v-if="store.distance">
<text class="icondiy icon-system-weizhi"></text>
<text>距您当前位置{{ store.distance }}km</text>
</view>
</view>
<text class="icondiy icon-daohang" @click="mapRoute()"></text>
</view>
<view class="content-item telphone-wrap" v-if="store.telphone">
<text v-if="store.telphone" class="telphone">{{ store.telphone }}</text>
<text class="iconfont icon-dianhua" @click="phoneCall"></text>
</view>
</view>
<view class="detail-map">
<view class="map-head">门店地图</view>
<map class="map-body" :latitude="store.latitude" :longitude="store.longitude" :markers="covers"></map>
</view>
<!-- <view class="store-action-fill"></view>
<view class="store-action"><button type="primary" @click="storeTap()">进入门店</button></view> -->
</view>
</template>
<script>
import Map from '@/common/js/map/openMap.js';
export default {
data() {
return {
storeId: 0,
latitude: null, // 纬度
longitude: null, // 经度
covers: [],
store: null,
swiperCurrent: 1,
swiperHeight: ''
};
},
onLoad(options) {
this.storeId = options.store_id || 0;
if (this.location) {
this.latitude = this.location.latitude;
this.longitude = this.location.longitude;
} else if (this.mapConfig.wap_is_open == 1) {
this.$util.getLocation();
}
this.getInfo();
},
watch: {
location: function(nVal) {
if (nVal) {
this.latitude = nVal.latitude;
this.longitude = nVal.longitude;
this.getInfo();
}
}
},
methods: {
//打电话
phoneCall() {
uni.makePhoneCall({
phoneNumber: this.store.telphone //仅为示例
});
},
//获取门店详情
getInfo() {
let data = {
store_id: this.storeId
};
if (this.latitude && this.longitude) {
data.latitude = this.latitude;
data.longitude = this.longitude;
}
this.$api.sendRequest({
url: '/api/store/info',
data: data,
success: res => {
if (res.data) {
// 默认数据
let defaultData = {
full_address: '',
address: '',
store_images: []
};
this.store = res.data || defaultData;
this.covers.push({
id: 1,
latitude: this.store.latitude,
longitude: this.store.longitude,
iconPath: this.$util.img('public/uniapp/store/map_icon.png'),
height: 25
});
this.store.show_address = this.store.full_address.replace(/,/g, ' ') + ' ' + this
.store.address;
this.handleStoreImage();
} else {
this.$util.showToast({
title: '门店不存在'
});
setTimeout(() => {
this.$util.redirectTo('/pages_tool/store/list', {}, 'redirectTo');
}, 2000);
}
}
});
},
// 处理门店图片+图片高度
handleStoreImage() {
if (!this.store.store_images) this.store.store_images = [];
this.store.store_images = this.store.store_images.reduce((pre, cur) => {
// 图片
if (!pre.images) pre.images = [];
if (pre.images) pre.images.push(cur.pic_path);
// 图片规格
if (!pre.spec) pre.spec = [];
if (pre.spec) pre.spec.push(cur.pic_spec);
return pre;
}, {});
let maxHeight = '';
if (this.store.store_images.spec) {
this.store.store_images.spec.forEach((item, index) => {
if (typeof item == 'string') item = item.split('*');
uni.getSystemInfo({
success: res => {
let ratio = item[0] / res.windowWidth;
item[0] = item[0] / ratio;
item[1] = item[1] / ratio;
}
});
if (!maxHeight || maxHeight > item[1]) {
maxHeight = item[1];
}
});
}
this.swiperHeight = Number(maxHeight) + 'px';
if (!Object.keys(this.store.store_images).length) {
this.store.store_images = {};
this.store.store_images.images = [this.$util.img('public/static/img/default_img/square.png')];
this.store.store_images.spec = ['350*350'];
this.swiperHeight = '380px';
}
},
swiperChange(e) {
this.swiperCurrent = e.detail.current + 1;
},
mapRoute() {
Map.openMap(Number(this.store.latitude), Number(this.store.longitude), this.store.store_name, 'gcj02');
},
swiperImageError() {
this.store.store_images.images = this.$util.img('public/static/img/default_img/square.png');
}
}
};
</script>
<style lang="scss">
page {
background-color: #f5f6fa;
}
.store-detail {
.detail-head {
position: relative;
width: 100%;
height: 300rpx;
background-color: #fff;
&::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 112rpx;
background-image: linear-gradient(transparent 10%, #f5f6fa);
}
.swiper {
width: 100%;
height: 100%;
.item {
width: 100%;
height: 100%;
}
image {
width: 100%;
height: 100%;
}
}
.img-indicator-dots {
position: absolute;
z-index: 5;
bottom: 60rpx;
right: 40rpx;
background: rgba(100, 100, 100, 0.4);
color: #fff;
font-size: $font-size-tag;
line-height: 40rpx;
border-radius: 20rpx;
padding: 0 20rpx;
}
}
.detail-content {
position: relative;
background-color: #fff;
margin: -30rpx 30rpx 30rpx;
padding: 0 24rpx;
border-radius: 18rpx;
z-index: 9;
.content-item {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid #ededed;
padding: 24rpx 0;
&:last-of-type {
border-bottom: 0;
}
}
.store-name {
font-size: $font-size-toolbar;
font-weight: bold;
line-height: 1.5;
padding: 6rpx 0;
}
.store-state {
padding: 8rpx 10rpx;
font-size: $font-size-tag;
border: 2rpx solid #66ad95;
color: #66ad95;
border-radius: 4rpx;
line-height: 1;
&.warning{
color:red;
border-color: red;
}
}
.store-time-wrap {
flex-direction: column;
align-items: baseline;
.store-time {
font-size: $font-size-tag;
color: $color-sub;
}
.close-desc{
color:red;
font-size: $font-size-tag;
}
.tag-wrap {
margin-top: 20rpx;
display: flex;
flex-wrap: wrap;
.tag-item {
padding: 8rpx 10rpx;
margin-right: 10rpx;
color: #6f7dad;
background: #f4f5fa;
border-radius: 6rpx;
line-height: 1;
font-size: $font-size-tag;
}
}
}
.telphone-wrap {
padding: 26rpx 0;
.telphone {
font-weight: bold;
color: $base-color;
font-size: $font-size-sub;
}
&>.iconfont {
width: 60rpx;
height: 48rpx;
line-height: 48rpx;
text-align: center;
background-color: #f4f5fa;
border-radius: 6rpx;
}
}
.address-wrap {
.address-name {
width: 520rpx;
line-height: 1.5;
color: $color-sub;
font-size: $font-size-tag;
}
.address-location {
margin-top: 12rpx;
display: flex;
align-items: center;
font-size: $font-size-tag;
color: #999ca7;
.icondiy {
font-size: $font-size-tag;
margin-right: 4rpx;
}
}
&>.icondiy {
width: 60rpx;
height: 48rpx;
line-height: 48rpx;
text-align: center;
background-color: #f4f5fa;
border-radius: 6rpx;
}
}
}
.detail-map {
background-color: #fff;
margin: 0 30rpx 30rpx;
border-radius: 18rpx;
margin-bottom: calc(constant(safe-area-inset-bottom) + 170rpx);
margin-bottom: calc(env(safe-area-inset-bottom) + 170rpx);
.map-head {
padding-left: 24rpx;
height: 100rpx;
line-height: 100rpx;
font-size: $font-size-toolbar;
font-weight: bold;
}
.map-body {
width: 100%;
height: 460rpx;
}
}
.store-action-fill {
padding-bottom: calc(constant(safe-area-inset-bottom) + 170rpx);
padding-bottom: calc(env(safe-area-inset-bottom) + 170rpx);
}
.store-action {
position: fixed;
background-color: #fff;
bottom: 0;
right: 0;
left: 0;
display: flex;
justify-content: center;
padding: 30rpx 0;
button {
width: 406rpx;
color: #fff;
font-size: 30rpx;
border-radius: 50rpx;
}
}
}
</style>

444
pages_tool/store/list.vue Normal file
View File

@@ -0,0 +1,444 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="store-list-wrap">
<view class="curr-store" v-if="globalStoreConfig && globalStoreConfig.store_business == 'store'">
<view class="store-desc">当前定位</view>
<view class="store-name-wrap">
<view class="store-name multi-hidden">{{ currentPosition || '定位中...' }}</view>
<view class="store-position" @click="reposition()">
<text class="iconfont icon-dingwei"></text>
<text>重新定位</text>
</view>
</view>
</view>
<view class="store-list-box">
<view class="store-list-head">
<view class="head-name">门店列表</view>
<view class="head-search">
<text class="iconfont icon-sousuo" @click="getData()"></text>
<input type="text" v-model="keyword" placeholder-class="input-placeholder" placeholder="搜索门店" @confirm="getData()" />
</view>
</view>
<scroll-view scroll-y="true" class="store-list-body" :style="{ height: globalStoreConfig && globalStoreConfig.store_business == 'store' ? 'calc(100vh - 320rpx)' : '' }">
<view :class="['store-item', { active: globalStoreInfo && item.store_id == globalStoreInfo.store_id }]" v-for="(item, index) in dataList" :key="index" @click="storeTap(item)">
<view class="item-state" :class="item.is_frozen.is_frozen == 1 || item.status == 0 ? 'warning' : ''">
{{ (item.is_frozen.is_frozen == 1 && '已停业') || (item.status == 0 && '休息中') || (item.status == 1 && '营业中') || '--' }}
</view>
<view class="item-name multi-hidden">{{ item.store_name }}</view>
<view class="item-close-desc" v-if="item.status == 0 && item.close_desc">
{{ item.close_desc }}
</view>
<view class="item-time">
<view class="item-time-left">
<text class="iconfont icon-shijian1"></text>
<text>{{ item.open_date || '--' }}</text>
</view>
<view class="item-time-right" v-if="item.distance">
{{ item.distance > 1 ? item.distance + 'km' : item.distance * 1000 + 'm' }}
</view>
</view>
<view class="item-address">
<text class="iconfont icon-location"></text>
<text>{{ item.show_address }}</text>
</view>
<view class="item-other">
<view class="other-tag-wrap">
<text class="tag-item" v-if="item.is_default == 1">总店</text>
<text class="tag-item" v-if="item.is_pickup == 1">门店自提</text>
<text class="tag-item" v-if="item.is_o2o == 1">同城配送</text>
<text class="tag-item" v-if="item.is_express == 1">物流配送</text>
</view>
<view class="other-action" @click.stop="selectStore(item)">
<text>详情</text>
<text class="iconfont icon-right"></text>
</view>
</view>
</view>
<ns-empty v-if="!dataList.length" text="您的附近暂无可选门店" :isIndex="false"></ns-empty>
</scroll-view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import Config from '@/common/js/config.js';
export default {
components: {},
data() {
return {
dataList: [],
latitude: null, // 纬度
longitude: null, // 经度
currentPosition: '', //当前位置
keyword: '' //搜索内容
};
},
watch: {
location: function(nVal) {
if (nVal) {
this.latitude = nVal.latitude;
this.longitude = nVal.longitude;
this.getData();
this.getCurrentLocation();
}
}
},
onLoad(option) {
// #ifdef H5
// H5地图选择位置回调数据
if (option.module && option.module == 'locationPicker') {
this.latitude = option.latng.split(',')[0];
this.longitude = option.latng.split(',')[1];
this.currentPosition = option.addr + option.name;
}
// #endif
//地图选点已经选中坐标的话就不要再重复选择了
if(!this.currentPosition){
if (this.location) {
this.latitude = this.location.latitude;
this.longitude = this.location.longitude;
this.getCurrentLocation();
} else if (this.mapConfig.wap_is_open == 1) {
this.$nextTick(()=>{
this.$util.getLocation({
fail: res => {
// 拒绝定位
this.currentPosition = '未获取到定位';
}
});
})
}
}
this.getData();
},
onShow() {
// 定位信息过期后,重新获取定位
if(this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) {
this.$util.getLocation({
fail: (res) => {
// 拒绝定位
this.currentPosition = '未获取到定位';
}
});
}
},
methods: {
getData() {
let data = {};
data.keyword = this.keyword;
if (this.latitude && this.longitude) {
data.latitude = this.latitude;
data.longitude = this.longitude;
}
this.$api.sendRequest({
url: '/api/store/page',
data: data,
success: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
if (res.code == 0 && res.data) {
this.dataList = res.data.list;
this.dataList.forEach(item => {
item.show_address = item.full_address.replace(/,/g, ' ') + ' ' + item.address;
});
} else {
this.$util.showToast({
title: res.message
});
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
storeTap(item) {
uni.setStorageSync('manual_store_info', item); // 记录手动切换的门店
this.changeStore(item, true); // 切换门店数据
},
selectStore(item) {
this.$util.redirectTo('/pages_tool/store/detail', {
store_id: item.store_id
});
},
// 根据经纬度获取位置
getCurrentLocation() {
let data = {};
if (this.latitude && this.longitude) {
data.latitude = this.latitude;
data.longitude = this.longitude;
}
this.$api.sendRequest({
url: '/api/store/getLocation',
data: data,
success: res => {
if (res.code == 0 && res.data) {
this.currentPosition = res.data.formatted_addresses.recommend; // 结合知名地点形成的描述性地址,更具人性化特点
} else {
this.currentPosition = '未获取到定位';
}
}
});
},
// 打开地图重新选择位置
reposition() {
// #ifdef MP
uni.chooseLocation({
success: res => {
this.latitude = res.latitude;
this.longitude = res.longitude;
this.currentPosition = res.name;
this.getData();
this.getCurrentLocation();
},
fail(res) {
uni.getSetting({
success: function(res) {
var statu = res.authSetting;
if (!statu['scope.userLocation']) {
uni.showModal({
title: '是否授权当前位置',
content: '需要获取您的地理位置,请确认授权,否则地图功能将无法使用',
success(tip) {
if (tip.confirm) {
uni.openSetting({
success: function(data) {
if (data.authSetting['scope.userLocation'] === true) {
this.$util.showToast({
title: '授权成功'
});
//授权成功之后再调用chooseLocation选择地方
setTimeout(function() {
uni.chooseLocation({
success: data => {
this.latitude = res.latitude;
this.longitude = res.longitude;
this.currentPosition = res.name;
this.getData();
this.getCurrentLocation();
}
});
}, 1000);
}
}
});
} else {
this.$util.showToast({
title: '授权失败'
});
}
}
});
}
}
});
}
});
// #endif
// #ifdef H5
let backurl = Config.h5Domain + '/pages_tool/store/list'; // 地图选择位置后的回调页面路径
window.location.href = 'https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=' + encodeURIComponent(backurl) + '&key=' + Config.mpKey + '&referer=myapp';
// #endif
}
}
};
</script>
<style scoped lang="scss">
/deep/ .input-placeholder {
color: #b3b4b9;
font-size: $font-size-tag;
}
</style>
<style lang="scss" scoped>
.store-list-wrap {
.curr-store {
background-color: #fff;
margin-bottom: 20rpx;
padding: 20rpx 24rpx 0;
.store-desc {
font-size: $font-size-tag;
color: #636363;
}
.store-name-wrap {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12rpx 0 30rpx;
.store-name {
width: 500rpx;
font-size: $font-size-sub;
font-weight: bold;
line-height: 1.5;
}
.store-position {
font-size: $font-size-tag;
color: #df5948;
.iconfont {
margin-right: 10rpx;
}
}
}
}
.store-list-box {
background-color: #fff;
padding: 0 24rpx 24rpx;
.store-list-head {
padding: 34rpx 0 10rpx;
display: flex;
align-items: center;
justify-content: space-between;
.head-name {
font-size: $font-size-sub;
color: #666;
}
.head-search {
display: flex;
align-items: center;
width: 218rpx;
height: 68rpx;
background-color: #f0f1f3;
border-radius: 50rpx;
color: #b3b4b9;
padding: 0 26rpx;
box-sizing: border-box;
.iconfont {
font-size: $font-size-sub;
margin-right: 10rpx;
}
input {
color: #666;
}
}
}
.store-list-body {
.store-item {
margin: 20rpx 6rpx 30rpx;
padding: 26rpx 28rpx;
display: flex;
flex-direction: column;
align-items: baseline;
box-shadow: 0 0 10rpx 0 rgba(128, 132, 148, 0.3);
border-radius: 10rpx;
&.active {
border: 2rpx solid #df5948;
}
.item-state {
padding: 8rpx 10rpx;
font-size: $font-size-tag;
border: 2rpx solid #66ad95;
color: #66ad95;
border-radius: 4rpx;
line-height: 1;
&.warning{
color:red;
border-color: red;
}
}
.item-name {
margin: 24rpx 0 10rpx;
font-size: $font-size-toolbar;
font-weight: bold;
line-height: 1.5;
}
.item-close-desc{
font-size: $font-size-tag;
color:red;
}
.item-time {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.item-time-left {
display: flex;
align-items: center;
justify-content: space-between;
font-size: $font-size-tag;
color: #5f6067;
.iconfont {
margin-right: 10rpx;
}
}
.item-time-right {
color: #5f6067;
font-size: $font-size-tag;
}
}
.item-address {
margin-top: 6rpx;
font-size: $font-size-tag;
color: #5f6067;
line-height: 1.3;
.iconfont {
margin-right: 10rpx;
}
}
.item-other {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 26rpx;
.other-tag-wrap {
.tag-item {
padding: 8rpx 12rpx;
margin-right: 20rpx;
font-size: $font-size-tag;
color: #77ab69;
background-color: #f3f9ed;
border-radius: 4rpx;
}
}
.other-action {
display: flex;
align-items: baseline;
font-size: $font-size-tag;
color: #df5948;
line-height: 1;
.iconfont {
font-size: $font-size-tag;
}
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,401 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="container">
<view v-if="payInfo && memberInfo">
<view class="paycode-wrap">
<view class="member-wrap">
<view class="headimg" @click="getWxAuth">
<image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head" mode="widthFix" @error="memberInfo.headimg = $util.getDefaultImage().head"/>
</view>
<view class="info-wrap">
<view class="nickname">{{ memberInfo.nickname }}</view>
<view class="member-level" v-if="memberInfo.member_level" @click="$util.redirectTo(memberInfo.member_level_type ? '/pages_tool/member/card' : '/pages_tool/member/level')">
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_tag.png')" mode="widthFix" class="level-icon"></image>
<view class="level-name">{{ memberInfo.member_level_name }}</view>
</view>
</view>
<view class="recharge" v-if="addonIsExist.memberrecharge && memberrechargeConfig && memberrechargeConfig.is_use" @click="$util.redirectTo('/pages_tool/recharge/list')">
去充值
</view>
</view>
<view class="body-wrap">
<view class="barcode-wrap">
<image :src="payInfo.barcode" class="barcode"></image>
</view>
<view class="auth-code">
<text class="price-font">{{ show ? splitFn(payInfo.auth_code) : payInfo.auth_code.substring(0, 5) + '******' }}</text>
<text class="show" v-if="!show" @click="showAuthCode(true)">查看数字</text>
<text class="show" v-else @click="showAuthCode(false)">隐藏数字</text>
</view>
<image :src="payInfo.qrcode" mode="widthFix" class="qrcode"></image>
<view class="dynamic-code" @click="getPayAuthCode">
<view class="code">
动态码
<text>{{ payInfo.dynamic_code }}</text>
<text class="iconfont icon-shuaxin"></text>
</view>
</view>
<view class="tips">付款码仅用于支付时向收银员出示请勿发送给他人</view>
</view>
<view class="footer-wrap">
<view class="account-item" @click="$util.redirectTo('/pages_tool/member/point')">
<view class="value price-font">{{ parseInt(memberInfo.point) }}</view>
<view class="title">积分</view>
</view>
<view class="split"></view>
<view class="account-item" @click="$util.redirectTo('/pages_tool/member/balance')">
<view class="value price-font">
{{ (parseFloat(memberInfo.balance) + parseFloat(memberInfo.balance_money)) | moneyFormat }}
</view>
<view class="title">余额</view>
</view>
<view class="split"></view>
<view class="account-item" @click="$util.redirectTo('/pages_tool/member/coupon')">
<view class="value price-font">{{ memberInfo.coupon_num ? memberInfo.coupon_num : 0 }}</view>
<view class="title">优惠券</view>
</view>
</view>
</view>
</view>
<loading-cover ref="loadingCover"></loading-cover>
<ns-login ref="login"></ns-login>
</view>
</template>
<script>
export default {
data() {
return {
isRepeat: false,
payInfo: null,
error: 0,
timer: null,
show: false,
memberrechargeConfig: null,
screenBrightness: 0
};
},
onShow() {
uni.setStorageSync('paySource', '');
if (this.storeToken) {
this.getCouponNum();
this.getMemberrechargeConfig();
this.getPayAuthCode();
// #ifndef H5
uni.getScreenBrightness({
success: res => {
this.screenBrightness = res.value;
}
});
uni.setScreenBrightness({
value: 1,
success: function() {}
});
// #endif
} else {
this.$nextTick(() => {
this.$refs.login.open('/pages_tool/store/payment_qrcode');
});
}
},
onLoad() {},
methods: {
getPayAuthCode() {
if (this.isRepeat) return;
this.isRepeat = true;
if (this.timer) clearInterval(this.timer);
this.$api.sendRequest({
url: '/api/pay/memberpaycode',
success: res => {
this.isRepeat = false;
if (res.code == 0 && res.data) {
this.payInfo = res.data;
this.error = 0;
this.show = false;
// this.refreshPaymentCode();
setTimeout(() => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}, 100);
} else if (this.error < 5) {
this.error++;
this.getPayAuthCode();
} else {
this.$util.showToast({
title: res.message
});
}
}
});
},
refreshPaymentCode() {
this.timer = setInterval(() => {
this.getPayAuthCode();
}, 30000);
},
showAuthCode(bool) {
this.show = bool;
},
/**
* 获取充值提现配置
*/
getMemberrechargeConfig() {
this.$api.sendRequest({
url: '/memberrecharge/api/memberrecharge/config',
success: res => {
if (res.code >= 0 && res.data) {
this.memberrechargeConfig = res.data;
}
}
});
},
/**
* 查询优惠券数量
*/
getCouponNum() {
this.$api.sendRequest({
url: '/coupon/api/coupon/num',
success: res => {
if (res.code == 0) {
this.memberInfo.coupon_num = res.data;
this.$forceUpdate();
this.$store.commit('setMemberInfo', this.memberInfo);
}
}
});
},
splitFn(str, length = 4) {
let reg = new RegExp('[^\n]{1,' + length + '}', 'g');
let res = str.match(reg);
return res.join(' ');
}
},
watch: {
storeToken: function(nVal, oVal) {
this.getPayAuthCode();
}
},
onHide() {
if (this.timer) clearInterval(this.timer);
uni.setScreenBrightness({
value: this.screenBrightness,
success: function() {}
});
},
onUnload() {
if (this.timer) clearInterval(this.timer);
uni.setScreenBrightness({
value: this.screenBrightness,
success: function() {}
});
}
};
</script>
<style lang="scss">
.container {
width: 100vw;
min-height: 100vh;
background: $base-color;
padding: 30rpx;
box-sizing: border-box;
overflow-y: auto;
}
.paycode-wrap {
overflow: hidden;
background: #fff;
border-radius: 20rpx;
.member-wrap {
padding: 36rpx 32rpx;
background: #f6f6f6;
display: flex;
align-items: center;
.headimg {
width: 88rpx;
height: 88rpx;
overflow: hidden;
border-radius: 50%;
margin-right: 20rpx;
image {
width: 88rpx;
height: 88rpx;
}
}
.info-wrap {
flex: 1;
width: 0;
}
.nickname {
font-size: 30rpx;
font-weight: 600;
white-space: nowrap;
overflow: hidden;
line-height: 1;
}
.member-level {
background: #474758;
padding: 0;
margin: 16rpx 0 0 0;
height: 40rpx;
border-radius: 40rpx;
display: inline-flex;
align-items: center;
.level-icon {
width: 40rpx;
vertical-align: middle;
margin-left: -2rpx;
}
.level-name {
padding: 0 20rpx 0 6rpx;
color: #ddc095;
font-size: 24rpx;
display: inline-block;
line-height: 1;
}
}
.recharge {
color: $base-color;
border: 2rpx solid $base-color;
height: 64rpx;
line-height: 64rpx;
border-radius: 64rpx;
font-size: 26rpx;
padding: 0 30rpx;
letter-spacing: 4rpx;
}
}
.body-wrap {
margin: 40rpx 40rpx 0 40rpx;
width: calc(100% -80rpx);
box-sizing: border-box;
text-align: center;
padding-bottom: 40rpx;
position: relative;
border-bottom: 2rpx dashed #dedede;
.barcode-wrap {
width: 590rpx;
height: 200rpx;
overflow: hidden;
margin: 0 auto;
.barcode {
width: 590rpx;
height: 250rpx;
}
}
.qrcode {
width: 320rpx;
margin-top: 30rpx;
}
.tips {
color: #999999;
font-size: 24rpx;
margin-top: 20rpx;
}
.dynamic-code {
display: flex;
align-items: center;
justify-content: center;
.code {
background: #f6f6f6;
color: #666;
padding: 4rpx 26rpx;
border-radius: 60rpx;
text {
margin-left: 10rpx;
}
}
}
.auth-code {
color: #999999;
font-size: 24rpx;
margin-top: 20rpx;
.price-font {
letter-spacing: 2rpx;
}
.show {
color: #163d8f;
font-size: 26rpx;
margin-left: 20rpx;
}
}
&:after,
&:before {
content: ' ';
width: 40rpx;
height: 40rpx;
background: $base-color;
border-radius: 50%;
z-index: 5;
bottom: 0;
display: block;
position: absolute;
}
&:after {
right: 0;
transform: translate(calc(50% + 40rpx), 50%);
}
&:before {
left: 0;
transform: translate(calc(-50% - 40rpx), 50%);
}
}
.footer-wrap {
padding: 50rpx 0;
display: flex;
align-items: center;
.split {
width: 2rpx;
background: #dddddd;
height: 50rpx;
}
.account-item {
flex: 1;
text-align: center;
.value {
font-size: 32rpx;
color: $base-color;
line-height: 1.5;
}
.title {
color: #999999;
font-size: 24rpx;
margin-top: 10rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,193 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<scroll-view scroll-y="true" class="scroll-view" >
<view class="container" :style="{backgroundImage: 'url('+ $util.img('/public/uniapp/store/payment/header_bg.png') +')'}">
<view class="header-wrap"></view>
<view class="store-wrap">
<view class="tips">支付时请确保您的账户有足够的余额</view>
<view class="store-list" @click="$util.redirectTo('/pages_tool/store/list')" v-if="addonIsExist.store">
<image :src="$util.img('/public/uniapp/store/payment/vip_icon.png')" mode="widthFix"></image>
<text>查看门店列表</text>
<text class="iconfont icon-right"></text>
</view>
</view>
<view class="menu-wrap">
<view class="menu-list">
<view class="menu-item" @click="redirect('/pages_tool/recharge/list')">
<image :src="$util.img('/public/uniapp/store/payment/recharge.png')" mode="widthFix"></image>
<view class="title">余额充值</view>
<view class="desc">余额账户充值</view>
</view>
<view class="menu-item" @click="redirect('/pages_tool/recharge/order_list')">
<image :src="$util.img('/public/uniapp/store/payment/recharge_record.png')" mode="widthFix"></image>
<view class="title">充值记录</view>
<view class="desc">余额充值记录</view>
</view>
<view class="menu-item" @click="redirect('/pages_tool/member/balance_detail')">
<image :src="$util.img('/public/uniapp/store/payment/balance_detail.png')" mode="widthFix"></image>
<view class="title">余额明细</view>
<view class="desc">余额变更明细</view>
</view>
<view class="menu-item" @click="redirect('/pages_tool/member/balance')">
<image :src="$util.img('/public/uniapp/store/payment/balance.png')" mode="widthFix"></image>
<view class="title">我的余额</view>
<view class="desc">我的余额</view>
</view>
<!-- <view class="menu-item" @click="redirect('/pages_tool/member/point_detail')">
<image :src="$util.img('/public/uniapp/store/payment/point.png')" mode="widthFix"></image>
<view class="title">积分明细</view>
<view class="desc">积分变更明细</view>
</view> -->
</view>
<view class="pay-btn" @click="redirect('/pages_tool/store/payment_qrcode')">立即进入支付页面</view>
</view>
<view class="content-wrap">
<image :src="$util.img('/public/uniapp/store/payment/payment_tips.png')" mode="widthFix"></image>
</view>
<view class="content-wrap">
<image :src="$util.img('/public/uniapp/store/payment/payment_strategy.png')" mode="widthFix"></image>
</view>
</view>
<ns-login ref="login"></ns-login>
<diy-bottom-nav></diy-bottom-nav>
</scroll-view>
</template>
<script>
export default {
data() {
return {};
},
onLoad(options) {},
methods: {
/**
* 跳转
* @param {Object} url
*/
redirect(url) {
if (!this.storeToken) {
this.$refs.login.open(url);
} else {
this.$util.redirectTo(url);
}
}
}
};
</script>
<style lang="scss">
.scroll-view {
width: 100vw;
height: 100vh;
.container {
width: 100%;
background-repeat: no-repeat;
background-size: 100%;
}
}
.header-wrap {
height: 200rpx;
}
.store-wrap {
margin: 0 30rpx;
background: linear-gradient(90deg, rgba(0,0,0,0.48) 0%, rgba(0,0,0,0.88) 100%);
border-radius: 24rpx;
padding: 30rpx 20rpx 60rpx 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
.tips {
color: #F2C7B5;
font-size: 24rpx;
font-weight: 600;
}
.store-list {
background: rgba(255, 255, 255, .2);
display: flex;
align-items: center;
height: 40rpx;
border-radius: 40rpx;
padding: 0 10rpx 0 4rpx;
text {
font-size: 24rpx;
color: #EFCAB6;
margin-left: 10rpx;
line-height: 1;
}
image {
width: 32rpx;
height: 32rpx;
}
}
}
.menu-wrap {
background: #fff;
border-radius: 24rpx;
margin: 0 30rpx;
padding: 30rpx 30rpx 60rpx 30rpx;
transform: translateY(-40rpx);
.menu-list {
display: flex;
.menu-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
image {
width: 96rpx;
height: 96rpx;
}
.title {
margin-top: 10rpx;
font-size: 28rpx;
color: #222;
font-weight: 600;
}
.desc {
font-size: 18rpx;
color: #999999;
text-align: center;
}
}
}
.pay-btn {
height: 98rpx;
line-height: 98rpx;
background: #F72D1E;
border-radius: 98rpx;
margin: 60rpx auto 0 auto;
font-size: 34rpx;
font-weight: 600;
color: #FFFFFF;
text-align: center;
}
}
.content-wrap {
background: #fff;
border-radius: 24rpx;
margin: 30rpx;
padding: 0;
overflow: hidden;
transform: translateY(-40rpx);
image {
width: 100%;
}
}
</style>

View File

@@ -0,0 +1,220 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="container">
<view class="site-wrap">
<view class="site-header">
<view class="shu color-base-bg"></view>
<view class="order-detail font-size-base">订单明细</view>
</view>
<view class="xian"></view>
<view class="site-body">
<block v-for="(goodsItem, goodsIndex) in verifyInfo.item_array" :key="goodsIndex">
<view class="goods-wrap">
<view class="goods-img"><image :src="$util.img(goodsItem.img)" @error="imageError(goodsIndex)" mode="aspectFill"></image></view>
<view class="info-wrap">
<view class="goods-info">
<text class="goods-name font-size-base">{{ goodsItem.name }}</text>
</view>
<view class="money-wrap">
<view class="align-right">{{ $lang('common.currencySymbol') }}{{ goodsItem.price | abs }}</view>
<view class="align-right color-tip">
<text class="iconfont icon-close"></text>
{{ goodsItem.num }}
</view>
</view>
</view>
</view>
<view class="all">
<view class="all-num">{{ goodsItem.num }}件商品</view>
<view class="all-money color-base-text">
<text>合计:</text>
{{ goodsItem.all | abs }}
</view>
</view>
</block>
<view class="xian"></view>
<view class="order-cell" v-for="(remarkItem, remarkIndex) in verifyInfo.remark_array" :key="remarkIndex" v-if="remarkItem.value">
<text class="tit">{{ remarkItem.title }}</text>
<view class="box">
<text class="color-tip">{{ remarkItem.value }}</text>
<view class="copy" @click="copy(remarkItem.value)" v-if="remarkItem.title == '订单编号'">复制</view>
</view>
</view>
</view>
</view>
<view class="order-summary">
<view class="site-header">
<view class="shu color-base-bg"></view>
<view class="order-detail">核销明细</view>
</view>
<view class="xian"></view>
<view class="order-cell">
<text class="tit">核销类型</text>
<view class="box">
<text class="color-tip">{{ verifyInfo.verify_type_name }}</text>
</view>
</view>
<block v-if="verifyInfo.is_verify">
<view class="order-cell">
<text class="tit">核销状态</text>
<view class="box"><text class="color-tip">已核销</text></view>
</view>
<view class="order-cell" v-if="verifyInfo.verify_time">
<text class="tit">核销人员</text>
<view class="box">
<text class="color-tip">{{ verifyInfo.verifier_name }}</text>
</view>
</view>
<view class="order-cell" v-if="verifyInfo.verify_time">
<text class="tit">核销时间</text>
<view class="box">
<text class="color-tip">{{ $util.timeStampTurnTime(verifyInfo.verify_time) }}</text>
</view>
</view>
</block>
</view>
<view class="verify-btn" @click="verify" v-if="verifyInfo.is_verify == 0"><button type="primary">确认使用</button></view>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
export default {
data() {
return {
code: '',
verifyInfo: {
verify_content: {
item_array: [],
remark_array: []
}
},
info: [],
isSub: false
};
},
onLoad(option) {
if (option.code) this.code = option.code;
// 小程序扫码进入
if (option.scene) {
var sceneParams = decodeURIComponent(option.scene);
sceneParams = sceneParams.split('&');
if (sceneParams.length) {
sceneParams.forEach(item => {
if (item.indexOf('code') != -1) this.code = item.split('-')[1];
});
}
}
},
onShow() {
if (this.storeToken) this.checkIsVerifier();
else this.$util.redirectTo('/pages/member/index');
this.getVerifyInfo();
},
methods: {
checkIsVerifier() {
this.$api.sendRequest({
url: '/api/verify/checkisverifier',
success: res => {
if (!res.data) {
this.$util.showToast({
title: '非核销员无此权限'
});
setTimeout(() => {
uni.navigateBack({
delta: 1
});
}, 1000);
}
}
});
},
getVerifyInfo() {
this.$api.sendRequest({
url: '/api/verify/verifyInfo',
data: {
verify_code: this.code
},
success: res => {
if (res.code >= 0) {
this.verifyInfo = res.data;
this.info = this.verifyInfo.remark_array.splice(0, 1);
this.verifyInfo.item_array.forEach(item => {
item.all = item.num * item.price;
});
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
} else {
this.$util.showToast({
title: res.message
});
setTimeout(() => {
uni.navigateBack({
delta: 1
});
}, 1000);
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
verify() {
if (this.isSub) return;
this.isSub = true;
this.$api.sendRequest({
url: '/api/verify/verify',
data: {
verify_code: this.code
},
success: res => {
this.$util.showToast({
title: res.message
});
if (res.code >= 0) {
let jump = true;
let arr = getCurrentPages().reverse();
let jump_url = 'pages_tool/verification/index';
for (let i = 0; i < arr.length; i++) {
if (jump_url.indexOf(arr[i].route) != -1) {
jump = false;
setTimeout(() => {
uni.navigateBack({
delta: i
});
}, 1000);
break;
}
}
if (jump) {
this.$util.redirectTo('/pages_tool/verification/index',{},'redirectTo');
}
} else {
this.isSub = false;
}
}
});
},
imageError(index) {
this.verifyInfo.item_array[index].img = this.$util.getDefaultImage().goods;
this.$forceUpdate();
},
copy(str) {
this.$util.copy(str);
}
},
filters: {
abs(value) {
return Math.abs(parseFloat(value)).toFixed(2);
}
}
};
</script>
<style lang="scss">
@import './public/css/detail.scss';
</style>

View File

@@ -0,0 +1,369 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="container">
<view class="action-wrap">
<view class="record-wrap color-base-text" @click="$util.redirectTo('/pages_tool/verification/list')">
<text class="iconfont icon-jilu color-base-text"></text>
<text>核销记录</text>
</view>
<view class="sweep-code ns-gradient-otherpages-member-balance-balance-rechange" @click="scanCode" v-show="operationType == 'sweepCode'">
<text class="iconfont icon-saoma"></text>
</view>
<view class="manual-input" v-show="operationType == 'manualInput'">
<view class="process-wrap">
<view class="wrap">
<view class="_icon"><text class="iconfont icon-shurutianxiebi color-base-text"></text></view>
<view class="_text">输入核销码</view>
</view>
<view>
<view><text class="iconfont icon-jiang-copy color-tip"></text></view>
</view>
<view class="wrap">
<view class="_icon"><text class="iconfont icon-hexiao color-base-text"></text></view>
<view class="_text">核销</view>
</view>
</view>
<input type="text" placeholder="请输入核销码" class="_input" placeholder-class="_placeholder" v-model="verify_code" :focus="isFocus" ref="input" />
<view class="_btn" @click="confirm"><button type="primary">确认</button></view>
</view>
</view>
<view class="arc-edge"></view>
<view class="action-type-wrap">
<view class="action" @click="changeOperationType('sweepCode')">
<view class="_icon"><text class="iconfont icon-saoma"></text></view>
<view class="_text">扫码核销</view>
</view>
<view class="iconfont icon-tiaoxingmasaomiao ns-gradient-otherpages-member-balance-balance-rechange"></view>
<view class="action" @click="changeOperationType('manualInput')">
<view class="_icon"><text class="iconfont icon-shuru"></text></view>
<view class="_text" @click="focus">手动输入</view>
</view>
</view>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif -->
</view>
</template>
<script>
import { Weixin } from 'common/js/wx-jssdk.js';
import Config from '@/common/js/config.js';
export default {
data() {
return {
// #ifdef H5
operationType: 'manualInput',
// #endif
// #ifndef H5
operationType: 'sweepCode',
// #endif
verify_code: '',
isFocus: false,
detail_path:'/pages_tool/verification/detail',
};
},
onLoad() {},
onShow() {
if (this.storeToken) {
this.checkIsVerifier();
} else {
this.$nextTick(() => {
this.$refs.login.open('/pages_tool/verification/index');
});
}
},
methods: {
focus() {
this.isFocus = !this.isFocus;
},
scanCode() {
// #ifdef MP
uni.scanCode({
onlyFromCamera: true,
success: res => {
if (res.errMsg == 'scanCode:ok') {
let result = res.result;
let code = '';
switch(res.scanType){
case 'CODE_128':
code = result;
break;
case 'QR_CODE':
if(result.indexOf(this.detail_path) > -1){
let matchs = result.match(/\?code=(.+)/);
if(matchs.length == 2){
code = matchs[1];
}
}
break;
}
if(!code){
this.$util.showToast({
title: '请扫码正确的条码或二维码'
});
return;
}
this.$util.redirectTo(this.detail_path+'?code='+code);
} else {
this.$util.showToast({
title: res.errorMsg
});
}
}
});
// #endif
// #ifdef H5
if (this.$util.isWeiXin()) {
if (uni.getSystemInfoSync().platform == 'ios') {
var url = uni.getStorageSync('initUrl');
} else {
var url = location.href;
}
this.$api.sendRequest({
url: '/wechat/api/wechat/jssdkconfig',
data: {
url: url
},
success: jssdkRes => {
if (jssdkRes.code == 0) {
var wxJS = new Weixin();
wxJS.init(jssdkRes.data);
wxJS.scanQRCode(res => {
if (res.resultStr) {
let result = res.resultStr;
let code = '';
if (result.indexOf(this.detail_path) != -1){
let matchs = result.match(/\?code=(.+)/);
if(matchs.length == 2){
code = matchs[1];
}
}else if(result.indexOf('CODE_128') != -1){
code = result.split(',')[1];
}
if(!code){
this.$util.showToast({
title: '请扫码正确的条码或二维码'
});
return;
}
this.$util.redirectTo(this.detail_path+'?code='+code);
}
});
} else {
this.$util.showToast({
title: jssdkRes.message
});
}
}
});
}
// #endif
},
changeOperationType(type) {
// #ifdef H5
if (type == 'sweepCode' && !this.$util.isWeiXin()) {
this.$util.showToast({
title: 'H5端不支持扫码核销'
});
return;
}
// #endif
this.operationType = type;
},
checkIsVerifier() {
this.$api.sendRequest({
url: '/api/verify/checkisverifier',
success: res => {
if (!res.data) {
this.$util.showToast({ title: '非核销员无此权限' });
setTimeout(() => {
this.$util.redirectTo('/pages/member/index');
}, 1000);
}
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
confirm() {
var reg = /[\S]+/;
if (!reg.test(this.verify_code)) {
this.$util.showToast({ title: '请输入核销码' });
return false;
}
this.$api.sendRequest({
url: '/api/verify/verifyInfo',
data: {
verify_code: this.verify_code
},
success: res => {
if (res.code >= 0) {
this.$util.redirectTo('/pages_tool/verification/detail', { code: this.verify_code });
} else {
this.$util.showToast({ title: res.message });
}
}
});
}
},
watch: {
storeToken: function(nVal, oVal) {
if (nVal) {
this.checkIsVerifier();
}
}
}
};
</script>
<style lang="scss">
.container {
width: 100vw;
height: 100vh;
.action-wrap {
padding: 100rpx 0;
background: #fff;
position: relative;
.record-wrap {
position: absolute;
top: 30rpx;
right: 30rpx;
.iconfont {
font-size: $font-size-tag;
margin-right: 10rpx;
}
}
.sweep-code {
width: 400rpx;
height: 400rpx;
box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.03), 0 6px 3px 0 rgba(0, 0, 0, 0.02);
border-radius: 50%;
margin: 0 auto;
text-align: center;
line-height: 400rpx;
background: $base-color;
.iconfont {
color: #fff;
font-size: 150rpx;
}
}
.manual-input {
width: 70%;
margin: auto;
.process-wrap {
height: 140rpx;
display: flex;
padding-top: 60rpx;
.wrap {
flex: 1;
text-align: center;
._icon {
width: 60rpx;
height: 60rpx;
background: #eee;
border-radius: 50%;
margin: 0 auto;
color: $color-tip;
.iconfont {
font-size: $font-size-toolbar;
}
}
._text {
font-size: $font-size-tag;
margin-top: 10rpx;
color: $color-tip;
}
}
}
._input {
height: 80rpx;
border: 1px solid #eee;
border-radius: 8rpx;
box-sizing: border-box;
padding: 20rpx;
font-size: $font-size-base;
text-align: center;
}
._placeholder {
font-size: $font-size-base;
text-align: center;
}
._btn {
margin-top: 40rpx;
height: 80rpx;
line-height: 80rpx;
}
}
}
.arc-edge {
width: 100%;
height: 80rpx;
background: #fff;
border-radius: 400rpx/40rpx; /*上下有弧度的边*/
transform: translateY(-50%);
}
.action-type-wrap {
width: 70%;
height: 90rpx;
background: #fff;
border-radius: 90rpx;
display: flex;
position: relative;
box-shadow: 0 6px 6px 0 rgba(0, 0, 0, 0.03), 0 4px 2px 0 rgba(0, 0, 0, 0.04);
margin: 100rpx auto;
.action {
flex: 1;
text-align: center;
color: $color-title;
._icon {
line-height: 25px;
height: 25px;
}
._text {
font-size: $font-size-tag;
line-height: 1;
}
}
.icon-tiaoxingmasaomiao {
width: 110rpx;
height: 110rpx;
border-radius: 50%;
transform: translateY(-10rpx);
box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.03), 0 6px 3px 0 rgba(0, 0, 0, 0.02);
text-align: center;
line-height: 110rpx;
background: $base-color;
color: #fff;
font-size: $font-size-toolbar;
}
}
}
</style>

View File

@@ -0,0 +1,186 @@
<template>
<page-meta :page-style="themeColor"></page-meta>
<view class="verify-container">
<view class="type-wrap">
<view v-for="(typeItem, typeIndex) in typeList" :key="typeIndex" class="uni-tab-item" :id="typeItem.pickup" :data-current="typeIndex" @click="ontabtap">
<text class="uni-tab-item-title" :class="type == typeIndex ? 'uni-tab-item-title-active color-base-text color-base-border' : ''">{{ typeItem.name }}</text>
</view>
</view>
<swiper :current="type" class="swiper-box" style="flex: 1;" :duration="200" @change="ontabchange">
<swiper-item class="swiper-item" :key="typeIndex" v-for="(typeItem, typeIndex) in typeList">
<scroll-view scroll-y="true" class="verify-list" @scrolltolower="scrolltolower">
<block v-if="verifyList[typeIndex] != undefined && verifyList[typeIndex].list.length > 0">
<view class="item" v-for="(item, index) in verifyList[typeIndex].list" :key="index">
<view @click="toDetail(item.verify_code)">
<view class="header">
<view class="color-tip font-size-goods-tag">核销码{{ item.verify_code }}</view>
<view class="color-tip align-right font-size-goods-tag">核销员{{ item.verifier_name }}</view>
</view>
<view class="xian"></view>
<view class="body">
<view class="content-item" v-for="(citem, citemIndex) in item.item_array" :key="citemIndex">
<view class="img-wrap">
<image :src="$util.img(citem.img)" @error="imageError(typeIndex, index, citemIndex)" mode="aspectFill"></image>
</view>
<view class="info-wrap">
<view class="name-wrap">
<view class="goods-name font-size-tag">{{ citem.name }}</view>
<view class="font-size-goods-tag color-tip">核销时间{{ $util.timeStampTurnTime(item.verify_time) }}</view>
</view>
<view class="money-wrap">
<view class="align-right color-tip font-size-goods-tag">
<text class="iconfont icon-close font-size-goods-tag"></text>
<text>{{ citem.num }}</text>
</view>
</view>
</view>
<view class="money-wrap">
<view>
<text class="color-base-text font-size-goods-tag">{{ $lang('common.currencySymbol') }}</text>
<text class="font-size-base color-base-text">{{ citem.price | abs }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</block>
<block v-else><ns-empty :isIndex="false" text="暂无核销记录!"></ns-empty></block>
</scroll-view>
</swiper-item>
</swiper>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
export default {
data() {
return {
scrollInto: '',
type: 0,
typeList: [],
verifyList: [],
isShow: false
};
},
onShow() {
this.getVerifyType();
},
methods: {
toDetail(id) {
this.$util.redirectTo('/pages_tool/verification/detail', {
code: id
});
},
ontabtap(e) {
let index = e.target.dataset.current || e.currentTarget.dataset.current;
this.switchTab(index);
this.isShow = false;
},
switchTab(index) {
if (this.type === index) {
return;
}
this.type = index;
this.scrollInto = this.typeList[index].type;
},
ontabchange(e) {
let index = e.target.current || e.detail.current;
this.switchTab(index);
},
getVerifyType() {
this.$api.sendRequest({
url: '/api/verify/getVerifyType',
success: res => {
if (res.code >= 0) {
this.typeList = [];
this.verifyList = [];
Object.keys(res.data).forEach(key => {
this.typeList.push({
type: key,
name: res.data[key].name
});
this.verifyList.push({
page: 1,
totalPage: 1,
list: [],
isLoading: false
});
this.getVerifyList(key, 1, this.typeList.length - 1);
});
}
},
fail: res => {
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
}
});
},
/**
* 获取核销记录
* @param {Object} type
* @param {Object} page
* @param {Object} index
*/
getVerifyList(type, page, index) {
if (this.verifyList[index].isLoading || (page != 1 && page > this.verifyList[index].totalPage)) return;
this.verifyList[index].isLoading = true;
this.verifyList[index].loadingType = 'loading';
this.$api.sendRequest({
url: '/api/verify/lists',
data: {
verify_type: type,
page: page
},
success: res => {
this.verifyList[index].page = page;
if (page == 1) {
this.verifyList[index].list = [];
uni.stopPullDownRefresh();
}
if (res.data.list.length) {
res.data.list.forEach(item => {
this.verifyList[index].list.push(item);
});
}
this.verifyList[index].totalPage = res.data.page_count;
this.verifyList[index].isLoading = false;
this.verifyList[index].loadingType = page == this.verifyList[index].totalPage ? 'nomore' : 'more';
if (this.$refs.loadingCover) this.$refs.loadingCover.hide();
this.isShow = true;
}
});
},
/**
* 滑到底部加载
*/
scrolltolower() {
let index = this.type;
this.getVerifyList(this.typeList[index].type, this.verifyList[index].page + 1, index);
},
/**
* 下拉刷新
*/
onPullDownRefresh() {
let index = this.type;
this.getVerifyList(this.typeList[index].type, 1, index);
},
imageError(typeIndex, index, citemIndex) {
this.verifyList[typeIndex].list[index].item_array[citemIndex].img = this.$util.getDefaultImage().goods;
this.$forceUpdate();
}
},
filters: {
abs(value) {
return Math.abs(parseFloat(value)).toFixed(2);
}
}
};
</script>
<style lang="scss">
@import './public/css/list.scss';
</style>

View File

@@ -0,0 +1,237 @@
@mixin flex-row-center {
display: flex;
justify-content: center;
align-items: center;
}
@mixin wrap {
margin: $margin-updown $margin-both;
padding: $padding;
border-radius: $border-radius;
background: #fff;
position: relative;
}
.align-right {
text-align: right;
}
.container {
width: 100vw;
height: 100vh;
}
.site-wrap {
@include wrap;
padding: 0;
padding-bottom: 40rpx;
.site-header {
padding: 20rpx 20rpx 20rpx 30rpx;
display: flex;
align-items: center;
.shu {
width: 6rpx;
height: 30rpx;
background: rgba(255, 69, 68, 1);
margin-right: 14rpx;
}
.icon-dianpu {
display: inline-block;
line-height: 1;
margin-right: 12rpx;
font-size: $font-size-base;
}
}
.xian {
width: 100%;
border: 0.5px solid #e7e7e7;
}
.site-body {
margin: 20rpx;
.goods-wrap {
padding: 0 20rpx 20rpx 20rpx;
display: flex;
padding-top: 20rpx;
.goods-img {
flex: 2;
width: 120rpx;
height: 120rpx;
image {
width: 100%;
height: 100%;
}
}
.info-wrap {
flex: 8;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
padding-right: 23rpx;
.goods-info {
flex: 1;
padding-left: 23rpx;
.goods-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
line-height: 1.5;
font-size: $font-size-goods-tag;
color: #000000;
}
}
.money-wrap {
margin-top: 31rpx;
padding: 0 23rpx;
display: flex;
justify-content: space-between;
width: 100%;
.align-right {
font-weight: normal;
font-size: $font-size-tag;
margin-right: 2rpx;
}
.iconfont {
line-height: 1;
font-size: $font-size-tag;
}
}
}
}
.xian {
width: 100%;
border: 0.5px solid #e7e7e7;
}
.xian-other {
width: 100%;
border: 0.5px solid #e7e7e7;
}
.all {
display: flex;
justify-content: space-between;
padding: 20rpx;
align-items: baseline;
.all-num {
font-size: $font-size-goods-tag;
color: #383838;
}
.all-money {
text {
font-size: $font-size-goods-tag;
color: #383838;
margin-right: 5rpx;
}
font-size: $font-size-base;
font-weight: 500;
}
}
}
}
.order-cell {
display: flex;
margin: 28rpx 0;
align-items: center;
background: #fff;
line-height: 40rpx;
padding-left: 20rpx;
.tit {
text-align: left;
color: #838383;
font-size: $font-size-goods-tag;
}
.box {
flex: 1;
padding: 0 57rpx;
line-height: inherit;
color: #000000;
font-size: $font-size-goods-tag;
.copy {
font-size: $font-size-activity-tag;
display: inline-block;
background: #f7f7f7;
line-height: 1;
padding: 6rpx 10rpx;
margin-left: 10rpx;
border-radius: 18rpx;
border: 2rpx solid #d2d2d2;
}
.textarea {
height: 40rpx;
}
}
.iconfont {
color: #bbb;
font-size: $font-size-base;
}
.order-pay {
padding: 0;
text {
display: inline-block;
margin-left: 6rpx;
}
}
}
.order-summary {
@include wrap;
margin-bottom: 40rpx;
.site-header {
padding: 20rpx 20rpx 20rpx 30rpx;
display: flex;
align-items: center;
.shu {
width: 6rpx;
height: 30rpx;
margin-right: 14rpx;
}
.icon-dianpu {
display: inline-block;
line-height: 1;
margin-right: 12rpx;
font-size: $font-size-base;
}
}
.xian {
width: 100%;
border: 0.5px solid #e7e7e7;
}
.order-cell {
.tit {
color: #999;
font-size: $font-size-goods-tag;
}
.box {
display: flex;
align-items: center;
color: #000000;
font-size: $font-size-goods-tag;
}
}
}
.verify-btn {
margin-top: $margin-updown;
}

View File

@@ -0,0 +1,140 @@
.verify-container {
width: 100vw;
height: 100vh;
}
.align-right {
text-align: right;
}
.type-wrap {
display: flex;
background-color: #fff;
height: 90rpx;
& > view {
flex: 1;
text-align: center;
text {
line-height: 86rpx;
border-bottom: 4rpx solid #fff;
display: inline-block;
font-size: 30rpx;
}
}
}
.swiper-box {
width: 100%;
height: calc(100vh - 100rpx);
.swiper-item {
width: 100%;
height: 100%;
.verify-list {
width: 100%;
height: 100%;
}
}
}
.verify-list {
.item {
margin: 24rpx;
border-radius: $border-radius;
background: #fff;
position: relative;
padding: 30rpx;
.header {
display: flex;
padding-bottom: 30rpx;
view {
line-height: 1;
flex: 1;
max-width: 50%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.xian {
width: 100%;
border: 0.5px solid #eee;
}
.body {
.content-item {
display: flex;
padding-top: 24rpx;
.img-wrap {
width: 120rpx;
height: 120rpx;
border-radius: $border-radius;
overflow: hidden;
image {
width: 100%;
height: 100%;
}
}
.info-wrap {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
padding-right: 23rpx;
.name-wrap {
flex: 1;
padding-left: 23rpx;
.goods-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
line-height: 1.5;
color: #000000;
font-size: $font-size-base;
}
}
.money-wrap {
margin-top: 20rpx;
padding: 0 23rpx;
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
& > view {
line-height: 1;
}
.unit {
font-weight: normal;
font-size: $font-size-tag;
margin-right: 2rpx;
}
.iconfont {
line-height: 1;
// font-size: $font-size-tag;
}
}
}
.money-wrap {
font-weight: bold;
}
}
}
}
}

View File

@@ -0,0 +1,48 @@
<template>
<view>
<view class="error-msg">{{errorMsg}}</view>
</view>
</template>
<script>
export default {
data() {
return {
outTradeNo:'',
errorMsg:'',
}
},
onLoad(option) {
if (option.merchant_trade_no){
this.outTradeNo = option.merchant_trade_no;
this.getOrderDetailPath();
}else{
this.errorMsg = '缺少merchant_trade_no参数';
}
},
methods: {
getOrderDetailPath(){
this.$api.sendRequest({
url: '/api/pay/outTradeNoToOrderDetailPath',
data:{
out_trade_no : this.outTradeNo,
},
success: res => {
if (res.code < 0) {
this.errorMsg = res.message || '未知错误';
}else{
this.$util.redirectTo(res.data);
}
}
});
},
},
}
</script>
<style>
.error-msg{
text-align: center;
padding-top: 10vh;
}
</style>