first commit

This commit is contained in:
2025-08-06 17:17:48 +08:00
commit dc5fba137c
453 changed files with 85995 additions and 0 deletions
@@ -0,0 +1,161 @@
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view class="activity-detail-contain">
<view class="header row-start" v-if="goodsList.length">
<text class="white header-title"> {{title}} <text class="white xxs ml20">{{name}}</text></text>
</view>
<view class="content">
<view class="goods-container">
<navigator v-for="(item, index) in goodsList" :key="index" :url="'/pages/goods_details/goods_details?id=' + item.id" class="goods-item bg-white row mb10" hover-class="none">
<view class="goods-img">
<custom-image width="100%" height="100%" radius="6rpx" lazy-load :src="item.image"></custom-image>
</view>
<view class="goods-info ml20">
<view class="goods-name line2 normal nr mb10">{{item.name}}</view>
<view class="count-buy br60 xxs">累计{{item.sales_sum}}人购买</view>
<view class="row-between mt10">
<view class="row">
<price-format :price="item.price" :subscript-size="26" :first-size="34" :second-size="26" color="#FF2C3C"></price-format >
<price-format class="ml20" :price="item.market_price" :subscript-size="24" :first-size="24" :second-size="24" color="#999999"></price-format>
</view>
<view class="buy-btn row-center br60">
马上抢
</view>
</view>
</view>
</navigator>
</view>
<loading-footer slot-empty :status="status">
<view slot="empty" class="data-null column-center" style="padding-top: 500rpx">
<image class="img-null" src="/static/images/goods_null.png"></image>
<view class="lighter">暂无活动商品</view>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
import { loadingType } from '@/utils/type';
import { getActivityGoodsLists } from "@/api/activity";
import { loadingFun } from "@/utils/tools";
export default {
data() {
return {
status: loadingType.LOADING,
goodsList: [],
page: 1,
name: '',
title: ''
};
},
components: {
},
props: {},
onLoad: function (options) {
this.id = options.id;
this.title = options.title,
this.name = options.name
uni.setNavigationBarTitle({
title: options.title
});
this.getActivityGoodsListsFun();
},
onReachBottom: function () {
this.getActivityGoodsListsFun();
},
methods: {
async getActivityGoodsListsFun() {
let {
page,
status,
goodsList
} = this;
const data = await loadingFun(getActivityGoodsLists,page, goodsList,status, {id : this.id})
if (!data) return
this.page = data.page
this.goodsList = data.dataList
this.status = data.status
}
}
};
</script>
<style>
.activity-detail-contain .header {
background-image: url(../../static/images/activity_detail_bg.png);
background-size: 100% 100%;
height: 340rpx;
width: 100%;
padding-left: 24rpx;
box-sizing: border-box;
padding-top: 20rpx;
}
.activity-detail-contain .header .header-title {
font-size: 47rpx;
}
.activity-detail-contain .content {
margin-top: -240rpx;
padding: 0 20rpx;
}
.activity-detail-contain .content .goods-container .goods-item {
padding: 30rpx 20rpx;
border-radius: 10rpx;
}
.activity-detail-contain .content .goods-container .goods-item .goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info {
flex: 1;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info .goods-name {
line-height: 40rpx;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info .count-buy {
background-color: #FEF0DA;
color: #F77A0C;
padding: 4rpx 18rpx;
display: inline-flex;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info .buy-btn {
padding: 0rpx 34rpx;
height: 60rpx;
color: white;
background: linear-gradient(90deg, #F95F2F 0%, #FF2C3C 100%);
}
.goods-container .data-null {
padding-top: 225rpx;
}
</style>
@@ -0,0 +1,341 @@
<template>
<view>
<!--pages/after_sales_detail/after_sales_detail.wxml-->
<view class="after-sales-detail">
<view class="after-sales-header">
<view class="after-sales-status white lg">
{{lists.status_text}}
</view>
<!-- <view class="after-sales-explain bg-white" hidden="{{lists.status == 2 || lists.status == 5 || lists == 6}}">
<text class="xs muted" style="line-height: 40rpx" wx:if="{{lists.status == 0 || lists.status == 1 || lists == 4}}">如果商家拒绝您可重新发起申请
如果商家同意将通过申请原路退款至您的账户中
如果商家逾期未处理平台将自动通过申请并退款给您
</text>
<text class="xs muted" style="line-height: 40rpx" wx:if="{{lists.status == 3}}">如果商家确认收到货后将会退款给您
如果商家拒绝收货该次退款将会关闭您可以重新发起退款
</text>
</view> -->
</view>
<!-- <view class="negotiation-record row-between bg-white mt20">
<view class="nr">协商记录</view>
<view class="arrow">
<image src="/images/arrow_right.png" />
</view>
</view> -->
<view class="return-address-contain row bg-white mt20" v-show="!(lists.refund_type == 0)">
<view class="nr normal address-title">退货地址</view>
<view class="sm normal address">{{lists.shop && lists.shop.address}}
{{lists.shop && lists.shop.contact}} {{lists.shop && lists.shop.mobile}}</view>
<view class="xs copy-btn row-center flex-none" @tap="onCopy">复制</view>
</view>
<view class="goods-container bg-white mt20">
<!-- <view class="goods-header row">
<view class="store-img mr10">
<image src="/images/icon_shop.png" />
</view>
<view class="store-name nr bold">
{{lists.shop.name}}
</view>
</view> -->
<view class="goods-item row">
<view class="goods-img">
<custom-image width="100%" height="100%" radius="10rpx" lazy-load
:src="lists.order_goods && lists.order_goods.image" />
</view>
<view class="goods-info">
<view class="two-txt-cut nr">{{lists.order_goods && lists.order_goods.goods_name}}</view>
<view class="row-between mt20">
<!-- <view class="md">999.00</view> -->
<price-format :price="lists.order_goods && lists.order_goods.goods_price" :firstSize="30"
:secondSize="30" :showSubscript="true" :subscriptSize="30" color="#101010" />
<view class="nr">x{{lists.order_goods && lists.order_goods.goods_num}}</view>
</view>
</view>
</view>
</view>
<view class="return-goods-container bg-white mt20">
<view class="return-goods-row row sm">
<view class="return-title">退款方式</view>
<view class="return-explain">{{lists.refund_type == 0 ? '仅退款' : '退款退货'}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">退款原因</view>
<view class="return-explain">{{lists.refund_reason}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">退款金额</view>
<view class="return-explain primary">¥{{lists.refund_price}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">退款编号</view>
<view class="return-explain">{{lists.sn}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">申请时间</view>
<view class="return-explain">{{lists.create_time}}</view>
</view>
<view class="return-goods-row row sm mt20" v-if="lists.refund_remark">
<view class="return-title">备注说明</view>
<view class="return-explain">{{lists.refund_remark}}</view>
</view>
<view class="return-goods-row row sm mt20" v-if="lists.refund_image">
<view class="return-title">图片凭证</view>
<view class="return-explain">
<custom-image mode="aspectFit" class="img-preview" radius="10rpx" :src="lists.refund_image" width="160rpx" height="160rpx" />
</view>
</view>
</view>
<view class="btn-group fixed bg-white row-end" v-show="lists.status != 6">
<view class="mr20 btn br60" @tap="showDialog">撤销申请</view>
<view class="mr20 btn br60" @tap="goRefund" v-show="lists.status == 4 || lists.status == 1">重新申请</view>
<navigator hover-class="none"
:url="'/bundle/pages/input_express_info/input_express_info?id=' + lists.id" class="mr20 btn br60"
v-show="lists.status == 2">填写快递单号</navigator>
<view class="btn br60" v-show="false">平台退款</view>
</view>
</view>
<u-modal v-model="confirmDialog" confirm-text="确定" :showCancelButton="true" :show-title="false"
confirm-color="#FF2C3C" @confirm="cancelApplyFun" @cancel="hideDialog">
<view class="column-center tips-dialog" style="padding: 20rpx 0;">
<image class="icon-lg" src="/static/images/icon_warning.png"></image>
<view style="margin-top:30rpx">是否要撤销申请</view>
</view>
</u-modal>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%开源免费商用电商系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,保留版权即可
// | 商业版本务必购买商业授权,以免引起法律纠纷
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | Gitee下载:https://gitee.com/likeshop_gitee/likeshop
// | 访问官网:https://www.likemarket.net
// | 访问社区:https://home.likemarket.net
// | 访问手册:http://doc.likemarket.net
// | 微信公众号:好象科技
// | 好象科技开发团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
afterSaleDetail,
cancelApply
} from "@/api/user";
import {
trottle,
copy
} from "@/utils/tools.js";
export default {
data() {
return {
goods: {},
reason: [],
lists: {},
copyContent: "",
confirmDialog: false
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
let {
afterSaleId,
order_id
} = options;
this.afterSaleId = afterSaleId;
this.orderId = order_id;
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
this.afterSaleDetailFun();
},
methods: {
onCopy() {
let {
lists,
copyContent
} = this;
let {
address,
contact,
mobile
} = lists.shop;
copyContent = address + " " + contact + " " + mobile;
copy(copyContent)
},
goRefund(e) {
let {
lists
} = this;
uni.navigateTo({
url: '/bundle/pages/apply_refund/apply_refund?order_id=' + this.orderId + '&afterSaleId=' +
this.afterSaleId + '&item_id=' + lists.order_goods.item_id
});
},
showDialog() {
this.confirmDialog = true
},
hideDialog() {
this.confirmDialog = false;
},
confirmCancel() {},
cancelApplyFun() {
cancelApply({
id: this.afterSaleId
}).then(res => {
if (res.code == 1) {
this.$toast({
title: res.msg
}, {
tab: 3
});
uni.$emit("refreshsale")
}
});
},
afterSaleDetailFun() {
afterSaleDetail({
id: this.afterSaleId
}).then(res => {
if (res.code == 1) {
this.lists = res.data
}
});
}
}
};
</script>
<style lang="scss">
/* pages/after_sales_detail/after_sales_detail.wxss */
.after-sales-detail {
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
.after-sales-header {
.after-sales-status {
padding: 48rpx 30rpx;
background-color: #555555;
}
.after-sales-explain {
padding: 20rpx 30rpx 24rpx;
}
}
.negotiation-record {
padding: 24rpx 30rpx;
.arrow {
width: 28rpx;
height: 28rpx;
}
}
.return-goods-container {
padding: 20rpx 24rpx 55rpx;
.return-goods-row {
line-height: 40rpx;
font-weight: 400;
}
}
.btn-group {
padding: 0rpx 24rpx;
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 100rpx;
.btn {
padding: 10rpx 34rpx;
border: 1px solid #999999;
}
}
.goods-container {
.goods-header {
padding: 20rpx 24rpx;
.store-img {
width: 40rpx;
height: 40rpx;
}
.store-name {
line-height: 40rpx;
align-self: flex-end;
font-family: PingFang SC;
}
}
.goods-item {
padding: 25rpx 24rpx;
.goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.goods-info {
margin-left: 24rpx;
flex: 1;
}
}
}
}
.return-address-contain {
padding: 20rpx 24rpx 28rpx 30rpx;
.address {
flex: 1;
line-height: 38rpx;
}
.address-title {
width: 150rpx;
align-self: flex-start;
line-height: 40rpx;
}
.copy-btn {
flex: 0 0 13%;
background-color: #F4F4F4;
color: #555555;
align-self: flex-start;
padding: 3rpx 16rpx;
margin-left: 12rpx;
border-radius: 4rpx;
}
}
.tips-dialog {
height: 230rpx;
width: 100%;
}
</style>
+394
View File
@@ -0,0 +1,394 @@
<template>
<view>
<!-- pages/apply_refund/apply_refund.wxml -->
<view class="apply-refund">
<view class="goods">
<view class="row">
<custom-image
width="160rpx"
height="160rpx"
radius="6rpx"
lazy-load
:src="goods.image"
/>
<view class="goods-info">
<view class="nr line2">{{ goods.goods_name }}</view>
<view class="xs muted mt10">{{ goods.spec_value }}</view>
</view>
</view>
</view>
<view class="opt-box mt20" :hidden="hiddenOpt">
<view class="opt-item row-between border-line" @tap="onlyRefund">
<view>
<view class="lg normal">仅退款</view>
<view class="muted xs mt10"
>未收到货与卖家协商同意无需退货只需退款</view
>
</view>
<image
style="width: 28rpx; height: 28rpx"
src="/static/images/arrow_right.png"
></image>
</view>
<view class="opt-item row-between" @tap="allRefunds">
<view>
<view class="lg normal">退货退款</view>
<view class="muted xs mt10">已收到货需退还收到的实物</view>
</view>
<image
style="width: 28rpx; height: 28rpx"
src="/static/images/arrow_right.png"
></image>
</view>
</view>
<view :hidden="!hiddenOpt">
<view class="refund-info row-between mt20">
<view class="lable">数量</view>
<view>{{ goods.goods_num }}</view>
</view>
<view class="refund-info row-between">
<view class="lable">退款金额</view>
<price-format
color="#FF2C3C"
:price="
parseFloat(goods.total_pay_price) +
parseFloat(goods.refund_express_money)
"
showSubscript="true"
:subscriptSize="28"
:firstSize="28"
:secondSize="28"
/>
</view>
<view class="refund-info row-between" @tap="showPopup">
<view class="lable">退款原因</view>
<view class="row">
<text :class="'nr ' + (reasonIndex == -1 ? 'muted' : 'normal')">{{
reasonIndex == -1 ? "请选择" : reason[reasonIndex]
}}</text>
<image
class="icon-sm ml20"
src="/static/images/arrow_right.png"
></image>
</view>
</view>
<view class="refund-info row">
<view class="label">备注说明</view>
<textarea
v-show="!showPop"
class="bg-body"
placeholder="请描述申请售后的具体原因,100字以内"
v-model="remark"
name="textarea"
></textarea>
</view>
<view class="upload bg-white">
<view class="title row-between">
<view>上传凭证</view>
<view class="muted">选填最多可上传1张</view>
</view>
<uploader
:deletable="true"
preview-size="160rpx"
:file-list="fileList"
@after-read="afterRead"
@delete="deleteImage"
image-fit="aspectFill"
/>
</view>
<button class="btn br60" type="primary" size="lg" @tap="onSubmit">
申请退款
</button>
</view>
</view>
<u-popup id="popup" v-model="showPop" mode="bottom">
<view class="pop-container bg-white">
<view class="pop-header row-center md normal"> 退款原因 </view>
<scroll-view style="height: 800rpx" :scroll-y="true">
<view class="reason-box mt20">
<radio-group @change="radioChange">
<label
v-for="(item, index) in reason"
:key="index"
class="reason-item row-between"
@tap="hidePopup"
>
<view class="reason-desc nr">
{{ item }}
</view>
<radio :value="index"></radio>
</label>
</radio-group>
</view>
</scroll-view>
</view>
</u-popup>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { refundOptType } from "@/utils/type";
import { baseURL } from "@/config/app";
import { getGoodsInfo, applyAfterSale, applyAgain } from "@/api/user";
import { uploadFile, trottle } from "@/utils/tools.js";
export default {
data() {
return {
hiddenOpt: false,
optTyle: refundOptType.ONLY_REFUND,
goods: {},
reason: [],
showPop: false,
reasonIndex: -1,
fileList: [],
remark: "",
};
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let { order_id, item_id, afterSaleId } = options;
this.orderId = order_id;
this.itemId = item_id;
this.afterSaleId = afterSaleId;
this.getGoodsInfoFun();
this.onSubmit = trottle(this.onSubmit, 1000, this);
},
methods: {
showPopup() {
this.showPop = true;
},
radioChange(e) {
this.reasonIndex = e.detail.value;
},
hidePopup() {
this.showPop = false;
},
onlyRefund: function () {
this.optTyle = refundOptType.ONLY_REFUND;
this.hiddenOpt = true;
},
allRefunds() {
this.optTyle = refundOptType.REFUNDS;
this.hiddenOpt = true;
},
onSubmit() {
console.log(this.afterSaleId);
if (this.afterSaleId) {
this.applyAgainFun();
} else {
this.applyAfterSaleFun();
}
},
// 重新申请
applyAgainFun() {
let { reason, reasonIndex, optTyle, remark, fileList } = this;
if (!reason[reasonIndex]) {
return this.$toast({
title: "请选择退款原因",
});
}
const data = {
id: this.afterSaleId,
reason: reason[reasonIndex],
refund_type: optTyle,
remark: remark,
img: fileList.length <= 0 ? "" : fileList[0].base_url,
};
applyAgain(data).then((res) => {
if (res.code == 1) {
uni.$emit("refreshsale");
this.$toast(
{
title: res.msg,
},
{
tab: 5,
url:
"/bundle/pages/after_sales_detail/after_sales_detail?afterSaleId=" +
res.data.after_sale_id,
}
);
}
});
},
onInput(e) {
this.setData({
remark: e.detail.value,
});
this.remark = e.detail.value;
},
applyAfterSaleFun() {
let { reason, reasonIndex, optTyle, remark, fileList } = this;
if (!reason[reasonIndex]) {
return this.$toast({
title: "请选择退款原因",
});
}
const data = {
item_id: this.itemId,
order_id: this.orderId,
reason: reason[reasonIndex],
refund_type: optTyle,
remark: remark,
img: fileList.length <= 0 ? "" : fileList[0].url,
};
applyAfterSale(data).then((res) => {
if (res.code == 1) {
uni.$emit("refreshsale");
this.$toast({
title: "提交成功",
});
setTimeout(() => {
uni.redirectTo({
url:
"/bundle/pages/after_sales_detail/after_sales_detail?afterSaleId=" +
res.data.after_sale_id,
});
}, 500);
}
});
},
afterRead(e) {
const file = e;
uni.showLoading({
title: "正在上传中...",
mask: true,
});
file.map((item) => {
uploadFile(item.path).then((res) => {
uni.hideLoading();
this.fileList.push(res);
});
});
},
deleteImage(index) {
this.fileList.splice(index, 1);
},
getGoodsInfoFun() {
let { orderId, itemId } = this;
getGoodsInfo({
order_id: orderId,
item_id: itemId,
}).then((res) => {
if (res.code == 1) {
this.goods = res.data.goods;
this.reason = res.data.reason;
}
});
},
},
};
</script>
<style lang="scss">
/* pages/apply_refund/apply_refund.wxss */
.apply-refund {
padding-bottom: 50rpx;
.goods {
padding: 20rpx 0;
background-color: white;
padding: 20rpx 24rpx;
.goods-info {
margin-left: 24rpx;
flex: 1;
}
}
}
.opt-box {
.opt-item {
padding: 20rpx 20rpx 20rpx 30rpx;
background-color: white;
}
}
.border-line {
border: 1px solid #f2f2f2;
}
.apply-refund {
.refund-info {
background-color: #fff;
padding: 24rpx 20rpx;
border-bottom: var(--border);
.label {
align-self: start;
width: 140rpx;
line-height: 36rpx;
margin-top: 19rpx;
}
textarea {
flex: 1;
height: 172rpx;
border-radius: 10rpx;
padding: 20rpx;
box-sizing: border-box;
}
}
.upload {
padding: 0 20rpx 20rpx;
.title {
padding: 24rpx 0;
}
}
.btn {
width: 680rpx;
margin-top: 30rpx;
margin-left: 26rpx;
margin-right: 26rpx;
}
}
.pop-header {
line-height: 42rpx;
padding: 30rpx;
}
.reason-box {
.reason-item {
padding: 24rpx 20rpx;
.reason-desc {
line-height: 46rpx;
}
}
}
</style>
@@ -0,0 +1,244 @@
<template>
<view class="balance-transfer">
<view class="contain bg-white">
<input
style="height: 100rpx"
v-model="userSn"
type="text"
placeholder="请输入对方会员ID/手机号码进行转账"
/>
</view>
<view class="contain transfer-money bg-white mt20">
<view class="muted xs">转账金额</view>
<view class="input row-center">
<view style="font-size: 23px; align-self: flex-end; margin-bottom: 5px">¥</view>
<input v-model="money" type="digit" placeholder="0.00" />
<view class="column" style="flex: none">
<view
class="xs primary"
style="text-align: right"
@tap="money = wallet.user_money"
>全部</view
>
<view class="xs mt10" style="color: #bbbbbb"
>钱包余额{{ wallet.user_money }}</view
>
</view>
</view>
<view class="btn lg white row-center br60" @tap="transferBtn">转账</view>
<navigator
url="/bundle/pages/transfer_record/transfer_record"
hover-class="none"
class="mt20 nr lighter row-center"
>
转账记录</navigator
>
</view>
<view class="user contain bg-white mt20" v-if="transferList.length">
<view class="lg bold">最近转账</view>
<view class="list">
<view
class="item row"
v-for="(item, index) in transferList"
:key="index"
@tap="userSn = item.sn"
>
<image class="avatar mr30" :src="item.avatar"></image>
<view>
<view class="md">{{ item.nickname }}</view>
<view class="xs muted">会员ID:{{ item.sn }}</view>
</view>
</view>
</view>
</view>
<u-modal
:value="showTransferInfo"
show-cancel-button
title="确认转账给"
:confirm-color="primaryColor"
async-close
confirm-text="确认转账"
@confirm="showInputPwd"
@cancel="showTransferInfo = false"
>
<view class="slot-content row-center" style="padding: 40rpx 80rpx">
<view class="transfer-user row">
<image class="avatar mr30" :src="transferInfo.avatar"></image>
<view>
<view class="md">{{ transferInfo.nickname }}</view>
<view class="xs muted mt10">会员ID:{{ transferInfo.sn }}</view>
</view>
</view>
</view>
</u-modal>
<set-pay-pwd ref="setPayPwd" @confirm="transferFun"></set-pay-pwd>
</view>
</template>
<script>
import {
hasPayPassword,
transfer,
getTransferRecent,
setPassword,
transferToInfo,
getWallet
} from '@/api/user'
import { trottle } from '@/utils/tools'
export default {
data() {
return {
showTransferInfo: false,
pwd: '',
comfirmPwd: '',
userSn: '',
money: '',
transferInfo: {},
transferList: [],
wallet: {}
}
},
onLoad() {
this.getTransferRecentFun()
this.getWalletFun()
this.transferFun = trottle(this.transferFun, 1000, this)
},
onShow() {
setTimeout(() => {
this.$refs.setPayPwd && this.$refs.setPayPwd.hasPayWord()
})
},
methods: {
getWalletFun() {
getWallet().then((res) => {
if (res.code == 1) {
this.wallet = res.data
}
})
},
showInputPwd() {
this.showTransferInfo = false
this.$refs.setPayPwd.showInputPwd()
},
getTransferRecentFun() {
getTransferRecent().then((res) => {
if (res.code == 1) {
this.transferList = res.data
}
})
},
async transferBtn() {
let { userSn, money } = this
if (!userSn)
return this.$toast({
title: '请输入对方会员ID/手机号码'
})
if (!money)
return this.$toast({
title: '请输入转账金额'
})
let data = {
transferTo: userSn
}
// 校验会员信息
const { code: vipCode, data: transferInfo } = await transferToInfo(data)
if (vipCode != 1) return
this.transferInfo = transferInfo
this.showTransferInfo = true
},
transferFun(payPwd) {
const { userSn, money } = this
let data = {
transferTo: userSn,
money: money,
pay_password: payPwd
}
transfer(data).then((res) => {
if (res.code == 1) {
this.$toast(
{
title: res.msg
}
// {
// tab: 2,
// url: '/bundle/pages/transfer_record/transfer_record'
// }
)
this.money = ''
this.showInputPwd()
this.getWalletFun()
this.getTransferRecentFun()
}
})
}
}
}
</script>
<style lang="scss">
.balance-transfer {
padding: 20rpx 30rpx;
.contain {
border-radius: 20rpx;
padding: 0 24rpx;
}
.transfer-money {
padding: 30rpx 45rpx;
.input {
border-bottom: $-solid-border;
margin-top: 30rpx;
input {
width: 100%;
height: 94rpx;
text-align: left;
font-size: 66rpx;
margin-left: 30rpx;
}
}
.btn {
background: linear-gradient(79deg, #f95f2f 0%, #ff2c3c 100%);
line-height: 84rpx;
margin-top: 80rpx;
}
}
.user {
padding: 22rpx 25rpx;
.list .item {
padding: 26rpx 0;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
}
}
.avatar {
width: 68rpx;
height: 68rpx;
border-radius: 50%;
flex: none;
}
}
/* 弹窗 */
.balance-transfer .set-word input {
border: var(--border);
padding: 16rpx 20rpx;
font-size: 28rpx;
border-radius: 6rpx;
margin-bottom: 20rpx;
}
.balance-transfer .phone {
padding: 20rpx 0;
font-size: 42rpx;
}
</style>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,84 @@
<template>
<view class="bargain-code-container">
<tabs :active="active" @change="onChange">
<tab v-for="(item, index) in bargain" :key="item.type" :title="item.name" >
<bargain-list :ref="item.ref_name" :bargainType="item.type" v-if="item.isShow" />
</tab>
</tabs>
</view>
</template>
<script>
import {bargainType} from "@/utils/type"
export default {
data() {
return {
active: 0,
bargainCodeType: bargainType.ALL,
bargain: [{
name: '全部',
type: bargainType.ALL,
ref_name: 'all',
isShow: true
}, {
name: '砍价中',
type: bargainType.BARGINNING,
ref_name: 'barginning',
isShow: false
}, {
name: "砍价成功",
type: bargainType.SUCCESS,
ref_name: 'success',
isShow: false
}, {
name: '砍价失败',
type: bargainType.FAIL,
ref_name: 'fail',
isShow: false
}]
}
},
onLoad(options) {
},
onReachBottom: function () {
const {
active, bargain
} = this;
let type = bargain[active].ref_name;
let myComponent = this.$refs[type][0];
if (myComponent.$getBargainActivityList) {
myComponent.$getBargainActivityList();
}
},
methods: {
onChange(active) {
const {bargain} = this;
console.log(active)
let type = bargain[active].ref_name
let index = bargain.findIndex(item => {
return item.ref_name == type;
});
if (index != -1) {
this.bargain[index].isShow = true;
console.log(this.bargain)
this.active = index;
}
this.$nextTick(() => {
console.log(this.$refs, "refs", type)
console.log('this.$refs[all]', this.$refs['all'])
if(this.$refs[type] && this.$refs[type][0].$getBargainActivityList) {
this.$refs[type][0].$getBargainActivityList();
}
})
}
}
}
</script>
<style lang="scss">
.bargain-code-container {
}
</style>
@@ -0,0 +1,717 @@
<template>
<view class="bargain-process-container">
<navbar title="砍价进度"></navbar>
<!-- #ifdef H5 -->
<download-nav v-if="showDownload" :top="44"></download-nav>
<!-- #endif -->
<view v-show="status == -1">
<view class="bargain-process-header">
<view class="mt20 column status-container">
<view class="white xxl">
{{activityObj.bargain_tips}}
</view>
<view class="mt10 white xxs">
{{activityObj.simple_tips}}
</view>
</view>
</view>
<view class="main">
<navigator class="goods-planel row" :url="'/pages/goods_details/goods_details?id=' + activityObj.goods_id" hover-class="none">
<custom-image width="180rpx" height="180rpx" :src="activityObj.image" radius="10rpx" />
<view class="goods-info">
<view class="goods-name line2 nr">
{{activityObj.name}}
</view>
<view class="xs" style="color: #F95F2F;">
最低可砍至<text class="sm" style="line-height: 48rpx;">¥<text class="xl">{{activityObj.activity_price}}</text></text>
</view>
<view class="xs muted">
原价 <text style="text-decoration:line-through;">¥{{activityObj.price}}</text>
</view>
</view>
</navigator>
<view class="choose-container">
<view class="title xl normal">
请选择商品规格
</view>
<view class="choose-content row-between" @click="showSpecPop">
<view class="row">
<view class="muted sm">已选</view>
<view class="md normal">
{{userSpecText}}
</view>
</view>
<u-icon name="arrow-right" size="28" color="#999" />
</view>
</view>
<view class="lunch-btn white br60 row-center" @click="$launchBargain">发起砍价</view>
</view>
</view>
<view v-show="status != -1">
<view class="bargain-process-header">
<view class="mt20 status-container row">
<custom-image
v-if="bargainObj.share_avatar"
width="80rpx"
height="80rpx"
:src="bargainObj.share_avatar"
round
:customStyle="{'border': '2rpx solid #fff'}"
/>
<view class="column ml20">
<view class="white xxl">
{{bargainObj.bargain_tips}}
</view>
<view class="mt10 white xxs">
{{bargainObj.simple_tips || '邀请好友帮忙砍价 —— 砍至'+ bargainObj.current_price +'元即可发货'}}
</view>
</view>
</view>
</view>
<view class="main">
<navigator class="goods-planel row" :url="'/pages/goods_details/goods_details?id=' + bargainObj.goods_id" hover-class="none">
<custom-image width="180rpx" height="180rpx" :src="bargainObj.image" radius="10rpx" />
<view class="goods-info">
<view class="goods-name line2 nr">
{{bargainObj.name}}
</view>
<view class="xs muted">
{{bargainObj.spec_value_str}}
</view>
<view class="row-between mt10">
<view class="xs muted">
原价 ¥{{bargainObj.price || 0}}
</view>
<view class="row" v-show="showCountDown" v-if="timestamp > 0">
<u-count-down
:timestamp="timestamp"
:bg-color="primaryColor"
color="#fff"
:separator-color="primaryColor"
height="36"
:show-days="true"
@end="closeBargainOrderFun"
/>
<text class="muted xs ml10">内可砍</text>
</view>
</view>
</view>
</navigator>
<!-- 非被邀请状态 -->
<view class="bargain-panel" v-if="status != 5">
<view class="bargain-panel-header nr">
已砍{{bargainObj.knife_price || 0}}还差{{bargainObj.diff_price || 0}}
</view>
<view class="progress-container row">
<view class="progress">
<view class="progress-bar" :style="{'width': precent + '%'}">
</view>
</view>
<view class="primary xs ml20">
<text class="xxs">¥</text>{{bargainObj.activity_price}}
</view>
</view>
<view class="nr lighter row-center" style="margin-top: 35rpx;" v-if="bargainObj.status != 0 && bargainObj != -1">
{{bargainObj.status_tips}}
</view>
<view class="invite-btn1 br60 white row-center lg" @click="shareToBargain" v-if="bargainObj.direct_buy_btn != 1 && bargainObj.invite_btn">
邀请好友帮砍价
</view>
<view class="invite-btn1 br60 white row-center lg" v-if="bargainObj.buy_btn" @tap="handleClickBuy" >
立即购买
</view>
<view class="fail-btn br60 white row-center lg" v-if="bargainObj.status == 2">
砍价失败
</view>
<view class="invite-btn-group row-between" v-if="bargainObj.direct_buy_btn">
<view class="buy-now-btn br60 md row-center" @click="handleClickBuy">
¥{{bargainObj.current_price}} 直接购买
</view>
<view class="invite-friend-btn white br60 md row-center" @click="shareToBargain">
邀请好友帮砍价
</view>
</view>
<view class="invite-btn1 br60 white row-center lg" v-if="bargainObj.order_btn" @click="toOrderDetail">
查看订单
</view>
<view class="bargain-code-content">
<view class="bargain-code-title row-between">
<view class="md normal bold">
砍价记录
</view>
<view class="muted xs">
已有{{bargainObj.knife_list && bargainObj.knife_list.length}}人帮砍
</view>
</view>
<view class="code-content">
<view class="user-item row-between" v-for="(item, index) in bargainObj.knife_list" :key="item.id">
<view class="user-content row">
<custom-image width="80rpx" height="80rpx" radius="60rpx" :src="item.avatar" />
<view class="ml20">
<view class="sm normal">
{{item.nickname}}
</view>
<view class="muted xxs">
小刀一砍惊喜满满
</view>
</view>
</view>
<view class="bargain-price xs primary">
¥{{item.help_price || 0}}
</view>
</view>
</view>
</view>
</view>
<!-- end -->
<!-- 被邀请状态 -->
<view class="shared-panel" v-if="status == 5" >
<view class="btn-container">
<view class="nr muted row-center">
{{bargainObj.status_tips}}
</view>
<view class="help-knife-btn row-center white lg br60" v-if="bargainObj.knife_btn" @click="$helpBargain">
帮忙砍一刀
</view>
<navigator hover-class="none" url="/bundle/pages/bargain/bargain" class="knife-btn row-center lg normal br60" v-if="bargainObj.sponsor_btn">
我也要砍价
</navigator>
</view>
<view class="code-content">
<view class="bargain-code-title row-between">
<view class="md normal bold">
砍价记录
</view>
<view class="muted xs">
已有{{bargainObj.knife_list.length}}人帮砍
</view>
</view>
<view class="user-item row-between" v-for="(item, index) in bargainObj.knife_list" :key="item.id">
<view class="user-content row">
<custom-image width="80rpx" height="80rpx" radius="60rpx" :src="item.avatar" />
<view class="ml20">
<view class="sm normal">
{{item.nickname}}
</view>
<view class="muted xxs">
小刀一砍惊喜满满
</view>
</view>
</view>
<view class="bargain-price xs primary">
¥{{item.help_price || 0}}
</view>
</view>
</view>
</view>
<!-- end -->
</view>
</view>
<loading-view v-if="showLoadingView" />
<goods-bargain v-if="status != -1" ref="goodsBargain" />
<u-popup v-model="showBargainPop" mode="center">
<view class="bargain-pop-container">
<view class="md normal bold row-center" style="padding-top: 64rpx;">
恭喜您成功砍下<text class="primary lg">{{knifePrice || 0}}</text>
</view>
<view class="bold md row-center" style="margin-top: 38rpx;" v-if="!isHelpKnife">
还差<text class="ml20 differ-price primary">{{diffPrice || 0}}<text style="font-size: 40rpx;"></text></text>
</view>
<view class="bold primary xxl row-center" style="margin-top: 38rpx;" v-else>
已为好友砍价成功
</view>
<view class="progress-container row-center">
<view class="progress">
<view class="progress-bar" :style="{'width': precent + '%'}" />
</view>
</view>
<view class="row-center">
<view class="invite-btn row-center md" @click="shareToBargain">
{{isHelpKnife ? '确定' : '邀请好友帮砍'}}
</view>
</view>
</view>
<view class="close-icon row-center" @click="closeBargainPop" mode="bottom">
<u-icon name="close-circle" size="68rpx" color="#fff"></u-icon>
</view>
</u-popup>
<spec-popup
:show="showPop"
:goods="activityObj"
:isBargain="true"
:show-add="false"
:show-buy="false"
:showConfirm="true"
:disabledNumberBox="true"
:showStock="false"
@confirm="chooseSpec"
@close="showPop=false"
/>
<!-- <share-popup
:show="showSharePop"
@close="showSharePop = false"
:goodsId="bargainId"
:isBargain="true"
:shareTitle="bargainObj.share_titles || bargainObj.name"
:summary="bargainObj.share_intros || bargainObj.simple_tips"
:img-url="bargainObj.image"
/> -->
<share-popup
v-model="showSharePop"
:share-id="bargainId"
pagePath="bundle/pages/bargain_process/bargain_process"
:config="{
avatar: userInfo.avatar,
nickname: userInfo.nickname,
image: bargainObj.image,
name: bargainObj.name ||bargainObj.share_titles,
}"
:type="2"
/>
</view>
</template>
<script>
import {getBargainDetail, launchBargain, getBargainActivityDetail, helpBargain, closeBargainOrder} from '@/api/activity'
import {strToParams} from '@/utils/tools'
import config from '@/config/app'
import { mapGetters } from 'vuex'
export default {
data() {
return {
showPop: false,
showBargainPop: false,
showSharePop: false,
activityObj: {},
bargainObj: {},
status: 1,
precent: 0,
timestamp: 0,
userSpecText: '请选择商品规格',
userSpec: {},
bargainId: -1,
activityId: -1,
// 砍价弹窗变量
knifePrice: 0,
diffPrice: 0,
isHelpKnife: false,
showCountDown: true,
showLoadingView: true,
showDownload: false
}
},
onLoad(options) {
if (options && options.scene) {
let scene = strToParams(decodeURIComponent(options.scene));
console.log('scenescene',scene)
options.bargainId = scene.id;
}
if(options && options.id) {
options.bargainId = options.id
}
// #ifdef H5
if(options && options.isapp == 1) {
this.showDownload = true
}
// #endif
// 活动详情ID
this.bargainId = options.bargainId;
// 砍价活动ID
this.activityId = options.activityId;
console.log(this.bargainId, this.activityId, "option")
if(this.activityId && this.activityId != -1) {
this.$getBargainDetail(this.activityId);
}
else if(this.bargainId && this.bargainId != -1) {
this.$getBargainActivityDetail(this.bargainId)
}
},
onReachBottom() {
if(this.$refs.goodsBargain) {
this.$refs.goodsBargain.$getBargainList();
}
},
// #ifdef MP-WEIXIN
onShareAppMessage() {
return {
path: "bundle/pages/bargain_process/bargain_process?bargainId=" + this.bargainId,
title: this.bargainObj.share_titles || this.bargainObj.name,
imageUrl: this.bargainObj.image,
}
},
// #endif
computed: {
...mapGetters(['userInfo']),
},
methods: {
showSpecPop() {
this.showPop = true;
},
closeBargainPop() {
this.showBargainPop = false
},
$getBargainDetail(id) {
getBargainDetail({bargain_id: id}).then(res => {
if(res.code == 1) {
this.activityObj = res.data;
this.status = res.data.status;
this.showLoadingView = false;
this.userSpecText = res.data.goods_item[0].spec_value_str
this.userSpec = {
id: res.data.goods_item[0].id
}
// let url = config.baseURL.replace(/\/api\//g, "/mobile/");
let options = {
shareTitle: this.activityObj.name,
shareLink: location.href + "&invite_code=" + this.$store.getters.inviteCode,
shareImage: this.activityObj.image,
shareDesc: this.activityObj.simple_tips
}
this.wxShare(options)
console.log(options, "share-bargain-options1", location.href);
}
})
},
chooseSpec(e) {
this.userSpec = e.detail;
this.userSpecText = e.detail.spec_value_str;
this.showPop = false;
},
$launchBargain() {
let data = {
// 砍价活动id
bargain_id: this.activityId,
item_id: this.userSpec.id
}
launchBargain(data).then(res => {
if(res.code == 1) {
this.$toast({title: res.msg});
this.knifePrice = res.data.knife_price;
this.diffPrice = res.data.diff_price;
this.precent = res.data.progress * 100;
if(this.precent > 100) {
this.precent = 100
}
this.showBargainPop = true;
this.bargainId = res.data.id;
this.showLoadingView = true;
uni.showLoading()
this.$getBargainActivityDetail(res.data.id);
}
})
},
$getBargainActivityDetail(id) {
let timestamp = 0;
let now_time = (new Date().getTime()) / 1000
getBargainActivityDetail({
id: id
}).then(res => {
if(res.code == 1) {
uni.hideLoading()
this.status = res.data.status;
this.bargainObj = res.data;
timestamp = res.data.over_time;
this.precent = res.data.progress * 100;
if(this.precent > 100) {
this.precent = 100
}
this.showLoadingView = false;
this.timestamp = (timestamp - Math.floor(now_time));
console.log('calc: ', timestamp, '-', Math.floor(now_time), '=', this.timestamp )
let url = location.href.replace(/activityId=\d*/g, "bargainId=" + id);
let options = {
shareTitle: this.bargainObj.share_titles || this.bargainObj.name,
shareLink: url + "&invite_code=" + this.$store.getters.inviteCode,
shareImage: this.bargainObj.image,
shareDesc: this.bargainObj.share_intros || this.bargainObj.simple_tips
}
this.wxShare(options)
console.log(options, "share-bargain-options2", url);
if(this.timestamp <= 0 || this.status == 1) {
// 砍价已结束
this.showCountDown = false;
}
else {
this.showCountDown = true;
}
}
})
},
shareToBargain() {
this.showBargainPop = false
if(this.isHelpKnife) {
return;
}
this.showSharePop = true
},
$helpBargain() {
// 帮好友砍价
helpBargain({
id: this.bargainId
}).then(res => {
if(res.code == 1) {
this.knifePrice = res.data.knife_price;
this.precent = res.data.progress * 100;
if(this.precent > 100) {
this.precent = 100
}
this.isHelpKnife = true;
this.showBargainPop = true;
this.$getBargainActivityDetail(this.bargainId)
}
})
},
toOrderDetail() {
uni.navigateTo({
url: "/pages/order_details/order_details?id=" + this.bargainObj.order_id
})
},
closeBargainOrderFun() {
// 计时结束后关闭订单
closeBargainOrder({
id: this.bargainObj.id
}).then(res => {
if(res.code == 1) {
this.$toast({
title: res.msg
})
this.$getBargainActivityDetail(this.bargainObj.id)
}
})
},
handleClickBuy() {
let goods = [{
num: 1,
item_id: this.bargainObj.item_id
}]
let params = {
goods
}
console.log(goods, 'handleClickBuy')
uni.navigateTo({
url: '/pages/confirm_order/confirm_order?data=' + encodeURIComponent(JSON.stringify(params)) + "&bargain_launch_id=" + this.bargainObj.id
})
}
}
}
</script>
<style lang="scss">
.bargain-process-container {
.bargain-process-header {
background-image: url(../../../static/images/bg_hometop.png);
height: 420rpx;
background-size: 100% 100%;
padding-top: 30rpx;
.rule-contain {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 100rpx;
padding: 6rpx 10rpx;
margin-right: 24rpx;
}
.status-container {
margin-left: 24rpx;
}
}
.main {
padding: 0 24rpx;
margin-top: -230rpx;
.goods-planel {
background-color: white;
padding: 30rpx 24rpx;
border-radius: 20rpx;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.06);
.goods-info {
margin-left: 24rpx;
flex: 1;
.goods-name {
line-height: 40rpx;
}
}
}
// 砍价状态2
.bargain-panel {
margin-top: 30rpx;
padding: 24rpx 24rpx 20rpx;
background-color: $-color-white;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.06);
border-radius: 20rpx;
.bargain-panel-header {
font-weight: bold;
}
.progress-container {
margin-top: 33rpx;
.progress {
flex: 1;
background-color: #FFEBE5;
height: 20rpx;
border-radius: 50rpx;
.progress-bar {
background: linear-gradient(90deg, #F95F2F 0%, #FF2C3C 100%);
transition: width .5s ease;
height: 100%;
width: 0%;
border-radius: 50rpx;
}
}
}
.invite-btn1 {
background-color: $-color-primary;
height: 84rpx;
margin-top: 36rpx;
box-shadow: 0px 3px 10px rgba(235, 36, 51, 0.5);
}
.fail-btn {
background-color: #E5E5E5;
height: 84rpx;
margin-top: 30rpx;
}
.invite-btn-group {
margin-top: 60rpx;
.buy-now-btn {
width: 316rpx;
height: 84rpx;
color: #F95F2F;
font-size: 30rpx;
background-color: rgba($color: #F95F2F, $alpha: 0.2);
}
.invite-friend-btn {
width: 316rpx;
height: 84rpx;
background-color: $-color-primary;
}
}
.bargain-code-content {
margin-top: 62rpx;
.bargain-code-title {
}
.code-content {
margin-top: 30rpx;
.user-item {
padding: 15rpx 0;
margin-bottom: 30rpx;
}
}
}
}
// end
// 被邀请状态
.shared-panel {
.btn-container {
margin-top: 40rpx;
.help-knife-btn {
background-color: $-color-primary;
height: 84rpx;
box-shadow: 0px 3px 10px rgba(235, 36, 51, 0.5);
}
.knife-btn {
height: 84rpx;
background-color: $-color-white;
border: 1px solid #BBBBBB;
margin-top: 30rpx;
}
}
.code-content {
margin-top: 30rpx;
padding: 27rpx 24rpx;
background-color: $-color-white;
.user-item {
padding: 15rpx 0;
margin-top: 10rpx;
}
}
}
// end
.choose-container {
margin: 40rpx 0;
.title {
font-weight: 500;
margin-bottom: 30rpx;
}
.choose-content {
padding: 30rpx 20rpx;
background-color: $-color-white;
border-radius: 10px;
}
}
.lunch-btn {
height: 84rpx;
background-color: $-color-primary;
box-shadow: 0px 3px 10px rgba(235, 36, 51, 0.5);
}
}
.pop-container {
height: 800rpx;
.goods-info {
padding: 20rpx 20rpx;
.goods-spec {
align-self: flex-end;
}
}
.spec-selector {
padding: 30rpx 20rpx;
.title {
line-height: 36rpx;
}
.spec-item {
padding: 8rpx 28rpx;
background-color: #F4F4F4;
}
.spec-active-item {
padding: 8rpx 28rpx;
color: white;
background-color: $-color-primary;
}
}
.pickup-number {
margin-top: 30rpx;
padding: 0 20rpx;
}
}
.bargain-pop-container {
width: 559rpx;
height: 580rpx;
background-image: url(../../static/images/bg_kanjia.png);
background-size: 100% 100%;
.differ-price {
font-size: 58rpx;
line-height: 38rpx;
}
.progress-container {
margin-top: 26rpx;
.progress {
width: 409rpx;
height: 20rpx;
background-color: #FD498F1A;
border-radius: 50rpx;
.progress-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #FA444D 0%, #FD498F 100%);
border-radius: 50rpx;
transition: width .5s ease;
}
}
}
.invite-btn {
background-image: url(../../static/images/coupon_button.png);
background-size: 100% 100%;
height: 106rpx;
color: #7B3200;
font-weight: 500;
margin-top: 180rpx;
width: 478rpx;
}
}
.close-icon {
margin-top: 26rpx;
}
.share-pop-container {
height: 500rpx;
background-color: $-color-white;
}
}
</style>
@@ -0,0 +1,157 @@
<template>
<view class="contact-offical">
<view class="header">
</view>
<view class="content column-center">
<view class="content-view column-center bg-white">
<img class="content-img" :src="server.image" />
<view class="primary wechat-num lg">客服微信</view>
<view class="row-center copy-btn xxl white" @click="onCopy(server.wechat)">
<image class="mr5" style="width: 32px;height: 25px;" src="../../static/images/wechat-btn-icon.png" />
微信扫码添加
</view>
<view class="mt20 normal xs" style="line-height: 35px">{{server.time}}</view>
<!-- #ifdef MP-WEIXIN -->
<button open-type="contact" class="sm row-center br60">
<text style="line-height: 50px;">在线客服</text>
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="sm row-center br60" @click="tipsShow()">
<text style="line-height: 50px;">在线客服</text>
</view>
<!-- #endif -->
</view>
<view class="xs white" style="margin-top: 40px;line-height: 49px;">
无法添加或疑难问题请联系工作人员
</view>
<view class="row white">
<view class="xs" style="line-height: 49px;">{{server.phone}}</view>
<!-- #ifdef H5 -->
<a class="ml10 phone-btn xs row-center white" :href="'tel:' + server.phone">拨打</a>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<a class="ml10 phone-btn xs row-center white" @click="showTelTips">拨打</a>
<!-- #endif -->
<view class="ml5 copy-phone-btn xs row-center" @click="onCopy(server.phone)">复制</view>
</view>
</view>
<u-modal
:content="content"
v-model="showPhoneCall"
show-cancel-button
confirm-text='呼叫'
:confirm-color="primaryColor"
@confirm="onCall"
>
</u-modal>
</view>
</template>
<script>
import {getService} from "@/api/app"
import {copy} from '@/utils/tools'
export default {
name: 'contactOffical',
data() {
return {
server: {},
showPhoneCall: false,
content: '即将打电话给'
}
},
onLoad() {
this.$getService()
},
methods: {
$getService() {
getService().then(res => {
if(res.code == 1) {
this.server = res.data
}
})
},
tipsShow() {
this.$toast({title: "该功能暂未开放"})
},
onCopy(str) {
copy(str);
},
showTelTips() {
this.showPhoneCall = true;
this.content = '即将打电话给' + this.server.phone
},
onCall() {
wx.makePhoneCall({
phoneNumber: this.server.phone.toString(),
success(e) {
console.log('成功', e)
},
fail(err) {
console.log('失败', err)
}
})
}
}
}
</script>
<style lang="scss">
.contact-offical {
min-height: 100vh;
background: linear-gradient(180deg, #F62318 0%, #F20407 100%);
.header {
height: 383px;
width: 100%;
}
.content {
.content-view {
border: 5px solid #FA7949;
width: 310px;
border-radius: 10px;
margin-top: -350px;
.content-img {
margin-top: 20px;
height: 192px;
width: 192px;
}
.wechat-num {
line-height: 45px;
}
.copy-btn {
background: linear-gradient(180deg, #FFA200 0%, #FF5E44 100%);
width: 230px;
height: 50px;
border-radius: 50px;
line-height: 49px;
margin-top: 30px;
}
.contact-btn {
width: 300rpx;
height: 60rpx;
margin-bottom: 20rpx;
}
}
.phone-btn {
background: linear-gradient(180deg, #FFA200 0%, #FF5E44 100%);
height: 24px;
width: 60px;
line-height: 33px;
border-radius: 50px;
}
.copy-phone-btn {
background-color: rgba($color: #fff, $alpha: 0.5);
height: 24px;
width: 60px;
line-height: 33px;
border-radius: 50px;
}
}
}
</style>
@@ -0,0 +1,184 @@
<template>
<view class="set-pwd">
<view class="input-container bg-white">
<view class="input-item row">
<view class="input-label md normal">手机号</view>
<u-input class="flex1" v-model="mobile" />
</view>
<view class="input-item row">
<view class="input-label md normal">验证码</view>
<u-input class="flex1" v-model="code" placeholder="请输入验证码" />
<view class="get-code xs br60 row-center primary" @tap="sendSms">
<view v-show="!showCount">获取验证码</view>
<u-count-down
v-show="showCount"
ref="countDown"
:show-days="false"
:timestamp="time"
separator="zh"
color="#FF2C3C"
separatorColor="#FF2C3C"
bg-color="rgba(0, 0, 0, 0)"
:show-hours="false"
:show-minutes="false"
:autoplay="false"
@end="showCount = false"
/>
</view>
</view>
<view class="input-item row">
<view class="input-label md normal">转账密码</view>
<u-input
class="flex1"
type="password"
v-model="setPwd"
placeholder="请输入新的转账密码"
/>
</view>
<view class="input-item row">
<view class="input-label md normal">确认密码</view>
<u-input
class="flex1"
type="password"
v-model="comfirmPwd"
placeholder="请再次确认密码"
/>
</view>
<button
size="lg"
type="primary"
class="btn bg-primary white br60 row-center"
@tap="retrievePayPasswordFun"
>
确认
</button>
</view>
</view>
</template>
<script>
import { retrievePayPassword, send } from '@/api/user'
import { mapGetters } from 'vuex'
export default {
data() {
return {
time: 59,
showCount: false,
setPwd: '',
comfirmPwd: '',
code: ''
}
},
onLoad() {},
methods: {
retrievePayPasswordFun() {
let { setPwd, comfirmPwd, code } = this
if (!code) {
this.$toast({
title: '请输入验证码'
})
return
}
if (!setPwd) {
this.$toast({
title: '请输入新的转账密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '请输入确认密码'
})
return
}
if (setPwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
if (setPwd.length < 4 || setPwd.length > 8) {
this.$toast({
title: '请输入长度为4-8位的密码'
})
return
}
let data = {
new_pay_password: setPwd,
mobile: this.userInfo.mobile,
code: code
}
retrievePayPassword(data).then((res) => {
if (res.code == 1) {
this.$toast(
{
title: res.msg
},
{ tab: 3 }
)
}
})
},
sendSms() {
let data = {
mobile: this.userInfo.mobile
}
if (this.showCount) return
send(data).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.showCount = true
this.$refs.countDown.start()
}
})
}
},
computed: {
...mapGetters(['userInfo']),
mobile() {
if (this.userInfo.mobile) {
return this.userInfo.mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}
}
}
}
</script>
<style lang="scss">
.set-pwd {
padding-top: 20rpx;
.input-container {
padding: 20rpx 0 100rpx;
border-radius: 20rpx;
.input-item {
margin: 0 30rpx;
height: 88rpx;
margin-bottom: 30rpx;
border-bottom: 1px solid #d7d7d7;
.input-label {
width: 180rpx;
flex: none;
}
.get-code {
width: 176rpx;
height: 58rpx;
flex: none;
border: 1px solid $-color-primary;
}
}
.btn {
margin: 80rpx 30rpx 0;
}
}
}
</style>
@@ -0,0 +1,169 @@
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view class="goods-combination">
<navbar title="拼团活动"></navbar>
<view class="header">
<image class="img" src="../../static/images/group_bg.png"></image>
</view>
<view class="main bg-primary">
<view class="goods-list">
<navigator v-for="(item, index) in groupList" :key="index" class="goods-item row mt20 bg-white" hover-class="none"
:url="'/pages/goods_details/goods_details?id=' + item.goods_id">
<custom-image width="180rpx" height="180rpx" radius="6rpx" lazy-load :src="item.image"></custom-image>
<view class="goods-info ml20">
<view class="goods-name line2 mb10">{{item.name}}</view>
<view class="dec row">
<view class="group mr20 row">
<view class="group-img row-center">
<image class="icon-sm" src="../../static/images/icon_group_white.png"></image>
</view>
<view class="primary xxs mr10 ml10">{{item.people_num}}人团</view>
</view>
<view class="sale muted xs">已拼{{item.sales_sum}}</view>
</view>
<view class="info-footer row-between">
<view class="price row">
<price-format color="#FF2C3C" :subscript-size="26" :second-size="26" :first-size="34" :price="item.team_min_price"
:weight="500"></price-format>
<price-format class="ml10" color="#999" :line-through="true" :subscript-size="24" :first-size="24" :second-size="24"
:price="item.min_price"></price-format>
</view>
<button class="br60 btn white" size="sm" type="primary">去拼团</button>
</view>
</view>
</navigator>
</view>
<loading-footer :status="status" :slot-empty="true" color="#fff" @refresh="getGroupListFun">
<view slot="empty" class="column-center" style="padding-top: 200rpx">
<text class="lg" style="color: #FFD4D8">暂无拼团商品</text>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
import {
loadingType
} from '@/utils/type';
import {
getGroupList
} from '@/api/activity';
import {
loadingFun
} from '@/utils/tools'
export default {
data() {
return {
page: 1,
groupList: [],
status: loadingType.LOADING
};
},
components: {},
onLoad: function(options) {
this.getGroupListFun();
},
onPullDownRefresh: function() {
this.page = 1;
this.groupList = [];
this.status = loadingType.LOADING;
this.getGroupListFun();
},
onReachBottom: function() {
this.getGroupListFun();
},
methods: {
async getGroupListFun() {
try {
let {
page,
groupList,
status
} = this;
const data = await loadingFun(getGroupList, page, groupList, status)
if (!data) return
this.page = data.page
this.groupList = data.dataList
this.status = data.status
} catch(err) {
this.status = loadingType.ERROR
}
}
}
};
</script>
<style lang="scss">
.goods-combination {
background-color: $-color-primary;
min-height: 100vh;
.header .img {
display: block;
width: 750rpx;
height: 380rpx;
}
.main {
padding: 0 20rpx;
margin-top: -30rpx;
position: relative;
z-index: 1;
.goods-list {
.goods-item {
border-radius: 20rpx;
padding: 30rpx 20rpx;
.goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.goods-info {
flex: 1;
width: 475rpx;
.group {
border: 1px solid $-color-primary;
border-radius: 4rpx;
.group-img {
padding: 2rpx 6rpx;
background: linear-gradient(90deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
border-radius: 0 4rpx 4rpx 0;
}
}
.info-footer {.btn {
padding: 0 30rpx;
background-color: #F95F2F;
}}
}
}
}
}
}
</style>
@@ -0,0 +1,48 @@
<template>
<view class="goods-comment-list">
<tabs :active="active" line-width="40" @change="changeActive">
<tab title="待评价">
<comment-list type="1" v-if="active == 0"></comment-list>
</tab>
<tab title="已评价">
<comment-list type="2" v-if="active == 1"></comment-list>
</tab>
</tabs>
</view>
</template>
<script>
export default {
data() {
return {
active: 0
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.type = options.type;
if (this.type) {
this.active = parseInt(this.type)
}
},
methods: {
changeActive(e) {
this.active = e
}
}
};
</script>
<style>
</style>
@@ -0,0 +1,258 @@
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view>
<view class="goods-logistics mb20">
<view class="header row bg-white">
<view class="goods mr20">
<image class="goods-img" :src="order.image"></image>
<view class="count xs white br60">{{order.count}}件商品</view>
</view>
<view class="info sm">
<view class="bold lg">{{order.tips}}</view>
<view class="black mt10 mb10">物流公司{{order.shipping_name}}</view>
<view class="row">
<text class="black">快递单号{{order.invoice_no}}</text>
<text class="primary ml20" @tap="onCopy">复制</text>
</view>
</view>
</view>
<view class="main mt20 bg-white column">
<!-- 物流时间轴 -->
<view class="express">
<!-- 顶部收货地址 -->
<view class="express-address row" v-if="take.contacts">
<view class="express-left column-center">
<image class="express-icon" :src="finish.tips ? '../../static/images/logistics_address.png' : '../../static/images/logistics_address_gray.png'"></image>
<view class="express-line"></view>
</view>
<view class="express-right">
<view class="name bold mb10 sm">{{take.contacts}} {{take.mobile}}</view>
<view class="address sm lighter line2">{{take.address}}</view>
</view>
</view>
<view class="express-item row" v-if="finish.tips">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_success.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right">
<view class="title bold sm">{{finish.title}}</view>
<view class="dec sm">{{finish.tips}}</view>
<view class="time xs muted">{{finish.time}}</view>
</view>
</view>
<view class="express-item row" v-if="delivery.traces && delivery.traces.length">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_transit.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="title bold sm ">{{delivery.title}}</view>
<view class="xs" v-if="delivery.traces[0][0]">
{{delivery.traces[0][0]}}
</view>
<view class="xs" v-if="delivery.traces[0][1]">
{{delivery.traces[0][1]}}
</view>
<view class="xs" v-if="delivery.traces[0][2]">
{{delivery.traces[0][2]}}
</view>
</view>
</view>
<block v-for="(item, index) in delivery.traces" :key="index">
<view class="express-item row" v-if="index >= 1">
<view class="express-left column-center">
<view class="express-doted"></view>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="sm" v-if="item[0]">{{item[0]}}</view>
<view class="sm" v-if="item[1]">{{item[1]}}</view>
<view class="sm" v-if="item[2]">{{item[2]}}</view>
</view>
</view>
</block>
<view class="express-item row" v-if="shipment.tips">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_delivered.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="title bold sm">{{shipment.title}}</view>
<view class="dec xs">{{shipment.tips}}</view>
<view class="time xs muted">{{shipment.time}}</view>
</view>
</view>
<view class="express-item row" v-if="buy.tips">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_pay.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="title bold sm">{{buy.title}}</view>
<view class="dec xs">{{buy.tips}}</view>
<view class="time xs muted">{{buy.time}}</view>
</view>
</view>
</view>
</view>
</view>
<recommend></recommend>
<loading-view v-if="isFirstLoading"></loading-view>
</view>
</template>
<script>
import {
orderTraces
} from '@/api/order';
import {copy} from '@/utils/tools'
export default {
data() {
return {
shipment: {},
buy: {},
delivery: {},
finish: {},
order: {},
take: {},
isFirstLoading: true
};
},
components: {},
props: {},
onLoad: function(options) {
this.id = options.id;
this.orderTracesFun();
},
methods: {
async orderTracesFun() {
const {
code,
data: {
shipment,
buy,
delivery,
finish,
order,
take
}
} = await orderTraces(this.id)
if (code == 1) {
this.shipment = shipment
this.buy = buy
this.delivery = delivery
this.finish = finish
this.order = order
this.take = take
this.isFirstLoading = false
} else {
setTimeout(() => uni.navigateBack(), 1000);
}
},
onCopy() {
copy(this.order.invoice_no)
}
}
};
</script>
<style lang="scss">
.goods-logistics {
padding-top: 20rpx;
.header {
padding: 20rpx;
.goods-img {
width: 160rpx;
height: 160rpx;
flex: none;
border-radius: 10rpx;
}
}
.goods {
position: relative;
.count {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
background-color: rgba(0, 0, 0, 0.6);
padding: 4rpx 0;
}
}
.express {
width: 700rpx;
padding-top: 30rpx;
padding-bottom: 100rpx;
margin: 0 auto;
border-radius: 10rpx;
}
.express-address,
.express-item {
align-items: flex-start;
position: relative;
padding: 20rpx 0;
}
.express-left {
margin-top: 10rpx;
margin-right: 24rpx;
height: 100%;
position: absolute;
width: 40rpx;
flex: none;
.express-icon {
width: 40rpx;
height: 40rpx;
}
.express-line {
flex: 1;
border-left: 1px dotted #E5E5E5;
}
.express-doted {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background-color: #E5E5E5;
}
}
.express-right {
padding-left: 60rpx;
& .title,
& .dec {
margin-bottom: 5rpx;
}
}
.express-item:last-of-type .express-left .express-line {
border: none;
}
}
</style>
@@ -0,0 +1,258 @@
<template>
<view class="goods-reviews">
<order-goods :list="goods"></order-goods>
<view class="goods-evaluate row">
<view class="lable">商品评价</view>
<u-rate
name="goodsRate"
:count="5"
:size="42"
active-color="#FF2C3C"
v-model="goodsRate"
@change="goodsRateChange"
/>
<view
:class="'desc ' + (goodsRate <= 2 ? 'muted' : 'primary') + ' '"
v-show="!(goodsRate == 0)"
>
{{ goodsRateDesc }}
</view>
</view>
<view class="rate bg-white">
<view class="item row mb20">
<view class="lable">描述相符</view>
<u-rate name="descRate" :size="42" active-color="#FF2C3C" v-model="descRate" />
</view>
<view class="item row mb20">
<view class="lable">服务态度</view>
<u-rate name="serverRate" :size="42" active-color="#FF2C3C" v-model="serverRate" />
</view>
<view class="item row">
<view class="lable">配送服务</view>
<u-rate
name="deliveryRate"
:size="42"
active-color="#FF2C3C"
v-model="deliveryRate"
/>
</view>
</view>
<view class="goods-dec bg-white mt20">
<view class="title mb20 md bold">商品描述</view>
<view class="textarea mb20" style="background-color: #f5f5f5">
<u-input
v-model="comment"
placeholder="宝贝收到还满意吗,说说你的使用心得。分享给想买的他们吧!!"
type="textarea"
:clearable="false"
:height="240"
>
</u-input>
</view>
<uploader
preview-size="180rpx"
:mutiple="true"
:maxUpload="5"
:file-list="fileList"
@after-read="afterRead"
:deletable="true"
@delete="onDelete"
/>
</view>
<button form-type="submit" class="btn br60" type="primary" size="lg" @tap="onSubmit">
立即评价
</button>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { baseURL } from '@/config/app.js'
import { goodsComment, getCommentInfo } from '@/api/user'
import { uploadFile } from '@/utils/tools.js'
export default {
data() {
return {
goodsRate: 0,
descRate: 0,
serverRate: 0,
deliveryRate: 0,
goodsRateDesc: '',
fileList: [],
goods: [],
comment: '',
type: ''
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.id = options.id
this.getCommentInfoFun()
},
methods: {
onChange(e) {
this.type = e.value
},
goodsRateChange: function (e) {
let goodsRateDesc = ''
if (e <= 2) {
goodsRateDesc = '差评'
} else if (e == 3) {
goodsRateDesc = '中评'
} else {
goodsRateDesc = '好评'
}
this.goodsRateDesc = goodsRateDesc
},
onSubmit() {
let { goodsRate, fileList, comment, deliveryRate, descRate, serverRate } = this
let image = fileList.map((item) => item.base_url)
if (!goodsRate)
return this.$toast({
title: '请对商品进行评分'
})
if (!descRate)
return this.$toast({
title: '请对描述相符进行评分'
})
if (!serverRate)
return this.$toast({
title: '请对服务态度进行评分'
})
if (!deliveryRate)
return this.$toast({
title: '请对配送服务进行评分'
})
goodsComment({
id: parseInt(this.id),
goods_comment: goodsRate,
service_comment: serverRate,
express_comment: deliveryRate,
description_comment: descRate,
comment,
image
}).then((res) => {
if (res.code == 1) {
this.$toast(
{
title: '评价成功'
},
{
tab: 5,
url: '/bundle/pages/goods_comment_list/goods_comment_list?type=1'
}
)
}
})
},
onInput(e) {
this.comment = e.detail.value
},
getCommentInfoFun() {
getCommentInfo({
id: this.id
}).then((res) => {
if (res.code == 1) {
this.goods.push(res.data)
}
})
},
afterRead(e) {
const file = e
uni.showLoading({
title: '正在上传中...',
mask: true
})
file.map((item) => {
uploadFile(item.path)
.then((res) => {
uni.hideLoading()
this.fileList.push(res)
})
.catch(() => {
uni.hideLoading()
this.$toast({
title: '上传失败'
})
})
})
},
onDelete(index) {
this.fileList.splice(index, 1)
}
}
}
</script>
<style>
.goods-reviews {
padding: 20rpx 0 40rpx;
}
.goods-reviews .rate {
padding: 20rpx 30rpx;
}
.goods-reviews .rate .lable {
width: 170rpx;
}
.goods-reviews .goods-dec {
padding: 30rpx;
}
.goods-reviews .goods-dec .textarea {
height: 240rpx;
border-radius: 10rpx;
}
.goods-reviews .goods-dec .textarea textarea {
width: 100%;
height: 100%;
padding: 20rpx;
box-sizing: border-box;
}
.goods-reviews .btn {
width: 698rpx;
margin: 30rpx 26rpx 0;
}
.rate .item .desc {
margin-left: 30rpx;
}
.goods-reviews .goods-evaluate {
padding: 20rpx 30rpx;
background-color: white;
border: 1rpx solid #f2f2f2;
}
.goods-reviews .goods-evaluate .desc {
margin-left: 30rpx;
}
.goods-reviews .goods-evaluate .lable {
width: 170rpx;
}
</style>
@@ -0,0 +1,288 @@
<template>
<!-- pages/active/goods_seckill/goods_seckill.wxml -->
<view class="goods-seckill">
<navbar title="限时秒杀"></navbar>
<view class="banner">
<swipers :pid="14" height="284rpx" radius="10rpx" padding="20rpx"></swipers>
</view>
<view class="time-list">
<scroll-view style="height: 120rpx; white-space: nowrap;" :scroll-into-view="'item-' + currentView" scroll-x="true" scroll-with-animation="true">
<view v-for="(item, index) in seckillTime" :key="index" :id="'item-' + index" class="time-item column-center" @tap="exchangeTime" :data-id="item.id" :data-index="index">
<view :class="'xl bold ' + (item.active==1 ? 'primary': '')">{{ item.start_time }}</view>
<view :class="'sm br60 state ' + ( item.active === 1 ? 'bg-primary white': '' ) + ' ' + ( item.status === 2 ? 'muted': '' )" :style="item.active==1 ? 'background-color: #FF2C3C;color: white': ''">
{{ item.tips }}
</view>
</view>
</scroll-view>
</view>
<view class="goods-list">
<view v-for="(item, index) in seckillGoods" :key="index" class="goods-item row bg-white" @tap="goGoodsDetail" :data-id="item.id" :data-shop_id="item.shop_id">
<custom-image width="180rpx" height="180rpx" radius="10rpx" lazy-load class="goods-img mr20" :src="item.image" />
<view class="goods-info">
<view style="width: 490rpx" class="goods-name line2 mb10">{{item.name}}</view>
<label class="sale-info xs primary br60">
已抢{{item.sales_sum}}
</label>
<view class="info-footer row-between" style="margin-top: 5rpx">
<view class="price">
<price-format class="mr10" :price="item.seckill_price" color="#FF2C3C" :firstSize="34" :secondSize="26" :showSubscript="true" :subscriptSize="26" />
<price-format class="line-through muted" :price="item.min_price" color="#999999" :firstSize="24" :secondSize="24" :showSubscript="true" :subscriptSize="24" />
</view>
<button :class="'br60 white ' + (currentStatus == 2? 'bg-gray' : currentStatus == 1 ? 'primary-btn' : 'border-btn')" size="sm" @tap.stop="goGoodsDetail" :data-id="item.id" :data-shop_id="item.shop_id">{{currentStatus == 2? '已结束': currentStatus == 1 ? '立即抢购' : '未开始'}}</button>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/goods_null.png"></image>
<view class="muted nr">暂无商品</view>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getSeckillTime, getSeckillGoods } from "@/api/activity";
import { loadingType } from "@/utils/type";
import {loadingFun} from "@/utils/tools";
export default {
data() {
return {
currentView: 0,
bannerList: [],
seckillTime: [],
seckillGoods: [],
page: 1,
loadingStatus: "loading",
currentId: 0,
// 当前状态
currentStatus: 0,
isDataNull: false,
id: ""
};
},
components: {
},
props: {},
onLoad: function (options) {
this.getSeckillTimeFun();
},
onReachBottom: function () {
this.getSeckillGoodsFun(this.currentId);
},
methods: {
// 获取秒杀时间段
getSeckillTimeFun() {
let {
currentView,
currentStatus
} = this;
getSeckillTime().then(res => {
if (res.code == 1) {
if (!res.data.length && res.data.length <= 0) {
this.isDataNull = true
return;
}
let index = res.data.findIndex(item => item.status == 1);
if (index == -1) {
index = res.data.findIndex(item => item.status == 0);
}
if (index == -1) {
index = 0;
}
res.data[index].active = 1;
currentView = index - 2;
currentStatus = res.data[index].status;
if (currentView < 0) {
currentView = 0;
}
this.seckillTime = res.data;
this.id = res.data[index].id;
this.currentView = currentView;
this.currentStatus = currentStatus;
this.getSeckillGoodsFun(res.data[index].id);
}
});
},
// 获取秒杀时间段商品
getSeckillGoodsFun(id) {
let {
page,
seckillGoods
} = this;
loadingFun(getSeckillGoods, page, seckillGoods, this.loadingStatus, {id: id}).then(res => {
if(res) {
this.page = res.page;
this.seckillGoods = res.dataList
this.loadingStatus = res.status
}
})
},
// 查看其他时间段
exchangeTime(e) {
let {
id,
index
} = e.currentTarget.dataset;
let {
currentView,
seckillTime,
currentStatus
} = this;
seckillTime.forEach((item, idx) => {
if (index == idx) {
item.active = 1;
currentStatus = item.status;
} else {
item.active = 0;
}
});
if (index == -1) {
index = 0;
}
currentView = index - 2;
if (currentView < 0) {
currentView = 0;
}
this.page = 1;
this.currentView = currentView;
this.isDataNull = false;
this.currentId = id;
this.seckillGoods = []
this.loadingStatus = loadingType.LOADING;
this.seckillTime = seckillTime;
this.currentStatus = currentStatus;
this.getSeckillGoodsFun(id);
},
goGoodsDetail(e) {
let {
id,
shop_id
} = e.currentTarget.dataset;
uni.navigateTo({
url: '/pages/goods_details/goods_details?id=' + id
});
},
goToBuy(e) {
console.log("goToBuy");
console.log(e);
}
}
};
</script>
<style lang="scss">
/* pages/active/goods_seckill/goods_seckill.wxss */
.bg-gray {
background-color: #CCCCCC !important;
}
.goods-seckill .banner {
}
.goods-seckill {
.time-list {
.time-item {
display: inline-flex;
width: 160rpx;
height: 100%;
.state {
padding: 0 10rpx;
}
}
}
.goods-list {
.goods-item{
padding: 30rpx;
.goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.goods-info {
flex: 1;
width: 470rpx;
.sale-info {
padding: 4rpx 16rpx;
background-color: #FFE9EB;
}
.info-footer {
.btn {
padding: 0 30rpx;
}
}
.progress-wrap {
.progress {
width: 260rpx;
display: inline-block;
}
}
}
}
}
}
.primary-btn {
padding: 0 30rpx;
background: linear-gradient(
270deg,
rgba(255, 44, 60, 1) 0%,
rgba(249, 95, 47, 1) 100%
);
}
.border-btn {
padding: 0 30rpx;
border: 1px solid #FF2C3C !important;
color: #FF2C3C !important;
}
.data-null {
padding-top: 100rpx;
.img-null {
width: 300rpx;
height: 300rpx;
flex: none;
}
}
</style>
+108
View File
@@ -0,0 +1,108 @@
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view class="hot-list">
<view class="header">
<view class="title row mb20">
<image src="../../static/images/icon_paixu.png" class="icon mr20"></image>
<text class="xs white">实时更新热销火爆商品</text>
</view>
<swipers :pid="15" height="284rpx" radius="10rpx"></swipers>
</view>
<view class="main">
<view v-if="hasHot">
<goods-list type="hot" :list="goodsList"></goods-list>
<loading-footer :status="status">
</loading-footer>
</view>
<view v-else class="column-center" style="padding-top: 400rpx">
<image class="img-null" src="/static/images/goods_null.png"></image>
<text class="lighter">暂无商品~</text>
</view>
</view>
</view>
</template>
<script>
import {
loadingType
} from '@/utils/type';
import {
getHotGoods
} from '@/api/store';
import {loadingFun} from '@/utils/tools'
export default {
data() {
return {
goodsList: [],
page: 1,
status: loadingType.LOADING,
hasHot: true
};
},
components: {},
props: {},
onLoad(options) {
this.getHotGoodsFun();
},
onReachBottom() {
this.getHotGoodsFun();
},
methods: {
async getHotGoodsFun() {
let {
page,
status,
goodsList
} = this;
const data = await loadingFun(getHotGoods,page, goodsList,status)
if (!data) return
this.page = data.page
this.goodsList = data.dataList
this.status = data.status
}
}
};
</script>
<style lang="scss">
.hot-list {
background: url(../../static/images/hot_list_bg.png) no-repeat;
background-size: 100% 330rpx;
padding: 62rpx 30rpx 0;
min-height: 100vh;
box-sizing: border-box;
.main {
padding: 0 0 20rpx;
}
.data-null {
padding-top: 150rpx;
}
}
</style>
@@ -0,0 +1,208 @@
<template>
<!--pages/input_express_info/input_express_info.wxml-->
<view class="input-express-info">
<form @submit="formSubmit">
<view class="input-contain mt20">
<view class="input-item row">
<view class="nr label">物流公司</view>
<input class="input" placeholder="请输入物流公司名称" :value="formInfo.express" name="express"></input>
</view>
<view class="input-item row">
<view class="nr label">快递单号</view>
<input class="input" placeholder="请输入快递单号" :value="formInfo.number" name="number"></input>
</view>
<view class="input-item row">
<view class="nr label">备注说明</view>
<input class="input" placeholder="选填" :value="formInfo.remark" name="remark"></input>
</view>
</view>
<view class="upload-contain mt20">
<view class="header row">
<view class="nr normal">上传凭证</view>
<view class="sm muted ml20">(请上传快递单号凭证</view>
</view>
<view class="upload">
<uploader :deletable="true" @delete="handleImage" preview-size="160rpx" max-count="1" :file-list="fileList" @after-read="afterRead" />
</view>
</view>
<view class="submit-btn">
<button size="lg" class=" br60 bg-primary white lg" form-type="submit">提交</button>
</view>
</form>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { inputExpressInfo } from '@/api/user';
import { baseURL } from '@/config/app.js';
export default {
data() {
return {
fileList: [],
formInfo: {
express: '',
number: '',
remark: ''
}
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let {
id
} = options; // 售后id
this.afterSalesId = id;
},
methods: {
afterRead(e) {
const file = e
uni.showLoading({
title: '正在上传中...',
mask: true
});
file.forEach(item => {
this.uploadFile(item.path).then(res => {
uni.hideLoading();
this.fileList.push(res);
});
})
},
formSubmit(e) {
let {
value
} = e.detail;
let {
fileList
} = this;
console.log(value);
if (!value.express) return this.$toast({
title: '请填写物流公司名称'
});
if (!value.number) return this.$toast({
title: '请填写快递单号'
});
let data = {
id: this.afterSalesId,
express_name: value.express,
invoice_no: value.number,
express_remark: value.remark,
express_image: fileList.length <= 0 ? '' : fileList[0].url
};
this.inputExpressInfoFun(data);
},
uploadFile(path) {
return new Promise(resolve => {
uni.uploadFile({
url: `${baseURL}/api/file/formimage`,
filePath: path,
name: 'file',
fileType: 'image',
cloudPath: '',
success: res => {
console.log('uploadFile res ==> ', res)
const {
fileList
} = this;
let data = JSON.parse(res.data);
if (data.code == 1) {
resolve(data.data);
}
},
fail: (err) => {
console.log(err)
}
});
});
},
inputExpressInfoFun(data) {
inputExpressInfo(data).then(res => {
if (res.code == 1) {
this.$toast({
title: '提交成功'
}, () => {
uni.navigateBack();
});
uni.$emit("refreshsale")
}
});
},
handleImage(index) {
this.fileList.splice(index)
}
}
};
</script>
<style>
/* pages/input_express_info/input_express_info.wxss */
.input-express-info {
}
.input-contain {
background-color: white;
}
.input-contain .input-item {
padding: 24rpx;
}
.input-item .label{
width: 152rpx;
}
.input-item .input {
flex: 1;
}
.upload-contain {
background-color: white;
padding: 24rpx 20rpx 44rpx;
}
.upload-contain .header {
margin-bottom: 30rpx;
}
.submit-btn {
margin-top: 50rpx;
margin-left: 26rpx;
margin-right: 26rpx;
}
</style>
+153
View File
@@ -0,0 +1,153 @@
<template>
<view class="pages">
<view class="invite-fans column column-center">
<image :src="path" mode="widthFix" class="poster"></image>
<invite-poster v-if="showPoster" :config="{
avatar: userInfo.avatar,
nickname: userInfo.nickname,
code:inviteCode,
link: link,
qrCode: qrCode,
poster: poster
}" @success="handleSuccess" />
<view class="bg-white footer flex1">
<view class="" style="margin-bottom: 40rpx;">
<view class="mb10 sm lighter">我的邀请码</view>
<view class="row row-between">
<view class="font-size-44">{{inviteCode}}</view>
<view class="sm mr30 copy-btn" @tap="$copy(inviteCode || '')">点击复制</view>
</view>
</view>
<!-- #ifndef H5 -->
<button class="save-btn br60" size="lg" @tap="saveImageToAlbum">保存到相册</button>
<!-- #endif -->
<!-- #ifdef H5 -->
<button class="save-btn br60" size="lg">长按保存到相册</button>
<!-- #endif -->
</view>
</view>
<loading-view v-show="loading"></loading-view>
</view>
</template>
<script>
import {
// apiMnpQrCode,
getShareMnQrcode
} from '@/api/app'
import {
baseURL,
basePath
} from '@/config/app'
import { apiDistributionPoster } from '@/api/user'
import { mapGetters } from 'vuex'
export default {
data() {
return {
path: '',
qrCode: '',
loading: true,
showPoster: false,
poster: ''
};
},
async onLoad() {
await this.getPoster()
// #ifdef MP-WEIXIN
this.getMnpQrCode()
// #endif
// #ifdef APP-PLUS || H5
this.showPoster = true
// #endif
},
methods: {
async getPoster() {
const res = await apiDistributionPoster()
this.poster = res.data.poster
},
getMnpQrCode() {
// apiMnpQrCode().then(res => {
// this.qrCode = res.qr_code
// this.showPoster = true
// })
getShareMnQrcode({
id: '', // 商品id或其他活动id
url: 'pages/index/index', // 跳转页面路径
type: 0, // 0-会员分享海报 1-商品详情 2-砍价活动
})
.then((res) => {
console.log('shareRes', res)
this.qrCode = res.data.qr_code
this.showPoster = true
})
},
saveImageToAlbum() {
// #ifndef H5
uni.saveImageToPhotosAlbum({
filePath: this.path,
success: res => {
this.$toast({
title: "保存成功"
});
},
fail: err => {
this.$toast({
title: '保存失败'
});
}
});
// #endif
// #ifdef H5
this.$toast({
title: 请长按图片保存
})
// #endif
},
handleSuccess(val) {
this.path = val
this.loading = false
}
},
computed: {
...mapGetters(['inviteCode','userInfo']),
link() {
return `${baseURL}${basePath}?invite_code=${this.inviteCode}`
}
}
};
</script>
<style lang="scss">
page {
padding: 0
}
.invite-fans {
min-height: 100vh;
overflow: hidden;
.poster {
width: 600rpx;
margin: 40rpx 0;
}
.footer {
padding: 30rpx;
width: 100%;
}
.copy-btn {
color: $-color-primary;
}
.save-btn {
color: #fff;
background-color: $-color-primary;
}
}
</style>
+71
View File
@@ -0,0 +1,71 @@
<template>
<view class="license">
<view class="box bg-white">
<template v-if="images.length">
<view v-for="(item, index) in images" :key="index" class="m-b-25" @click="viewImage(index)">
<u-image :src="item" width="100%" height="348rpx">
</u-image>
</view>
</template>
<template v-else>
<view class="data-null xs muted">
<image src="../../../static/images/order_null.png" mode=""></image>
<view>
商家暂时还没有上传资质哦~
</view>
</view>
</template>
</view>
</view>
</template>
<script>
import {
getCopyright
} from "@/api/user";
export default {
data() {
return {
images: []
}
},
methods: {
getCopyrightFunc() {
getCopyright().then(res => {
this.images = res.data
})
},
viewImage(current) {
uni.previewImage({
current,
urls: this.images// 需要预览的图片http链接列表
});
}
},
onLoad() {
this.getCopyrightFunc()
}
}
</script>
<style lang="scss">
.license {
padding: 30rpx;
.box {
padding: 30rpx;
border-radius: 16rpx;
.data-null {
padding-top: 200rpx;
height: 700rpx;
text-align: center;
image {
width: 200rpx;
height: 200rpx;
}
}
}
}
</style>
@@ -0,0 +1,155 @@
<template>
<view class="live-broadcast">
<!-- #ifdef MP-WEIXIN -->
<view class="broadcast-list">
<view class="broadcast-item" @tap="navigateTo(item)" v-for="(item, index) in lists" :key="index">
<view class="img-wrap">
<u-image width="100%" height="100%" :src="item.cover_img"></u-image>
<view class="tag xxs" :class="{
active: item.status == 101
}">
<u-icon v-if="item.status == 101" name="play-right-fill" size="24"></u-icon>
<text v-else class="circel"></text>
<text class="ml10">{{ item.live_status }}</text>
</view>
<view class="tips line1">{{ item.name }}</view>
</view>
<view class="info">
<view class="md">
主播{{ item.anchor_name }}
<text class="xs">直播商品{{item.goods}}</text>
</view>
<view class="muted xs mt20">直播时间{{item.start_time}} {{item.end_time}}</view>
</view>
</view>
</view>
<loading-footer :status="status" slot-empty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">暂无直播~</text>
</view>
</loading-footer>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="data-null column-center" style="padding-top: 400rpx;">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">非小程序端暂不支持直播~</text>
</view>
<!-- #endif -->
</view>
</template>
<script>
import {
loadingType
} from "@/utils/type";
import {
loadingFun
} from "@/utils/tools"
import {
getLiveRoom
} from "@/api/store"
export default {
data() {
return {
lists: [],
page: 1,
status: loadingType.LOADING
};
},
methods: {
navigateTo(item) {
const roomId = [item.roomid];
wx.navigateTo({
url: `plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin?room_id=${roomId}`
});
},
getLists() {
let {
lists,
status,
page
} = this;
loadingFun(getLiveRoom, page, lists, status).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.status = res.status
}
})
}
},
onLoad(options) {
this.getLists();
},
onReachBottom() {
this.getLists();
},
onPullDownRefresh() {
this.page = 1
this.status = loadingType.LOADING
this.getLists();
},
}
</script>
<style lang="scss">
.live-broadcast {
.broadcast-list {
padding: 20rpx 20rpx 0;
overflow: hidden;
.broadcast-item {
border-radius: 12rpx;
overflow: hidden;
background-color: #fff;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
.img-wrap {
height: 300rpx;
position: relative;
color: #fff;
.tag {
position: absolute;
top: 0;
border-radius: 0 60rpx 60rpx 0;
background: #ccc;
padding: 8rpx 20rpx;
&.active{
background: linear-gradient(#ff2c3c 0%, #f95f2f 100%);
}
.circel {
display: inline-block;
width: 14rpx;
height: 14rpx;
background: #fff;
border-radius: 50%;
}
}
.tips {
position: absolute;
background: linear-gradient(rgba(255, 255, 255, 0) 0%, #808080 100%);
bottom: 0;
width: 100%;
font-weight: 500;
font-size: 30rpx;
padding: 42rpx 20rpx 16rpx;
}
}
.info {
padding: 20rpx;
}
}
}
}
</style>
File diff suppressed because one or more lines are too long
@@ -0,0 +1,88 @@
<template>
<!--pages/message_center/message_center.wxml-->
<view class="message-center-container">
<navigator v-for="(item, index) in list" :key="index" class="message-item row" hover-class="none" :url="'/bundle/pages/notice/notice?type=' + item.type">
<image style="width: 76rpx;height: 76rpx;flex: none" :src="item.img"></image>
<view class="item-info ml20 column">
<view class="item-title">{{item.title}}</view>
<view class="item-desc line1 muted">{{item.content}}</view>
</view>
</navigator>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getNoticeLists, getMessageLists } from '@/api/store';
export default {
data() {
return {
list: []
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getMessageListsFun();
},
methods: {
getMessageListsFun() {
getMessageLists().then(res => {
if (res.code == 1) {
this.list = res.data;
}
});
}
}
};
</script>
<style lang="scss">
/* pages/message_center/message_center.wxss */
.message-center-container {
margin-top: 10rpx;
padding: 0 20rpx;
background-color: white;
.message-item {
padding: 32rpx 0;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
.item-info {
font-size: 32rpx;
flex: 1;
overflow: hidden;
.item-title{
font-size: 32rpx;
}
.item-desc{
font-size: 26rpx;
}
}
}
}
</style>
+149
View File
@@ -0,0 +1,149 @@
<template>
<!--pages/notice/notice.wxml-->
<view class="notice-container">
<view v-for="(item, index) in lists" :key="index" class="notice-item mb20">
<view class="row-between item-header">
<view class="header-title md">{{item.title}}</view>
<view class="header-time muted xs">{{item.create_time}}</view>
</view>
<view class="item-main">
<view class="content sm lighter">{{item.content}}</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/news_null.png" />
<text class="nr muted">暂无消息通知</text>
</view>
</loading-footer>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getNoticeLists } from '@/api/store';
import { loadingType } from '@/utils/type';
export default {
data() {
return {
page: 1,
loadingStatus: loadingType.LOADING,
lists: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.type = options.type;
switch (this.type) {
case "system":
uni.setNavigationBarTitle({
title: '系统通知'
});
break;
case "earning":
uni.setNavigationBarTitle({
title: '收益通知'
});
break;
}
this.getNoticeListsFun();
},
onReachBottom: function () {
this.getNoticeListsFun();
},
methods: {
getNoticeListsFun() {
let {
page,
loadingStatus,
lists
} = this;
if (loadingStatus == loadingType.FINISHED) return;
getNoticeLists({
type: this.type,
page_no: page
}).then(res => {
if (res.code == 1) {
let {
list,
more
} = res.data;
lists.push(...list);
this.lists = lists;
this.page ++;
if (!more) {
this.loadingStatus = loadingType.FINISHED
}
if (lists.length <= 0) {
this.loadingStatus = loadingType.EMPTY
return;
}
} else {
this.loadingStatus = loadingType.ERROR
}
});
}
}
};
</script>
<style lang="scss">
/* pages/notice/notice.wxss */
.notice-container {
padding: 0 20rpx;
margin-top: 8rpx;
.notice-item {
background-color: white;
padding: 0rpx 20rpx 30rpx;
border-radius: 10rpx;
.item-header {
padding: 19rpx 0;
border-bottom: $-solid-border;
.header-title {
font-weight: bold;
}
}
.item-main {
.content {
margin-top: 15rpx;
}
}
}
.data-null {
padding-top: 100rpx;
}
}
</style>
+177
View File
@@ -0,0 +1,177 @@
<template>
<view class="post-sale">
<view class="contain">
<tabs :active="active" :line-width="40" @change="onChange" sticky>
<tab v-for="(item, index) in afterSale" :key="index" :title="item.name">
<after-sales-list :ref="item.type" :type="item.type" v-if="item.isShow"></after-sales-list>
</tab>
</tabs>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getAfterSaleList, applyAfterSale, getGoodsInfo, inputExpressInfo, cancelApply, afterSaleDetail, applyAgain } from "@/api/user";
import { AfterSaleType } from "@/utils/type";
export default {
data() {
return {
active: 0,
afterSaleType: AfterSaleType.NORMAL,
afterSaleList: [],
afterSale: [{
name: '售后申请',
type: AfterSaleType.NORMAL,
isShow: true
}, {
name: '处理中',
type: AfterSaleType.HANDLING,
isShow: false
}, {
name: '已处理',
type: AfterSaleType.FINISH,
isShow: false
}]
};
},
components: {
},
props: {},
onReachBottom: function () {
const {
active
} = this;
let afterSaleType = AfterSaleType.NORMAL
switch(active) {
case 0:
afterSaleType = AfterSaleType.NORMAL;
break;
case 1:
break;
case 2:
afterSaleType = AfterSaleType.FINISH;
break;
default:
afterSaleType = AfterSaleType.NORMAL
break;
}
let myComponent = this.$refs[afterSaleType][0];
if (myComponent.getAfterSaleListFun) {
myComponent.getAfterSaleListFun();
}
},
methods: {
onChange(e) {
// const {
// name
// } = e.detail;
this.changeShow(e);
},
changeShow(active) {
const {
afterSale
} = this;
let type = active == 0 ? AfterSaleType.NORMAL : active == 1 ? AfterSaleType.HANDLING : AfterSaleType.FINISH
let index = afterSale.findIndex(item => {
return item.type == type;
});
if (index != -1) {
this.afterSale[index].isShow = true;
this.active = type == AfterSaleType.NORMAL ? 0 : type == AfterSaleType.HANDLING ? 1 : 2
}
if(this.$refs[type] && this.$refs[type][0].getAfterSaleListFun()) {
this.$refs[type][0].getAfterSaleListFun()
}
},
goPage(e) {
let {
url
} = e.currentTarget.dataset;
uni.navigateTo({
url: url
});
}
}
};
</script>
<style lang="scss">
image {
width: 100%;
height: 100%;
}
.post-sale {
.contain {
.sale-list {
padding: 20rpx 0;
.sale-item {
.sale-header {
padding: 20rpx 24rpx;
.store-name {
font-weight: bold;
font-family:PingFang SC;
line-height: 40rpx;
}
}
.sale-goods-show {
padding: 20rpx 24rpx;
.goods-img {
height: 160rpx;
width: 160rpx;
}
.goods-desc {
margin-left: 24rpx;
}
.sale-status {
padding: 20rpx 60rpx;
background-color: #F6F6F6;
}
}
.sale-footer {
padding: 0 24rpx 22rpx;
.btn {
padding: 9rpx 34rpx;
font-family: PingFang SC;
}
.grey-btn {
border: 1px solid #CCCCCC;
padding: 9rpx 34rpx;
font-family: PingFang SC;
}
}
}
}
}
}
</style>
+104
View File
@@ -0,0 +1,104 @@
<template>
<!--bundle/pages/prize_record/prize_record.wxml-->
<view class="prize-record-container">
<view v-for="(item, index) in lists" :key="index" class="prize-record-item row">
<custom-image :src="item.prize_image" style="width: 90rpx;height: 90rpx" radius="6rpx" />
<view class="prize-record-info">
<view class="lg">{{item.prize_name}}</view>
<view class="mt20 row-between">
<view class="xs lighter">{{item.create_time}}</view>
<view class="xs primary need-integral-tips" v-if="item.need_tips">{{item.need_tips}}</view>
</view>
<view class="xs primary mt10">
{{item.send_tips}}
</view>
<!-- <view class="xs lighter">领取时间{{item.create_time}}</view> -->
</view>
</view>
<loading-footer slotEmpty :status="loadingStatus">
<view class="data-null column-center" slot="empty">
<image src="../../static/images/null_gift.png" class="img-null"></image>
<text class="xs muted">暂无抽奖记录</text>
</view>
</loading-footer>
</view>
</template>
<script>
// bundle/pages/prize_record/prize_record.js
import {
loadingType
} from '@/utils/type';
import {
getUserRecord
} from '@/api/user';
import {
loadingFun
} from "@/utils/tools"
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
lists: []
};
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.getUserRecordFun();
},
onReachBottom: function() {
this.getUserRecordFun();
},
methods: {
getUserRecordFun() {
let {
loadingStatus,
lists,
page
} = this;
loadingFun(getUserRecord, page, lists, loadingStatus).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
/* bundle/pages/prize_record/prize_record.wxss */
.prize-record-container {
padding: 0 20rpx;
.prize-record-item {
align-items: flex-start;
margin-top: 20rpx;
background-color: white;
padding: 26rpx 24rpx;
border-radius: 10rpx;
.prize-record-info {
margin-left: 24rpx;
flex: 1
}
}
}
.data-null {
padding-top: 200rpx;
}
</style>
@@ -0,0 +1,81 @@
<template>
<view class="recharge-code">
<view class="list">
<view v-for="(item, index) in lists" :key="index" class="item bg-white">
<view class="row-between">
<view class="black mb10">{{item.desc}}</view>
<view class="xl primary">+{{item.total}}</view>
</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
</view>
<loading-footer :status="status" slotEmpty>
<view class="data-null column-center" slot="empty" style="padding-top: 200rpx">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无记录</text>
</view>
</loading-footer>
</view>
</template>
<script>
import {
getRechargeRecord
} from '@/api/user'
import {
loadingType
} from "@/utils/type";
import {
loadingFun
} from "@/utils/tools"
export default {
data() {
return {
lists: [],
page: 1,
status: loadingType.LOADING
}
},
onLoad: function(options) {
this.getRechargeRecordFun();
},
onReachBottom: function() {
this.getRechargeRecordFun();
},
methods: {
getRechargeRecordFun(type) {
let {
lists,
status,
page
} = this;
loadingFun(getRechargeRecord, page, lists, status).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.status = res.status
}
})
}
}
}
</script>
<style lang="scss">
.recharge-code {
padding-top: 20rpx;
.list {
.item {
padding: 20rpx 30rpx;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
}
}
}
</style>
@@ -0,0 +1,120 @@
<template>
<view>
<!--pages/server_explan/server_explan.wxml-->
<view class="main">
<u-parse :html="article_content" />
</view>
<!--<import src="/wxParse/wxParse.wxml"></import>-->
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getServerProto, getPrivatePolicy, getAfterSaleGuar } from '@/api/app';
export default {
data() {
return {
article_content: ""
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let {
type
} = options;
type = parseInt(type); // 0 ==> 服务协议 1 ==> 隐私政策 2 ==> 售后保障
uni.setNavigationBarTitle({
title: type == 0 ? '服务协议' : type == 1 ? '隐私政策' : '售后保障'
});
switch (type) {
case 0:
this.getServerProtoFun();
break;
case 1:
this.getPrivatePolicyFun();
break;
case 2:
this.getAfterSaleGuarFun();
break;
default:
this.getServerProtoFun();
break;
}
},
methods: {
// 服务协议
getServerProtoFun() {
getServerProto().then(res => {
if (res.code == 1) {
//wxParse.wxParse('content', 'html', res.data, this, 15)
setTimeout(() => {
this.article_content = res.data;
}, 200);
}
});
},
// 隐私协议
getPrivatePolicyFun() {
getPrivatePolicy().then(res => {
if (res.code == 1) {
//wxParse.wxParse('content', 'html', res.data, this, 15)
setTimeout(() => {
this.article_content = res.data;
}, 200);
}
});
},
// 售后保障
getAfterSaleGuarFun() {
getAfterSaleGuar().then(res => {
if (res.code == 1) {
//wxParse.wxParse('content', 'html', res.data, this, 15)
setTimeout(() => {
this.article_content = res.data;
}, 200);
}
});
}
}
};
</script>
<style lang="scss">
/* pages/server_explan/server_explan.wxss */
.main {
padding: 20rpx;
/* min-height: 100vh; */
}
</style>
+154
View File
@@ -0,0 +1,154 @@
<template>
<view class="set-pwd">
<view class="input-container bg-white">
<view class="input-item row" v-if="hasPayPwd">
<view class="input-label md normal">原密码</view>
<u-input
class="flex1"
type="password"
v-model="originPwd"
placeholder="请输入原来的转账密码"
/>
</view>
<view class="input-item row">
<view class="input-label md normal">转账密码</view>
<u-input
class="flex1"
type="password"
v-model="setPwd"
:placeholder="hasPayPwd ? '请输入新的转账密码' : '请输入转账密码'"
/>
</view>
<view class="input-item row">
<view class="input-label md normal">确认密码</view>
<u-input
class="flex1"
type="password"
v-model="comfirmPwd"
placeholder="请再次确认密码"
/>
</view>
<navigator
hover-class="none"
url="/bundle/pages/forget_pay_pwd/forget_pay_pwd"
class="row-end lighter xs mr20"
v-if="hasPayPwd"
>忘记原密码</navigator
>
<button
size="lg"
type="primary"
class="btn bg-primary white br60 row-center"
@tap="setPasswordFun"
>
确认
</button>
</view>
</view>
</template>
<script>
import { hasPayPassword, setPassword, changePayPassword } from '@/api/user'
export default {
data() {
return {
hasPayPwd: false,
setPwd: '',
comfirmPwd: '',
originPwd: ''
}
},
onLoad() {
this.hasPayWord()
},
methods: {
async setPasswordFun() {
let { setPwd, comfirmPwd, originPwd, hasPayPwd } = this
if (hasPayPwd) {
if (!originPwd) {
this.$toast({
title: '请输入原来的转账密码'
})
return
}
}
if (!setPwd) {
this.$toast({
title: '请输入新的转账密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '请填写确认密码'
})
return
}
if (setPwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
if (setPwd.length < 4 || setPwd.length > 8) {
this.$toast({
title: '请输入长度为4-8位的密码'
})
return
}
let data = {
pay_password: setPwd
}
const { msg, code } = hasPayPwd
? await changePayPassword({
origin_pay_password: originPwd,
new_pay_password: setPwd
})
: await setPassword(data)
if (code == 1) {
this.$toast(
{
title: msg
},
{ tab: 3 }
)
}
},
hasPayWord() {
hasPayPassword().then((res) => {
if (res.code == 1) {
this.hasPayPwd = true
}
})
}
}
}
</script>
<style lang="scss">
.set-pwd {
padding-top: 20rpx;
.input-container {
padding: 20rpx 0 100rpx;
border-radius: 20rpx;
.input-item {
margin: 0 30rpx;
height: 88rpx;
margin-bottom: 30rpx;
border-bottom: 1px solid #d7d7d7;
.input-label {
width: 180rpx;
flex: none;
}
}
.btn {
margin: 80rpx 30rpx 0;
}
}
}
</style>
+116
View File
@@ -0,0 +1,116 @@
<template>
<!--pages/sign_detail/sign_detail.wxml-->
<view class="sign-detail-container">
<view v-for="(item, index) in detailList" :key="index">
<view class="sign-item row-between">
<view class="flexnone">
<view class="nr sign-type">{{item.source_type}}</view>
<view class="muted xs mt10" style="line-height: 33rpx">{{item.create_time}}</view>
</view>
<view class="column-end" style="align-items: flex-end;">
<text class="lg" :class="{
primary: item.change_type == 1,
normal: item.change_type == 2
}" style="line-height: 45rpx">{{item.change_amount}}</text>
<view v-if="item.remark" style="width: 300rpx" class="xxs primary">备注{{ item.remark }}</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image src="/static/images/order_null.png" class="img-null"></image>
<view class="muted sm">暂无其他记录</view>
</view>
</loading-footer>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载:https://gitee.com/likeshop_gitee
// | github下载:https://github.com/likeshop-github
// | 访问官网:https://www.likeshop.cn
// | 访问社区:https://home.likeshop.cn
// | 访问手册:http://doc.likeshop.cn
// | 微信公众号:likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用,未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权,购买去版权授权后,方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { loadingType } from '@/utils/type';
import { getAccountLog } from '@/api/user.js';
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
rule: '',
loadingStatus: loadingType.LOADING,
detailList: [],
page: 1
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getAccountLogFun();
},
onReachBottom: function () {
this.getAccountLogFun();
},
methods: {
getAccountLogFun() {
let {
detailList,
loadingStatus,
page
} = this;
loadingFun(getAccountLog, page, detailList, loadingStatus, {source: 2}).then(res => {
if(res) {
this.page = res.page;
this.detailList = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
/* pages/sign_detail/sign_detail.wxss */
.sign-detail-container {
margin-top: 20rpx;
}
.sign-detail-container .sign-item {
padding: 18rpx 30rpx;
background-color: #fff;
border-bottom: $-solid-border;
}
.sign-type {
line-height: 40rpx;
}
.data-null {
padding-top: 100rpx;
}
</style>
+60
View File
@@ -0,0 +1,60 @@
<template>
<!--pages/sign_rule/sign_rule.wxml-->
<view style="padding: 30rpx">
<text class="nr" style="line-height: 36rpx">{{rule}}</text>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getSignRule } from "@/api/user.js";
export default {
data() {
return {
rule: ""
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getSignRuleFun();
},
methods: {
getSignRuleFun() {
getSignRule().then(res => {
if (res.code == 1) {
this.rule = res.data
}
});
}
}
};
</script>
<style>
/* pages/sign_rule/sign_rule.wxss */
</style>
+263
View File
@@ -0,0 +1,263 @@
<template>
<view class="store-list">
<!-- #ifndef APP-PLUS -->
<map
v-if="location.latitude"
style="width: 750rpx; height: 400rpx"
show-location
:latitude="location.latitude"
:longitude="location.longitude"
:markers="markers"
/>
<!-- #endif -->
<view class="scroll">
<scroll-view style="height: 100%" :scroll-y="true">
<view class="lists">
<view
:class="[
'item',
'bg-white',
'row',
{ 'item-disabled': !(item.business_status * 1) },
]"
v-for="(item, index) in lists"
:key="index"
@tap="onSelect(item)"
>
<view class="flex1">
<view class="name mb20">
<text class="bold lg black">{{ item.name }}</text>
<text class="muted xs ml10">{{ item.distance }}</text>
</view>
<view class="address black xs mb20 row">
<image
class="icon1"
src="../../static/images/icon_shop.png"
></image>
{{ item.shop_address }}
</view>
<view class="time black xs row">
<image
class="icon1"
src="../../static/images/icon_time.png"
></image>
{{ item.business_start_time }} - {{ item.business_end_time }}
</view>
</view>
<view class="ml20 flexnone">
<image
class="icon2"
src="../../static/images/icon_call.png"
@tap.stop="onCall(item.mobile)"
></image>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view slot="empty" class="data-null column-center">
<image
src="/static/images/address_null.png"
class="img-null"
></image>
<view class="muted xs">暂无门店</view>
</view>
</loading-footer>
</scroll-view>
</view>
</view>
</template>
<script>
import { getStoreList } from "@/api/store";
import { loadingType } from "@/utils/type";
import { loadingFun } from "@/utils/tools";
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
lists: [],
location: {},
markers: [],
};
},
methods: {
onCall(phone) {
uni.makePhoneCall({
phoneNumber: String(phone),
});
},
async getLocation() {
const [error, res] = await uni.getLocation({
// #ifndef APP
type: 'gcj02',
// #endif
});
if (!res) {
// #ifdef MP-WEIXIN
this.getAuthorize();
// #endif
return;
}
if (error) {
return this.$toast({
title: error.msg,
});
}
return {
latitude: res.latitude,
longitude: res.longitude,
};
},
async getAuthorize() {
const [error, res] = await uni.showModal({
title: "您已拒绝地理位置权限",
content: "是否进入权限管理,调整授权?",
});
if (res.confirm) {
// #ifdef MP
const [error, res] = await uni.openSetting();
if (res) this.getLocation();
// #endif
// #ifdef APP-PLUS
// #ifdef APP-PLUS
// android
if (uni.getSystemInfoSync().platform == 'android') {
var Intent = plus.android.importClass('android.content.Intent');
var Settings = plus.android.importClass('android.provider.Settings');
var intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
var main = plus.android.runtimeMainActivity();
main.startActivity(intent); // GPS
}
// ios
if (uni.getSystemInfoSync().platform == 'ios') {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("App-Prefs:root=Privacy&path=LOCATION");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
}
// #endif
// #endif
} else if (res.cancel) {
this.$Router.go(-1);
}
},
getLists() {
let { loadingStatus, page, lists } = this;
loadingFun(getStoreList, page, lists, loadingStatus, this.location).then(
(res) => {
if (res) {
this.page = res.page;
this.lists = res.dataList;
this.loadingStatus = res.status;
this.markers = this.lists.map((item) => {
return {
id: item.id,
latitude: item.latitude,
longitude: item.longitude,
iconPath: "../../static/images/icon_marker.png",
width: 34,
height: 34,
callout: {
content: item.name,
padding: 5,
borderRadius: 4,
fontSize: 13,
display: "ALWAYS",
},
};
});
}
}
);
},
onSelect(info) {
if (!(info.business_status * 1))
return this.$toast({
title: "不在营业中",
});
//
uni.$emit("store", info);
uni.navigateBack();
},
},
async onLoad() {
const res = await this.getLocation();
if (res) {
this.location = res;
this.getLists();
} else {
this.$toast({ title: "获取定位失败" });
}
},
onReachBottom: function () {
this.getLists();
},
};
</script>
<style lang="scss">
page {
padding: 0;
height: 100%;
}
.store-list {
height: 100%;
display: flex;
flex-direction: column;
.scroll {
flex: 1;
.lists {
padding: 20rpx;
.item {
padding: 30rpx;
border-radius: 14rpx;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
&-disabled {
position: relative;
&::before {
z-index: 9;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: block;
content: "";
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.5);
}
}
.icon1 {
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
.icon2 {
width: 60rpx;
height: 60rpx;
margin-right: 10rpx;
}
}
}
}
}
</style>
@@ -0,0 +1,170 @@
<template>
<!--pages/user_bill/user_bill.wxml-->
<view class="transfer-record">
<tabs :active="active" line-width="40" @change="onChange">
<tab title="全部">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item bg-white row">
<view class="flexnone mr20">
<image class="avatar" :src="item.avatar"></image>
</view>
<view class="flex1 mr20">
<view class="black mb10">{{item.nickname}}</view>
<view class="xs muted">会员ID:{{item.sn}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg flexnone ' + (item.type == 1 ? 'primary' : '')">
{{item.type == 1 ? '+' : '-'}}{{item.money}}
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无记录</text>
</view>
</loading-footer>
</tab>
<tab title="转出">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item bg-white row">
<view class="flexnone mr20">
<image class="avatar" :src="item.avatar"></image>
</view>
<view class="flex1 mr20">
<view class="black mb10">{{item.nickname}}</view>
<view class="xs muted">会员ID:{{item.sn}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg flexnone ' + (item.type == 1 ? 'primary' : '')">
{{item.type == 1 ? '+' : '-'}}{{item.money}}
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无转出记录</text>
</view>
</loading-footer>
</tab>
<tab title="转入">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item bg-white row">
<view class="flexnone mr20">
<image class="avatar" :src="item.avatar"></image>
</view>
<view class="flex1 mr20">
<view class="black mb10">{{item.nickname}}</view>
<view class="xs muted">会员ID:{{item.sn}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg flexnone ' + (item.type == 1 ? 'primary' : '')">
{{item.type == 1 ? '+' : '-'}}{{item.money}}
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">暂无转入记录</text>
</view>
</loading-footer>
</tab>
</tabs>
</view>
</template>
<script>
import {
transferRecord
} from "@/api/user";
import {
loadingType
} from "@/utils/type";
import {
loadingFun
} from "@/utils/tools"
export default {
data() {
return {
active: 0,
lists: [],
page: 1,
loadingStatus: loadingType.LOADING
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.active = parseInt(options.type || 0);
this.transferRecordFun(this.active);
},
onReachBottom: function() {
this.transferRecordFun(this.active);
},
methods: {
onChange(e) {
this.active = e;
this.cleanStatus();
this.transferRecordFun(e);
},
cleanStatus() {
//
this.page = 1;
this.lists = [];
this.loadingStatus = loadingType.LOADING
},
transferRecordFun(type) {
let changeType = 'all';
type == 0 ? changeType = 'all' : type == 1 ? changeType = 'out' : changeType = 'in';
let {
lists,
loadingStatus,
page
} = this;
loadingFun(transferRecord, page, lists, loadingStatus, {
type: changeType
}).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
.transfer-record {
.list {
.item {
padding: 20rpx 30rpx;
border-bottom: $-solid-border;
align-items: flex-start;
.avatar {
width: 68rpx;
height: 68rpx;
border-radius: 50%;
}
}
}
}
.data-null {
padding-top: 150rpx;
}
</style>
+185
View File
@@ -0,0 +1,185 @@
<template>
<!--pages/user_bill/user_bill.wxml-->
<view class="user-bill">
<tabs :active="active" line-width="40" @change="onChange">
<tab title="全部">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item">
<view class="bill-list bg-white">
<view class="bill-item row-between">
<view>
<view class="black mb10">{{item.source_type}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg ' + (item.change_type == 1 ? 'income' : '')">{{item.change_amount}}</view>
</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无记录</text>
</view>
</loading-footer>
</tab>
<tab title="支出">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item">
<view class="bill-list bg-white">
<view class="bill-item row-between">
<view>
<view class="black mb10">{{item.source_type}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view class="lg">{{item.change_amount}}</view>
</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无支出记录</text>
</view>
</loading-footer>
</tab>
<tab title="收入">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item">
<view class="bill-list bg-white">
<view class="bill-item row-between">
<view>
<view class="black mb10">{{item.source_type}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view class="lg income">{{item.change_amount}}</view>
</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">暂无收入记录</text>
</view>
</loading-footer>
</tab>
</tabs>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getAccountLog } from "@/api/user";
import { loadingType } from "@/utils/type";
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
active: 0,
lists: [],
page: 1,
loadingStatus: loadingType.LOADING
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options.type, "option.type")
this.active = parseInt(options.type);
this.getAccountLogFun(this.active);
},
onReachBottom: function () {
this.getAccountLogFun(this.active);
},
methods: {
onChange(e) {
this.active = e;
this.cleanStatus();
this.getAccountLogFun(e);
},
cleanStatus() {
//
this.page = 1;
this.lists = [];
this.loadingStatus = loadingType.LOADING
},
getAccountLogFun(type) {
let changeType = 0;
changeType = type == 0 ? 0 : type == 1 ? 2 : 1;
let {
lists,
loadingStatus,
page
} = this;
loadingFun(getAccountLog, page, lists, loadingStatus, { source: 1, type: changeType}).then(res => {
if(res) {
this.page = res.page;
this.lists = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
/* pages/user_bill/user_bill.wxss */
.user-bill {
.list {
.item {
.time{
padding: 30rpx;
}
.bill-list {
.bill-item {
padding: 20rpx 30rpx;
border-bottom: $-solid-border;
.income {
color: $-color-primary;
}
}
}
}
}
}
.order-null {
padding-top: 200rpx;
}
.data-null {
padding-top: 150rpx;
}
</style>
+313
View File
@@ -0,0 +1,313 @@
<template>
<view class="user-fans-box">
<view class="header">
<view class="top-bar row bg-white md">
<view :class="'bar-item row-center ' + (active == 'all' ? 'item-active' : '')" @tap="changeTab" data-active="all">全部粉丝</view>
<view :class="'bar-item row-center ' + (active == 'first' ? 'item-active' : '')" @tap="changeTab" data-active="first">一级粉丝</view>
<view :class="'bar-item row-center ' + (active == 'second' ? 'item-active' : '')" @tap="changeTab" data-active="second">二级粉丝</view>
</view>
<u-search
v-model="keyword"
shape="round"
background="white"
:show-action="true"
action-text="确定"
placeholder="请输入搜索关键词"
@search="onSearch"
@custom="onSearch"
/>
<view class="sort-bar row">
<view class="sort-bar-item row-center nr" @tap="sortStatusChange" data-sort-type="0">
<view :class="sortType == 0 ? 'item-active' : ''">团队排序</view>
<view class="column">
<trigonometry direction="up" :color="fansSort == 'asc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
<trigonometry :color="fansSort == 'desc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
</view>
</view>
<view class="sort-bar-item row-center nr" @tap="sortStatusChange" data-sort-type="1">
<view :class="sortType == 1 ? 'item-active' : ''">金额排序</view>
<view class="column">
<trigonometry direction="up" :color="moneySort == 'asc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
<trigonometry :color="moneySort == 'desc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
</view>
</view>
<view class="sort-bar-item row-center nr" @tap="sortStatusChange" data-sort-type="2">
<view :class="sortType == 2 ? 'item-active' : ''">订单排序</view>
<view class="column">
<trigonometry direction="up" :color="orderSort == 'asc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
<trigonometry :color="orderSort == 'desc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
</view>
</view>
</view>
</view>
<view class="content">
<view class="data-null" v-if="false">
<view class="muted">暂无相关数据...</view>
</view>
<view v-else class="card-box">
<view v-for="(item, index) in fansObject" :key="index" class="card-item row-between">
<view class="row">
<view class="card-img">
<u-image :src="item.avatar" round width="100%" height="100%" />
</view>
<view class="fans-info ml10">
<view class="fans-name row">{{item.nickname}}</view>
<view class="row lighter mt5">
<view>{{item.mobile}}</view>
<view class="ml20">{{item.create_time}}</view>
</view>
</view>
</view>
<view class="column xs">
<view class="msg"><span class="primary">{{item.fans_team}} </span></view>
<view class="mt5 msg"><span>{{item.fans_order}} </span></view>
<view class="mt5 msg"><span>{{item.fans_money}} </span></view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text>暂无相关数据...</text>
</view>
</loading-footer>
</view>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { loadingType, SortType, FansType } from '@/utils/type';
import { getUserFans } from '@/api/user';
import {loadingFun} from '@/utils/tools'
export default {
data() {
return {
active: FansType.ALL,
loadingStatus: loadingType.LOADING,
sortType: 0,
keyword: "",
page: 1,
fansSort: SortType.ASC,
moneySort: SortType.NONE,
orderSort: SortType.NONE,
fansObject: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getUserFansFun();
},
onReachBottom() {
this.getUserFansFun();
},
methods: {
onSearch() {
console.log(this.keyword);
this.cleanStatus();
this.getUserFansFun();
},
changeTab(e) {
let {
active
} = e.currentTarget.dataset;
this.active = active
this.cleanStatus();
this.getUserFansFun();
},
//
getUserFansFun() {
const {
fansSort,
moneySort,
orderSort,
active,
loadingStatus,
keyword,
fansObject,
page,
} = this;
const inputData = {
type: active,
keyword,
fans: fansSort,
money: moneySort,
order: orderSort
};
loadingFun(getUserFans, page, fansObject, loadingStatus, inputData).then(res => {
if(res) {
this.page = res.page;
this.fansObject = res.dataList
this.loadingStatus = res.status
}
})
},
//
cleanStatus() {
this.loadingStatus = loadingType.LOADING;
this.fansObject = [];
this.page = 1
},
//
sortStatusChange(e) {
let {
sortType
} = e.currentTarget.dataset;
let {
fansSort,
moneySort,
orderSort
} = this;
this.sortType = parseInt(sortType)
switch (parseInt(sortType)) {
case 0:
//
if (fansSort == SortType.NONE || fansSort == SortType.DESC) {
this.fansSort = SortType.ASC;
this.moneySort = SortType.NONE
this.orderSort = SortType.NONE
}
else if (fansSort == SortType.ASC) {
this.fansSort = SortType.DESC;
this.moneySort = SortType.NONE;
this.orderSort = SortType.NONE;
}
break;
case 1:
//
if (moneySort == SortType.DESC || moneySort == SortType.NONE) {
this.moneySort = SortType.ASC;
this.fansSort = SortType.NONE;
this.orderSort = SortType.NONE
} else if (moneySort == SortType.ASC) {
this.moneySort = SortType.DESC;
this.fansSort = SortType.NONE;
this.orderSort = SortType.NONE;
}
break;
case 2:
//
if (orderSort == SortType.DESC || orderSort == SortType.NONE) {
this.orderSort = SortType.ASC;
this.moneySort = SortType.NONE;
this.fansSort = SortType.NONE;
} else if (orderSort == SortType.ASC) {
this.orderSort = SortType.DESC;
this.moneySort = SortType.NONE;
this.fansSort = SortType.NONE;
}
break;
}
this.cleanStatus();
this.getUserFansFun();
}
}
};
</script>
<style lang="scss">
/* pages/user_fans/user_fans.wxss */
.user-fans-box {
.header {
.top-bar {
padding: 18rpx 50rpx;
height: 100rpx;
.bar-item {
flex: 1;
line-height: 34rpx;
height: 100%;
&:not(:last-of-type) {
margin-right: 54rpx;
}
}
.item-active {
color: white;
background-color: $-color-primary;
border-radius: 100rpx;
height: 100%;
}
}
.sort-bar {
background-color: white;
height: 80rpx;
.sort-bar-item {
flex: 1;
line-height: 40rpx;
height: 100%;
.item-active {
color: $-color-primary;
}
}
}
}
}
.content {
.data-null {
padding-top: 200rpx;
line-height: 40rpx;
}
.card-box {
margin-top: 20rpx;
.card-item {
padding: 20rpx;
background-color: white;
.card-img {
width: 100rpx;
height: 100rpx;
flex: none;
}
.fans-info {
.fans-name {
line-height: 44rpx;
}
}
.msg {
line-height: 32rpx;
text-align: right;
}
&:not(:nth-last-of-type(3)) {
border-bottom: $-solid-border;
}
}
}
}
</style>
+71
View File
@@ -0,0 +1,71 @@
<template>
<view class="user-group">
<tabs :active="active" @change="changeShow">
<tab v-for="(item, index) in group" :key="index" :title="item.name">
<group-list v-if="item.isShow" :ref="'group' + item.type" :group-type="item.type"></group-list>
</tab>
</tabs>
</view>
</template>
<script>
import { groupType } from "@/utils/type";
export default {
data() {
return {
active: "",
typeStr: "",
group: [{
name: '全部',
type: groupType.ALL,
isShow: false
}, {
name: '拼团中',
type: groupType.PROGESS,
isShow: false
}, {
name: '拼团成功',
type: groupType.SUCCESS,
isShow: false
}, {
name: '拼团失败',
type: groupType.FAIL,
isShow: false
}]
};
},
onLoad: function (options) {
const{group} = this
let type = options.type || groupType.ALL;
let index = group.findIndex(item => item.type == type)
this.changeShow(index);
},
onPullDownRefresh: function () {
const {active, group} = this
console.log(this.$refs['group' + group[active].type])
this.$refs['group' + group[active].type][0].reflesh()
},
onReachBottom: function () {
const {active, group} = this
console.log(this.$refs['group' + group[active].type])
this.$refs['group' + group[active].type][0].getUserGroupFun()
},
methods: {
changeShow(index) {
if(index != -1) {
this.active = index
this.group[index].isShow = true
}
},
}
};
</script>
<style>
</style>
+330
View File
@@ -0,0 +1,330 @@
<template>
<view>
<!-- pages/user_payment/user_payment.wxml -->
<view class="user-payment">
<form report-submit="true">
<view class="payment bg-white">
<view class="md normal row" style="padding: 66rpx 66rpx 0">
充值金额
</view>
<view class="input row">
<text style="font-size: 46rpx"></text>
<input :placeholder="placeholder" type="digit" @focus="setPlaceholder"
@blur="setPlaceholderStatus" :value="number" @input="onInput"></input>
</view>
<view class="tip muted mt20 row">
提示当前余额为
<text class="primary">{{userInfo.user_money || 0}}</text>
</view>
</view>
<button size="lg" class="btn white br60" @tap="rechargeRights">
立即充值
</button>
</form>
<view class="fast-payment-container">
<view class="title bold normal row">推荐充值</view>
<view class="fast-pay row wrap">
<view v-for="(item, index) in rechargeObj" :key="index" class="fast-pay-item bg-white column-center"
@tap="temRecharge" :data-id="item.id">
<view class="hot-recharge white" v-if="item.is_recommend">热门充值</view>
<view class="price primary bold">
<price-format weight="500" :firstSize="42" :secondSize="42" :price="item.money">
</price-format>
<text class="xxl" style="font-weight: 500"></text>
</view>
<view class="preferential primary xs">{{item.tips}}</view>
</view>
</view>
</view>
</view>
<u-popup class="pay-popup" v-model="showPopup" closeable round mode="center">
<view class="content bg-white">
<image class="img-icon" src="../../static/images/recharge_success.png"></image>
<view class="xxl bold mt10">充值成功</view>
<view v-if="rechargeInfo.give_integral || rechargeInfo.give_growth" class="lg"
style="margin-top: 50rpx">恭喜您获得 <text><text class="primary"
v-if="rechargeInfo.give_integral">{{rechargeInfo.give_integral}}</text> 积分</text> <text
v-if="rechargeInfo.give_growth">+ <text
class="primary">{{rechargeInfo.give_growth}}</text>成长值</text></view>
<button class="br60 btn" type="primary" size="md" @tap="onShowPopup">好的谢谢</button>
</view>
</u-popup>
<loading-view id="van-toast" v-if="showLoading" backgroundColor="rgba(0, 0, 0, 0)"></loading-view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
rechargeTemplate,
recharge,
getUser
} from '@/api/user';
import {
prepay
} from '@/api/app';
import {
wxpay
} from '@/utils/pay';
export default {
data() {
return {
navRecharge: ['账户充值', '佣金转入'],
active: 0,
number: '',
placeholder: "0.00",
rechargeObj: [],
showPopup: false,
rechargeInfo: {},
userInfo: {},
showLoading: false
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.rechargeTemplateFun();
this.getUserInfoFun();
uni.$on('payment', params => {
if (params.result) {
this.onShowPopup()
this.getUserInfoFun()
uni.navigateBack()
}
})
},
onUnload() {
uni.$off('payment')
},
methods: {
onShowPopup() {
this.showPopup = !this.showPopup
},
setPlaceholderStatus: function(event) {
if (event.detail.value.length == 0) {
this.placeholder = '0.00'
}
},
setPlaceholder: function() {
this.placeholder = ''
},
getUserInfoFun() {
getUser().then(res => {
if (res.code == 1) {
this.userInfo = res.data
}
});
},
rechargeTemplateFun() {
rechargeTemplate().then(res => {
if (res.code == 1) {
this.rechargeObj = res.data
}
});
},
rechargeRights() {
const {
number
} = this;
this.rechargeFun({
money: Number(number)
});
},
temRecharge(e) {
let {
id
} = e.currentTarget.dataset;
this.rechargeFun({
id
});
},
rechargeFun(obj) {
this.showLoading = true
recharge(obj).then(({ code, data, msg }) => {
if (code != 1) throw new Error(msg)
this.rechargeInfo = data
uni.navigateTo({
url: `/pages/payment/payment?from=${'recharge'}&order_id=${data.id}`
})
}).catch(err => {
console.log(err)
}).finally(() => {
this.showLoading = false
})
},
checkInputText: function(text) {
var reg = /^(\.*)(\d+)(\.?)(\d{0,2}).*$/g;
if (reg.test(text)) {
//
text = text.replace(reg, '$2$3$4');
} else {
//
text = '';
}
return text; //2
},
onInput(e) {
let number = e.detail.value;
number = this.checkInputText(number);
this.number = number
}
}
};
</script>
<style lang="scss">
/* pages/user_payment/user_payment.wxss */
.user-payment {
padding: 20rpx 30rpx;
.payment {
text-align: center;
border-radius: 20rpx;
overflow: hidden;
padding-bottom: 74rpx;
.nav {
margin: 20rpx 95rpx 80rpx;
.item {
flex: 1;
.line {
width: 110rpx;
height: 2px;
}
}
}
.line {
width: 110rpx;
height: 2px;
}
.input {
margin-left: 66rpx;
margin-top: 35rpx;
margin-right: 30rpx;
input {
height: 94rpx;
text-align: left;
font-size: 66rpx;
margin-left: 30rpx;
}
border-bottom: $-solid-border;
}
.tip {
margin: 25rpx 66rpx;
}
}
.btn {
background: linear-gradient(79deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
margin: 70rpx 0 30rpx;
}
.fast-payment-container {
margin-top: 72rpx;
.title {
font-size: 38rpx;
line-height: 53rpx;
}
.fast-pay {
margin-top: 40rpx;
.fast-pay-item {
position: relative;
width: 214rpx;
height: 150rpx;
border-radius: 10rpx;
margin-bottom: 16rpx;
border: 1px solid $-color-primary;
&:not(:nth-of-type(3n)) {
margin-right: 24rpx;
}
.hot-recharge {
position: absolute;
padding: 2rpx 10rpx;
background: linear-gradient(180deg, #FF2C3C 0%, #F95F2F 100%);
border-radius: 0 10rpx 0 10rpx;
font-size: 20rpx;
top: 0;
right: 0;
}
.price {
font-size: 42rpx;
line-height: 50rpx;
}
.preferential {
line-height: 32rpx;
}
}
}
}
}
.pay-popup {
.content {
padding: 40rpx 0;
text-align: center;
width: 560rpx;
border-radius: 20rpx;
}
.img-icon {
width: 168rpx;
height: 118rpx;
display: inline-block;
}
.btn {
margin: 80rpx 60rpx 0;
}
}
</style>
+702
View File
@@ -0,0 +1,702 @@
<template>
<view class="user-profile-container mt10">
<view class="user-profile">
<view class="user-avatar-box row-start" @click="handleUser">
<!-- <button
class="column column-center"
hover-class="none"
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar"
@click="onChooseAvatar"
>
</button> -->
<image
class="user-avatar"
:src="
userInfo.avatar != ''
? userInfo.avatar
: '../../static/images/default_avatar.png'
"
@click="handleUser"
>
</image>
<view class="row-between flex1">
<view class="ml30 text-name">
<view class="">
{{ userInfo.nickname }}
</view>
<view> ID:{{ userInfo.sn }} </view>
</view>
<u-icon name="arrow-right" />
</view>
<!-- <view class="muted xs" @click="handleUser">点击修改头像</view> -->
</view>
<!-- <view class="row-info row bdb-line" @click="changeName">
<view class="label md">昵称</view>
<view class="md row" style="flex: 1">{{ userInfo.nickname }}</view>
<u-icon name="arrow-right" />
</view> -->
<!-- <view class="row-info row bdb-line" @click="changeSex()">
<view class="label md">性别</view>
<view class="md row" :class="userInfo.sex == 0 ? 'muted' : ''" style="flex: 1">
{{ userInfo.sex == 0 ? '未设置' : userInfo.sex == 1 ? '男' : '女' }}
</view>
<u-icon name="arrow-right" />
</view> -->
<!-- <view class="row-info row bdb-line">
<view class="label md">手机号</view>
<view class="md row" :class="{ muted: !userInfo.mobile }" style="flex: 1">
{{ userInfo.mobile ? userInfo.mobile : '未绑定' }}
</view> -->
<!-- #ifdef H5 || APP-PLUS -->
<!-- <view class="bd-btn br60 row-center" @click="showModifyMobile">
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</view> -->
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<!-- <button
class="bd-btn br60 row-center"
size="sm"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</button> -->
<!-- #endif -->
<!-- </view> -->
<view class="row-info row-between bdb-line mt10" @tap="toSetPayPwd">
<view class="label md">转账密码</view>
<u-icon name="arrow-right" />
</view>
<!-- #ifdef H5 -->
<view class="row-info row-between bdb-line" @tap="bindWechat" v-if="!userInfo.oa_auth">
<view class="label md">微信授权</view>
<u-icon name="arrow-right" />
</view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="row-info row-between" @click="showPwdPop">
<view class="label md">登录密码</view>
<view class="row">
<view class="muted nr">点击设置</view>
<u-icon name="arrow-right" />
</view>
</view>
<!-- #endif -->
<view class="row-info row-between bdb-line mt10" @click="goToExplain(0)">
<view class="label md">服务协议</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row-between bdb-line" @click="goToExplain(1)">
<view class="label md">隐私政策</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row-between bdb-line" @click="goLicense()">
<view class="label md">版权信息</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row-between">
<view class="label md">关于我们</view>
<view>v{{ version }}</view>
</view>
<view class="bg-primary white save-btn row-center lg" @click="logout">退出登录</view>
<!-- 版权信息 -->
<view class="license xs" v-if="appConfig.copyright_info">
<view>{{ appConfig.copyright_info }}</view>
<view>{{ appConfig.icp_number }}</view>
</view>
</view>
<u-popup type="center" closeable v-model="showMobile" mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showMobile">
<view class="title xl">{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row" v-else>
<view style="width: 71px">手机号</view>
<input v-model="new_mobile" placeholder="请输入绑定手机号" />
</view>
<view class="modify-row row">
<view style="width: 71px">验证码</view>
<input
v-model="smsCode"
style="padding-left: 5px; width: 130px"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-b"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 71px">新手机号</view>
<input v-model="new_mobile" placeholder="请输入新的手机号码" />
</view>
<view class="primary mt10"
>{{
userInfo.mobile ? '更改' : '绑定'
}}手机号码成功后您的账号将会变更为该设置号码</view
>
<view class="btn bg-primary white row-center" @click="$changeUserMobile">确定</view>
</view>
</u-popup>
<!-- 昵称修改组件 -->
<u-popup
v-model="showNickName"
:closeable="true"
:maskCloseAble="false"
mode="center"
border-radius="14"
>
<view
class="modify-container column-center bg-white"
style="width: 70vw; padding: 24rpx"
>
<view class="title xl">修改用户名</view>
<form @submit="changeNameConfirm">
<u-form-item label="新昵称" :labelWidth="120">
<input
style="height: 60rpx"
class="nr"
:value="userInfo.nickname"
name="nickname"
type="nickname"
placeholder="请输入新的昵称"
/>
</u-form-item>
<button class="btn bg-primary white row-center" form-type="submit">确定</button>
</form>
</view>
</u-popup>
<u-popup v-model="showPwd" closeable mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showPwd">
<view class="title xl">设置密码</view>
<view class="modify-row row">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row">
<view style="width: 142rpx">验证码</view>
<input
v-model="smsCode"
style="padding-left: 10rpx; width: 260rpx"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-a"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row">
<view style="width: 71px">设置密码</view>
<input type="password" v-model="pwd" placeholder="请输入新密码" />
</view>
<view class="modify-row row">
<view style="width: 71px">确认密码</view>
<input type="password" v-model="comfirmPwd" placeholder="再次输入新密码确认" />
</view>
<view class="btn bg-primary white row-center" @click="$forgetPwd">确定</view>
</view>
</u-popup>
<u-picker
mode="selector"
v-model="showPicker"
:default-selector="[0]"
:range="sexList"
@confirm="onConfirm"
/>
<view class="xs muted" style="margin: 50rpx 0;">
<view class="row-center">
likeshop 提供免费开源商城系统
</view>
<view class="row-center">
© likeshop.cn
</view>
</view>
</view>
</template>
<script>
import { userLogout, getUserInfo, changeUserMobile, setUserInfo, setWechatInfo } from '@/api/user'
import { version } from '@/config/app'
import { sendSms, forgetPwd } from '@/api/app'
import { bindOawechat } from '@/api/user'
import { SMSType } from '@/utils/type'
import { mapState, mapGetters } from 'vuex'
import { uploadFile, isWeixinClient, trottle } from '@/utils/tools'
import { getWxCode, getUserProfile } from '@/utils/login'
import wechath5 from '@/utils/wechath5'
const FieldType = {
NONE: '',
SEX: 'sex',
NICKNAME: 'nickname',
AVATAR: 'avatar',
MOBILE: 'mobile'
}
export default {
name: 'userProfile',
data() {
return {
version: version,
fileList: [],
userInfo: {},
new_mobile: '',
smsCode: '',
newNickname: '',
sexList: ['男', '女'],
fieldType: FieldType.NONE,
showPicker: false,
showMobile: false,
showPwd: false,
showNickName: false,
tips: '',
canSendSms: true,
pwd: '',
comfirmPwd: '',
smsType: SMSType.FINDPWD,
code: ''
}
},
methods: {
oaAuth() {
wechath5.getWxUrl()
},
bindWechat() {
this.oaAuth()
},
handleUser() {
console.log(123465)
uni.redirectTo({
url: '/bundle/pages/user_set/user_set'
})
},
codeChange(text) {
this.tips = text
},
onChooseAvatar(e) {
this.fieldType = FieldType.AVATAR
// #ifndef MP-WEIXIN
// uView"-JS"uniuni.navigateTo
uni.$u.route({
// ""
url: '/components/uview-ui/components/u-avatar-cropper/u-avatar-cropper',
//
params: {
// px
destWidth: 300,
// px
rectWidth: 200,
// 'png'"jpg"
fileType: 'jpg'
}
})
// #endif
// #ifdef MP-WEIXIN
if (e.detail.avatarUrl) {
console.log(e.detail.avatarUrl)
this.uploadImage(e.detail.avatarUrl)
}
// #endif
},
//
async changeNameConfirm(e) {
this.fieldType = FieldType.NICKNAME
this.newNickname = e.detail.value.nickname
if (!this.newNickname)
return this.$toast({
title: '请输入新的昵称'
})
await this.$setUserInfo(this.newNickname)
this.showNickName = false
},
// end
logout() {
// 退
userLogout({
token: this.token
}).then((res) => {
if (res.code == 1) {
this.$store.commit('LOGOUT')
this.$toast({
title: '退出成功'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/login/login'
})
}, 500)
}
})
},
goToExplain(value) {
uni.navigateTo({
url: '/bundle/pages/server_explan/server_explan?type=' + value
})
},
goLicense() {
uni.navigateTo({
url: '/bundle/pages/license/license'
})
},
toSetPayPwd() {
if (!this.userInfo.mobile)
return this.$toast({
title: '请先设置手机号'
})
uni.navigateTo({
url: '/bundle/pages/set_pay_pwd/set_pay_pwd'
})
},
//
$sendSms(type) {
if (!this.canSendSms) return
sendSms({
mobile: this.userInfo.mobile || this.new_mobile,
key: this.smsType
}).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$refs.uCode.start()
}
})
},
$getUserInfo() {
getUserInfo().then((res) => {
if (res.code == 1) {
this.userInfo = res.data
}
})
},
//
showModifyMobile() {
this.smsCode = ''
this.new_mobile = ''
this.showMobile = true
this.smsType = this.userInfo.mobile ? SMSType.CHANGE_MOBILE : SMSType.BIND
},
$changeUserMobile() {
if (!this.smsCode) {
this.$toast({
title: '请输入验证码'
})
return
}
if (!this.new_mobile) {
this.$toast({
title: '请输入新的手机号码'
})
return
}
changeUserMobile({
mobile: this.userInfo.mobile,
new_mobile: this.new_mobile,
code: this.smsCode,
action: this.userInfo.mobile ? 'change' : ''
}).then((res) => {
if (res.code == 1) {
this.showMobile = false
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
})
},
// end
//
async $setUserInfo(value) {
const res = await setUserInfo({
field: this.fieldType,
value: value
})
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
},
// end
timeChange(timestamp) {
console.log(timestamp, 'timestamp')
},
onConfirm(value) {
this.$setUserInfo(value[0] + 1)
this.showPicker = false
},
changeSex(e) {
this.showPicker = true
this.fieldType = FieldType.SEX
},
//
countDownFinish() {
this.canSendSms = true
},
//
showPwdPop() {
if (!this.userInfo.mobile) {
this.$toast({
title: '请绑定手机后再设置密码'
})
return
}
this.smsCode = ''
this.smsType = SMSType.FINDPWD
this.showPwd = true
},
$forgetPwd() {
let { smsCode, pwd, comfirmPwd } = this
if (!smsCode) {
this.$toast({
title: '请填写短信验证码'
})
return
}
if (!pwd) {
this.$toast({
title: '请输入新密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '再次输入新密码确认'
})
return
}
if (pwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
let data = {
mobile: this.userInfo.mobile,
code: smsCode,
password: pwd,
repassword: comfirmPwd
}
forgetPwd(data).then((res) => {
if (res.code == 1) {
this.showPwd = false
this.$toast({
title: '设置密码成功'
})
this.$getUserInfo()
}
})
},
// end
//
changeName() {
this.fieldType = FieldType.NICKNAME
this.newNickname = ''
this.showNickName = true
},
// end
async getPhoneNumber(e) {
const { encryptedData, iv } = e.detail
let data = {
code: this.code,
encrypted_data: encryptedData,
iv
}
this.fieldType = FieldType.MOBILE
if (encryptedData) {
this.$changeUserMobileMP(data)
}
},
$changeUserMobileMP(data) {
changeUserMobile(data).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
})
},
uploadImage(path) {
uni.showLoading({
title: '正在上传中...',
mask: true
})
uploadFile(path)
.then((res) => {
uni.hideLoading()
this.$setUserInfo(res.url)
})
.catch(() => {
uni.hideLoading()
this.$toast({
title: '上传失败'
})
})
}
},
async onLoad(options) {
// #ifdef H5
const bindCode = options.code
if (bindCode) {
if (Array.isArray(bindCode)) bindCode = bindCode.pop()
await bindOawechat({ code: bindCode })
}
// #endif
this.$getUserInfo()
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
//
uni.$on('uAvatarCropper', (path) => {
console.log(path)
this.uploadImage(path)
})
this.getUserProfile = trottle(this.getUserProfile, 500, this)
},
onUnload() {
uni.$off('uAvatarCropper')
},
computed: {
...mapState(['token']),
...mapGetters(['appConfig'])
}
}
</script>
<style lang="scss">
.user-profile-container {
.user-profile {
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar-box {
padding: 30rpx 20rpx;
background-color: white;
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
}
.row-info {
padding: 30rpx 20rpx;
background-color: white;
.label {
width: 180rpx;
}
.bd-btn {
padding: 8rpx 24rpx;
border: 1px solid $-color-primary;
color: $-color-primary;
}
}
.license {
margin-top: 80rpx;
color: #a7a7a7;
text-align: center;
}
.bdb-line {
border-bottom: 1rpx solid #e5e5e5;
}
.save-btn {
margin-top: 40rpx;
height: 88rpx;
margin-left: 54rpx;
margin-right: 54rpx;
border-radius: 10rpx;
box-sizing: border-box;
}
.updata-btn {
margin: 0 30rpx;
margin-top: 40rpx;
background-color: #0cc267;
}
}
.modify-container {
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: 30rpx;
width: 580rpx;
border-radius: 30rpx;
background-color: $-color-white;
.title {
padding: 26rpx 0rpx;
}
.modify-row {
padding: 32rpx 0rpx;
width: 100%;
border-bottom: 1rpx solid #e5e5e5;
.send-code-btn {
border: 1px solid $-color-primary;
width: 184rpx;
height: 62rpx;
color: $-color-primary;
}
}
.btn {
height: 80rpx;
padding: 0 180rpx;
border-radius: 20rpx;
margin-top: 60rpx;
}
}
}
.text-name {
display: flex;
flex-direction: column;
justify-content: space-around;
}
</style>
+615
View File
@@ -0,0 +1,615 @@
<template>
<view class="user-profile-container mt10">
<view class="user-profile">
<view class="user-avatar-box column-center">
<button
class="column column-center"
hover-class="none"
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar"
@click="onChooseAvatar"
>
<image
class="user-avatar"
:src="
userInfo.avatar != ''
? userInfo.avatar
: '../../static/images/default_avatar.png'
"
>
</image>
<view class="muted xs">点击修改头像</view>
</button>
</view>
<view class="row-info row bdb-line">
<view class="label md">ID</view>
<view class="md row" style="flex: 1">{{ userInfo.sn }}</view>
</view>
<view class="row-info row bdb-line" @click="changeName">
<view class="label md">昵称</view>
<view class="md row" style="flex: 1">{{ userInfo.nickname }}</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row bdb-line" @click="changeSex()">
<view class="label md">性别</view>
<view class="md row" :class="userInfo.sex == 0 ? 'muted' : ''" style="flex: 1">
{{ userInfo.sex == 0 ? '未设置' : userInfo.sex == 1 ? '男' : '女' }}
</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row bdb-line">
<view class="label md">手机</view>
<view class="md row" :class="{ muted: !userInfo.mobile }" style="flex: 1">
{{ userInfo.mobile ? userInfo.mobile : '未绑定' }}
</view>
<!-- #ifdef H5 || APP-PLUS -->
<view class="bd-btn br60 row-center" @click="showModifyMobile">
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<button
class="bd-btn br60 row-center"
size="sm"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</button>
<!-- #endif -->
</view>
<view class="row-info row bdb-line">
<view class="label md">注册时间 </view>
<view class="md row" style="flex: 1">{{ userInfo.create_time }}</view>
</view>
</view>
<u-popup type="center" closeable v-model="showMobile" mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showMobile">
<view class="title xl">{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row" v-else>
<view style="width: 71px">手机号</view>
<input v-model="new_mobile" placeholder="请输入绑定手机号" />
</view>
<view class="modify-row row">
<view style="width: 71px">验证码</view>
<input
v-model="smsCode"
style="padding-left: 5px; width: 130px"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-b"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 71px">新手机号</view>
<input v-model="new_mobile" placeholder="请输入新的手机号码" />
</view>
<view class="primary mt10"
>{{
userInfo.mobile ? '更改' : '绑定'
}}手机号码成功后您的账号将会变更为该设置号码</view
>
<view class="btn bg-primary white row-center" @click="$changeUserMobile">确定</view>
</view>
</u-popup>
<!-- 昵称修改组件 -->
<u-popup
v-model="showNickName"
:closeable="true"
:maskCloseAble="false"
mode="center"
border-radius="14"
>
<view
class="modify-container column-center bg-white"
style="width: 70vw; padding: 24rpx"
>
<view class="title xl">修改用户名</view>
<form @submit="changeNameConfirm">
<u-form-item label="新昵称" :labelWidth="120">
<input
style="height: 60rpx"
class="nr"
:value="userInfo.nickname"
name="nickname"
type="nickname"
placeholder="请输入新的昵称"
/>
</u-form-item>
<button class="btn bg-primary white row-center" form-type="submit">确定</button>
</form>
</view>
</u-popup>
<u-popup v-model="showPwd" closeable mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showPwd">
<view class="title xl">设置密码</view>
<view class="modify-row row">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row">
<view style="width: 142rpx">验证码</view>
<input
v-model="smsCode"
style="padding-left: 10rpx; width: 260rpx"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-a"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row">
<view style="width: 71px">设置密码</view>
<input type="password" v-model="pwd" placeholder="请输入新密码" />
</view>
<view class="modify-row row">
<view style="width: 71px">确认密码</view>
<input type="password" v-model="comfirmPwd" placeholder="再次输入新密码确认" />
</view>
<view class="btn bg-primary white row-center" @click="$forgetPwd">确定</view>
</view>
</u-popup>
<u-picker
mode="selector"
v-model="showPicker"
:default-selector="[0]"
:range="sexList"
@confirm="onConfirm"
/>
</view>
</template>
<script>
import { userLogout, getUserInfo, changeUserMobile, setUserInfo, setWechatInfo } from '@/api/user'
import { version } from '@/config/app'
import { sendSms, forgetPwd } from '@/api/app'
import { SMSType } from '@/utils/type'
import { mapState, mapGetters } from 'vuex'
import { uploadFile, isWeixinClient, trottle } from '@/utils/tools'
import { getWxCode, getUserProfile } from '@/utils/login'
const FieldType = {
NONE: '',
SEX: 'sex',
NICKNAME: 'nickname',
AVATAR: 'avatar',
MOBILE: 'mobile'
}
export default {
name: 'userProfile',
data() {
return {
version: version,
fileList: [],
userInfo: {},
new_mobile: '',
smsCode: '',
newNickname: '',
sexList: ['男', '女'],
fieldType: FieldType.NONE,
showPicker: false,
showMobile: false,
showPwd: false,
showNickName: false,
tips: '',
canSendSms: true,
pwd: '',
comfirmPwd: '',
smsType: SMSType.FINDPWD,
code: ''
}
},
methods: {
codeChange(text) {
this.tips = text
},
onChooseAvatar(e) {
this.fieldType = FieldType.AVATAR
// #ifndef MP-WEIXIN
// uView"-JS"uniuni.navigateTo
uni.$u.route({
// ""
url: '/components/uview-ui/components/u-avatar-cropper/u-avatar-cropper',
//
params: {
// px
destWidth: 300,
// px
rectWidth: 200,
// 'png'"jpg"
fileType: 'jpg'
}
})
// #endif
// #ifdef MP-WEIXIN
if (e.detail.avatarUrl) {
console.log(e.detail.avatarUrl)
this.uploadImage(e.detail.avatarUrl)
}
// #endif
},
//
async changeNameConfirm(e) {
this.fieldType = FieldType.NICKNAME
this.newNickname = e.detail.value.nickname
if (!this.newNickname)
return this.$toast({
title: '请输入新的昵称'
})
await this.$setUserInfo(this.newNickname)
this.showNickName = false
},
// end
logout() {
// 退
userLogout({
token: this.token
}).then((res) => {
if (res.code == 1) {
this.$store.commit('LOGOUT')
this.$toast({
title: '退出成功'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/login/login'
})
}, 500)
}
})
},
goToExplain(value) {
uni.navigateTo({
url: '/bundle/pages/server_explan/server_explan?type=' + value
})
},
goLicense() {
uni.navigateTo({
url: '/bundle/pages/license/license'
})
},
toSetPayPwd() {
if (!this.userInfo.mobile)
return this.$toast({
title: '请先设置手机号'
})
uni.navigateTo({
url: '/bundle/pages/set_pay_pwd/set_pay_pwd'
})
},
//
$sendSms(type) {
if (!this.canSendSms) return
sendSms({
mobile: this.userInfo.mobile || this.new_mobile,
key: this.smsType
}).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$refs.uCode.start()
}
})
},
$getUserInfo() {
getUserInfo().then((res) => {
if (res.code == 1) {
this.userInfo = res.data
}
})
},
//
showModifyMobile() {
this.smsCode = ''
this.new_mobile = ''
this.showMobile = true
this.smsType = this.userInfo.mobile ? SMSType.CHANGE_MOBILE : SMSType.BIND
},
$changeUserMobile() {
if (!this.smsCode) {
this.$toast({
title: '请输入验证码'
})
return
}
if (!this.new_mobile) {
this.$toast({
title: '请输入新的手机号码'
})
return
}
changeUserMobile({
mobile: this.userInfo.mobile,
new_mobile: this.new_mobile,
code: this.smsCode,
action: this.userInfo.mobile ? 'change' : ''
}).then((res) => {
if (res.code == 1) {
this.showMobile = false
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
})
},
// end
//
async $setUserInfo(value) {
const res = await setUserInfo({
field: this.fieldType,
value: value
})
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
},
// end
timeChange(timestamp) {
console.log(timestamp, 'timestamp')
},
onConfirm(value) {
this.$setUserInfo(value[0] + 1)
this.showPicker = false
},
changeSex(e) {
this.showPicker = true
this.fieldType = FieldType.SEX
},
//
countDownFinish() {
this.canSendSms = true
},
//
showPwdPop() {
if (!this.userInfo.mobile) {
this.$toast({
title: '请绑定手机后再设置密码'
})
return
}
this.smsCode = ''
this.smsType = SMSType.FINDPWD
this.showPwd = true
},
$forgetPwd() {
let { smsCode, pwd, comfirmPwd } = this
if (!smsCode) {
this.$toast({
title: '请填写短信验证码'
})
return
}
if (!pwd) {
this.$toast({
title: '请输入新密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '再次输入新密码确认'
})
return
}
if (pwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
let data = {
mobile: this.userInfo.mobile,
code: smsCode,
password: pwd,
repassword: comfirmPwd
}
forgetPwd(data).then((res) => {
if (res.code == 1) {
this.showPwd = false
this.$toast({
title: '设置密码成功'
})
this.$getUserInfo()
}
})
},
// end
//
changeName() {
this.fieldType = FieldType.NICKNAME
this.newNickname = ''
this.showNickName = true
},
// end
async getPhoneNumber(e) {
const { encryptedData, iv } = e.detail
let data = {
code: this.code,
encrypted_data: encryptedData,
iv
}
this.fieldType = FieldType.MOBILE
if (encryptedData) {
this.$changeUserMobileMP(data)
}
},
$changeUserMobileMP(data) {
changeUserMobile(data).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
})
},
uploadImage(path) {
uni.showLoading({
title: '正在上传中...',
mask: true
})
uploadFile(path)
.then((res) => {
uni.hideLoading()
this.$setUserInfo(res.url)
})
.catch(() => {
uni.hideLoading()
this.$toast({
title: '上传失败'
})
})
}
},
onLoad() {
this.$getUserInfo()
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
//
uni.$on('uAvatarCropper', (path) => {
console.log(path)
this.uploadImage(path)
})
this.getUserProfile = trottle(this.getUserProfile, 500, this)
},
onUnload() {
uni.$off('uAvatarCropper')
},
computed: {
...mapState(['token']),
...mapGetters(['appConfig'])
}
}
</script>
<style lang="scss">
.user-profile-container {
.user-profile {
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar-box {
padding: 30rpx;
background-color: white;
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
}
.row-info {
padding: 30rpx 20rpx;
background-color: white;
.label {
width: 180rpx;
}
.bd-btn {
padding: 8rpx 24rpx;
border: 1px solid $-color-primary;
color: $-color-primary;
}
}
.license {
margin-top: 80rpx;
color: #a7a7a7;
text-align: center;
}
.bdb-line {
border-bottom: 1rpx solid #e5e5e5;
}
.save-btn {
margin-top: 40rpx;
height: 88rpx;
margin-left: 54rpx;
margin-right: 54rpx;
border-radius: 10rpx;
box-sizing: border-box;
}
.updata-btn {
margin: 0 30rpx;
margin-top: 40rpx;
background-color: #0cc267;
}
}
.modify-container {
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: 30rpx;
width: 580rpx;
border-radius: 30rpx;
background-color: $-color-white;
.title {
padding: 26rpx 0rpx;
}
.modify-row {
padding: 32rpx 0rpx;
width: 100%;
border-bottom: 1rpx solid #e5e5e5;
.send-code-btn {
border: 1px solid $-color-primary;
width: 184rpx;
height: 62rpx;
color: $-color-primary;
}
}
.btn {
height: 80rpx;
padding: 0 180rpx;
border-radius: 20rpx;
margin-top: 60rpx;
}
}
}
</style>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,118 @@
<template>
<view class="user-spread-month-bill">
<view v-for="(item, index) in orderList" :key="index">
<view class="bill-time row normal sm">
{{item.date}}
</view>
<view class="show-panel row">
<view class="panel-item column-center">
<price-format :price="item.total_money" showSubscript :subScriptSize="26" color="#FF2C3C" :firstSize="36" :secondSize="36" />
<view class="lighter label mt10">预估收入</view>
</view>
<view class="panel-item column-center">
<view class="normal xxl">{{item.order_num}}</view>
<view class="lighter label mt10">成交笔数</view>
</view>
<view class="panel-item column-center" style="align-self: flex-end;">
<navigator hover-class="none" :url="'/bundle/pages/user_spread_month_bill_detail/user_spread_month_bill_detail?year=' + item.year + '&month=' + item.month" class="row lighter">
查看详情<u-icon name="arrow-right" size="28rpx" color="#666666" />
</navigator>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view slot="empty" class="data-null column-center">
<image src="/static/images/order_null.png" class="img-null"></image>
<view class="muted xs">暂无相关数据</view>
</view>
</loading-footer>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getMonthBill } from "@/api/user";
import { loadingType } from '@/utils/type';
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
orderList: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getMonthBillFun();
},
onReachBottom: function () {
this.getMonthBillFun()
},
methods: {
getMonthBillFun() {
let {
loadingStatus,
page,
orderList
} = this;
loadingFun(getMonthBill, page, orderList, loadingStatus).then(res => {
if(res) {
this.page = res.page;
this.orderList = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
.user-spread-month-bill {
.bill-time {
padding: 20rpx;
line-height: 34rpx;
}
.show-panel {
background-color: white;
padding: 36rpx 0 26rpx;
}
.show-panel {
.panel-item {
flex: 1;
line-height: 34rpx;
}
}
}
.data-null {
padding-top: 200rpx;
}
</style>
@@ -0,0 +1,282 @@
<template>
<view class="user-spread-month-bill">
<view class="header row white">
<view class="header-show column-center">
<view class="num">{{month}}</view>
<view class="label sm row" @tap="openPop">月份 <trigonometry color="white" opacity="1"></trigonometry></view>
</view>
<view class="header-show column-center">
<view class="num">{{order}}</view>
<view class="label sm">成交笔数</view>
</view>
<view class="header-show column-center">
<view>
<price-format showSubscript :subscriptSize="26" :firstSize="42" :secondSize="42" color="#ffffff" :price="money" />
</view>
<view class="label sm">累计预估收益</view>
</view>
</view>
<view class="content">
<view class="order-container">
<view v-for="(item, index) in orderList" :key="index" class="order-item bg-white mb20">
<view class="order-header row-between">
<view>订单编号:{{item.order_sn}}</view>
<view class="white guide-shop-btn row-center">导购订单</view>
</view>
<view class="order-content row">
<view class="order-goods-img">
<custom-image :src="item.image" width="100%" height="100%" radius="6px" />
</view>
<view class="order-goods-info ml10">
<view class="name row sm">{{item.goods_name}}</view>
<view class="pre-income muted">预估收益
<price-format showSubscript subScriptClass="nr" firstClass="nr" secondClass="nr" :color="primaryColor" weight="bold" :price="item.money" />
</view>
</view>
</view>
<view class="order-footer row-between">
<view class="time muted">{{item.create_time}}</view>
<view class="static" :style="'color: ' + (item.status == '待返佣' ? '#F95F2F' : '#07CE1B')">{{item.status}}</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<view class="xs muted">暂无账单明细</view>
</view>
</loading-footer>
</view>
</view>
<u-select v-model="showPop" :list="months" mode="single-column" @confirm="changeMonths" ></u-select>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getMonthOrderDetail } from "@/api/user";
import { loadingType } from '@/utils/type';
const months = [];
for(let i = 1; i <= 12; i ++) {
months.push({
value: i,
label: i + "月"
})
}
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
orderList: [],
month: 1,
year: 2010,
//
money: 0,
//
order: 0,
//
months: months,
chooseMonth: 1,
showPop: false
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.year = options.year;
this.chooseMonth = [Number(options.month)]
this.month = Number(options.month)
},
onShow: function () {
this.getMonthOrderDetailFun();
},
onReachBottom: function () {
this.getMonthOrderDetailFun();
},
methods: {
getMonthOrderDetailFun() {
let {
page,
orderList,
loadingStatus,
year,
month
} = this;
if (loadingStatus == loadingType.FINISHED) return;
getMonthOrderDetail({
page_no: page,
year: year,
month: month
}).then(res => {
if (res.code == 1) {
let {
more,
list,
total_money,
total_order
} = res.data;
orderList.push(...list);
this.orderList = orderList;
this.page ++;
this.money = total_money;
this.order = total_order
if (!more) {
this.loadingStatus = loadingType.FINISHED;
}
if (orderList.length <= 0) {
this.loadingStatus = loadingType.EMPTY
return;
}
} else {
this.loadingStatus = loadingType.ERROR
}
});
},
openPop() {
this.showPop = true
},
closePop() {
this.showPop = false
},
changeMonths(e) {
const val = e[0].value;
this.chooseMonth = val
this.selectMonth()
},
cleanStatus() {
this.loadingStatus = loadingType.LOADING;
this.page = 1;
this.orderList = []
},
selectMonth(e) {
const {
chooseMonth,
month
} = this;
this.month = chooseMonth;
this.showPop = false
this.cleanStatus();
this.getMonthOrderDetailFun();
}
}
};
</script>
<style lang="scss">
.user-spread-month-bill .header {
height: 240rpx;
background-color: $-color-primary;
padding-top: 60rpx;
}
.user-spread-month-bill .header .header-show {
flex: 1;
align-self: flex-start;
}
.user-spread-month-bill .header .header-show .num {
font-size: 42rpx;
}
.user-spread-month-bill .content {
padding: 0 20rpx;
margin-top: -60rpx;
}
.user-spread-month-bill .content .order-container .order-item {
border-radius: 14rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-header {
padding: 20rpx 30rpx;
border-bottom: $-solid-border;
}
.user-spread-month-bill .content .order-container .order-item .order-header .guide-shop-btn {
background: linear-gradient(80deg, #F95F2F 0%, #FF2C3C 100%);
border-radius: 4rpx;
width: 134rpx;
height: 42rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-content {
padding: 20rpx 30rpx 20rpx 20rpx;
border-bottom: $-solid-border;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-img {
width: 140rpx;
height: 140rpx;
flex: none;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-info {
text-align: left;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-info .name {
line-height: 36rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-info .pre-income {
line-height: 34rpx;
margin-top: 8rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-footer {
padding: 20rpx 30rpx 20rpx 20rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-footer .static {
color: #F95F2F;
}
.user-spread-month-bill .content .order-container .order-item .order-footer .wait-return {
color: #F95F2F;
}
.user-spread-month-bill .pop-header {
height: 80rpx;
}
.content .order-container .data-null {
padding-top: 200rpx;
}
</style>
@@ -0,0 +1,98 @@
<template>
<view class="user-promote-order">
<tabs :active="active" :line-width="40" @change="onChange">
<tab v-for="(item, index) in order" :key="index" :title="item.name">
<spread-order :ref="'order' + item.type" class="mt20" v-if="item.isShow" :type="item.type"></spread-order>
</tab>
</tabs>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { userOrderPromoteOrder } from "@/utils/type";
export default {
data() {
return {
order: [{
name: "全部",
type: userOrderPromoteOrder.ALL,
isShow: false
}, {
name: "待返佣",
type: userOrderPromoteOrder.WAIT_RETURN,
isShow: false
}, {
name: "已结算",
type: userOrderPromoteOrder.HANDLED,
isShow: false
}, {
name: "已失效",
type: userOrderPromoteOrder.INVALED,
isShow: false
}],
active: userOrderPromoteOrder.ALL
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let type = parseInt(options.type) || userOrderPromoteOrder.ALL;
this.changeShow(type);
},
onReachBottom: function () {
const {active, order} = this
this.$refs['order' + active][0].getPromoteOrderFun()
},
methods: {
onChange(e) {
this.changeShow(e);
},
changeShow(type) {
const {
order
} = this;
console.log('changeShow');
let index = order.findIndex(item => {
return item.type == type;
});
console.log(index);
if (index != -1) {
this.active = type;
this.order[index].isShow = true
console.log(this.order[index].isShow);
}
}
}
};
</script>
<style>
/* pages/user_spread_order/user_spread_order.wxss */
</style>
+165
View File
@@ -0,0 +1,165 @@
<template>
<!--pages/user_wallet/user_wallet.wxml-->
<view class="user-wallet">
<view class="contain bg-white mb20">
<view class="header">
<view class="white mb20">
<view class="xs">总资产</view>
<view style="font-size: 76rpx">{{wallet.user_money}}</view>
</view>
<view class="money white row">
<view class="item">
<view class="xs">累计充值()</view>
<view style="font-size: 38rpx">{{wallet.total_recharge_amount || 0}}</view>
</view>
<view class="item">
<view class="xs">累计消费()</view>
<view style="font-size: 38rpx">{{wallet.total_order_amount || 0}}</view>
</view>
<navigator v-if="wallet.open_racharge" style="height: 58rpx;" hover-class="none" url="/bundle/pages/user_payment/user_payment" class="row-center primary bg-white br60 btn" size="xs">充值</navigator>
</view>
</view>
<view class="nav row">
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/balance_transfer/balance_transfer">
<image src="../../static/images/icon_yezz.png"></image>
<view class="mt10">余额转账</view>
</navigator>
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/user_bill/user_bill?type=0">
<image src="../../static/images/icon_zhmx.png"></image>
<view class="mt10">账户明细</view>
</navigator>
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/transfer_record/transfer_record">
<image src="../../static/images/icon_zzjl.png"></image>
<view class="mt10">转账记录</view>
</navigator>
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/recharge_code/recharge_code">
<image src="../../static/images/icon_czjl.png"></image>
<view class="mt10">充值记录</view>
</navigator>
</view>
<view class="activity">
<view class="activity-title xl row">
<view class="mr20" style="width: 6rpx;height: 30rpx;background-color: #FF2C3C;"></view> 热门活动
</view>
<view class="activity-item row-between">
<view>
<view class="xl normal" style="font-weight: 500;">会员积分 限时兑换</view>
<view class="muted sm mt10">积分签到抵现金</view>
<navigator class="br60 bg-primary white join-btn row-center" url="/bundle/pages/user_sign/user_sign" hover-class="none">立即参与</navigator>
</view>
<image style="width:274rpx;height: 210rpx;" src="../../static/images/img_activity_jifen.png"></image>
</view>
</view>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getWallet } from '@/api/user';
export default {
data() {
return {
wallet: {}
};
},
components: {
},
props: {},
onShow: function () {
this.getWalletFun();
},
methods: {
getWalletFun() {
getWallet().then(res => {
if (res.code == 1) {
this.wallet = res.data
}
});
}
}
};
</script>
<style lang="scss">
image {
width: 100%;
height: 100%;
}
.user-wallet {
.contain {
padding: 20rpx 30rpx 36rpx;
.header {
position: relative;
background:linear-gradient(180deg,rgba(255,44,60,1) 0%,rgba(255,49,106,1) 100%);
border-radius: 20rpx;
height: 320rpx;
padding: 50rpx 30rpx 30rpx;
box-sizing: border-box;
.money {
.item {
flex: 1;
}
}
.btn {
position: absolute;
right: 30rpx;
top: 50rpx;
padding: 0 51rpx;
}
}
.nav {
.nav-item {
width: 25%;
padding: 40rpx 0;
image {
width: 52rpx;
height: 52rpx;
}
}
}
}
}
.activity {
padding: 40rpx 0rpx;
.activity-title {
font-weight: bold;
}
.activity-item {
padding: 15rpx 40rpx;
box-shadow: 0px 0rpx 20rpx rgba(0, 0, 0, 0.16);
margin-top: 34rpx;
.join-btn {
height: 52rpx;
width: 156rpx;
margin-top: 24rpx;
}
}
}
</style>
@@ -0,0 +1,442 @@
<template>
<view class="user-withdraw">
<view class="user-tab-container">
<tabs :active="active" :line-width="40" @change="onChange" :config="{itemWidth: 200}">
<tab :title="item.name" :name="item.value" v-for="(item, index) in widthDrawWay" :key="index">
<template v-if="item.value == 1 || item.value == 2">
<view class="bg-white withdraw-container mt20">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt20 muted row xs" v-if="item.value == 2">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml10">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">提现记录</navigator>
</template>
<template v-if="item.value == 3">
<view class="bg-white form-container">
<view class="input-item row md">
<view class="input-label ">微信账号</view>
<input v-model="account" placeholder="请输入微信账号"></input>
</view>
<view class="input-item row md">
<view class="input-label ">真实姓名</view>
<input v-model="realName" placeholder="请输入真实姓名"></input>
</view>
<view class="input-item row md">
<view class="input-label ">备注</view>
<input v-model="remark" placeholder="(选填)"></input>
</view>
<view class="uploader-container row mt20">
<uploader @after-read="afterRead" :file-list="fileList" :max-upload="1"
:deletable="true" useSlot @delete="handleDelete">
<view>
<view class="upload-area row-center">
<image src="/static/images/uploader_icon.png"></image>
</view>
<view class="mt10 normal nr" style="line-height: 36rpx;text-align: center;">
微信收款码</view>
</view>
</uploader>
</view>
</view>
<view class="bg-white withdraw-container mt10">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt10 muted row xs">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml5">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">提现记录</navigator>
</template>
<template v-if="item.value == 4">
<view class="bg-white form-container">
<view class="input-item row md">
<view class="input-label ">支付宝账号</view>
<input v-model="account" placeholder="请输入支付宝账号"></input>
</view>
<view class="input-item row md">
<view class="input-label ">真实姓名</view>
<input v-model="realName" placeholder="请输入真实姓名"></input>
</view>
<view class="input-item row md">
<view class="input-label ">备注</view>
<input v-model="remark" placeholder="(选填)"></input>
</view>
<view class="uploader-container row mt20">
<uploader @after-read="afterRead" :file-list="fileList" :max-upload="1"
:deletable="true" useSlot @delete="handleDelete">
<view class="column-center">
<view class="upload-area row-center">
<image src="/static/images/uploader_icon.png"></image>
</view>
<view class="mt10 normal nr" style="line-height: 36rpx;text-align: center;">
支付宝收款码</view>
</view>
</uploader>
</view>
</view>
<view class="bg-white withdraw-container mt10">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt10 muted row xs">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml5">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">
提现记录
</navigator>
</template>
<template v-if="item.value == 5">
<view class="bg-white form-container">
<view class="input-item row md">
<view class="input-label ">银行卡账号</view>
<input v-model="account" placeholder="请输入银行卡账号"></input>
</view>
<view class="input-item row md">
<view class="input-label ">真实姓名</view>
<input v-model="realName" placeholder="请输入真实姓名"></input>
</view>
<view class="input-item row md">
<view class="input-label ">提现银行</view>
<input v-model="bank" placeholder="请输入提现银行"></input>
</view>
<view class="input-item row md">
<view class="input-label ">银行支行</view>
<input v-model="subbank" placeholder="请输入银行支行"></input>
</view>
<view class="input-item row md">
<view class="input-label ">备注</view>
<input v-model="remark" placeholder="(选填)"></input>
</view>
</view>
<view class="bg-white withdraw-container mt10">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt10 muted row xs">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml5">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">
提现记录
</navigator>
</template>
</tab>
</tabs>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
applyWithdraw,
getWithdrawConfig
} from "@/api/user";
import {
uploadFile,
trottle
} from "@/utils/tools";
import {
baseURL
} from '@/config/app';
import {
withdrawType
} from "@/utils/type"
export default {
data() {
return {
active: 0,
money: '',
account: '',
realName: '',
bank: '',
subbank: '',
qrCode: '',
remark: '',
fileList: [],
widthDrawConfig: {},
widthDrawWay: []
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.getWithdrawConfigFun();
this.applyWithdrawFun = trottle(this.applyWithdrawFun, 1000, this)
},
methods: {
allWithdraw(e) {
const {
widthDrawConfig
} = this;
console.log(widthDrawConfig, "widthDrawConfig")
this.money = widthDrawConfig.able_withdraw.toString()
},
onChange(e) {
this.active = e
this.account = "";
this.realName = "";
this.qrCode = "";
this.remark = ""
this.fileList = [];
},
getWithdrawConfigFun() {
getWithdrawConfig().then(res => {
if (res.code == 1) {
this.widthDrawConfig = res.data
this.widthDrawWay = res.data.type
}
});
},
afterRead(e) {
const file = e;
uni.showLoading({
title: '正在上传中...',
mask: true
});
file.forEach(item => {
uploadFile(item.path).then(res => {
uni.hideLoading();
this.fileList.push(res);
this.qrCode = res.url;
});
})
},
handleDelete(index) {
this.fileList.splice(index, 1)
},
//
applyWithdrawFun(type) {
let {
active,
account,
realName,
qrCode,
remark,
money,
bank,
subbank,
widthDrawWay
} = this;
console.log(realName, "###", active, "###", money);
switch (parseInt(type)) {
case withdrawType.ACCOUNT:
break;
case withdrawType.WECHAT:
break
case withdrawType.PAY_WECHAT:
case withdrawType.PAY_ALIPAY:
if (!account) return this.$toast({
title: '请输入账户信息'
})
if (!realName) return this.$toast({
title: '请输入真实姓名'
})
if (!qrCode) return this.$toast({
title: '请上传收款码'
})
break;
case withdrawType.BANK:
if (!account) return this.$toast({
title: '请输入账户信息'
})
if (!realName) return this.$toast({
title: '请输入真实姓名'
})
if (!bank) return this.$toast({
title: '请输入提现银行'
})
if (!subbank) return this.$toast({
title: '请输入银行支行'
})
}
if (!money) {
this.$toast({
title: '请输入提现金额'
});
return;
}
const data = {
type: widthDrawWay[active].value,
money: money,
account: account,
real_name: realName,
money_qr_code: qrCode,
remark: remark,
bank,
subbank
};
applyWithdraw(data).then(res => {
if (res.code == 1) {
this.$toast({
title: '提交成功'
}, {
tab: 2,
url: '/bundle/pages/widthdraw_result/widthdraw_result?id=' + res.data.id
});
}
});
}
}
};
</script>
<style lang="scss">
.van-tabs .van-tabs__wrap {
border-radius: 10rpx;
}
.van-tabs__line {
background: linear-gradient(90deg, #F79C0C 0%, #FF2C3C 100%);
bottom: 8rpx !important;
/* width: 50rpx !important; */
height: 6rpx !important;
border-radius: 100rpx;
}
.user-withdraw {
.user-tab-container {
padding: 20rpx 30rpx;
::v-deep .scroll-view-h {
background-color: #FFFFFF;
}
.withdraw-container {
padding: 52rpx 72rpx;
border-radius: 20rpx;
.input {
border-bottom: $-solid-border;
input {
width: 100%;
height: 94rpx;
text-align: left;
font-size: 66rpx;
margin-left: 30rpx;
}
}
}
.withdraw-btn {
background: linear-gradient(80deg, #F95F2F 0%, #FF2C3C 100%);
line-height: 44rpx;
height: 84rpx;
margin-top: 30rpx;
border-radius: 100rpx;
}
.form-container {
border-radius: 20rpx;
padding: 0 36rpx 26rpx;
line-height: 36rpx;
margin-top: 10rpx;
.input-item {
padding: 28rpx 0 30rpx;
border-bottom: $-solid-border;
}
.input-label {
width: 200rpx;
text-align: left;
line-height: 36rpx;
}
input {
flex: 1;
}
.uploader-container {
.upload-area {
width: 160rpx;
height: 160rpx;
border: 4rpx dashed #E5E5E5;
border-radius: 10rpx;
image {
width: 54rpx;
height: 44rpx;
}
}
}
}
}
}
</style>
@@ -0,0 +1,119 @@
<template>
<view class="user-withdraw-code">
<view class="withdraw-code-container mt10">
<view class="withdraw-code-contain">
<navigator v-for="(item, index) in withdrawRecords" :key="index" class="withdraw-code-item bg-white" hover-class="none"
:url="`/bundle/pages/widthdraw_result/widthdraw_result?id=${item.id}&type=1`">
<view class="row-between">
<view>{{item.desc}}</view>
<price-format showSubscript :subScriptSize="26" :firstSize="36" :secondSize="36" :price="item.left_money" />
</view>
<view class="row-between mt10">
<view class="muted xs time">{{item.create_time}}</view>
<view class="withdraw-status xs" :class="{'error-status' : item.status == 2 || item.status == 4, 'common-status': item.status == 3}">{{item.status_text}}</view>
</view>
<view v-if="item.description && item.status == 4" class="primary mt10 line1 xs">{{item.description}}</view>
</navigator>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image src="/static/images/order_null.png" class="img-null"></image>
<text class="muted">暂无提现记录</text>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getWithdrawRecords } from '@/api/user';
import { loadingType } from '@/utils/type.js';
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
withdrawRecords: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getWithdrawRecordsFun();
},
onReachBottom: function () {
this.getWithdrawRecordsFun()
},
methods: {
getWithdrawRecordsFun() {
let {
loadingStatus,
withdrawRecords,
page
} = this;
loadingFun(getWithdrawRecords, page, withdrawRecords, loadingStatus).then(res => {
if(res) {
this.page = res.page;
this.withdrawRecords = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
.user-withdraw-code {
.withdraw-code-container {
.withdraw-code-item {
padding: 24rpx 30rpx;
.time {
line-height: 32rpx;
}
.withdraw-status {
color: #0CC21E;
}
.common-status {
color: #666666;
}
.error-status {
color: $-color-primary;
}
&:not(:last-of-type) {
border-bottom: var(--border);
}
}
}
.data-null {
padding-top: 200rpx;
}
}
</style>
@@ -0,0 +1,184 @@
<template>
<view class="pay-result">
<view class="contain bg-white">
<view style="border-top: 1rpx solid transparent;">
<view class="header column-center">
<view>
<image class="tips-icon" :src="getStatusImg"></image>
</view>
<view class="xl mt20 line1">{{widthdrawInfo.statusDesc}}</view>
</view>
<view class="column-center mt10">
<price-format :price="widthdrawInfo.money" color="#FF2C3C" showSubscript subscriptSize="30"
firstSize="46" secondSize="46" weight="500" />
</view>
<view class="info">
<view class="order-num row-between mt20">
<view class="ml20">流水号</view>
<view class="mr20">
{{widthdrawInfo.sn}}
</view>
</view>
<view v-if="widthdrawInfo.create_time" class="order-time row-between mt20">
<view class="ml20">提交时间</view>
<view class="mr20">{{widthdrawInfo.create_time}}</view>
</view>
<view class="order-pay-type row-between mt20">
<view class="ml20">提现至</view>
<view class="mr20">{{widthdrawInfo.typeDesc}}</view>
</view>
<view class="order-pay-money row-between mt20">
<view class="ml20">服务费</view>
<view class="mr20">
<price-format :price="widthdrawInfo.poundage" />
</view>
</view>
<view class="order-pay-money row-between mt20">
<view class="ml20">实际到账</view>
<view class="mr20">
<price-format :price="widthdrawInfo.left_money" />
</view>
</view>
</view>
<view class="line ml20" v-if="!type"></view>
<view class="opt-btn-contain row-center wrap" v-if="!type">
<navigator hover-class="none" class="check-order-btn row-center bg-primary br60 mt20"
url="/bundle/pages/user_withdraw_code/user_withdraw_code">
<view class="white bg-primary lg">查看历史提现记录</view>
</navigator>
<navigator hover-class="none" class="go-back-btn row-center br60 mt20" open-type="switchTab"
url="/pages/index/index">
<view class="primary br60 lg">返回首页</view>
</navigator>
</view>
</view>
</view>
<view class="muted mt20 row-center xs">* 审核通过后约72小时内到账请留意账户明细</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
getWithdrawDetail
} from '@/api/user';
export default {
data() {
return {
widthdrawInfo: {},
type: ""
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.id = options.id;
this.type = options.type
this.getWithdrawDetailFun();
},
methods: {
getWithdrawDetailFun() {
getWithdrawDetail({
id: this.id
}).then(res => {
if (res.code == 1) {
this.widthdrawInfo = res.data
}
});
}
},
computed: {
getStatusImg() {
switch (this.widthdrawInfo.status) {
case 1:
"";
case 2:
return '../../static/images/icon_cashOut_wait.png';
case 3:
return '/static/images/icon_paySuccess.png';
case 4:
return '../../static/images/icon_payFail.png';
}
}
}
};
</script>
<style lang="scss">
.pay-result {
overflow: hidden;
.contain {
/* height: 732rpx; */
margin-left: 20rpx;
margin-right: 20rpx;
border-radius: 10rpx;
margin-top: 78rpx;
padding-left: 20rpx;
padding-right: 20rpx;
padding-bottom: 40rpx;
position: relative;
.tips-icon {
width: 112rpx;
height: 112rpx;
}
.header {
margin-top: -56rpx;
}
.info {
margin-bottom: 40rpx;
.order-num {
align-items: flex-start;
}
}
.opt-btn-contain {
margin-top: 40rpx;
.check-order-btn {
width: 650rpx;
height: 84rpx;
}
.go-back-btn {
width: 650rpx;
height: 84rpx;
border: solid 1rpx $-color-primary;
box-sizing: border-box;
}
}
}
}
.line {
width: 650rpx;
border-top: 1px solid rgba(229, 229, 229, 1);
}
</style>
@@ -0,0 +1,85 @@
<template>
<view class="win-prize-code">
<view class="goods-list">
<view class="" v-for="(item, index) in bargainGoods" :key="index">
<view class="bg-white row code-item">
<u-image :src="item.prize_image" width="90rpx" height="90rpx" mode="aspectFill" radius="6rpx"></u-image>
<view class="ml20 desc">
<view class="nr line1 bold">{{item.title}}</view>
<view class="mt10 row-between">
<view class="xs lighter">抽奖时间{{item.create_time}}</view>
<!-- <view class="xs">+100</view> -->
</view>
</view>
</view>
</view>
</view>
<loading-footer slotEmpty :status="loadingStatus">
<view style="padding-top: 200rpx;" class="data-null column-center" slot="empty">
<image src="../../../static/images/order_null.png" class="img-null"></image>
<text class="xs muted">暂无中奖名单</text>
</view>
</loading-footer>
</view>
</template>
<script>
import {
loadingType
} from '@/utils/type';
import {
loadingFun
} from "@/utils/tools"
import {
luckyDrawWinningList
} from "@/api/user";
export default {
data() {
return {
loadingStatus: loadingType.EMPTY,
page: 1,
bargainGoods: [], //
}
},
methods: {
//
getLists() {
let {
loadingStatus,
bargainGoods,
page
} = this;
loadingFun(luckyDrawWinningList, page, bargainGoods, loadingStatus).then(res => {
if (res) {
this.page = res.page;
this.bargainGoods = res.dataList
this.loadingStatus = res.status
}
})
}
},
onLoad() {
this.getLists()
},
onReachBottom() {
this.getLists();
},
}
</script>
<style lang="scss" scoped>
.goods-list {
margin: 0 20rpx;
// margin-top: 20rpx;
.code-item {
margin-top: 20rpx;
padding: 26rpx 24rpx;
}
.desc {
width: 550rpx;
}
}
</style>
@@ -0,0 +1,107 @@
<template>
<view class="writeoff-order">
<template v-if="detail.id">
<view class="list">
<view class="item bg-white">
<view class="row-between title">
<view>联系人{{detail.consignee}}</view>
<view :class="[detail.verification_status == 0 ? 'primary' : 'muted']">{{detail.verification_status_desc}}</view>
</view>
<order-goods :list="detail.order_goods"></order-goods>
</view>
</view>
<view class="btns">
<button class="bg-primary br60 white btn" size="lg" @tap="showModal=true">已提货</button>
<navigator class="mt20" open-type="navigateBack" :delta="1" hover-class="none">
<button class="bg-white br60 btn" size="lg">返回核销列表</button>
</navigator>
</view>
</template>
<template v-else>
<view class="column-center" style="padding-top: 200rpx">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="lighter">抱歉该订单不存在</text>
<view class="btns" style="margin-top: 100rpx;">
<navigator style="width: 100%;" open-type="navigateBack" :delta="1" hover-class="none">
<button class="bg-primary br60 white" size="lg">返回核销列表</button>
</navigator>
</view>
</view>
</template>
<u-modal ref="uModalInput" v-model="showModal" show-cancel-button :confirm-color="primaryColor"
confirm-text="确定" @confirm="handleVerificationConfirm" title="确认核销" content="是否确认核销?">
</u-modal>
<loading-view v-if="isFirstLoading"></loading-view>
</view>
</template>
<script>
import {
verificationConfirm,
verification
} from '@/api/order'
export default {
data() {
return {
detail: {},
showModal: false,
isFirstLoading: true
}
},
methods: {
verificationFun() {
verification({
pickup_code: this.code
}).then(res => {
this.isFirstLoading = false
if(res.code == 1) {
this.detail = res.data
}
})
},
handleVerificationConfirm() {
verificationConfirm({
id: this.detail.id
}).then(res => {
if(res.code == 1) {
uni.$emit('refreshverify')
this.$toast({
title: res.msg
}, {
tab: 3,
url: 1
})
}
})
}
},
async onLoad(options) {
this.code = options.code
this.verificationFun()
console.log(options)
},
}
</script>
<style lang="scss">
.writeoff-order {
.list {
padding: 20rpx;
.item {
border-radius: 10rpx;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
.title {
padding: 20rpx;
}
}
}
.btns {
width: 100%;
padding: 0 40rpx 50rpx;
}
}
</style>
@@ -0,0 +1,169 @@
<template>
<view class="writeoff-order">
<u-tabs :list="order" :active-color="primaryColor" inactive-color="#333" :is-scroll="false" :current="current"
@change="changeCurrent"></u-tabs>
<view class="list">
<view class="item bg-white" v-for="(item, index) in orderList" :key="index">
<view class="row-between title">
<view>联系人{{item.consignee}}</view>
<view :class="[item.verification_status == 0 ? 'primary' : 'muted']">{{item.verification_status_desc}}</view>
</view>
<order-goods :list="item.order_goods"></order-goods>
</view>
</view>
<loading-footer :status="status" :slot-empty="true" @refresh="reflesh">
<view slot="empty" class="column-center" style="padding-top: 200rpx">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="lighter">暂无订单</text>
</view>
</loading-footer>
<view class="btns row-between">
<button class="bg-primary br60 white btn" size="lg" @tap="onScanCode">扫码核销</button>
<button class="bg-primary br60 white btn ml20" size="lg" @tap="showModal=true">手动核销</button>
</view>
<u-modal ref="uModalInput" v-model="showModal" show-cancel-button :confirm-color="primaryColor"
confirm-text="确定" @confirm="onConfirm" title="手动核销">
<view class="slot-content row-center" style="padding: 40rpx;">
<u-input type="number" v-model="code" :border="true" placeholder="请输入核销码" style="width: 100%" />
</view>
</u-modal>
</view>
</template>
<script>
import {
getVerifyLists,
verification
} from '@/api/order'
import {
loadingType
} from '@/utils/type';
import {
loadingFun,
isWeixinClient
} from '@/utils/tools';
import wechath5 from '@/utils/wechath5'
export default {
data() {
return {
page: 1,
orderList: [],
status: loadingType.LOADING,
current: 0,
showModal: false,
code: '',
order: [{
name: '待核销',
type: 0
}, {
name: '已核销',
type: 1
}]
}
},
methods: {
reflesh() {
this.page = 1
this.orderList = []
this.status = loadingType.LOADING
this.getVerifyListsFun();
},
changeCurrent(current) {
this.current = current
this.reflesh()
},
onScanCode() {
// #ifdef H5
if(!isWeixinClient()) return this.$toast({title: 'h5暂不支持扫码'})
wechath5.scanQRCode().then(res => {
this.toDetail(res)
})
// #endif
// #ifndef H5
uni.scanCode({
scanType: ['qrCode'],
success: (res) => {
console.log(res)
this.toDetail(res.result)
},
fail: (res) => {
console.log(res)
}
});
// #endif
},
async getVerifyListsFun() {
let {
page,
orderList,
status,
current,
order
} = this;
const type = order[current].type
const data = await loadingFun(getVerifyLists, page, orderList, status, {
type
})
if (!data) return
this.page = data.page
this.orderList = data.dataList
this.status = data.status
},
onConfirm() {
if(this.code === '') return this.$toast({title: '请输入核销码'})
this.toDetail(this.code)
},
toDetail(code) {
this.code = ''
uni.navigateTo({
url: `/bundle/pages/writeoff_detail/writeoff_detail?code=${code}`,
})
}
},
async onLoad() {
uni.$on("refreshverify", () => {
this.reflesh()
})
this.getVerifyListsFun()
},
onUnload() {
uni.$off('refreshverify')
},
onPullDownRefresh: function() {
this.reflesh()
},
onReachBottom: function() {
this.getVerifyListsFun()
},
}
</script>
<style lang="scss">
.writeoff-order {
padding-bottom: 120rpx;
.list {
padding: 20rpx;
.item {
border-radius: 10rpx;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
.title {
padding: 20rpx;
}
}
}
.btns {
position: fixed;
bottom: env(safe-area-inset-bottom);
width: 100%;
padding: 20rpx 25rpx;
.btn {
flex: 1;
}
}
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB