hwq 1 rok temu
rodzic
commit
b4249089dd
100 zmienionych plików z 13450 dodań i 0 usunięć
  1. 23 0
      .hbuilderx/launch.json
  2. 130 0
      App.vue
  3. 239 0
      api/activity.js
  4. 169 0
      api/app.js
  5. 131 0
      api/community.js
  6. 46 0
      api/order.js
  7. 170 0
      api/shop.js
  8. 200 0
      api/store.js
  9. 354 0
      api/user.js
  10. 11 0
      apple-app-site-association
  11. 17 0
      autoRelease.sh
  12. 118 0
      bundle/pages/activity_detail/activity_detail.vue
  13. 211 0
      bundle/pages/address_edit/address_edit.vue
  14. 43 0
      bundle/pages/after_sales/after_sales.vue
  15. 235 0
      bundle/pages/after_sales_detail/after_sales_detail.vue
  16. 200 0
      bundle/pages/all_comments/all_comments.vue
  17. 260 0
      bundle/pages/apply_refund/apply_refund.vue
  18. 111 0
      bundle/pages/bargain/bargain.vue
  19. 77 0
      bundle/pages/bargain_code/bargain_code.vue
  20. 518 0
      bundle/pages/bargain_process/bargain_process.vue
  21. 602 0
      bundle/pages/chat/chat.vue
  22. 63 0
      bundle/pages/commission_details/commission_details.vue
  23. 157 0
      bundle/pages/contact_offical/contact_offical.vue
  24. 61 0
      bundle/pages/exchange_order/exchange_order.vue
  25. 368 0
      bundle/pages/exchange_order_details/exchange_order_details.vue
  26. 123 0
      bundle/pages/goods_combination/goods_combination.vue
  27. 240 0
      bundle/pages/goods_logistics/goods_logistics.vue
  28. 193 0
      bundle/pages/goods_reviews/goods_reviews.vue
  29. 219 0
      bundle/pages/goods_seckill/goods_seckill.vue
  30. 128 0
      bundle/pages/input_express_info/input_express_info.vue
  31. 84 0
      bundle/pages/integral_details/integral_details.vue
  32. 261 0
      bundle/pages/integral_goods_details/integral_goods_details.vue
  33. 269 0
      bundle/pages/integral_mall/integral_mall.vue
  34. 266 0
      bundle/pages/integral_settlement/integral_settlement.vue
  35. 355 0
      bundle/pages/integral_sign/integral_sign.vue
  36. 160 0
      bundle/pages/invite_fans/invite_fans.vue
  37. 379 0
      bundle/pages/invoice/invoice.vue
  38. 212 0
      bundle/pages/invoice_detail/invoice_detail.vue
  39. 72 0
      bundle/pages/license/license.vue
  40. 102 0
      bundle/pages/monthly_bill/monthly_bill.vue
  41. 156 0
      bundle/pages/monthly_bill_detail/monthly_bill_detail.vue
  42. 475 0
      bundle/pages/order_details/order_details.vue
  43. 63 0
      bundle/pages/recharge_record/recharge_record.vue
  44. 72 0
      bundle/pages/server_explan/server_explan.vue
  45. 97 0
      bundle/pages/settled_recode/settled_recode.vue
  46. 196 0
      bundle/pages/settled_result/settled_result.vue
  47. 38 0
      bundle/pages/sign_rule/sign_rule.vue
  48. 463 0
      bundle/pages/store_settled/store_settled.vue
  49. 250 0
      bundle/pages/user_address/user_address.vue
  50. 85 0
      bundle/pages/user_bill/user_bill.vue
  51. 51 0
      bundle/pages/user_collection/user_collection.vue
  52. 35 0
      bundle/pages/user_comment/user_comment.vue
  53. 41 0
      bundle/pages/user_coupon/user_coupon.vue
  54. 253 0
      bundle/pages/user_fans/user_fans.vue
  55. 59 0
      bundle/pages/user_group/user_group.vue
  56. 64 0
      bundle/pages/user_growth/user_growth.vue
  57. 58 0
      bundle/pages/user_order/user_order.vue
  58. 336 0
      bundle/pages/user_payment/user_payment.vue
  59. 550 0
      bundle/pages/user_profile/user_profile.vue
  60. 908 0
      bundle/pages/user_spread/user_spread.vue
  61. 48 0
      bundle/pages/user_spread_order/user_spread_order.vue
  62. 358 0
      bundle/pages/user_vip/user_vip.vue
  63. 224 0
      bundle/pages/user_wallet/user_wallet.vue
  64. 250 0
      bundle/pages/user_withdraw/user_withdraw.vue
  65. 97 0
      bundle/pages/user_withdraw_code/user_withdraw_code.vue
  66. 127 0
      bundle/pages/widthdraw_result/widthdraw_result.vue
  67. 519 0
      bundle/pages/xxstore_settled/xxstore_settled.vue
  68. BIN
      bundle/static/No.0.png
  69. BIN
      bundle/static/activity_detail_bg.png
  70. BIN
      bundle/static/bg_sgin.png
  71. BIN
      bundle/static/contact_official_bg.png
  72. BIN
      bundle/static/icon_camera_line.png
  73. BIN
      bundle/static/icon_czjl.png
  74. BIN
      bundle/static/icon_fenxiao.png
  75. BIN
      bundle/static/icon_integral.png
  76. BIN
      bundle/static/icon_invite.png
  77. BIN
      bundle/static/icon_jifen.png
  78. BIN
      bundle/static/icon_wait.png
  79. BIN
      bundle/static/icon_yezz.png
  80. BIN
      bundle/static/icon_yongjin.png
  81. BIN
      bundle/static/icon_zhangdan.png
  82. BIN
      bundle/static/icon_zhmx.png
  83. BIN
      bundle/static/icon_zzjl.png
  84. BIN
      bundle/static/img_activity_coupon.png
  85. BIN
      bundle/static/img_activity_jifen.png
  86. BIN
      bundle/static/img_activity_pintuan.png
  87. BIN
      bundle/static/img_activity_seckill.png
  88. BIN
      bundle/static/invoice_success.png
  89. BIN
      bundle/static/invoice_wait.png
  90. BIN
      bundle/static/jifen_icon_data.png
  91. BIN
      bundle/static/jifen_icon_help.png
  92. BIN
      bundle/static/jifen_icon_select.png
  93. BIN
      bundle/static/jifen_popBg.png
  94. BIN
      bundle/static/logistics_address.png
  95. BIN
      bundle/static/logistics_address_gray.png
  96. BIN
      bundle/static/logistics_delivered.png
  97. BIN
      bundle/static/logistics_pay.png
  98. BIN
      bundle/static/logistics_success.png
  99. BIN
      bundle/static/logistics_transit.png
  100. BIN
      bundle/static/settled_bg.png

+ 23 - 0
.hbuilderx/launch.json

@@ -0,0 +1,23 @@
+{
+    // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+    // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+    "version" : "0.0",
+    "configurations" : [
+        {
+            "app-plus" : {
+                "launchtype" : "local"
+            },
+            "default" : {
+                "launchtype" : "local"
+            },
+            "mp-weixin" : {
+                "launchtype" : "local"
+            },
+            "type" : "uniCloud"
+        },
+        {
+            "playground" : "custom",
+            "type" : "uni-app:app-android"
+        }
+    ]
+}

+ 130 - 0
App.vue

@@ -0,0 +1,130 @@
+<script>
+	// #ifdef APP-PLUS
+	import {
+		getUpApp
+	} from './utils/upApp.js';
+	// #endif
+	import {
+		mapActions,
+		mapMutations
+	} from 'vuex';
+	import {
+		getConfig
+	} from '@/api/app';
+	import {
+		setTabbar,
+		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 APP-PLUS
+			// 判断是否升级
+			getUpApp();
+			// #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();
+					}
+					setTabbar();
+					// 防止第一次调用时拿不到数据
+					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);
+					}
+				}
+			}
+		}
+	};
+</script>
+<style lang="scss">
+	@import 'styles/common.scss';
+	@import 'components/uview-ui/index.scss';
+	@import url('@/plugin/emoji-awesome/css/apple.css');
+	@import url('static/font/iconfont.css');
+
+	/*每个页面公共css */
+	page {
+		background: linear-gradient(180deg, rgba(243, 244, 246, 0.98) 0%, #f4e4e4 37%, #f4eced 69%, #f3eced 85%, #f3f4f6 100%);
+	}
+
+	.d-flex {
+		display: flex;
+	}
+
+	.justify-content-between {
+		justify-content: space-between;
+	}
+
+	.justify-content-center {
+		justify-content: center;
+	}
+
+	.align-items-center {
+		align-items: center;
+	}
+
+	.flex-wrap {
+		flex-wrap: wrap;
+	}
+
+	.text-center {
+		text-align: center;
+	}
+
+	.bg-white {
+		background-color: #fff;
+	}
+
+	.radius10 {
+		border-radius: 20upx;
+	}
+
+	.titColor {
+		color: #040404;
+	}
+
+	.align-content-between {
+		align-content: space-between;
+	}
+</style>

+ 239 - 0
api/activity.js

@@ -0,0 +1,239 @@
+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
+		}
+	})
+}
+// 直播列表
+export function live(data) {
+	return request.get("wechat/live", {
+		params: data
+	});
+}

+ 169 - 0
api/app.js

@@ -0,0 +1,169 @@
+import request from '@/utils/request'
+import wechath5 from '@/utils/wechath5'
+import {
+	client
+} from '@/utils/tools'
+
+
+//获取app版本号
+export function version(data) {
+	return request.post('index/version');
+}
+
+//小程序授权登录
+export function authLogin(data) {
+	return request.post('account/authLogin', data);
+}
+//小程序静默登录
+export function silentLogin(data) {
+	return request.post('account/silentLogin', data);
+}
+
+// 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(params) {
+	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
+	})
+}

+ 131 - 0
api/community.js

@@ -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")
+}

+ 46 - 0
api/order.js

@@ -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/submit_order", 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 });
+} 

+ 170 - 0
api/shop.js

@@ -0,0 +1,170 @@
+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
+	})
+}
+
+// 抵用券
+export function apiEnergy() {
+	return request.get("/user/energy")
+}
+
+// 转让抵用券
+export function transferEnergy(params) {
+	return request.post("/user/transferenergy", params)
+}
+
+// 兑换抵用券
+export function exchangeEnergy(params) {
+	return request.post("/user/exchangeenergy", params)
+}
+
+//  抵用券明细
+export function energyLog(params) {
+	return request.get("/user/energylog", {
+		params
+	})
+}
+
+// 抵用券馈赠
+export function giftEnergy(params) {
+	return request.post('/user/gift_energy', params)
+}
+
+// 可抵扣商品
+export function getGoodsDiscountList(params) {
+	return request.get('/goods/getGoodsDiscountLists', {
+		params
+	})
+}
+
+// 直播
+export function getLiveList(params) {
+	return request.get("/LiveBroadcast/get_live_list", {
+		params
+	})
+}
+
+// 获取广告视频列表
+export function getAdVideoList(params) {
+	return request.get("/LiveBroadcast/get_video_list", {
+		params
+	})
+}
+// 看完视频获取券
+export function seeVideoGift(params) {
+	return request.post("/LiveBroadcast/see_video_gift_integral", params)
+}

+ 200 - 0
api/store.js

@@ -0,0 +1,200 @@
+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})
+}

+ 354 - 0
api/user.js

@@ -0,0 +1,354 @@
+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 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
+	})
+}
+
+// 获取昵称
+export function nickname(data) {
+	return request.get('user/nickname', {
+		params: data
+	})
+}

+ 11 - 0
apple-app-site-association

@@ -0,0 +1,11 @@
+{  
+    "applinks": {  
+        "apps": [],  
+        "details": [  
+            {  
+                "appID": "8656MXP6VT.com.gzyx.likemall",  
+                "paths": [ "/ulink/*"]  
+            }  
+        ]  
+    }  
+}

+ 17 - 0
autoRelease.sh

@@ -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

+ 118 - 0
bundle/pages/activity_detail/activity_detail.vue

@@ -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>

+ 211 - 0
bundle/pages/address_edit/address_edit.vue

@@ -0,0 +1,211 @@
+<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
+				console.log(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>

+ 43 - 0
bundle/pages/after_sales/after_sales.vue

@@ -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>

+ 235 - 0
bundle/pages/after_sales_detail/after_sales_detail.vue

@@ -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>

+ 200 - 0
bundle/pages/all_comments/all_comments.vue

@@ -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>

+ 260 - 0
bundle/pages/apply_refund/apply_refund.vue

@@ -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>

Plik diff jest za duży
+ 111 - 0
bundle/pages/bargain/bargain.vue


+ 77 - 0
bundle/pages/bargain_code/bargain_code.vue

@@ -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>

Plik diff jest za duży
+ 518 - 0
bundle/pages/bargain_process/bargain_process.vue


+ 602 - 0
bundle/pages/chat/chat.vue

@@ -0,0 +1,602 @@
+<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) {
+				console.log('1111');
+				// uni.navigateTo({
+				// 	url: '/bundle/pages/contact_offical/contact_offical?id=' + this.shopId,
+				// 	success(e) {
+				// 		console.log(e, 'cg');
+				// 	},
+				// 	fail(e) {
+				// 		console.log(e, 'sb');
+				// 	}
+				// });
+				// #ifdef APP
+				setTimeout(function() {
+					uni.redirectTo({
+						url: `/bundle/pages/contact_offical/contact_offical?id=${this.shopId}`
+					});
+				}, 2000);
+				// #endif
+				// #ifdef H5
+				uni.redirectTo({
+					url: `/bundle/pages/contact_offical/contact_offical?id=${this.shopId}`
+				});
+				// #endif
+				return;
+			} else {
+				uni.showModal({
+					title: '温馨提示',
+					content: msg,
+					success: res => {
+						if (res.confirm) {
+							uni.redirectTo({
+								url: `/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();
+				console.log(res);
+				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 0.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 0.3s;
+
+		&.emoji-show {
+			height: 200px;
+		}
+	}
+
+	.send-btn {
+		padding: 0 25rpx;
+		color: #fff;
+		background-color: #ed5349;
+		border-radius: 60rpx;
+	}
+}
+</style>

+ 63 - 0
bundle/pages/commission_details/commission_details.vue

@@ -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>

+ 157 - 0
bundle/pages/contact_offical/contact_offical.vue

@@ -0,0 +1,157 @@
+<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(opt) {
+		console.log(opt, 'ss');
+		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>

+ 61 - 0
bundle/pages/exchange_order/exchange_order.vue

@@ -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>

+ 368 - 0
bundle/pages/exchange_order_details/exchange_order_details.vue

@@ -0,0 +1,368 @@
+<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>

Plik diff jest za duży
+ 123 - 0
bundle/pages/goods_combination/goods_combination.vue


+ 240 - 0
bundle/pages/goods_logistics/goods_logistics.vue

@@ -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>

+ 193 - 0
bundle/pages/goods_reviews/goods_reviews.vue

@@ -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>

+ 219 - 0
bundle/pages/goods_seckill/goods_seckill.vue

@@ -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>

+ 128 - 0
bundle/pages/input_express_info/input_express_info.vue

@@ -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>

+ 84 - 0
bundle/pages/integral_details/integral_details.vue

@@ -0,0 +1,84 @@
+<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>

+ 261 - 0
bundle/pages/integral_goods_details/integral_goods_details.vue

@@ -0,0 +1,261 @@
+<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>

+ 269 - 0
bundle/pages/integral_mall/integral_mall.vue

@@ -0,0 +1,269 @@
+<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>

+ 266 - 0
bundle/pages/integral_settlement/integral_settlement.vue

@@ -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>

+ 355 - 0
bundle/pages/integral_sign/integral_sign.vue

@@ -0,0 +1,355 @@
+<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>

+ 160 - 0
bundle/pages/invite_fans/invite_fans.vue

@@ -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}/pages/register/register?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>

+ 379 - 0
bundle/pages/invoice/invoice.vue

@@ -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>

+ 212 - 0
bundle/pages/invoice_detail/invoice_detail.vue

@@ -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.type == 0 ? '个人' : '企业' }}</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>

+ 72 - 0
bundle/pages/license/license.vue

@@ -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>

+ 102 - 0
bundle/pages/monthly_bill/monthly_bill.vue

@@ -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>

+ 156 - 0
bundle/pages/monthly_bill_detail/monthly_bill_detail.vue

@@ -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>

+ 475 - 0
bundle/pages/order_details/order_details.vue

@@ -0,0 +1,475 @@
+<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">
+						<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 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
+						});
+					} else {
+						setTimeout(() => uni.navigateBack(), 1500)
+					}
+				});
+			},
+            
+            // 复制内容
+            copy(content) {
+                copy(content)
+            }
+		},
+		computed: {
+
+		}
+	};
+</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;
+	}
+
+	.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>

+ 63 - 0
bundle/pages/recharge_record/recharge_record.vue

@@ -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>

+ 72 - 0
bundle/pages/server_explan/server_explan.vue

@@ -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>

+ 97 - 0
bundle/pages/settled_recode/settled_recode.vue

@@ -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>

+ 196 - 0
bundle/pages/settled_result/settled_result.vue

@@ -0,0 +1,196 @@
+<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>

+ 38 - 0
bundle/pages/sign_rule/sign_rule.vue

@@ -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>

+ 463 - 0
bundle/pages/store_settled/store_settled.vue

@@ -0,0 +1,463 @@
+<template>
+	<view class="">
+		<view class="store-settled" v-if='userInfo.is_shop == 0'>
+			<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>
+
+		<view class="shop-show" v-else>
+			<view class="top" :style="{
+				backgroundImage:'url(' + (shopData.background) + ')'
+			}">
+				<view class="wrap">
+					<image :src="shopData.logo" mode="" class="logo"></image>
+					<view class="shop-info">
+						<view class="name">
+							{{shopData.name}}
+						</view>
+						<view class="tags">
+							{{shopData.type_desc}}
+						</view>
+					</view>
+				</view>
+				<view class="num-data">
+					<view class="item text-center">
+						<view class="num">
+							{{shopData.on_sale_count}}
+						</view>
+						<view class="desc">
+							在售总数
+						</view>
+					</view>
+					<view class="item text-center">
+						<view class="num">
+							{{shopData.follow_num}}
+						</view>
+						<view class="desc">
+							粉丝数
+						</view>
+					</view>
+					<view class="item text-center">
+						<view class="num">
+							{{shopData.score}}
+						</view>
+						<view class="desc">
+							店铺评分
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="content">
+				<view class="title">
+					恭喜您已成为入驻商家
+				</view>
+				<view class="cont">
+					<view class="">
+						PC浏览器打开以下网址即可进行店铺管理操作:
+					</view>
+					<view class="admin_url">
+						{{appConfig.base_domain + 'shop/'}}
+					</view>
+					<button @tap='onCopy'>点我一键复制链接</button>
+					<view class="tips">
+						注:使用商家入驻申请时所填写的账号密码登录哦
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	import {
+		getShopCategory,
+		shopApply
+	} from "@/api/shop"
+	import {
+		baseURL
+	} from '@/config/app'
+	import {
+		sendSms
+	} from '@/api/app'
+	import {
+		SMSType
+	} from '@/utils/type'
+	import {
+		mapGetters,
+		mapActions
+	} from 'vuex'
+	import {
+		copy
+	} from '@/utils/tools'
+	import {
+		shopApplyDetail,
+		getShopInfo
+	} from '@/api/shop'
+	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: [],
+				shopData: {}
+			}
+		},
+		onLoad() {
+			this.getShopCategoryFun()
+
+			if (this.userInfo.shop_id != 0) {
+				this.shopDetail()
+			}
+
+		},
+		methods: {
+			...mapActions(['getUser']),
+			async getShopCategoryFun() {
+				const {
+					code,
+					data
+				} = await getShopCategory()
+				if (code == 1) {
+					this.shopCategory = data.filter(e => {
+						return e.id != 35
+					})
+				}
+			},
+			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
+				console.log(submitObj, 'info');
+				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)
+			},
+			async shopDetail() {
+				const {
+					code,
+					data
+				} = await getShopInfo({
+					shop_id: this.userInfo.shop_id
+				})
+				if (code == 1) {
+					console.log(data)
+					this.shopData = data
+				}
+			},
+			onCopy() {
+				copy(this.appConfig.base_domain + 'shop/')
+			},
+		},
+		computed: {
+			...mapGetters(["userInfo", "appConfig"]),
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: #fff;
+	}
+
+	.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;
+		// 		}
+		// 	}
+		// }
+	}
+
+	.shop-show {
+
+		.top {
+			width: 100%;
+			height: 300rpx;
+			background-size: 100% 100%;
+			padding: 40rpx 30rpx;
+			box-sizing: border-box;
+
+			.wrap {
+				display: flex;
+				align-items: center;
+				color: #fff;
+
+				.logo {
+					width: 120rpx;
+					height: 120rpx;
+					border-radius: 50%;
+					margin-right: 20rpx;
+				}
+
+				.name {
+					font-size: 40rpx;
+					line-height: 60rpx;
+					font-weight: bold;
+				}
+
+				.tags {
+					font-size: 28rpx;
+					line-height: 60rpx;
+				}
+			}
+
+			.num-data {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				color: #fff;
+				margin-top: 40rpx;
+
+				.item {
+					flex-basis: 100%;
+
+					.num {
+						font-weight: bold;
+						font-size: 36rpx;
+						line-height: 48rpx;
+					}
+
+					.desc {
+						font-size: 24rpx;
+					}
+				}
+			}
+		}
+
+		.content {
+			background: transparent;
+			padding: 40rpx 30rpx;
+
+			.title {
+				text-align: center;
+				font-weight: bold;
+				font-size: 48rpx;
+				margin-bottom: 40rpx;
+			}
+
+			.cont {
+				font-size: 32rpx;
+				text-align: center;
+				line-height: 60rpx;
+
+				.admin_url {
+					font-weight: bold;
+					text-align: center;
+				}
+
+				button {
+					width: 45%;
+					background: linear-gradient(97deg, #ff5784, #ff2c3c);
+					color: #fff;
+					border-radius: 50rpx;
+					margin: 20rpx auto;
+				}
+
+				.tips {
+					font-size: 28rpx;
+				}
+			}
+		}
+	}
+</style>

+ 250 - 0
bundle/pages/user_address/user_address.vue

@@ -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>

+ 85 - 0
bundle/pages/user_bill/user_bill.vue

@@ -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>

+ 51 - 0
bundle/pages/user_collection/user_collection.vue

@@ -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>

+ 35 - 0
bundle/pages/user_comment/user_comment.vue

@@ -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>

+ 41 - 0
bundle/pages/user_coupon/user_coupon.vue

@@ -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>

+ 253 - 0
bundle/pages/user_fans/user_fans.vue

@@ -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>

+ 59 - 0
bundle/pages/user_group/user_group.vue

@@ -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>

+ 64 - 0
bundle/pages/user_growth/user_growth.vue

@@ -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>

+ 58 - 0
bundle/pages/user_order/user_order.vue

@@ -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>

+ 336 - 0
bundle/pages/user_payment/user_payment.vue

@@ -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>

+ 550 - 0
bundle/pages/user_profile/user_profile.vue

@@ -0,0 +1,550 @@
+<template>
+	<view class="user-profile p-t-10">
+		<view class="content">
+			<view class="bg-white">
+				<view class="user-avatar-box flex-col col-center">
+					<uploader @after-read="afterRead" use-slot preview-size="120rpx">
+						<image class="user-avatar" :src="userInfo.avatar || '/static/images/portrait_empty.png'" />
+					</uploader>
+					<!-- #ifdef MP-WEIXIN -->
+					<view class="xs muted flex row-center m-t-20" @tap="getUserProfileFun">更新微信头像</view>
+					<!-- #endif -->
+				</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>
+		<view class="bg-primary white save-btn flex row-center lg" @tap="logout">退出登录</view>
+		<!-- #ifndef MP-WEIXIN -->
+
+		<view class="bg-primary white save-btn flex row-center lg" @click="cancel">注销账户</view>
+		<u-popup mode="center" type="center" v-model="showGs">
+			<view class="psw-wrapper">
+				<view class="psw-title">请输入自己的账户</view>
+				<input type="text" v-model="password" class="psw-ipt" />
+				<view class="psw-btn">
+					<text @click.stop="qx">取消</text>
+					<text class="psw-qd" @click.stop="pswQd">确定</text>
+				</view>
+			</view>
+		</u-popup>
+		<!-- #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" mode="center" border-radius="14">
+			<view class="modify-container bg-white" v-show="showNickName">
+				<view class="title xl text-center">修改用户名</view>
+				<u-field v-model="newNickname" label="新昵称" placeholder="请输入新的昵称"></u-field>
+				<view class="btn bg-primary white flex row-center" @tap="changeNameConfirm">确定</view>
+			</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',
+			password: '',
+			fileList: [],
+			userInfo: {},
+			new_mobile: '',
+			pwdCode: '',
+			mobileCode: '',
+			newNickname: '',
+			sexList: ['男', '女'],
+			fieldType: FieldType.NONE,
+			showGs: false,
+			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);
+		},
+		// 文件上传读取
+		afterRead(e) {
+			const file = e;
+			console.log(file);
+			uni.showLoading({
+				title: '正在上传中...',
+				mask: true
+			});
+			file.forEach(item => {
+				uploadFile(item.path).then(res => {
+					uni.hideLoading();
+					this.fieldType = FieldType.AVATAR;
+					this.setUserInfoFun(res.base_uri);
+				});
+			});
+		},
+		// 更新小程序头像信息
+		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();
+			}
+		},
+		cancel() {
+			this.showGs = true;
+		},
+		qx() {
+			this.password = '';
+			this.showGs = false;
+		},
+		pswQd() {
+			if (this.password != this.userInfo.mobile) {
+				this.showGs = false;
+				this.password = '';
+				uni.showToast({
+					title: '请输入自己的账户',
+					icon: 'none'
+				});
+				return;
+			}
+			this.showGs = false;
+			this.password = '';
+			uni.showToast({
+				title: '申请注销成功,请耐心等待审核',
+				icon: 'none'
+			});
+		},
+		// 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) {
+			console.log(this.smsType);
+			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();
+				}
+			});
+		},
+		// 修改用户信息
+		setUserInfoFun(value) {
+			setUserInfo({
+				field: this.fieldType,
+				value: value
+			}).then(res => {
+				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;
+		},
+		changeNameConfirm() {
+			this.setUserInfoFun(this.newNickname);
+			this.showNickName = false;
+		},
+		// 微信获取手机号
+		// #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
+		this.getUserProfileFun = trottle(this.getUserProfileFun, 500, this);
+	},
+	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;
+		}
+	}
+}
+.psw-wrapper {
+	width: 548rpx;
+	height: 344rpx;
+	background-color: #ffffff;
+	.psw-title {
+		width: 100%;
+		font-size: 35rpx;
+		padding: 43rpx 0 49rpx;
+		text-align: center;
+		font-weight: 800;
+	}
+	.psw-ipt {
+		display: block;
+		background-color: #dce3ed;
+		height: 90rpx;
+		width: 464rpx;
+		padding-left: 30rpx;
+		margin: 0 auto;
+		font-size: 80rpx;
+	}
+	.psw-btn text {
+		display: inline-block;
+		text-align: center;
+		width: 50%;
+		padding-top: 29rpx;
+		font-size: 35rpx;
+	}
+	.psw-qd {
+		color: #32c6ff;
+	}
+}
+</style>

+ 908 - 0
bundle/pages/user_spread/user_spread.vue

@@ -0,0 +1,908 @@
+<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="left">
+							<view class="m-b-10">
+								<view class="xxl bold  m-r-20">{{ userInfo.user.nickname }}</view>
+							</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="avatar-tag white xxs text-center m-b-10" v-if="data.business_name">{{ data.business_name }}
+				</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="account bg-white radius10">
+						<view class="top d-flex justify-content-between align-items-center">
+							<view class="item">
+								<view class="txt">抵用券余额</view>
+								<view class="num">{{ data.energy ? data.energy : 0 }}</view>
+							</view>
+							<view class="item">
+								<view class="txt">今日抵用券收益</view>
+								<view class="num">{{ data.todayenergy ? data.todayenergy : 0 }}</view>
+							</view>
+							<view class="item">
+								<view class="txt">邀请有效账号</view>
+								<view class="num">{{ data.ztui ? data.ztui : 0 }}</view>
+							</view>
+						</view>
+						<view class="wrap">
+							<view class="acc-data d-flex justify-content-between flex-wrap">
+								<view class="item">
+									<view class="txt">累计推荐商家(奖励抵用券)</view>
+									<view class="num">{{ data.tshopenergy ? data.tshopenergy : 0 }}</view>
+								</view>
+								<view class="item">
+									<view class="txt">累计推荐用户(奖励抵用券)</view>
+									<view class="num">{{ data.tuserenergy ? data.tuserenergy : 0 }}</view>
+								</view>
+								<view class="item">
+									<view class="txt">月度收益抵用券</view>
+									<view class="num">{{ data.menergy ? data.menergy : 0 }}</view>
+								</view>
+								<view class="item">
+									<view class="txt">总收益抵用券</view>
+									<view class="num">{{ data.totalenergy ? data.totalenergy : 0 }}</view>
+								</view>
+							</view>
+							<router-link to="/pages/user/energy-transfer?type=1"><button
+									class="btn">转让抵用券</button></router-link>
+							<!-- <router-link to="/pages/user/energy-transfer?type=2"><button
+									class="btn blue">抵用券馈赠</button></router-link> -->
+						</view>
+					</view>
+
+					<view class="user-code d-flex justify-content-between align-items-center bg-white radius10">
+						<view class="title">
+							我的邀请码
+							<text class="tip">点击复制即可</text>
+						</view>
+						<view class="code" @tap="onCopy">{{ userInfo.user.distribution_code }}</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="menu bg-white radius10">
+						<router-link to="/pages/user/energy-detials">
+							<view class="item d-flex justify-content-between align-items-center">
+								<view class="title">抵用券明细</view>
+								<text class="iconfont">&#xe63c;</text>
+							</view>
+						</router-link>
+
+						<view class="item d-flex justify-content-between align-items-center">
+							<view class="title">推广商家</view>
+							<text class="num">{{ data.tshop ? data.tshop : 0 }}家</text>
+						</view>
+						<view class="item d-flex justify-content-between align-items-center">
+							<view class="title">推广用户</view>
+							<text class="num">{{ data.tuser ? data.tuser : 0 }}人</text>
+						</view>
+						<view class="item d-flex justify-content-between align-items-center">
+							<view class="title">奖励规则</view>
+							<text class="iconfont">&#xe63c;</text>
+						</view>
+					</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="inviteCodes" 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';
+	import {
+		apiEnergy
+	} from '@/api/shop.js';
+	import {
+		mapGetters,
+		mapActions
+	} from 'vuex';
+	export default {
+		data() {
+			return {
+				list: ['成为分销会员,推广下级可获得额外收益,推广越多收益越多'],
+				showTips: true,
+				showLoading: true,
+				// 弹窗展示
+				showPop: false,
+				inviteCodes: '',
+				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: {},
+				data: {}
+			};
+		},
+		onLoad(options) {
+			// 获取上级及个人信息
+			this.getSuperiorInfoFun();
+			// 判断是否是分销会员
+			this.veryfiyDistributeFun();
+		},
+		onShow() {
+			this.getEnergy();
+		},
+
+		methods: {
+			...mapActions(['getUser']),
+			// 分销会员信息
+			async getDistributionFun() {
+				const {
+					data,
+					code
+				} = await getDistribution();
+				if (code == 1) {
+					this.showLoading = false;
+					this.distributionInfo = data;
+				}
+			},
+			async getEnergy() {
+				const {
+					data,
+					code
+				} = await apiEnergy();
+				if (code == 1) {
+					console.log(data);
+					this.data = 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.inviteCodes
+				}).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">
+	page {
+		background: #f3f4f6 url('https://shop.xianghuaqi.net.cn/images/treasureBg.png') no-repeat;
+		background-size: 100%;
+	}
+
+	.user-spread {
+		// background-image: url(../../static/spread_top_bg.png);
+		background-repeat: no-repeat;
+		background-size: 100% auto;
+
+		.header {
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+
+			.user-info {
+				.user-avatar {
+					position: relative;
+				}
+
+				.user-message {
+					.write-btn {
+						height: 42rpx;
+						width: 100rpx;
+						background-color: #ff838d;
+					}
+				}
+			}
+
+			.avatar-tag {
+				background: linear-gradient(151deg, #ffe9d1 0%, #ffd2a7 100%);
+				border-radius: 14px;
+				font-size: 24rpx;
+				color: #f73e33;
+				width: 160rpx;
+				height: 56rpx;
+				text-align: center;
+				line-height: 56rpx;
+				margin-right: 20rpx;
+			}
+		}
+
+		.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%);
+					display: none;
+
+					.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;
+	}
+
+	.account {
+		margin: 32rpx auto;
+
+		.top {
+			background: linear-gradient(158deg, #fef6e1 0%, #f5e4be 100%);
+			border-radius: 10px 10px 0px 0px;
+			height: 186rpx;
+
+			.item {
+				text-align: center;
+				flex-basis: 100%;
+
+				.txt {
+					font-size: 20rpx;
+					color: #b18044;
+				}
+
+				.num {
+					margin-top: 12rpx;
+					font-weight: 600;
+					font-size: 32rpx;
+					color: #823308;
+				}
+			}
+		}
+
+		.wrap {
+			padding: 40rpx;
+			box-sizing: border-box;
+
+			.item {
+				width: 50%;
+				border-bottom: 1px solid #f3f4f6;
+				border-right: 1px solid #f3f4f6;
+				padding: 40rpx 0;
+
+				.txt {
+					color: #616161;
+					font-size: 20rpx;
+				}
+
+				.num {
+					font-size: 32rpx;
+					color: #040404;
+					font-weight: 600;
+					margin-top: 12rpx;
+				}
+
+				&:nth-child(3),
+				&:nth-child(4) {
+					border-bottom: none;
+				}
+
+				&:nth-child(2n) {
+					padding-left: 20rpx;
+					border-right: none;
+				}
+			}
+
+			.btn {
+				background: linear-gradient(142deg, #f16d60 0%, #f8352b 100%);
+				border-radius: 25px;
+				color: #fff;
+				margin-top: 30rpx;
+
+				&.blue {
+					background: linear-gradient(142deg, #4897eb 0%, #1c80eb 100%);
+				}
+			}
+		}
+	}
+
+	.user-code {
+		height: 100rpx;
+		padding: 0 24rpx;
+		margin: 20rpx auto;
+
+		.title {
+			font-size: 28rpx;
+			color: #363636;
+
+			.tip {
+				color: #aaaaaa;
+				font-size: 24rpx;
+				margin-left: 20rpx;
+			}
+		}
+
+		.code {
+			padding: 10rpx 20rpx;
+			background-color: #f3f4f6;
+			border-radius: 30rpx;
+			font-size: 28rpx;
+			font-weight: 600;
+		}
+	}
+
+	.menu {
+		margin: 24rpx auto;
+		padding: 0 24rpx;
+		box-sizing: border-box;
+
+		.item {
+			padding: 30rpx 0;
+			box-sizing: border-box;
+			border-bottom: 1px solid #f3f4f6;
+
+			.title {
+				color: #040404;
+				font-size: 28rpx;
+				font-weight: 600;
+			}
+
+			.num {
+				color: #040404;
+				font-weight: 600;
+			}
+		}
+	}
+</style>

+ 48 - 0
bundle/pages/user_spread_order/user_spread_order.vue

@@ -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>

+ 358 - 0
bundle/pages/user_vip/user_vip.vue

@@ -0,0 +1,358 @@
+<template>
+	<view>
+		<hua-page-head :pageTitle="pageTitle" :rightMenu='rightMenu' @clickMenu='clickMenu'></hua-page-head>
+		<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 vip-name white">
+									<image class="grade-icon" :src="item.image"></image>
+									<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="new-vip-progress" style="padding: 0 30rpx">
+									<view class="sm " style="line-height: 36rpx" v-if="item.current_level_status == 0">
+										{{item.tips1}}
+									</view>
+									<router-link to="/bundle/pages/user_growth/user_growth" class="" v-else>
+										<view class="sm " style="line-height: 36rpx">
+											<!-- {{item.current_level_status == 0 ? '当前高于该等级' : item.current_growth_tips}} -->
+											{{item.tips1}}
+										</view>
+										<view class="progress">
+											<u-line-progress :showPercent="false" active-color="#687B8B"
+												:percent="item.diff_growth_percent * 100" height='4'></u-line-progress>
+										</view>
+										<view class="">{{item.tips2}} <u-icon name="arrow-right"></u-icon></view>
+
+									</router-link>
+
+								</view>
+							</view>
+						</swiper-item>
+					</swiper>
+				</view>
+				<view class="vip-grade-rule">
+					<view class="title ">
+						会员福利
+					</view>
+					<view class="iconbar">
+						<view class="item">
+							<view class="icon">
+								<text class="iconfont">&#xe646;</text>
+							</view>
+							<view class="tit">
+								会员福利
+							</view>
+						</view>
+						<view class="item">
+							<view class="icon">
+								<text class="iconfont">&#xe644;</text>
+							</view>
+							<view class="tit">
+								奖励现金
+							</view>
+						</view>
+						<view class="item">
+							<view class="icon">
+								<text class="iconfont">&#xe897;</text>
+							</view>
+							<view class="tit">
+								奖励券
+							</view>
+						</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: [],
+				pageTitle: '会员中心',
+				rightMenu: "邀请",
+
+			};
+		},
+
+
+		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
+				});
+			},
+			clickMenu() {
+				uni.navigateTo({
+					url: '/bundle/pages/invite_fans/invite_fans'
+				})
+			}
+		}
+	};
+</script>
+<style lang="scss">
+	page {
+		background: #F3F4F6;
+		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: 340rpx;
+					width: 690rpx;
+					position: relative;
+					background-size: 100% 100%;
+					border-radius: 20rpx;
+					overflow: hidden;
+
+					.grade {
+						line-height: 36rpx;
+						background-color: rgba(0, 0, 0, 0.5);
+						border-radius: 0 20rpx 0 20rpx;
+						height: 50rpx;
+						padding: 0 28rpx;
+						position: absolute;
+						right: 0;
+						top: 0;
+					}
+
+					.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: center;
+						margin-top: 50rpx;
+						margin-bottom: 80rpx;
+						display: flex;
+						font-family: HYk1gj;
+						color: #5D707F;
+
+						image {
+							width: 42rpx;
+							height: 44rpx;
+							margin-right: 12rpx;
+						}
+					}
+
+					.new-vip-progress {
+						color: #5D707F;
+						font-size: 24rpx;
+
+						.progress {
+							width: 260rpx;
+						}
+					}
+
+
+					.vip-progress {
+						height: 8rpx;
+						border-radius: 8rpx;
+						width: 100%;
+						overflow: hidden;
+
+						.vip-progress-bar {
+							background-color: #f8d07c;
+							height: 100%;
+						}
+					}
+
+				}
+
+				.vip-grade-rule {
+					margin: 24rpx 24rpx;
+					background-color: #fff;
+					border-radius: 20rpx;
+					padding: 28rpx 36rpx;
+
+					.title {
+						font-size: 32rpx;
+						color: #040404;
+						font-weight: bold;
+					}
+
+					.iconbar {
+						width: 100%;
+						display: flex;
+						justify-content: space-between;
+						margin: 40rpx auto;
+						padding: 0 30rpx;
+
+						.item {
+							// flex-basis: 100%;
+							text-align: center;
+
+							.icon {
+								width: 96rpx;
+								height: 96rpx;
+								color: #fff;
+								background: linear-gradient(151deg, #CBE8FB 0%, #94B6CA 100%);
+								border-radius: 50%;
+								line-height: 96rpx;
+								text-align: center;
+								margin: 0 auto 16rpx;
+
+								.iconfont {
+									font-size: 36rpx;
+								}
+							}
+
+							.tit {
+								color: #616161;
+								font-size: 24rpx;
+							}
+						}
+					}
+				}
+
+				.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>

+ 224 - 0
bundle/pages/user_wallet/user_wallet.vue

@@ -0,0 +1,224 @@
+<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_withdraw/user_withdraw">
+					<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>
+				<router-link class="nav-item" to="/bundle/pages/user_withdraw_code/user_withdraw_code">
+					<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" 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>

+ 250 - 0
bundle/pages/user_withdraw/user_withdraw.vue

@@ -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>

+ 97 - 0
bundle/pages/user_withdraw_code/user_withdraw_code.vue

@@ -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>

+ 127 - 0
bundle/pages/widthdraw_result/widthdraw_result.vue

@@ -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>

+ 519 - 0
bundle/pages/xxstore_settled/xxstore_settled.vue

@@ -0,0 +1,519 @@
+<template>
+	<view class="">
+		<view class="store-settled" v-if='userInfo.is_shop == 0'>
+			<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" @click="showRegion = true">
+						<u-field v-model="region" :disabled="true" label="所在地区" placeholder="请选择省、市、区"
+							right-icon="arrow-right" required>
+						</u-field>
+					</view>
+					<view class="apply-form-item" @click="getLocation()">
+						<u-field v-model="dw" :disabled="true" label="所在地址" placeholder="请选择地址" right-icon="arrow-right"
+							required>
+						</u-field>
+					</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">
+						<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="5" width="150" height="150" :action="action" upload-text="上传图片"
+								@on-success="onSuccesstt" @on-remove="onRemovett" />
+						</view>
+						<view class="muted m-t-20 m-b-30">支持jpg、png、jpeg格式的图片,最多可上传5张</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="showRegion" mode="mutil-column-auto" @confirm="regionChange" :list="lists"></u-select>
+
+		</view>
+		<view class="shop-show" v-else>
+			<view class="top" :style="{
+				backgroundImage:'url(' + (shopData.background) + ')'
+			}">
+				<view class="wrap">
+					<image :src="shopData.logo" mode="" class="logo"></image>
+					<view class="shop-info">
+						<view class="name">
+							{{shopData.name}}
+						</view>
+						<view class="tags">
+							{{shopData.type_desc}}
+						</view>
+					</view>
+				</view>
+				<view class="num-data">
+					<!-- <view class="item text-center">
+						<view class="num">
+							{{shopData.on_sale_count}}
+						</view>
+						<view class="desc">
+							在售总数
+						</view>
+					</view> -->
+					<view class="item text-center">
+						<view class="num">
+							{{shopData.follow_num}}
+						</view>
+						<view class="desc">
+							粉丝数
+						</view>
+					</view>
+					<view class="item text-center">
+						<view class="num">
+							{{shopData.score}}
+						</view>
+						<view class="desc">
+							店铺评分
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="content">
+				<view class="title">
+					恭喜您已成为入驻商家
+				</view>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	import {
+		getShopCategory,
+		shopApply
+	} from "@/api/shop"
+	import {
+		baseURL
+	} from '@/config/app'
+	import {
+		sendSms
+	} from '@/api/app'
+	import {
+		SMSType
+	} from '@/utils/type'
+	import {
+		mapGetters,
+		mapActions
+	} from 'vuex'
+	import {
+		copy
+	} from '@/utils/tools'
+	import {
+		shopApplyDetail,
+		getShopInfo
+	} from '@/api/shop'
+	import area from '@/utils/area'
+	export default {
+
+		data() {
+			return {
+				isAgree: false,
+				// 表单数据
+				form: {
+					cid: 35,
+					clabel: '',
+					name: '',
+					nickname: '',
+					mobile: '',
+					account: '',
+					password: '123456',
+					code: '',
+					province_id: '',
+					city_id: '',
+					district_id: '',
+					longitude: '',
+					latitude: ''
+				},
+				showRegion: false,
+				codeTips: '',
+				shopCategory: [],
+				showPop: false,
+				action: baseURL + '/api/file/formimage',
+				fileList: [],
+				images: [],
+				shopData: {},
+				lists: [],
+				region: '',
+				dw: '',
+			}
+		},
+		onLoad() {
+			this.getShopCategoryFun()
+
+			if (this.userInfo.shop_id != 0) {
+				this.shopDetail()
+			}
+			this.$nextTick(() => {
+				this.lists = area
+				console.log(area);
+			})
+
+		},
+		methods: {
+			...mapActions(['getUser']),
+			async getShopCategoryFun() {
+				const {
+					code,
+					data
+				} = await getShopCategory()
+				if (code == 1) {
+					this.shopCategory = data
+				}
+			},
+			getLocation() {
+				console.log('选择当前位置');
+				let obj = this;
+				uni.chooseLocation({
+					success: function(res) {
+						console.log('位置名称:' + res.name);
+						console.log('详细地址:' + res.address);
+						console.log('纬度:' + res.latitude);
+						console.log('经度:' + res.longitude);
+						obj.form.latitude = res.latitude;
+						obj.form.longitude = res.longitude;
+						if (res.address) {
+							obj.dw = res.address;
+						} else {
+							obj.dw = res.name;
+						}
+					}
+				});
+			},
+			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
+			},
+			regionChange(region) {
+				this.form.province_id = region[0].value;
+				this.form.city_id = region[1].value;
+				this.form.district_id = region[2].value;
+				this.region = region[0].label + " " + region[1].label + " " + region[2].label
+			},
+			// 提交表单
+			async onSubmit() {
+				const {
+					form,
+					isAgree,
+					fileList,
+					images
+				} = this
+				const submitObj = {
+					...form,
+					license: fileList,
+					images: images
+				}
+				delete submitObj.clabel
+				submitObj.account = submitObj.mobile
+				console.log(submitObj, '123456');
+				if (!submitObj.city_id) {
+					return uni.showToast({
+						title: '请选择省市区',
+						duration: 1500,
+						icon: 'none'
+					})
+				}
+				if (!submitObj.latitude) {
+					return uni.showToast({
+						title: '请选择地址',
+						duration: 1500,
+						icon: 'none'
+					})
+				}
+				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)
+			},
+			onSuccesstt(e) {
+				this.images.push(e.data.base_uri)
+			},
+			onRemovett(index) {
+				this.images.splice(index, 1)
+				console.log(index)
+			},
+			async shopDetail() {
+				const {
+					code,
+					data
+				} = await getShopInfo({
+					shop_id: this.userInfo.shop_id
+				})
+				if (code == 1) {
+					console.log(data)
+					this.shopData = data
+				}
+			},
+			onCopy() {
+				copy(this.appConfig.base_domain + 'shop/')
+			},
+		},
+		computed: {
+			...mapGetters(["userInfo", "appConfig"]),
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: #fff;
+	}
+
+	.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;
+		// 		}
+		// 	}
+		// }
+	}
+
+	.shop-show {
+
+		.top {
+			width: 100%;
+			height: 300rpx;
+			background-size: 100% 100%;
+			padding: 40rpx 30rpx;
+			box-sizing: border-box;
+
+			.wrap {
+				display: flex;
+				align-items: center;
+				color: #fff;
+
+				.logo {
+					width: 120rpx;
+					height: 120rpx;
+					border-radius: 50%;
+					margin-right: 20rpx;
+				}
+
+				.name {
+					font-size: 40rpx;
+					line-height: 60rpx;
+					font-weight: bold;
+				}
+
+				.tags {
+					font-size: 28rpx;
+					line-height: 60rpx;
+				}
+			}
+
+			.num-data {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				color: #fff;
+				margin-top: 40rpx;
+
+				.item {
+					flex-basis: 100%;
+
+					.num {
+						font-weight: bold;
+						font-size: 36rpx;
+						line-height: 48rpx;
+					}
+
+					.desc {
+						font-size: 24rpx;
+					}
+				}
+			}
+		}
+
+		.content {
+			background: transparent;
+			padding: 40rpx 30rpx;
+
+			.title {
+				text-align: center;
+				font-weight: bold;
+				font-size: 48rpx;
+				margin-bottom: 40rpx;
+			}
+
+			.cont {
+				font-size: 32rpx;
+				text-align: center;
+				line-height: 60rpx;
+
+				.admin_url {
+					font-weight: bold;
+					text-align: center;
+				}
+
+				button {
+					width: 45%;
+					background: linear-gradient(97deg, #ff5784, #ff2c3c);
+					color: #fff;
+					border-radius: 50rpx;
+					margin: 20rpx auto;
+				}
+
+				.tips {
+					font-size: 28rpx;
+				}
+			}
+		}
+	}
+</style>

BIN
bundle/static/No.0.png


BIN
bundle/static/activity_detail_bg.png


BIN
bundle/static/bg_sgin.png


BIN
bundle/static/contact_official_bg.png


BIN
bundle/static/icon_camera_line.png


BIN
bundle/static/icon_czjl.png


BIN
bundle/static/icon_fenxiao.png


BIN
bundle/static/icon_integral.png


BIN
bundle/static/icon_invite.png


BIN
bundle/static/icon_jifen.png


BIN
bundle/static/icon_wait.png


BIN
bundle/static/icon_yezz.png


BIN
bundle/static/icon_yongjin.png


BIN
bundle/static/icon_zhangdan.png


BIN
bundle/static/icon_zhmx.png


BIN
bundle/static/icon_zzjl.png


BIN
bundle/static/img_activity_coupon.png


BIN
bundle/static/img_activity_jifen.png


BIN
bundle/static/img_activity_pintuan.png


BIN
bundle/static/img_activity_seckill.png


BIN
bundle/static/invoice_success.png


BIN
bundle/static/invoice_wait.png


BIN
bundle/static/jifen_icon_data.png


BIN
bundle/static/jifen_icon_help.png


BIN
bundle/static/jifen_icon_select.png


BIN
bundle/static/jifen_popBg.png


BIN
bundle/static/logistics_address.png


BIN
bundle/static/logistics_address_gray.png


BIN
bundle/static/logistics_delivered.png


BIN
bundle/static/logistics_pay.png


BIN
bundle/static/logistics_success.png


BIN
bundle/static/logistics_transit.png


BIN
bundle/static/settled_bg.png


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików