@ -0,0 +1,3 @@ |
|||
unpackage |
|||
node_modules/ |
|||
.hbuilderx/ |
|||
@ -0,0 +1,94 @@ |
|||
<script> |
|||
import { |
|||
mapActions, |
|||
mapMutations |
|||
} from 'vuex' |
|||
import { |
|||
getConfig |
|||
} from '@/api/app' |
|||
import { |
|||
strToParams |
|||
} from '@/utils/tools' |
|||
import { |
|||
bindSuperior |
|||
} from '@/api/user' |
|||
import {INVITE_CODE} from '@/config/cachekey' |
|||
import Cache from '@/utils/cache' |
|||
export default { |
|||
onLaunch: function(options) { |
|||
//#ifdef MP-WEIXIN |
|||
this.checkMpUpdate() |
|||
//#endif |
|||
// 获取配置 |
|||
this.getConfigFun() |
|||
this.getUser() |
|||
this.getSystemInfo() |
|||
}, |
|||
onShow: function(options) { |
|||
console.log(options) |
|||
this.bindCode(options) |
|||
}, |
|||
onHide: function() { |
|||
|
|||
}, |
|||
methods: { |
|||
...mapActions(['getSystemInfo', 'getUser', 'wxShare', 'initLocationFunc']), |
|||
...mapMutations(['setConfig']), |
|||
async getConfigFun() { |
|||
const { |
|||
code, |
|||
data |
|||
} = await getConfig() |
|||
if (code == 1) { |
|||
this.setConfig(data) |
|||
if(data.is_open_nearby) { |
|||
// 获取定位 |
|||
this.initLocationFunc() |
|||
} |
|||
// 防止第一次调用时拿不到数据 |
|||
this.wxShare() |
|||
} |
|||
|
|||
}, |
|||
async bindCode(options) { |
|||
if(!options.query) return |
|||
let invite_code = options.query.invite_code || strToParams(decodeURIComponent(options.query.scene)) |
|||
.invite_code |
|||
if (invite_code) { |
|||
const { |
|||
data, |
|||
code |
|||
} = await bindSuperior({ |
|||
code: invite_code |
|||
}) |
|||
if (code == -1) { |
|||
Cache.set(INVITE_CODE, invite_code) |
|||
} |
|||
} |
|||
}, |
|||
//#ifdef MP-WEIXIN |
|||
checkMpUpdate() { |
|||
const updateManager = wx.getUpdateManager() |
|||
updateManager.onUpdateReady(function () { |
|||
wx.showModal({ |
|||
title: '更新提示', |
|||
content: '新版本已准备好,是否重启?', |
|||
success: function (res) { |
|||
if (res.confirm) { |
|||
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 |
|||
updateManager.applyUpdate() |
|||
} |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
//#endif |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss"> |
|||
@import 'styles/common.scss'; |
|||
@import "components/uview-ui/index.scss"; |
|||
@import url('@/plugin/emoji-awesome/css/apple.css'); |
|||
/*每个页面公共css */ |
|||
</style> |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"version" : "1", |
|||
"prompt" : "template", |
|||
"title" : "用户协议和隐私政策", |
|||
"message" : " 请你务必审慎阅读、充分理解“用户协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https://b2b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=0\">《用户协议》</a>和<a href=\"https://b2b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=1\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", |
|||
"buttonAccept" : "同意并接受", |
|||
"buttonRefuse" : "暂不同意", |
|||
"hrefLoader" : "system|default", |
|||
"second" : { |
|||
"title" : "确认提示", |
|||
"message" : " 进入应用前,你需先同意<a href=\"https://b2b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=0\" >《用户协议》</a>和<a href=\"https://b2b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=1\">《隐私政策》</a>,否则将退出应用。", |
|||
"buttonAccept" : "同意并继续", |
|||
"buttonRefuse" : "退出应用" |
|||
}, |
|||
"styles" : { |
|||
"backgroundColor" : "#ffffff", |
|||
"borderRadius" : "5px", |
|||
"title" : { |
|||
"color" : "#FF2C3C" |
|||
}, |
|||
"buttonAccept" : { |
|||
"color" : "#FF2C3C" |
|||
}, |
|||
"buttonRefuse" : { |
|||
"color" : "#545454" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,183 @@ |
|||
import request from '@/utils/request' |
|||
import {client} from '@/utils/tools' |
|||
|
|||
|
|||
//领券中心
|
|||
export function getCouponList(params) { |
|||
return request.get("coupon/getCouponList", {params}); |
|||
} |
|||
|
|||
//用户领取优惠券
|
|||
export function getCoupon(id) { |
|||
return request.post('coupon/getCoupon', {coupon_id:id}) |
|||
} |
|||
|
|||
|
|||
// 下单优惠券
|
|||
export function getOrderCoupon(data) { |
|||
return request.post("coupon/getBuyCouponList", data); |
|||
} |
|||
|
|||
|
|||
//我的优惠券
|
|||
export function getMyCoupon(params) { |
|||
return request.get('coupon/myCouponList', { |
|||
params |
|||
}) |
|||
} |
|||
|
|||
// 获取活动专区商品列表
|
|||
export function getActivityGoodsLists(data) { |
|||
return request.get("activity_area/activityGoodsList", {params: data}) |
|||
} |
|||
|
|||
|
|||
// 获取秒杀时间段
|
|||
export function getSeckillTime() { |
|||
return request.get("seckill_goods/getSeckillTime"); |
|||
} |
|||
|
|||
// 获取秒杀商品
|
|||
export function getSeckillGoods(params) { |
|||
return request.get("seckill_goods/getSeckillGoods", {params}) |
|||
} |
|||
|
|||
// 拼团列表
|
|||
export function getGroupList(params) { |
|||
return request.get('team/activity', {params}); |
|||
} |
|||
|
|||
//拼团记录
|
|||
export function getUserGroup(params) { |
|||
return request.get('team/record', {params}); |
|||
} |
|||
|
|||
//拼团详情
|
|||
export function getTeamInfo(params) { |
|||
return request.get('team/teamInfo', {params}); |
|||
} |
|||
|
|||
//开团|结算
|
|||
export function teamKaiTuan(data) { |
|||
return request.post('team/kaituan', data); |
|||
} |
|||
|
|||
//参与拼团验证
|
|||
export function teamCheck(data) { |
|||
return request.post('team/check', data); |
|||
} |
|||
|
|||
//拼团下单
|
|||
export function teamBuy(data) { |
|||
return request.post("team/buy",data); |
|||
} |
|||
|
|||
// 获取砍价列表
|
|||
export function getBargainList(data) { |
|||
return request.get('bargain/lists', {params: data}) |
|||
} |
|||
|
|||
// 获取砍价详情
|
|||
export function getBargainDetail(data) { |
|||
return request.get('bargain/detail', {params: data}) |
|||
} |
|||
|
|||
// 获取砍价成功人数
|
|||
export function getBargainNumber() { |
|||
return request.get("bargain/barginNumber") |
|||
} |
|||
|
|||
// 发起砍价
|
|||
export function launchBargain(data) { |
|||
return request.post('bargain/sponsor', data) |
|||
} |
|||
|
|||
// 获取砍价活动商品列表
|
|||
export function getBargainActivityList(data) { |
|||
return request.get('bargain/orderList', {params: data}) |
|||
} |
|||
|
|||
// 砍价详情
|
|||
export function getBargainActivityDetail(data) { |
|||
return request.get("bargain/bargainDetail", {params: data}) |
|||
} |
|||
|
|||
// 砍价海报
|
|||
export function getBargainPost(data) { |
|||
return request.get("share/shareBargain", {params: data}) |
|||
} |
|||
|
|||
// 好友助力
|
|||
export function helpBargain(data) { |
|||
return request.post('bargain/knife', data) |
|||
} |
|||
|
|||
// 关闭结算订单
|
|||
export function closeBargainOrder(data) { |
|||
return request.get("bargain/closeBargain", {params: data}) |
|||
} |
|||
|
|||
|
|||
// 获取签到列表
|
|||
export function getSignLists() { |
|||
return request.get("sign/lists") |
|||
} |
|||
|
|||
// 获取签到列表
|
|||
export function getSignRule() { |
|||
return request.get("sign/rule") |
|||
} |
|||
|
|||
// 签到
|
|||
export function userSignIn() { |
|||
return request.get("sign/sign") |
|||
} |
|||
|
|||
// 积分商城
|
|||
export function getIntegralGoods(params) { |
|||
return request.get("integral_goods/lists", { params }) |
|||
} |
|||
|
|||
// 积分商品详情
|
|||
export function getIntegralGoodsDetail(params) { |
|||
return request.get("integral_goods/detail", { params }) |
|||
} |
|||
|
|||
// 积分兑换订单结算
|
|||
export function integralSettlement(params) { |
|||
return request.get("integral_order/settlement", { params }) |
|||
} |
|||
|
|||
// 积分兑换提交订单
|
|||
export function integralSubmitOrder(params) { |
|||
return request.post("integral_order/submitOrder", params) |
|||
} |
|||
|
|||
// 积分兑换订单列表
|
|||
export function getIntegralOrder(params) { |
|||
return request.get("integral_order/lists", {params}) |
|||
} |
|||
|
|||
//删除积分兑换订单
|
|||
export function delIntegralOrder(id) { |
|||
return request.post('integral_order/del', {id}) |
|||
} |
|||
|
|||
//积分兑换订单订单详情
|
|||
export function getIntegralOrderDetail(id) { |
|||
return request.get('integral_order/detail', {params: {id}}) |
|||
} |
|||
|
|||
//取消积分兑换订单
|
|||
export function cancelIntegralOrder(id) { |
|||
return request.post('integral_order/cancel', {id}) |
|||
} |
|||
|
|||
//确认收货积分兑换订单
|
|||
export function confirmIntegralOrder(id) { |
|||
return request.post("integral_order/confirm", {id}) |
|||
} |
|||
// 查看物流
|
|||
export function getIntegralOrderTraces(id) { |
|||
return request.get("integral_order/orderTraces", {params: {id}}) |
|||
} |
|||
@ -0,0 +1,139 @@ |
|||
import request from '@/utils/request' |
|||
import wechath5 from '@/utils/wechath5' |
|||
import {client} from '@/utils/tools' |
|||
|
|||
//小程序授权登录
|
|||
export function authLogin(data) { |
|||
return request.post('account/authLogin', data); |
|||
} |
|||
//小程序静默登录
|
|||
export function silentLogin(data) { |
|||
return request.post('account/silentLogin', data); |
|||
} |
|||
//更新小程序头像昵称
|
|||
export function updateUser(data, token) { |
|||
return request.post('account/updateUser', data, {header: {token}}); |
|||
} |
|||
|
|||
// app登录
|
|||
export function opLogin(data) { |
|||
return request.post('account/uinAppLogin', {...data, client}); |
|||
} |
|||
|
|||
//预支付接口
|
|||
export function prepay(data) { |
|||
return request.post('pay/unifiedpay', {...data,}); |
|||
} |
|||
|
|||
//小程序订阅
|
|||
export function getMnpNotice(data) { |
|||
return request.get("subscribe/lists", { |
|||
params: data |
|||
}); |
|||
} |
|||
|
|||
//账号登录
|
|||
export function accountLogin(data) { |
|||
return request.post("account/login", {...data, client}) |
|||
} |
|||
|
|||
|
|||
|
|||
// 登录
|
|||
export function wechatLogin(data) { |
|||
return request.post('account/oalogin', data) |
|||
} |
|||
|
|||
// 向微信请求code的链接
|
|||
export function getCodeUrl() { |
|||
return request.get('account/codeurl', { |
|||
params:{ |
|||
url: encodeURIComponent(location.href) |
|||
} |
|||
}); |
|||
} |
|||
|
|||
|
|||
|
|||
//微信sdk配置
|
|||
export function getJsconfig() { |
|||
return request.get('wechat/jsconfig', { |
|||
|
|||
params: { |
|||
url: encodeURIComponent(wechath5.signLink()) |
|||
} |
|||
}); |
|||
} |
|||
|
|||
// 忘记密码
|
|||
export function forgetPwd(data) { |
|||
return request.post('login_password/forget', {...data, client}) |
|||
} |
|||
|
|||
// 发送短信
|
|||
export function sendSms(data) { |
|||
return request.post('sms/send', {...data, client}) |
|||
} |
|||
|
|||
// Html5 注册账号
|
|||
export function register(data) { |
|||
return request.post('account/register', {...data, client}) |
|||
} |
|||
|
|||
// 获取服务协议
|
|||
export function getServerProto() { |
|||
return request.get("policy/service") |
|||
} |
|||
|
|||
// 获取隐私政策
|
|||
export function getPrivatePolicy() { |
|||
return request.get("policy/privacy") |
|||
} |
|||
|
|||
// 获取售后保障
|
|||
export function getAfterSaleGuar() { |
|||
return request.get("policy/afterSale") |
|||
} |
|||
|
|||
//客服
|
|||
export function getService() { |
|||
return request.get("setting/getPlatformCustomerService") |
|||
} |
|||
|
|||
|
|||
//客服配置
|
|||
export function getChatConfig(params) { |
|||
return request.get("index/chatConfig", { params }) |
|||
} |
|||
|
|||
|
|||
// 足迹气泡
|
|||
export function getBubbleLists() { |
|||
return request.get("footprint/lists") |
|||
} |
|||
|
|||
|
|||
|
|||
// 验证码登录
|
|||
export function smsCodeLogin(data) { |
|||
return request.post('account/smsLogin', {...data, client}) |
|||
} |
|||
export function getConfig() { |
|||
return request.get("index/config") |
|||
} |
|||
|
|||
|
|||
// 注册赠送优惠券
|
|||
export function getRegisterCoupon() { |
|||
return request.get('coupon/registerSendCoupon') |
|||
} |
|||
|
|||
// 获取支付配置
|
|||
export function getPayway(params) { |
|||
return request.get('order/getPayWay', { params }) |
|||
} |
|||
|
|||
// 小程序码
|
|||
export function apiMnpQrCode(params) { |
|||
return request.get('share/getMnQrcode', { params }) |
|||
} |
|||
@ -0,0 +1,131 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 关联商品
|
|||
export function getCommunityGoods(params) { |
|||
return request.get("community/goods", {params}) |
|||
} |
|||
|
|||
// 关联店铺
|
|||
export function getCommunityShop(params) { |
|||
return request.get("community/shop", {params}) |
|||
} |
|||
|
|||
// 推荐话题
|
|||
export function getCommunityRecommendTopic() { |
|||
return request.get("community/recommendTopic") |
|||
} |
|||
|
|||
// 话题列表
|
|||
export function getCommunityTopicLists(params) { |
|||
return request.get("community/topicLists", {params}) |
|||
} |
|||
|
|||
// 发布文章
|
|||
export function apiCommunityAdd(params) { |
|||
return request.post("community/addArticle", params) |
|||
} |
|||
|
|||
// 编辑文章
|
|||
export function apiCommunityEdit(params) { |
|||
return request.post("community/editArticle", params) |
|||
} |
|||
|
|||
// 个人中心
|
|||
export function getCommunityUserCenter(params) { |
|||
return request.get("community_user/center", {params}) |
|||
} |
|||
|
|||
// 分类
|
|||
export function getCommunityCate() { |
|||
return request.get("community/cate") |
|||
} |
|||
|
|||
// 发现页文章列表
|
|||
export function getCommunityArticleLists(params) { |
|||
return request.get("community/articleLists", {params}) |
|||
} |
|||
|
|||
// 关注/取消
|
|||
export function apiCommunityFollow(params) { |
|||
return request.post("community/follow", params) |
|||
} |
|||
|
|||
// 获取设置
|
|||
export function getCommunitySetting() { |
|||
return request.get("community_user/getSetting") |
|||
} |
|||
|
|||
// 提交设置
|
|||
export function apiCommunitySetSetting(params) { |
|||
return request.post("community_user/setSetting", params) |
|||
} |
|||
|
|||
// 关注页-数据
|
|||
export function getCommunityFollow(params) { |
|||
return request.get("community/followArticle", { params }) |
|||
} |
|||
|
|||
// 个人页-作品列表
|
|||
export function getCommunityWorksLists(params) { |
|||
return request.get("community/worksLists", { params }) |
|||
} |
|||
|
|||
// 个人页-点赞列表
|
|||
export function getCommunityLikeLists(params) { |
|||
return request.get("community/likeLists", { params }) |
|||
} |
|||
|
|||
// 相关话题
|
|||
export function getCommunityTopicArticle(params) { |
|||
return request.get("community/topicArticle", { params }) |
|||
} |
|||
|
|||
// 文章详情
|
|||
export function getCommunityDetail(params) { |
|||
return request.get("community/detail", { params }) |
|||
} |
|||
|
|||
// 文章中的关联商品
|
|||
export function getCommunityGoodsLists(params) { |
|||
return request.get("community/relationGoods", { params }) |
|||
} |
|||
|
|||
// 文章中的关联店铺
|
|||
export function getCommunityShopLists(params) { |
|||
return request.get("community/relationShop", { params }) |
|||
} |
|||
|
|||
// 删除文章
|
|||
export function apiCommunityDel(params) { |
|||
return request.post("community/delArticle", params) |
|||
} |
|||
|
|||
// 添加评论
|
|||
export function apiCommunityCommentAdd(params) { |
|||
return request.post("community_comment/add", params) |
|||
} |
|||
|
|||
// 文章评论
|
|||
export function getCommunityCommentLists(params) { |
|||
return request.get("community_comment/lists", { params }) |
|||
} |
|||
|
|||
// 文章子级评论
|
|||
export function getCommunityCommentChildLists(params) { |
|||
return request.get("community_comment/commentChild", { params }) |
|||
} |
|||
|
|||
// 点赞 | 取消 | 作品点赞 | 评论点赞
|
|||
export function apiCommunityCommentLike(params) { |
|||
return request.post("community/giveLike", params) |
|||
} |
|||
|
|||
// 搜索记录
|
|||
export function getCommunitySearchHistory() { |
|||
return request.get("community_search/lists") |
|||
} |
|||
|
|||
// 清空搜索记录
|
|||
export function apiCommunityClearSearchHistory() { |
|||
return request.post("community_search/clear") |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 直播间列表
|
|||
export function getLiveLists(params) { |
|||
return request.get("live/lists", {params}) |
|||
} |
|||
// 店铺直播间列表
|
|||
export function getShopLive(params) { |
|||
return request.get("live/shopLive", {params}) |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
import {client} from '@/utils/tools' |
|||
|
|||
//订单结算页
|
|||
export function orderInfo(data) { |
|||
return request.post("order/settlement", data); |
|||
} |
|||
// 下单
|
|||
export function orderBuy(data) { |
|||
return request.post("order/submitOrder", data); |
|||
} |
|||
//删除订单
|
|||
export function delOrder(id) { |
|||
return request.post('order/del', {id}) |
|||
} |
|||
//订单列表
|
|||
export function getOrderList(data) { |
|||
return request.get('order/lists', {params: data}) |
|||
} |
|||
//订单详情
|
|||
export function getOrderDetail(id) { |
|||
return request.get('order/getOrderDetail', {params: {id}}) |
|||
} |
|||
|
|||
//取消订单
|
|||
export function cancelOrder(id) { |
|||
return request.post('order/cancel', {id}) |
|||
} |
|||
|
|||
//物流
|
|||
export function orderTraces(id) { |
|||
return request.get("order/orderTraces", {params: {id}}) |
|||
} |
|||
|
|||
//确认收货
|
|||
export function confirmOrder(id) { |
|||
return request.post("order/confirm", {id}) |
|||
} |
|||
|
|||
|
|||
|
|||
// 支付结果
|
|||
export function getPayResult(params) { |
|||
return request.get("order/pay_result", { params }); |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
import request from '@/utils/request' |
|||
import {client} from '@/utils/tools' |
|||
|
|||
|
|||
|
|||
|
|||
//获取店铺列表
|
|||
export function getShopList(params) { |
|||
return request.get('shop/getShopList', {params}) |
|||
} |
|||
|
|||
//获取附近店铺列表
|
|||
export function getNearbyShops(params) { |
|||
return request.get('shop/getNearbyShops', {params}) |
|||
} |
|||
|
|||
|
|||
//获取主营类目列表
|
|||
export function getShopCategory() { |
|||
return request.get('shop_category/getList') |
|||
} |
|||
|
|||
|
|||
//获取店铺信息
|
|||
export function getShopInfo(params) { |
|||
return request.get('shop/getShopInfo', {params}) |
|||
} |
|||
|
|||
|
|||
//获取店铺商品分类
|
|||
|
|||
export function getShopGoodsCategory(params) { |
|||
return request.get('shop_goods_category/getShopGoodsCategory', {params}) |
|||
} |
|||
|
|||
//店铺关注/取消关注
|
|||
export function changeShopFollow(data) { |
|||
return request.post('shop_follow/changeStatus', data) |
|||
} |
|||
|
|||
|
|||
// 商家入驻
|
|||
export function shopApply(data) { |
|||
return request.post('ShopApply/apply', data) |
|||
} |
|||
|
|||
|
|||
// 申请记录
|
|||
export function shopApplyRecord(params) { |
|||
return request.get('ShopApply/record', {params}) |
|||
} |
|||
|
|||
// 申请记录详情
|
|||
export function shopApplyDetail(id) { |
|||
return request.get('ShopApply/detail', {params:{id}}) |
|||
} |
|||
|
|||
|
|||
// 入住协议
|
|||
export function getTreaty() { |
|||
return request.get('ShopApply/getTreaty') |
|||
} |
|||
|
|||
//客服
|
|||
export function getShopService(id) { |
|||
return request.get("setting/getShopCustomerService", {params:{shop_id: id}}) |
|||
} |
|||
|
|||
// 商家发票设置
|
|||
export function getInvoiceSetting(params) { |
|||
return request.get("order_invoice/setting", { params }) |
|||
} |
|||
|
|||
// 发票提交
|
|||
export function apiInvoiceAdd(params) { |
|||
return request.post("order_invoice/add", params) |
|||
} |
|||
|
|||
// 发票编辑
|
|||
export function apiInvoiceEdit(params) { |
|||
return request.post("order_invoice/edit", params) |
|||
} |
|||
|
|||
// 发票详情
|
|||
export function apiInvoiceDetail(params) { |
|||
return request.get("order_invoice/detail", { params }) |
|||
} |
|||
|
|||
// 订单发票详情
|
|||
export function apiOrderInvoiceDetail(params) { |
|||
return request.get("order/invoice", { params }) |
|||
} |
|||
@ -0,0 +1,223 @@ |
|||
import request from '@/utils/request' |
|||
import {client} from '@/utils/tools' |
|||
|
|||
|
|||
|
|||
|
|||
//获取首页数据接口
|
|||
export function getHome(params) { |
|||
return request.get('index/index', { params }) |
|||
} |
|||
|
|||
// 通过首页分类id获取数据
|
|||
export function getIndexCategory(params) { |
|||
return request.get('index/indexCategory', {params}) |
|||
} |
|||
//获取菜单
|
|||
export function getMenu(data) { |
|||
return request.get('menu/lists', { |
|||
params: data, |
|||
}); |
|||
} |
|||
|
|||
//商品栏目
|
|||
export function getGoodsColumn() { |
|||
return request.get('goods_column/getGoodsColumnList'); |
|||
} |
|||
|
|||
//栏目商品
|
|||
export function getGoodsListColumn(params) { |
|||
return request.get('goods/getGoodsListByColumnId', {params}); |
|||
} |
|||
|
|||
//平台一级分类
|
|||
export function getLevelOneList() { |
|||
return request.get('goods_category/getLevelOneList'); |
|||
} |
|||
|
|||
// 一级分类的后代分类
|
|||
export function getListByLevelOne(params) { |
|||
return request.get('goods_category/getListByLevelOne', {params}); |
|||
} |
|||
|
|||
|
|||
//品牌列表
|
|||
export function getBrandList() { |
|||
return request.get('goods_brand/getGoodsBrandList'); |
|||
} |
|||
|
|||
//文章分类
|
|||
export function getCategoryList(data) { |
|||
let {type} = data |
|||
let url = type ? 'help/category' : 'article/category' |
|||
delete data.type |
|||
return request.get(url) |
|||
} |
|||
|
|||
//文章列表
|
|||
export function getArticleList(data) { |
|||
let {type} = data |
|||
let url = type ? 'help/lists' : 'article/lists' |
|||
delete data.type |
|||
return request.get(url, { |
|||
params: data |
|||
}) |
|||
} |
|||
|
|||
// 文章详情
|
|||
export function getArticleDetail(data) { |
|||
let {type} = data |
|||
let url = type ? 'help/detail' : 'article/detail' |
|||
delete data.type |
|||
return request.get(url, { |
|||
params: { id: data.id } |
|||
}) |
|||
} |
|||
|
|||
//购物车
|
|||
export function getCartList() { |
|||
return request.get('cart/lists') |
|||
} |
|||
|
|||
//商品详情
|
|||
export function getGoodsDetail(data) { |
|||
return request.get('goods/getGoodsDetail', { |
|||
params: data |
|||
}); |
|||
} |
|||
|
|||
|
|||
//加入购物车
|
|||
|
|||
export function addCart(data) { |
|||
return request.post('cart/add', data); |
|||
} |
|||
|
|||
//购物车数量
|
|||
|
|||
export function getCartNum(params) { |
|||
return request.get("cart/num", {params}); |
|||
} |
|||
|
|||
|
|||
// 购物车数量更改
|
|||
export function changeGoodsCount(data) { |
|||
return request.post("cart/change", data) |
|||
} |
|||
|
|||
// 单选/全选/店铺选择
|
|||
export function selectedOpt(data) { |
|||
return request.post("cart/selected", data) |
|||
} |
|||
|
|||
// 删除商品
|
|||
export function deleteGoods(data) { |
|||
return request.post("cart/del", data); |
|||
} |
|||
|
|||
//购物车选中状态
|
|||
export function changeCartSelect(data) { |
|||
return request.post('cart/selected', data) |
|||
} |
|||
|
|||
//广告位
|
|||
export function getAdList(data) { |
|||
return request.get('ad_content/lists', { |
|||
params: data |
|||
}); |
|||
} |
|||
|
|||
|
|||
// 商品分类
|
|||
export function getCatrgory() { |
|||
return request.get('goods_category/lists'); |
|||
} |
|||
|
|||
|
|||
// 商品搜索
|
|||
|
|||
export function getGoodsList(data) { |
|||
return request.get('goods/getGoodsList', { |
|||
params: data |
|||
}); |
|||
} |
|||
|
|||
//评价列表
|
|||
export function getCommentList(data) { |
|||
return request.get("goods_comment/lists", { |
|||
params: data |
|||
}) |
|||
} |
|||
|
|||
//评价分类
|
|||
export function getCommentCategory(id) { |
|||
return request.get("goods_comment/category", { |
|||
params: { |
|||
goods_id: id |
|||
} |
|||
}) |
|||
} |
|||
|
|||
//搜索页,热门搜索列表,和历史搜索列表
|
|||
export function getSearchpage() { |
|||
return request.get('search_record/lists'); |
|||
} |
|||
|
|||
// 清空历史搜索
|
|||
export function clearSearch() { |
|||
return request.post('search_record/clear'); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
//商品海报
|
|||
|
|||
export function getPoster(data) { |
|||
return request.get("share/sharegoods", { |
|||
params: data |
|||
}); |
|||
} |
|||
|
|||
// 消息中心首页
|
|||
export function getMessageLists() { |
|||
return request.get("notice/index") |
|||
} |
|||
|
|||
// 消息通知
|
|||
export function getNoticeLists(params) { |
|||
return request.get("notice/lists", {params}) |
|||
} |
|||
|
|||
// 城市列表
|
|||
export function getCityLists() { |
|||
return request.get("index/city") |
|||
} |
|||
|
|||
// 逆解析定位地址
|
|||
export function getGeocoder(params) { |
|||
return request.get("index/geocoder", {params}) |
|||
} |
|||
|
|||
|
|||
//资料分类
|
|||
export function getResourceCategoryList() { |
|||
let url = 'resource/category' |
|||
return request.get(url) |
|||
} |
|||
|
|||
//资料列表
|
|||
export function getResourceList(data) { |
|||
let url = 'resource/lists' |
|||
return request.get(url, { |
|||
params: data |
|||
}) |
|||
} |
|||
|
|||
// 资料详情
|
|||
export function getResourceDetail(data) { |
|||
let url = 'resource/detail' |
|||
return request.get(url, { |
|||
params: { id: data.id } |
|||
}) |
|||
} |
|||
@ -0,0 +1,332 @@ |
|||
import request from '../utils/request' |
|||
import {client} from '@/utils/tools' |
|||
//个人中心
|
|||
export function getUser() { |
|||
return request.get('user/center') |
|||
} |
|||
|
|||
|
|||
// 地址列表
|
|||
export function getAddressLists() { |
|||
return request.get('user_address/lists') |
|||
} |
|||
// 商品的增添取消收藏
|
|||
export function collectGoods(data) { |
|||
return request.post('goods_collect/changeStatus', data) |
|||
} |
|||
|
|||
// 添加编辑地址
|
|||
export function editAddress(data) { |
|||
return request.post('user_address/update', data) |
|||
} |
|||
|
|||
export function addAddress(data) { |
|||
return request.post('user_address/add', data) |
|||
} |
|||
|
|||
// 删除地址
|
|||
export function delAddress(id) { |
|||
return request.post('user_address/del', {id}) |
|||
} |
|||
|
|||
// 获取单个地址
|
|||
export function getOneAddress(id) { |
|||
return request.get('user_address/detail', {params: {id}}) |
|||
} |
|||
|
|||
// 获取默认地址
|
|||
export function getDefaultAddress(id) { |
|||
return request.get('user_address/getDefault', {params: {id}}) |
|||
} |
|||
|
|||
// 设置默认地址
|
|||
export function setDefaultAddress(id) { |
|||
return request.post('user_address/setDefault', {id}) |
|||
} |
|||
|
|||
//传省市区字符串判读是否有code
|
|||
export function hasRegionCode(data) { |
|||
return request.post('user_address/handleRegion', data) |
|||
} |
|||
|
|||
// 获取评价信息
|
|||
export function getCommentInfo(params) { |
|||
return request.get("goods_comment/getCommentPage", {params}); |
|||
} |
|||
|
|||
// 未评价列表
|
|||
export function getUnComment(params) { |
|||
return request.get("goods_comment/getUnCommentOrder", {params}); |
|||
} |
|||
|
|||
// 校验商品
|
|||
export function apiCheckGoods(params) { |
|||
return request.get("goods_comment/checkGoods", {params}); |
|||
} |
|||
|
|||
// 已评价列表
|
|||
export function getComment(params) { |
|||
return request.get("goods_comment/getCommentOrder", {params}); |
|||
} |
|||
|
|||
|
|||
//商品评价
|
|||
export function goodsComment(data) { |
|||
return request.post("goods_comment/addGoodsComment", data) |
|||
} |
|||
|
|||
// 获取抽奖配置
|
|||
export function getPrize(data) { |
|||
return request.get("Luckdraw/prize", data) |
|||
} |
|||
|
|||
// 抽奖记录
|
|||
export function getUserRecord(data) { |
|||
return request.get("Luckdraw/record", data) |
|||
} |
|||
|
|||
// 获取个人详情
|
|||
export function getUserInfo() { |
|||
return request.get('user/info') |
|||
} |
|||
|
|||
// 获取资质信息
|
|||
export function getCopyright(data) { |
|||
return request.get('index/copyright', {data}) |
|||
} |
|||
|
|||
// 设置个人信息
|
|||
export function setUserInfo(data) { |
|||
return request.post('user/setInfo', data) |
|||
} |
|||
|
|||
// 获取手机号
|
|||
export function getWxMnpMobile(data) { |
|||
return request.post('user/getMobile',data); |
|||
} |
|||
|
|||
|
|||
//更新微信信息
|
|||
|
|||
export function setWechatInfo(data) { |
|||
return request.post('user/setWechatInfo', data) |
|||
} |
|||
|
|||
|
|||
// 更换手机号
|
|||
export function changeUserMobile(data) { |
|||
return request.post("user/changeMobile", {...data, client}) |
|||
} |
|||
//会员中心
|
|||
export function getLevelList() { |
|||
return request.get('user/getUserLevelInfo'); |
|||
} |
|||
|
|||
// 用户钱包
|
|||
export function getWallet() { |
|||
return request.get("user/myWallet") |
|||
} |
|||
// 账户流水
|
|||
|
|||
export function getAccountLog(params) { |
|||
return request.get("user/accountLog", {params}) |
|||
} |
|||
|
|||
// 充值模板
|
|||
export function rechargeTemplate() { |
|||
return request.get("recharge/rechargeTemplate"); |
|||
} |
|||
|
|||
//充值
|
|||
export function recharge(data) { |
|||
return request.post("recharge/recharge", data) |
|||
} |
|||
|
|||
//充值记录
|
|||
export function getRechargeRecord(params) { |
|||
return request.post("recharge/rechargeRecord", {params}) |
|||
} |
|||
|
|||
|
|||
// 填写邀请码(绑定上级)
|
|||
export function bindSuperior(data) { |
|||
return request.post("distribution/code", data) |
|||
} |
|||
|
|||
// 分销会员申请
|
|||
export function applyDistribute(data) { |
|||
return request.post("distribution/apply", data) |
|||
} |
|||
|
|||
// 分销入口验证
|
|||
export function veryfiyDistribute() { |
|||
return request.post('distribution/check') |
|||
} |
|||
|
|||
// 最新分销会员申请详情
|
|||
export function applyDetail() { |
|||
return request.post("distribution/applydetail") |
|||
} |
|||
|
|||
// 邀请人信息
|
|||
export function getSuperiorInfo() { |
|||
return request.get("distribution/myLeader") |
|||
} |
|||
// 分销主页
|
|||
export function getDistribution() { |
|||
return request.get("distribution/index") |
|||
} |
|||
|
|||
// 分销订单列表
|
|||
export function getDistributionOrder(params) { |
|||
return request.get("distribution/order", {params}) |
|||
} |
|||
// 我的粉丝
|
|||
export function getUserFans(data) { |
|||
return request.get("user/fans", {params: data}) |
|||
} |
|||
|
|||
// 佣金明细
|
|||
export function getCommission(params) { |
|||
return request.get("distribution/commission", {params}) |
|||
} |
|||
|
|||
// 月度账单
|
|||
export function getMonthBill(params) { |
|||
return request.get("distribution/monthbill", {params}) |
|||
} |
|||
|
|||
|
|||
// 月度账单明细
|
|||
export function getMonthOrderDetail(params) { |
|||
return request.get("distribution/monthDetail", {params}) |
|||
} |
|||
|
|||
|
|||
// 获取商品的收藏列表
|
|||
export function getCollectGoods(params) { |
|||
return request.get('goods_collect/lists', {params}) |
|||
} |
|||
|
|||
// 获取店铺的收藏列表
|
|||
export function getCollectShop(params) { |
|||
return request.get('shop_follow/lists', {params}) |
|||
} |
|||
|
|||
|
|||
|
|||
// 获取售后列表
|
|||
export function getAfterSaleList(params) { |
|||
return request.get("after_sale/lists", {params}); |
|||
} |
|||
|
|||
// 申请售后
|
|||
export function applyAfterSale(data) { |
|||
return request.post("after_sale/add", data) |
|||
} |
|||
|
|||
// 获取商品信息
|
|||
export function getGoodsInfo(params) { |
|||
return request.get("after_sale/goodsInfo", {params}) |
|||
} |
|||
|
|||
// 填写快递信息
|
|||
export function inputExpressInfo(data) { |
|||
return request.post("after_sale/express", data) |
|||
} |
|||
|
|||
// 撤销申请
|
|||
export function cancelApply(data) { |
|||
return request.post("after_sale/cancel", data) |
|||
} |
|||
|
|||
// 售后详情
|
|||
export function afterSaleDetail(params) { |
|||
return request.get("after_sale/detail", {params}) |
|||
} |
|||
|
|||
// 重新申请
|
|||
export function applyAgain(data) { |
|||
return request.post("after_sale/again", data) |
|||
} |
|||
|
|||
// 佣金提现
|
|||
export function applyWithdraw(data) { |
|||
return request.post("withdraw/apply", data); |
|||
} |
|||
|
|||
// 提现记录列表
|
|||
export function getWithdrawRecords(params) { |
|||
return request.get("withdraw/records", {params}) |
|||
} |
|||
|
|||
// 提现详情
|
|||
export function getWithdrawDetail(params) { |
|||
return request.get("withdraw/info", {params}) |
|||
} |
|||
|
|||
// 提现页信息
|
|||
export function getWithdrawConfig() { |
|||
return request.get("withdraw/config") |
|||
} |
|||
|
|||
|
|||
// 邀请海报
|
|||
export function getUserPoster(data) { |
|||
return request.get("share/userPoster", {params: data}) |
|||
} |
|||
|
|||
// 退出登录
|
|||
export function userLogout(data) { |
|||
return request.post('account/logout', data) |
|||
} |
|||
|
|||
|
|||
// 海报背景
|
|||
export function apiDistributionPoster(data) { |
|||
return request.get("distribution/getPoster", {params: data}) |
|||
} |
|||
|
|||
// 聊天记录
|
|||
export function chatRecord(data) { |
|||
return request.get('user/chatRecord', {params: data}) |
|||
} |
|||
|
|||
|
|||
// 用户vip
|
|||
export function getUserShip(data) { |
|||
return request.get('user/userShip', {params: data}) |
|||
} |
|||
|
|||
// 用户vip
|
|||
export function getUserRight(data) { |
|||
return request.get('user/userRight', {params: data}) |
|||
} |
|||
|
|||
// 用户vip时间
|
|||
export function getUserVipTime(data) { |
|||
return request.get('user/userVipTime', {params: data}) |
|||
} |
|||
|
|||
//获取投诉类型列表
|
|||
export function getComplainCategory() { |
|||
return request.get('user/getComplainCategoryList') |
|||
} |
|||
|
|||
|
|||
// 投诉驻
|
|||
export function complain(data) { |
|||
return request.post('user/complain', data) |
|||
} |
|||
|
|||
|
|||
// 投诉记录
|
|||
export function complainRecord(params) { |
|||
return request.get('user/complainRecord', {params}) |
|||
} |
|||
|
|||
// 投诉记录详情
|
|||
export function complainDetail(id) { |
|||
return request.get('user/complainDetail', {params:{id}}) |
|||
} |
|||
|
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"applinks": { |
|||
"apps": [], |
|||
"details": [ |
|||
{ |
|||
"appID": "8656MXP6VT.com.gzyx.likemall", |
|||
"paths": [ "/ulink/*"] |
|||
} |
|||
] |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
#!/bin/bash |
|||
# 文件原路径 |
|||
srcPath="./unpackage/dist/build/h5" |
|||
# 发布路径文件夹 |
|||
releasePath="../server/public/mobile" |
|||
|
|||
#删除发布目录下的mobile文件 |
|||
rm -r $releasePath |
|||
echo "已删除 ==> $releasePath 下的目录文件" |
|||
mkdir $releasePath |
|||
echo "已新建 ==> $releasePath 目录" |
|||
|
|||
# 复制打包目录内的文件到发布目录 |
|||
cp -r $srcPath/* $releasePath |
|||
echo "已复制 $srcPath/* ==> $releasePath" |
|||
|
|||
cp $releasePath/../favicon.ico $releasePath |
|||
@ -0,0 +1,118 @@ |
|||
|
|||
|
|||
<template> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" @down="downCallback"> |
|||
<view class="activity-detail"> |
|||
<view class="header" v-if="goodsList.length"> |
|||
<image class="header-bg" src="/bundle/static/activity_detail_bg.png"></image> |
|||
<view class="header-con flex-col col-center"> |
|||
<view class="title white">{{name}}</view> |
|||
<view class="desc white sm br60">{{title}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="content"> |
|||
<view class="goods-container"> |
|||
<goods-list :list="goodsList" type="activity"></goods-list> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getActivityGoodsLists |
|||
} from "@/api/activity"; |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
|
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/goods_null.png', |
|||
tip: '暂无商品', // 提示 |
|||
} |
|||
}, |
|||
goodsList: [], |
|||
name: '', |
|||
title: '' |
|||
}; |
|||
}, |
|||
onLoad: function(options) { |
|||
const { |
|||
id, |
|||
title, |
|||
name |
|||
} = this.$Route.query |
|||
this.id = id; |
|||
this.title = title |
|||
this.name = name |
|||
uni.setNavigationBarTitle({ |
|||
title: name |
|||
}); |
|||
}, |
|||
methods: { |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
getActivityGoodsLists({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
id: this.id |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.goodsList = []; |
|||
const curPageData = data.list; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.goodsList = this.goodsList.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.activity-detail { |
|||
overflow: hidden; |
|||
.header { |
|||
height: 410rpx; |
|||
width: 100%; |
|||
position: relative; |
|||
|
|||
.header-bg { |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
.header-con { |
|||
position: relative; |
|||
padding-top: 50rpx; |
|||
|
|||
.title { |
|||
font-size: 60rpx; |
|||
} |
|||
|
|||
.desc { |
|||
margin-top: 30rpx; |
|||
background-color: rgba(256, 203, 203, 0.5); |
|||
padding: 4rpx 40rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.content { |
|||
position: relative; |
|||
margin-top: -140rpx; |
|||
padding: 0 20rpx; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,209 @@ |
|||
<template> |
|||
<view class="address-edit"> |
|||
<view class="form bg-white"> |
|||
<u-field v-model="addressObj.contact" label="收货人" placeholder="请填写收货人姓名"> |
|||
</u-field> |
|||
<u-field v-model="addressObj.telephone" label="联系方式" placeholder="请填写手机号码"> |
|||
</u-field> |
|||
<view @click="showRegion = true"> |
|||
<u-field v-model="region" :disabled="true" label="所在地区" placeholder="请选择省、市、区" right-icon="arrow-right"> |
|||
</u-field> |
|||
</view> |
|||
<view> |
|||
<u-field v-model="addressObj.address" type="textarea" label="详细地址" placeholder="请填写小区、街道、门牌号等信息" |
|||
:field-style="{flex: 1, height: '200rpx'}" /> |
|||
</view> |
|||
</view> |
|||
<view class="m-t-10 m-b-10 bg-white p-20"> |
|||
<u-checkbox @click="changeDefault" v-model="addressObj.is_default" shape="circle"> |
|||
<text class="xs">设置为默认</text> |
|||
</u-checkbox> |
|||
</view> |
|||
<button class="my-btn bg-primary white br60" @tap="formSubmit">完成</button> |
|||
<u-select v-model="showRegion" mode="mutil-column-auto" @confirm="regionChange" :list="lists"></u-select> |
|||
</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 { |
|||
editAddress, |
|||
getOneAddress, |
|||
hasRegionCode, |
|||
addAddress |
|||
} from '@/api/user'; |
|||
import area from '@/utils/area' |
|||
export default { |
|||
data() { |
|||
return { |
|||
addressObj: { |
|||
contact: '', |
|||
telephone: '', |
|||
province: '', |
|||
city: '', |
|||
district: '', |
|||
address: '', |
|||
is_default: false |
|||
}, |
|||
region: '', |
|||
addressId: '', |
|||
defaultRegion: ['广东省', '广州市', '番禺区'], |
|||
defaultRegionCode: '440113', |
|||
showRegion: false, |
|||
lists: [] |
|||
}; |
|||
}, |
|||
onLoad: function(options) { |
|||
this.addressId = parseInt(options.id) |
|||
if (options.id) { |
|||
uni.setNavigationBarTitle({ |
|||
title: '编辑地址' |
|||
}); |
|||
this.getOneAddressFun(); |
|||
} else { |
|||
uni.setNavigationBarTitle({ |
|||
title: '添加地址' |
|||
}); |
|||
this.getWxAddressFun(); |
|||
} |
|||
this.$nextTick(() => { |
|||
this.lists = area |
|||
}) |
|||
}, |
|||
|
|||
onUnload: function() { |
|||
uni.removeStorageSync('wxAddress'); |
|||
}, |
|||
|
|||
methods: { |
|||
async formSubmit() { |
|||
let { |
|||
addressObj: { |
|||
contact, |
|||
telephone, |
|||
province_id, |
|||
city_id, |
|||
district_id, |
|||
is_default, |
|||
address |
|||
}, |
|||
addressId, |
|||
region, |
|||
} = this; |
|||
if (!contact) return this.$toast({ |
|||
title: '请填写收货人姓名' |
|||
}); |
|||
if (!telephone) return this.$toast({ |
|||
title: '请填写手机号码' |
|||
}); |
|||
if (!region) return this.$toast({ |
|||
title: '请选择省、市、区' |
|||
}); |
|||
if (!address) return this.$toast({ |
|||
title: '请填写小区、街道、门牌号等信息' |
|||
}); |
|||
const params = { |
|||
contact, |
|||
telephone, |
|||
province_id: parseInt(province_id), |
|||
city_id: parseInt(city_id), |
|||
district_id: parseInt(district_id), |
|||
is_default: is_default ? 1 : 0, |
|||
id: addressId, |
|||
address |
|||
} |
|||
const {code, msg} = addressId ? await editAddress(params) : await addAddress(params) |
|||
if (code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}, { |
|||
tab: 3, |
|||
url: 1 |
|||
}); |
|||
} |
|||
}, |
|||
regionChange(region) { |
|||
this.addressObj.province_id = region[0].value; |
|||
this.addressObj.city_id = region[1].value; |
|||
this.addressObj.district_id = region[2].value; |
|||
this.region = region[0].label + " " + region[1].label + " " + region[2].label |
|||
}, |
|||
|
|||
getOneAddressFun() { |
|||
getOneAddress(this.addressId).then(res => { |
|||
if (res.code == 1) { |
|||
let { |
|||
city, |
|||
province, |
|||
district |
|||
} = res.data; |
|||
this.addressObj = res.data; |
|||
this.region = `${province} ${city} ${district}` |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
getWxAddressFun() { |
|||
let wxAddress = uni.getStorageSync('wxAddress'); |
|||
if (!wxAddress) return; |
|||
wxAddress = JSON.parse(wxAddress) |
|||
let { |
|||
userName: contact, |
|||
telNumber: telephone, |
|||
provinceName: province, |
|||
cityName: city, |
|||
detailInfo: address |
|||
} = wxAddress; |
|||
let district = wxAddress.countryName || wxAddress.countyName |
|||
hasRegionCode({ |
|||
province, |
|||
city, |
|||
district |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
|
|||
if (res.data.province && res.data.city && res.data.district) { |
|||
this.region = `${province} ${city} ${district}`; |
|||
this.addressObj.province_id = res.data.province; |
|||
this.addressObj.city_id = res.data.city; |
|||
this.addressObj.district_id = res.data.district; |
|||
} |
|||
this.addressObj.contact = contact; |
|||
this.addressObj.telephone = telephone |
|||
this.addressObj.address = address |
|||
} |
|||
}); |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
|
|||
.address-edit { |
|||
padding-top: 10rpx; |
|||
|
|||
|
|||
.my-btn { |
|||
margin: 30rpx 26rpx; |
|||
text-align: center; |
|||
} |
|||
} |
|||
|
|||
</style> |
|||
@ -0,0 +1,43 @@ |
|||
<template> |
|||
<view class="post-sale"> |
|||
<view class="contain"> |
|||
<tabs :current="active" :bar-width="80" @change="onChange" :is-scroll="false"> |
|||
<tab v-for="(item, index) in afterSale" :key="index" :name="item.name"> |
|||
<after-sales-list :type="item.type" :i="index" :index="active"></after-sales-list> |
|||
</tab> |
|||
</tabs> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { afterSaleType } from "@/utils/type"; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
active: 0, |
|||
afterSale: [{ |
|||
name: '售后申请', |
|||
type: afterSaleType.NORMAL |
|||
}, { |
|||
name: '处理中', |
|||
type: afterSaleType.HANDLING |
|||
}, { |
|||
name: '已处理', |
|||
type: afterSaleType.FINISH |
|||
}] |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
onChange(index) { |
|||
this.active = index |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
|
|||
</style> |
|||
@ -0,0 +1,235 @@ |
|||
<template> |
|||
<view> |
|||
<view class="after-sales-detail"> |
|||
<view class="after-sales-header"> |
|||
<view class="after-sales-status white lg"> |
|||
{{afterSale.status_text}} |
|||
</view> |
|||
</view> |
|||
<view class="return-address-contain flex bg-white m-t-20"> |
|||
<view class="address-title">退货地址:</view> |
|||
<view class="sm address flex-1">{{afterSale.shop.address}}, {{afterSale.shop.contact}}, |
|||
{{afterSale.shop.mobile}}</view> |
|||
<view class="xs copy-btn flex-none row-center" @tap="onCopy">复制</view> |
|||
</view> |
|||
<view class="goods-container bg-white m-t-20"> |
|||
<view class="m-l-20"> |
|||
<shop-title :shop="{name: afterSale.shop_name, id: afterSale.sid}"></shop-title> |
|||
</view> |
|||
<view class="goods-item flex"> |
|||
<view class="goods-img"> |
|||
<u-image width="180rpx" height="180rpx" border-radius="10rpx" |
|||
:src="afterSale.order_goods.image"></u-image> |
|||
</view> |
|||
<view class="goods-info flex-1 m-l-24"> |
|||
<view class="line-2">{{afterSale.order_goods.goods_name}}</view> |
|||
<view class="m-t-10 xs line-1 muted">{{afterSale.order_goods.spec_value}}</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<price-format :price="afterSale.order_goods.goods_price" :first-size="30" :second-size="30" |
|||
:subscript-size="30" /> |
|||
<view>x{{afterSale.order_goods.goods_num}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="return-goods-container bg-white m-t-20"> |
|||
<view class="return-goods-item flex sm"> |
|||
<view class="return-title">退款方式:</view> |
|||
<view class="return-explain">{{afterSale.refund_type_text}}</view> |
|||
</view> |
|||
<view class="return-goods-item flex sm m-t-20"> |
|||
<view class="return-title">退款原因:</view> |
|||
<view class="return-explain">{{afterSale.refund_reason}}</view> |
|||
</view> |
|||
<view class="return-goods-item flex sm m-t-20"> |
|||
<view class="return-title">退款金额:</view> |
|||
<view class="return-explain primary">¥{{afterSale.refund_price}}</view> |
|||
</view> |
|||
<view class="return-goods-item flex sm m-t-20"> |
|||
<view class="return-title">退款编号:</view> |
|||
<view class="return-explain">{{afterSale.sn}}</view> |
|||
</view> |
|||
<view class="return-goods-item flex sm m-t-20"> |
|||
<view class="return-title">申请时间:</view> |
|||
<view class="return-explain">{{afterSale.create_time}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="btn-group fixed bg-white flex row-right" v-if="afterSale.status != 6"> |
|||
<view class="m-r-20 btn br60" @tap="confirmDialog=true">撤销申请</view> |
|||
<router-link :to="{path: '/bundle/pages/apply_refund/apply_refund', query: {after_sale_id: afterSale.id, |
|||
order_id: afterSale.order_goods.order_id, |
|||
item_id: afterSale.order_goods.item_id}}"> |
|||
<view class="m-r-20 btn br60 primary" v-if="(afterSale.status == 4 || afterSale.status == 1)">重新申请 |
|||
</view> |
|||
</router-link> |
|||
<router-link |
|||
:to="{path: '/bundle/pages/input_express_info/input_express_info', query: {id: afterSale.id}}"> |
|||
<view class="m-r-20 btn br60" v-if="afterSale.status == 2"> |
|||
填写快递单号 |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
<u-modal v-model="confirmDialog" confirm-text="确定" :showCancelButton="true" :confirm-color="colorConfig.primary" |
|||
@confirm="cancelApplyFun"> |
|||
<view class="flex-col col-center tips-dialog" style="padding: 30rpx 0;"> |
|||
<image class="icon-lg" src="/static/images/icon_warning.png"></image> |
|||
<view class="m-t-30">是否要撤销申请?</view> |
|||
</view> |
|||
</u-modal> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
afterSaleDetail, |
|||
cancelApply |
|||
} from "@/api/user"; |
|||
import { |
|||
trottle, |
|||
copy |
|||
} from "@/utils/tools.js"; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
afterSale: { |
|||
shop: {}, |
|||
order_goods: {} |
|||
}, |
|||
confirmDialog: false |
|||
}; |
|||
}, |
|||
onLoad(options) { |
|||
|
|||
}, |
|||
|
|||
onShow() { |
|||
this.id = this.$Route.query.id |
|||
this.afterSaleDetailFun(); |
|||
}, |
|||
|
|||
methods: { |
|||
onCopy() { |
|||
const { |
|||
afterSale |
|||
} = this; |
|||
const { |
|||
address, |
|||
contact, |
|||
mobile |
|||
} = afterSale.shop; |
|||
copy(`${address},${contact},${mobile}`) |
|||
}, |
|||
|
|||
|
|||
cancelApplyFun() { |
|||
cancelApply({ |
|||
id: this.id |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
|
|||
uni.$emit("refreshsale") |
|||
this.$toast({ |
|||
title: res.msg |
|||
}, { |
|||
tab: 3, |
|||
url: 1 |
|||
}); |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
afterSaleDetailFun() { |
|||
afterSaleDetail({ |
|||
id: this.id |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
this.afterSale = res.data |
|||
} |
|||
}); |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.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; |
|||
} |
|||
} |
|||
|
|||
.return-goods-container { |
|||
padding: 20rpx 24rpx 55rpx; |
|||
|
|||
.return-goods-item { |
|||
line-height: 40rpx; |
|||
} |
|||
} |
|||
|
|||
.btn-group { |
|||
padding: 0rpx 24rpx; |
|||
position: fixed; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
height: 100rpx; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
box-sizing: content-box; |
|||
.btn { |
|||
padding: 10rpx 34rpx; |
|||
border: 1px solid #999999; |
|||
|
|||
&.primary { |
|||
border-color: $-color-primary; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.goods-container { |
|||
.goods-item { |
|||
padding: 25rpx 24rpx; |
|||
.goods-info { |
|||
min-width: 500rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.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 { |
|||
background-color: #F4F4F4; |
|||
color: #555555; |
|||
padding: 3rpx 16rpx; |
|||
margin-left: 12rpx; |
|||
border-radius: 4rpx; |
|||
} |
|||
} |
|||
|
|||
.tips-dialog { |
|||
height: 230rpx; |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,200 @@ |
|||
<template> |
|||
<view> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption"> |
|||
<view class="all-comments"> |
|||
<view class="header bg-white" v-if="!isEmpty"> |
|||
<view class="title xs"> |
|||
<text class="lighter m-r-10">商品好评率</text> |
|||
<text class="primary">{{percent}}</text> |
|||
</view> |
|||
<view class="tab flex flex-wrap"> |
|||
<view v-for="(item, index) in categoryList" |
|||
:class="'tab-item xs m-r-10 br60 m-b-20 ' + (type == item.id ? 'bg-primary white' : 'bg-gray' )" |
|||
:key="index" @tap="onChangType(index)" v-show="item.count"> |
|||
{{item.name}}({{item.count}}) |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="main bg-white"> |
|||
<view class="evaluation-list"> |
|||
<view v-for="(item, index) in commentList" :key="index" class="evaluation-item"> |
|||
<view class="user-info flex"> |
|||
<image class="avatar m-r-20" :src="item.avatar"></image> |
|||
<view class="user-name md m-r-10">{{item.nickname}}</view> |
|||
<u-rate disabled size="26rpx" :color="colorConfig.primary" v-model="item.goods_comment"> |
|||
</u-rate> |
|||
</view> |
|||
<view class="muted xs m-t-10"> |
|||
<text class="m-r-20">{{item.create_time}}</text> |
|||
<text v-show="item.spec_value_str">{{item.spec_value_str}}</text> |
|||
</view> |
|||
<view v-if="item.comment" class="dec m-t-20">{{item.comment}}</view> |
|||
<view class="img m-t-20 flex flex-wrap" v-if="item.image.length"> |
|||
<view v-for="(imgitem, imgindex) in item.image" :key="imgindex" |
|||
class="img-item m-r-20 m-b-20" :data-current="imgitem" :data-uri="item.image" |
|||
@tap="previewImage"> |
|||
<u-image width="160rpx" fit="cover" height="160rpx" radius="6rpx" lazy-load |
|||
class="goods-img" :src="imgitem" /> |
|||
</view> |
|||
</view> |
|||
<view class="seller-recall-container bg-gray m-t-10" v-if="item.reply"> |
|||
<view class="lighter"> |
|||
商家回复: |
|||
<text class="normal">{{item.reply}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { |
|||
getCommentList, |
|||
getCommentCategory |
|||
} from '@/api/store'; |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"; |
|||
export default { |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
active: 0, |
|||
type: '', |
|||
commentList: [], |
|||
categoryList: [], |
|||
percent: '', |
|||
isEmpty: true, |
|||
upOption:{ |
|||
auto: false, |
|||
empty: { |
|||
icon: '/static/images/goods_null.png', |
|||
tip : "暂无评价", |
|||
} |
|||
}, |
|||
}; |
|||
}, |
|||
|
|||
onLoad(options) { |
|||
this.id = this.$Route.query.id; |
|||
}, |
|||
onShow() { |
|||
this.id = this.$Route.query.id; |
|||
}, |
|||
methods: { |
|||
async downCallback(page) { |
|||
|
|||
await this.getCommentCategoryFun() |
|||
this.mescroll.resetUpScroll(); |
|||
}, |
|||
upCallback(page) { |
|||
let pageNum = page.num; // 页码, 默认从1开始 |
|||
let pageSize = page.size; // 页长, 默认每页10条 |
|||
getCommentList({ |
|||
type: this.type, |
|||
goods_id: this.id, |
|||
page_no: pageNum, |
|||
page_size: pageSize |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
let curPageData = res.data.lists; |
|||
let curPageLen = curPageData.length; |
|||
let hasNext = !!res.data.more; |
|||
if (page.num == 1) this.commentList = []; |
|||
this.commentList = this.commentList.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
} |
|||
}) |
|||
}, |
|||
onChangType(index) { |
|||
this.active = index |
|||
this.type = this.categoryList[index].id |
|||
this.commentList = [] |
|||
this.mescroll.resetUpScroll(); |
|||
}, |
|||
|
|||
getCommentCategoryFun() { |
|||
return new Promise(resolve => { |
|||
getCommentCategory(this.id).then(res => { |
|||
let { |
|||
code, |
|||
data: { |
|||
comment, |
|||
percent |
|||
} |
|||
} = res; |
|||
if (code == 1) { |
|||
this.categoryList = comment; |
|||
this.percent = percent; |
|||
this.type = comment[this.active].id |
|||
this.isEmpty = !comment[0].count |
|||
this.$nextTick(() => resolve()); |
|||
} |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
previewImage(e) { |
|||
const { |
|||
current, |
|||
uri |
|||
} = e.currentTarget.dataset; |
|||
let urls = uri; |
|||
uni.previewImage({ |
|||
current, |
|||
// 当前显示图片的http链接 |
|||
urls // 需要预览的图片http链接列表 |
|||
|
|||
}); |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.all-comments { |
|||
padding-top: 20rpx; |
|||
|
|||
.header { |
|||
.title { |
|||
padding: 24rpx 26rpx; |
|||
border-bottom: var(--border); |
|||
} |
|||
|
|||
.tab { |
|||
padding: 30rpx 0 10rpx 20rpx; |
|||
flex-wrap: wrap; |
|||
|
|||
.tab-item { |
|||
padding: 9rpx 29rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.main { |
|||
.evaluation-list { |
|||
.evaluation-item { |
|||
padding: 20rpx; |
|||
|
|||
&:not(:last-of-type) { |
|||
border-bottom: $-solid-border; |
|||
} |
|||
|
|||
.avatar { |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
border-radius: 50%; |
|||
} |
|||
|
|||
.seller-recall-container { |
|||
padding: 24rpx 20rpx; |
|||
border-radius: 12rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,260 @@ |
|||
<template> |
|||
<view class="apply-refund"> |
|||
<view class="goods bg-white m-t-20"> |
|||
<view class="flex"> |
|||
<u-image width="160rpx" height="160rpx" border-radius="6rpx" lazy-load :src="goods.image" /> |
|||
<view class="goods-info"> |
|||
<view class="line-2">{{goods.goods_name}}</view> |
|||
<view class="xs muted m-t-10">{{goods.spec_value}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="opt-box m-t-20 bg-white"> |
|||
<view v-show="!hiddenOpt"> |
|||
<view class="opt-item flex row-between border-line" @tap="onlyRefund"> |
|||
<view> |
|||
<view class="lg">仅退款</view> |
|||
<view class="muted xs m-t-10">未收到货,与卖家协商同意无需退货只需退款</view> |
|||
</view> |
|||
<u-icon class="m-l-10" name="arrow-right" size="28" /> |
|||
</view> |
|||
<view class="opt-item flex row-between" @tap="allRefunds"> |
|||
<view> |
|||
<view class="lg">退货退款</view> |
|||
<view class="muted xs m-t-10">已收到货,需退还收到的实物</view> |
|||
</view> |
|||
<u-icon class="m-l-10" name="arrow-right" size="28" /> |
|||
</view> |
|||
</view> |
|||
<view v-show="hiddenOpt"> |
|||
<view class="refund-info flex row-between m-t-20"> |
|||
<view class="lable">数量</view> |
|||
<view>{{goods.goods_num}}</view> |
|||
</view> |
|||
<view class="refund-info flex row-between"> |
|||
<view class="lable">退款金额</view> |
|||
<price-format :color="colorConfig.primary" :price="goods.total_pay_price" /> |
|||
</view> |
|||
<view class="refund-info flex row-between" @tap="showPop=true"> |
|||
<view class="lable">退款原因</view> |
|||
<view class="flex"> |
|||
<text :class="{muted: !reasonString}">{{reasonString ? reasonString : '请选择' }}</text> |
|||
<u-icon class="m-l-10" name="arrow-right" size="28" /> |
|||
</view> |
|||
</view> |
|||
<view class="refund-info flex col-top"> |
|||
<view class="label">备注说明</view> |
|||
<view class="flex-1" style="background-color: #F8F8F8;"> |
|||
<u-input v-model="remark" type="textarea" placeholder="请描述申请售后的具体原因,100字以内" :border="false" |
|||
:height="160" /> |
|||
</view> |
|||
</view> |
|||
<view class="upload bg-white"> |
|||
<view class="title flex row-between"> |
|||
<view>上传凭证</view> |
|||
<view class="muted">(选填,最多可上传1张)</view> |
|||
</view> |
|||
<u-upload ref="uUpload" :show-progress="false" :header="{token: $store.getters.token}" |
|||
:max-count="1" width="160" height="160" :action="action" upload-text="上传图片" |
|||
@on-success="onSuccess" @on-remove="onRemove" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<button v-show="hiddenOpt" class="btn br60" type="primary" size="lg" @tap="onSubmit">申请退款</button> |
|||
|
|||
<u-select v-model="showPop" mode="single-column" value-name="index" label-name="name" :list="reason" |
|||
@confirm="confirmSelect"></u-select> |
|||
</view> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
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 { |
|||
action: baseURL + '/api/file/formimage', |
|||
hiddenOpt: false, |
|||
optTyle: refundOptType.ONLY_REFUND, |
|||
goods: {}, |
|||
reason: [], |
|||
showPop: false, |
|||
reasonString: '', |
|||
fileList: [], |
|||
remark: "" |
|||
}; |
|||
}, |
|||
onLoad(options) { |
|||
const { |
|||
order_id, |
|||
item_id, |
|||
after_sale_id |
|||
} = this.$Route.query |
|||
this.orderId = order_id; |
|||
this.itemId = item_id; |
|||
this.afterSaleId = after_sale_id; |
|||
this.getGoodsInfoFun(); |
|||
this.onSubmit = trottle(this.onSubmit, 1000, this) |
|||
}, |
|||
|
|||
methods: { |
|||
confirmSelect(e) { |
|||
this.reasonString = e[0].label |
|||
}, |
|||
|
|||
onlyRefund() { |
|||
this.optTyle = refundOptType.ONLY_REFUND |
|||
this.hiddenOpt = true |
|||
}, |
|||
|
|||
allRefunds() { |
|||
this.optTyle = refundOptType.REFUNDS; |
|||
this.hiddenOpt = true; |
|||
}, |
|||
onSuccess(e) { |
|||
this.fileList.push(e.data.base_uri) |
|||
}, |
|||
onRemove(index) { |
|||
this.fileList.splice(index, 1) |
|||
console.log(index) |
|||
}, |
|||
async onSubmit() { |
|||
const { |
|||
reason, |
|||
reasonString, |
|||
optTyle, |
|||
remark, |
|||
fileList |
|||
} = this; |
|||
if (!reasonString) { |
|||
return this.$toast({ |
|||
title: '请选择退款原因' |
|||
}); |
|||
} |
|||
const params = { |
|||
reason: reasonString, |
|||
refund_type: optTyle, |
|||
remark: remark, |
|||
img: fileList.length ? fileList[0] : '' |
|||
}; |
|||
if (this.afterSaleId) { |
|||
params.id = this.afterSaleId |
|||
} else { |
|||
params.item_id = this.itemId |
|||
params.order_id = this.orderId |
|||
} |
|||
const { |
|||
data, |
|||
code, |
|||
msg |
|||
} = this.afterSaleId ? await applyAgain(params) : await applyAfterSale(params) |
|||
if (code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}); |
|||
uni.$emit("refreshsale") |
|||
setTimeout(() => { |
|||
this.$Router.replace({ |
|||
path: '/bundle/pages/after_sales_detail/after_sales_detail', |
|||
query: { |
|||
id: data.after_sale_id |
|||
} |
|||
}) |
|||
}, 1000) |
|||
} |
|||
|
|||
}, |
|||
|
|||
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.map((item, index) => ({ |
|||
name: item, |
|||
index |
|||
})); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.apply-refund { |
|||
padding-bottom: 50rpx; |
|||
|
|||
.goods { |
|||
padding: 20rpx 24rpx; |
|||
|
|||
.goods-info { |
|||
margin-left: 24rpx; |
|||
flex: 1; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.opt-box { |
|||
.opt-item { |
|||
padding: 20rpx 20rpx 30rpx; |
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
.apply-refund { |
|||
.refund-info { |
|||
padding: 24rpx 20rpx; |
|||
border-bottom: $-solid-border; |
|||
|
|||
.label { |
|||
width: 140rpx; |
|||
margin-top: 19rpx; |
|||
} |
|||
|
|||
textarea { |
|||
flex: 1; |
|||
height: 172rpx; |
|||
border-radius: 10rpx; |
|||
padding: 20rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
} |
|||
|
|||
.upload { |
|||
padding: 0 20rpx 30rpx; |
|||
|
|||
.title { |
|||
padding: 24rpx 0; |
|||
} |
|||
} |
|||
|
|||
.btn { |
|||
margin: 30rpx 26rpx |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,77 @@ |
|||
<template> |
|||
<view class="bargain-code-container"> |
|||
<tabs :active="active" @change="onChange" :isScroll="false"> |
|||
<tab v-for="(item, index) in bargain" :key="item.type" :name="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; |
|||
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> |
|||
@ -0,0 +1,637 @@ |
|||
<template> |
|||
<view class="chat flex-col"> |
|||
<view class="content" @tap="showEmoji = false"> |
|||
<scroll-view style="height: 100%;" :scroll-y="true" :scroll-top="scrollTop" :scroll-into-view="intoView" |
|||
@scrolltoupper="scrollToupper"> |
|||
<view class="loading flex row-center" v-if="pageStatus == 'loading'"> |
|||
<u-loading mode="flower" size="40"></u-loading> |
|||
</view> |
|||
<view class="chat-lists"> |
|||
<view class="chat-item" v-for="(item,index) in recoreds" :id="`chat-item_${item.id}`" :key="item.id" |
|||
:class="{ |
|||
'right': item.from_type == 'user', |
|||
'left': item.from_type == 'kefu', |
|||
'visibility': showIndex > index |
|||
} "> |
|||
|
|||
<!-- 普通聊天记录 --> |
|||
<template v-if="item.type == 1"> |
|||
<!-- 时间 --> |
|||
<view class="text-center m-b-30 white" v-if="timeFormat(item,index)"> |
|||
<view class="chat-tips xs">{{timeFormat(item,index)}}</view> |
|||
</view> |
|||
<view class="chat-info"> |
|||
<image class="avatar" :src="$getImageUri(item.from_avatar)"> |
|||
</image> |
|||
<!-- 文本 --> |
|||
<view class="text-box" v-if="item.msg_type == 1"> |
|||
<rich-text :nodes="replaceEmoji(item.msg)" space="nbsp"></rich-text> |
|||
</view> |
|||
<!-- 图片 --> |
|||
<view class="image-box" v-if="item.msg_type == 2"> |
|||
<image class="image" mode="widthFix" :src="$getImageUri(item.msg)" |
|||
@tap="previewImage($getImageUri(item.msg))"> |
|||
</image> |
|||
</view> |
|||
<!-- 商品 --> |
|||
<view class="goods m-r-20 goods-box" v-if="item.msg_type == 3"> |
|||
<view class="goods-img m-r-20"> |
|||
<image style="width: 140rpx;height: 140rpx;" |
|||
:src="$getImageUri(item.goods.image)"> |
|||
</image> |
|||
</view> |
|||
<view class="goods-info flex-1"> |
|||
<view class="line-2"> |
|||
{{item.goods.name}} |
|||
</view> |
|||
<view class="flex m-t-10 row-between"> |
|||
<price-format :color="colorConfig.primary" :subscript-size="26" |
|||
:first-size="38" :second-size="26" :price="item.goods.min_price"> |
|||
</price-format> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
<!-- 通知类型记录 --> |
|||
<template v-else> |
|||
<view class="text-center white"> |
|||
<view class="muted xs">{{item.msg}}</view> |
|||
</view> |
|||
</template> |
|||
</view> |
|||
</view> |
|||
<view class="error" v-if="isError"> |
|||
<view class="error-msg text-center xs">{{errorMsg}}</view> |
|||
</view> |
|||
<view id="bottom"></view> |
|||
</scroll-view> |
|||
</view> |
|||
|
|||
<view class="footer" @tap="showGoods = false"> |
|||
<view class="footer-input flex"> |
|||
<view class="album" @tap="uploadFile"> |
|||
<image class="icon" src="@/static/images/icon_album.png"></image> |
|||
</view> |
|||
<view class="input-contain flex"> |
|||
<input v-model="msg" class="text-area" confirm-type="send" maxlength="-1" |
|||
@focus="scrollToBottom" @confirm="sendText" /> |
|||
<image class="icon" src="@/static/images/icon_emoji.png" @tap="handleEmojiShow"></image> |
|||
</view> |
|||
<button size="sm" class="send-btn" @tap="sendText">发送</button> |
|||
</view> |
|||
<view class="emoji-wrap" :class="{'emoji-show': showEmoji}"> |
|||
<scroll-view style="height:100%;" scroll-y="true"> |
|||
<emoji @input="handleEmojiInput"></emoji> |
|||
</scroll-view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="goods" v-if="showGoods"> |
|||
<view class="close" @tap="showGoods = false"> |
|||
<u-icon name="close-circle-fill" color="#ccc" size="40"></u-icon> |
|||
</view> |
|||
<view class="goods-img m-r-20"> |
|||
<u-image width="140rpx" height="140rpx" :src="goodsInfo.image"></u-image> |
|||
</view> |
|||
<view class="goods-info flex-1"> |
|||
<view class="line-2"> |
|||
{{goodsInfo.name}} |
|||
</view> |
|||
<view class="flex m-t-10 row-between"> |
|||
<price-format :color="colorConfig.primary" :subscript-size="26" :first-size="38" :second-size="26" |
|||
:price="goodsInfo.min_price"> |
|||
</price-format> |
|||
<view class="send-btn" @tap="sendGoods">发送链接</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import Socket from '@/utils/socket' |
|||
import { |
|||
chatRecord |
|||
} from '@/api/user' |
|||
import { |
|||
getChatConfig |
|||
} from '@/api/app' |
|||
import { |
|||
getGoodsDetail |
|||
} from '@/api/store' |
|||
import { |
|||
client, |
|||
uploadFile, |
|||
getRect, |
|||
debounce |
|||
} from '@/utils/tools' |
|||
import { |
|||
timeFormatChat |
|||
} from '@/utils/date' |
|||
import { |
|||
mapMutations |
|||
} from 'vuex'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
pageStatus: 'loading', |
|||
scrollTop: '', |
|||
intoView: '', |
|||
page: 1, |
|||
msg: '', |
|||
socket: {}, |
|||
kefu: {}, |
|||
showEmoji: false, |
|||
recoreds: [], |
|||
errorMsg: '', |
|||
goodsInfo: {}, |
|||
isError: false, |
|||
showGoods: false, |
|||
showIndex: -1 |
|||
} |
|||
}, |
|||
computed: { |
|||
// 设置记录 |
|||
timeFormat() { |
|||
return (item, index) => { |
|||
let timeFmt = timeFormatChat(item.create_time_stamp) |
|||
if (index && item.create_time_stamp - this.recoreds[index - 1].create_time_stamp < 300 && !item |
|||
.show_time) { |
|||
timeFmt = '' |
|||
} |
|||
|
|||
return timeFmt |
|||
} |
|||
}, |
|||
// 表情转换 |
|||
replaceEmoji() { |
|||
return (str) => str.replace(/\[em-([a-z_]+)\]/g, `<span class="em em-$1"></span>`) |
|||
}, |
|||
// 获取图片域名 |
|||
$getImageUri() { |
|||
return (url) => this.$store.state.app.config.base_domain + url |
|||
} |
|||
}, |
|||
watch: { |
|||
kefu(val) { |
|||
if (val.id) { |
|||
this.setTitle(val.nickname) |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
// 初始化 |
|||
init() { |
|||
this.shopId = this.$Route.query.shop_id || 0 |
|||
this.goodsId = this.$Route.query.goods_id |
|||
this.socket = new Socket(this.appConfig.ws_domain, { |
|||
token: this.$store.getters.token, |
|||
type: 'user', |
|||
client, |
|||
shop_id: this.shopId, |
|||
}) |
|||
this.socket.addEvent('connect', () => { |
|||
this.setTitle('连接中...') |
|||
}) |
|||
this.socket.addEvent('open', () => { |
|||
this.setTitle(this.kefu.nickname) |
|||
this.isError = false |
|||
}) |
|||
this.socket.addEvent('message', (data) => { |
|||
|
|||
switch (data.event) { |
|||
case 'login': |
|||
this.loginEvent(data.data) |
|||
break; |
|||
case 'chat': |
|||
this.chatEvent(data.data) |
|||
break; |
|||
case 'transfer': |
|||
this.transferEvent(data.data) |
|||
break; |
|||
case 'error': |
|||
this.errorEvent(data.data) |
|||
break; |
|||
|
|||
} |
|||
}) |
|||
this.socket.addEvent('error', (data) => { |
|||
this.setTitle('连接失败') |
|||
}) |
|||
}, |
|||
|
|||
showTips(msg) { |
|||
if (!msg) { |
|||
setTimeout(() => { |
|||
this.$Router.replace({ |
|||
path: `/bundle/pages/contact_offical/contact_offical?id=${this.shopId}` |
|||
}); |
|||
}, 200) |
|||
return |
|||
} |
|||
uni.showModal({ |
|||
title: '温馨提示', |
|||
content: msg, |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
this.$Router.replace({ |
|||
path: `/bundle/pages/contact_offical/contact_offical?id=${this.shopId}` |
|||
}); |
|||
} else if (res.cancel) { |
|||
this.$Router.back() |
|||
} |
|||
} |
|||
}); |
|||
}, |
|||
getConfig() { |
|||
return getChatConfig({ |
|||
shop_id: this.shopId |
|||
}).then(res => { |
|||
return Promise.resolve(res) |
|||
}).catch(() => { |
|||
return Promise.reject() |
|||
}) |
|||
}, |
|||
// 获取数据 |
|||
async getData() { |
|||
try { |
|||
const res = await this.getConfig() |
|||
if (res.code == 0) return this.showTips(res.msg) |
|||
await this.getChatRecord() |
|||
this.getGoods() |
|||
this.scrollToBottom() |
|||
if (!this.kefu.id) { |
|||
this.setTitle('客服不在线') |
|||
return |
|||
} |
|||
this.socket.connect() |
|||
} catch (e) { |
|||
|
|||
} |
|||
|
|||
|
|||
}, |
|||
getGoods() { |
|||
if (!this.goodsId) return |
|||
getGoodsDetail({ |
|||
goods_id: this.goodsId |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
this.goodsInfo = res.data |
|||
if (this.kefu.id) { |
|||
this.showGoods = true |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
// 图片预览 |
|||
previewImage(url) { |
|||
uni.previewImage({ |
|||
urls: [url] |
|||
}); |
|||
}, |
|||
|
|||
// 上传图片 |
|||
async uploadFile() { |
|||
const [error, success] = await uni.chooseImage({ |
|||
count: 1 |
|||
}) |
|||
if (error) { |
|||
return |
|||
} |
|||
uni.showLoading({ |
|||
title: '上传中...' |
|||
}) |
|||
try { |
|||
const file = await uploadFile(success.tempFilePaths[0]) |
|||
this.send(file.base_uri, 2) |
|||
uni.hideLoading() |
|||
} catch (e) { |
|||
this.$toast({ |
|||
title: '上传失败,请稍后再试' |
|||
}) |
|||
uni.hideLoading() |
|||
} |
|||
|
|||
}, |
|||
// 发送文本 |
|||
sendText() { |
|||
if (!this.msg) return |
|||
this.send(this.msg, 1) |
|||
this.msg = '' |
|||
}, |
|||
// 发送商品 |
|||
sendGoods() { |
|||
this.showGoods = false |
|||
this.send(this.goodsId, 3) |
|||
}, |
|||
|
|||
// 获取聊天记录 |
|||
async getChatRecord() { |
|||
const { |
|||
page, |
|||
pageStatus |
|||
} = this |
|||
if (pageStatus == 'finish') return |
|||
const res = await chatRecord({ |
|||
shop_id: this.shopId, |
|||
page_no: page |
|||
}) |
|||
if (res.code == 1) { |
|||
let toid = 0 |
|||
this.page++ |
|||
const { |
|||
kefu, |
|||
record |
|||
} = res.data |
|||
this.kefu = kefu |
|||
this.showIndex = record.list.length |
|||
if (this.recoreds.length) { |
|||
toid = this.recoreds[0].id |
|||
this.recoreds[0].show_time = true |
|||
} |
|||
|
|||
this.recoreds.unshift(...record.list) |
|||
this.$nextTick(() => { |
|||
if (!record.more) { |
|||
this.pageStatus = 'finish' |
|||
} |
|||
this.scrollToItem(toid) |
|||
this.showIndex = -1 |
|||
}) |
|||
} |
|||
}, |
|||
// 发送消息 |
|||
send(msg, type) { |
|||
this.socket.send({ |
|||
event: 'chat', |
|||
data: { |
|||
msg, |
|||
msg_type: type, // 暂定 1=>文本;2=>图片;3=>表情 |
|||
to_id: this.kefu.id, // 接收人id;客服发给用户则为user_id, 用户发给客服则为kefu_id |
|||
to_type: "kefu" |
|||
} |
|||
}) |
|||
}, |
|||
// 显示、隐藏表情库 |
|||
handleEmojiShow() { |
|||
this.showEmoji = !this.showEmoji |
|||
if (!this.showEmoji) return |
|||
setTimeout(() => { |
|||
this.scrollToBottom() |
|||
}, 300) |
|||
}, |
|||
scrollToupper() { |
|||
this.getChatRecord() |
|||
}, |
|||
scrollToBottom() { |
|||
this.intoView = 'bottom' |
|||
this.$nextTick(() => { |
|||
this.intoView = '' |
|||
}) |
|||
}, |
|||
scrollToItem(id) { |
|||
this.intoView = `chat-item_${id}` |
|||
this.$nextTick(() => { |
|||
this.intoView = '' |
|||
}) |
|||
}, |
|||
|
|||
handleEmojiInput(val) { |
|||
this.msg = this.msg + val |
|||
}, |
|||
chatEvent(data) { |
|||
this.isError = false |
|||
if (data.from_type == 'kefu') { |
|||
uni.vibrateLong({ |
|||
success: function() { |
|||
console.log('success'); |
|||
} |
|||
}); |
|||
} |
|||
if (data.shop_id != this.shopId) { |
|||
return |
|||
} |
|||
this.recoreds.push(data) |
|||
this.$nextTick(() => { |
|||
getRect('#bottom').then(res => { |
|||
if (res.bottom < 1000) { |
|||
this.scrollToItem(data.id) |
|||
} |
|||
}) |
|||
}) |
|||
|
|||
}, |
|||
errorEvent(data) { |
|||
this.errorMsg = data.msg |
|||
this.isError = true |
|||
this.$nextTick(() => { |
|||
this.scrollToBottom() |
|||
}) |
|||
}, |
|||
loginEvent(data) { |
|||
// 登录成功,发送用户上线通知 |
|||
this.socket.send({ |
|||
event: 'user_online', |
|||
data: { |
|||
kefu_id: this.kefu.id |
|||
} |
|||
}) |
|||
}, |
|||
transferEvent(data) { |
|||
this.kefu = data |
|||
}, |
|||
setTitle(title) { |
|||
uni.setNavigationBarTitle({ |
|||
title |
|||
}) |
|||
} |
|||
|
|||
}, |
|||
async onLoad() { |
|||
this.scrollToupper = debounce(this.scrollToupper, 500, this) |
|||
this.init() |
|||
this.getData() |
|||
}, |
|||
onUnload() { |
|||
this.socket.close() |
|||
}, |
|||
onReady() { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
page { |
|||
pading: 0; |
|||
height: 100%; |
|||
} |
|||
|
|||
.chat { |
|||
height: 100%; |
|||
|
|||
.goods { |
|||
display: flex; |
|||
position: fixed; |
|||
width: 600rpx; |
|||
right: 20rpx; |
|||
bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
border-radius: 14rpx; |
|||
background: #fff; |
|||
padding: 20rpx; |
|||
|
|||
.close { |
|||
position: absolute; |
|||
left: -20rpx; |
|||
top: -20rpx; |
|||
} |
|||
|
|||
.send-btn { |
|||
padding: 8rpx 22rpx; |
|||
} |
|||
} |
|||
|
|||
.content { |
|||
transition: all .3s; |
|||
flex: 1; |
|||
min-height: 0; |
|||
|
|||
.loading { |
|||
padding: 20rpx; |
|||
height: 40px; |
|||
} |
|||
|
|||
.chat-lists { |
|||
padding: 0 20rpx 30rpx; |
|||
overflow: hidden; |
|||
position: relative; |
|||
|
|||
.chat-tips { |
|||
padding: 4rpx 20rpx; |
|||
border-radius: 21rpx; |
|||
display: inline-block; |
|||
text-align: center; |
|||
background-color: rgba(0, 0, 0, 0.2); |
|||
} |
|||
|
|||
.chat-item { |
|||
padding-top: 30rpx; |
|||
|
|||
&.visibility { |
|||
visibility: hidden; |
|||
} |
|||
|
|||
.chat-info { |
|||
display: flex; |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
&.right { |
|||
.chat-info { |
|||
flex-direction: row-reverse; |
|||
|
|||
.text-box { |
|||
background-color: #ED5349; |
|||
color: #fff; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.avatar { |
|||
width: 78rpx; |
|||
height: 78rpx; |
|||
border-radius: 14rpx; |
|||
flex: none; |
|||
} |
|||
|
|||
.text-box { |
|||
max-width: 500rpx; |
|||
min-width: 80rpx; |
|||
background-color: #fff; |
|||
border-radius: 14rpx; |
|||
padding: 16rpx 20rpx; |
|||
margin: 0 20rpx; |
|||
word-break: break-word; |
|||
line-height: 40rpx; |
|||
} |
|||
|
|||
.image-box { |
|||
max-width: 300rpx; |
|||
margin: 0 20rpx; |
|||
|
|||
.image { |
|||
max-width: 100%; |
|||
} |
|||
} |
|||
|
|||
.goods-box { |
|||
position: static; |
|||
width: 510rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.error { |
|||
padding: 0 30rpx 30rpx; |
|||
|
|||
.error-msg { |
|||
color: #bbb; |
|||
word-break: break-word; |
|||
} |
|||
} |
|||
|
|||
.footer { |
|||
background: #f2f2f2; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
|
|||
.footer-input { |
|||
height: 100rpx; |
|||
padding: 0 20rpx; |
|||
|
|||
.icon { |
|||
width: 52rpx; |
|||
height: 52rpx; |
|||
} |
|||
|
|||
.input-contain { |
|||
margin: 0 20rpx; |
|||
background-color: #fff; |
|||
height: 68rpx; |
|||
border-radius: 60rpx; |
|||
flex: 1; |
|||
overflow: hidden; |
|||
padding: 0 10rpx 0 30rpx; |
|||
|
|||
.text-area { |
|||
flex: 1; |
|||
height: 100rpx; |
|||
word-break: break-all; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
.emoji-wrap { |
|||
height: 0; |
|||
transition: all .3s; |
|||
|
|||
&.emoji-show { |
|||
height: 200px; |
|||
} |
|||
} |
|||
|
|||
.send-btn { |
|||
padding: 0 25rpx; |
|||
color: #fff; |
|||
background-color: #ED5349; |
|||
border-radius: 60rpx; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,63 @@ |
|||
|
|||
|
|||
<template> |
|||
<view class="commission-details"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" :down="downOption" @down="downCallback"> |
|||
<view class="p-t-20" > |
|||
<view class="bg-white" v-for="(item, index) in list" :key="index" > |
|||
<record-cell :remark="item.source_type" :date="item.create_time" :money="item.change_amount" :type="item.change_type" /> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
import {getCommission} from "@/api/user" |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
// Tabs 列表 |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无记录', // 提示 |
|||
} |
|||
}, |
|||
list: [], // 列表数据--全部 |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
|
|||
// 上拉加载 |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
getCommission({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.list = []; |
|||
const curPageData = data.list; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.list = this.list.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
|
|||
</style> |
|||
@ -0,0 +1,158 @@ |
|||
<template> |
|||
<view class="contact-offical" v-show="isShow" :class="{'shop-contact': shopId}"> |
|||
<template v-if="shopId"> |
|||
<view class="header white" > |
|||
<view class="title font-size-50 text-center">店铺客服</view> |
|||
<view class="line m-t-36"></view> |
|||
</view> |
|||
<view class="content flex-col col-center"> |
|||
<view class="content-view flex-col col-center bg-white text-center"> |
|||
<view class="flex col-center m-b-40 m-l-40" style="align-self: flex-start;"> |
|||
<u-image width="88rpx" height="88rpx" border-radius="50%" :src="server.shop.logo" /> |
|||
<view class="lg m-l-20">{{server.shop.name}}</view> |
|||
</view> |
|||
<u-image width="360rpx" height="360rpx" :src="server.config.image" /> |
|||
<view v-if="server.config.wechat" class="flex row-center copy-btn white lg br60 m-t-50 m-b-40" @click="onCopy(server.config.wechat)"> |
|||
复制去微信添加 |
|||
</view> |
|||
<view class="lighter xs">营业时间:{{server.config.business_time}}</view> |
|||
<view class="xs lighter m-t-10 flex"> |
|||
客服电话:{{server.config.phone}} |
|||
<view class="phone-btn m-l-30" @tap="showPhoneCall=true">拨打</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<u-modal :content="'即将打电话给'+ server.config.phone" v-model="showPhoneCall" show-cancel-button confirm-text='呼叫' |
|||
:confirm-color="colorConfig.primary" @confirm="onCall"> |
|||
</u-modal> |
|||
</template> |
|||
<template v-else> |
|||
<view class="header white" > |
|||
<view class="title font-size-50 text-center">平台客服</view> |
|||
<view class="line m-t-36"></view> |
|||
</view> |
|||
<view class="content flex-col col-center"> |
|||
<view class="content-view flex-col col-center bg-white text-center"> |
|||
<u-image width="360rpx" height="360rpx" :src="server.image" /> |
|||
<view v-if="server.wechat" class="flex row-center copy-btn lg br60 white m-t-50 m-b-40" @click="onCopy(server.wechat)"> |
|||
复制去微信添加 |
|||
</view> |
|||
<view class="lighter xs">营业时间:{{server.business_time}}</view> |
|||
<view class="xs lighter m-t-10 flex"> |
|||
平台电话:{{server.phone}} |
|||
<view class="phone-btn m-l-30" @tap="showPhoneCall=true">拨打</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<u-modal :content="'即将打电话给'+ server.phone" v-model="showPhoneCall" show-cancel-button confirm-text='呼叫' |
|||
:confirm-color="colorConfig.primary" @confirm="onCall"> |
|||
</u-modal> |
|||
</template> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getService, |
|||
getChatConfig |
|||
} from "@/api/app" |
|||
import { |
|||
getShopService |
|||
} from "@/api/shop" |
|||
import { |
|||
copy |
|||
} from '@/utils/tools' |
|||
export default { |
|||
name: 'contactOffical', |
|||
data() { |
|||
return { |
|||
server: { |
|||
config: {}, |
|||
shop: {} |
|||
}, |
|||
showPhoneCall: false, |
|||
shopId: 0, |
|||
isShow: false |
|||
} |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.shopId = Number(this.$Route.query.id) |
|||
this.getServiceFun() |
|||
}, |
|||
|
|||
methods: { |
|||
async getServiceFun() { |
|||
const {data, code} = this.shopId ? await getShopService(this.shopId) : await getService() |
|||
if(code == 1) { |
|||
this.server = data |
|||
this.isShow = true |
|||
} |
|||
}, |
|||
onCopy(str) { |
|||
copy(str); |
|||
}, |
|||
onCall() { |
|||
wx.makePhoneCall({ |
|||
phoneNumber: String(this.server.config && this.server.config.phone || this.server.phone), |
|||
success(e) { |
|||
console.log('成功', e) |
|||
}, |
|||
fail(err) { |
|||
console.log('失败', err) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
page { |
|||
padding: 0; |
|||
} |
|||
.contact-offical { |
|||
min-height: 100vh; |
|||
background-image: url(../../static/contact_official_bg.png); |
|||
background-position: center; |
|||
background-size: cover; |
|||
background-repeat: no-repeat; |
|||
&.shop-contact { |
|||
background-image: url(../../static/shop_official_bg.png); |
|||
|
|||
.header{ |
|||
.line { |
|||
background:#3A67E4; |
|||
} |
|||
} |
|||
} |
|||
.header { |
|||
padding: 80rpx 50rpx 0; |
|||
.line { |
|||
height: 25rpx; |
|||
background: #BE000E; |
|||
border-radius: 20rpx; |
|||
} |
|||
} |
|||
.content { |
|||
margin-top: -10rpx; |
|||
.content-view { |
|||
width: 620rpx; |
|||
padding: 80rpx 20rpx 40rpx; |
|||
} |
|||
|
|||
.phone-btn { |
|||
padding: 2rpx 19rpx; |
|||
border: 1px solid #D7D7D7; |
|||
border-radius: 10rpx; |
|||
} |
|||
.copy-btn { |
|||
background: linear-gradient(#12c96e 0%, #0abd57 50.76%, #03b240 100%); |
|||
width: 460rpx; |
|||
height: 84rpx; |
|||
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16); |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,61 @@ |
|||
<template> |
|||
<view class="user-order"> |
|||
<tabs :current="active" @change="changeShow" bar-width="60" :is-scroll="true"> |
|||
<tab v-for="(item, index) in order" :key="index" :name="item.name"> |
|||
<exchange-order-list :order-type="item.type" :i="index" :index="active"></exchange-order-list> |
|||
</tab> |
|||
</tabs> |
|||
<float-tab></float-tab> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
active: -1, |
|||
order: [{ |
|||
name: '全部', |
|||
type: '' |
|||
}, { |
|||
name: '待付款', |
|||
type: 0 |
|||
}, { |
|||
name: '待发货', |
|||
type: 1 |
|||
}, { |
|||
name: '待收货', |
|||
type: 2 |
|||
}, { |
|||
name: '已完成', |
|||
type: 3 |
|||
}, { |
|||
name: '已关闭', |
|||
type: 4 |
|||
}] |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
changeShow(index) { |
|||
if (index != -1) { |
|||
this.$nextTick(() => { |
|||
this.active = index |
|||
}) |
|||
} |
|||
}, |
|||
}, |
|||
onLoad(options) { |
|||
const { |
|||
order |
|||
} = this |
|||
let type = this.$Route.query.type || ''; |
|||
let index = order.findIndex(item => item.type == type) |
|||
this.changeShow(index); |
|||
}, |
|||
|
|||
}; |
|||
</script> |
|||
<style> |
|||
|
|||
</style> |
|||
@ -0,0 +1,369 @@ |
|||
<template> |
|||
<view> |
|||
<view class="order-details"> |
|||
<view class="header-bg"></view> |
|||
<view class="main"> |
|||
<view class="header"> |
|||
<view class="item" v-if="orderDetail.order_status == 0"> |
|||
<view class="white lg m-b-10">等待买家付款</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 1"> |
|||
<view class="white lg m-b-10">待发货</view> |
|||
<view class="white sm">您的商品正在打包中,请耐心等待…</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 2"> |
|||
<view class="white lg m-b-10">待收货</view> |
|||
<view class="white sm">您的商品正在路中,请耐心等待…</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 3"> |
|||
<view class="white lg m-b-10">已完成</view> |
|||
<view class="white sm">商品已签收,期待再次购买!</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 4"> |
|||
<view class="white lg m-b-10">订单已关闭</view> |
|||
<!-- <view class="white sm">原因:超时未支付</view> --> |
|||
</view> |
|||
</view> |
|||
<view class="address-wrap flex contain"> |
|||
<image class="icon-md m-r-20" src="/static/images/icon_address.png"></image> |
|||
<view class="address"> |
|||
<view> |
|||
<text class="name md m-r-10">{{orderDetail.consignee}}</text> |
|||
<text class="phone md">{{orderDetail.mobile}}</text> |
|||
<view class="area sm m-t-10 lighter">{{orderDetail.delivery_address}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
|
|||
|
|||
<view class="goods contain"> |
|||
<view class="flex"> |
|||
<u-image :src="orderDetail.goods.image" border-radius="10" width="160" height="160"></u-image> |
|||
<view class="goods-info flex-1 m-l-20"> |
|||
<view class="goods-name line-2">{{ orderDetail.goods.name }}</view> |
|||
<view class="flex row-between"> |
|||
<view class="goods-price primary m-t-10"> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderDetail.goods.need_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="orderDetail.goods.exchange_way === 2"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderDetail.goods.need_money" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
<view class="lighter">×{{orderDetail.total_num}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="price contain"> |
|||
<view class="flex row-between"> |
|||
<view>商品金额</view> |
|||
<view class="black"> |
|||
<price-format :show-subscript="false" :price="orderDetail.order_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="orderDetail.goods_price > 0"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :price="orderDetail.goods_price" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between" v-if="orderDetail.shipping_price"> |
|||
<view>运费</view> |
|||
<view class="black">+ |
|||
<price-format :price="orderDetail.shipping_price"></price-format> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-right"> |
|||
<view class="lighter">实付金额:</view> |
|||
<view class="primary"> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderDetail.order_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="orderDetail.order_amount > 0"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderDetail.order_amount" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="order-info contain"> |
|||
<view class="item flex" style="align-items: flex-start;"> |
|||
<view class="title">买家留言</view> |
|||
<view class="black">{{orderDetail.user_remark || '无'}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="order-info contain"> |
|||
<view class="item flex"> |
|||
<view class="title">订单编号</view> |
|||
<view class="black">{{orderDetail.order_sn}}</view> |
|||
</view> |
|||
|
|||
<view class="item flex"> |
|||
<view class="title">支付方式</view> |
|||
<view class="black">{{orderDetail.pay_way}}</view> |
|||
</view> |
|||
<view class="item flex"> |
|||
<view class="title">下单时间</view> |
|||
<view class="black">{{orderDetail.create_time}}</view> |
|||
</view> |
|||
<view v-if="orderDetail.pay_time" class="item flex"> |
|||
<view class="title">付款时间</view> |
|||
<view class="black">{{orderDetail.pay_time}}</view> |
|||
</view> |
|||
<view v-if="orderDetail.shipping_time" class="item flex"> |
|||
<view class="title">发货时间</view> |
|||
<view class="black">{{orderDetail.shipping_time }}</view> |
|||
</view> |
|||
<view v-if="orderDetail.confirm_take_time" class="item flex"> |
|||
<view class="title">成交时间</view> |
|||
<view class="black">{{orderDetail.confirm_take_time }}</view> |
|||
</view> |
|||
<view v-if="orderDetail.cancel_time" class="item flex"> |
|||
<view class="title">关闭时间</view> |
|||
<view class="black">{{orderDetail.cancel_time}}</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="footer bg-white flex fixed" |
|||
v-if="orderDetail.btns.cancel_btn || orderDetail.btns.delivery_btn || orderDetail.btns.confirm_btn || orderDetail.btns.del_btn || orderDetail.btns.pay_btn"> |
|||
<view class="flex-1"></view> |
|||
<view v-if="orderDetail.btns.cancel_btn"> |
|||
<button size="sm" class="plain br60" hover-class="none" @tap="handleOrder(0)">取消订单</button> |
|||
</view> |
|||
<router-link |
|||
v-if="orderDetail.btns.delivery_btn" |
|||
:to="{path: '/bundle/pages/goods_logistics/goods_logistics', query: {id: orderDetail.id, type: 'integral'}}"> |
|||
<button size="sm" class="plain br60" hover-class="none">查看物流</button> |
|||
</router-link> |
|||
<view v-if="orderDetail.btns.confirm_btn" class="m-l-20"> |
|||
<button size="sm" class="plain br60 primary red" hover-class="none" |
|||
@tap.stop="handleOrder(2)">确认收货</button> |
|||
</view> |
|||
<view v-if="orderDetail.btns.del_btn"> |
|||
<button size="sm" class="plain br60" hover-class="none" @tap="handleOrder(1)">删除订单</button> |
|||
</view> |
|||
<view class="m-l-20" v-if="orderDetail.btns.pay_btn"> |
|||
<button size="sm" class="bg-primary br60 white" @tap="payNow">立即付款</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<loading-view v-if="isFirstLoading"></loading-view> |
|||
<order-dialog ref="orderDialog" :orderId="orderDetail.id" :type="type" @confirm="confirmDialog"></order-dialog> |
|||
<float-tab></float-tab> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getIntegralOrderDetail, |
|||
cancelIntegralOrder, |
|||
delIntegralOrder, |
|||
confirmIntegralOrder |
|||
} from '@/api/activity'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
orderDetail: { |
|||
goods: {}, |
|||
btns: {} |
|||
}, |
|||
team: {}, |
|||
isFirstLoading: true, |
|||
type: 0, |
|||
showCancel: "", |
|||
showLoading: false |
|||
}; |
|||
}, |
|||
|
|||
onLoad: function(options) { |
|||
const { |
|||
id |
|||
} = this.$Route.query; |
|||
this.id = id; |
|||
this.getOrderDetailFun(); |
|||
uni.$on('payment', this.payCallback) |
|||
}, |
|||
onUnload() { |
|||
uni.$off('payment', this.payCallback) |
|||
}, |
|||
methods: { |
|||
payCallback(params) { |
|||
setTimeout(() => { |
|||
if (params.result) { |
|||
this.$toast({ |
|||
title: "支付成功" |
|||
}) |
|||
this.getOrderDetailFun() |
|||
} else { |
|||
this.$toast({ |
|||
title: "支付失败" |
|||
}) |
|||
} |
|||
}, 500) |
|||
}, |
|||
async confirmDialog() { |
|||
const { |
|||
type, |
|||
id |
|||
} = this |
|||
let res = null |
|||
switch (type) { |
|||
case 0: |
|||
res = await cancelIntegralOrder(id); |
|||
break; |
|||
|
|||
case 1: |
|||
res = await delIntegralOrder(id); |
|||
break; |
|||
|
|||
case 2: |
|||
res = await confirmIntegralOrder(id); |
|||
break; |
|||
} |
|||
if (res.code == 1) { |
|||
uni.$emit("refreshorder") |
|||
|
|||
if ([0, 2].includes(type)) { |
|||
this.getOrderDetailFun(); |
|||
} else if (type == 1) { |
|||
setTimeout(() => { |
|||
uni.navigateBack() |
|||
}, 2000) |
|||
} |
|||
} |
|||
|
|||
}, |
|||
dialogOpen() { |
|||
this.$refs.orderDialog.open() |
|||
}, |
|||
|
|||
handleOrder(type) { |
|||
this.type = type |
|||
this.$nextTick(() => { |
|||
this.dialogOpen(); |
|||
}); |
|||
}, |
|||
payNow() { |
|||
this.$Router.push({ |
|||
path: '/pages/payment/payment', |
|||
query: { |
|||
from: 'integral', |
|||
order_id: this.id |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
getOrderDetailFun() { |
|||
getIntegralOrderDetail(this.id).then(res => { |
|||
if (res.code == 1) { |
|||
this.orderDetail = res.data |
|||
this.$nextTick(() => { |
|||
this.isFirstLoading = false |
|||
}); |
|||
} else { |
|||
setTimeout(() => uni.navigateBack(), 1500) |
|||
} |
|||
}); |
|||
}, |
|||
}, |
|||
computed: { |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.order-details { |
|||
position: relative; |
|||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
|
|||
.contain { |
|||
margin: 0 20rpx 20rpx; |
|||
border-radius: 14rpx; |
|||
background-color: #fff; |
|||
} |
|||
|
|||
.header-bg { |
|||
position: absolute; |
|||
top: 0; |
|||
width: 100%; |
|||
height: 200rpx; |
|||
background-color: $-color-primary; |
|||
z-index: 0; |
|||
|
|||
} |
|||
|
|||
.header { |
|||
padding: 24rpx 40rpx; |
|||
} |
|||
|
|||
.main { |
|||
position: relative; |
|||
z-index: 1; |
|||
} |
|||
|
|||
.goods { |
|||
padding: 30rpx 24rpx; |
|||
|
|||
.goods-name { |
|||
line-height: 40rpx; |
|||
height: 80rpx; |
|||
} |
|||
} |
|||
|
|||
.address-wrap { |
|||
height: 164rpx; |
|||
padding: 0 24rpx; |
|||
} |
|||
|
|||
.order-info { |
|||
padding: 12rpx 0; |
|||
|
|||
.item { |
|||
padding: 12rpx 24rpx; |
|||
|
|||
.title { |
|||
width: 180rpx; |
|||
flex: none; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.price { |
|||
padding: 24rpx 0; |
|||
|
|||
&>view { |
|||
height: 60rpx; |
|||
padding: 0 24rpx; |
|||
} |
|||
} |
|||
|
|||
.footer { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
height: 100rpx; |
|||
padding: 0 24rpx; |
|||
box-sizing: content-box; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
|
|||
.plain { |
|||
border: 1px solid #BBBBBB; |
|||
|
|||
&.red { |
|||
border: 1px solid $-color-primary; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
</style> |
|||
@ -0,0 +1,240 @@ |
|||
|
|||
|
|||
|
|||
<template> |
|||
<view> |
|||
<view class="goods-logistics p-t-20"> |
|||
<view class="header flex bg-white"> |
|||
<view class="goods m-r-20"> |
|||
<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 m-t-10 m-b-10">物流公司:{{order.shipping_name}}</view> |
|||
<view class="row"> |
|||
<text class="black">快递单号:{{order.invoice_no}}</text> |
|||
<text class="primary m-l-20" @tap="onCopy">复制</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="main m-t-20 bg-white column"> |
|||
<!-- 物流时间轴 --> |
|||
<view class="express"> |
|||
<!-- 顶部收货地址 --> |
|||
<view class="express-address row" v-if="take.contacts"> |
|||
<view class="express-left flex-col col-center"> |
|||
<image class="express-icon" :src="finish.tips ? '/bundle/static/logistics_address.png' : '/bundle/static/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 flex-col col-center"> |
|||
<image class="express-icon" src="/bundle/static/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 flex-col col-center"> |
|||
<image class="express-icon" src="/bundle/static/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 flex-col col-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 flex-col col-center"> |
|||
<image class="express-icon" src="/bundle/static/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 flex-col col-center"> |
|||
<image class="express-icon" src="/bundle/static/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 { getIntegralOrderTraces } from '@/api/activity' |
|||
import {copy} from '@/utils/tools' |
|||
export default { |
|||
data() { |
|||
return { |
|||
shipment: {}, |
|||
buy: {}, |
|||
delivery: {}, |
|||
finish: {}, |
|||
order: {}, |
|||
take: {}, |
|||
isFirstLoading: true |
|||
}; |
|||
}, |
|||
onLoad () { |
|||
this.id = this.$Route.query.id |
|||
this.type = this.$Route.query.type |
|||
this.orderTracesFun(); |
|||
}, |
|||
|
|||
methods: { |
|||
async orderTracesFun() { |
|||
const { |
|||
code, |
|||
data: { |
|||
shipment, |
|||
buy, |
|||
delivery, |
|||
finish, |
|||
order, |
|||
take |
|||
} |
|||
} = this.type == 'integral' ? await getIntegralOrderTraces(this.id) : 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,193 @@ |
|||
<template> |
|||
<view class="goods-reviews"> |
|||
<view class="bg-white flex p-20"> |
|||
<u-image width="160rpx" height="160rpx" border-radius="6rpx" :src="goodsInfo.goods_item.image"></u-image> |
|||
<view class="goods-desc flex-1 m-l-24"> |
|||
<view class="goods-name line-2">{{goodsInfo.goods_name}}</view> |
|||
<view class="m-t-10 xs muted" >{{goodsInfo.goods_item.spec_value_str}}</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<price-format :price="goodsInfo.goods_price" :subscript-size="26" |
|||
:first-size="30" :second-size="30" /> |
|||
<view class="nr">x{{goodsInfo.goods_num}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="goods-evaluate bg-white flex"> |
|||
<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="bg-white p-20 lighter">{{goodsInfo.shop.name}}</view> |
|||
<view class="rate bg-white"> |
|||
<view class="item flex m-b-20"> |
|||
<view class="lable">描述相符</view> |
|||
<u-rate name="descRate" :size="42" active-color="#FF2C3C" v-model="descRate" /> |
|||
</view> |
|||
<view class="item flex m-b-20"> |
|||
<view class="lable">服务态度</view> |
|||
<u-rate name="serverRate" :size="42" active-color="#FF2C3C" v-model="serverRate" /> |
|||
</view> |
|||
<view class="item flex m-b-20"> |
|||
<view class="lable">配送服务</view> |
|||
<u-rate name="deliveryRate" :size="42" active-color="#FF2C3C" v-model="deliveryRate" /> |
|||
</view> |
|||
</view> |
|||
<view class="goods-dec bg-white m-t-20"> |
|||
<view class="title m-b-20 md bold">商品描述</view> |
|||
<view class="p-20" style="background-color: #F8F8F8;"> |
|||
<u-input v-model="comment" type="textarea" placeholder="宝贝收到还满意吗,说说你的使用心得。分享给想买的他们吧!!" :border="false" |
|||
:height="160" /> |
|||
</view> |
|||
<view class="m-t-20"> |
|||
<u-upload ref="uUpload" :show-progress="false" :header="{token: $store.getters.token}" |
|||
:max-count="8" width="150" height="150" :action="action" upload-text="上传图片" |
|||
@on-success="onSuccess" @on-remove="onRemove" /> |
|||
</view> |
|||
<view class="muted m-t-20 m-b-10">支持jpg、png、jpeg格式的图片,最多可上传8张</view> |
|||
</view> |
|||
<button class="btn br60" type="primary" size="lg" @tap="onSubmit">立即评价</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
baseURL |
|||
} from '@/config/app.js'; |
|||
import { |
|||
goodsComment, |
|||
getCommentInfo |
|||
} from '@/api/user'; |
|||
import { |
|||
uploadFile |
|||
} from '@/utils/tools.js'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
action: baseURL + '/api/file/formimage', |
|||
goodsRate: 0, |
|||
descRate: 0, |
|||
serverRate: 0, |
|||
deliveryRate: 0, |
|||
goodsRateDesc: "", |
|||
fileList: [], |
|||
goodsInfo: { |
|||
shop: {}, |
|||
goods_item: {} |
|||
}, |
|||
comment: '', |
|||
type: "" |
|||
}; |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.id = this.$Route.query.id |
|||
this.getCommentInfoFun(); |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
onSuccess(e) { |
|||
this.fileList.push(e.data.base_uri) |
|||
}, |
|||
onRemove(index) { |
|||
this.fileList.splice(index, 1) |
|||
}, |
|||
|
|||
goodsRateChange(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; |
|||
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({ |
|||
order_goods_id: parseInt(this.id), |
|||
goods_comment: goodsRate, |
|||
service_comment: serverRate, |
|||
express_comment: deliveryRate, |
|||
description_comment: descRate, |
|||
comment, |
|||
image: fileList |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
this.$toast({ |
|||
title: '评价成功' |
|||
}, { |
|||
tab: 3, |
|||
url: 1 |
|||
}); |
|||
uni.$emit('refreshcomment') |
|||
} |
|||
}); |
|||
}, |
|||
getCommentInfoFun() { |
|||
getCommentInfo({ |
|||
order_goods_id: this.id |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
this.goodsInfo = res.data |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.goods-reviews { |
|||
padding: 20rpx 0 40rpx; |
|||
} |
|||
|
|||
.goods-reviews .rate { |
|||
padding: 20rpx 20rpx; |
|||
} |
|||
|
|||
.goods-reviews .lable { |
|||
width: 170rpx; |
|||
} |
|||
|
|||
.goods-reviews .goods-dec { |
|||
padding: 30rpx 20rpx; |
|||
} |
|||
|
|||
.goods-reviews .btn { |
|||
width: 698rpx; |
|||
margin: 30rpx 26rpx 0; |
|||
} |
|||
|
|||
.goods-reviews .goods-evaluate { |
|||
padding: 20rpx; |
|||
border: 1rpx solid #F2F2F2; |
|||
} |
|||
|
|||
</style> |
|||
@ -0,0 +1,219 @@ |
|||
<template> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" :up="upOption" @down="downCallback" @up="upCallback"> |
|||
<view class="goods-seckill"> |
|||
<view class="banner"> |
|||
<ad-swipers :pid="20" height="340rpx"></ad-swipers> |
|||
</view> |
|||
<view class="time-list"> |
|||
<scroll-view style="height: 120rpx; white-space: nowrap;" :scroll-into-view="'item-' + (active - 2)" |
|||
scroll-x="true" scroll-with-animation="true"> |
|||
<view v-for="(item, index) in seckillTime" :key="index" :id="'item-' + index" |
|||
class="time-item flex-col row-center col-center" :class="{active: index == active}" |
|||
@tap="exchangeTime(index)"> |
|||
<view :class="'xl bold time'">{{ item.start_time }}</view> |
|||
<view :class="'sm br60 state ' + ( item.status === 2 ? 'muted': '' )"> |
|||
{{ item.tips }} |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
<view class="goods-list"> |
|||
<router-link v-for="(item, index) in seckillGoods" :key="index" |
|||
:to="{path: '/pages/goods_details/goods_details', query: {id: item.goods_id}}"> |
|||
<view class="goods-item flex bg-white"> |
|||
<u-image width="180rpx" height="180rpx" border-radius="10rpx" :src="item.goods_image" /> |
|||
<view class="goods-info m-l-20"> |
|||
<view style="width: 490rpx" class="goods-name line-2 m-b-10">{{item.goods_name}}</view> |
|||
<label class="sale-info xs primary br60"> |
|||
已抢{{item.seckill_total}}件 |
|||
</label> |
|||
<view class="info-footer flex row-between m-t-5"> |
|||
<view class="price"> |
|||
<price-format class="m-r-10" :price="item.seckill_price" |
|||
:color="colorConfig.primary" :first-ize="34" :second-ize="26" |
|||
:subscript-ize="26" /> |
|||
<price-format class="line-through" :price="item.goods_min_price" |
|||
:color="colorConfig.muted" :first-ize="24" :second-ize="24" |
|||
:subscript-ize="24" /> |
|||
</view> |
|||
<button :class="'br60 white ' + (currentStatus == 2? ' bg-gray' : currentStatus == 1 |
|||
? 'primary-btn' : 'border-btn' )" size="sm"> |
|||
{{currentStatus == 2? '已结束': currentStatus == 1 ? '立即抢购' : '未开始'}}</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getSeckillTime, |
|||
getSeckillGoods |
|||
} from "@/api/activity"; |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"; |
|||
export default { |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
active: 0, |
|||
upOption: { |
|||
auto: false, |
|||
empty: { |
|||
use: true, |
|||
icon: '/static/images/goods_null.png', |
|||
tip: "暂无秒杀商品~", |
|||
}, |
|||
}, |
|||
seckillTime: [], |
|||
seckillGoods: [] |
|||
|
|||
}; |
|||
}, |
|||
methods: { |
|||
async downCallback(page) { |
|||
this.seckillGoods = [] |
|||
await this.getSeckillTimeFun() |
|||
this.mescroll.resetUpScroll(); |
|||
}, |
|||
upCallback(page) { |
|||
let pageNum = page.num; |
|||
let pageSize = page.size; |
|||
const {seckillTime, active} = this |
|||
if(!seckillTime.length) return this.mescroll.endSuccess(0,false) |
|||
let id = seckillTime[active].id |
|||
getSeckillGoods({ |
|||
page_no: pageNum, |
|||
page_size: pageSize, |
|||
seckill_id:id |
|||
}).then(res => { |
|||
let curPageData = res.data.lists; |
|||
let hasNext = !!res.data.more; |
|||
let curPageLen = curPageData.length; |
|||
if (pageNum == 1) this.seckillGoods = []; |
|||
this.seckillGoods = this.seckillGoods.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
}, |
|||
// 获取秒杀时间段 |
|||
getSeckillTimeFun() { |
|||
return new Promise((resolve) => { |
|||
getSeckillTime().then(({code, data}) => { |
|||
if (code == 1) { |
|||
// 抢购中 |
|||
let index = data.findIndex(item => item.status == 1); |
|||
if (index == -1) { |
|||
// 未开始 |
|||
index = data.findIndex(item => item.status == 0); |
|||
} |
|||
if(index == -1) { |
|||
// 全部结束选中最后一个 |
|||
index = data.length - 1 |
|||
} |
|||
this.seckillTime = data; |
|||
this.$nextTick(function(){ |
|||
this.active = index |
|||
resolve() |
|||
}) |
|||
} |
|||
}) |
|||
}) |
|||
|
|||
}, |
|||
|
|||
|
|||
// 查看其他时间段 |
|||
exchangeTime(index) { |
|||
this.active = index |
|||
this.seckillGoods = [] |
|||
this.mescroll.resetUpScroll(); |
|||
}, |
|||
}, |
|||
computed: { |
|||
currentStatus() { |
|||
const {active, seckillTime} = this |
|||
return seckillTime[active] && seckillTime[active].status |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.bg-gray { |
|||
background-color: #CCCCCC !important; |
|||
} |
|||
|
|||
.goods-seckill { |
|||
|
|||
.time-list { |
|||
.time-item { |
|||
display: inline-flex; |
|||
width: 160rpx; |
|||
height: 100%; |
|||
|
|||
&.active { |
|||
.time { |
|||
color: $-color-primary; |
|||
} |
|||
|
|||
.state { |
|||
color: $-color-white; |
|||
background-color: $-color-primary; |
|||
} |
|||
} |
|||
|
|||
.state { |
|||
padding: 0 10rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.endtime-box { |
|||
height: 100rpx; |
|||
|
|||
.line { |
|||
width: 100rpx; |
|||
height: 2rpx; |
|||
background-color: #CCC; |
|||
} |
|||
} |
|||
|
|||
.goods-list { |
|||
.goods-item { |
|||
padding: 30rpx; |
|||
|
|||
.goods-info { |
|||
flex: 1; |
|||
width: 470rpx; |
|||
|
|||
.sale-info { |
|||
padding: 4rpx 16rpx; |
|||
background-color: #FFE9EB; |
|||
} |
|||
|
|||
.info-footer { |
|||
.btn { |
|||
padding: 0 30rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.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 $-color-primary; |
|||
color: $-color-primary; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,128 @@ |
|||
<template> |
|||
<view class="input-express-info p-t-20"> |
|||
<view class="input-contain bg-white"> |
|||
<u-field v-model="formInfo.express" :border-bottom="false" label="物流公司" placeholder="请输入物流公司名称"> |
|||
</u-field> |
|||
<u-field v-model="formInfo.number" :border-bottom="false" label="快递单号" placeholder="请输入快递单号"> |
|||
</u-field> |
|||
<u-field v-model="formInfo.remark" :border-bottom="false" label="备注说明" placeholder="选填"> |
|||
</u-field> |
|||
</view> |
|||
<view class="upload-contain bg-white m-t-20"> |
|||
<view class="header flex"> |
|||
<view class="normal">上传凭证</view> |
|||
<view class="sm muted m-l-20">(请上传快递单号凭证)</view> |
|||
</view> |
|||
<view class="upload"> |
|||
<u-upload ref="uUpload" :show-progress="false" :header="{token: $store.getters.token}" |
|||
:max-count="1" width="160" height="160" :action="action" upload-text="上传图片" |
|||
@on-success="onSuccess" @on-remove="onRemove" /> |
|||
</view> |
|||
</view> |
|||
<view class="submit-btn"> |
|||
<button size="lg" class=" br60 bg-primary white lg" @tap="formSubmit">提交</button> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
inputExpressInfo |
|||
} from '@/api/user'; |
|||
import { |
|||
baseURL |
|||
} from '@/config/app.js'; |
|||
|
|||
|
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
action: baseURL + '/api/file/formimage', |
|||
fileList: [], |
|||
formInfo: { |
|||
express: '', |
|||
number: '', |
|||
remark: '' |
|||
} |
|||
}; |
|||
}, |
|||
|
|||
onLoad() { |
|||
|
|||
this.id = this.$Route.query.id |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
onSuccess(e) { |
|||
this.fileList.push(e.data.base_uri) |
|||
}, |
|||
onRemove(index) { |
|||
this.fileList.splice(index, 1) |
|||
}, |
|||
|
|||
formSubmit(e) { |
|||
const { |
|||
fileList, |
|||
formInfo: { |
|||
express, |
|||
number, |
|||
remark |
|||
} |
|||
} = this; |
|||
if (!express) return this.$toast({ |
|||
title: '请填写物流公司名称' |
|||
}); |
|||
if (!number) return this.$toast({ |
|||
title: '请填写快递单号' |
|||
}); |
|||
let data = { |
|||
id: this.id, |
|||
express_name: express, |
|||
invoice_no: number, |
|||
express_remark: remark, |
|||
express_image: fileList.length ? fileList[0] : '' |
|||
}; |
|||
inputExpressInfo(data).then(res => { |
|||
if (res.code == 1) { |
|||
this.$toast({ |
|||
title: '提交成功' |
|||
}, { |
|||
tab: 3, |
|||
url: 1 |
|||
}); |
|||
uni.$emit("refreshsale") |
|||
} |
|||
}); |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
.input-contain .input-item { |
|||
padding: 24rpx; |
|||
} |
|||
|
|||
.input-item .label { |
|||
width: 152rpx; |
|||
} |
|||
|
|||
.input-item .input { |
|||
flex: 1; |
|||
} |
|||
|
|||
.upload-contain { |
|||
padding: 24rpx 20rpx 44rpx; |
|||
} |
|||
|
|||
.upload-contain .header { |
|||
margin-bottom: 30rpx; |
|||
} |
|||
|
|||
.submit-btn { |
|||
margin-top: 50rpx; |
|||
margin-left: 26rpx; |
|||
margin-right: 26rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,83 @@ |
|||
<template> |
|||
<view class="integral-details"> |
|||
<mescroll-body ref="mescrollRef" :up="{ |
|||
noMoreSize: 10, |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无积分明细~', |
|||
fixed: false |
|||
} |
|||
}" @init="mescrollInit" @down="downCallback" @up="upCallback"> |
|||
<view class="integral-lists"> |
|||
<view class="item flex row-between bg-white" v-for="(item, index) in integralList" :key="index"> |
|||
<view class=""> |
|||
<view class="nr"> |
|||
{{item.source_type}} |
|||
</view> |
|||
<view class="xs muted m-t-10"> |
|||
{{item.create_time}} |
|||
</view> |
|||
</view> |
|||
<view :class="'lg ' +(item.change_type == 1 ? 'primary' : '')"> |
|||
{{item.change_amount_format}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getAccountLog |
|||
} from "@/api/user"; |
|||
|
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
integralList: [], |
|||
}; |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
// 上拉加载更多 |
|||
upCallback({ |
|||
num, |
|||
size |
|||
}) { |
|||
getAccountLog({ |
|||
page_no: num, |
|||
page_size: size, |
|||
source: 2, //积分明细 |
|||
}).then(({ |
|||
data, |
|||
code |
|||
}) => { |
|||
if(code != 1) return this.mescroll.endErr() |
|||
if (num === 1) this.integralList = [] |
|||
this.integralList = [...this.integralList, ...data.list] |
|||
this.mescroll.endSuccess(data.list.length, !!data.more) |
|||
}).catch(err => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.integral-lists { |
|||
padding-top: 20rpx; |
|||
.item { |
|||
padding: 18rpx 30rpx; |
|||
position: relative; |
|||
&:not(:last-of-type) { |
|||
border-bottom: $-solid-border; |
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
|||
@ -0,0 +1,256 @@ |
|||
<template> |
|||
<view class="integral-goods-details"> |
|||
<!-- 商品图片 --> |
|||
<view class="goods-image" @tap="previewImage(goodsDetails.image)"> |
|||
<u-image :src="goodsDetails.image" width="100%" height="750rpx"></u-image> |
|||
</view> |
|||
<!-- 商品信息 --> |
|||
<view class="goods-info bg-white"> |
|||
<view class="info-header flex"> |
|||
<view class="price flex flex-1"> |
|||
<view class="primary m-r-10"> |
|||
<price-format :first-size="38" :second-size="24" :price="goodsDetails.need_integral" |
|||
:weight="500" :show-subscript="false"></price-format> |
|||
<text class="xs">积分</text> |
|||
<block v-if="goodsDetails.exchange_way === 2"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :first-size="38" |
|||
:second-size="24" :weight="500" :price="goodsDetails.need_money" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
<view class="muted xs" v-if="goodsDetails.market_price > 0"> |
|||
市场价 <price-format :first-size="24" :second-size="24" :subscript-size="24" |
|||
:price="goodsDetails.market_price"></price-format> |
|||
</view> |
|||
</view> |
|||
<view class="muted xs"> |
|||
已兑换:{{ goodsDetails.sales }} |
|||
</view> |
|||
</view> |
|||
<view class="name lg bold">{{ goodsDetails.name }}</view> |
|||
</view> |
|||
<!-- 商品规格选择 --> |
|||
<view class="goods-spec flex bg-white m-t-20" @tap="showSpec = true"> |
|||
<view class="label muted">已选</view> |
|||
<view class="line-1 m-r-20 flex-1">数量x{{ count }}</view> |
|||
<u-icon name="arrow-right" :color="colorConfig.muted"></u-icon> |
|||
</view> |
|||
<!-- 商品详情 --> |
|||
<view class="goods-details m-t-20 bg-white"> |
|||
<view class="details-title lg">商品详情</view> |
|||
<view class="details-content"> |
|||
<u-parse :html="goodsDetails.content" :lazy-load="true" :show-with-animation="true"></u-parse> |
|||
</view> |
|||
</view> |
|||
<!-- 底部按钮 --> |
|||
<view class="goods-footer bg-white flex"> |
|||
<button type="primary" class="right-btn flex-1 br60" :disabled="!goodsDetails.stock" @tap="toSettlement"> |
|||
立即兑换 |
|||
</button> |
|||
</view> |
|||
<!-- 悬浮按钮 --> |
|||
<float-tab></float-tab> |
|||
<!-- 规格弹窗 --> |
|||
<view class="spec-popup"> |
|||
<u-popup v-model="showSpec" mode="bottom" border-radius="14" :closeable="true" |
|||
:safe-area-inset-bottom="true"> |
|||
<view class="bg-white spec-contain"> |
|||
<view class="spec-header flex"> |
|||
<u-image width="160rpx" height="160rpx" class="m-r-20" border-radius="10rpx" |
|||
@click="previewImage(goodsDetails.image)" :src="goodsDetails.image"></u-image> |
|||
<view class="goods-info"> |
|||
<view class="primary flex"> |
|||
<price-format :first-size="38" :second-size="24" :price="goodsDetails.need_integral" |
|||
:weight="500" :show-subscript="false"> |
|||
</price-format> |
|||
<text class="xs">积分</text> |
|||
<block v-if="goodsDetails.exchange_way === 2"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :weight="500" :first-size="38" :second-size="24" |
|||
:price="goodsDetails.need_money" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
<view class="sm"> |
|||
库存:{{goodsDetails.stock}}件 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="spec-main" style="height: 400rpx;"> |
|||
<view class="good-num flex row-between m-l-20 m-r-20"> |
|||
<view class="label">数量</view> |
|||
<u-number-box :disabled="!goodsDetails.stock" v-model="count" :min="1" :max="goodsDetails.stock"> |
|||
</u-number-box> |
|||
</view> |
|||
</view> |
|||
<view class="spec-footer"> |
|||
|
|||
<button type="primary" class="right-btn flex-1 br60" :disabled="!goodsDetails.stock" @tap="toSettlement"> |
|||
立即兑换 |
|||
</button> |
|||
</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
<loading-view v-if="isFirstLoading"></loading-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getIntegralGoodsDetail |
|||
} from '@/api/activity' |
|||
export default { |
|||
data() { |
|||
return { |
|||
isFirstLoading: true, |
|||
goodsDetails: {}, |
|||
count: 1, |
|||
showSpec: false |
|||
} |
|||
}, |
|||
methods: { |
|||
// 获取商品详情 |
|||
getGoodsDetails() { |
|||
getIntegralGoodsDetail({ |
|||
id: this.id |
|||
}).then((res) => { |
|||
if (res.code == 1) { |
|||
this.goodsDetails = res.data |
|||
} |
|||
}).finally(() => { |
|||
this.isFirstLoading = false |
|||
}) |
|||
}, |
|||
// 图片预览 |
|||
previewImage(current) { |
|||
uni.previewImage({ |
|||
current, |
|||
urls: [current] // 需要预览的图片http链接列表 |
|||
}); |
|||
}, |
|||
// 前往结算页面 |
|||
toSettlement() { |
|||
this.$Router.push({ |
|||
path: '/bundle/pages/integral_settlement/integral_settlement', |
|||
query: { |
|||
id: this.id, |
|||
count: this.count |
|||
} |
|||
}) |
|||
} |
|||
|
|||
}, |
|||
onLoad() { |
|||
this.id = this.$Route.query.id |
|||
this.getGoodsDetails() |
|||
}, |
|||
onShareAppMessage() { |
|||
const { |
|||
goodsDetails |
|||
} = this; |
|||
return { |
|||
title: goodsDetails.name, |
|||
imageUrl: goodsDetails.image, |
|||
path: '/bundle/pages/integral_goods_details/integral_goods_details?id=' + this.id + "&invite_code=" + this.$store.getters.inviteCode |
|||
}; |
|||
}, |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.integral-goods-details { |
|||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
|
|||
.goods-info { |
|||
position: relative; |
|||
|
|||
.info-header { |
|||
padding: 20rpx 24rpx 0; |
|||
|
|||
.price { |
|||
align-items: baseline; |
|||
} |
|||
} |
|||
|
|||
.name { |
|||
padding: 20rpx 24rpx; |
|||
flex: 1; |
|||
} |
|||
} |
|||
|
|||
.goods-details { |
|||
|
|||
// overflow: hidden; |
|||
.details-title { |
|||
line-height: 88rpx; |
|||
text-align: center; |
|||
} |
|||
|
|||
&>.details-content { |
|||
padding: 0 20rpx 20rpx; |
|||
|
|||
::v-deep image { |
|||
vertical-align: middle; |
|||
} |
|||
|
|||
// #ifdef H5 |
|||
::v-deep img { |
|||
vertical-align: middle; |
|||
} |
|||
|
|||
// #endif |
|||
// #ifdef MP-WEIXIN || APP-PLUS |
|||
::v-deep ._img { |
|||
display: block; |
|||
} |
|||
|
|||
// #endif |
|||
} |
|||
} |
|||
|
|||
.goods-spec { |
|||
padding: 24rpx 24rpx; |
|||
|
|||
.label { |
|||
width: 100rpx; |
|||
} |
|||
} |
|||
|
|||
.goods-footer { |
|||
height: 100rpx; |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
box-sizing: content-box; |
|||
padding: 0 24rpx; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
} |
|||
|
|||
.spec-popup { |
|||
.spec-contain { |
|||
overflow: hidden; |
|||
position: relative; |
|||
|
|||
.spec-header { |
|||
padding: 30rpx; |
|||
padding-right: 70rpx; |
|||
align-items: flex-start; |
|||
border: $-solid-border; |
|||
} |
|||
|
|||
.spec-main, .spec-footer { |
|||
padding: 24rpx; |
|||
} |
|||
} |
|||
|
|||
} |
|||
.right-btn { |
|||
height: 80rpx; |
|||
line-height: 80rpx; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,265 @@ |
|||
<template> |
|||
<view class="integral-mall"> |
|||
|
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption"> |
|||
<view class="header bg-primary flex row-between white"> |
|||
<router-link to="/bundle/pages/integral_sign/integral_sign"> |
|||
<view class="user-integral flex"> |
|||
<u-icon class="m-r-16" :name="require('@/bundle/static/icon_integral.png')" :size="44"></u-icon> |
|||
我的积分:<text class="xxl bold">{{ integral }}</text> |
|||
</view> |
|||
</router-link> |
|||
<router-link to="/bundle/pages/exchange_order/exchange_order"> |
|||
兑换订单 <u-icon name="arrow-right"></u-icon> |
|||
</router-link> |
|||
</view> |
|||
<view class="main"> |
|||
<view class="sort-bar flex bg-white"> |
|||
<view class="sort-bar-item flex-2 flex row-center" v-for="(item, index) in sortConfig" :key="index" |
|||
@tap="handleSort(item)"> |
|||
<text :class="item.value ? 'primary' : ''">{{ item.name }}</text> |
|||
<view class="arrow-icon flex-col col-center row-center" v-if="!item.setValue"> |
|||
<u-icon name="arrow-up-fill" |
|||
:color="item.value == 'asc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
<u-icon name="arrow-down-fill" |
|||
:color="item.value == 'desc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
</view> |
|||
</view> |
|||
<view class="flex-1 flex row-center" @tap="changeGoodsType"> |
|||
<image class="icon-sm" |
|||
:src="goodsType === 'one' ? '/static/images/icon_double.png' : '/static/images/icon_one.png'"> |
|||
</image> |
|||
</view> |
|||
</view> |
|||
<view class="goods-lists" :class="{ |
|||
'goods-lists--one': goodsType === 'one' |
|||
}"> |
|||
<view class="goods-item" v-for="(item, index) in goodsLists" :key="index"> |
|||
<router-link :to="`/bundle/pages/integral_goods_details/integral_goods_details?id=${item.id}`"> |
|||
<view class="goods-item-info"> |
|||
<view class="goods-image"> |
|||
<view class="image-wrap"> |
|||
<u-image :src="item.image" width="100%" height="100%"></u-image> |
|||
</view> |
|||
</view> |
|||
<view class="goods-info"> |
|||
<view class="goods-name line-2"> |
|||
{{ item.name }} |
|||
</view> |
|||
<view class="goods-price primary m-t-10"> |
|||
<price-format :color="colorConfig.primary" :show-subscript="false" |
|||
:first-size="36" :second-size="24" :price="item.need_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="item.exchange_way === 2"> |
|||
<text>+</text> |
|||
<price-format :color="colorConfig.primary" :show-subscript="false" |
|||
:first-size="36" :second-size="24" :price="item.need_money" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getIntegralGoods |
|||
} from '@/api/activity' |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"; |
|||
import {trottle} from '@/utils/tools' |
|||
export default { |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
sortConfig: [{ |
|||
name: '最新', |
|||
type: 'sort_by_new', |
|||
value: 'desc', |
|||
setValue: 'desc' |
|||
}, |
|||
{ |
|||
name: '积分', |
|||
type: 'sort_by_integral', |
|||
value: '' |
|||
}, |
|||
{ |
|||
name: '兑换量', |
|||
type: 'sort_by_sales', |
|||
value: '', |
|||
setValue: 'desc' |
|||
} |
|||
], |
|||
goodsType: 'double', |
|||
upOption: { |
|||
noMoreSize: 2, |
|||
auto: false, |
|||
empty: { |
|||
icon: '/static/images/goods_null.png', |
|||
tip: "暂无商品", |
|||
} |
|||
}, |
|||
goodsLists: [], |
|||
integral: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
changeGoodsType() { |
|||
this.goodsType = this.goodsType === 'one' ? 'double' : 'one' |
|||
}, |
|||
handleSort(current) { |
|||
this.sortConfig.forEach((item) => { |
|||
if(current.type != item.type) { |
|||
item.value = '' |
|||
return |
|||
} |
|||
if(item.setValue) { |
|||
item.value = item.setValue |
|||
return |
|||
} |
|||
if(item.value == 'asc') { |
|||
item.value = 'desc' |
|||
}else{ |
|||
item.value ='asc' |
|||
} |
|||
}) |
|||
|
|||
}, |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
const sort = this.sortConfig.find((item) => item.value) || {} |
|||
getIntegralGoods({ |
|||
[sort.type]: sort.value, |
|||
page_no: pageNum, |
|||
page_size: pageSize |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
const { |
|||
goods, |
|||
integral |
|||
} = res.data |
|||
this.integral = integral |
|||
let curPageData = goods.lists; |
|||
let curPageLen = curPageData.length; |
|||
let hasNext = !!goods.more; |
|||
if (pageNum == 1) this.goodsLists = []; |
|||
this.goodsLists = this.goodsLists.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}else{ |
|||
this.mescroll.endErr(); |
|||
} |
|||
}).catch(() => { |
|||
this.mescroll.endErr(); |
|||
}) |
|||
}, |
|||
}, |
|||
watch: { |
|||
sortConfig: { |
|||
handler(val) { |
|||
this.goodsLists = [] |
|||
this.mescroll.resetUpScroll() |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
onLoad() { |
|||
this.handleSort = trottle(this.handleSort, 500, this); |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
page { |
|||
padding: 0; |
|||
} |
|||
$goods-margin: 8rpx; |
|||
|
|||
.integral-mall { |
|||
.header { |
|||
padding: 22rpx 24rpx; |
|||
} |
|||
|
|||
.main { |
|||
.sort-bar { |
|||
height: 80rpx; |
|||
|
|||
.sort-bar-item { |
|||
height: 100%; |
|||
} |
|||
|
|||
.arrow-icon { |
|||
transform: scale(0.4); |
|||
} |
|||
} |
|||
|
|||
.goods-lists { |
|||
padding: 20rpx 20rpx 0; |
|||
margin: -$goods-margin; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
.goods-item { |
|||
|
|||
width: 50%; |
|||
|
|||
.goods-item-info { |
|||
margin: $goods-margin; |
|||
border-radius: 14rpx; |
|||
background: #fff; |
|||
overflow: hidden; |
|||
|
|||
.goods-image { |
|||
flex: none; |
|||
position: relative; |
|||
height: 0; |
|||
padding-top: 100%; |
|||
|
|||
.image-wrap { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
} |
|||
} |
|||
|
|||
.goods-info { |
|||
padding: 14rpx; |
|||
|
|||
.goods-name { |
|||
line-height: 40rpx; |
|||
height: 80rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
&--one { |
|||
.goods-item { |
|||
width: 100%; |
|||
|
|||
.goods-item-info { |
|||
display: flex; |
|||
|
|||
.goods-image { |
|||
width: 200rpx; |
|||
padding-top: 200rpx; |
|||
} |
|||
|
|||
.goods-info { |
|||
padding: 24rpx 20rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,266 @@ |
|||
<template> |
|||
<view class="integral-settlement"> |
|||
<view class="settlement-main"> |
|||
<router-link to="/bundle/pages/user_address/user_address?type=1"> |
|||
<view class="address flex contain"> |
|||
<image class="icon-md m-r-20" src="/static/images/icon_address.png"></image> |
|||
<view class="flex-1 m-r-20"> |
|||
<view class="black md" v-if="!address.contact">设置收货地址</view> |
|||
<view v-else> |
|||
<text class="name md m-r-10">{{address.contact}}</text> |
|||
<text class="phone md">{{address.telephone}}</text> |
|||
<view class="area sm m-t-10 lighter"> |
|||
{{address.province}} {{address.city}} {{address.district}} {{address.address}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<u-icon name="arrow-right"></u-icon> |
|||
</view> |
|||
</router-link> |
|||
<view class="order-goods contain"> |
|||
<view class="flex goods"> |
|||
<u-image :src="goods.image" border-radius="10" width="160" height="160"></u-image> |
|||
<view class="goods-info flex-1 m-l-20"> |
|||
<view class="goods-name line-2">{{ goods.name }}</view> |
|||
<view class="flex row-between"> |
|||
<view class="goods-price primary m-t-10"> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="goods.need_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="goods.exchange_way === 2"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="goods.need_money" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
<view class="lighter">×{{orderInfo.total_num}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="buyer-message"> |
|||
<u-field v-model="remark" type="textarea" :border-bottom="false" :auto-height="false" label="买家留言" |
|||
placeholder="请添加备注(150字以内)" maxlength="150" :field-style="{ height: '240rpx' }"> |
|||
</u-field> |
|||
</view> |
|||
</view> |
|||
<view class="total-goods contain"> |
|||
<view class="flex row-between "> |
|||
<view>商品总额</view> |
|||
<view class="primary"> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderInfo.order_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="orderInfo.exchange_way === 2"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderInfo.goods_price" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<view>运费</view> |
|||
<view> |
|||
<price-format :first-size="28" :subscript-size="24" :second-size="24" |
|||
:price="orderInfo.shipping_price" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="settlement-footer bg-white flex row-between"> |
|||
<view class="all-price lg flex"> |
|||
<text>合计:</text> |
|||
<view class="primary"> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderInfo.order_integral" /> |
|||
<text class="xs">积分</text> |
|||
<block v-if="orderInfo.order_amount > 0"> |
|||
<text>+</text> |
|||
<price-format :show-subscript="false" :first-size="36" :second-size="24" |
|||
:price="orderInfo.order_amount" /> |
|||
<text class="xs">元</text> |
|||
</block> |
|||
</view> |
|||
</view> |
|||
<button type="primary" class="br60" size="md" hover-class="none" @tap="orderBuy"> |
|||
提交订单 |
|||
</button> |
|||
</view> |
|||
<loading-view v-show="showLoading" :background-color="hasBg ? '#fff' : ''"></loading-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
integralSettlement, |
|||
integralSubmitOrder |
|||
} from '@/api/activity' |
|||
export default { |
|||
data() { |
|||
return { |
|||
showLoading: true, |
|||
hasBg: true, |
|||
address: {}, |
|||
goods: {}, |
|||
orderInfo: {}, |
|||
addressId: '', |
|||
remark: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
// 订单信息 |
|||
getOrderInfo() { |
|||
integralSettlement({ |
|||
id: this.goodsId, |
|||
num: this.count, |
|||
address_id: this.addressId |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
const { |
|||
address, |
|||
goods |
|||
} = res.data |
|||
this.address = address |
|||
this.orderInfo = res.data |
|||
this.goods = goods |
|||
} |
|||
}).finally(() => { |
|||
this.showLoading = false |
|||
}) |
|||
}, |
|||
// 提交订单 |
|||
orderBuy() { |
|||
this.hasBg = false |
|||
this.showLoading = true |
|||
const address_id = this.addressId || this.address.id |
|||
integralSubmitOrder({ |
|||
id: this.goodsId, |
|||
num: this.count, |
|||
address_id, |
|||
user_remark: this.remark |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
const { |
|||
type, |
|||
order_id |
|||
} = res.data |
|||
if(!this.orderInfo.need_pay) { |
|||
this.$Router.replace({ |
|||
path: '/pages/pay_result/pay_result', |
|||
query: { |
|||
id: order_id, |
|||
from: type |
|||
} |
|||
}) |
|||
return |
|||
} |
|||
uni.$on('payment', params => { |
|||
setTimeout(() => { |
|||
if (params.result) { |
|||
this.$Router.replace({ |
|||
path: '/pages/pay_result/pay_result', |
|||
query: { |
|||
id: params.order_id, |
|||
from: params.from |
|||
} |
|||
}) |
|||
}else { |
|||
this.$Router.replace({ |
|||
path: '/bundle/pages/exchange_order/exchange_order', |
|||
query: { |
|||
id: params.order_id, |
|||
from: params.from |
|||
} |
|||
}) |
|||
} |
|||
}, 1 * 1000) |
|||
}) |
|||
this.$Router.push({ |
|||
path: '/pages/payment/payment', |
|||
query: { |
|||
order_id: order_id, |
|||
from: type |
|||
} |
|||
}) |
|||
} |
|||
}).finally(() => { |
|||
setTimeout(() => { |
|||
this.showLoading = false |
|||
}, 200) |
|||
}) |
|||
} |
|||
}, |
|||
onLoad(options) { |
|||
uni.$on("selectaddress", (e) => { |
|||
this.addressId = e.id |
|||
}) |
|||
}, |
|||
onUnload() { |
|||
uni.$off("selectaddress") |
|||
uni.$off("payment") |
|||
}, |
|||
onShow() { |
|||
const { |
|||
count, |
|||
id |
|||
} = this.$Route.query |
|||
|
|||
this.goodsId = id |
|||
this.count = count |
|||
this.getOrderInfo() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.integral-settlement { |
|||
overflow: hidden; |
|||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
|
|||
.contain { |
|||
background-color: #fff; |
|||
border-radius: 14rpx; |
|||
margin: 20rpx 20rpx 0; |
|||
} |
|||
|
|||
.settlement-main { |
|||
.address { |
|||
min-height: 164rpx; |
|||
padding: 20rpx 24rpx; |
|||
} |
|||
|
|||
.order-goods { |
|||
.goods { |
|||
padding: 30rpx 24rpx; |
|||
border-bottom: $-solid-border; |
|||
|
|||
.goods-info { |
|||
.goods-name { |
|||
line-height: 40rpx; |
|||
height: 80rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.buyer-message {} |
|||
} |
|||
|
|||
.total-goods { |
|||
padding: 20rpx 24rpx; |
|||
} |
|||
} |
|||
|
|||
.settlement-footer { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
height: 100rpx; |
|||
padding: 0 30rpx; |
|||
box-sizing: content-box; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,357 @@ |
|||
<template> |
|||
<view class="integral-sign" v-show="user.id"> |
|||
<view class="user-sgin"> |
|||
<view class="header"> |
|||
<view class="flex"> |
|||
<!-- 头像 --> |
|||
<view class="flex m-l-40"> |
|||
<u-avatar :src="user.avatar" :size="110"></u-avatar> |
|||
</view> |
|||
<!-- 积分和明细按钮 --> |
|||
<view class="m-l-30 flex row-between flex-1"> |
|||
<!-- 积分 --> |
|||
<view> |
|||
<view class="white" style="font-size: 56rpx">{{user.user_integral}}</view> |
|||
<router-link to="/bundle/pages/sign_rule/sign_rule"> |
|||
<view class="sm flex white"> |
|||
我的积分 |
|||
<image src="../../static/jifen_icon_help.png" class="m-l-10" |
|||
style="height: 30rpx; width: 30rpx;"></image> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
<!-- 明细按钮 --> |
|||
<router-link to="/bundle/pages/integral_details/integral_details"> |
|||
<view class="score-detail-entry flex"> |
|||
<image style="width: 26rpx;height: 26rpx;flex: none; margin-right: 7rpx" |
|||
src="../../static/jifen_icon_data.png"></image> |
|||
<text class="sm white">积分明细</text> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="main"> |
|||
<!-- 签到列表 --> |
|||
<view class="contain bg-white"> |
|||
<view class="title">已累积签到 {{user.days}}天</view> |
|||
<view class="day-list flex flex-wrap"> |
|||
<view v-for="(item, index) in signList" :key="index" |
|||
class="item flex-col col-center"> |
|||
<view :class="'circle flex row-center ' + (item.status == 1 ? 'active-circle' : '')"> |
|||
<view class="num xs lighter" v-if="item.status == 0">+{{item.integral}}</view> |
|||
<image class="num" src="../../static/jifen_icon_select.png" v-if="item.status == 1"> |
|||
</image> |
|||
</view> |
|||
<view class="day m-t-10 lighter sm">{{item.day}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="right-sgin"> |
|||
<button :class="'lighter br60 ' + (user.today_sign ? 'gray' : 'primary-button')" |
|||
@tap="userSignFun" size="md">{{user.today_sign ? '已签到' : '立即签到' }}</button> |
|||
</view> |
|||
</view> |
|||
<!-- 赚积分 --> |
|||
<view class="contain bg-white m-t-20" v-if="integralTips.length > 0"> |
|||
<view class="title flex"> |
|||
<view class="line br60 m-r-20"></view> |
|||
<view class="bold xl">赚积分</view> |
|||
</view> |
|||
<view class="task"> |
|||
<view v-for="(item, index) in integralTips" :key="index" class="item flex"> |
|||
<image class="img m-r-20" :src="item.image"> |
|||
</image> |
|||
<view class="con"> |
|||
<view class="md">{{item.name}}</view> |
|||
</view> |
|||
<button hover-class="none" :class="'btn br60 ' + (item.status ? 'muted' : 'primary' )" |
|||
:style="'border-color: ' + (item.status ? '#BBBBBB' : '#FF2C3C') + ';'" |
|||
size="xs">{{item.status ? '已完成' : '未完成'}}</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<u-popup v-model="showPop" mode="center"> |
|||
<view class="pop-container"> |
|||
<view class="header-score flex row-center">+{{signInfo.integral}}</view> |
|||
<view class="box column-center"> |
|||
<view class="desc m-t-20 sm flex row-center"> |
|||
<view class=""> |
|||
获得 |
|||
</view> |
|||
<image style="width: 28rpx; height: 30rpx;margin-right: 8rpx; margin-left: 8rpx" |
|||
src="../../static/icon_jifen.png"></image> |
|||
<view class=""> |
|||
{{signInfo.integral}} |
|||
</view> |
|||
<view class="m-l-20 flex" v-if="signInfo.growth"> |
|||
+ {{ signInfo.growth }}成长值 |
|||
</view> |
|||
</view> |
|||
<view class="bottom-box"> |
|||
<view class="md" style="line-height: 36rpx"> |
|||
您已累积签到 <text style="font-size: 36rpx; color: #FF2C3C;">{{signInfo.days}}</text>天 |
|||
</view> |
|||
</view> |
|||
<view class="white br60 primary-btn" style="margin-top: 26rpx" @tap="showPop = false">确定</view> |
|||
</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getSignLists, |
|||
userSignIn |
|||
} from "@/api/activity"; |
|||
import { |
|||
trottle |
|||
} from "@/utils/tools" |
|||
export default { |
|||
data() { |
|||
return { |
|||
// 用户信息 |
|||
user: { |
|||
|
|||
}, |
|||
// 签到天数列表 |
|||
signList: [], |
|||
// 每日签到 |
|||
integralTips: [], |
|||
// 显示签到结果弹窗 |
|||
showPop: false, |
|||
// 签到结果 |
|||
signInfo: { |
|||
} |
|||
}; |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.getSignListsFun() |
|||
this.userSignFun = trottle(this.userSignFun, 1000, this) |
|||
}, |
|||
|
|||
methods: { |
|||
// 获取签到数据 |
|||
getSignListsFun() { |
|||
getSignLists() |
|||
.then((res) => { |
|||
if (res.code == 1) { |
|||
const { |
|||
user, |
|||
sign_list, |
|||
integral_tips |
|||
} = res.data |
|||
this.user = user |
|||
this.signList = sign_list |
|||
this.integralTips = integral_tips |
|||
} |
|||
}).catch((err) => { |
|||
|
|||
}) |
|||
}, |
|||
// 点击签到 |
|||
userSignFun() { |
|||
if(this.user.today_sign) return |
|||
userSignIn().then((res) => { |
|||
if(res.code == 1) { |
|||
this.showPop = true; |
|||
this.signInfo = res.data |
|||
this.getSignListsFun() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.user-sgin { |
|||
padding-bottom: 100rpx; |
|||
} |
|||
|
|||
.user-sgin .header { |
|||
background-image: url(../../static/bg_sgin.png); |
|||
background-repeat: no-repeat; |
|||
background-size: 100%; |
|||
height: 400rpx; |
|||
width: 750rpx; |
|||
padding-top: 40rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.user-sgin .header .avatar { |
|||
border-radius: 50%; |
|||
border: 4rpx solid #fff; |
|||
} |
|||
|
|||
.user-sgin .main { |
|||
z-index: 100; |
|||
margin-top: -200rpx; |
|||
width: 100%; |
|||
top: 186rpx; |
|||
padding: 0 20rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.user-sgin .main .contain { |
|||
border-radius: 10rpx; |
|||
} |
|||
|
|||
.user-sgin .main .contain .title { |
|||
padding: 24rpx 30rpx; |
|||
} |
|||
|
|||
.user-sgin .main .contain .title .line { |
|||
width: 6rpx; |
|||
height: 34rpx; |
|||
background-color: #ff2c3c; |
|||
} |
|||
|
|||
.user-sgin .main .day-list { |
|||
width: 100%; |
|||
} |
|||
|
|||
.user-sgin .main .day-list .item { |
|||
width: 14.2%; |
|||
margin-bottom: 10rpx; |
|||
} |
|||
|
|||
.user-sgin .main .day-list .item .num { |
|||
width: 68rpx; |
|||
height: 68rpx; |
|||
line-height: 58rpx; |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
background-color: #f2f2f2; |
|||
} |
|||
|
|||
.user-sgin .main .day-list .item .circle { |
|||
position: relative; |
|||
} |
|||
|
|||
.user-sgin .main .day-list .item .circle::before { |
|||
content: ""; |
|||
height: 6rpx; |
|||
background-color: #f2f2f2; |
|||
width: 34rpx; |
|||
position: absolute; |
|||
right: 68rpx; |
|||
top: 34rpx; |
|||
} |
|||
|
|||
.user-sgin .main .day-list .item:nth-of-type(7n+1) .circle::before { |
|||
background-color: rgba(0, 0, 0, 0); |
|||
} |
|||
|
|||
.user-sgin .main .day-list .item .active-circle::before { |
|||
background-color: #FFBD40; |
|||
|
|||
} |
|||
|
|||
|
|||
.user-sgin .main .right-sgin { |
|||
padding: 35rpx 145rpx; |
|||
} |
|||
|
|||
.user-sgin .main .right-sgin .primary-button { |
|||
color: #fff; |
|||
background: linear-gradient(270deg, rgba(249, 95, 47, 1) 0%, rgba(252, 67, 54, 1) 55%, rgba(255, 44, 60, 1) 100%); |
|||
} |
|||
|
|||
.user-sgin .main .contain .task { |
|||
border-top: 1px solid $-color-border; |
|||
} |
|||
|
|||
.user-sgin .main .contain .task .item { |
|||
padding: 23rpx 30rpx; |
|||
} |
|||
|
|||
.user-sgin .main .contain .task .item .img { |
|||
width: 74rpx; |
|||
height: 74rpx; |
|||
border-radius: 22rpx; |
|||
} |
|||
|
|||
.user-sgin .main .contain .task .item .con { |
|||
flex: 1; |
|||
} |
|||
|
|||
.user-sgin .main .contain .task .item .btn { |
|||
width: 154rpx; |
|||
border: 1px solid #FF2C3C; |
|||
} |
|||
|
|||
.user-sgin .main .contain .task .item .con .num { |
|||
color: #FF2C3C; |
|||
} |
|||
|
|||
.user-sgin .main .contain .task .item .primary { |
|||
color: #FF2C3C; |
|||
} |
|||
|
|||
.score-detail-entry { |
|||
background-color: rgba(255, 255, 255, 0.3); |
|||
border-radius: 100rpx 0rpx 0rpx 100rpx; |
|||
padding: 12rpx 19rpx 12rpx 16rpx; |
|||
align-self: flex-end; |
|||
} |
|||
|
|||
.van-popup { |
|||
background-color: rgba(0, 0, 0, 0) !important; |
|||
} |
|||
|
|||
.pop-container { |
|||
background-repeat: no-repeat; |
|||
background-size: 100%; |
|||
height: 626rpx; |
|||
width: 560rpx; |
|||
position: relative; |
|||
background-image: url('../../static/jifen_popBg.png'); |
|||
} |
|||
|
|||
.u-mode-center-box { |
|||
background-color: rgba(0, 0, 0, 0) !important; |
|||
} |
|||
|
|||
.header-score { |
|||
font-size: 46rpx; |
|||
line-height: 36rpx; |
|||
font-weight: bold; |
|||
padding-top: 90rpx; |
|||
padding-bottom: 150rpx; |
|||
// color: #FF2C3C; |
|||
color: #FF8412; |
|||
} |
|||
|
|||
.desc { |
|||
color: white; |
|||
background: linear-gradient(82deg, rgba(250, 81, 50, 1) 0%, rgba(236, 60, 34, 1) 49%, rgba(250, 83, 50, 1) 100%); |
|||
padding: 16rpx 22rpx 16rpx 42rpx; |
|||
text-align: center; |
|||
} |
|||
|
|||
|
|||
.bottom-box { |
|||
margin-top: 84rpx; |
|||
text-align: center; |
|||
} |
|||
|
|||
.primary-btn { |
|||
margin: 0 60rpx; |
|||
width: 440rpx; |
|||
height: 74rpx; |
|||
border-radius: 37rpx; |
|||
padding: 16rpx 190rpx; |
|||
// background: linear-gradient(#f95f2f 0%, #ff2c3c 100%); |
|||
background: linear-gradient(#f95f2f 0%, #ff2c3c 100%); |
|||
} |
|||
|
|||
.gray { |
|||
background-color: #f2f2f2 !important; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,160 @@ |
|||
<template> |
|||
<view class="pages"> |
|||
<view class="invite-fans flex-col col-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 flex-1"> |
|||
<view class="m-b-40"> |
|||
<view class="m-b-10 sm lighter">我的邀请码</view> |
|||
<view class="flex row-between"> |
|||
<view class="font-size-44">{{inviteCode}}</view> |
|||
<view class="sm m-r-30 copy-btn" @tap="onCopy(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 |
|||
} from '@/api/app' |
|||
import { |
|||
baseURL, |
|||
basePath |
|||
} from '@/config/app' |
|||
import { |
|||
mapGetters |
|||
} from 'vuex' |
|||
|
|||
import { |
|||
apiDistributionPoster |
|||
} from '@/api/user' |
|||
import { |
|||
copy |
|||
} from '@/utils/tools.js' |
|||
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: { |
|||
onCopy(text) { |
|||
copy(text) |
|||
}, |
|||
async getPoster() { |
|||
const res = await apiDistributionPoster() |
|||
this.poster = res.data.poster |
|||
}, |
|||
getMnpQrCode() { |
|||
apiMnpQrCode({ |
|||
type: 0, |
|||
url: 'pages/index/index' |
|||
}).then(res => { |
|||
console.log(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> |
|||
@ -0,0 +1,379 @@ |
|||
<template> |
|||
<view class="invoice"> |
|||
<view class="box bg-white"> |
|||
|
|||
<!-- 发票类型 --> |
|||
<view class="item flex row-between" @click="handleOpenInvoiceType"> |
|||
<view class="label">发票类型</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<text>{{ type == 0 ? '增值税电子普通发票' : '增值税专用发票' }}</text> |
|||
<u-icon name="arrow-right" size="22" v-if="formData.header_type == 1"></u-icon> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 抬头类型 --> |
|||
<view class="item flex row-between"> |
|||
<view class="label">抬头类型</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-radio-group v-model="formData.header_type"> |
|||
<u-radio v-for="(item, index) in list" :key="index" :name="item.header_type" |
|||
:disabled="item.disabled" :active-color="colorConfig.primary"> |
|||
{{item.name}} |
|||
</u-radio> |
|||
</u-radio-group> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 发票抬头 --> |
|||
<view class="item flex row-between"> |
|||
<view class="label">发票抬头</view> |
|||
<view class="content"> |
|||
<u-input v-model="formData.name" input-align="right" placeholder="填写需要开具发票的姓名" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 税号 --> |
|||
<view class="item flex row-between" v-show="formData.header_type === 1"> |
|||
<view class="label">税号</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-input v-model="formData.duty_number" input-align="right" placeholder="纳税人识别号" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 邮箱 --> |
|||
<view class="item flex row-between"> |
|||
<view class="label">邮箱</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-input v-model="formData.email" input-align="right" placeholder="您的联系邮箱" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 企业地址 --> |
|||
<view class="item flex row-between" v-show="type == 1 && formData.header_type == 1"> |
|||
<view class="label">企业地址</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-input v-model="formData.address" input-align="right" placeholder="必填" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 企业电话 --> |
|||
<view class="item flex row-between" v-show="type == 1 && formData.header_type == 1"> |
|||
<view class="label">企业电话</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-input v-model="formData.mobile" input-align="right" placeholder="必填" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 开户银行 --> |
|||
<view class="item flex row-between" v-show="type == 1 && formData.header_type == 1"> |
|||
<view class="label">开户银行</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-input v-model="formData.bank" input-align="right" placeholder="必填" /> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 银行账号 --> |
|||
<view class="item flex row-between" v-show="type == 1 && formData.header_type == 1"> |
|||
<view class="label">银行账号</view> |
|||
<view class="content flex-1 flex row-right"> |
|||
<u-input v-model="formData.bank_account" input-align="right" placeholder="必填" /> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
|
|||
<view class="footer"> |
|||
<view class="" v-if="order_id && shop_id"> |
|||
<button class="submit-btn br60 white btn" size="lg" @click="handleInvoiceAdd">提交申请</button> |
|||
</view> |
|||
<view class="" v-if="invoice_id && shop_id"> |
|||
<button class="submit-btn br60 white btn" size="lg" @click="handleInvoiceEdit">提交编辑</button> |
|||
</view> |
|||
<view class="" v-if="shop_id && !invoice_id && !order_id"> |
|||
<button class="submit-btn br60 white btn" size="lg" @click="handleConfirm">确定</button> |
|||
</view> |
|||
<view class="m-t-40"> |
|||
<button class="cancel-btn br60 white btn" size="lg" @click="handleCancel">不开发票</button> |
|||
</view> |
|||
</view> |
|||
|
|||
|
|||
<!-- 发票类型选择 --> |
|||
<u-popup v-model="showCoupon" border-radius="14" mode="bottom" closeable :safe-area-inset-bottom="true" @open="type=formData.type" @close="handleCloseInvoiceType"> |
|||
<view class="p-30 bg-body"> |
|||
<view class="text-center">发票类型选择</view> |
|||
</view> |
|||
<view class="invoice-type bg-body"> |
|||
<!-- 普票 --> |
|||
<view class="invoice-type--item bg-white flex row-between" @click="type=0"> |
|||
<view> |
|||
<view class="nr black">增值税电子普通发票</view> |
|||
<view class="xs lighter m-t-14">默认发送至所提供的电子邮件</view> |
|||
</view> |
|||
<u-checkbox :value="type==0" shape="circle" |
|||
name="0"></u-checkbox> |
|||
</view> |
|||
<!-- 专票 --> |
|||
<view class="invoice-type--item bg-white flex row-between" @click="type=1" v-show="spec_invoice"> |
|||
<view> |
|||
<view class="nr black">增值税专用发票</view> |
|||
<view class="xs lighter m-t-14">纸质发票开出后将以邮寄形式交付</view> |
|||
</view> |
|||
<u-checkbox :value="type==1" shape="circle" |
|||
name="1"></u-checkbox> |
|||
</view> |
|||
<!-- 底部确认按钮 --> |
|||
<view class="invoice-type-confirm-btn"> |
|||
<button class="confirm br60 white btn" size="lg" @click="handleChoise">确定</button> |
|||
</view> |
|||
</view> |
|||
</u-popup> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getInvoiceSetting, |
|||
apiInvoiceAdd, |
|||
apiInvoiceEdit, |
|||
apiInvoiceDetail |
|||
} from "@/api/shop.js" |
|||
import { invoiceType } from "@/utils/type.js" |
|||
export default { |
|||
data() { |
|||
return { |
|||
shop_id: '', // 商家ID |
|||
invoice_id: '', // 发票ID (编辑时 |
|||
order_id: '', // 订单ID (添加时 |
|||
showCoupon: false, |
|||
list: [{ |
|||
name: '个人', |
|||
header_type: 0, |
|||
disabled: false |
|||
}, |
|||
{ |
|||
name: '企业', |
|||
header_type: 1, |
|||
disabled: false |
|||
} |
|||
], |
|||
formData: { |
|||
id: '', // 必填 int 发票id |
|||
order_id: '', // 必填 int 订单id |
|||
type: 0, // 必填 int 发票类型 0-普通 1-专用 |
|||
header_type: 0, // 必填 int 抬头类型 0-个人 1-企业 |
|||
name: '', // 必填 string 抬头名称 |
|||
duty_number: '',// 否 string 税号 |
|||
email: '', // 否 string 邮箱 |
|||
mobile: '', // 否 string 企业电话 |
|||
address: '', // 否 string 企业地址 |
|||
bank: '', // 否 string 开户行 |
|||
bank_account: ''// 否 string 银行账号 |
|||
}, |
|||
type: 0, // |
|||
open_invoice: 0, // 发票开关 0- 关闭 1-开启 |
|||
spec_invoice: 0 // 是否支持专票 0-不支持 1-支持 |
|||
}; |
|||
}, |
|||
methods: { |
|||
// 初始化发票 |
|||
initInvoiceSetting() { |
|||
getInvoiceSetting({ |
|||
shop_id: this.shop_id, |
|||
}).then(res => { |
|||
this.spec_invoice = res.data.spec_invoice |
|||
if ( res.data.open_invoice ) this.open_invoice = res.data.open_invoice |
|||
else this.$toast({ title: '当前店铺暂未开启发票' }) |
|||
}) |
|||
}, |
|||
// 获取发票详情 |
|||
getInvoiceDetail() { |
|||
apiInvoiceDetail({ id: this.invoice_id }).then(res => { |
|||
for (const key in res.data) { |
|||
if (!this.formData.hasOwnProperty(key)) continue |
|||
this.formData[key] = res.data[key] |
|||
} |
|||
}) |
|||
}, |
|||
initRules() { |
|||
const form = this.formData |
|||
if(!this.open_invoice) { |
|||
this.$toast({title: '当前店铺暂未开启发票'}) |
|||
return false |
|||
} |
|||
if(!form.name) { |
|||
this.$toast({title: '请输入发票抬头'}) |
|||
return false |
|||
} |
|||
if(!form.duty_number && form.header_type == 1) { |
|||
this.$toast({title: '请输入税号'}) |
|||
return false |
|||
} |
|||
if(!form.email) { |
|||
this.$toast({title: '请输入邮箱地址'}) |
|||
return false |
|||
} |
|||
if(!/^[0-9a-zA-Z_.-]+[@][0-9a-zA-Z_.-]+([.][a-zA-Z]+){1,2}$/.test(form.email)) { |
|||
this.$toast({title: '邮箱输入有误,请重新输入'}) |
|||
return false |
|||
} |
|||
if(!form.address && form.header_type == 1 && form.type == 1) { |
|||
this.$toast({title: '请输入企业地址'}) |
|||
return false |
|||
} |
|||
if(!form.mobile && form.type == 1) { |
|||
this.$toast({title: '请输入手机号码'}) |
|||
return false |
|||
} |
|||
if(!form.bank && form.header_type == 1 && form.type == 1) { |
|||
this.$toast({title: '请输入开户银行'}) |
|||
return false |
|||
} |
|||
if(!form.bank_account && form.header_type == 1 && form.type == 1) { |
|||
this.$toast({title: '请输入银行账号'}) |
|||
return false |
|||
} |
|||
return true |
|||
}, |
|||
// 打开发票类型选择 |
|||
handleOpenInvoiceType() { |
|||
if( this.formData.header_type == 0 ) return |
|||
this.showCoupon=true |
|||
}, |
|||
// 关闭发票类型选择 |
|||
handleCloseInvoiceType() { |
|||
if( this.type != this.formData.type ) { |
|||
this.type = this.type == 1 ? 0 : 1 |
|||
} |
|||
}, |
|||
// 选择发票类型 |
|||
handleChoise() { |
|||
this.formData.type = this.type |
|||
this.showCoupon = false |
|||
}, |
|||
// 确定发票(订单下单时 |
|||
handleConfirm() { |
|||
if(!this.initRules()) return |
|||
uni.$emit('invoice', {...this.formData, shop_id: this.shop_id}); |
|||
uni.navigateBack() |
|||
}, |
|||
// 确认添加 |
|||
handleInvoiceAdd() { |
|||
if(!this.initRules()) return |
|||
apiInvoiceAdd({...this.formData, order_id: this.order_id}).then(res => { |
|||
if(res.code == 1) { |
|||
setTimeout(() => { |
|||
uni.navigateBack() |
|||
}, 500) |
|||
} |
|||
}) |
|||
}, |
|||
// 确认编辑 |
|||
handleInvoiceEdit() { |
|||
if(!this.initRules()) return |
|||
apiInvoiceEdit({...this.formData}).then(res => { |
|||
if(res.code == 1) { |
|||
setTimeout(() => { |
|||
uni.navigateBack() |
|||
}, 500) |
|||
} |
|||
}) |
|||
}, |
|||
// 不开发票 |
|||
handleCancel() { |
|||
if ( !this.order_id && !this.invoice_id ) { |
|||
uni.$emit('invoice', {del: true, shop_id: this.shop_id}); |
|||
} |
|||
uni.navigateBack() |
|||
} |
|||
}, |
|||
|
|||
onLoad() { |
|||
const query = this.$Route.query; |
|||
switch (query.type * 1) { |
|||
case invoiceType['SETTLEMENT']: |
|||
this.shop_id = query.shop_id || '' |
|||
if( query.invoice != '{}') { |
|||
this.formData = JSON.parse(query.invoice) |
|||
this.type = this.formData.type |
|||
} |
|||
break; |
|||
case invoiceType['ORDERDETAILEdit']: |
|||
this.invoice_id = query.invoice_id || '' |
|||
this.shop_id = query.shop_id || '' |
|||
this.getInvoiceDetail() |
|||
break; |
|||
case invoiceType['ORDERDETAILADD']: |
|||
this.order_id = query.order_id || '' |
|||
this.shop_id = query.shop_id || '' |
|||
break; |
|||
} |
|||
// 初始化发票 |
|||
this.initInvoiceSetting() |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.invoice { |
|||
height: calc(100vh - env(safe-area-inset-bottom)); |
|||
padding: 24rpx; |
|||
position: relative; |
|||
|
|||
.box { |
|||
padding: 20rpx 0; |
|||
border-radius: 16rpx; |
|||
|
|||
.item { |
|||
padding: 16rpx 30rpx; |
|||
|
|||
.label { |
|||
font-size: 28rpx; |
|||
color: $-color-black; |
|||
} |
|||
|
|||
.content { |
|||
min-width: 440rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.footer { |
|||
left: 0; |
|||
bottom: 0; |
|||
width: 100%; |
|||
padding: 24rpx; |
|||
position: absolute; |
|||
.btn { |
|||
height: 88rpx; |
|||
} |
|||
.submit-btn { |
|||
color: $-color-white; |
|||
background-color: #E39B37; |
|||
} |
|||
.cancel-btn { |
|||
color: #E39B37; |
|||
background-color: $-color-white; |
|||
} |
|||
} |
|||
|
|||
.invoice-type { |
|||
padding: 40rpx; |
|||
padding-bottom: 0; |
|||
|
|||
.invoice-type--item { |
|||
padding: 28rpx 36rpx; |
|||
border-radius: 40rpx; |
|||
margin-bottom: 30rpx; |
|||
} |
|||
|
|||
.invoice-type-confirm-btn { |
|||
padding: 90rpx 0 50rpx 0; |
|||
|
|||
.confirm { |
|||
background-color: #FF9E1E; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,212 @@ |
|||
<template> |
|||
<view class="invoice-detail"> |
|||
|
|||
<!-- Header Start --> |
|||
<view class="header white text-center flex-col row-center"> |
|||
<view class="flex row-center lg bold"> |
|||
<image v-if="!invoiceInfo.status" src="../../static/invoice_wait.png" mode=""></image> |
|||
<image v-else src="../../static/invoice_success.png" mode=""></image> |
|||
{{ invoiceInfo.status_text || '' }} |
|||
</view> |
|||
<view class="sm m-t-10" v-if="!invoiceInfo.status">正在开具发票中,请耐心等候…</view> |
|||
<view class="sm m-t-10" v-else>已开发票金额:{{ invoiceInfo.invoice_amount }}</view> |
|||
</view> |
|||
<!-- Header End --> |
|||
|
|||
<!-- Main Start --> |
|||
<view class="main"> |
|||
<view class="card bg-white"> |
|||
<view class="lg bold p-l-30 p-b-18">发票信息</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">发票金额</view> |
|||
<view class="content">{{ invoiceInfo.invoice_amount || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">发票类型</view> |
|||
<view class="content">{{ invoiceInfo.type == 0 ? '普通' : '专用' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">抬头类型</view> |
|||
<view class="content">{{ invoiceInfo.header_type_text }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">抬头名称</view> |
|||
<view class="content">{{ invoiceInfo.name || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item" v-if="invoiceInfo.duty_number"> |
|||
<view class="label">税号</view> |
|||
<view class="content">{{ invoiceInfo.duty_number || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">邮箱</view> |
|||
<view class="content">{{ invoiceInfo.email || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item" v-if="invoiceInfo.address"> |
|||
<view class="label">企业地址</view> |
|||
<view class="content">{{ invoiceInfo.address || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item" v-if="invoiceInfo.mobile"> |
|||
<view class="label">企业电话</view> |
|||
<view class="content">{{ invoiceInfo.mobile || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item" v-if="invoiceInfo.bank"> |
|||
<view class="label">开户银行</view> |
|||
<view class="content">{{ invoiceInfo.bank || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item" v-if="invoiceInfo.bank_account"> |
|||
<view class="label">银行账号</view> |
|||
<view class="content">{{ invoiceInfo.bank_account || '' }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">申请时间</view> |
|||
<view class="content">{{ invoiceInfo.create_time || '' }}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="card bg-white m-t-20"> |
|||
<view class="m-l-20"> |
|||
<shop-title :shop="shopInfo" :is-link="false"></shop-title> |
|||
</view> |
|||
<order-goods :list="goodsInfo"></order-goods> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">订单状态</view> |
|||
<view class="content">{{ order_status_text }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">订单编号</view> |
|||
<view class="content">{{ order_sn }}</view> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<view class="label">下单时间</view> |
|||
<view class="content">{{ create_time }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- Main End --> |
|||
|
|||
<!-- Footer Start --> |
|||
<view class="footer" v-if="!invoiceInfo.status"> |
|||
<view class="btn br60"> |
|||
<button class="btn br60" size="lg" @click="toEditInvoice">编辑发票</button> |
|||
</view> |
|||
</view> |
|||
<!-- Footer End --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { apiOrderInvoiceDetail } from "@/api/shop.js" |
|||
import { invoiceType } from "@/utils/type.js" |
|||
export default { |
|||
data() { |
|||
return { |
|||
invoiceInfo: {},// 发票信息 |
|||
goodsInfo: {}, // 商品信息 |
|||
shopInfo: {}, // 店铺信息 |
|||
orderId: '', // 订单ID |
|||
create_time: '', |
|||
order_status_text: '', |
|||
order_sn: '' |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
// 获取订单发票详情 |
|||
initInvoiceInfoFunc() { |
|||
apiOrderInvoiceDetail({ id: this.orderId }).then(res => { |
|||
this.invoiceInfo = res.data.invoice; |
|||
this.goodsInfo = res.data.order_goods; |
|||
this.shopInfo = res.data.shop; |
|||
this.create_time = res.data.create_time; |
|||
this.order_status_text = res.data.order_status_text; |
|||
this.order_sn = res.data.order_sn; |
|||
}) |
|||
}, |
|||
// 去编辑发票 |
|||
toEditInvoice() { |
|||
this.$Router.push({ |
|||
path: '/bundle/pages/invoice/invoice', |
|||
query: { |
|||
invoice_id: this.invoiceInfo.id, |
|||
shop_id: this.shopInfo.id, |
|||
type: invoiceType['ORDERDETAILEdit'] |
|||
} |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
onLoad() { |
|||
const query = this.$Route.query; |
|||
this.orderId = query.id || '' |
|||
}, |
|||
|
|||
onShow() { |
|||
this.initInvoiceInfoFunc(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.invoice-detail { |
|||
padding-bottom: 120rpx; |
|||
background: linear-gradient(to bottom, $-color-primary 230rpx, transparent 0); |
|||
|
|||
.header { |
|||
height: 140rpx; |
|||
image { |
|||
width: 44rpx; |
|||
height: 44rpx; |
|||
} |
|||
} |
|||
|
|||
.main { |
|||
.card { |
|||
padding: 24rpx 0 30rpx 0; |
|||
border-radius: 14rpx; |
|||
} |
|||
|
|||
.form-item { |
|||
display: flex; |
|||
padding: 12rpx 30rpx; |
|||
color: $-color-normal; |
|||
font-size: 28rpx; |
|||
|
|||
.label { |
|||
width: 120rpx; |
|||
text-align: right; |
|||
margin-right: 40rpx; |
|||
} |
|||
.content { |
|||
flex: 1; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.footer { |
|||
left: 0; |
|||
bottom: 20rpx; |
|||
width: 100%; |
|||
padding: 24rpx; |
|||
position: fixed; |
|||
.btn { |
|||
height: 88rpx; |
|||
color: $-color-white; |
|||
background-color: $-color-primary; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,72 @@ |
|||
<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(id) { |
|||
getCopyright({shop_id: id}).then(res => { |
|||
this.images = res.data |
|||
}) |
|||
}, |
|||
|
|||
viewImage(current) { |
|||
uni.previewImage({ |
|||
current, |
|||
urls: this.images// 需要预览的图片http链接列表 |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
onLoad() { |
|||
const id = this.$Route.query.id; |
|||
this.getCopyrightFunc(id) |
|||
} |
|||
} |
|||
</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,102 @@ |
|||
<template> |
|||
<view class="month-bill"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" |
|||
:up="upOption"> |
|||
<view v-for="(item, index) in orderList" :key="index"> |
|||
<view class="bill-time flex sm"> |
|||
{{item.date}} |
|||
</view> |
|||
<view class="show-panel flex"> |
|||
<view class="panel-item flex-col col-center"> |
|||
<price-format :price="item.total_money" :subscript-size="26" :color="colorConfig.primary" |
|||
:first-size="36" :second-size="36" /> |
|||
<view class="lighter label m-t-10">预估收入</view> |
|||
</view> |
|||
<view class="panel-item flex-col col-center"> |
|||
<view class="xxl">{{item.order_num}}</view> |
|||
<view class="lighter label m-t-10">成交笔数</view> |
|||
</view> |
|||
<view class="panel-item flex-col col-center"> |
|||
<router-link :to="{path: '/bundle/pages/monthly_bill_detail/monthly_bill_detail', query: {year: item.year, month: item.month}}"> |
|||
<view class="flex lighter"> |
|||
查看详情 |
|||
<u-icon name="arrow-right" size="28rpx" color="#666666" /> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getMonthBill |
|||
} from "@/api/user"; |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"; |
|||
export default { |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
orderList: [], |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无数据~', // 提示 |
|||
} |
|||
}, |
|||
}; |
|||
}, |
|||
|
|||
onLoad: function(options) { |
|||
|
|||
}, |
|||
|
|||
methods: { |
|||
upCallback(page) { |
|||
let pageNum = page.num; // 页码, 默认从1开始 |
|||
let pageSize = page.size; // 页长, 默认每页10条 |
|||
getMonthBill({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.orderList = []; |
|||
let curPageData = data.list; |
|||
let curPageLen = curPageData.length; |
|||
let hasNext = !!data.more; |
|||
this.orderList = this.orderList.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.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,156 @@ |
|||
<template> |
|||
<view class="monthly-bill-detail"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" |
|||
:up="upOption"> |
|||
<view class="content"> |
|||
<view class="order-container"> |
|||
<view v-for="(item, index) in orderList" :key="index" class="order-item bg-white m-t-20"> |
|||
<view class="order-header flex row-between"> |
|||
<view>订单编号:{{item.order_sn}}</view> |
|||
</view> |
|||
<view class="order-content flex"> |
|||
<view> |
|||
<u-image width="180rpx" height="180rpx" border-radius="6px" :src="item.goods_image" /> |
|||
</view> |
|||
<view class="order-goods-info flex-1 m-l-20"> |
|||
<view class="name sm line-2">{{item.goods_name}}</view> |
|||
<view class="flex row-between m-t-6"> |
|||
<view class="xs muted"> |
|||
<text class="m-r-10"> |
|||
数量 |
|||
</text> |
|||
<text class="normal nr">{{item.goods_num}}</text></view> |
|||
<view class="xs"> |
|||
<text class="muted m-r-10">付款金额</text> |
|||
<price-format :subscript-size="28" :first-size="28" :second-size="28" |
|||
:price="item.pay_price" /> |
|||
</view> |
|||
</view> |
|||
<view class="pre-income muted sm m-t-10"> |
|||
<text class="m-r-10">预估收益</text> |
|||
<price-format :subscript-size="28" :first-size="28" :second-size="28" |
|||
:color="colorConfig.primary" :price="item.money" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="order-footer flex row-between"> |
|||
<view class="time muted">{{item.create_time}}</view> |
|||
<view class="static sm" :style="'color: ' + (item.status == 1 ? '#F95F2F' : '#07CE1B')"> |
|||
{{item.statusDesc}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<u-select v-model="showPop" :list="months" mode="single-column" @confirm="changeMonths"></u-select> |
|||
</mescroll-body> |
|||
</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 { |
|||
getMonthOrderDetail |
|||
} from "@/api/user"; |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"; |
|||
|
|||
export default { |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
orderList: [], |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无数据~', // 提示 |
|||
} |
|||
}, |
|||
}; |
|||
}, |
|||
|
|||
onLoad() { |
|||
const {month, year} = this.$Route.query |
|||
this.year = year; |
|||
this.month = Number(month) |
|||
uni.setNavigationBarTitle({ |
|||
title: this.month + '月账单明细' |
|||
}) |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
upCallback(page) { |
|||
let pageNum = page.num; // 页码, 默认从1开始 |
|||
let pageSize = page.size; // 页长, 默认每页10条 |
|||
let { |
|||
year, |
|||
month |
|||
} = this; |
|||
getMonthOrderDetail({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
year: year, |
|||
month: month |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.orderList = []; |
|||
let curPageData = data.list; |
|||
let curPageLen = curPageData.length; |
|||
let hasNext = !!data.more; |
|||
this.orderList = this.orderList.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
}, |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
|
|||
.monthly-bill-detail .content { |
|||
padding: 0 20rpx; |
|||
.order-item { |
|||
border-radius: 14rpx; |
|||
.order-header { |
|||
padding: 20rpx 30rpx; |
|||
border-bottom: $-solid-border; |
|||
.guide-shop-btn { |
|||
background: linear-gradient(80deg, #F95F2F 0%, #FF2C3C 100%); |
|||
border-radius: 4rpx; |
|||
width: 134rpx; |
|||
height: 42rpx; |
|||
} |
|||
} |
|||
.order-content { |
|||
padding: 20rpx 30rpx 20rpx 20rpx; |
|||
border-bottom: $-solid-border; |
|||
} |
|||
.order-footer { |
|||
padding: 20rpx 30rpx 20rpx 20rpx; |
|||
.static { |
|||
color: #F95F2F; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
|||
@ -0,0 +1,553 @@ |
|||
<template> |
|||
<view> |
|||
<view class="order-details"> |
|||
<view class="header-bg"></view> |
|||
<view class="main"> |
|||
<view class="header"> |
|||
<view class="item" v-if="orderDetail.order_status == 0"> |
|||
<view class="white lg m-b-10">等待买家付款</view> |
|||
<view class="white sm flex" v-if="cancelTime > 0">支付剩余 <u-count-down separator="zh" |
|||
:timestamp="cancelTime" separator-color="#fff" color="#fff" :separator-size="26" |
|||
:font-size="26" bg-color="transparent" @end="getOrderDetailFun"></u-count-down> 自动关闭 |
|||
</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 1 && !orderDetail.pickup_code"> |
|||
<view class="white lg m-b-10">等待商家发货</view> |
|||
<view class="white sm">您的商品正在打包中,请耐心等待…</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 1 && orderDetail.pickup_code"> |
|||
<view class="white lg m-b-10">待取货</view> |
|||
<view class="white sm">请前往门店取货</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 2"> |
|||
<view class="white lg m-b-10">已发货</view> |
|||
<view class="white sm">您的商品正在路中,请耐心等待…</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 3"> |
|||
<view class="white lg m-b-10">已完成</view> |
|||
<view class="white sm">商品已签收,期待再次购买!</view> |
|||
</view> |
|||
<view class="item" v-if="orderDetail.order_status == 4"> |
|||
<view class="white lg m-b-10">订单已关闭</view> |
|||
<!-- <view class="white sm">原因:超时未支付</view> --> |
|||
</view> |
|||
</view> |
|||
<view class="address-wrap flex contain"> |
|||
<image class="icon-md m-r-20" src="/static/images/icon_address.png"></image> |
|||
<view class="address"> |
|||
<view> |
|||
<text class="name md m-r-10">{{orderDetail.consignee}}</text> |
|||
<text class="phone md">{{orderDetail.mobile}}</text> |
|||
<view class="area sm m-t-10 lighter">{{orderDetail.delivery_address}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="order-info contain" v-if="team.status_text"> |
|||
<view class="item flex" style="align-items: flex-start;"> |
|||
<view class="title">拼购状态</view> |
|||
<view class="bt">{{team.status_text}}</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="goods contain"> |
|||
<view class="m-l-20"> |
|||
<shop-title :shop="orderDetail.shop"></shop-title> |
|||
</view> |
|||
|
|||
<order-goods :team="team" :link="true" :isJumpGoods="true" :list="orderDetail.order_goods"></order-goods> |
|||
</view> |
|||
|
|||
<!-- 虚拟发货内容 --> |
|||
<template v-if="orderDetail.delivery_content"> |
|||
<view class="order-info contain" @click="copy(orderDetail.delivery_content)"> |
|||
<view class="item"> |
|||
<view class="black" style="word-break: break-all;">{{orderDetail.delivery_content || '无'}}</view> |
|||
<view class="flex row-right m-t-30"> |
|||
<view class="copy-btn">复制</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<!-- 扫码收货 --> |
|||
<view v-if="orderDetail.delivery_type == 2 " class="contain receive"> |
|||
<!-- <view v-if="orderDetail.verification_status" class="delivery--die"> |
|||
<u-image src="/static/images/delivery_die.png" width="134" height="98" mode="scaleFill" /> |
|||
</view> |
|||
--> |
|||
|
|||
<view class="receive-qr" v-if="orderDetail.show_pickup_code"> |
|||
<text class="xs lighter">请凭二维码取货</text> |
|||
<view class="m-t-20 qr-contain" :class="{'qr-contain--die': orderDetail.verification_status}" ref="qr-image"> |
|||
<tki-qrcode |
|||
ref="qrcode" |
|||
uni="px" |
|||
:val="orderDetail.pickup_code" |
|||
:size="118 * 2" |
|||
:showLoading="false" |
|||
/> |
|||
</view> |
|||
<view class="m-t-30 xs black qr-code">提货码:{{ orderDetail.pickup_code }}</view> |
|||
</view> |
|||
|
|||
<view class="p-30 flex col-top"> |
|||
<view style="width: 140rpx;" class="bold">店铺地址: </view> |
|||
<view style="width: 500rpx;"> |
|||
{{ orderDetail.shop_address }} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="price contain"> |
|||
<view class="flex row-between"> |
|||
<view>商品金额</view> |
|||
<view class="black"> |
|||
<price-format :price="orderDetail.goods_price"></price-format> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between"> |
|||
<view>运费</view> |
|||
<view class="black">+ |
|||
<price-format :price="orderDetail.shipping_price"></price-format> |
|||
</view> |
|||
</view> |
|||
<view v-if="orderDetail.discount_amount != 0" class="flex row-between"> |
|||
<view>优惠券</view> |
|||
<view class="primary">- |
|||
<price-format :price="orderDetail.discount_amount"></price-format> |
|||
</view> |
|||
</view> |
|||
<view v-if="orderDetail.member_amount" class="flex row-between"> |
|||
<view>会员抵扣</view> |
|||
<view class="primary">- |
|||
<price-format :price="orderDetail.member_amount"></price-format> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-right"> |
|||
<view class="lighter">实付金额:</view> |
|||
<view class="primary xl"> |
|||
<price-format weight="500" :first-size="34" :second-size="34" |
|||
:price="orderDetail.order_amount"></price-format> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="order-info contain"> |
|||
<view class="item flex" style="align-items: flex-start;"> |
|||
<view class="title">买家留言</view> |
|||
<view class="black">{{orderDetail.user_remark || '无'}}</view> |
|||
</view> |
|||
</view> |
|||
<view class="order-info contain"> |
|||
<view class="item flex"> |
|||
<view class="title">订单编号</view> |
|||
<view class="black">{{orderDetail.order_sn}}</view> |
|||
</view> |
|||
<view class="item flex"> |
|||
<view class="title">订单类型</view> |
|||
<view class="black">{{orderDetail.order_type}}</view> |
|||
</view> |
|||
<view class="item flex"> |
|||
<view class="title">支付方式</view> |
|||
<view class="black">{{orderDetail.pay_way}}</view> |
|||
</view> |
|||
<view class="item flex"> |
|||
<view class="title">下单时间</view> |
|||
<view class="black">{{orderDetail.create_time}}</view> |
|||
</view> |
|||
<view v-if="orderDetail.pay_time" class="item flex"> |
|||
<view class="title">付款时间</view> |
|||
<view class="black">{{orderDetail.pay_time}}</view> |
|||
</view> |
|||
<view v-if="orderDetail.shipping_time" class="item flex"> |
|||
<view class="title">发货时间</view> |
|||
<view class="black">{{orderDetail.shipping_time }}</view> |
|||
</view> |
|||
<view v-if="orderDetail.confirm_take_time" class="item flex"> |
|||
<view class="title">成交时间</view> |
|||
<view class="black">{{orderDetail.confirm_take_time }}</view> |
|||
</view> |
|||
<view v-if="orderDetail.cancel_time" class="item flex"> |
|||
<view class="title">关闭时间</view> |
|||
<view class="black">{{orderDetail.cancel_time}}</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="footer bg-white flex fixed row-right" |
|||
v-if="orderDetail.cancel_btn || orderDetail.delivery_btn || orderDetail.take_btn || orderDetail.del_btn || orderDetail.pay_btn || orderDetail.view_invoice_btn || orderDetail.save_invoice_btn"> |
|||
<!-- 左侧更多 --> |
|||
<!-- <view class="more"> |
|||
<view class="flex" v-if="orderDetail.view_invoice_btn || orderDetail.save_invoice_btn" @click="moreStatus=!moreStatus"> |
|||
<text class="m-r-10">更多</text> |
|||
<u-icon name="arrow-up" size="22"></u-icon> |
|||
</view> |
|||
|
|||
<view class="more-container bg-white" v-show="moreStatus"> |
|||
<navigator v-if="orderDetail.view_invoice_btn" hover-class="none" |
|||
:url="'/bundle/pages/invoice_detail/invoice_detail?id=' + orderDetail.id"> |
|||
<view class="more-item" >查看发票</view> |
|||
</navigator> |
|||
|
|||
<navigator v-if="orderDetail.save_invoice_btn" hover-class="none" |
|||
:url="'/bundle/pages/invoice/invoice?shop_id=' + orderDetail.shop.id + '&order_id=' + orderDetail.id + '&type=' + invoiceType"> |
|||
<view class="more-item">申请开票</view> |
|||
</navigator> |
|||
</view> |
|||
</view> --> |
|||
<!-- 右侧订单操作按钮组 --> |
|||
<view class="flex"> |
|||
<view v-if="orderDetail.cancel_btn"> |
|||
<button size="sm" class="plain br60" hover-class="none" @tap="cancelOrder">取消订单</button> |
|||
</view> |
|||
<navigator v-if="orderDetail.view_invoice_btn && orderDetail.shop.open_invoice" hover-class="none" class="m-l-20" |
|||
:url="'/bundle/pages/invoice_detail/invoice_detail?id=' + orderDetail.id"> |
|||
<button size="sm" class="plain br60" hover-class="none">查看发票</button> |
|||
</navigator> |
|||
<navigator v-if="orderDetail.save_invoice_btn && orderDetail.shop.open_invoice" hover-class="none" class="m-l-20" |
|||
:url="'/bundle/pages/invoice/invoice?shop_id=' + orderDetail.shop.id + '&order_id=' + orderDetail.id + '&type=' + invoiceType"> |
|||
<button size="sm" class="plain br60" hover-class="none">申请开票</button> |
|||
</navigator> |
|||
<navigator v-if="orderDetail.delivery_btn" hover-class="none" class="m-l-20" |
|||
:url="'/bundle/pages/goods_logistics/goods_logistics?id=' + orderDetail.id"> |
|||
<button size="sm" class="plain br60" hover-class="none">查看物流</button> |
|||
</navigator> |
|||
<view v-if="orderDetail.take_btn" class="m-l-20"> |
|||
<button size="sm" class="plain br60 primary red" hover-class="none" |
|||
@tap.stop="comfirmOrder">确认收货</button> |
|||
</view> |
|||
<view v-if="orderDetail.del_btn" class="m-l-20"> |
|||
<button size="sm" class="plain br60" hover-class="none" @tap="delOrder">删除订单</button> |
|||
</view> |
|||
<view class="m-l-20" v-if="orderDetail.pay_btn"> |
|||
<button size="sm" class="bg-primary br60 white" @tap="payNow">立即付款</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<loading-view v-if="isFirstLoading"></loading-view> |
|||
<order-dialog ref="orderDialog" :orderId="orderDetail.id" :type="type" @confirm="confirmDialog"></order-dialog> |
|||
<loading-view v-if="showLoading" background-color="transparent" :size="50"></loading-view> |
|||
<float-tab></float-tab> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getOrderDetail, |
|||
cancelOrder, |
|||
delOrder, |
|||
confirmOrder |
|||
} from '@/api/order'; |
|||
import { |
|||
copy |
|||
} from "@/utils/tools.js" |
|||
import { invoiceType } from "@/utils/type.js" |
|||
export default { |
|||
data() { |
|||
return { |
|||
orderDetail: { |
|||
shop: {} |
|||
}, |
|||
team: {}, |
|||
isFirstLoading: true, |
|||
type: 0, |
|||
cancelTime: 0, |
|||
showCancel: "", |
|||
showLoading: false, |
|||
moreStatus: false, // 更多 |
|||
invoiceType: invoiceType['ORDERDETAILADD'] |
|||
}; |
|||
}, |
|||
|
|||
onLoad: function(options) { |
|||
const { |
|||
id |
|||
} = this.$Route.query; |
|||
this.id = id; |
|||
}, |
|||
|
|||
onShow() { |
|||
this.moreStatus = false; |
|||
this.getOrderDetailFun(); |
|||
}, |
|||
|
|||
methods: { |
|||
async confirmDialog() { |
|||
const { type, id } = this |
|||
let res = null |
|||
switch (type) { |
|||
case 0: |
|||
res = await cancelOrder(id); |
|||
break; |
|||
|
|||
case 1: |
|||
res = await delOrder(id); |
|||
break; |
|||
|
|||
case 2: |
|||
res = await confirmOrder(id); |
|||
break; |
|||
} |
|||
if(res.code == 1) { |
|||
uni.$emit("refreshorder") |
|||
|
|||
if ([0, 2].includes(type)) { |
|||
this.getOrderDetailFun(); |
|||
} else if (type == 1) { |
|||
setTimeout(() => { |
|||
uni.navigateBack() |
|||
}, 2000) |
|||
} |
|||
} |
|||
|
|||
}, |
|||
|
|||
// 打开弹窗 |
|||
dialogOpen() { |
|||
this.$refs.orderDialog.open() |
|||
}, |
|||
|
|||
// 删除订单 |
|||
delOrder() { |
|||
this.type = 1 |
|||
this.$nextTick(() => { |
|||
this.dialogOpen(); |
|||
}); |
|||
}, |
|||
|
|||
// 确认订单 |
|||
comfirmOrder() { |
|||
this.type = 2 |
|||
this.$nextTick(() => { |
|||
this.dialogOpen(); |
|||
}); |
|||
}, |
|||
|
|||
// 取消订单 |
|||
cancelOrder() { |
|||
this.type = 0 |
|||
this.$nextTick(() => { |
|||
this.dialogOpen(); |
|||
}); |
|||
}, |
|||
|
|||
// 支付 |
|||
payNow() { |
|||
uni.$on('payment', params => { |
|||
setTimeout(() => { |
|||
if (params.result) { |
|||
this.$toast({ title: "支付成功" }) |
|||
this.getOrderDetailFun(); |
|||
uni.$emit("refreshorder") |
|||
uni.$off("payment") |
|||
} else { |
|||
this.$toast({ title: "支付失败" }) |
|||
} |
|||
}, 500) |
|||
}) |
|||
|
|||
uni.navigateTo({ |
|||
url: `/pages/payment/payment?from=${'order'}&order_id=${this.id}` |
|||
}) |
|||
}, |
|||
|
|||
// 请求订单详情 |
|||
getOrderDetailFun() { |
|||
getOrderDetail(this.id).then(res => { |
|||
console.log(res) |
|||
if (res.code == 1) { |
|||
this.cancelTime = res.data.order_cancel_time - Date.now() / 1000; |
|||
this.orderDetail = res.data |
|||
this.team = res.data.team || {} |
|||
this.$nextTick(() => { |
|||
this.isFirstLoading = false |
|||
if (res.data.delivery_type === 2) { |
|||
const refQR = this.$refs['qrcode'] |
|||
refQR._makeCode() |
|||
} |
|||
}); |
|||
} else { |
|||
setTimeout(() => uni.navigateBack(), 1500) |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
// 复制内容 |
|||
copy(content) { |
|||
copy(content) |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.bt { |
|||
width: 100%; |
|||
text-align: right; |
|||
} |
|||
|
|||
.order-details { |
|||
position: relative; |
|||
padding-bottom: calc(120rpx + env(safe-area-inset-bottom)); |
|||
} |
|||
|
|||
.order-details .header-bg { |
|||
position: absolute; |
|||
top: 0; |
|||
width: 100%; |
|||
height: 200rpx; |
|||
background-color: $-color-primary; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.order-details .goods .status { |
|||
height: 88rpx; |
|||
padding: 0 20rpx; |
|||
} |
|||
|
|||
.order-details .main { |
|||
position: relative; |
|||
z-index: 1; |
|||
} |
|||
|
|||
.order-details .contain { |
|||
margin: 0 20rpx 20rpx; |
|||
border-radius: 14rpx; |
|||
background-color: #fff; |
|||
} |
|||
|
|||
.order-details .header { |
|||
padding: 24rpx 40rpx; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.order-details .img-line { |
|||
height: 1.5px; |
|||
width: 100%; |
|||
display: block; |
|||
} |
|||
|
|||
.order-details .address-wrap { |
|||
height: 164rpx; |
|||
padding: 0 24rpx; |
|||
} |
|||
|
|||
.order-details .order-info { |
|||
padding: 12rpx 0; |
|||
} |
|||
|
|||
.order-details .order-info .item { |
|||
padding: 12rpx 24rpx; |
|||
} |
|||
|
|||
.order-details .order-info .copy-btn { |
|||
font-size: 24rpx; |
|||
padding: 6rpx 18rpx; |
|||
border-radius: 8rpx; |
|||
color: $-color-primary; |
|||
background: rgba($color: $-color-primary, $alpha: .1); |
|||
} |
|||
|
|||
.order-details .order-info .item .title { |
|||
width: 180rpx; |
|||
flex: none; |
|||
} |
|||
|
|||
|
|||
.receive-qr { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
min-height: 460rpx; |
|||
} |
|||
|
|||
.qr-contain { |
|||
box-sizing: border-box; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 140px; |
|||
height: 140px; |
|||
padding: 8px; |
|||
// border: 1px solid #CCCCCC; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.qr-contain--die { |
|||
position: relative; |
|||
} |
|||
|
|||
.qr-contain--die::before { |
|||
position: absolute; |
|||
z-index: 99; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
display: block; |
|||
content: ''; |
|||
background-color: rgba(255, 255, 255, .5); |
|||
} |
|||
|
|||
.qr-code { |
|||
padding: 8rpx 30rpx; |
|||
border-radius: 60px; |
|||
background-color: #F6F6F6; |
|||
} |
|||
|
|||
|
|||
.order-details .price>view { |
|||
height: 60rpx; |
|||
padding: 0 24rpx; |
|||
} |
|||
|
|||
.order-details .footer { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
right: 0; |
|||
height: 100rpx; |
|||
padding: 0 24rpx; |
|||
box-sizing: content-box; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
} |
|||
|
|||
.footer .plain { |
|||
border: 1px solid #BBBBBB; |
|||
} |
|||
|
|||
.footer .plain.red { |
|||
border: 1px solid $-color-primary; |
|||
} |
|||
|
|||
.tips-dialog { |
|||
height: 230rpx; |
|||
width: 100%; |
|||
} |
|||
|
|||
.order-details .invite-btn { |
|||
background: linear-gradient(270deg, #FF2C3C 0%, #F95F2F 100%); |
|||
margin: 30rpx 26rpx 40rpx; |
|||
} |
|||
|
|||
// 点击更多 |
|||
.more { |
|||
position: relative; |
|||
.more-container { |
|||
width: 200rpx; |
|||
bottom: 70rpx; |
|||
left: -20rpx; |
|||
position: absolute; |
|||
border: 1px solid #e9e9e9; |
|||
.more-item { |
|||
padding: 10rpx 20rpx; |
|||
text-align: center; |
|||
border-top: 1px solid #e9e9e9; |
|||
} |
|||
.more-item:first-child { |
|||
border-top: 0; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,63 @@ |
|||
<!-- 账户明细 --> |
|||
|
|||
<template> |
|||
<view class="user-growth"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" @down="downCallback"> |
|||
<view class="p-t-20" > |
|||
<view class="bg-white" v-for="(item, index) in list" :key="index" > |
|||
<record-cell :remark="item.desc" :date="item.create_time" :money="item.total" :type="1" /> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
import {getRechargeRecord} from "@/api/user" |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
// Tabs 列表 |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无记录', // 提示 |
|||
} |
|||
}, |
|||
list: [], // 列表数据--全部 |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
|
|||
// 上拉加载 |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
getRechargeRecord({ |
|||
page_size: pageSize, |
|||
page_no: pageNum |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.list = []; |
|||
const curPageData = data.lists; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.list = this.list.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
|
|||
</style> |
|||
@ -0,0 +1,72 @@ |
|||
<template> |
|||
<view> |
|||
<view class="main"> |
|||
<u-parse :html="content" /> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getServerProto, |
|||
getPrivatePolicy, |
|||
getAfterSaleGuar |
|||
} from '@/api/app'; |
|||
import { |
|||
getTreaty |
|||
} from '@/api/shop' |
|||
export default { |
|||
data() { |
|||
return { |
|||
content: "" |
|||
}; |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.type = Number(this.$Route.query.type) |
|||
// 0 ==> 服务协议 1 ==> 隐私政策 2 ==> 售后保障 |
|||
this.getData() |
|||
}, |
|||
methods: { |
|||
async getData() { |
|||
let res = {} |
|||
switch (this.type) { |
|||
case 0: |
|||
uni.setNavigationBarTitle({ |
|||
title: '服务协议' |
|||
}); |
|||
res = await getServerProto(); |
|||
break; |
|||
case 1: |
|||
uni.setNavigationBarTitle({ |
|||
title: '隐私政策' |
|||
}); |
|||
res = await getPrivatePolicy(); |
|||
break; |
|||
case 2: |
|||
uni.setNavigationBarTitle({ |
|||
title: '售后保障' |
|||
}); |
|||
res = await getAfterSaleGuar(); |
|||
break; |
|||
case 3: |
|||
uni.setNavigationBarTitle({ |
|||
title: '入驻协议' |
|||
}); |
|||
res = await getTreaty(); |
|||
break; |
|||
} |
|||
if(res.code == 1) { |
|||
this.content = res.data.content; |
|||
} |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
|
|||
.main { |
|||
padding: 20rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,97 @@ |
|||
<template> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" |
|||
:up="upOption"> |
|||
<view class="settled-recode"> |
|||
<view class="settled-list"> |
|||
<router-link v-for="(item, index) in list" :key="index" :to="{path: '/bundle/pages/settled_result/settled_result', query: {id: item.id}}"> |
|||
<view class="settled-item bg-white m-t-20"> |
|||
<!-- Title --> |
|||
<view class="settled-title md bold">{{item.name}}</view> |
|||
<view class="settled-info"> |
|||
<!-- Time --> |
|||
<view class="sm muted m-t-26"> |
|||
提交时间:{{item.apply_time}} |
|||
</view> |
|||
<!-- Status --> |
|||
<view class="flex row-between m-t-20"> |
|||
<view class="muted sm" style="align-self: flex-end;"> |
|||
<text>申请状态:</text> |
|||
<text :class="{primary: item.audit_status == 3}">{{item.audit_status_desc}}</text> |
|||
</view> |
|||
<view class="watch-btn br60 flex row-center" @tap="onShowDetail">查看</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins"; |
|||
import { |
|||
shopApplyRecord |
|||
} from '@/api/shop' |
|||
export default { |
|||
mixins: [MescrollMixin], |
|||
data() { |
|||
return { |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: "暂无记录", |
|||
} |
|||
}, |
|||
list: [] |
|||
}; |
|||
}, |
|||
methods: { |
|||
upCallback(page) { |
|||
shopApplyRecord({ |
|||
page_size: page.size, |
|||
page_no: page.num |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.list = []; |
|||
let curPageData = data.lists; |
|||
let curPageLen = curPageData.length; |
|||
let hasNext = !!data.more; |
|||
this.list = this.list.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.settled-recode { |
|||
|
|||
.settled-list { |
|||
padding: 20rpx; |
|||
|
|||
.settled-item { |
|||
border-radius: 10rpx; |
|||
padding: 20rpx 30rpx 30rpx; |
|||
|
|||
.settled-title { |
|||
padding: 21rpx 0 25rpx; |
|||
border-bottom: $-solid-border; |
|||
} |
|||
|
|||
.settled-info { |
|||
|
|||
.watch-btn { |
|||
border: $-solid-border; |
|||
height: 52rpx; |
|||
width: 124rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,192 @@ |
|||
<template> |
|||
<view class="settled-result"> |
|||
<view class="result-box"> |
|||
<!-- Header --> |
|||
<view class="result-header bg-white flex-col col-center"> |
|||
<u-image width="165rpx" height="165rpx" class="m-t-42" :src="getStatus.img" /> |
|||
<view class="m-t-32 lg bold">{{getStatus.text}}</view> |
|||
<view> |
|||
<!-- 地址、账号 --> |
|||
<view v-if="applyDetail.audit_status == 2"> |
|||
<view class="m-t-40 flex flex-wrap"> |
|||
<view class="m-r-20">PC管理后台地址:<text class="lighter">{{applyDetail.admin_address}}</text> |
|||
</view> |
|||
<view class="btn-copy br60 text-center" @tap="onCopy(applyDetail.admin_address)">复制</view> |
|||
</view> |
|||
<view class="m-t-30 flex flex-wrap"> |
|||
<view class="m-r-20">商家账号:<text class="lighter">{{applyDetail.account}}</text></view> |
|||
<view class="btn-copy br60 text-center" @tap="onCopy(applyDetail.account)">复制</view> |
|||
</view> |
|||
</view> |
|||
<view class="m-t-20 muted sm text-center">{{getStatus.desc}}</view> |
|||
<view class="flex" v-if="applyDetail.audit_status !=2"> |
|||
<router-link v-if="applyDetail.audit_status == 3" class="flex-1 m-r-20" to="/bundle/pages/store_settled/store_settled" > |
|||
<view class="br60 flex row-center primary back-btn m-t-60 md">重新提交</view> |
|||
</router-link> |
|||
<router-link class="flex-1" to="/pages/index/index" navType="pushTab"> |
|||
<view class="br60 flex row-center back-btn m-t-60 md">返回首页</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- Content --> |
|||
<view class="result-content bg-white m-t-20 p-20"> |
|||
<view class="apply-form-item flex row-between"> |
|||
<view><text class="primary m-r-10">*</text>商家名称</view> |
|||
<view>{{applyDetail.name}}</view> |
|||
</view> |
|||
|
|||
<!-- 主营行业 --> |
|||
<view class="apply-form-item flex row-between"> |
|||
<view><text class="primary m-r-10">*</text>主营类目</view> |
|||
<view>{{applyDetail.cid_desc}}</view> |
|||
</view> |
|||
|
|||
<!-- 联系人姓名 --> |
|||
<view class="apply-form-item flex row-between"> |
|||
<view><text class="primary m-r-10">*</text>联系人姓名</view> |
|||
<view>{{applyDetail.nickname}}</view> |
|||
</view> |
|||
|
|||
<!-- 手机号码 --> |
|||
<view class="apply-form-item flex row-between"> |
|||
<view><text class="primary m-r-10">*</text>手机号码</view> |
|||
<view>{{applyDetail.mobile}}</view> |
|||
</view> |
|||
<!-- 商家账号 --> |
|||
<view class="apply-form-item flex row-between"> |
|||
<view><text class="primary m-r-10">*</text>商家账号</view> |
|||
<view>{{applyDetail.account}}</view> |
|||
</view> |
|||
|
|||
<!-- 图片 --> |
|||
<view class="apply-form-item"> |
|||
<view><text class="primary m-r-10">*</text>营业执照</view> |
|||
<view class="license-list flex m-t-10 flex-wrap"> |
|||
<view v-for="(item,index) in license" class="m-r-14 m-t-20" @tap="previewImage(index)" |
|||
:key="index"> |
|||
<u-image width="152rpx" height="152rpx" :src="item" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
shopApplyDetail |
|||
} from '@/api/shop' |
|||
import {copy} from '@/utils/tools' |
|||
export default { |
|||
data() { |
|||
return { |
|||
applyDetail: {}, |
|||
license: [] |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
async getShopApplyDetail() { |
|||
const { |
|||
data, |
|||
code |
|||
} = await shopApplyDetail(this.id) |
|||
if (code == 1) { |
|||
this.applyDetail = data |
|||
this.license = data.license |
|||
} |
|||
}, |
|||
previewImage(current) { |
|||
uni.previewImage({ |
|||
current, |
|||
urls: this.license |
|||
}) |
|||
}, |
|||
onCopy(text) { |
|||
copy(text) |
|||
} |
|||
}, |
|||
|
|||
onLoad(options) { |
|||
this.id = this.$Route.query.id |
|||
this.getShopApplyDetail() |
|||
}, |
|||
computed: { |
|||
getStatus() { |
|||
const { |
|||
applyDetail: { |
|||
audit_status |
|||
} |
|||
} = this |
|||
switch (audit_status) { |
|||
case 1: |
|||
return { |
|||
img: '/static/images/img_store_submit.png', |
|||
text: '恭喜您,资料提交成功!', |
|||
desc: '预计在3个工作日内审核完毕,如通过我们将会发送短信通知您,请注意查收!' |
|||
} |
|||
case 2: |
|||
return { |
|||
img: '/static/images/img_store_success.png', |
|||
text: '恭喜您,审核已通过!', |
|||
desc: '温馨提示:密码是您在创建账号时设置的登录密码,如忘记密码可联系官方客服进行修改!' |
|||
} |
|||
case 3: |
|||
return { |
|||
img: '/static/images/img_store_fail.png', |
|||
text: '很遗憾,审核不通过!', |
|||
desc: '请尽量完善您的资料信息再重新提交!' |
|||
} |
|||
default: |
|||
return {} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.settled-result { |
|||
padding: 20rpx; |
|||
|
|||
.result-box { |
|||
.result-header { |
|||
padding: 0 75rpx 50rpx; |
|||
border-radius: 10rpx; |
|||
|
|||
.btn-copy { |
|||
width: 96rpx; |
|||
height: 42rpx; |
|||
line-height: 42rpx; |
|||
border: $-solid-border; |
|||
} |
|||
} |
|||
|
|||
.back-btn { |
|||
height: 88rpx; |
|||
border: 1px solid #CCC; |
|||
&.primary { |
|||
border-color: $-color-primary; |
|||
color: $-color-primary; |
|||
} |
|||
} |
|||
|
|||
.result-content { |
|||
border-radius: 10rpx; |
|||
|
|||
.apply-form-item { |
|||
padding: 30rpx 0; |
|||
|
|||
&:not(:last-of-type) { |
|||
border-bottom: $-solid-border; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,38 @@ |
|||
<template> |
|||
<view class="m-t-20 m-l-20 m-r-20"> |
|||
<text class="nr sign-rule">{{rules}}</text> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getSignRule } from "@/api/activity"; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
rules: '', |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
getSignRuleFun() { |
|||
getSignRule() |
|||
.then(res => { |
|||
if(res.code == 1) { |
|||
this.rules = res.data.rule |
|||
} |
|||
}) |
|||
} |
|||
}, |
|||
|
|||
onLoad() { |
|||
this.getSignRuleFun() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.sign-rule { |
|||
line-height: 36rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,257 @@ |
|||
<template> |
|||
<view class="store-settled"> |
|||
<view class="content"> |
|||
<view class="apply-form bg-white"> |
|||
<!-- 商家名称 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="商家名称" v-model="form.name" label-width="160" placeholder="请输入商家名称" required /> |
|||
</view> |
|||
|
|||
<!-- 主营行业 --> |
|||
<view class="apply-form-item" @tap="showPop=true"> |
|||
<u-field label="主营类目" v-model="form.clabel" label-width="160" style="flex: 1;" placeholder="请选择行业类目" |
|||
required disabled> |
|||
<u-icon name="arrow-right" slot="right" size="28" /> |
|||
</u-field> |
|||
</view> |
|||
|
|||
<!-- 联系人姓名 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="联系人姓名" v-model="form.nickname" label-width="160" placeholder="请输入联系人姓名" required /> |
|||
</view> |
|||
|
|||
<!-- 手机号码 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="手机号码" v-model="form.mobile" label-width="160" placeholder="请输入手机号码" required /> |
|||
</view> |
|||
|
|||
<!-- 验证码 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="验证码" label-width="160" placeholder="请输入验证码" required v-model="form.code"> |
|||
<view slot="right" class="primary send-code-btn br60 flex row-center" @tap="sendSmsFun"> |
|||
<u-verification-code unique-key="store-settled" ref="uCode" @change="codeChange"> |
|||
</u-verification-code> |
|||
<view class="xs">{{codeTips}}</view> |
|||
</view> |
|||
</u-field> |
|||
</view> |
|||
|
|||
<!-- 验证码 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="创建账号" v-model="form.account" label-width="160" placeholder="请设置登录账号(可用手机号代替)" |
|||
required /> |
|||
</view> |
|||
|
|||
<!-- 设置密码 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="设置密码" :password="true" v-model="form.password" label-width="160" |
|||
placeholder="请设置登录密码" required /> |
|||
</view> |
|||
|
|||
<!-- 上传图片 --> |
|||
<view class="apply-form-item"> |
|||
<u-field label="营业执照" label-width="160" placeholder="请上传营业执照及行业相关资质证明" :border-bottom="false" |
|||
required disabled /> |
|||
<view> |
|||
<u-upload ref="uUpload" :show-progress="false" :header="{token: $store.getters.token}" |
|||
:max-count="10" width="150" height="150" :action="action" upload-text="上传图片" |
|||
@on-success="onSuccess" @on-remove="onRemove" /> |
|||
</view> |
|||
<view class="muted m-t-20 m-b-30">支持jpg、png、jpeg格式的图片,最多可上传10张</view> |
|||
</view> |
|||
|
|||
<!-- 同意协议 --> |
|||
<view class="apply-form-item flex"> |
|||
<u-checkbox shape="circle" :active-color="colorConfig.primary" v-model="isAgree"> |
|||
<text class="sm">已阅读并同意</text> |
|||
</u-checkbox> |
|||
<router-link :to="{path: '/bundle/pages/server_explan/server_explan', query: {type: 3}}"> |
|||
<text class="primary sm">《入驻协议》</text> |
|||
</router-link> |
|||
</view> |
|||
|
|||
<!-- 提交申请 --> |
|||
<view style="padding: 30rpx 20rpx 30rpx 0;"> |
|||
<button type="primary" size="lg" class="br60" @tap="onSubmit">提交申请</button> |
|||
</view> |
|||
|
|||
<!-- 查阅记录 --> |
|||
<router-link to="/bundle/pages/settled_recode/settled_recode"> |
|||
<view class="flex row-center muted"> |
|||
<u-icon name="order" size="32" /> |
|||
<view class="m-l-10">查看提交记录</view> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
<u-select v-model="showPop" mode="single-column" value-name="id" label-name="name" :list="shopCategory" |
|||
@confirm="confirmSelect"></u-select> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getShopCategory, |
|||
shopApply |
|||
} from "@/api/shop" |
|||
import { |
|||
baseURL |
|||
} from '@/config/app' |
|||
import { |
|||
sendSms |
|||
} from '@/api/app' |
|||
import { |
|||
SMSType |
|||
} from '@/utils/type' |
|||
export default { |
|||
data() { |
|||
return { |
|||
isAgree: false, |
|||
// 表单数据 |
|||
form: { |
|||
cid: '', |
|||
clabel: '', |
|||
name: '', |
|||
nickname: '', |
|||
mobile: '', |
|||
account: '', |
|||
password: '', |
|||
code: '' |
|||
}, |
|||
codeTips: '', |
|||
shopCategory: [], |
|||
showPop: false, |
|||
action: baseURL + '/api/file/formimage', |
|||
fileList: [] |
|||
} |
|||
}, |
|||
onLoad() { |
|||
this.getShopCategoryFun() |
|||
}, |
|||
methods: { |
|||
async getShopCategoryFun() { |
|||
const { |
|||
code, |
|||
data |
|||
} = await getShopCategory() |
|||
if (code == 1) { |
|||
this.shopCategory = data |
|||
} |
|||
}, |
|||
sendSmsFun() { |
|||
if(!this.$refs.uCode.canGetCode) return |
|||
if (!this.form.mobile) { |
|||
this.$toast({ |
|||
title: '请填写手机号信息' |
|||
}) |
|||
return; |
|||
} |
|||
sendSms({mobile: this.form.mobile, key: SMSType.SJSQYZ}).then(res => { |
|||
if(res.code == 1) { |
|||
this.$toast({title:res.msg}); |
|||
this.$refs.uCode.start(); |
|||
} |
|||
}) |
|||
}, |
|||
codeChange(tip) { |
|||
this.codeTips = tip |
|||
}, |
|||
// 提交表单 |
|||
async onSubmit() { |
|||
const { |
|||
form, |
|||
isAgree, |
|||
fileList |
|||
} = this |
|||
const submitObj = { |
|||
...form, |
|||
license: fileList |
|||
} |
|||
delete submitObj.clabel |
|||
if (!isAgree) return this.$toast({ |
|||
title: '请先同意《入驻协议》' |
|||
}) |
|||
const { |
|||
data, |
|||
code, |
|||
msg |
|||
} = await shopApply(submitObj) |
|||
if(code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}) |
|||
setTimeout(() => { |
|||
this.$Router.replace({ |
|||
path: '/bundle/pages/settled_result/settled_result', |
|||
query: { |
|||
id: data.id |
|||
} |
|||
}) |
|||
},1000) |
|||
|
|||
} |
|||
}, |
|||
confirmSelect(e) { |
|||
const { |
|||
value, |
|||
label |
|||
} = e[0] |
|||
this.form.cid = value |
|||
this.form.clabel = label |
|||
}, |
|||
onSuccess(e) { |
|||
this.fileList.push(e.data.base_uri) |
|||
}, |
|||
onRemove(index) { |
|||
this.fileList.splice(index, 1) |
|||
console.log(index) |
|||
}, |
|||
}, |
|||
|
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.store-settled { |
|||
background-color: #FA844C; |
|||
min-height: 100vh; |
|||
background-image: url(../../static/store_recruitment_bg.png); |
|||
background-repeat: no-repeat; |
|||
background-size: 100% auto; |
|||
overflow: hidden; |
|||
|
|||
.content { |
|||
margin-top: 320rpx; |
|||
padding: 0 20rpx 31rpx; |
|||
|
|||
.apply-form { |
|||
border-radius: 8px; |
|||
padding: 20rpx 0 30rpx 26rpx; |
|||
|
|||
.apply-form-item { |
|||
.send-code-btn { |
|||
height: 56rpx; |
|||
width: 188rpx; |
|||
border: 1rpx solid $-color-primary; |
|||
} |
|||
} |
|||
|
|||
.primary-btn { |
|||
width: 100%; |
|||
height: 88rpx; |
|||
background-color: $-color-primary; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// .pop-categories { |
|||
// .reason-item { |
|||
// padding: 24rpx 20rpx; |
|||
|
|||
// .reason-desc { |
|||
// line-height: 46rpx; |
|||
// } |
|||
// } |
|||
// } |
|||
} |
|||
</style> |
|||
@ -0,0 +1,250 @@ |
|||
<template> |
|||
<view class="user-address"> |
|||
<view class="no-address flex-col col-center" v-if="!hasAddress"> |
|||
<image class="img-null mt20" src="/static/images/address_null.png"></image> |
|||
<view class="sm muted">暂无添加地址,请添加~</view> |
|||
</view> |
|||
<view class="address-list" v-else> |
|||
<u-radio-group v-model="currentId" class="radio-group" @change="radioChange" :active-color="colorConfig.primary"> |
|||
<view v-for="(item, index) in addressList" :key="index" class="item bg-white m-b-20" @tap="onSelect(item.id)"> |
|||
<view class="address"> |
|||
<view class="consignee md bold"> |
|||
{{item.contact}} |
|||
<text class="phone m-l-10">{{item.telephone}}</text> |
|||
</view> |
|||
<view class="lighter sm m-t-10"> |
|||
{{item.province}} {{item.city}} {{item.district}} {{item.address}} |
|||
</view> |
|||
</view> |
|||
<view class="operation flex row-between"> |
|||
<view @tap.stop=""> |
|||
<u-radio class="radio flex" :name="item.id"> |
|||
<text class="xs">{{currentId == item.id ? '默认' : '设为默认'}}</text> |
|||
</u-radio> |
|||
</view> |
|||
<view class="flex row-center"> |
|||
<router-link :to="{path: '/bundle/pages/address_edit/address_edit', query: {id: item.id}}"> |
|||
<view class="flex m-r-20"> |
|||
<image class="icon-md m-r-10" src="/static/images/icon_edit.png"></image> |
|||
编辑 |
|||
</view> |
|||
</router-link> |
|||
<view class="flex m-l-20" @tap.stop="showSurePop(item.id)"> |
|||
<image class="icon-md m-r-10" src="/static/images/icon_del_1.png"></image> |
|||
删除 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</u-radio-group> |
|||
</view> |
|||
<u-modal |
|||
id="delete-dialog" |
|||
v-model="deleteSure" |
|||
:show-cancel-button="true" |
|||
confirm-text="狠心删除" |
|||
:confirm-color="colorConfig.primary" |
|||
:show-title="false" |
|||
@confirm="delAddressFun"> |
|||
<view class="flex-col col-center tips-dialog p-t-40"> |
|||
<image class="icon-lg" src="/static/images/icon_warning.png"></image> |
|||
<view style="margin-top:30rpx">确认删除该地址吗?</view> |
|||
</view> |
|||
</u-modal> |
|||
<view class="footer flex row-between fixed bg-white"> |
|||
<!-- #ifdef H5 || MP-WEIXIN --> |
|||
<view class="btn flex row-center bg-gray br60 m-r-20" @click="getWxAddressFun" v-if="isWeixin"> |
|||
<image class="icon-lg m-r-10" src="/static/images/icon_wechat.png"></image> |
|||
<text class="md">微信导入</text> |
|||
</view> |
|||
<!-- #endif --> |
|||
<router-link class="flex-1" :to="{path: '/bundle/pages/address_edit/address_edit'}"> |
|||
<view class="btn bg-primary white md flex row-center br60">新增收货地址</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { getAddressLists, delAddress, setDefaultAddress } from '@/api/user'; |
|||
import wechath5 from '@/utils/wechath5' |
|||
import {isWeixinClient} from '@/utils/tools' |
|||
export default { |
|||
data() { |
|||
return { |
|||
addressList: [], |
|||
hasAddress: true, |
|||
deleteSure: false, |
|||
currentId: 0, |
|||
isWeixin: true |
|||
}; |
|||
}, |
|||
|
|||
onLoad (options) { |
|||
this.type = this.$Route.query.type; |
|||
//#ifdef H5 |
|||
this.isWeixin = isWeixinClient() |
|||
//#endif |
|||
}, |
|||
|
|||
onShow() { |
|||
this.getAddressListsFun(); |
|||
}, |
|||
|
|||
methods: { |
|||
onSelect(id) { |
|||
if (this.type) { |
|||
uni.$emit('selectaddress', { |
|||
id |
|||
}); |
|||
uni.navigateBack(); |
|||
} |
|||
}, |
|||
getAddressListsFun() { |
|||
getAddressLists().then(res => { |
|||
if (res.code == 1) { |
|||
if (res.data.length) { |
|||
this.addressList = res.data; |
|||
const defaultA = res.data.find((item) => item.is_default) |
|||
this.currentId = defaultA ? defaultA.id : 0 |
|||
this.hasAddress = true; |
|||
} else { |
|||
this.hasAddress = false; |
|||
} |
|||
} else { |
|||
this.hasAddress = false |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
async radioChange(id) { |
|||
const {code, msg} = await setDefaultAddress(id) |
|||
if (code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}) |
|||
this.getAddressListsFun(); |
|||
} |
|||
}, |
|||
|
|||
onLoadFun() { |
|||
this.getAddressListsFun(); |
|||
}, |
|||
|
|||
delAddressFun() { |
|||
delAddress(this.delectId).then(res => { |
|||
if (res.code == 1) { |
|||
this.$toast({ |
|||
title: res.msg |
|||
}); |
|||
this.deleteSure = false |
|||
this.getAddressListsFun(); |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
getWxAddressFun() { |
|||
// #ifdef H5 |
|||
wechath5.getWxAddress().then((res) => { |
|||
uni.setStorageSync('wxAddress', JSON.stringify(res)); |
|||
setTimeout(() => { |
|||
this.$Router.push({ |
|||
path: '/bundle/pages/address_edit/address_edit' |
|||
}) |
|||
}, 200); |
|||
}) |
|||
// #endif |
|||
// #ifdef MP-WEIXIN |
|||
uni.authorize({ |
|||
scope: 'scope.address', |
|||
success: (res) => { |
|||
uni.chooseAddress({ |
|||
success: (res) => { |
|||
uni.setStorageSync('wxAddress', JSON.stringify(res)); |
|||
setTimeout(() => { |
|||
this.$Router.push({ |
|||
path: '/bundle/pages/address_edit/address_edit' |
|||
}) |
|||
}, 200); |
|||
}, |
|||
fail: (res) => { |
|||
if (res.errMsg == 'chooseAddress:cancel') return this.$toast({ |
|||
title: '取消选择' |
|||
}); |
|||
} |
|||
}); |
|||
}, |
|||
fail: (res) => { |
|||
uni.showModal({ |
|||
title: '您已拒绝导入微信地址权限', |
|||
content: '是否进入权限管理,调整授权?', |
|||
success:(res) => { |
|||
if (res.confirm) { |
|||
uni.openSetting({ |
|||
success: (res) => {} |
|||
}); |
|||
} else if (res.cancel) { |
|||
return this.$toast({ |
|||
title: '已取消!' |
|||
}); |
|||
} |
|||
} |
|||
|
|||
}); |
|||
} |
|||
}); |
|||
// #endif |
|||
}, |
|||
|
|||
showSurePop(id) { |
|||
this.deleteSure = true; |
|||
this.delectId = id; |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.user-address { |
|||
padding-bottom: calc(140rpx + env(safe-area-inset-bottom)); |
|||
.no-address { |
|||
padding-top: 300rpx; |
|||
text-align: center; |
|||
} |
|||
.address-list { |
|||
padding: 10rpx 0; |
|||
.item { |
|||
padding: 0 30rpx; |
|||
.address { |
|||
padding: 20rpx 0; |
|||
border-bottom: $-solid-border; |
|||
} |
|||
.operation { |
|||
height: 80rpx; |
|||
} |
|||
} |
|||
.u-radio-group { |
|||
display: block; |
|||
} |
|||
} |
|||
.footer { |
|||
position: fixed; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
height: 118rpx; |
|||
padding: 0 30rpx; |
|||
box-sizing: content-box; |
|||
padding-bottom: env(safe-area-inset-bottom); |
|||
.btn { |
|||
flex: 1; |
|||
height: 80rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.tips-dialog { |
|||
height: 230rpx; |
|||
width: 100%; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,85 @@ |
|||
<!-- 账户明细 --> |
|||
|
|||
<template> |
|||
<view class="user-bill"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" @down="downCallback"> |
|||
<u-tabs :list="tabsList" :is-scroll="false" :current="currentTab" :bold="false" :active-color="colorConfig.primary" |
|||
@change="changeTab" /> |
|||
<view class="p-t-20" > |
|||
<view class="bg-white" v-for="(item, index) in list" :key="index" > |
|||
<record-cell :remark="item.source_type" :date="item.create_time_format" :money="item.change_amount_format" :type="item.change_type" /> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
import {getAccountLog} from "@/api/user" |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
// Tabs 列表 |
|||
tabsList: [{ |
|||
name: '全部' |
|||
}, { |
|||
name: '收入' |
|||
}, { |
|||
name: '支出' |
|||
}], |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无记录', // 提示 |
|||
} |
|||
}, |
|||
currentTab: 0, |
|||
list: [], // 列表数据--全部 |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
// 改变当前的Tabs位置 |
|||
changeTab(index) { |
|||
this.currentTab = index; |
|||
this.list = [] |
|||
this.mescroll.resetUpScroll(); |
|||
}, |
|||
|
|||
// 上拉加载 |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
getAccountLog({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
source: 1, |
|||
type: this.currentTab |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.list = []; |
|||
const curPageData = data.list; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.list = this.list.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
} |
|||
}, |
|||
|
|||
onLoad(options) { |
|||
console.log(options, "option") |
|||
this.currentTab = options.mode || 0; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
|
|||
</style> |
|||
@ -0,0 +1,51 @@ |
|||
<template> |
|||
<view class="user-collection"> |
|||
<tabs :is-scroll="false" :current="active" @change="onChange"> |
|||
<tab name="商品"> |
|||
<collection-list :type="1" :i="0" :index="active"></collection-list> |
|||
</tab> |
|||
<tab name="店铺"> |
|||
<collection-list :type="2" :i="1" :index="active"></collection-list> |
|||
</tab> |
|||
</tabs> |
|||
</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 |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
active: 0 |
|||
}; |
|||
}, |
|||
|
|||
|
|||
|
|||
methods: { |
|||
onChange(index) { |
|||
this.active = index |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
|
|||
</style> |
|||
@ -0,0 +1,35 @@ |
|||
<template> |
|||
<view class="goods-comment-list"> |
|||
<tabs :current="active" :is-scroll="false" @change="changeActive"> |
|||
<tab name="待评价"> |
|||
<comment-list type="1" :i="0" :index="active"></comment-list> |
|||
</tab> |
|||
<tab name="已评价"> |
|||
<comment-list type="2" :i="1" :index="active"></comment-list> |
|||
</tab> |
|||
</tabs> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
active: -1 |
|||
}; |
|||
}, |
|||
onLoad() { |
|||
this.type = this.$Route.query.type || 0; |
|||
this.active = parseInt(this.type) |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
changeActive(e) { |
|||
this.active = e |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
</style> |
|||
@ -0,0 +1,41 @@ |
|||
<template> |
|||
<view class="user-coupon"> |
|||
<tabs :current="active" @change="onChange" :is-scroll="false"> |
|||
<tab v-for="(item, index) in coupons" :key="index" :name="item.title"> |
|||
<my-coupons :type="item.type" :btn-type="item.btnType" :i="index" :index="active"></my-coupons> |
|||
</tab> |
|||
</tabs> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
active: 0, |
|||
coupons: [{ |
|||
title: '可使用', |
|||
btnType: 0, |
|||
type: 'valid' |
|||
}, { |
|||
title: '已使用', |
|||
btnType: 1, |
|||
type: 'used' |
|||
}, { |
|||
title: '已过期', |
|||
btnType: 2, |
|||
type: 'expired' |
|||
}] |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
onChange(index) { |
|||
this.active = index |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
</style> |
|||
@ -0,0 +1,253 @@ |
|||
<template> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" :down="downOption" |
|||
@down="downCallback"> |
|||
<view class="user-fans"> |
|||
<view class="header"> |
|||
<u-search v-model="keyword" shape="round" background="white" placeholder="请输入搜索关键词" @search="changeTab" |
|||
@custom="changeTab" /> |
|||
<view class="top-bar flex bg-white md"> |
|||
<view class="bar-item flex" :class="{'item-active': active == 'all'}" @tap="changeTab('all')">全部粉丝 |
|||
</view> |
|||
<view class="bar-item flex" :class="{'item-active': active == 'first'}" @tap="changeTab('first')"> |
|||
一级粉丝</view> |
|||
<view class="bar-item flex" :class="{'item-active': active == 'second'}" @tap="changeTab('second')"> |
|||
二级粉丝</view> |
|||
</view> |
|||
<view class="sort-bar flex bg-white"> |
|||
<view class="sort-bar-item flex row-center" @tap="sortChange(0)"> |
|||
<view :class="sortType == 0 ? 'item-active' : ''">团队排序</view> |
|||
<view class="arrow-icon flex-col col-center row-center"> |
|||
<u-icon name="arrow-up-fill" |
|||
:color="fansSort == 'asc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
<u-icon name="arrow-down-fill" |
|||
:color="fansSort == 'desc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
</view> |
|||
</view> |
|||
<view class="sort-bar-item flex row-center" @tap="sortChange(1)"> |
|||
<view :class="sortType == 1 ? 'item-active' : ''">金额排序</view> |
|||
<view class="arrow-icon flex-col col-center row-center"> |
|||
<u-icon name="arrow-up-fill" |
|||
:color="moneySort == 'asc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
<u-icon name="arrow-down-fill" |
|||
:color="moneySort == 'desc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
</view> |
|||
</view> |
|||
<view class="sort-bar-item flex row-center" @tap="sortChange(2)"> |
|||
<view :class="sortType == 2 ? 'item-active' : ''">订单排序</view> |
|||
<view class="arrow-icon flex-col col-center row-center"> |
|||
<u-icon name="arrow-up-fill" |
|||
:color="orderSort == 'asc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
<u-icon name="arrow-down-fill" |
|||
:color="orderSort == 'desc' ? colorConfig.primary : colorConfig.normal"></u-icon> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="content"> |
|||
<view class="card-box p-t-20"> |
|||
<view v-for="(item, index) in fansList" :key="index" class="card-item flex row-between bg-white p-20"> |
|||
<view class="flex"> |
|||
<u-image :src="item.avatar" border-radius="50%" width="100rpx" height="100rpx" /> |
|||
<view class="fans-info m-l-20"> |
|||
<view class="fans-name bold line-1">{{item.nickname}}</view> |
|||
<view class="flex lighter m-t-20"> |
|||
<view v-if="item.mobile" class="m-r-20">{{item.mobile}}</view> |
|||
<view>{{item.create_time}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="flex-col xs flex-none m-l-20"> |
|||
<view class="msg"><span class="primary">{{item.fans_team}} </span>人</view> |
|||
<view class="m-t-5 msg"><span>{{item.fans_order}} </span>单</view> |
|||
<view class="m-t-5 msg"><span>{{item.fans_money}} </span>元</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
sortType, |
|||
} from '@/utils/type'; |
|||
import { |
|||
getUserFans |
|||
} from '@/api/user'; |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无相关数据', // 提示 |
|||
} |
|||
}, |
|||
active: 'all', |
|||
sortType: -1, |
|||
keyword: "", |
|||
fansSort: sortType.NONE, |
|||
moneySort: sortType.NONE, |
|||
orderSort: sortType.NONE, |
|||
fansList: [] |
|||
}; |
|||
}, |
|||
methods: { |
|||
onRefresh() { |
|||
this.fansList = [] |
|||
this.mescroll.resetUpScroll(); |
|||
}, |
|||
|
|||
// 上拉加载 |
|||
upCallback(page) { |
|||
const { |
|||
fansSort, |
|||
moneySort, |
|||
orderSort, |
|||
active, |
|||
keyword, |
|||
} = this; |
|||
const params = { |
|||
type: active, |
|||
keyword, |
|||
fans: fansSort, |
|||
money: moneySort, |
|||
order: orderSort, |
|||
page_size: page.size, |
|||
page_no: page.num, |
|||
}; |
|||
getUserFans(params).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.fansList = []; |
|||
const curPageData = data.list; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.fansList = this.fansList.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
}, |
|||
|
|||
changeTab(val) { |
|||
this.active = val |
|||
this.onRefresh() |
|||
}, |
|||
|
|||
// 排序状态变化 |
|||
sortChange(type) { |
|||
let { |
|||
fansSort, |
|||
moneySort, |
|||
orderSort |
|||
} = this; |
|||
|
|||
this.sortType = parseInt(type) |
|||
|
|||
switch (this.sortType) { |
|||
case 0: |
|||
// 团队排序 |
|||
if (fansSort == sortType.DESC || fansSort == sortType.NONE) { |
|||
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.onRefresh() |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.user-fans { |
|||
.header { |
|||
.top-bar { |
|||
padding: 18rpx 50rpx; |
|||
height: 100rpx; |
|||
|
|||
.bar-item { |
|||
flex: 1; |
|||
padding: 0 30rpx; |
|||
height: 58rpx; |
|||
|
|||
&:not(:last-of-type) { |
|||
margin-right: 54rpx; |
|||
} |
|||
} |
|||
|
|||
.item-active { |
|||
color: white; |
|||
background-color: $-color-primary; |
|||
border-radius: 100rpx; |
|||
} |
|||
} |
|||
|
|||
.sort-bar { |
|||
height: 80rpx; |
|||
|
|||
.sort-bar-item { |
|||
flex: 1; |
|||
|
|||
.arrow-icon { |
|||
transform: scale(0.36); |
|||
} |
|||
|
|||
.item-active { |
|||
color: $-color-primary; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.content { |
|||
.card-box { |
|||
.card-item { |
|||
.fans-name { |
|||
width: 500rpx; |
|||
} |
|||
&:not(:last-of-type) { |
|||
border-bottom: $-solid-border; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,59 @@ |
|||
<template> |
|||
<view class="user-group"> |
|||
<tabs :active="active" @change="changeShow" :isScroll="false"> |
|||
<tab v-for="(item, index) in group" :key="index" :name="item.name"> |
|||
<group-list v-if="item.isShow" :ref="'group' + item.type" :groupType="item.type"></group-list> |
|||
</tab> |
|||
</tabs> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import {groupType} from "@/utils/type"; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
active: "", |
|||
group: [{ |
|||
name: '全部', |
|||
type: groupType.ALL, |
|||
isShow: true |
|||
}, { |
|||
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); |
|||
}, |
|||
|
|||
methods: { |
|||
changeShow(index) { |
|||
if (index != -1) { |
|||
this.active = index |
|||
this.group[index].isShow = true |
|||
} |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
|
|||
</style> |
|||
@ -0,0 +1,64 @@ |
|||
<!-- 账户明细 --> |
|||
|
|||
<template> |
|||
<view class="user-growth"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" :down="downOption" @down="downCallback"> |
|||
<view class="p-t-20" > |
|||
<view class="bg-white" v-for="(item, index) in list" :key="index" > |
|||
<record-cell :remark="item.source_type" :date="item.create_time_format" :money="item.change_amount_format" :type="item.change_type" /> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
import {getAccountLog} from "@/api/user" |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
// Tabs 列表 |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无记录', // 提示 |
|||
} |
|||
}, |
|||
list: [], // 列表数据--全部 |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
|
|||
// 上拉加载 |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
getAccountLog({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
source: 3, |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.list = []; |
|||
const curPageData = data.list; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.list = this.list.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
} |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
|
|||
</style> |
|||
@ -0,0 +1,58 @@ |
|||
|
|||
<template> |
|||
<view class="user-order"> |
|||
<tabs :current="active" @change="changeShow" bar-width="60" :is-scroll="false"> |
|||
<tab v-for="(item, index) in order" :key="index" :name="item.name"> |
|||
<order-list :order-type="item.type" :i="index" :index="active"></order-list> |
|||
</tab> |
|||
</tabs> |
|||
<float-tab></float-tab> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { orderType } from '@/utils/type'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
active: -1, |
|||
order: [{ |
|||
name: '全部', |
|||
type: orderType.ALL |
|||
}, { |
|||
name: '待付款', |
|||
type: orderType.PAY |
|||
}, { |
|||
name: '待收货', |
|||
type: orderType.DELIVERY |
|||
}, { |
|||
name: '已完成', |
|||
type: orderType.FINISH |
|||
}, { |
|||
name: '已关闭', |
|||
type: orderType.CLOSE |
|||
}] |
|||
}; |
|||
}, |
|||
onLoad (options) { |
|||
const{order} = this |
|||
let type = this.$Route.query.type || orderType.ALL; |
|||
let index = order.findIndex(item => item.type == type) |
|||
this.changeShow(index); |
|||
}, |
|||
methods: { |
|||
changeShow(index) { |
|||
if(index != -1) { |
|||
this.$nextTick(() => { |
|||
this.active = index |
|||
}) |
|||
} |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
|
|||
</style> |
|||
@ -0,0 +1,336 @@ |
|||
<template> |
|||
<view> |
|||
<view class="user-payment"> |
|||
<!-- 充值 --> |
|||
<form report-submit="true"> |
|||
<view class="payment bg-white"> |
|||
<view class="md normal flex" style="padding: 66rpx 66rpx 0"> |
|||
充值金额 |
|||
</view> |
|||
<view class="input flex"> |
|||
<text style="font-size: 46rpx">¥</text> |
|||
<input :placeholder="placeholder" type="digit" @focus="setPlaceholder" |
|||
@blur="setPlaceholderStatus" :value="number" @input="onInput" /> |
|||
</view> |
|||
<view class="tip muted m-t-20 flex"> |
|||
提示:当前余额为 |
|||
<text class="primary">¥{{wallet.user_money || 0}}</text> |
|||
</view> |
|||
</view> |
|||
<button size="lg" class="btn white br60" @tap="rechargeRights"> |
|||
立即充值 |
|||
</button> |
|||
</form> |
|||
|
|||
<!-- 推荐充值 --> |
|||
<view class="fast-payment-container" v-if="rechargeObj.length"> |
|||
<view class="title bold normal flex">推荐充值</view> |
|||
<view class="fast-pay flex flex-wrap"> |
|||
<view v-for="(item, index) in rechargeObj" :key="index" |
|||
class="fast-pay-item bg-white flex-col col-center row-center" @tap="temRecharge(item.id)"> |
|||
<view class="hot-recharge white" v-if="item.is_recommend">热门充值</view> |
|||
<view class="price bold"> |
|||
<price-format weight="bold" :firstSize="42" :price="item.money"></price-format> |
|||
<text class="xxl" style="font-weight: 400">元</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/icon_success.png"></image> |
|||
<view class="xxl bold m-t-10">充值成功</view> |
|||
<view v-if="rechargeInfo.give_growth" class="lg" style="margin-top: 50rpx">恭喜您获得 <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> |
|||
<float-tab></float-tab> |
|||
</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 { |
|||
rechargeTemplate, |
|||
recharge, |
|||
getWallet |
|||
} 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: {}, |
|||
wallet: {}, |
|||
showLoading: false |
|||
}; |
|||
}, |
|||
|
|||
/** |
|||
* 生命周期函数--监听页面加载 |
|||
*/ |
|||
onLoad: function(options) { |
|||
this.rechargeTemplateFun(); |
|||
this.getWalletFun(); |
|||
}, |
|||
|
|||
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 = '' |
|||
}, |
|||
|
|||
getWalletFun() { |
|||
getWallet().then(res => { |
|||
if (res.code == 1) { |
|||
this.wallet = res.data |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
rechargeTemplateFun() { |
|||
rechargeTemplate().then(res => { |
|||
if (res.code == 1) { |
|||
this.rechargeObj = res.data |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
rechargeRights() { |
|||
const { |
|||
number |
|||
} = this; |
|||
this.rechargeFun({ |
|||
money: Number(number) |
|||
}); |
|||
}, |
|||
|
|||
temRecharge(id) { |
|||
this.rechargeFun({ |
|||
id |
|||
}); |
|||
}, |
|||
|
|||
rechargeFun(obj) { |
|||
if (!obj.id && obj.money == 0) { |
|||
return this.$toast({ |
|||
title: '请输入金额' |
|||
}) |
|||
} |
|||
|
|||
this.showLoading = true |
|||
|
|||
recharge(obj).then(({ code, data, msg }) => { |
|||
if (code != 1) throw new Error(msg) |
|||
|
|||
this.rechargeInfo = data |
|||
uni.$on('payment', params => { |
|||
setTimeout(() => { |
|||
if (params.result) { |
|||
this.$toast({ title: "支付成功" }) |
|||
this.onShowPopup(); |
|||
this.getWalletFun(); |
|||
} else { |
|||
this.$toast({ title: "支付失败" }) |
|||
} |
|||
}, 500) |
|||
}) |
|||
|
|||
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"> |
|||
.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; |
|||
|
|||
&:not(:nth-of-type(3n)) { |
|||
margin-right: 24rpx; |
|||
} |
|||
|
|||
.hot-recharge { |
|||
position: absolute; |
|||
padding: 2rpx 10rpx; |
|||
height: 30rpx; |
|||
background: linear-gradient(180deg, #FF2C3C 0%, #F95F2F 100%); |
|||
border-radius: 0 20rpx 0 20rpx; |
|||
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: 112rpx; |
|||
height: 112rpx; |
|||
display: inline-block; |
|||
} |
|||
|
|||
.btn { |
|||
margin: 80rpx 60rpx 0; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,612 @@ |
|||
<template> |
|||
<view class="user-profile p-t-10"> |
|||
<view class="content"> |
|||
<view class="bg-white"> |
|||
<view class="user-avatar-box flex-col col-center"> |
|||
<button class="column column-center" hover-class="none" open-type="chooseAvatar" |
|||
@chooseavatar="onChooseAvatar" @click="onChooseAvatar"> |
|||
<image class="user-avatar" |
|||
:src="userInfo.avatar1!= '' ? userInfo.avatar:'/static/images/portrait_empty.png'"> |
|||
</image> |
|||
<view class="muted xs">点击修改头像</view> |
|||
</button> |
|||
</view> |
|||
<view class="row-info flex bdb-line" @tap="changeName"> |
|||
<view class="label md">昵称</view> |
|||
<view class="md flex-1">{{ userInfo.nickname }}</view> |
|||
<u-icon name="arrow-right" /> |
|||
</view> |
|||
<view class="row-info flex bdb-line" @tap="changeSex"> |
|||
<view class="label md">性别</view> |
|||
<view class="md flex-1" :class="userInfo.sex == 0 ? 'muted' : ''">{{ userInfo.sex }}</view> |
|||
<u-icon name="arrow-right" /> |
|||
</view> |
|||
<view class="row-info flex bdb-line"> |
|||
<view class="label md">手机号</view> |
|||
<view |
|||
class="md flex-1" |
|||
:class="{ 'muted': !userInfo.mobile }" |
|||
>{{ userInfo.mobile ? userInfo.mobile : "未绑定" }}</view> |
|||
<!-- #ifdef H5 || APP-PLUS --> |
|||
<view |
|||
class="bd-btn br60 flex row-center" |
|||
@tap="showModifyMobile" |
|||
>{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</view> |
|||
<!-- #endif --> |
|||
<!-- #ifdef MP-WEIXIN --> |
|||
<button |
|||
class="bd-btn br60 flex row-center" |
|||
size="sm" |
|||
open-type="getPhoneNumber" |
|||
@getphonenumber="getPhoneNumber" |
|||
>{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</button> |
|||
<!-- #endif --> |
|||
</view> |
|||
<!-- #ifndef MP-WEIXIN--> |
|||
<view class="row-info flex row-between" @tap="showPwdPop"> |
|||
<view class="label md">登录密码</view> |
|||
<view class="flex"> |
|||
<view class="muted">点击设置</view> |
|||
<u-icon name="arrow-right" /> |
|||
</view> |
|||
</view> |
|||
<!-- #endif --> |
|||
<view class="row-info flex row-between bdb-line mt10" @tap="goToExplain(0)"> |
|||
<view class="label md">服务协议</view> |
|||
<u-icon name="arrow-right" /> |
|||
</view> |
|||
<view class="row-info flex row-between bdb-line" @tap="goToExplain(1)"> |
|||
<view class="label md">隐私政策</view> |
|||
<u-icon name="arrow-right" /> |
|||
</view> |
|||
<view class="row-info flex row-between bdb-line" @tap="goLicense()"> |
|||
<view class="label md">资质信息</view> |
|||
<u-icon name="arrow-right" /> |
|||
</view> |
|||
<view class="row-info flex row-between"> |
|||
<view class="label md">关于我们</view> |
|||
<view>v{{ version }}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- #ifndef MP-WEIXIN --> |
|||
<view class="bg-primary white save-btn flex row-center lg" @tap="logout">退出登录</view> |
|||
<!-- #endif --> |
|||
<!-- 版权信息 --> |
|||
<view class="license xs text-center" v-if="appConfig.copyright_info"> |
|||
<view>{{ appConfig.copyright_info }}</view> |
|||
<view>{{ appConfig.icp_number }}</view> |
|||
</view> |
|||
|
|||
<!-- #ifndef MP-WEIXIN --> |
|||
<u-popup type="center" closeable v-model="showMobile" mode="center" border-radius="14"> |
|||
<view class="modify-container bg-white" v-show="showMobile"> |
|||
<view class="title xl text-center">{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</view> |
|||
<u-field |
|||
label="+86" |
|||
v-if="userInfo.mobile" |
|||
label-width="100" |
|||
disabled |
|||
v-model="userInfo.mobile" |
|||
></u-field> |
|||
<u-field label="+86" v-else label-width="140" v-model="new_mobile" placeholder="请输入手机号"></u-field> |
|||
<u-field v-model="mobileCode" label="验证码" label-width="140" placeholder="请输入验证码"> |
|||
<view slot="right" class="primary send-code-btn br60 flex row-center" @tap="sendSmsFun"> |
|||
<u-verification-code |
|||
:keep-running="true" |
|||
unique-key="mobile" |
|||
ref="uCode" |
|||
@change="codeChange" |
|||
></u-verification-code> |
|||
<view class="sm">{{ codeTips }}</view> |
|||
</view> |
|||
</u-field> |
|||
<u-field |
|||
label="新手机号" |
|||
v-if="userInfo.mobile" |
|||
label-width="140" |
|||
placeholder="请输入新的手机号码" |
|||
v-model="new_mobile" |
|||
></u-field> |
|||
<view class="primary m-t-10 xs">{{ userInfo.mobile ? '更改' : '绑定' }}手机号码成功后,您的账号将会变更为该设置号码</view> |
|||
<view class="btn bg-primary white flex row-center" @tap="changeUserMobileFun">确定</view> |
|||
</view> |
|||
</u-popup> |
|||
<!-- #endif --> |
|||
<u-popup v-model="showNickName" :closeable="true" :maskCloseAble="false" mode="center" border-radius="14"> |
|||
<view class="modify-container bg-white" style="width: 70vw;padding: 24rpx"> |
|||
<view class="title xl text-center">修改用户名</view> |
|||
<form @submit="changeNameConfirm"> |
|||
<u-form-item label="新昵称" :labelWidth="120"> |
|||
<input style="height: 60rpx;" class="nr" :value="userInfo.nickname" name="nickname" |
|||
type="nickname" placeholder="请输入新的昵称"> |
|||
</input> |
|||
</u-form-item> |
|||
<button class="btn bg-primary white flex row-center" form-type="submit">确定</button> |
|||
</form> |
|||
</view> |
|||
</u-popup> |
|||
<!-- #ifndef MP-WEIXIN --> |
|||
<u-popup v-model="showPwd" closeable mode="center" border-radius="14"> |
|||
<view class="modify-container bg-white"> |
|||
<view class="title xl text-center">设置密码</view> |
|||
<u-field label="+86" disabled label-width="100" v-model="userInfo.mobile"></u-field> |
|||
<u-field v-model="pwdCode" label="验证码" label-width="140" placeholder="请输入验证码"> |
|||
<view slot="right" class="primary send-code-btn br60 flex row-center" @tap="sendSmsFun"> |
|||
<u-verification-code |
|||
unique-key="password" |
|||
:keep-running="true" |
|||
ref="uCode" |
|||
@change="codeChange" |
|||
></u-verification-code> |
|||
<view class="sm">{{ codeTips }}</view> |
|||
</view> |
|||
</u-field> |
|||
<u-field label="设置密码" label-width="140" type="password" placeholder="请输入新密码" v-model="pwd"></u-field> |
|||
<u-field |
|||
label="确认密码" |
|||
label-width="140" |
|||
type="password" |
|||
placeholder="再次输入新密码确认" |
|||
v-model="comfirmPwd" |
|||
></u-field> |
|||
<view class="btn bg-primary white flex row-center" @tap="forgetPwdFun">确定</view> |
|||
</view> |
|||
</u-popup> |
|||
<!-- #endif --> |
|||
<u-picker |
|||
mode="selector" |
|||
v-model="showPicker" |
|||
:default-selector="[0]" |
|||
:range="sexList" |
|||
@confirm="onConfirm" |
|||
/> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
userLogout, |
|||
getUserInfo, |
|||
getWxMnpMobile, |
|||
setUserInfo, |
|||
setWechatInfo, |
|||
changeUserMobile |
|||
} from "@/api/user"; |
|||
import { |
|||
baseURL, |
|||
version |
|||
} from '@/config/app'; |
|||
import { |
|||
sendSms, |
|||
forgetPwd, |
|||
} from '@/api/app' |
|||
import { |
|||
SMSType |
|||
} from '@/utils/type' |
|||
import { |
|||
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 { |
|||
action: baseURL + '/api/file/formimage', |
|||
fileList: [], |
|||
userInfo: {}, |
|||
new_mobile: '', |
|||
pwdCode: '', |
|||
mobileCode: '', |
|||
newNickname: '', |
|||
sexList: ['男', '女'], |
|||
fieldType: FieldType.NONE, |
|||
showPicker: false, |
|||
showMobile: false, |
|||
showPwd: false, |
|||
showNickName: false, |
|||
codeTips: '', |
|||
canSendSms: true, |
|||
pwd: '', |
|||
comfirmPwd: '', |
|||
smsType: '', |
|||
code: '', |
|||
version |
|||
} |
|||
}, |
|||
methods: { |
|||
codeChange(text) { |
|||
this.codeTips = text; |
|||
}, |
|||
onSuccess(e) { |
|||
console.log(e) |
|||
}, |
|||
uploadImage(path) { |
|||
uni.showLoading({ |
|||
title: '正在上传中...', |
|||
mask: true |
|||
}); |
|||
uploadFile(path).then(res => { |
|||
uni.hideLoading() |
|||
this.setUserInfoFun(res.uri) |
|||
}).catch(() => { |
|||
uni.hideLoading() |
|||
this.$toast({ |
|||
title: "上传失败" |
|||
}) |
|||
}) |
|||
}, |
|||
onChooseAvatar(e) { |
|||
this.fieldType = FieldType.AVATAR; |
|||
// #ifndef MP-WEIXIN |
|||
// 此为uView的跳转方法,详见"文档-JS"部分,也可以用uni的uni.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) { |
|||
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.setUserInfoFun(this.newNickname) |
|||
this.showNickName = false; |
|||
}, |
|||
// 更新小程序头像信息 |
|||
async getUserProfileFun() { |
|||
const { |
|||
userInfo |
|||
} = await getUserProfile() |
|||
const { |
|||
avatarUrl, |
|||
nickName, |
|||
gender |
|||
} = userInfo |
|||
const { |
|||
msg, |
|||
code |
|||
} = await setWechatInfo({ |
|||
nickname: nickName, |
|||
avatar: avatarUrl, |
|||
sex: gender |
|||
}) |
|||
if (code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}); |
|||
this.getUserInfoFun() |
|||
} |
|||
}, |
|||
|
|||
// end |
|||
logout() { |
|||
// 退出登录 |
|||
userLogout().then(res => { |
|||
if (res.code == 1) { |
|||
this.$store.commit("logout"); |
|||
this.$toast({ |
|||
title: '退出成功' |
|||
}) |
|||
setTimeout(() => { |
|||
this.$Router.replaceAll('/pages/index/index') |
|||
}, 500) |
|||
} |
|||
}) |
|||
}, |
|||
goToExplain(value) { |
|||
this.$Router.push({ |
|||
path: '/bundle/pages/server_explan/server_explan', |
|||
query: { |
|||
type: value |
|||
} |
|||
}) |
|||
}, |
|||
goLicense() { |
|||
this.$Router.push({ |
|||
path: '/bundle/pages/license/license', |
|||
query: { |
|||
id: '' |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
// 发送短信 |
|||
sendSmsFun(type) { |
|||
if (!this.$refs.uCode.canGetCode) 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(); |
|||
} |
|||
}) |
|||
}, |
|||
getUserInfoFun() { |
|||
getUserInfo().then(res => { |
|||
if (res.code == 1) { |
|||
this.userInfo = res.data; |
|||
} |
|||
}) |
|||
}, |
|||
// 更换手机号 |
|||
showModifyMobile() { |
|||
this.new_mobile = ''; |
|||
this.showMobile = true |
|||
this.smsType = this.userInfo.mobile ? SMSType.CHANGE_MOBILE : SMSType.BIND |
|||
}, |
|||
changeUserMobileFun() { |
|||
if (!this.mobileCode) { |
|||
this.$toast({ |
|||
title: '请输入验证码' |
|||
}) |
|||
return; |
|||
} |
|||
if (!this.new_mobile) { |
|||
this.$toast({ |
|||
title: '请输入新的手机号码' |
|||
}) |
|||
return; |
|||
} |
|||
|
|||
changeUserMobile({ |
|||
mobile: this.userInfo.mobile, |
|||
new_mobile: this.new_mobile, |
|||
code: this.mobileCode, |
|||
action: this.userInfo.mobile ? 'change' : 'binding' |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
this.showMobile = false; |
|||
this.$toast({ |
|||
title: res.msg |
|||
}) |
|||
this.getUserInfoFun(); |
|||
} |
|||
}) |
|||
}, |
|||
// 修改用户信息 |
|||
async setUserInfoFun(value) { |
|||
const res = await setUserInfo({ |
|||
field: this.fieldType, |
|||
value: value |
|||
}) |
|||
if (res.code == 1) { |
|||
this.$toast({ |
|||
title: res.msg |
|||
}); |
|||
this.getUserInfoFun() |
|||
} |
|||
}, |
|||
onConfirm(value) { |
|||
this.setUserInfoFun(value[0] + 1); |
|||
this.showPicker = false; |
|||
}, |
|||
changeSex(e) { |
|||
this.showPicker = true; |
|||
this.fieldType = FieldType.SEX; |
|||
}, |
|||
|
|||
// 修改密码 |
|||
showPwdPop() { |
|||
if (!this.userInfo.mobile) { |
|||
this.$toast({ |
|||
title: '请绑定手机后再设置密码' |
|||
}) |
|||
return; |
|||
} |
|||
this.smsType = SMSType.FINDPWD |
|||
this.showPwd = true |
|||
}, |
|||
forgetPwdFun() { |
|||
let { |
|||
pwdCode, |
|||
pwd, |
|||
comfirmPwd |
|||
} = this; |
|||
if (!pwdCode) { |
|||
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: pwdCode, |
|||
password: pwd, |
|||
repassword: comfirmPwd |
|||
}; |
|||
forgetPwd(data).then(res => { |
|||
if (res.code == 1) { |
|||
this.showPwd = false; |
|||
this.$toast({ |
|||
title: '设置密码成功' |
|||
}); |
|||
this.getUserInfoFun(); |
|||
} |
|||
}) |
|||
}, |
|||
// 修改昵称 |
|||
changeName() { |
|||
this.fieldType = FieldType.NICKNAME; |
|||
this.newNickname = ''; |
|||
this.showNickName = true; |
|||
}, |
|||
// 微信获取手机号 |
|||
// #ifdef MP-WEIXIN |
|||
async getPhoneNumber(e) { |
|||
console.log(e, this.code) |
|||
const { |
|||
encryptedData, |
|||
iv |
|||
} = e.detail; |
|||
const params = { |
|||
code: this.code, |
|||
encrypted_data: encryptedData, |
|||
iv |
|||
} |
|||
this.fieldType = FieldType.MOBILE |
|||
if (encryptedData) { |
|||
const { |
|||
data, |
|||
code, |
|||
msg |
|||
} = await getWxMnpMobile(params) |
|||
if (code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}); |
|||
// #ifdef MP-WEIXIN |
|||
getWxCode().then(res => { |
|||
this.code = res |
|||
}) |
|||
// #endif |
|||
this.getUserInfoFun() |
|||
} |
|||
} |
|||
}, |
|||
// #endif |
|||
}, |
|||
onLoad() { |
|||
this.getUserInfoFun() |
|||
// #ifdef MP-WEIXIN |
|||
getWxCode().then(res => { |
|||
this.code = res |
|||
}) |
|||
// #endif |
|||
uni.$on('uAvatarCropper', path => { |
|||
console.log(path) |
|||
this.uploadImage(path) |
|||
}) |
|||
this.getUserProfileFun = trottle(this.getUserProfileFun, 500, this) |
|||
}, |
|||
onUnload() { |
|||
uni.$off('uAvatarCropper') |
|||
}, |
|||
computed: { |
|||
...mapGetters(['token', 'appConfig']) |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.user-profile { |
|||
min-height: calc(100vh - env(safe-area-inset-bottom)); |
|||
display: flex; |
|||
flex-direction: column; |
|||
.content { |
|||
// flex: 1; |
|||
border-top-left-radius: 28rpx; |
|||
border-top-right-radius: 28rpx; |
|||
|
|||
.user-avatar-box { |
|||
padding: 30rpx; |
|||
|
|||
.user-avatar { |
|||
width: 120rpx; |
|||
height: 120rpx; |
|||
border-radius: 50%; |
|||
} |
|||
} |
|||
|
|||
.row-info { |
|||
padding: 30rpx 20rpx; |
|||
|
|||
.label { |
|||
width: 180rpx; |
|||
} |
|||
|
|||
.bd-btn { |
|||
padding: 8rpx 24rpx; |
|||
border: 1px solid $-color-primary; |
|||
color: $-color-primary; |
|||
} |
|||
} |
|||
|
|||
.bdb-line { |
|||
border-bottom: 1rpx solid #e5e5e5; |
|||
} |
|||
} |
|||
.license { |
|||
margin-top: 80rpx; |
|||
color: #a7a7a7; |
|||
} |
|||
|
|||
.save-btn { |
|||
margin: 40rpx 54rpx 0; |
|||
height: 88rpx; |
|||
border-radius: 10rpx; |
|||
} |
|||
.modify-container { |
|||
padding: 30rpx; |
|||
width: 620rpx; |
|||
border-radius: 30rpx; |
|||
|
|||
.title { |
|||
padding: 26rpx 0rpx; |
|||
} |
|||
|
|||
.btn { |
|||
height: 80rpx; |
|||
border-radius: 20rpx; |
|||
margin: 60rpx 50rpx 0; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,690 @@ |
|||
<template> |
|||
<view> |
|||
<loading-view v-if="showLoading"></loading-view> |
|||
<u-notice-bar :show="showTips" mode="horizontal" :list="list" :font-size="26" :close-icon="true" :speed="100" |
|||
@close="showTips=false"></u-notice-bar> |
|||
<view class="user-spread"> |
|||
<view class="header p-t-40 m-b-50"> |
|||
<view class="user-info flex m-l-30"> |
|||
<view class="user-avatar"> |
|||
<u-image width="110rpx" height="110rpx" border-radius="60" :src="userInfo.user.avatar" /> |
|||
</view> |
|||
<view class="user-message m-l-20 white"> |
|||
<view class="m-b-10"> |
|||
<view class="xxl bold m-r-20">{{userInfo.user.nickname}}</view> |
|||
</view> |
|||
<view class="avatar-tag white xxs text-center m-b-10" v-if="distributionInfo.level_name">{{distributionInfo.level_name}}</view> |
|||
<view class="xs flex"> |
|||
上级分销商:{{userInfo.leader.nickname ? userInfo.leader.nickname : '无'}} |
|||
<view v-if="!userInfo.leader.nickname" |
|||
class="br60 white write-btn flex row-center m-l-30 xxs" @tap="showInvitePop">填写 |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view class="main"> |
|||
<!-- 填表格 --> |
|||
<view v-if="vipState == 0" class="user-apply-box"> |
|||
<view class="user-apply-vip flex-col col-center"> |
|||
<view class="user-apply-header flex-col col-center"> |
|||
<view class="title xxl normal">申请成为分销会员</view> |
|||
</view> |
|||
<view class="vip-form"> |
|||
<view class="form-item"> |
|||
<u-field v-model="realName" :label-width="150" label="真实姓名:" :border-bottom="false" |
|||
placeholder="请输入您的真实姓名"> |
|||
</u-field> |
|||
</view> |
|||
|
|||
<view class="form-item"> |
|||
<u-field v-model="mobile" :label-width="150" label="手机号码:" :border-bottom="false" |
|||
placeholder="请输入您的手机号码"> |
|||
</u-field> |
|||
</view> |
|||
<view class="form-item" @tap="showRegion=true"> |
|||
<u-field v-model="region" disabled right-icon="arrow-right" :label-width="150" |
|||
label="现住省份:" :border-bottom="false" placeholder="请选择省、市、区"> |
|||
</u-field> |
|||
</view> |
|||
<view class="form-item"> |
|||
<u-field v-model="reason" :label-width="150" type="textarea" label="申请原因:" |
|||
placeholder="(必填)" :field-style="{ height: '250rpx'}" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<button class="apply-btn bg-primary white md m-t-20 flex row-center br60" @tap="formSubmit"> |
|||
立即申请 |
|||
</button> |
|||
<view class="m-t-20 xxs lighter flex row-center">提交成功后,我们将会在1-2个工作日内给您回复</view> |
|||
</view> |
|||
|
|||
<!-- 申请状态 --> |
|||
<view v-if="vipState==1" class="user-result-box"> |
|||
<view class="user-result flex-col col-center"> |
|||
<view class="user-result-header flex-col col-center"> |
|||
<view class="title xxl normal">申请成为分销会员</view> |
|||
</view> |
|||
<view class="user-result-content flex-col col-center"> |
|||
<image class="apply-result-img" |
|||
:src="applyObject.status == 2 ? '/static/images/icon_fail.png' : '/static/images/icon_success.png'" /> |
|||
<view class="m-t-10 nr" style="line-height: 40rpx">{{applyObject.status_str}}</view> |
|||
<view class="apply-fail-reason sm" |
|||
:style="applyObject == 2 ? 'visibility: none' : 'visibility: hidden'"> |
|||
{{applyObject.reason}} |
|||
</view> |
|||
</view> |
|||
<view class="user-result-info"> |
|||
<view class="info-item flex nr"> |
|||
<view class="label">真实姓名:</view> |
|||
<view class="info-text ml20">{{applyObject.real_name}}</view> |
|||
</view> |
|||
<view class="info-item flex nr"> |
|||
<view class="label">手机号码:</view> |
|||
<view class="info-text ml20">{{applyObject.mobile}}</view> |
|||
</view> |
|||
<view class="info-item flex nr"> |
|||
<view class="label">现住省份:</view> |
|||
<view class="info-text ml20">{{applyObject.province}} {{applyObject.city}} |
|||
{{applyObject.district}} |
|||
</view> |
|||
</view> |
|||
<view class="info-item flex nr"> |
|||
<view class="label">申请原因:</view> |
|||
<view class="info-text ml20">{{applyObject.reason ? applyObject.reason : '-'}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view :class="'white m-t-20 br60 apply-btn flex row-center md bg-primary'" @tap="reApply">重新申请 |
|||
</view> |
|||
<view class="m-t-20 xxs lighter flex row-center">提交成功后,我们将会在1-2个工作日内给您回复</view> |
|||
</view> |
|||
|
|||
<!-- 已申请 --> |
|||
<view v-if="vipState==2" class="user-vip"> |
|||
<view class="user-assets-box"> |
|||
<view class="user-assets-header flex row-between"> |
|||
<view class="flex nr bold" style="line-height: 80rpx;color: #8F430E;"> |
|||
可提现佣金: |
|||
<price-format weight="bold" :first-size="36" :subscript-size="26" :second-size="36" |
|||
:price="distributionInfo.able_withdrawal" :color="colorConfig.primary" /> |
|||
</view> |
|||
<navigator hover-class="none" class="primary-btn white flex row-center" |
|||
url="/bundle/pages/user_withdraw/user_withdraw">立即提现</navigator> |
|||
</view> |
|||
<view class="user-assets-content flex flex-wrap"> |
|||
<view class="user-item flex-col col-center"> |
|||
<tool-tip v-if="false" class="m-t-20" id="today-profit" content="今日预估收益金额" |
|||
style="position: absolute;right: -66rpx;"></tool-tip> |
|||
<view class="nr user-assets-name flex" style="color: #8F430E"> |
|||
今日预估收益 |
|||
<!-- <u-icon class="ml10" name="question-circle" size="30rpx" color="#D88D5A" /> --> |
|||
</view> |
|||
<view class="assets m-l-20"> |
|||
<price-format weight="bold" :first-size="36" :subscript-size="26" :second-size="36" |
|||
:price="distributionInfo.today_earnings" :color="colorConfig.primary" /> |
|||
</view> |
|||
</view> |
|||
<view class="user-item flex-col col-center"> |
|||
<view class="nr user-assets-name flex" style="color: #8F430E"> |
|||
本月预估收益 |
|||
<!-- <u-icon class="ml10" name="question-circle" size="30rpx" color="#D88D5A" /> --> |
|||
</view> |
|||
<view class="assets m-l-20"> |
|||
<price-format weight="bold" :first-size="36" :subscript-size="26" :second-size="36" |
|||
:price="distributionInfo.month_earnings" :color="colorConfig.primary" /> |
|||
</view> |
|||
</view> |
|||
<view class="user-item flex-col col-center"> |
|||
<view class="nr user-assets-name flex" style="color: #8F430E"> |
|||
累计获得收益 |
|||
<!-- <u-icon class="ml10" name="question-circle" size="30rpx" color="#D88D5A" /> --> |
|||
</view> |
|||
<view class="assets"> |
|||
<price-format weight="bold" :first-size="36" :subscript-size="26" :second-size="36" |
|||
:price="distributionInfo.history_earnings" :color="colorConfig.primary" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="mt20 fans-msg-box flex bg-white md"> |
|||
<router-link class="flex-1" to="/bundle/pages/user_fans/user_fans"> |
|||
<view class="my-fans flex row-center normal"> |
|||
我的粉丝 <view class="primary m-l-10">{{distributionInfo.fans}}</view> |
|||
<u-icon class="m-l-10" name="arrow-right" size="28rpx" color="#666" /> |
|||
</view> |
|||
</router-link> |
|||
|
|||
|
|||
</view> |
|||
<view class="my-invite-box m-t-20 bg-white flex-col col-center"> |
|||
<view class="my-invite-title sm normal">我的邀请码</view> |
|||
<view class="flex bold m-t-20" style="font-size: 42rpx;line-height: 30rpx"> |
|||
{{userInfo.user.distribution_code}} |
|||
<view class="invite-copy-btn m-l-10 xxs" @click="onCopy">点击复制</view> |
|||
</view> |
|||
<!-- <view class="row-center my-promote-banner bg-primary white">我的推广海报</view> --> |
|||
</view> |
|||
<view class="usual-tools-box bg-white m-t-20"> |
|||
<view class="usual-tools-header flex lg bold"> |
|||
常用工具 |
|||
</view> |
|||
<view class="usual-content flex"> |
|||
|
|||
<router-link class="usual-item" to="/bundle/pages/user_spread_order/user_spread_order"> |
|||
<view class="flex-col col-center"> |
|||
<image src="/bundle/static/icon_fenxiao.png" class="usual-item-img"></image> |
|||
<view class="nr normal m-t-20" style="line-height: 40rpx">分销订单</view> |
|||
</view> |
|||
</router-link> |
|||
<router-link class="usual-item" to="/bundle/pages/commission_details/commission_details"> |
|||
<view class="flex-col col-center"> |
|||
<image src="/bundle/static/icon_yongjin.png" class="usual-item-img"></image> |
|||
<view class="nr normal m-t-20" style="line-height: 40rpx">佣金明细</view> |
|||
</view> |
|||
</router-link> |
|||
<router-link class="usual-item" to="/bundle/pages/monthly_bill/monthly_bill"> |
|||
<view class="flex-col col-center"> |
|||
<image src="/bundle/static/icon_zhangdan.png" class="usual-item-img"></image> |
|||
<view class="nr normal m-t-20" style="line-height: 40rpx">月度账单</view> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<u-popup v-model="showPop" mode="center" closeable border-radius="30"> |
|||
<view class="inviteform-contain flex-col col-center"> |
|||
<view class="title xl">填写邀请人</view> |
|||
<view class="input-row flex"> |
|||
<view style="width: 140rpx;">邀请码:</view> |
|||
<u-input :clearable="false" v-model="inviteCode" placeholder="请输入邀请码" ></u-input> |
|||
</view> |
|||
<view class="btn bg-primary white flex row-center" @tap="bindSuperiorFun">确定</view> |
|||
</view> |
|||
</u-popup> |
|||
<u-select v-model="showRegion" mode="mutil-column-auto" @confirm="regionChange" :list="regionLists"> |
|||
</u-select> |
|||
</view> |
|||
</view> |
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
bindSuperior, |
|||
applyDistribute, |
|||
applyDetail, |
|||
getSuperiorInfo, |
|||
getDistribution, |
|||
veryfiyDistribute |
|||
} from "@/api/user"; |
|||
import area from '@/utils/area' |
|||
import { |
|||
copy |
|||
} from '@/utils/tools' |
|||
export default { |
|||
data() { |
|||
return { |
|||
list: ['成为分销会员,推广下级可获得额外收益,推广越多收益越多'], |
|||
showTips: true, |
|||
showLoading: true, |
|||
// 弹窗展示 |
|||
showPop: false, |
|||
inviteCode: '', |
|||
mobile: '', |
|||
realName: '', |
|||
reason: '', |
|||
region: '', |
|||
// 省id |
|||
provinceId: -1, |
|||
// 市id |
|||
cityId: -1, |
|||
// 区ID |
|||
districtId: -1, |
|||
// 推销状态 0 ==> 未申请 1 ==> 申请进度 2 ==> 已申请 |
|||
vipState: 0, |
|||
userInfo: { |
|||
user: {}, |
|||
leader: {} |
|||
}, |
|||
// 审核信息对象 |
|||
applyObject: {}, |
|||
// 邀请人状态 |
|||
inviteStatus: false, |
|||
showRegion: false, |
|||
regionLists: area, |
|||
distributionInfo: {} |
|||
}; |
|||
}, |
|||
onLoad(options) { |
|||
// 获取上级及个人信息 |
|||
this.getSuperiorInfoFun() |
|||
// 判断是否是分销会员 |
|||
this.veryfiyDistributeFun() |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
// 分销会员信息 |
|||
async getDistributionFun() { |
|||
const { |
|||
data, |
|||
code |
|||
} = await getDistribution() |
|||
if (code == 1) { |
|||
this.showLoading = false |
|||
this.distributionInfo = data |
|||
} |
|||
}, |
|||
|
|||
veryfiyDistributeFun() { |
|||
veryfiyDistribute().then(res => { |
|||
if (res.code == 10001) { |
|||
// 分销会员 |
|||
this.vipState = 2 |
|||
this.getDistributionFun() |
|||
} else if (res.code == 20001) { |
|||
// 非分销会员 |
|||
this.vipState = 0; |
|||
this.applyDetailFun() |
|||
} else if (res.code == 0) { |
|||
// 返回上一页 |
|||
setTimeout(() => { |
|||
uni.navigateBack() |
|||
}, 500) |
|||
} |
|||
}) |
|||
}, |
|||
|
|||
// 最新分销会员申请详情 |
|||
async applyDetailFun() { |
|||
const { |
|||
data, |
|||
code |
|||
} = await applyDetail() |
|||
if (code == 1) { |
|||
this.showLoading = false |
|||
switch (data.status) { |
|||
case 0: |
|||
// 待审核 |
|||
case 2: |
|||
// 审核不通过 |
|||
this.vipState = 1; |
|||
this.applyObject = data |
|||
break; |
|||
} |
|||
} |
|||
}, |
|||
|
|||
reApply() { |
|||
this.vipState = 0 |
|||
}, |
|||
|
|||
regionChange(region) { |
|||
this.region = region[0].label + " " + region[1].label + " " + region[2].label |
|||
this.provinceId = region[0].value; |
|||
this.cityId = region[1].value; |
|||
this.districtId = region[2].value |
|||
}, |
|||
|
|||
async formSubmit() { |
|||
let { |
|||
provinceId, |
|||
cityId, |
|||
districtId, |
|||
reason, |
|||
mobile, |
|||
realName, |
|||
region |
|||
} = this; |
|||
|
|||
if (!realName) { |
|||
this.$toast({ |
|||
title: "请填写真实姓名" |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (!region.length) { |
|||
this.$toast({ |
|||
title: "请选择省市区" |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
let params = { |
|||
real_name: realName, |
|||
province: provinceId, |
|||
city: cityId, |
|||
district: districtId, |
|||
reason: reason, |
|||
mobile |
|||
}; |
|||
const { |
|||
data, |
|||
code, |
|||
msg |
|||
} = await applyDistribute(params) |
|||
if (code == 1) { |
|||
this.$toast({ |
|||
title: msg |
|||
}); |
|||
this.applyDetailFun(); |
|||
} |
|||
}, |
|||
|
|||
|
|||
// 填写邀请码 |
|||
bindSuperiorFun() { |
|||
bindSuperior({ |
|||
code: this.inviteCode |
|||
}).then(res => { |
|||
this.$toast({ |
|||
title: res.msg |
|||
}) |
|||
if (res.code == 1) { |
|||
this.showPop = false |
|||
this.getSuperiorInfoFun(); |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
showInvitePop() { |
|||
this.showPop = true; |
|||
}, |
|||
|
|||
// 获取邀请人信息 |
|||
async getSuperiorInfoFun() { |
|||
const { |
|||
data, |
|||
code |
|||
} = await getSuperiorInfo() |
|||
if (code == 1) { |
|||
this.userInfo = data |
|||
} |
|||
}, |
|||
onCopy() { |
|||
copy(this.userInfo.user.distribution_code) |
|||
}, |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.user-spread { |
|||
background-image: url(../../static/spread_top_bg.png); |
|||
background-repeat: no-repeat; |
|||
background-size: 100% auto; |
|||
|
|||
.header { |
|||
|
|||
.user-info { |
|||
.user-avatar { |
|||
position: relative; |
|||
|
|||
|
|||
} |
|||
.avatar-tag { |
|||
display: inline-block; |
|||
background-color: #F79C0C; |
|||
border: 1rpx solid #FFFFFF; |
|||
border-radius: 100rpx; |
|||
line-height: 32rpx; |
|||
padding: 0 10rpx; |
|||
} |
|||
.user-message { |
|||
.write-btn { |
|||
height: 42rpx; |
|||
width: 100rpx; |
|||
background-color: #FF838D; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.main { |
|||
padding: 0 20rpx; |
|||
|
|||
.user-vip { |
|||
.user-assets-box { |
|||
background-color: #fff; |
|||
border-radius: 20rpx; |
|||
padding: 10rpx 20rpx 22rpx; |
|||
background: linear-gradient(90deg, #FBEFDB 0%, #FED09E 100%); |
|||
|
|||
.user-assets-header { |
|||
border-bottom: 1rpx dashed #8F430E; |
|||
padding-bottom: 4rpx; |
|||
|
|||
.primary-btn { |
|||
height: 54rpx; |
|||
border-radius: 120rpx; |
|||
width: 144rpx; |
|||
background: linear-gradient(180deg, #FF3067 0%, #FF2C3C 100%); |
|||
} |
|||
} |
|||
|
|||
.user-assets-content { |
|||
margin-top: 30rpx; |
|||
|
|||
.user-item { |
|||
flex: 1; |
|||
position: relative; |
|||
|
|||
.user-assets-name { |
|||
text-align: left; |
|||
align-self: flex-start; |
|||
} |
|||
|
|||
.assets { |
|||
margin-top: 14rpx; |
|||
text-align: left; |
|||
align-self: flex-start; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.fans-msg-box { |
|||
border-radius: 10rpx; |
|||
line-height: 42rpx; |
|||
|
|||
.my-fans { |
|||
height: 120rpx; |
|||
} |
|||
|
|||
.line { |
|||
width: 3rpx; |
|||
height: 60rpx; |
|||
background-color: #E5E5E5; |
|||
} |
|||
|
|||
.invite-fans { |
|||
height: 120rpx; |
|||
} |
|||
} |
|||
|
|||
.my-invite-box { |
|||
padding: 26rpx 0 57rpx; |
|||
border-radius: 10rpx; |
|||
|
|||
.invite-copy-btn { |
|||
line-height: 30rpx; |
|||
padding: 10rpx; |
|||
background: linear-gradient(90deg, #FEE4B4 0%, #FBCB96 100%); |
|||
color: #8F430E; |
|||
border-radius: 4rpx; |
|||
} |
|||
|
|||
.my-promote-banner { |
|||
margin-top: 30rpx; |
|||
height: 148rpx; |
|||
width: 542rpx; |
|||
border-radius: 10rpx; |
|||
} |
|||
} |
|||
|
|||
.usual-tools-box { |
|||
border-radius: 10rpx; |
|||
padding: 0 25rpx; |
|||
|
|||
.usual-tools-header { |
|||
height: 100rpx; |
|||
line-height: 44rpx; |
|||
border-bottom: $-solid-border; |
|||
} |
|||
|
|||
.usual-content { |
|||
padding: 40rpx 0; |
|||
|
|||
.usual-item { |
|||
width: 25%; |
|||
|
|||
.usual-item-img { |
|||
width: 56rpx; |
|||
height: 56rpx; |
|||
flex: none; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.user-apply-box { |
|||
.user-apply-vip { |
|||
background-color: white; |
|||
padding: 40rpx 0 0rpx; |
|||
border-radius: 20rpx; |
|||
|
|||
.title { |
|||
line-height: 30rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.explain { |
|||
margin-top: 20rpx; |
|||
|
|||
image { |
|||
width: 24rpx; |
|||
height: 24rpx; |
|||
flex: none; |
|||
} |
|||
|
|||
span { |
|||
font-size: 20rpx; |
|||
line-height: 30rpx; |
|||
} |
|||
} |
|||
|
|||
.vip-form { |
|||
width: 100%; |
|||
margin-top: 60rpx; |
|||
|
|||
.form-item { |
|||
border: $-solid-border; |
|||
margin: 0 30rpx 30rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.apply-btn { |
|||
line-height: 30rpx; |
|||
height: 82rpx; |
|||
} |
|||
} |
|||
|
|||
.user-result-box { |
|||
.user-result { |
|||
background-color: white; |
|||
padding: 36rpx 14rpx 50rpx; |
|||
border-radius: 20rpx; |
|||
|
|||
.user-result-header { |
|||
.title { |
|||
line-height: 30rpx; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
} |
|||
.user-result-content { |
|||
padding: 60rpx 0 22rpx; |
|||
width: 100%; |
|||
border-bottom: $-solid-border; |
|||
|
|||
.apply-result-img { |
|||
width: 100rpx; |
|||
height: 100rpx; |
|||
} |
|||
} |
|||
|
|||
.user-result-info { |
|||
margin-top: 42rpx; |
|||
width: 100%; |
|||
|
|||
.info-item { |
|||
margin-left: 60rpx; |
|||
margin-bottom: 28rpx; |
|||
line-height: 30rpx; |
|||
|
|||
.label { |
|||
width: 140rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.apply-btn { |
|||
line-height: 30rpx; |
|||
height: 82rpx; |
|||
} |
|||
|
|||
.bg-gray { |
|||
background-color: #CCCCCC; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
.main .user-apply-box .apply-btn { |
|||
line-height: 30rpx; |
|||
height: 82rpx; |
|||
} |
|||
|
|||
.main .user-result-box .user-result-content .apply-fail-reason { |
|||
color: $-color-primary; |
|||
line-height: 36rpx; |
|||
margin-top: 10rpx; |
|||
} |
|||
|
|||
/* 弹窗 */ |
|||
.inviteform-contain { |
|||
padding-left: 30rpx; |
|||
padding-right: 30rpx; |
|||
padding-bottom: 30rpx; |
|||
width: 580rpx; |
|||
border-radius: 6rpx; |
|||
background-color: $-color-white; |
|||
} |
|||
|
|||
.inviteform-contain .title { |
|||
padding: 26rpx 0rpx; |
|||
} |
|||
|
|||
.inviteform-contain .modify-row { |
|||
padding: 32rpx 0px; |
|||
width: 100%; |
|||
border-bottom: 1rpx solid #E5E5E5; |
|||
} |
|||
|
|||
.inviteform-contain .btn { |
|||
height: 80rpx; |
|||
padding: 0 180rpx; |
|||
border-radius: 10rpx; |
|||
margin-top: 60rpx; |
|||
} |
|||
|
|||
</style> |
|||
@ -0,0 +1,48 @@ |
|||
<template> |
|||
<view class="user-promote-order"> |
|||
<tabs :current="active" @change="onChange" bar-width="60" :is-scroll="false"> |
|||
<tab v-for="(item, index) in order" :key="index" :name="item.name"> |
|||
<spread-order :type="item.type" :i="index" :index="active"></spread-order> |
|||
</tab> |
|||
</tabs> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
|
|||
import { distributionOrder } from "@/utils/type"; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
order: [{ |
|||
name: "全部", |
|||
type: distributionOrder.ALL, |
|||
}, { |
|||
name: "待返佣", |
|||
type: distributionOrder.WAIT_RETURN, |
|||
}, { |
|||
name: "已结算", |
|||
type: distributionOrder.HANDLED, |
|||
}, { |
|||
name: "已失效", |
|||
type: distributionOrder.INVALED, |
|||
}], |
|||
active: distributionOrder.ALL |
|||
}; |
|||
}, |
|||
|
|||
|
|||
onLoad: function (options) { |
|||
|
|||
}, |
|||
|
|||
methods: { |
|||
onChange(index) { |
|||
this.active = index |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
</style> |
|||
@ -0,0 +1,253 @@ |
|||
<template> |
|||
<view> |
|||
<view class="user-vip"> |
|||
<view class="header"> |
|||
<view class="user-vip-info flex"> |
|||
<u-image width="110rpx" height="110rpx" border-radius="50%" :src="userInfo.avatar"></u-image> |
|||
<view class="m-l-20"> |
|||
<view class="user-text white xxl flex">{{userInfo.nickname}}</view> |
|||
<view class="flex"> |
|||
<view class="user-level white xs flex row-center m-t-10">当前等级:{{userInfo.level_name || "无"}}</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="content m-t-50"> |
|||
<view class="vip-swiper-container"> |
|||
<swiper class="swiper" style="height: 360rpx" previous-margin="30rpx" |
|||
:current="currentIndex" @change="bindchange"> |
|||
<swiper-item v-for="(item, index) in levelList" :key="index"> |
|||
<view class="vip-card-item" :style="'background-image: url(' + item.background_image + ');'"> |
|||
<view class="flex row-between"> |
|||
<view class="flex grade white sm"> |
|||
{{item.lock_desc}} |
|||
<!-- <view v-if="item.current_level_status == 1" class="flex grade white sm">当前等级</view> |
|||
<view v-else-if="item.current_level_status == -1" class="flex white sm ml20">未解锁</view> |
|||
<view v-else-if="item.current_level_status == 0" class="flex white sm ml20">已解锁</view> --> |
|||
</view> |
|||
<image class="grade-icon m-r-34" :src="item.image"></image> |
|||
</view> |
|||
<view class="flex row-between vip-name white"> |
|||
<view class="bold">{{item.name}}</view> |
|||
<!-- <view class="sm">{{item.tips2}}</view> --> |
|||
</view> |
|||
<view class="flex row-center m-l-30 m-r-30" v-if="item.diff_growth_percent"> |
|||
<view class="vip-progress bg-white flex"> |
|||
<view class="vip-progress-bar" :style="'width: ' + (item.diff_growth_percent*100) + '%'"></view> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between m-t-30" style="padding: 0 30rpx"> |
|||
<view class="sm white" style="line-height: 36rpx" v-if="item.current_level_status == 0"> |
|||
{{item.tips1}} |
|||
</view> |
|||
<router-link to="/bundle/pages/user_growth/user_growth" class="flex" v-else> |
|||
<view class="sm white" style="line-height: 36rpx"> |
|||
<!-- {{item.current_level_status == 0 ? '当前高于该等级' : item.current_growth_tips}} --> |
|||
{{item.tips1}} <u-icon name="arrow-right"></u-icon> |
|||
</view> |
|||
</router-link> |
|||
<view class="white">{{item.tips2}}</view> |
|||
</view> |
|||
</view> |
|||
</swiper-item> |
|||
</swiper> |
|||
</view> |
|||
<view class="vip-grade-rule"> |
|||
<view class="title flex"> |
|||
<view class="line br60"></view> |
|||
<view class="xl m-l-20 bold">说明</view> |
|||
</view> |
|||
<view class="p-t-20"> |
|||
<text class="rule-content column lighter"> |
|||
{{growthRule}} |
|||
</text> |
|||
</view> |
|||
</view> |
|||
<!-- <view class="vip-rights"> |
|||
<view class="title flex"> |
|||
<view class="line br60"></view> |
|||
<view class="xl ml20 bold">会员权益</view> |
|||
</view> |
|||
<view class="rights-list flex"> |
|||
<view v-for="(item, index) in privilegeList" :key="index" class="rights-item column-center"> |
|||
<image class="mb10" :src="item.image"></image> |
|||
<view class="sm">{{item.name}}</view> |
|||
</view> |
|||
</view> |
|||
</view> --> |
|||
</view> |
|||
</view> |
|||
<loading-view v-if="!userInfo.nickname"></loading-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
getLevelList |
|||
} from '@/api/user'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
userInfo: {}, |
|||
currentIndex: 0, |
|||
levelList: [], |
|||
growthRule: "", |
|||
privilegeList: [] |
|||
}; |
|||
}, |
|||
|
|||
|
|||
onLoad() { |
|||
this.getLevelListFun(); |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
bindchange(e) { |
|||
let { |
|||
current |
|||
} = e.detail; |
|||
let currentLevel = this.levelList[current]; |
|||
this.currentIndex = current |
|||
}, |
|||
|
|||
getLevelListFun() { |
|||
getLevelList().then(res => { |
|||
const { |
|||
code, |
|||
data |
|||
} = res; |
|||
if (code != 1) return; |
|||
const { |
|||
user, |
|||
level_intro, |
|||
level |
|||
} = data; |
|||
let index = level.findIndex(item => item.current_level_status == 1); |
|||
if (index == -1) index = 0; |
|||
this.userInfo = user |
|||
this.growthRule = level_intro |
|||
this.levelList = level |
|||
this.currentIndex = index |
|||
}); |
|||
}, |
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
page { |
|||
background-color: #fff; |
|||
background-image: url(../../static/vip_grade_bg.png); |
|||
background-size: 100% auto; |
|||
background-repeat: no-repeat; |
|||
.user-vip { |
|||
.header { |
|||
padding-top: 40rpx; |
|||
.user-vip-info { |
|||
padding-left: 30rpx; |
|||
|
|||
.user-level { |
|||
border: 1px solid white; |
|||
border-radius: 100rpx; |
|||
padding: 4rpx 20rpx; |
|||
line-height: 30rpx; |
|||
} |
|||
|
|||
.user-text { |
|||
line-height: 50rpx; |
|||
font-weight: bold; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.content { |
|||
|
|||
.vip-card-item { |
|||
height: 360rpx; |
|||
width: 690rpx; |
|||
position: relative; |
|||
background-size: 100% 100%; |
|||
|
|||
.grade { |
|||
line-height: 36rpx; |
|||
background-color: rgba(0, 0, 0, 0.5); |
|||
border-top-right-radius: 100rpx; |
|||
border-bottom-right-radius: 100rpx; |
|||
height: 50rpx; |
|||
padding: 0 28rpx; |
|||
} |
|||
|
|||
.user-grade { |
|||
line-height: 36rpx; |
|||
margin-left: 30rpx; |
|||
} |
|||
|
|||
.grade-icon { |
|||
width: 160rpx; |
|||
height: 145rpx; |
|||
} |
|||
|
|||
.vip-name { |
|||
padding: 10rpx 30rpx; |
|||
font-size: 46rpx; |
|||
text-align: center; |
|||
align-items: flex-end; |
|||
margin-bottom: 30rpx; |
|||
margin-top: -20rpx; |
|||
} |
|||
|
|||
.vip-progress { |
|||
height: 8rpx; |
|||
border-radius: 8rpx; |
|||
width: 100%; |
|||
overflow: hidden; |
|||
.vip-progress-bar { |
|||
background-color: #f8d07c; |
|||
height: 100%; |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
.vip-grade-rule { |
|||
margin: 24rpx 40rpx; |
|||
|
|||
.title { |
|||
.line { |
|||
width: 8rpx; |
|||
height: 34rpx; |
|||
background-color: #f79c0c; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.vip-rights { |
|||
margin: 24rpx 40rpx; |
|||
|
|||
.title { |
|||
padding: 28rpx 0; |
|||
|
|||
.line { |
|||
width: 8rpx; |
|||
height: 34rpx; |
|||
background-color: #f79c0c; |
|||
} |
|||
} |
|||
|
|||
.rights-item { |
|||
width: 25%; |
|||
padding-bottom: 30rpx; |
|||
|
|||
image { |
|||
width: 82rpx; |
|||
height: 82rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,212 @@ |
|||
<template> |
|||
<view class="user-wallet"> |
|||
<view class="contain bg-white m-b-20"> |
|||
<!-- 资产总计 --> |
|||
<view class="header"> |
|||
<view class="white m-b-20"> |
|||
<view class="xs">总资产(元)</view> |
|||
<view style="font-size: 76rpx">{{wallet.user_money || '0.00'}}</view> |
|||
</view> |
|||
<view class="money white flex"> |
|||
<view class="item"> |
|||
<view class="xs">累计充值(元)</view> |
|||
<view style="font-size: 38rpx">{{wallet.total_recharge_amount || '0.00'}}</view> |
|||
</view> |
|||
<view class="item"> |
|||
<view class="xs">累计消费(元)</view> |
|||
<view style="font-size: 38rpx">{{wallet.total_order_amount || '0.00'}}</view> |
|||
</view> |
|||
<template v-if="wallet.open_racharge"> |
|||
<router-link style="height: 58rpx;" class="flex primary bg-white br60 btn" size="xs" |
|||
to="/bundle/pages/user_payment/user_payment">充值</router-link> |
|||
</template> |
|||
</view> |
|||
</view> |
|||
|
|||
|
|||
<!-- 资金明细 --> |
|||
<view class="nav flex"> |
|||
|
|||
<!-- <router-link class="nav-item"> |
|||
<view class="flex-col col-center"> |
|||
<image class="icon" src="../../static/icon_yezz.png"></image> |
|||
<view class="m-t-10 sm">余额转账</view> |
|||
</view> |
|||
</router-link> --> |
|||
<router-link class="nav-item" to="/bundle/pages/user_bill/user_bill"> |
|||
<view class="flex-col col-center"> |
|||
<image class="icon" src="../../static/icon_zhmx.png"></image> |
|||
<view class="m-t-10 sm">账户明细</view> |
|||
</view> |
|||
</router-link> |
|||
<!-- <router-link class="nav-item"> |
|||
<view class="flex-col col-center"> |
|||
<image class="icon" src="../../static/icon_zzjl.png"></image> |
|||
<view class="m-t-10 sm">转账记录</view> |
|||
</view> |
|||
</router-link> --> |
|||
<router-link class="nav-item" to="/bundle/pages/recharge_record/recharge_record"> |
|||
<view class="flex-col col-center"> |
|||
<image class="icon" src="../../static/icon_czjl.png"></image> |
|||
<view class="m-t-10 sm">充值记录</view> |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
|
|||
|
|||
<!-- 热门活动 --> |
|||
<view class="activity"> |
|||
<view class="activity-title xl flex"> |
|||
<view class="m-r-20 bg-primary" style="width: 6rpx;height: 30rpx;"></view> |
|||
<text>热门活动</text> |
|||
</view> |
|||
<block v-for="(item, index) in activityList" :key="item.title"> |
|||
<view class="activity-item flex row-between" :style="{backgroundColor: item.background}"> |
|||
<view> |
|||
<view class="xl normal" style="font-weight: 500;">{{ item.title }}</view> |
|||
<view class="muted sm m-t-10">{{ item.slogan }}</view> |
|||
<router-link style="display: inline-block;" :to="item.href"> |
|||
<view :style="{backgroundColor: item.buttonColor}" |
|||
class="br60 white join-btn flex row-center">立即参与</view> |
|||
</router-link> |
|||
</view> |
|||
<image style="width:274rpx; height: 210rpx;" :src="item.image"></image> |
|||
</view> |
|||
</block> |
|||
</view> |
|||
|
|||
</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 { |
|||
getWallet |
|||
} from '@/api/user'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
wallet: {}, |
|||
// 热门活动列表数据 |
|||
activityList: [ |
|||
|
|||
{ |
|||
title: "领取优惠券", |
|||
slogan: "每日优惠券抢不停", |
|||
button: "立即抢购", |
|||
buttonColor: "#FC597A", |
|||
href: "/pages/get_coupon/get_coupon", |
|||
image: "/bundle/static/img_activity_coupon.png", |
|||
background: "rgba(252, 89, 122, 0.1)" |
|||
}, |
|||
{ |
|||
title: "超值商品 限时秒杀", |
|||
slogan: "最新商品秒杀中", |
|||
button: "立即抢购", |
|||
buttonColor: "#FF2C3C", |
|||
href: "/bundle/pages/goods_seckill/goods_seckill", |
|||
image: "/bundle/static/img_activity_seckill.png", |
|||
background: "rgba(236, 71, 37, 0.1)" |
|||
} |
|||
] |
|||
}; |
|||
}, |
|||
|
|||
onShow() { |
|||
this.getWalletFun(); |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
getWalletFun() { |
|||
getWallet().then(res => { |
|||
if (res.code == 1) { |
|||
this.wallet = res.data |
|||
} |
|||
}); |
|||
}, |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.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 { |
|||
border-bottom: $-solid-border; |
|||
|
|||
.nav-item { |
|||
width: 25%; |
|||
padding: 40rpx 0; |
|||
|
|||
.icon { |
|||
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,250 @@ |
|||
<!-- 提现 --> |
|||
|
|||
<template> |
|||
<view class="user-withdraw"> |
|||
<!-- Tabs --> |
|||
<view class="withdraw-tabs"> |
|||
<u-tabs :list="tabsList" :is-scroll="true" :current="currentTab" :bold="true" height="100" |
|||
font-size="30rpx" active-color="#333333" inactive-color="#666666" :bar-style="styleTabsBarStyle" |
|||
@change="changeTab" /> |
|||
</view> |
|||
|
|||
|
|||
<!-- 微信钱包 --> |
|||
<view v-if="currentValue == 3" class="withdraw-wechat m-t-20 bg-white"> |
|||
<!-- Account --> |
|||
<u-field label-width="160" label="微信账号" v-model="form.account" placeholder="请输入微信账号" /> |
|||
<!-- Name --> |
|||
<u-field label-width="160" label="真实姓名" v-model="form.real_name" placeholder="请输入真实姓名" /> |
|||
<!-- Remark --> |
|||
<u-field label-width="160" label="备注" v-model="form.remark" placeholder="(选填)" /> |
|||
|
|||
<!-- 上传图片 --> |
|||
<view class="flex-col m-t-20"> |
|||
<u-upload ref="uUpload" :header="{token: $store.getters.token}" :auto-upload="true" :show-progress="false" max-count="1" width="142" height="142" :custom-btn="true" :action="action" @on-success="onSuccess" @on-remove="onRemove" > |
|||
<view slot="addBtn" class="flex-col col-center row-center"> |
|||
<view class="upload-image flex-col col-center row-center" > |
|||
<u-icon name="/bundle/static/icon_camera_line.png" width="54" /> |
|||
</view> |
|||
|
|||
<view class="xs m-t-10">微信收款码</view> |
|||
</view> |
|||
</u-upload> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 支付宝 --> |
|||
<view v-else-if="currentValue == 4" class="withdraw-alipay m-t-20 bg-white"> |
|||
<!-- Account --> |
|||
<u-field label-width="160" label="支付宝账号" v-model="form.account" placeholder="请输入支付宝账号" /> |
|||
<!-- Name --> |
|||
<u-field label-width="160" label="真实姓名" v-model="form.real_name" placeholder="请输入真实姓名" /> |
|||
<!-- Remark --> |
|||
<u-field label-width="160" label="备注" v-model="form.remark" placeholder="(选填)" /> |
|||
|
|||
<!-- 上传图片 --> |
|||
<view class="flex-col m-t-20"> |
|||
<u-upload ref="uUpload" :header="{token: $store.getters.token}" :auto-upload="true" :show-progress="false" max-count="1" width="142" height="142" :custom-btn="true" :action="action" @on-success="onSuccess" @on-remove="onRemove" > |
|||
<view slot="addBtn" class="flex-col col-center row-center"> |
|||
<view class="upload-image flex-col col-center row-center" > |
|||
<u-icon name="/bundle/static/icon_camera_line.png" width="54" /> |
|||
</view> |
|||
|
|||
<view class="xs m-t-10">支付宝收款码</view> |
|||
</view> |
|||
</u-upload> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 银行卡 --> |
|||
<view v-else-if="currentValue == 5" class="withdraw-alipay m-t-20 bg-white"> |
|||
<!-- Account --> |
|||
<u-field label-width="160" label="银行卡账号" v-model="form.account" placeholder="请输入银行卡账号" /> |
|||
<!-- Name --> |
|||
<u-field label-width="160" label="持卡人姓名" v-model="form.real_name" placeholder="请输入持卡人姓名" /> |
|||
<!-- Name --> |
|||
<u-field label-width="160" label="提现银行" v-model="form.bank" placeholder="请输入银行名称" /> |
|||
<!-- Remark --> |
|||
<u-field label-width="160" label="银行支行" v-model="form.subbank" placeholder="如:金湾支行" /> |
|||
<!-- Remark --> |
|||
<u-field label-width="160" label="备注" v-model="form.remark" placeholder="(选填)" /> |
|||
</view> |
|||
|
|||
<!-- 提现金额 --> |
|||
<view class="withdraw-money-wrap m-t-20 bg-white"> |
|||
<view class="flex withdraw-money p-b-20"> |
|||
<view class="flex flex-1"> |
|||
<text class="font-size-46 m-r-10 normal">¥</text> |
|||
<u-input v-model="form.money" placeholder="0.00" :custom-style="{ |
|||
'font-size': '66rpx' |
|||
}" /> |
|||
</view> |
|||
<view class="flex-col flex-1 text-right"> |
|||
<text class="xs primary" @tap="form.money=widthDrawConfig.able_withdraw">全部提现</text> |
|||
<text class="xs muted m-t-10">可提现金额 ¥ {{widthDrawConfig.able_withdraw}}</text> |
|||
</view> |
|||
</view> |
|||
<view class="muted xs m-t-30" v-if="widthDrawConfig.poundage_percent && currentValue != 1">提示:提现需扣除服务费{{widthDrawConfig.poundage_percent}}%</view> |
|||
</view> |
|||
|
|||
<!-- 确认提交 --> |
|||
<button class="withdraw-submit m-t-30 white br60" @tap="onSubmit" size="lg">确认提交</button> |
|||
|
|||
<!-- 提现记录 --> |
|||
<router-link to="/bundle/pages/user_withdraw_code/user_withdraw_code"> |
|||
<view class="withdraw-log m-t-40 text-center muted">提现记录</view> |
|||
</router-link> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
|
|||
<script> |
|||
import { |
|||
applyWithdraw, |
|||
getWithdrawConfig |
|||
} from "@/api/user"; |
|||
import { |
|||
trottle |
|||
} from "@/utils/tools"; |
|||
import { |
|||
baseURL |
|||
} from '@/config/app'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
action: baseURL + '/api/file/formimage', |
|||
currentTab: 0, // Tabs当前位置 |
|||
// Tabs 列表 |
|||
tabsList: [], |
|||
// Tabs滑块样式 |
|||
styleTabsBarStyle: { |
|||
bottom: '12rpx', |
|||
width: '50rpx', |
|||
height: '6rpx', |
|||
background: 'green', |
|||
borderRadius: '50px', |
|||
backgroundImage: 'linear-gradient(to right, \#F79C0C, \#FF2C3C)' |
|||
}, |
|||
// 表单数据 |
|||
form: { |
|||
money: '', // 提现金额 |
|||
account: '', // 账户名称 |
|||
real_name: '', // 真实姓名 |
|||
money_qr_code: '', // 收款二维码 |
|||
bank: '', // 银行 |
|||
subbank: '', // 支行 |
|||
remark: '', // 备注 |
|||
}, |
|||
widthDrawConfig: {} |
|||
} |
|||
}, |
|||
onLoad() { |
|||
this.getWithdrawConfigFun(); |
|||
this.onSubmit = trottle(this.onSubmit, 1000, this) |
|||
}, |
|||
methods: { |
|||
// 改变当前的Tabs位置 |
|||
changeTab(index) { |
|||
this.currentTab = index; |
|||
this.form = { |
|||
money: '', |
|||
account: '', |
|||
real_name: '', |
|||
money_qr_code: '', |
|||
remark: '', |
|||
bank: '', |
|||
subbank: '' |
|||
}; |
|||
}, |
|||
async getWithdrawConfigFun() { |
|||
const { |
|||
code, |
|||
data |
|||
} = await getWithdrawConfig() |
|||
|
|||
if (code == 1) { |
|||
this.widthDrawConfig = data |
|||
this.tabsList = data.type |
|||
} |
|||
}, |
|||
// 提交表单 |
|||
onSubmit() { |
|||
const data = { |
|||
...this.form |
|||
} |
|||
data.type = this.currentValue |
|||
if (!data.money) { |
|||
this.$toast({ |
|||
title: '请输入提现金额' |
|||
}); |
|||
return; |
|||
} |
|||
applyWithdraw(data).then(res => { |
|||
if (res.code == 1) { |
|||
this.$toast({ |
|||
title: '提交成功' |
|||
}, { |
|||
tab: 2, |
|||
url: '/bundle/pages/widthdraw_result/widthdraw_result?id=' + res.data.id |
|||
}); |
|||
} |
|||
}); |
|||
}, |
|||
onSuccess(e) { |
|||
console.log(e) |
|||
this.form.money_qr_code = e.data.base_uri |
|||
}, |
|||
onRemove(index) { |
|||
this.form.money_qr_code = "" |
|||
}, |
|||
}, |
|||
computed: { |
|||
currentValue(val) { |
|||
const {currentTab, tabsList} = this |
|||
return tabsList[currentTab] ? tabsList[currentTab].value : '' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
|
|||
<style lang="scss" scoped> |
|||
.user-withdraw { |
|||
padding: 20rpx 30rpx; |
|||
|
|||
.withdraw-tabs { |
|||
border-radius: 10px; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.withdraw-money-wrap { |
|||
padding: 50rpx 66rpx; |
|||
border-radius: 10px; |
|||
|
|||
.withdraw-money { |
|||
border-bottom: $-solid-border; |
|||
} |
|||
} |
|||
|
|||
.withdraw-wechat, |
|||
.withdraw-alipay { |
|||
padding: 0 36rpx 20rpx; |
|||
border-radius: 10px; |
|||
} |
|||
|
|||
.upload-image { |
|||
width: 142rpx; |
|||
height: 142rpx; |
|||
border: 2rpx dashed #CCCCCC; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
.withdraw-submit { |
|||
background: linear-gradient(11deg, #F95F2F, #FF2C3C); |
|||
} |
|||
::v-deep .u-field { |
|||
padding: 26rpx 0; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,97 @@ |
|||
<!-- 账户明细 --> |
|||
|
|||
<template> |
|||
<view class="user-withdraw-code"> |
|||
<mescroll-body ref="mescrollRef" @init="mescrollInit" @up="upCallback" :up="upOption" |
|||
@down="downCallback"> |
|||
<view class="list p-t-20"> |
|||
<view class="item bg-white" v-for="(item,index) in list" :key="index"> |
|||
<router-link :to="{path: '/bundle/pages/widthdraw_result/widthdraw_result', query: {id: item.id}}"> |
|||
<view class="flex row-between"> |
|||
<view class="md ">{{item.desc}}</view> |
|||
<view> |
|||
<text class="xxl">-{{item.money}}</text> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between"> |
|||
<view class="xs muted">{{item.create_time}}</view> |
|||
<view class="xs" :style="{color: [styleWithdrawStatus(item.status)]}">{{item.status_text}}</view> |
|||
</view> |
|||
<view class="m-t-10 sm primary" v-if="item.description && item.status == 4"> |
|||
{{item.description}} |
|||
</view> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
</mescroll-body> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
|||
import { |
|||
getWithdrawRecords |
|||
} from "@/api/user" |
|||
export default { |
|||
mixins: [MescrollMixin], // 使用mixin |
|||
data() { |
|||
return { |
|||
upOption: { |
|||
empty: { |
|||
icon: '/static/images/order_null.png', |
|||
tip: '暂无记录', // 提示 |
|||
} |
|||
}, |
|||
list: [], // 列表数据--全部 |
|||
}; |
|||
}, |
|||
|
|||
methods: { |
|||
|
|||
// 上拉加载 |
|||
upCallback(page) { |
|||
const pageNum = page.num; // 页码, 默认从1开始 |
|||
const pageSize = page.size; // 页长, 默认每页10条 |
|||
getWithdrawRecords({ |
|||
page_size: pageSize, |
|||
page_no: pageNum, |
|||
}).then(({ |
|||
data |
|||
}) => { |
|||
if (page.num == 1) this.list = []; |
|||
const curPageData = data.list; |
|||
const curPageLen = curPageData.length; |
|||
const hasNext = !!data.more; |
|||
this.list = this.list.concat(curPageData); |
|||
this.mescroll.endSuccess(curPageLen, hasNext); |
|||
}).catch(() => { |
|||
this.mescroll.endErr() |
|||
}) |
|||
|
|||
}, |
|||
styleWithdrawStatus(status) { |
|||
switch(status) { |
|||
case 1: return '#0CC21E'; |
|||
case 2: return '#666666'; |
|||
case 3: return '#FF2C3C'; |
|||
case 4: return '#FF2C3C'; |
|||
} |
|||
} |
|||
}, |
|||
|
|||
onLoad(options) { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.user-withdraw-code { |
|||
.item { |
|||
padding: 22rpx 30rpx; |
|||
&:not(:last-of-type) { |
|||
border-bottom: $-solid-border; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,127 @@ |
|||
|
|||
|
|||
<template> |
|||
<view class="widthdraw-result"> |
|||
<view class="contain bg-white"> |
|||
<view class="header flex-col col-center"> |
|||
<view> |
|||
<image class="tips-icon" :src="getTipsIcon(widthdrawInfo.status)"></image> |
|||
</view> |
|||
<view class="xl m-t-20 bold">{{widthdrawInfo.statusDesc}}</view> |
|||
<view class="flex-col col-center"> |
|||
<price-format :price="widthdrawInfo.money" :color="colorConfig.primary" subscript-size="30" first-size="46" second-size="46" weight="bold" /> |
|||
</view> |
|||
</view> |
|||
<view class="info"> |
|||
<view class="flex row-between m-t-20"> |
|||
<view>流水号</view> |
|||
<view> |
|||
{{widthdrawInfo.sn}} |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<view>提交时间</view> |
|||
<view>{{widthdrawInfo.create_time}}</view> |
|||
</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<view>提现至</view> |
|||
<view>{{widthdrawInfo.typeDesc}}</view> |
|||
</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<view>服务费</view> |
|||
<view> |
|||
<price-format :price="widthdrawInfo.poundage"></price-format> |
|||
</view> |
|||
</view> |
|||
<view class="flex row-between m-t-20"> |
|||
<view>实际到账</view> |
|||
<view> |
|||
<price-format :price="widthdrawInfo.left_money"></price-format> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="line m-t-40"></view> |
|||
<view class="m-t-40 flex-col row-center"> |
|||
<router-link to="/bundle/pages/user_withdraw_code/user_withdraw_code"> |
|||
<button type="primary" size="lg" class="br60">查看历史提现记录</button> |
|||
</router-link> |
|||
<router-link navType="pushTab" to="/pages/index/index"> |
|||
<button size="lg" class="br60 plain primary m-t-30">返回首页</button> |
|||
</router-link> |
|||
</view> |
|||
</view> |
|||
<view class="muted m-t-20 xs text-center">* 审核通过后约72小时内到账,请留意账户明细</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getWithdrawDetail } from '@/api/user'; |
|||
|
|||
export default { |
|||
data() { |
|||
return { |
|||
widthdrawInfo: {} |
|||
}; |
|||
}, |
|||
|
|||
onLoad () { |
|||
this.id = this.$Route.query.id |
|||
this.getWithdrawDetailFun(); |
|||
}, |
|||
|
|||
|
|||
methods: { |
|||
getWithdrawDetailFun() { |
|||
getWithdrawDetail({ |
|||
id: this.id |
|||
}).then(res => { |
|||
if (res.code == 1) { |
|||
this.widthdrawInfo = res.data |
|||
} |
|||
}); |
|||
}, |
|||
getTipsIcon(status) { |
|||
// status 状态:1-待提现2-提现中3-提现成功4-提现失败 |
|||
switch(status) { |
|||
case 1: |
|||
case 2: return '/static/images/icon_wait.png' |
|||
case 3: return '/static/images/icon_success.png' |
|||
case 4: return '/static/images/icon_fail.png' |
|||
} |
|||
} |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
<style lang="scss"> |
|||
.widthdraw-result { |
|||
.contain { |
|||
border-radius: 10rpx; |
|||
padding: 0 30rpx 40rpx; |
|||
position: relative; |
|||
margin: 78rpx 20rpx 0; |
|||
.tips-icon { |
|||
width: 112rpx; |
|||
height: 112rpx; |
|||
} |
|||
|
|||
.header { |
|||
position: absolute; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
top: -50rpx; |
|||
} |
|||
.info { |
|||
padding-top: 180rpx; |
|||
} |
|||
.line { |
|||
border-top: $-solid-border; |
|||
} |
|||
.plain { |
|||
border: 1px solid $-color-primary; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 520 B |
|
After Width: | Height: | Size: 619 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 691 B |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 760 B |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 141 B |
|
After Width: | Height: | Size: 653 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 848 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.6 KiB |