Sfoglia il codice sorgente

Signed-off-by: xiezongxing <xx123456>

xiezongxing 2 anni fa
commit
42747a5135
100 ha cambiato i file con 16298 aggiunte e 0 eliminazioni
  1. 4 0
      .gitignore
  2. 293 0
      App.vue
  3. 21 0
      LICENSE
  4. 44 0
      README.md
  5. 365 0
      components/Progress-Bar/Progress-Bar.css
  6. 70 0
      components/Progress-Bar/Progress-Bar.vue
  7. 52 0
      components/empty.vue
  8. 14 0
      components/lee-logistics/icon.scss
  9. 213 0
      components/lee-logistics/lee-logistics.vue
  10. 119 0
      components/mix-list-cell.vue
  11. 68 0
      components/mix-loading/mix-loading.vue
  12. 249 0
      components/mpvueCityPicker.vue
  13. 202 0
      components/share.vue
  14. 199 0
      components/uni-countdown/uni-countdown.vue
  15. 96 0
      components/uni-icons/icons.js
  16. 57 0
      components/uni-icons/uni-icons.vue
  17. 194 0
      components/uni-load-more/uni-load-more.vue
  18. 205 0
      components/uni-number-box.vue
  19. 142 0
      components/uni-rate/uni-rate.vue
  20. 226 0
      components/upload-images.vue
  21. 13 0
      components/z-table/table-render.js
  22. 782 0
      components/z-table/z-table.vue
  23. BIN
      image/Thumbs.db
  24. BIN
      image/WechatIMG1.jpeg
  25. BIN
      image/WechatIMG10.jpeg
  26. BIN
      image/WechatIMG11.jpeg
  27. BIN
      image/WechatIMG12.jpeg
  28. BIN
      image/WechatIMG13.jpeg
  29. BIN
      image/WechatIMG14.jpeg
  30. BIN
      image/WechatIMG2.jpeg
  31. BIN
      image/WechatIMG3.jpeg
  32. BIN
      image/WechatIMG4.jpeg
  33. BIN
      image/WechatIMG5.jpeg
  34. BIN
      image/WechatIMG6.jpeg
  35. BIN
      image/WechatIMG7.jpeg
  36. BIN
      image/WechatIMG8.jpeg
  37. BIN
      image/WechatIMG9.jpeg
  38. 213 0
      main.js
  39. 77 0
      manifest.json
  40. 159 0
      node_modules/deepmerge/changelog.md
  41. 133 0
      node_modules/deepmerge/dist/cjs.js
  42. 139 0
      node_modules/deepmerge/dist/umd.js
  43. 16 0
      node_modules/deepmerge/index.d.ts
  44. 106 0
      node_modules/deepmerge/index.js
  45. 21 0
      node_modules/deepmerge/license.txt
  46. 71 0
      node_modules/deepmerge/package.json
  47. 264 0
      node_modules/deepmerge/readme.md
  48. 22 0
      node_modules/deepmerge/rollup.config.js
  49. 30 0
      node_modules/jweixin-module/README.md
  50. 1 0
      node_modules/jweixin-module/lib/index.js
  51. 54 0
      node_modules/jweixin-module/package.json
  52. 21 0
      node_modules/shvl/LICENSE
  53. 48 0
      node_modules/shvl/README.md
  54. 2 0
      node_modules/shvl/dist/shvl.js
  55. 1 0
      node_modules/shvl/dist/shvl.js.map
  56. 2 0
      node_modules/shvl/dist/shvl.mjs
  57. 1 0
      node_modules/shvl/dist/shvl.mjs.map
  58. 2 0
      node_modules/shvl/dist/shvl.umd.js
  59. 1 0
      node_modules/shvl/dist/shvl.umd.js.map
  60. 2 0
      node_modules/shvl/index.d.ts
  61. 11 0
      node_modules/shvl/index.js
  62. 87 0
      node_modules/shvl/package.json
  63. 21 0
      node_modules/vuex-persistedstate/LICENSE
  64. 227 0
      node_modules/vuex-persistedstate/README.md
  65. 23 0
      node_modules/vuex-persistedstate/dist/index.d.ts
  66. 2 0
      node_modules/vuex-persistedstate/dist/vuex-persistedstate.es.js
  67. 1 0
      node_modules/vuex-persistedstate/dist/vuex-persistedstate.es.js.map
  68. 2 0
      node_modules/vuex-persistedstate/dist/vuex-persistedstate.js
  69. 1 0
      node_modules/vuex-persistedstate/dist/vuex-persistedstate.js.map
  70. 2 0
      node_modules/vuex-persistedstate/dist/vuex-persistedstate.umd.js
  71. 1 0
      node_modules/vuex-persistedstate/dist/vuex-persistedstate.umd.js.map
  72. 112 0
      node_modules/vuex-persistedstate/package.json
  73. 117 0
      node_modules/vuex-persistedstate/src/index.ts
  74. 35 0
      package-lock.json
  75. 459 0
      pages.json
  76. 464 0
      pages/Withdrawal/addbank.vue
  77. 244 0
      pages/Withdrawal/banklist.vue
  78. 318 0
      pages/Withdrawal/index.vue
  79. 180 0
      pages/address/address.vue
  80. 203 0
      pages/address/addressManage.vue
  81. 60 0
      pages/article/detail.vue
  82. 139 0
      pages/article/index.vue
  83. 516 0
      pages/cart/cart.vue
  84. 199 0
      pages/category/category.vue
  85. 355 0
      pages/favorite/favorite.vue
  86. 466 0
      pages/flash/list.vue
  87. 773 0
      pages/index/index.vue
  88. 1016 0
      pages/intergalShop/confirm.vue
  89. 1219 0
      pages/intergalShop/goodsDetail.vue
  90. 589 0
      pages/intergalShop/index.vue
  91. 665 0
      pages/intergalShop/logs.vue
  92. 1073 0
      pages/intergalShop/orderDetail.vue
  93. 22 0
      pages/money/money.vue
  94. 375 0
      pages/money/pay.vue
  95. 61 0
      pages/money/paySuccess.vue
  96. 153 0
      pages/notice/notice.vue
  97. 878 0
      pages/order/createOrder.vue
  98. 43 0
      pages/order/delivery.vue
  99. 172 0
      pages/order/evaluate.vue
  100. 0 0
      pages/order/express.vue

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+unpackage/*
+.DS_Store
+.hbuilderx/*
+.idea/*

+ 293 - 0
App.vue

@@ -0,0 +1,293 @@
+<script>
+	/**
+	 * vuex管理登陆状态,具体可以参考官方登陆模板示例
+	 */
+	import {
+		mapMutations,
+		mapState
+	} from 'vuex';
+	export default {
+		globalData:{
+			        toPage(e) {
+			            var query = e.currentTarget.dataset;
+			            var url = query['url'];
+			            delete query.url;
+			            console.log(url);
+			            console.log(query);
+			            var str = '';
+			
+			            for (var k in query) {
+			                str = str + '&' + k + '=' + query[k];
+			            }
+			
+			            console.log(str);
+			            url = url + '?' + str;
+			            console.log(url);
+			            uni.navigateTo({
+			                url
+			            });
+			        },
+
+		},
+		methods: {
+			...mapMutations(['login', 'logout', 'setUserInfo']),
+			// #ifdef H5
+			// 检查登录状态
+			async checkLogin() {
+				let user = uni.getStorageSync('userInfo');
+				if (user) {
+					this.login(user);
+				} else {
+					let result = await this.$api.request('/user/status');
+					if (!result) {
+						// 若没有登录则清空个人信息
+						this.logout();
+					}
+				}
+			},
+			// #endif
+		},
+		onLaunch: function() {
+			// 锁定屏幕竖向
+			// #ifdef APP-PLUS
+			plus.screen.lockOrientation('portrait-primary');
+			// #endif
+			
+		
+		},
+		onShow: async function() {
+			// 检查用户登录情况
+			// #ifdef H5
+			this.checkLogin();
+			// #endif
+			// #ifdef MP-WEIXIN
+			const userInfo = await this.$wechatMiniLogin();
+			this.login(userInfo)
+			// #endif
+		},
+		onHide: function() {
+			console.log('App Hide')
+		},
+	}
+</script>
+
+<style lang='scss'>
+	/* project id 1729059 */
+	@font-face {
+	  font-family: 'unishop';  
+	  font-weight: normal;
+	  font-style: normal;
+	  src: url('https://at.alicdn.com/t/font_1729059_llr8d2acjac.ttf') format('truetype');
+	}
+	
+	.yticon {
+		font-family: "unishop" !important;
+		font-size: 16px;
+		font-style: normal;
+		-webkit-font-smoothing: antialiased;
+		-moz-osx-font-smoothing: grayscale;
+	}
+	
+	.icon-shouhuodizhi:before{
+		content: "\e6b5";
+	}
+	
+	.icon-xuanzhong:before{
+		content: "\e64c";
+	}
+	
+	.icon-fenlei:before{
+		content: "\e71b";
+	}
+	
+	.icon-bianji:before{
+		content: "\e77d";
+	}
+	
+	.icon-jiahao:before{
+		content: "\e616";
+	}
+	
+	.icon-jianhao:before{
+		content: "\e617";
+	}
+	
+	.icon-wxpay:before{
+		content: "\e607";
+	}
+	
+	.icon-pay:before{
+		content: "\e624";
+	}
+	
+	.icon-alipay:before{
+		content: "\e60b";
+	}
+	
+	.icon-you:before{
+		content: "\e65f";
+	}
+	
+	.icon-huoche:before{
+		content: "\e6f0";
+	}
+	
+	.icon-shoucang:before{
+		content: "\e60a";
+	}
+	
+	.icon-gouwuche:before{
+		content: "\e60e";
+	}
+	
+	.icon-fangzi:before{
+		content: "\e657";
+	}
+	
+	.icon-daifukuan:before{
+		content: "\e601";
+	}
+	
+	.icon-daifahuo:before{
+		content: "\e704";
+	}
+	
+	.icon-daishouhuo:before{
+		content: "\e62f";
+	}
+	
+	.icon-pingjia:before{
+		content: "\e61d";
+	}
+	
+	.icon-shouhou:before{
+		content:"\e610";
+	}
+	
+	.icon-shoucang-setting:before{
+		content:"\e612";
+	}
+	
+	.icon-setting:before{
+		content:"\e62b";
+	}
+	
+	.icon-dizhi:before{
+		content: "\e67c";
+	}
+	
+	.icon-lajitong:before{
+		content: "\e615";
+	}
+
+	view,
+	scroll-view,
+	swiper,
+	swiper-item,
+	cover-view,
+	cover-image,
+	icon,
+	text,
+	rich-text,
+	progress,
+	button,
+	checkbox,
+	form,
+	input,
+	label,
+	radio,
+	slider,
+	switch,
+	textarea,
+	navigator,
+	audio,
+	camera,
+	image,
+	video {
+		box-sizing: border-box;
+	}
+	/* 骨架屏替代方案 */
+	.Skeleton {
+		background: #f3f3f3;
+		padding: 20upx 0;
+		border-radius: 8upx;
+	}
+
+	/* 图片载入替代方案 */
+	.image-wrapper {
+		font-size: 0;
+		background: #f3f3f3;
+		border-radius: 4px;
+
+		image {
+			width: 100%;
+			height: 100%;
+			transition: .6s;
+			opacity: 0;
+
+			&.loaded {
+				opacity: 1;
+			}
+		}
+	}
+
+	.clamp {
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		display: block;
+	}
+
+	.common-hover {
+		background: #f5f5f5;
+	}
+
+	/*边框*/
+	.b-b:after,
+	.b-t:after {
+		position: absolute;
+		z-index: 3;
+		left: 0;
+		right: 0;
+		height: 0;
+		content: '';
+		transform: scaleY(.5);
+		border-bottom: 1px solid $border-color-base;
+	}
+
+	.b-b:after {
+		bottom: 0;
+	}
+
+	.b-t:after {
+		top: 0;
+	}
+
+	/* button样式改写 */
+	uni-button,
+	button {
+		height: 80upx;
+		line-height: 80upx;
+		font-size: $font-lg + 2upx;
+		font-weight: normal;
+
+		&.no-border:before,
+		&.no-border:after {
+			border: 0;
+		}
+	}
+
+	uni-button[type=default],
+	button[type=default] {
+		color: $font-color-dark;
+	}
+
+	/* input 样式 */
+	.input-placeholder {
+		color: #999999;
+	}
+
+	.placeholder {
+		color: #999999;
+	}
+</style>

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 mingwei zheng
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 44 - 0
README.md

@@ -0,0 +1,44 @@
+# uniShop
+
+#### 介绍
+{**本项目简称uniShop,是一个完整的商城。基于[uniapp框架](https://uniapp.dcloud.io/)开发。**}
+
+#### 体验
+![微信小程序](https://images.gitee.com/uploads/images/2020/0415/215327_77d28dac_1588098.jpeg "微信小程序")
+
+#### 后台演示
+1.  后端演示地址 [后端地址](http://demo.shop.weivee.com/admin) http://demo.shop.weivee.com/admin
+
+#### 后台源码
+1.  后端源码地址 [源码地址](https://www.fastadmin.net/store/unishop.html) https://www.fastadmin.net/store/unishop.html 
+
+#### 安装教程
+
+1.  git clone 下来之后直接在HBuilderX打开即可
+2.  接口地址在main.js修改
+
+#### 参与贡献
+
+1.  Fork 本仓库
+2.  新建 Feat_xxx 分支
+3.  提交代码
+4.  新建 Pull Request
+
+
+#### 特别鸣谢
+
+1.  uni-app https://uniapp.dcloud.io/
+2.  mix-mall https://ext.dcloud.net.cn/plugin?id=200
+3.  mpvue-citypicker https://github.com/MPComponent/mpvue-citypicker  
+4.  vue.js https://cn.vuejs.org/
+
+
+#### 版权信息
+
+unishop遵循MIT开源协议发布,并提供免费使用。
+
+本项目包含的第三方源码和二进制文件之版权信息另行标注。
+
+版权所有Copyright © 2020 by uniShop
+
+All rights reserved。

File diff suppressed because it is too large
+ 365 - 0
components/Progress-Bar/Progress-Bar.css


+ 70 - 0
components/Progress-Bar/Progress-Bar.vue

@@ -0,0 +1,70 @@
+<template>
+	<view>
+		<view class="progress" :class="Type" :style="{width: widthUpx + 'rpx'}">
+			<view class="progress-text" v-if="Vice == true" :style="{width: widthUpx + 'rpx'}">
+				已抢{{Sold}}件
+				{{ Width + '%' }}
+			</view>
+			<view class="progress-bar" :style="{width: Width+'%'}"><view class="progress-text" v-if="Main == true">{{ Width + '%' }}</view></view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	props: {
+		// 已卖多少件
+		Sold: {
+			type: Number,
+			default: 0
+		},
+		// 进度条宽度
+		widthUpx: {
+			type: Number,
+			default: 710
+		},
+		// 进度条百分比
+		Width: {
+			type: Number,
+			default: 0
+		},
+		// 进度条样式
+		/*
+			aqua
+			copper
+			candy
+			neon
+			shine
+			zigzag
+			diamond
+			hearts
+			sparkle
+		*/
+		Type: {
+			type: String,
+			default: 'aqua',
+		},
+		// 主进度显示百分比
+		Main: {
+			type: Boolean,
+			default: true,
+		},
+		// 副进度显示百分比
+		Vice: {
+			type: Boolean,
+			default: true,
+		},
+		
+	},
+	data() {
+		return {
+
+		};
+	},
+	methods: {}
+};
+</script>
+
+<style>
+@import url('Progress-Bar.css');
+</style>

File diff suppressed because it is too large
+ 52 - 0
components/empty.vue


File diff suppressed because it is too large
+ 14 - 0
components/lee-logistics/icon.scss


+ 213 - 0
components/lee-logistics/lee-logistics.vue

@@ -0,0 +1,213 @@
+<template>
+	<block v-if="init">
+		<scroll-view class="lee-logistics-scroll" :style="{ height }" scroll-y="true" v-if="result">
+			<view class="lee-logistics">
+				<!-- 物流公司与送达状态面板 -->
+				<view class="lee-logistics-caption">
+					<!-- <image class="lee-logistics-caption-logo" :src="result.img" mode="widthFix" /> -->
+					<view class="lee-logistics-caption-info">
+						<!-- <view class="lee-logistics-caption-status">{{ result.status }}</view> -->
+						<view class="lee-logistics-caption-nu">
+							<text>{{ result.company }}:</text>
+							<text>{{ expresssn }}</text>
+						</view>
+					</view>
+				</view>
+				<!-- 物流公司与送达状态面板END -->
+				
+				<!-- 物流信息列表 --> 
+				<view class="lee-logistics-list">
+					<view class="lee-logistics-msg" v-for="(v, k) of result.message" :key="k">
+						<view class="lee-logistics-msg-time">
+							<view>{{ v.time.split(' ')[1] }}</view>
+							<view>{{ v.time.split(' ')[0] }}</view>
+						</view>
+						<view class="lee-logistics-msg-context">
+							<rich-text :nodes="v.step | contextFormatter"></rich-text>
+						</view>
+					</view>
+				</view>
+				<!-- 物流信息列表END -->
+			</view>
+		</scroll-view>
+		<view class="lee-logistics-defults" :style="{ height }" v-else>
+			<view class="lee-logistics-defults-icon leeIcon-empty"></view>
+			<view class="lee-logistics-defults-title">暂无查询结果</view>
+			<view class="lee-logistics-defults-intro">单号输入错误或暂未寄出</view>
+		</view>
+	</block>
+</template>
+
+<script>
+	export default {
+		props: {
+			expresssn: {
+				type: String,
+				required: true
+			},
+			height: {
+				type: String,
+				default: '100%'
+			}
+		},
+		data() {
+			return {
+				init: false,
+				result: null
+			}
+		},
+		filters: {
+			// 格式化物流信息
+			contextFormatter(v) {
+				return v.replace(/\d{11}/, re => `<span class="phoneText">${re}</span>`)
+			}
+		},
+		created() {
+			// this.search()
+		},
+		methods: {
+			// 查询快递信息
+			async search(express, expresssn) { 
+				let list = await this.$api.request('/order/express', 'POST', {
+					express: express,
+					expresssn: expresssn
+				});				 
+				if (list) {
+					this.init = true
+					this.result = list;
+				}
+			},
+			
+			// 查询到数据后的处理函数
+			dataHandler(res) {
+				this.init = true
+				this.result = res.status === 1 && res.data.status ? res.data : null
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	@import './icon.scss';
+	
+	.lee-logistics-defults {
+		height: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		flex-direction: column;
+		color: $uni-text-color-grey;
+		
+		&-icon {
+			font-size: 200rpx;
+			font-weight: 600;
+		}
+		
+		&-title {
+			font-size: 40rpx;
+			margin-bottom: 10rpx;
+		}
+		
+		&-intro {
+			font-size: 32rpx;
+		}
+	}
+	
+	.lee-logistics {
+		padding: 30rpx;
+		
+		&-list {
+			padding: 30rpx;
+			background-color: $uni-bg-color;
+			border-radius: 8rpx;
+			box-shadow: 0 0 2rpx rgba(0, 0, 0, .15);
+			padding-top: 50rpx;
+		}
+	}
+	
+	.lee-logistics-caption {
+		padding: 30rpx;
+		background-color: $uni-bg-color;
+		border-radius: 8rpx;
+		box-shadow: 0 0 2rpx rgba(0, 0, 0, .15);
+		display: flex;
+		align-items: center;
+		margin-bottom: 30rpx;
+	
+		&-logo {
+			$size: 120rpx;
+			width: $size;
+			height: $size;
+		}
+		
+		&-info {
+			flex: 1;
+			width: 0;
+			margin-left: 30rpx;
+		}
+		
+		&-status {
+			font-size: 36rpx;
+			font-weight: 400;
+			margin-bottom: 10rpx;
+		}
+		
+		&-nu {
+			font-size: 32rpx;
+		}
+	}
+	
+	.lee-logistics-msg {
+		display: flex;
+	
+		&-time {
+			width: 162rpx;
+			display: flex;
+			flex-direction: column;
+			align-items: flex-end;
+			padding-right: 30rpx;
+			font-size: 24rpx;
+		}
+		
+		&-context {
+			flex: 1;
+			width: 0;
+			padding-left: 30rpx;
+			padding-bottom: 50rpx;
+			border-left: 2rpx solid $uni-border-color;
+			position: relative;
+			font-size: 32rpx;
+			
+			&::before {
+				--size: 20rpx;
+				content: '';
+				position: absolute;
+				width: var(--size);
+				height: var(--size);
+				top: calc(-1 * var(--size) / 2);
+				left: calc(-1 * var(--size) / 2);
+				background-color: $uni-border-color;
+				border-radius: 50%;
+			}
+			
+		}
+		
+		&:last-child > &-context {
+			border: none;
+		}
+		&:first-child > &-context {
+			border-color: $uni-color-primary;
+			border-left-style: dashed;
+			
+			&::before {
+				--size: 30rpx;
+				background-color: $uni-color-primary;
+			}
+		}
+	}
+	
+	.phoneText {
+		color: $uni-color-primary;
+		font-weight: 600;
+	}
+</style>

+ 119 - 0
components/mix-list-cell.vue

@@ -0,0 +1,119 @@
+<template>
+	<view class="content">
+		
+		<view class="mix-list-cell" :class="border" @click="eventClick" hover-class="cell-hover"  :hover-stay-time="50">
+			<text
+				v-if="icon"
+				class="cell-icon yticon"
+				:style="[{
+					color: iconColor,
+				}]"
+				:class="icon"
+			></text>
+			<text class="cell-tit clamp">{{title}}</text>
+			<text v-if="tips" class="cell-tip">{{tips}}</text>
+			<text class="cell-more yticon"
+				:class="typeList[navigateType]"
+			></text>
+		</view>
+
+	</view>
+</template>
+ 
+<script>
+	/**
+	 *  简单封装了下, 应用范围比较狭窄,可以在此基础上进行扩展使用
+	 *  比如加入image, iconSize可控等
+	 */
+	export default {
+		data() {
+			return {
+				typeList: {
+					left: 'icon-zuo',
+					right: 'icon-you',
+					up: 'icon-shang',
+					down: 'icon-xia'
+				},
+			}
+		},
+		props: {
+			icon: {
+				type: String,
+				default: ''
+			},
+			title: {
+				type: String,
+				default: '标题'
+			},
+			tips: {
+				type: String,
+				default: ''
+			},
+			navigateType: {
+				type: String,
+				default: 'right'
+			},
+			border: {
+				type: String,
+				default: 'b-b'
+			},
+			hoverClass: {
+				type: String,
+				default: 'cell-hover'
+			},
+			iconColor: {
+				type: String,
+				default: '#333'
+			}
+		},
+		methods: {
+			eventClick(){
+				this.$emit('eventClick');
+			}
+		},
+	}
+</script>
+
+<style lang='scss'>
+
+	.icon .mix-list-cell.b-b:after{
+		left: 90upx;
+	}
+	.mix-list-cell{
+		display:flex;
+		align-items:baseline;
+		padding: 20upx $page-row-spacing;
+		line-height:60upx;
+		position:relative;
+		
+		&.cell-hover{
+			background:#fafafa;
+		}
+		&.b-b:after{
+			left: 30upx;
+		}
+
+		.cell-icon{
+			align-self:center;
+			width:56upx;
+			max-height:60upx;
+			font-size:38upx;
+		}
+		.cell-more{
+			align-self: center;
+			font-size:30upx;
+			color:$font-color-base;
+			margin-left:$uni-spacing-row-sm;
+		}
+		.cell-tit{
+			flex: 1;
+			font-size: $font-base;
+			color: $font-color-dark;
+			margin-right:10upx;
+		}
+		.cell-tip{
+			font-size: $font-sm+2upx;
+			color: $font-color-light;
+		}
+	}
+</style>

File diff suppressed because it is too large
+ 68 - 0
components/mix-loading/mix-loading.vue


+ 249 - 0
components/mpvueCityPicker.vue

@@ -0,0 +1,249 @@
+<template>
+	<div class="mpvue-picker">
+		<div :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></div>
+		<div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
+			<div class="mpvue-picker__hd" catchtouchmove="true">
+				<div class="mpvue-picker__action" @click="pickerCancel">取消</div>
+				<div class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</div>
+			</div>
+			<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange">
+				<block>
+					<picker-view-column>
+						<div class="picker-item" v-for="(item,index) in provinceDataList" :key="index">{{item.label}}</div>
+					</picker-view-column>
+					<picker-view-column>
+						<div class="picker-item" v-for="(item,index) in cityDataList" :key="index">{{item.label}}</div>
+					</picker-view-column>
+					<picker-view-column>
+						<div class="picker-item" v-for="(item,index) in areaDataList" :key="index">{{item.label}}</div>
+					</picker-view-column>
+				</block>
+			</picker-view>
+		</div>
+	</div>
+</template>
+
+<script>
+	
+	export default {
+		data() {
+			return {
+				pickerValue: [0, 0, 0],
+				provinceDataList: [],
+				cityDataList: [],
+				areaDataList: [],
+				showPicker: false,
+				pickerValueDefault:[0,0,0]
+			};
+		},
+		async created() {
+			
+			// 微信小程序不需要这行 ,H5需要
+			// #ifndef MP
+			this.pickerValue = await this.handPickValueDefault();
+			this._$emit('onConfirm');
+			// #endif
+		},
+		props: {
+			/* 默认值 */
+			// pickerValueDefault: {
+			// 	type: Array,
+			// 	default: [0, 0, 0]
+			// },
+			/* 主题色 */
+			themeColor: {
+				type: String,
+				default: '#1aad19'
+			}
+		},
+		methods: {
+			async creat(pickerValueDefault) {
+				this.pickerValueDefault = pickerValueDefault;
+				this.pickerValue = await this.handPickValueDefault();
+				this._$emit('onConfirm');
+			},
+			show() {
+				setTimeout(() => {
+					this.showPicker = true;
+				}, 0);
+			},
+			maskClick() {
+				this.pickerCancel();
+			},
+			pickerCancel() {
+				this.showPicker = false;
+				this._$emit('onCancel');
+			},
+			pickerConfirm(e) {
+				this.showPicker = false;
+				this._$emit('onConfirm');
+			},
+			showPickerView() {
+				this.showPicker = true;
+			},
+			async handPickValueDefault() {
+				let tempPickerValue = this.pickerValueDefault;
+				console.log(tempPickerValue);
+				
+				this.provinceDataList = await this.$api.request('/address/area?pid=0');
+				this.cityDataList = await this.$api.request('/address/area?pid=' + (tempPickerValue[0] != 0 ? tempPickerValue[0] : this.provinceDataList[0].id));
+				this.areaDataList = await this.$api.request('/address/area?pid=' + (tempPickerValue[1] != 0 ? tempPickerValue[1] : this.cityDataList[0].id));
+		
+				for (let i in this.provinceDataList) {
+					if (this.provinceDataList[i].id == tempPickerValue[0]) {
+						tempPickerValue[0] = i;
+						break;
+					}
+				}
+				for (let i in this.cityDataList) {
+					if (this.cityDataList[i].id == tempPickerValue[1]) {
+						tempPickerValue[1] = i;
+						break;
+					}
+				}
+				for (let i in this.areaDataList) {
+					if (this.areaDataList[i].id == tempPickerValue[2]) {
+						tempPickerValue[2] = i;
+						break;
+					}
+				}
+				
+				return tempPickerValue;
+			},
+			async pickerChange(e) {
+				let changePickerValue = e.mp.detail.value;
+	
+				if (this.pickerValue[0] !== changePickerValue[0]) {
+					// 第一级发生滚动
+					// this.cityDataList = cityData[changePickerValue[0]];
+					// this.areaDataList = areaData[changePickerValue[0]][0];
+
+					let provinceId = this.provinceDataList[changePickerValue[0]].id;
+					this.cityDataList = await this.$api.request('/address/area?pid=' + provinceId);
+					this.areaDataList = await this.$api.request('/address/area?pid=' + this.cityDataList[0].id);
+
+					changePickerValue[1] = 0;
+					changePickerValue[2] = 0;
+				} else if (this.pickerValue[1] !== changePickerValue[1]) {
+					// 第二级滚动
+					// this.areaDataList =
+					// 	areaData[changePickerValue[0]][changePickerValue[1]];
+
+					let cityId = this.cityDataList[changePickerValue[1]].id;
+					this.areaDataList = await this.$api.request('/address/area?pid=' + cityId);
+
+					changePickerValue[2] = 0;
+				}
+				this.pickerValue = changePickerValue;
+				this._$emit('onChange');
+			},
+			_$emit(emitName) {
+				let pickObj = {
+					label: this._getLabel(),
+					value: this._getAreaId(),
+					cityCode: this._getCityCode()
+				};
+				this.$emit(emitName, pickObj);
+			},
+			_getLabel() {
+				let pcikerLabel =
+					this.provinceDataList[this.pickerValue[0]].label +
+					'-' +
+					this.cityDataList[this.pickerValue[1]].label +
+					'-' +
+					this.areaDataList[this.pickerValue[2]].label;
+				return pcikerLabel;
+			},
+			_getCityCode() {
+				return this.areaDataList[this.pickerValue[2]].value;
+			},
+			_getAreaId() {
+				let areaId = [
+					this.provinceDataList[this.pickerValue[0]].id,
+					this.cityDataList[this.pickerValue[1]].id,
+					this.areaDataList[this.pickerValue[2]].id
+				];
+				return areaId;
+			}
+		}
+	};
+</script>
+
+<style>
+	.pickerMask {
+		position: fixed;
+		z-index: 1000;
+		top: 0;
+		right: 0;
+		left: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+	}
+
+	.mpvue-picker-content {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		transition: all 0.3s ease;
+		transform: translateY(100%);
+		z-index: 3000;
+	}
+
+	.mpvue-picker-view-show {
+		transform: translateY(0);
+	}
+
+	.mpvue-picker__hd {
+		display: flex;
+		padding: 9px 15px;
+		background-color: #fff;
+		position: relative;
+		text-align: center;
+		font-size: 17px;
+	}
+
+	.mpvue-picker__hd:after {
+		content: " ";
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		height: 1px;
+		border-bottom: 1px solid #e5e5e5;
+		color: #e5e5e5;
+		transform-origin: 0 100%;
+		transform: scaleY(0.5);
+	}
+
+	.mpvue-picker__action {
+		display: block;
+		flex: 1;
+		color: #1aad19;
+	}
+
+	.mpvue-picker__action:first-child {
+		text-align: left;
+		color: #888;
+	}
+
+	.mpvue-picker__action:last-child {
+		text-align: right;
+	}
+
+	.picker-item {
+		text-align: center;
+		line-height: 40px;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+	}
+
+	.mpvue-picker-view {
+		position: relative;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		height: 238px;
+		background-color: rgba(255, 255, 255, 1);
+	}
+</style>

+ 202 - 0
components/share.vue

@@ -0,0 +1,202 @@
+<template>
+	<view v-if="show" class="mask" @click="toggleMask" @touchmove.stop.prevent="stopPrevent"
+		:style="{backgroundColor: backgroundColor}"
+	>
+		<view 
+			class="mask-content"
+			@click.stop.prevent="stopPrevent"
+			:style="[{
+				height: config.height, 
+				transform: transform
+			}]"
+		>
+			<scroll-view class="view-content" scroll-y>
+				<view class="share-header">
+					分享到
+				</view>
+				<view class="share-list">
+					<view 
+						v-for="(item, index) in shareList" :key="index"
+						class="share-item" 
+						@click="shareToFriend(item.text)"
+					>
+						<image :src="item.icon" mode=""></image>
+						<text>{{item.text}}</text>
+					</view>
+				</view>
+			</scroll-view>
+			<view class="bottom b-t" @click="toggleMask">取消</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				transform: 'translateY(50vh)',
+				timer: 0,
+				backgroundColor: 'rgba(0,0,0,0)',
+				show: false,
+				config: {},
+			};
+		},
+		props:{
+			contentHeight:{
+				type: Number,
+				default: 0
+			},
+			//是否是tabbar页面
+			hasTabbar:{
+				type: Boolean,
+				default: false
+			},
+			shareList:{
+				type: Array,
+				default: function(){
+					return [];
+				}
+			}
+		},
+		created() {
+			const height = uni.upx2px(this.contentHeight) + 'px';
+			this.config = {
+				height: height,
+				transform: `translateY(${height})`,
+				backgroundColor: 'rgba(0,0,0,.4)',
+			}
+			this.transform = this.config.transform;
+		},
+		methods:{
+			toggleMask(){
+				//防止高频点击
+				if(this.timer == 1){
+					return;
+				}
+				this.timer = 1;
+				setTimeout(()=>{
+					this.timer = 0;
+				}, 500)
+				
+				if(this.show){
+					this.transform = this.config.transform;
+					this.backgroundColor = 'rgba(0,0,0,0)';
+					setTimeout(()=>{
+						this.show = false;
+						this.hasTabbar && uni.showTabBar();
+					}, 200)
+					return;
+				}
+				
+				this.show = true;
+				//等待mask重绘完成执行
+				if(this.hasTabbar){
+					uni.hideTabBar({
+						success: () => {
+							setTimeout(()=>{
+								this.backgroundColor = this.config.backgroundColor;
+								this.transform = 'translateY(0px)';
+							}, 10)
+						}
+					});
+				}else{
+					setTimeout(()=>{
+						this.backgroundColor = this.config.backgroundColor;
+						this.transform = 'translateY(0px)';
+					}, 10)
+				}
+			},
+			//防止冒泡和滚动穿透
+			stopPrevent(){},
+			//分享操作
+			shareToFriend(type){
+				this.$api.msg(`分享给${type}`);
+				this.toggleMask();
+			},
+		}
+	}
+</script>
+
+<style lang='scss'>
+	.mask{
+		position:fixed;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		display:flex;
+		justify-content: center;
+		align-items: flex-end;
+		z-index: 998;
+		transition: .3s;
+		.bottom{
+			position:absolute;
+			left: 0;
+			bottom: 0;
+			display:flex;
+			justify-content: center;
+			align-items: center;
+			width: 100%;
+			height: 90upx;
+			background: #fff;
+			z-index: 9;
+			font-size: $font-base + 2upx;
+			color: $font-color-dark;
+		}
+	}
+	
+	.mask-content{
+		width: 100%;
+		height: 580upx;
+		transition: .3s;
+		background: #fff;
+		&.has-bottom{
+			padding-bottom: 90upx;
+		}
+		.view-content{
+			height: 100%;
+		}
+	}
+	.share-header{
+		height: 110upx;
+		font-size: $font-base+2upx;
+		color: font-color-dark;
+		display:flex;
+		align-items:center;
+		justify-content: center;
+		padding-top: 10upx;
+		&:before, &:after{
+			content: '';
+			width: 240upx;
+			heighg: 0;
+			border-top: 1px solid $border-color-base;
+			transform: scaleY(.5);
+			margin-right: 30upx;
+		}
+		 &:after{
+			 margin-left: 30upx;
+			 margin-right: 0;
+		 }
+	}
+	.share-list{
+		display:flex;
+		flex-wrap: wrap;
+	}
+	.share-item{
+		min-width: 33.33%;
+		display:flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		height: 180upx;
+		image{
+			width: 80upx;
+			height: 80upx;
+			margin-bottom: 16upx;
+		}
+		text{
+			font-size: $font-base;
+			color: $font-color-base;
+		}
+	}
+</style>

+ 199 - 0
components/uni-countdown/uni-countdown.vue

@@ -0,0 +1,199 @@
+<template>
+	<view class="uni-countdown">
+		<text v-if="showDay" :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor, width: borderWidth }" class="uni-countdown__number">{{ d }}</text>
+		<text v-if="showDay" :style="{ color: splitorColor }" class="uni-countdown__splitor">天</text>
+		<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor, width: borderWidth  }" class="uni-countdown__number">{{ h }}</text>
+		<text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? ':' : '时' }}</text>
+		<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor, width: borderWidth  }" class="uni-countdown__number">{{ i }}</text>
+		<text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? ':' : '分' }}</text>
+		<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor, width: borderWidth  }" class="uni-countdown__number">{{ s }}</text>
+		<text v-if="!showColon" :style="{ color: splitorColor }" class="uni-countdown__splitor">秒</text>
+	</view>
+</template>
+<script>
+	export default {
+		name: 'UniCountdown',
+		props: {
+			showDay: {
+				type: Boolean,
+				default: true
+			},
+			showColon: {
+				type: Boolean,
+				default: true
+			},
+			backgroundColor: {
+				type: String,
+				default: '#FFFFFF'
+			},
+			borderColor: {
+				type: String,
+				default: '#000000'
+			},
+			color: {
+				type: String,
+				default: '#000000'
+			},
+			splitorColor: {
+				type: String,
+				default: '#000000'
+			},
+			day: {
+				type: Number,
+				default: 0
+			},
+			hour: {
+				type: Number,
+				default: 0
+			},
+			minute: {
+				type: Number,
+				default: 0
+			},
+			second: {
+				type: Number,
+				default: 0
+			},
+			borderWidth: {
+				type: String,
+				default: "52rpx"
+			}
+		},
+		data() {
+			return {
+				timer: null,
+				syncFlag: false,
+				d: '00',
+				h: '00',
+				i: '00',
+				s: '00',
+				leftTime: 0,
+				seconds: 0
+			}
+		},
+		watch: {
+			day(val) {
+				this.changeFlag()
+			},
+			hour(val) {
+				this.changeFlag()
+			},
+			minute(val) {
+				this.changeFlag()
+			},
+			second(val) {
+				this.changeFlag()
+			}
+		},
+		created: function(e) {
+			this.startData();
+		},
+		beforeDestroy() {
+			clearInterval(this.timer)
+		},
+		methods: {
+			toSeconds(day, hours, minutes, seconds) {
+				return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
+			},
+			timeUp() {
+				clearInterval(this.timer)
+				this.timer = 0;
+				// 优化建议:提前1秒去请求
+				this.$emit('timeup', this)
+			},
+			countDown() {
+				let seconds = this.seconds
+				let [day, hour, minute, second] = [0, 0, 0, 0]
+				if (seconds > 0) {
+					day = Math.floor(seconds / (60 * 60 * 24))
+					hour = Math.floor(seconds / (60 * 60)) - (day * 24)
+					minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
+					second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
+				} else {
+					this.timeUp()
+				}
+				if (day < 10) {
+					day = '0' + day
+				}
+				if (hour < 10) {
+					hour = '0' + hour
+				}
+				if (minute < 10) {
+					minute = '0' + minute
+				}
+				if (second < 10) {
+					second = '0' + second
+				}
+				this.d = day
+				this.h = hour
+				this.i = minute
+				this.s = second
+			},
+			startData() {
+				this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
+				if (this.seconds <= 0) {
+					this.timeUp()
+					return
+				}
+				if (this.timer > 0){
+					return;
+				}
+				this.countDown()
+				this.timer = setInterval(() => {
+					this.seconds--
+					if (this.seconds < 0) {
+						this.timeUp()
+						return
+					}
+					this.countDown()
+				}, 1000)
+				//console.log('timer:' + this.timer);
+			},
+			changeFlag() {
+				if (!this.syncFlag) {
+					this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
+					this.startData();
+					this.syncFlag = true;
+				} 
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	@import '~@/uni.scss';
+	$countdown-height: 48rpx;
+	$countdown-width: 52rpx;
+
+	.uni-countdown {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: flex-start;
+		padding: 2rpx 0;
+	}
+
+	.uni-countdown__splitor {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		line-height: $countdown-height;
+		padding: 5rpx;
+		font-size: $uni-font-size-sm;
+	}
+
+	.uni-countdown__number {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		width: $countdown-width;
+		height: $countdown-height;
+		line-height: $countdown-height;
+		margin: 5rpx;
+		text-align: center;
+		font-size: $uni-font-size-sm;
+	}
+</style>

+ 96 - 0
components/uni-icons/icons.js

@@ -0,0 +1,96 @@
+export default {
+	'contact': '\ue100',
+	'person': '\ue101',
+	'personadd': '\ue102',
+	'contact-filled': '\ue130',
+	'person-filled': '\ue131',
+	'personadd-filled': '\ue132',
+	'phone': '\ue200',
+	'email': '\ue201',
+	'chatbubble': '\ue202',
+	'chatboxes': '\ue203',
+	'phone-filled': '\ue230',
+	'email-filled': '\ue231',
+	'chatbubble-filled': '\ue232',
+	'chatboxes-filled': '\ue233',
+	'weibo': '\ue260',
+	'weixin': '\ue261',
+	'pengyouquan': '\ue262',
+	'chat': '\ue263',
+	'qq': '\ue264',
+	'videocam': '\ue300',
+	'camera': '\ue301',
+	'mic': '\ue302',
+	'location': '\ue303',
+	'mic-filled': '\ue332',
+	'speech': '\ue332',
+	'location-filled': '\ue333',
+	'micoff': '\ue360',
+	'image': '\ue363',
+	'map': '\ue364',
+	'compose': '\ue400',
+	'trash': '\ue401',
+	'upload': '\ue402',
+	'download': '\ue403',
+	'close': '\ue404',
+	'redo': '\ue405',
+	'undo': '\ue406',
+	'refresh': '\ue407',
+	'star': '\ue408',
+	'plus': '\ue409',
+	'minus': '\ue410',
+	'circle': '\ue411',
+	'checkbox': '\ue411',
+	'close-filled': '\ue434',
+	'clear': '\ue434',
+	'refresh-filled': '\ue437',
+	'star-filled': '\ue438',
+	'plus-filled': '\ue439',
+	'minus-filled': '\ue440',
+	'circle-filled': '\ue441',
+	'checkbox-filled': '\ue442',
+	'closeempty': '\ue460',
+	'refreshempty': '\ue461',
+	'reload': '\ue462',
+	'starhalf': '\ue463',
+	'spinner': '\ue464',
+	'spinner-cycle': '\ue465',
+	'search': '\ue466',
+	'plusempty': '\ue468',
+	'forward': '\ue470',
+	'back': '\ue471',
+	'left-nav': '\ue471',
+	'checkmarkempty': '\ue472',
+	'home': '\ue500',
+	'navigate': '\ue501',
+	'gear': '\ue502',
+	'paperplane': '\ue503',
+	'info': '\ue504',
+	'help': '\ue505',
+	'locked': '\ue506',
+	'more': '\ue507',
+	'flag': '\ue508',
+	'home-filled': '\ue530',
+	'gear-filled': '\ue532',
+	'info-filled': '\ue534',
+	'help-filled': '\ue535',
+	'more-filled': '\ue537',
+	'settings': '\ue560',
+	'list': '\ue562',
+	'bars': '\ue563',
+	'loop': '\ue565',
+	'paperclip': '\ue567',
+	'eye': '\ue568',
+	'arrowup': '\ue580',
+	'arrowdown': '\ue581',
+	'arrowleft': '\ue582',
+	'arrowright': '\ue583',
+	'arrowthinup': '\ue584',
+	'arrowthindown': '\ue585',
+	'arrowthinleft': '\ue586',
+	'arrowthinright': '\ue587',
+	'pulldown': '\ue588',
+	'closefill': '\ue589',
+	'sound': '\ue590',
+	'scan': '\ue612'
+}

File diff suppressed because it is too large
+ 57 - 0
components/uni-icons/uni-icons.vue


+ 194 - 0
components/uni-load-more/uni-load-more.vue

@@ -0,0 +1,194 @@
+<template>
+	<view class="uni-load-more">
+		<view class="uni-load-more__img" v-show="status === 'loading' && showIcon">
+			<view class="load1">
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+			</view>
+			<view class="load2">
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+			</view>
+			<view class="load3">
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+				<view :style="{background:color}"></view>
+			</view>
+		</view>
+		<text class="uni-load-more__text" :style="{color:color}">{{status === 'more' ? contentText.contentdown : (status === 'loading' ? contentText.contentrefresh : contentText.contentnomore)}}</text>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "uni-load-more",
+		props: {
+			status: {
+				//上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
+				type: String,
+				default: 'more'
+			},
+			showIcon: {
+				type: Boolean,
+				default: true
+			},
+			color: {
+				type: String,
+				default: "#777777"
+			},
+			contentText: {
+				type: Object,
+				default () {
+					return {
+						contentdown: "上拉显示更多",
+						contentrefresh: "正在加载...",
+						contentnomore: "没有更多数据了"
+					};
+				}
+			}
+		},
+		data() {
+			return {}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-load-more {
+		display: flex;
+		flex-direction: row;
+		height: 80upx;
+		align-items: center;
+		justify-content: center
+	}
+
+	.uni-load-more__text {
+		font-size: 28upx;
+		color: #999
+	}
+
+	.uni-load-more__img {
+		height: 24px;
+		width: 24px;
+		margin-right: 10px
+	}
+
+	.uni-load-more__img>view {
+		position: absolute
+	}
+
+	.uni-load-more__img>view view {
+		width: 6px;
+		height: 2px;
+		border-top-left-radius: 1px;
+		border-bottom-left-radius: 1px;
+		background: #999;
+		position: absolute;
+		opacity: .2;
+		transform-origin: 50%;
+		animation: load 1.56s ease infinite
+	}
+
+	.uni-load-more__img>view view:nth-child(1) {
+		transform: rotate(90deg);
+		top: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(2) {
+		transform: rotate(180deg);
+		top: 11px;
+		right: 0
+	}
+
+	.uni-load-more__img>view view:nth-child(3) {
+		transform: rotate(270deg);
+		bottom: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(4) {
+		top: 11px;
+		left: 0
+	}
+
+	.load1,
+	.load2,
+	.load3 {
+		height: 24px;
+		width: 24px
+	}
+
+	.load2 {
+		transform: rotate(30deg)
+	}
+
+	.load3 {
+		transform: rotate(60deg)
+	}
+
+	.load1 view:nth-child(1) {
+		animation-delay: 0s
+	}
+
+	.load2 view:nth-child(1) {
+		animation-delay: .13s
+	}
+
+	.load3 view:nth-child(1) {
+		animation-delay: .26s
+	}
+
+	.load1 view:nth-child(2) {
+		animation-delay: .39s
+	}
+
+	.load2 view:nth-child(2) {
+		animation-delay: .52s
+	}
+
+	.load3 view:nth-child(2) {
+		animation-delay: .65s
+	}
+
+	.load1 view:nth-child(3) {
+		animation-delay: .78s
+	}
+
+	.load2 view:nth-child(3) {
+		animation-delay: .91s
+	}
+
+	.load3 view:nth-child(3) {
+		animation-delay: 1.04s
+	}
+
+	.load1 view:nth-child(4) {
+		animation-delay: 1.17s
+	}
+
+	.load2 view:nth-child(4) {
+		animation-delay: 1.3s
+	}
+
+	.load3 view:nth-child(4) {
+		animation-delay: 1.43s
+	}
+
+	@-webkit-keyframes load {
+		0% {
+			opacity: 1
+		}
+
+		100% {
+			opacity: .2
+		}
+	}
+</style>

+ 205 - 0
components/uni-number-box.vue

@@ -0,0 +1,205 @@
+<template>
+	<view class="uni-numbox" @click.stop="nothing">
+		<view class="uni-numbox-minus" 
+			@click="_calcValue('subtract')"
+		>
+			<text class="yticon icon-jianhao" :class="isMin?'uni-numbox-disabled': ''" ></text>
+			<!-- <text class="yticon icon-jianhao" :class="minDisabled?'uni-numbox-disabled': ''" ></text> -->
+		</view>
+		<input 
+			class="uni-numbox-value" 
+			type="number" 
+			:disabled="disabled"
+			:value="inputValue"
+			@input="_onBlur"
+			@blur="_onBlur"
+		>
+		<view 
+			class="uni-numbox-plus" 
+			@click="_calcValue('add')"
+		>
+			<text class="yticon icon-jiahao" :class="isMax?'uni-numbox-disabled': ''" ></text>
+			<!-- <text class="yticon icon-jiahao" :class="maxDisabled?'uni-numbox-disabled': ''" ></text> -->
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		name: 'uni-number-box',
+		props: {
+			isMax: {
+				type: Boolean,
+				default: false
+			},
+			isMin: {
+				type: Boolean,
+				default: false
+			},
+			index: {
+				type: Number,
+				default: 0
+			},
+			value: {
+				type: Number,
+				default: 0
+			},
+			min: {
+				type: Number,
+				default: -Infinity
+			},
+			max: {
+				type: Number,
+				default: Infinity
+			},
+			step: {
+				type: Number,
+				default: 1
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				inputValue: this.value,
+				minDisabled: false,
+				maxDisabled: false
+			}
+		},
+		created(){
+			this.maxDisabled = this.isMax;
+			this.minDisabled = this.isMin;
+		},
+		computed: {
+			
+		},
+		watch: {
+			value(number){
+				this.inputValue = number;
+			},
+			inputValue(number) {
+				const data = {
+					number: number,
+					index: this.index
+				}
+				this.$emit('eventChange', data);
+			}
+		},
+		methods: {
+			nothing(){},
+			_calcValue(type) {
+				const scale = this._getDecimalScale();
+				let value = this.inputValue * scale;
+				let newValue = 0;
+				let step = this.step * scale;
+				
+				if(type === 'subtract'){
+					newValue = value - step;
+					if (newValue <= this.min){
+						this.minDisabled = true;
+					}
+					if(newValue < this.min){
+						newValue = this.min
+					}
+					if(newValue < this.max && this.maxDisabled === true){
+						this.maxDisabled = false;
+					}
+				}else if(type === 'add'){
+					newValue = value + step;
+					if (newValue >= this.max){
+						this.maxDisabled = true;
+					}
+					if(newValue > this.max){
+						newValue = this.max
+					}
+					if(newValue > this.min && this.minDisabled === true){
+						this.minDisabled = false;
+					}
+				}
+				if(newValue === value){
+					return;
+				}
+				this.inputValue = newValue / scale;
+			},
+			_getDecimalScale() {
+				let scale = 1;
+				// 浮点型
+				if (~~this.step !== this.step) {
+					scale = Math.pow(10, (this.step + '').split('.')[1].length);
+				}
+				return scale;
+			},
+			_onBlur(event) {
+				let value = event.detail.value;
+				if (!value) {
+					this.inputValue = 0;
+					return
+				}
+				value = +value;
+				if (value > this.max) {
+					value = this.max;
+				} else if (value < this.min) {
+					value = this.min
+				}
+
+				this.inputValue = value
+			}
+		}
+	}
+</script>
+<style>
+	.uni-numbox {
+		position:absolute;
+		left: 30upx;
+		bottom: 0;
+		display: flex;
+		justify-content: flex-start;
+		align-items: center;
+		width:230upx;
+		height: 70upx;
+		background:#f5f5f5;
+	}
+
+	.uni-numbox-minus,
+	.uni-numbox-plus {
+		margin: 0;
+		background-color: #f5f5f5;
+		width: 70upx;
+		height: 100%;
+		line-height: 70upx;
+		text-align: center;
+		position: relative;
+	}
+	.uni-numbox-minus .yticon,
+	.uni-numbox-plus .yticon{
+		font-size: 36upx;
+		color: #555;
+	}
+
+	.uni-numbox-minus {
+		border-right: none;
+		border-top-left-radius: 6upx;
+		border-bottom-left-radius: 6upx;
+	}
+
+	.uni-numbox-plus {
+		border-left: none;
+		border-top-right-radius: 6upx;
+		border-bottom-right-radius: 6upx;
+	}
+
+	.uni-numbox-value {
+		position: relative;
+		background-color: #f5f5f5;
+		width: 90upx;
+		height: 50upx;
+		text-align: center;
+		padding: 0;
+		font-size: 30upx;
+	}
+
+	.uni-numbox-disabled.yticon {
+		color: #d6d6d6;
+	}
+</style>

+ 142 - 0
components/uni-rate/uni-rate.vue

@@ -0,0 +1,142 @@
+<template>
+	<view class="uni-rate">
+		<view :key="index" :style="{ marginLeft: margin + 'px' }" @click="_onClick(index)" class="uni-rate__icon" v-for="(star, index) in stars">
+			<uni-icons :color="color" :size="size" :type="isFill ? 'star-filled' : 'star'" />
+			<!-- #ifdef APP-NVUE -->
+			<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on">
+				<uni-icons style="text-align: left;" :color="activeColor" :size="size" type="star-filled" />
+			</view>
+			<!-- #endif -->
+			<!-- #ifndef APP-NVUE -->
+			<view :style="{ width: star.activeWitch,top:-size/2+'px' }" class="uni-rate__icon-on">
+				<uni-icons :color="activeColor" :size="size" type="star-filled" />
+			</view>
+			<!-- #endif -->
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniIcons from "../uni-icons/uni-icons.vue";
+	export default {
+		name: "UniRate",
+		components: {
+			uniIcons
+		},
+		props: {
+			isFill: {
+				// 星星的类型,是否镂空
+				type: [Boolean, String],
+				default: true
+			},
+			color: {
+				// 星星的颜色
+				type: String,
+				default: "#ececec"
+			},
+			activeColor: {
+				// 星星选中状态颜色
+				type: String,
+				default: "#ffca3e"
+			},
+			size: {
+				// 星星的大小
+				type: [Number, String],
+				default: 24
+			},
+			value: {
+				// 当前评分
+				type: [Number, String],
+				default: 0
+			},
+			max: {
+				// 最大评分
+				type: [Number, String],
+				default: 5
+			},
+			margin: {
+				// 星星的间距
+				type: [Number, String],
+				default: 0
+			},
+			disabled: {
+				// 是否可点击
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		data() {
+			return {
+				valueSync: ""
+			};
+		},
+		computed: {
+			stars() {
+				const value = this.valueSync ? this.valueSync : 0;
+				const starList = [];
+				const floorValue = Math.floor(value);
+				const ceilValue = Math.ceil(value);
+				// console.log("ceilValue: " + ceilValue);
+				// console.log("floorValue: " + floorValue);
+				for (let i = 0; i < this.max; i++) {
+					if (floorValue > i) {
+						starList.push({
+							activeWitch: "100%"
+						});
+					} else if (ceilValue - 1 === i) {
+						starList.push({
+							activeWitch: (value - floorValue) * 100 + "%"
+						});
+					} else {
+						starList.push({
+							activeWitch: "0"
+						});
+					}
+				}
+				//console.log("starList[4]: " + starList[4].activeWitch);
+				return starList;
+			}
+		},
+		created() {
+			this.valueSync = Number(this.value);
+		},
+		methods: {
+			_onClick(index) {
+				if (this.disabled) {
+					return;
+				}
+				this.valueSync = index + 1;
+				this.$emit("change", {
+					value: this.valueSync
+				});
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.uni-rate {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		line-height: 0;
+		font-size: 0;
+		flex-direction: row;
+	}
+
+	.uni-rate__icon {
+		position: relative;
+		line-height: 0;
+		font-size: 0;
+		display: inline-block;
+	}
+
+	.uni-rate__icon-on {
+		overflow: hidden;
+		position: absolute;
+		top: 0;
+		left: 0;
+		line-height: 1;
+		text-align: left;
+	}
+</style>

File diff suppressed because it is too large
+ 226 - 0
components/upload-images.vue


+ 13 - 0
components/z-table/table-render.js

@@ -0,0 +1,13 @@
+import Vue from 'vue'
+
+Vue.mixin({
+	methods: {
+		tableNameRender(h, {
+			row,
+			col
+		}) {
+			console.log(row)
+			return h('view', row.name)
+		}
+	}
+})

+ 782 - 0
components/z-table/z-table.vue

@@ -0,0 +1,782 @@
+<template>
+	<view class="z-table">
+		<view class="z-table-main" :style="compluteHeight">
+			<view v-if="!tableLoaded && (!tableData || !columns)" :class="['z-loading', {ztableLoading: tableShow}]">
+				<view class="z-loading-animate"></view>
+			</view>
+			<view class="z-table-container">
+				<view class="z-table-pack">
+					<view class="z-table-title">
+						<view class="z-table-title-item" :class="{ 'z-table-stick-side': stickSide && index == 0 }" :style="{ width: item.width ? item.width + 'rpx' : '200rpx' }"
+						 v-for="(item, index) in columns" :key="index" @click="sort(item.key, index)">
+							<view v-if="showSelect && !singleSelect && index === 0" class="select-box" @click="doSelect(true)">
+								<view :class="['select-tip', {'selected': selectAll}]"></view>
+							</view>
+							<view :class="['z-table-col-text', {'text-left': titleTextAlign === 'left', 'text-center': titleTextAlign === 'center', 'text-right': titleTextAlign === 'right'}]">
+								<view v-html="getTitleText(item.title)"></view>
+								<view v-if="item.hasOwnProperty('key') && item.hasOwnProperty('sort') && tableData.length" class="sort">
+									<view class="up-arrow" :class="{ action: nowSortKey == item.key && sortType == 'asc' }"></view>
+									<view class="down-arrow" :class="{ action: nowSortKey == item.key && sortType == 'desc' }"></view>
+								</view>
+							</view>
+						</view>
+					</view>
+					<view v-if="tableData.length" :class="['table-container-box', {'short-table': !longTable && showBottomSum}]">
+						<view class="z-table-container-row" :class="{ 'z-table-has-bottom': showBottomSum }" v-for="(row, iIndex) in tableData"
+						 :key="iIndex">
+							<view :class="['z-table-container-col', { 'z-table-stick-side': stickSide && jIndex == 0 }]" :style="{ width: col.width ? col.width + 'rpx' : '200rpx' }"
+							 v-for="(col, jIndex) in columns" :key="jIndex" @click="itemClick(row, col)">
+								<view v-if="showSelect && jIndex === 0" class="select-box" @click="doSelect(false, iIndex)">
+									<view :class="['select-tip', {'selected': selectArr.includes(iIndex)}]"></view>
+								</view>
+								<view :class="['z-table-col-text', {'text-left': textAlign === 'left', 'text-center': textAlign === 'center', 'text-right': textAlign === 'right'}]">
+									<view v-if="!col.isLink" v-html="getRowContent(row, col)">
+										<!-- <view v-if="!col.render" v-html="getRowContent(row, col)"></view> -->
+										<!-- <renderComponents v-else :row="row" :col="col" /> -->
+									</view>
+									<!-- #ifdef H5 -->
+									<router-link v-else-if="setUrl(row, col).indexOf('http') != 0" :to="setUrl(row, col)" v-html="getRowContent(row, col)"></router-link>
+									<a v-else-if="col.isLink" :href="setUrl(row, col)" v-html="getRowContent(row, col)"></a>
+									<!-- #endif -->
+									<!-- #ifndef H5 -->
+									<navigator v-else-if="col.isLink" :url="setUrl(row, col)" v-html="getRowContent(row, col)"></navigator>
+									<!-- #endif -->
+								</view>
+							</view>
+						</view>
+					</view>
+					<view :class="['z-table-bottom', {'long-table': longTable}]" v-if="showBottomSum && tableData.length">
+						<view class="z-table-bottom-col" :class="{ 'z-table-stick-side': stickSide && sumIndex == 0 }" :style="{ width: sumCol.width ? sumCol.width + 'rpx' : '200rpx' }"
+						 v-for="(sumCol, sumIndex) in columns" :key="sumIndex">
+							<view class="z-table-bottom-text">
+								<!-- <view v-if="sumIndex != 0" class="z-table-bottom-text-title">{{ sumCol.title }}</view> -->
+								<text :class="{ sum: sumIndex == 0 }">{{ sumIndex == 0 ? '总计' : dosum(sumCol.key) }}</text>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="tableData && tableData.length == 0 && !tableLoaded" class="table-empty">
+				<!-- image v-if="!showLoading" class="empty-img" src="../static/empty.png"></image -->
+				<view v-html="showLoading ? '' : emptyText"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	/*
+	 * 表格使用
+	 * 注意如果需要异步加载,需要把tableData初始值设为false,当没有数据的时候值为空数组
+	 * props: tableData [Array | Boolean] | 表格数据 如果为false则显示loading
+	 * 		 columns [Array | Boolean] | 数据映射表 如果为false则显示loading 每列params => title(表头文字可以是html字符串模版), width(每列宽度) [, key(对应tableData的字段名) || format(自定义内容), sort(是否要排序), isLink(是否显示为超链接Object)]
+	 * 										   format格式: {template: 字符串模版用#key#表示需要被替换的数据,names: 对应template属性内要被替换的内容的key}
+	 * 										   isLink格式: {url: 链接地址, params: 地址带的参数Array[key|value, key|value, ...]每一项都是key和value以'|'链接,如果不带'|'默认键值同名
+	 * 										   listenerClick(是否监听点击事件Boolean)}
+	 * 		 stickSide Boolean | 是否固定右侧首栏 默认不显示
+	 * 		 showBottomSum Boolean | 是否显示底部统计 默认不显示
+	 * 		 showLoading Boolean | 是否首次加载首次加载不显示暂无数据内容
+	 * 		 emptyText String | 空数据显示的文字内容
+	 *		 tableHeight Number | 设置表格高度会滚动
+	 *		 sort Boolean | 开启排序
+	 * 		 showSelect Boolean | 开启选择
+	 *		 singleSelect Boolean | 在开启选择的状态下是否开起单选
+	 * 		 textAlign String | 内容对齐方式 left center right
+	 * 		 titleTextAlign String | 表头对齐方式 left center right
+	 *
+	 * event: onSort | 排序事件 返回{key: 被排序列的字段名, type: 正序'asc'/倒序'desc'}
+	 *		  onSelect | 选中时触发 返回选择的行的下标
+	 * 		  onClick | 单元格点击事件 返回点击单元格所属行的数据
+	 *
+	 * function: resetSort | 调用后重置排序 *注意:不会触发sort事件
+	 *
+	 * */
+	import Vue from 'vue'
+	// import tableRender from './table-render'
+
+	export default {
+		data() {
+			return {
+				version: '1.1.0',
+				nowSortKey: '',
+				sortType: 'desc', // asc/desc 升序/降序
+				longTable: true,
+				lineHeight: uni.upx2px(64),
+				tableLoaded: false,
+				tableShow: true,
+				selectAll: false,
+				selectArr: []
+			}
+		},
+		// mixin: [tableRender],
+		computed: {
+			compluteHeight() {
+				return this.tableHeight ?
+					'height: ' + uni.upx2px(this.tableHeight) + 'px' :
+					''
+			}
+		},
+		props: {
+			tableData: {
+				type: [Array, Boolean],
+				default () {
+					return false
+				}
+			},
+			columns: {
+				/*
+				 *
+				 * [{title: xxx, key: 当前列展示对象名, width: 列宽, render: function}]
+				 *
+				 * */
+				type: [Array, Boolean],
+				required: true
+			},
+			stickSide: {
+				type: Boolean,
+				default: false
+			},
+			showBottomSum: {
+				type: Boolean,
+				default: false
+			},
+			showLoading: {
+				type: Boolean,
+				default: true
+			},
+			emptyText: {
+				type: String,
+				default: '暂无数据'
+			},
+			tableHeight: {
+				type: [Number, Boolean],
+				default: 0
+			},
+			showSelect: {
+				type: Boolean,
+				default: false
+			},
+			singleSelect: {
+				type: Boolean,
+				default: false
+			},
+			textAlign: {
+				type: String,
+				default: 'left' // right|center|left
+			},
+			titleTextAlign: {
+				type: String,
+				default: 'left' // right|center|left
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		// components: {
+		// 	renderComponents: {
+		// 		functional: true,
+		// 		props: {
+		// 			row: {
+		// 				type: Object,
+		// 				required: true
+		// 			},
+		// 			col: {
+		// 				type: Object,
+		// 				required: true
+		// 			}
+		// 		},
+		// 		render: function(h, ctx) {
+		// 			return _this[ctx.props.col.render](h, ctx.props)
+		// 		}
+		// 	}
+		// },
+		watch: {
+			columns() {
+				this.init()
+			},
+			tableData() {
+				this.init()
+			}
+		},
+		methods: {
+			async init() {
+				// 重置选择内容
+				this.selectAll = false
+				this.selectArr = []
+				this.tableLoaded = false
+				this.tableShow = true
+				let _this = this
+				let container = await _this.getPageSize('.z-table-container'),
+					pack = await _this.getPageSize('.z-table-pack')
+				_this.timer && clearTimeout(_this.timer)
+				if (container && pack) {
+					_this.$nextTick(function() {
+						if (_this.tableData && _this.tableData.length) {
+							_this.tableShow = false
+							_this.timer = setTimeout(function() {
+								_this.tableLoaded = true
+							}, 300)
+						}
+					})
+					if (container.height != pack.height) {
+						_this.longTable = true
+					} else {
+						_this.longTable = false
+					}
+				} else {
+					_this.tableLoaded = false
+					_this.$nextTick(function() {
+						_this.tableShow = true
+					})
+				}
+			},
+			getPageSize(selecter) {
+				// 获取元素信息
+				let query = uni.createSelectorQuery().in(this),
+					_this = this
+				return new Promise((resolve, reject) => {
+					query
+						.select(selecter)
+						.boundingClientRect(res => {
+							resolve(res)
+						})
+						.exec()
+				})
+			},
+			dosum(key) {
+				let sum = '-'
+				if (this.tableData) {
+					if (
+						this.tableData.every(item => {
+							return !Number.isNaN(item[key] - 0)
+						})
+					) {
+						sum = 0
+						this.tableData.map((item, index) => {
+							if (!key && index != 0) {
+								sum = '-'
+							} else {
+								let val = item[key] - 0
+								if (Number.isNaN(val)) {
+									sum += 0
+								} else {
+									sum += val
+								}
+							}
+						})
+					}
+				}
+				// sum = sum == 0 ? "-" : sum
+				return this.numTransform(sum)
+			},
+			getRowContent(row, col) {
+				// 表格值处理函数
+				// 如果columns带了key则显示对应的key
+				// 如果columns带的format则按规定返回format后的html
+				// format规定: params names <Array> 对应tableData的键名,作为匹配template中两个#之间动态内容的名字
+				//			   params template <String> html字符串模版
+				let tempHTML = ''
+				let rowKey = row[col.key]
+				if ([null, ''].includes(rowKey)) {
+					rowKey = '-'
+				}
+				if (rowKey || rowKey === 0) {
+					tempHTML = isNaN(rowKey - 0) ?
+						rowKey :
+						this.numTransform(rowKey - 0)
+					// tempHTML = tempHTML == 0 ? "-" : tempHTML
+				} else if (!!col.format) {
+					let tempFormat = col.format.template
+					col.format.names.map(item => {
+						let regexp = new RegExp(`\#${item}\#`, 'mg')
+						tempFormat = tempFormat.replace(regexp, row[item])
+					})
+					tempHTML = tempFormat
+				} else if (!col.render) {
+					let error = new Error('数据的key或format值至少一个不为空')
+					throw error
+				}
+				// console.log(tempHTML)
+				return tempHTML.toString()
+			},
+			sort(key, index) {
+				if (!key || !this.columns[index].sort) {
+					return
+				}
+				// 排序功能: 如果点击的排序按钮是原先的 那么更改排序类型
+				//			如果点击的另一个排序按钮 那么选择当前排序并且排序类型改为降序(desc)
+				if (key != this.nowSortKey) {
+					this.nowSortKey = key
+					this.sortType = 'desc'
+				} else {
+					this.toggleSort()
+				}
+				this.$emit('onSort', {
+					key: this.nowSortKey,
+					type: this.sortType
+				})
+			},
+			toggleSort() {
+				this.sortType = this.sortType == 'asc' ? 'desc' : 'asc'
+			},
+			numTransform(n) {
+				if (Number.isNaN(n - 0)) {
+					return n
+				}
+				if (Math.abs(n) >= 100000000) {
+					n = Number((n / 100000000).toFixed(1)) + '亿'
+				} else if (Math.abs(n) >= 10000) {
+					n = Number((n / 10000).toFixed(1)) + '万'
+				}
+				return n.toString()
+			},
+			resetSort() {
+				// 重置排序状态
+				this.nowSortKey = ''
+				this.sortType = 'desc'
+			},
+			setUrl(row, col) {
+				if (!col.isLink) {
+					return
+				}
+				let urlParam = {}
+				let {
+					isLink: {
+						url,
+						params = []
+					}
+				} = col
+				params.forEach(item => {
+					if (~item.indexOf('|')) {
+						let temp = item.split('|')
+						urlParam[temp[0]] = row[temp[1]]
+					} else {
+						urlParam[item] = row[item]
+					}
+				})
+				url = this.setUrlParams(url, urlParam)
+				return url
+			},
+			setUrlParams(url, params) {
+				let tempUrl = url,
+					keyArr = Object.keys(params)
+				keyArr.forEach(item => {
+					tempUrl += `&${item}=${params[item]}`
+				})
+				tempUrl = tempUrl.replace(/\&/, '?')
+				return tempUrl
+			},
+			itemClick(row, col) {
+				if (col.listenerClick) {
+					this.$emit('onClick', row)
+				}
+			},
+			doSelect(isAll = false, index) {
+				let temp = new Set()
+				if (isAll) {
+					// 全选
+					if (!this.selectAll) {
+						for (let i = 0; i < this.tableData.length; i++) {
+							temp.add(i)
+						}
+					}
+				} else {
+					// if (!this.singleSelect) {
+					// 	this.selectArr.forEach(item => {
+					// 		temp.add(item)
+					// 	})
+					// }
+					this.selectArr.forEach(item => {
+						temp.add(item)
+					})
+					if (temp.has(index)) {
+						temp.delete(index)
+					} else {
+						if (this.singleSelect) {
+							temp.clear()
+						}
+						temp.add(index)
+					}
+				}
+				this.selectArr = Array.from(temp)
+				// console.log(this.selectArr)
+				if (this.selectArr.length == this.tableData.length) {
+					this.selectAll = true
+				} else {
+					this.selectAll = false
+				}
+				
+				this.$emit('onSelect', this.selectArr)
+			},
+			// 1.1.1
+			getTitleText(title) {
+				// 自定义表头
+				let tempHTML = title
+				return tempHTML.toString()
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navigator-hover {
+		background: transparent;
+		opacity: 1;
+	}
+
+	@mixin ellipsis($num: 1) {
+		overflow: hidden;
+		text-overflow: ellipsis;
+
+		@if $num==1 {
+			white-space: nowrap;
+		}
+
+		@else {
+			display: -webkit-box;
+			-webkit-line-clamp: $num;
+			/* autoprefixer: off */
+			-webkit-box-orient: vertical;
+			/* autoprefixer: on */
+		}
+	}
+
+	// 三角形
+	%triangle-basic {
+		content: '';
+		height: 0;
+		width: 0;
+		overflow: hidden;
+	}
+
+	@mixin triangle($direction, $size, $borderColor) {
+		@extend %triangle-basic;
+
+		@if $direction==top {
+			border-bottom: $size solid $borderColor;
+			border-left: $size dashed transparent;
+			border-right: $size dashed transparent;
+			border-top: 0;
+		}
+
+		@else if $direction==right {
+			border-left: $size solid $borderColor;
+			border-top: $size dashed transparent;
+			border-bottom: $size dashed transparent;
+			border-right: 0;
+		}
+
+		@else if $direction==bottom {
+			border-top: $size solid $borderColor;
+			border-left: $size dashed transparent;
+			border-right: $size dashed transparent;
+			border-bottom: 0;
+		}
+
+		@else if $direction==left {
+			border-right: $size solid $borderColor;
+			border-top: $size dashed transparent;
+			border-bottom: $size dashed transparent;
+			border-left: 0;
+		}
+	}
+
+	a {
+		text-decoration: none;
+	}
+
+	.z-table {
+		position: relative;
+		display: inline-block;
+		height: 100%;
+		min-height: 130rpx;
+		width: 100%;
+		background: #fff;
+		border: solid 2rpx #ccc;
+		font-size: $uni-font-size-sm;
+		box-sizing: border-box;
+		transform: translateZ(0);
+
+		.z-table-main {
+			height: 100%;
+			box-sizing: border-box;
+		}
+
+		.z-table-container {
+			height: 100%;
+			overflow: scroll;
+			box-sizing: border-box;
+		}
+
+		.z-table-pack {
+			position: relative;
+			min-height: 100%;
+			width: fit-content;
+		}
+
+		.z-table-title {
+			position: sticky;
+			top: 0;
+			height: 64rpx;
+			z-index: 1;
+
+			.z-table-title-item {
+				border-bottom: solid 1rpx #dbdbdb;
+				background: #f8f8f8;
+			}
+
+			.z-table-stick-side {
+				position: sticky;
+				top: 0;
+				left: 0;
+				border-right: solid 1rpx #dbdbdb;
+				box-sizing: border-box;
+			}
+		}
+
+		.table-container-box.short-table {
+			padding-bottom: 48rpx;
+		}
+
+		.z-table-title,
+		.z-table-container-row {
+			display: flex;
+			width: fit-content;
+			white-space: nowrap;
+			box-sizing: border-box;
+
+			.z-table-title-item,
+			.z-table-container-col {
+				@include ellipsis();
+				display: inline-flex;
+				padding: 0 16rpx;
+				height: 64rpx;
+				align-items: center;
+				line-height: 64rpx;
+				box-sizing: border-box;
+			}
+		}
+
+		.z-table-container-row {
+			z-index: 0;
+			border-bottom: solid 1rpx #f4f4f4;
+			box-sizing: border-box;
+		}
+
+		.z-table-stick-side {
+			position: sticky;
+			left: 0;
+			background: #f7f9ff;
+			border-right: solid 1rpx #dbdbdb;
+			box-sizing: border-box;
+		}
+
+		.z-table-bottom {
+			position: absolute;
+			bottom: 0;
+			z-index: 9;
+			display: flex;
+			justify-items: center;
+			width: fit-content;
+			background: #4298f7 !important;
+			color: #fff !important;
+			white-space: nowrap;
+			box-sizing: border-box;
+
+			&.long-table {
+				position: sticky;
+			}
+
+			.z-table-stick-side {
+				background: #4298f7 !important;
+				box-sizing: border-box;
+			}
+
+			.z-table-bottom-col {
+				display: inline-flex;
+				align-items: center;
+				text-align: center;
+				padding: 16rpx;
+				box-sizing: border-box;
+			}
+
+			.z-table-bottom-text {
+				line-height: 100%;
+				box-sizing: border-box;
+			}
+
+			.z-table-bottom-text-title {
+				margin-bottom: 10rpx;
+				font-size: 22rpx;
+				color: #aad0ff;
+				box-sizing: border-box;
+			}
+
+			.sum {
+				margin-left: 14rpx;
+				font-size: 28rpx;
+				box-sizing: border-box;
+			}
+		}
+
+		.table-empty {
+			position: absolute;
+			top: 64rpx;
+			height: 64rpx;
+			line-height: 64rpx;
+			width: 100%;
+			text-align: center;
+		}
+
+		.sort {
+			display: flex;
+			padding: 5rpx;
+			flex-direction: column;
+			justify-content: center;
+
+			.up-arrow {
+				@include triangle(top, 10rpx, #ccc);
+				display: block;
+				margin-bottom: 5rpx;
+
+				&.action {
+					@include triangle(top, 10rpx, #4298f7);
+				}
+			}
+
+			.down-arrow {
+				@include triangle(bottom, 10rpx, #ccc);
+				display: block;
+
+				&.action {
+					@include triangle(bottom, 10rpx, #4298f7);
+				}
+			}
+		}
+
+		// 1.0.5
+		.z-loading {
+			position: absolute;
+			top: 0;
+			left: 0;
+			z-index: 2;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			height: 100%;
+			width: 100%;
+			background: #fff;
+			opacity: 0;
+			transition: all 0.3s;
+
+			&.ztableLoading {
+				opacity: 1;
+			}
+
+			.z-loading-animate {
+				position: relative;
+				display: inline-block;
+				width: 30rpx;
+				height: 30rpx;
+				margin-right: 20rpx;
+				border-radius: 100%;
+				border: solid 6rpx #ccc;
+				vertical-align: middle;
+				animation: rotate 1s ease-in-out infinite;
+
+				&::after {
+					content: '';
+					display: block;
+					position: absolute;
+					top: -10rpx;
+					z-index: 1;
+					background: #fff;
+					width: 20rpx;
+					height: 20rpx;
+					border-radius: 10rpx;
+				}
+			}
+
+			@keyframes rotate {
+				from {
+					transform: rotate(0deg);
+				}
+
+				to {
+					transform: rotate(360deg);
+				}
+			}
+		}
+
+		// 1.1.0
+		.select-box {
+			display: inline-block;
+			width: 26rpx;
+			height: 26rpx;
+			line-height: 14rpx;
+			margin-right: 15rpx;
+			border: solid 2rpx #4298f7;
+			border-radius: 4rpx;
+			background: #fff;
+			text-align: center;
+		}
+
+		.select-tip {
+			display: inline-block;
+			opacity: 0;
+			transform: rotate(90deg);
+			transition: all .3s;
+
+			&.selected {
+				position: relative;
+				top: 4rpx;
+				left: -4rpx;
+				height: 4rpx;
+				background: #4298f7;
+				width: 10rpx;
+				opacity: 1;
+				transform: rotate(45deg);
+
+				&:before,
+				&:after {
+					content: '';
+					position: absolute;
+					display: block;
+					height: 4rpx;
+					background: #4298f7;
+				}
+
+				&:before {
+					bottom: -2rpx;
+					left: -4rpx;
+					width: 8rpx;
+					transform: rotate(-90deg);
+				}
+
+				&:after {
+					bottom: 16rpx;
+					right: -16rpx;
+					width: 34rpx;
+					transform: rotate(-90deg);
+				}
+			}
+		}
+		
+		// 1.1.1
+		.z-table-col-text {
+			display: flex;
+			width: 100%;
+			flex: 1;
+			justify-content: flex-start;
+			align-content: center;
+			
+			&.text-center {
+				justify-content: center;
+			}
+			
+			&.text-right {
+				justify-content: flex-end;
+			}
+		}
+	}
+</style>

BIN
image/Thumbs.db


BIN
image/WechatIMG1.jpeg


BIN
image/WechatIMG10.jpeg


BIN
image/WechatIMG11.jpeg


BIN
image/WechatIMG12.jpeg


BIN
image/WechatIMG13.jpeg


BIN
image/WechatIMG14.jpeg


BIN
image/WechatIMG2.jpeg


BIN
image/WechatIMG3.jpeg


BIN
image/WechatIMG4.jpeg


BIN
image/WechatIMG5.jpeg


BIN
image/WechatIMG6.jpeg


BIN
image/WechatIMG7.jpeg


BIN
image/WechatIMG8.jpeg


BIN
image/WechatIMG9.jpeg


+ 213 - 0
main.js

@@ -0,0 +1,213 @@
+import Vue from 'vue'
+import store from './store'
+import App from './App'
+
+// 后端api地址
+Vue.prototype.$unishow = "https://81f.dev.ytxxjs.cn/addons/unishop";
+// Vue.prototype.$unishow = "http://www.bj.com/addons/unishop";
+
+// 为了方便每次上传的时候忘记修改上面的参数
+uni.getSystemInfo({
+	success(res) { 
+		//console.log(res)
+		if (res.platform != "devtools") {
+			//Vue.prototype.$unishow = "https://shop.weivee.com/addons/unishop";
+		}
+	}
+}); 
+
+
+
+// 平台号
+// #ifdef APP-PLUS
+Vue.prototype.$platform = 'APP-PLUS';
+// #endif
+// #ifdef H5
+Vue.prototype.$platform = 'H5';
+// #endif
+// #ifdef MP-WEIXIN
+Vue.prototype.$platform = 'MP-WEIXIN';
+// #endif
+// #ifdef MP-ALIPAY
+Vue.prototype.$platform = 'MP-ALIPAY';
+// #endif
+// #ifdef MP-BAIDU
+Vue.prototype.$platform = 'MP-BAIDU';
+// #endif
+// #ifdef MP-TOUTIAO
+Vue.prototype.$platform = 'MP-TOUTIAO';
+// #endif
+
+
+// 提示
+const msg = (title, duration = 3000, mask = false, icon = 'none') => {
+	//统一提示方便全局修改
+	if (Boolean(title) === false) {
+		return;
+	}
+	uni.showToast({
+		title,
+		duration,
+		mask,
+		icon
+	});
+	setTimeout(function() {
+		uni.hideToast();
+	}, duration)
+}
+
+// 返回上一页
+const prePage = () => {
+	let pages = getCurrentPages();
+	let prePage = pages[pages.length - 2];
+	// #ifdef H5
+	return prePage;
+	// #endif
+	return prePage.$vm;
+}
+
+// 检查有没有登录
+const checkLogin = async () => {
+	let user = uni.getStorageSync('userInfo');
+	if (user) {
+		Vue.prototype.$store._mutations.login[0](user);
+	} else {
+		let result = await request('/user/status');
+		if (!result) {
+			// 若没有登录则清空个人信息
+			Vue.prototype.$store._mutations.logout[0]();
+		}
+	}
+}
+
+// 深拷贝
+const deepCopy = (p, c) => {
+	var c = c || {};
+	for (var i in p) {
+		if (typeof p[i] === "object") {
+			c[i] = (p[i].constructor === Array) ? [] : {};
+			deepCopy(p[i], c[i])
+		} else {
+			c[i] = p[i]
+		}
+	}
+	return c;
+}
+
+// 同步网络请求
+const request = async (url, method = 'GET', data = {}, showMsg = true) => {
+	let header = {
+		'content-type': 'application/x-www-form-urlencoded',
+		'lang': Vue.prototype.$store.state.lang,
+		'platform': Vue.prototype.$platform
+	};
+	if (Vue.prototype.$store.state.userInfo.token) {
+		header.token = Vue.prototype.$store.state.userInfo.token;
+	}
+	if (Vue.prototype.$store.state.cookie) {
+		header.cookie = Vue.prototype.$store.state.cookie;
+	}
+	var [error, res] = await uni.request({
+		url: Vue.prototype.$unishow + url,
+		method: method,
+		header: header,
+		data: data,
+		timeout: 5000
+	});
+	if (url == '/pay/submit'){
+		console.log(res);
+	}
+	return new Promise(function(revolve){
+		if (error) {
+			showMsg && msg(JSON.stringify(res));
+			revolve(false);
+		}
+		
+		if (res) {
+			if (res.header.hasOwnProperty('Set-Cookie')) {
+				let cookie = res.header['Set-Cookie'].replace("; path=/", "");
+				Vue.prototype.$store.commit('setCookie', cookie);
+			}
+			if (res.hasOwnProperty('data')) {
+				if (res.data.hasOwnProperty('code') && res.data.code == 401) {
+					// 未登录 或 登录失效
+					Vue.prototype.$store.commit('logout');
+				}
+				if (res.data.hasOwnProperty('code') && res.data.code == 1) {
+					if (res.data.msg) {
+						showMsg && msg(res.data.msg);
+					} else {
+						uni.hideToast();
+					}
+					
+					revolve(res.data.data);
+				} else {
+					if (res.data.hasOwnProperty('msg')) {
+						showMsg && msg(res.data.msg);
+					} else {
+						showMsg && msg('返回参数错误');
+					}
+					revolve(false);
+				}
+			} else {
+				showMsg && msg('不能识别数据');
+				revolve(false);
+			}
+		}
+	});
+	
+}
+
+// 跳转判断是否登录
+const navTo = (url, check = true) => {
+	if (check && !Vue.prototype.$store.state.hasLogin) {
+		url = '/pages/public/login';
+	}
+	uni.navigateTo({
+		url: url
+	});
+}
+
+Vue.config.productionTip = false
+Vue.prototype.$fire = new Vue();
+Vue.prototype.$store = store;
+Vue.prototype.$api = {
+	msg,
+	prePage,
+	checkLogin,
+	request,
+	deepCopy,
+	navTo
+};
+
+// #ifdef MP-WEIXIN
+// 微信小程序
+const wechatMiniLogin = async (noMsg = false) => {
+	if (!noMsg) msg('登录中');
+	let [error, loginRes] = await uni.login({
+		provider: 'weixin'
+	});
+	if (loginRes.hasOwnProperty('code')) {
+		let data = await request('/user/authSession', 'GET', {
+			code: loginRes.code
+		});
+		if (data) {
+			if (data.hasOwnProperty('userInfo') && data.userInfo.token && data.userInfo.token != '') {
+				Vue.prototype.$store.commit('login', data.userInfo);
+			}
+		}
+		return data.userInfo;
+	} else {
+		msg('登录失败');
+		return false;
+	}
+};
+Vue.prototype.$wechatMiniLogin = wechatMiniLogin;
+// #endif
+
+App.mpType = 'app'
+
+const app = new Vue({
+	...App
+})
+app.$mount()

+ 77 - 0
manifest.json

@@ -0,0 +1,77 @@
+{
+    "name" : "八十一坊商城",
+    "appid" : "__UNI__3E17984",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    "app-plus" : {
+        /* 5+App特有相关 */
+        "usingComponents" : true,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "modules" : {},
+        /* 模块配置 */
+        "distribute" : {
+            /* 应用发布信息 */
+            "android" : {
+                /* android打包配置 */
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            "ios" : {},
+            /* ios打包配置 */
+            "sdkConfigs" : {
+                "payment" : {}
+            }
+        },
+        "nativePlugins" : {}
+    },
+    /* SDK配置 */
+    "quickapp" : {},
+    /* 快应用特有相关 */
+    "mp-weixin" : {
+        /* 小程序特有相关 */
+        "usingComponents" : true,
+        "appid" : "wx21e1dd837509ee70",
+        "setting" : {
+            "urlCheck" : false,
+            "minified" : true
+        },
+        "permission" : {}
+    },
+    "h5" : {
+        "title" : "喂喂商城",
+        "domain" : "shop.weivee.com",
+        "router" : {
+            "base" : "/h5/"
+        },
+        "template" : "template.h5.html",
+        "devServer" : {
+            "disableHostCheck" : true,
+            "https" : false
+        }
+    }
+}

+ 159 - 0
node_modules/deepmerge/changelog.md

@@ -0,0 +1,159 @@
+# [4.2.2](https://github.com/TehShrike/deepmerge/releases/tag/v4.2.2)
+
+- `isMergeableObject` is now only called if there are two values that could be merged.  [a34dd4d2](https://github.com/TehShrike/deepmerge/commit/a34dd4d25bf5e250653540a2022bc832c7b00a19)
+
+# [4.2.1](https://github.com/TehShrike/deepmerge/releases/tag/v4.2.1)
+
+- Fix: falsey values can now be merged.  [#170](https://github.com/TehShrike/deepmerge/issues/170)
+
+# [4.2.0](https://github.com/TehShrike/deepmerge/releases/tag/v4.2.0)
+
+- Properties are now only overwritten if they exist on the target object and are enumerable.  [#164](https://github.com/TehShrike/deepmerge/pull/164)
+
+Technically this could probably be a patch release since "which properties get overwritten" wasn't documented and accidentally overwriting a built-in function or some function up the property chain would almost certainly be undesirable, but it feels like a gray area, so here we are with a feature version bump.
+
+# [4.1.2](https://github.com/TehShrike/deepmerge/releases/tag/v4.1.2)
+
+- Rolled back #167 since `Object.assign` breaks ES5 support.  [55067352](https://github.com/TehShrike/deepmerge/commit/55067352a92c65a6c44a5165f3387720aae1e192)
+
+# [4.1.1](https://github.com/TehShrike/deepmerge/releases/tag/v4.1.1)
+
+- The `options` argument is no longer mutated [#167](https://github.com/TehShrike/deepmerge/pull/167)
+
+# [4.1.0](https://github.com/TehShrike/deepmerge/releases/tag/v4.1.0)
+
+- `cloneUnlessOtherwiseSpecified` is now exposed to the `arrayMerge` function [#165](https://github.com/TehShrike/deepmerge/pull/165)
+
+# [4.0.0](https://github.com/TehShrike/deepmerge/releases/tag/v4.0.0)
+
+- The `main` entry point in `package.json` is now a CommonJS module instead of a UMD module [#155](https://github.com/TehShrike/deepmerge/pull/155)
+
+# [3.3.0](https://github.com/TehShrike/deepmerge/releases/tag/v3.3.0)
+
+- Enumerable Symbol properties are now copied [#151](https://github.com/TehShrike/deepmerge/pull/151)
+
+# [3.2.1](https://github.com/TehShrike/deepmerge/releases/tag/v3.2.1)
+
+- bumping dev dependency versions to try to shut up bogus security warnings from Github/npm [#149](https://github.com/TehShrike/deepmerge/pull/149)
+
+# [3.2.0](https://github.com/TehShrike/deepmerge/releases/tag/v3.2.0)
+
+- feature: added the [`customMerge`](https://github.com/TehShrike/deepmerge#custommerge) option [#133](https://github.com/TehShrike/deepmerge/pull/133)
+
+# [3.1.0](https://github.com/TehShrike/deepmerge/releases/tag/v3.1.0)
+
+- typescript typing: make the `all` function generic [#129](https://github.com/TehShrike/deepmerge/pull/129)
+
+# [3.0.0](https://github.com/TehShrike/deepmerge/releases/tag/v3.0.0)
+
+- drop ES module build [#123](https://github.com/TehShrike/deepmerge/issues/123)
+
+# [2.2.1](https://github.com/TehShrike/deepmerge/releases/tag/v2.2.1)
+
+- bug: typescript export type was wrong [#121](https://github.com/TehShrike/deepmerge/pull/121)
+
+# [2.2.0](https://github.com/TehShrike/deepmerge/releases/tag/v2.2.0)
+
+- feature: added TypeScript typings [#119](https://github.com/TehShrike/deepmerge/pull/119)
+
+# [2.1.1](https://github.com/TehShrike/deepmerge/releases/tag/v2.1.1)
+
+- documentation: Rename "methods" to "api", note ESM syntax [#103](https://github.com/TehShrike/deepmerge/pull/103)
+- documentation: Fix grammar [#107](https://github.com/TehShrike/deepmerge/pull/107)
+- documentation: Restructure headers for clarity + some wording tweaks [108](https://github.com/TehShrike/deepmerge/pull/108) + [109](https://github.com/TehShrike/deepmerge/pull/109)
+
+
+# [2.1.0](https://github.com/TehShrike/deepmerge/releases/tag/v2.1.0)
+
+- feature: Support a custom `isMergeableObject` function [#96](https://github.com/TehShrike/deepmerge/pull/96)
+- documentation: note a Webpack bug that some users might need to work around [#100](https://github.com/TehShrike/deepmerge/pull/100)
+
+# [2.0.1](https://github.com/TehShrike/deepmerge/releases/tag/v2.0.1)
+
+- documentation: fix the old array merge algorithm in the readme.  [#84](https://github.com/TehShrike/deepmerge/pull/84)
+
+# [2.0.0](https://github.com/TehShrike/deepmerge/releases/tag/v2.0.0)
+
+- breaking: the array merge algorithm has changed from a complicated thing to `target.concat(source).map(element => cloneUnlessOtherwiseSpecified(element, optionsArgument))`
+- breaking: The `clone` option now defaults to `true`
+- feature: `merge.all` now accepts an array of any size, even 0 or 1 elements
+
+See [pull request 77](https://github.com/TehShrike/deepmerge/pull/77).
+
+# [1.5.2](https://github.com/TehShrike/deepmerge/releases/tag/v1.5.2)
+
+- fix: no longer attempts to merge React elements [#76](https://github.com/TehShrike/deepmerge/issues/76)
+
+# [1.5.1](https://github.com/TehShrike/deepmerge/releases/tag/v1.5.1)
+
+- bower support: officially dropping bower support.  If you use bower, please depend on the [unpkg distribution](https://unpkg.com/deepmerge/dist/umd.js).  See [#63](https://github.com/TehShrike/deepmerge/issues/63)
+
+# [1.5.0](https://github.com/TehShrike/deepmerge/releases/tag/v1.5.0)
+
+- bug fix: merging objects into arrays was allowed, and doesn't make any sense. [#65](https://github.com/TehShrike/deepmerge/issues/65) published as a feature release instead of a patch because it is a decent behavior change.
+
+# [1.4.4](https://github.com/TehShrike/deepmerge/releases/tag/v1.4.4)
+
+- bower support: updated `main` in bower.json
+
+# [1.4.3](https://github.com/TehShrike/deepmerge/releases/tag/v1.4.3)
+
+- bower support: inline is-mergeable-object in a new CommonJS build, so that people using both bower and CommonJS can bundle the library [0b34e6](https://github.com/TehShrike/deepmerge/commit/0b34e6e95f989f2fc8091d25f0d291c08f3d2d24)
+
+# [1.4.2](https://github.com/TehShrike/deepmerge/releases/tag/v1.4.2)
+
+- performance: bump is-mergeable-object dependency version for a slight performance improvement [5906c7](https://github.com/TehShrike/deepmerge/commit/5906c765d691d48e83d76efbb0d4b9ca150dc12c)
+
+# [1.4.1](https://github.com/TehShrike/deepmerge/releases/tag/v1.4.1)
+
+- documentation: fix unpkg link [acc45b](https://github.com/TehShrike/deepmerge/commit/acc45be85519c1df906a72ecb24764b622d18d47)
+
+# [1.4.0](https://github.com/TehShrike/deepmerge/releases/tag/v1.4.0)
+
+- api: instead of only exporting a UMD module, expose a UMD module with `pkg.main`, a CJS module with `pkg.browser`, and an ES module with `pkg.module` [#62](https://github.com/TehShrike/deepmerge/pull/62)
+
+# [1.3.2](https://github.com/TehShrike/deepmerge/releases/tag/v1.3.2)
+
+- documentation: note the minified/gzipped file sizes [56](https://github.com/TehShrike/deepmerge/pull/56)
+- documentation: make data structures more readable in merge example: pull request [57](https://github.com/TehShrike/deepmerge/pull/57)
+
+# [1.3.1](https://github.com/TehShrike/deepmerge/releases/tag/v1.3.1)
+
+- documentation: clarify and test some array merging documentation: pull request [51](https://github.com/TehShrike/deepmerge/pull/51)
+
+# [1.3.0](https://github.com/TehShrike/deepmerge/releases/tag/v1.3.0)
+
+- feature: `merge.all`, a merge function that merges any number of objects: pull request [50](https://github.com/TehShrike/deepmerge/pull/50)
+
+# [1.2.0](https://github.com/TehShrike/deepmerge/releases/tag/v1.2.0)
+
+- fix: an error that would be thrown when an array would be merged onto a truthy non-array value: pull request [46](https://github.com/TehShrike/deepmerge/pull/46)
+- feature: the ability to clone: Issue [28](https://github.com/TehShrike/deepmerge/issues/28), pull requests [44](https://github.com/TehShrike/deepmerge/pull/44) and [48](https://github.com/TehShrike/deepmerge/pull/48)
+- maintenance: added tests + travis to `.npmignore`: pull request [47](https://github.com/TehShrike/deepmerge/pull/47)
+
+# [1.1.1](https://github.com/TehShrike/deepmerge/releases/tag/v1.1.1)
+
+- fix an issue where an error was thrown when merging an array onto a non-array: [Pull request 46](https://github.com/TehShrike/deepmerge/pull/46)
+
+# [1.1.0](https://github.com/TehShrike/deepmerge/releases/tag/v1.1.0)
+
+- allow consumers to specify their own array merging algorithm: [Pull request 37](https://github.com/TehShrike/deepmerge/pull/37)
+
+# [1.0.3](https://github.com/TehShrike/deepmerge/releases/tag/v1.0.3)
+
+- adding bower.json back: [Issue 38](https://github.com/TehShrike/deepmerge/pull/38)
+- updating keywords and Github links in package.json [bc3898e](https://github.com/TehShrike/deepmerge/commit/bc3898e587a56f74591328f40f656b0152c1d5eb)
+
+# [1.0.2](https://github.com/TehShrike/deepmerge/releases/tag/v1.0.2)
+
+- Updating the readme: dropping bower, testing that the example works: [7102fc](https://github.com/TehShrike/deepmerge/commit/7102fcc4ddec11e2d33205866f9f18df14e5aeb5)
+
+# [1.0.1](https://github.com/TehShrike/deepmerge/releases/tag/v1.0.1)
+
+- `null`, dates, and regular expressions are now properly merged in arrays: [Issue 18](https://github.com/TehShrike/deepmerge/pull/18), plus commit: [ef1c6b](https://github.com/TehShrike/deepmerge/commit/ef1c6bac8350ba12a24966f0bc7da02560827586)
+
+# 1.0.0
+
+- Should only be a patch change, because this module is READY. [Issue 15](https://github.com/TehShrike/deepmerge/issues/15)
+- Regular expressions are now treated like primitive values when merging: [Issue 30](https://github.com/TehShrike/deepmerge/pull/30)
+- Dates are now treated like primitives when merging: [Issue 31](https://github.com/TehShrike/deepmerge/issues/31)

+ 133 - 0
node_modules/deepmerge/dist/cjs.js

@@ -0,0 +1,133 @@
+'use strict';
+
+var isMergeableObject = function isMergeableObject(value) {
+	return isNonNullObject(value)
+		&& !isSpecial(value)
+};
+
+function isNonNullObject(value) {
+	return !!value && typeof value === 'object'
+}
+
+function isSpecial(value) {
+	var stringValue = Object.prototype.toString.call(value);
+
+	return stringValue === '[object RegExp]'
+		|| stringValue === '[object Date]'
+		|| isReactElement(value)
+}
+
+// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
+var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
+var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
+
+function isReactElement(value) {
+	return value.$$typeof === REACT_ELEMENT_TYPE
+}
+
+function emptyTarget(val) {
+	return Array.isArray(val) ? [] : {}
+}
+
+function cloneUnlessOtherwiseSpecified(value, options) {
+	return (options.clone !== false && options.isMergeableObject(value))
+		? deepmerge(emptyTarget(value), value, options)
+		: value
+}
+
+function defaultArrayMerge(target, source, options) {
+	return target.concat(source).map(function(element) {
+		return cloneUnlessOtherwiseSpecified(element, options)
+	})
+}
+
+function getMergeFunction(key, options) {
+	if (!options.customMerge) {
+		return deepmerge
+	}
+	var customMerge = options.customMerge(key);
+	return typeof customMerge === 'function' ? customMerge : deepmerge
+}
+
+function getEnumerableOwnPropertySymbols(target) {
+	return Object.getOwnPropertySymbols
+		? Object.getOwnPropertySymbols(target).filter(function(symbol) {
+			return target.propertyIsEnumerable(symbol)
+		})
+		: []
+}
+
+function getKeys(target) {
+	return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
+}
+
+function propertyIsOnObject(object, property) {
+	try {
+		return property in object
+	} catch(_) {
+		return false
+	}
+}
+
+// Protects from prototype poisoning and unexpected merging up the prototype chain.
+function propertyIsUnsafe(target, key) {
+	return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
+		&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
+			&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
+}
+
+function mergeObject(target, source, options) {
+	var destination = {};
+	if (options.isMergeableObject(target)) {
+		getKeys(target).forEach(function(key) {
+			destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
+		});
+	}
+	getKeys(source).forEach(function(key) {
+		if (propertyIsUnsafe(target, key)) {
+			return
+		}
+
+		if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
+			destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
+		} else {
+			destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
+		}
+	});
+	return destination
+}
+
+function deepmerge(target, source, options) {
+	options = options || {};
+	options.arrayMerge = options.arrayMerge || defaultArrayMerge;
+	options.isMergeableObject = options.isMergeableObject || isMergeableObject;
+	// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
+	// implementations can use it. The caller may not replace it.
+	options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
+
+	var sourceIsArray = Array.isArray(source);
+	var targetIsArray = Array.isArray(target);
+	var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
+
+	if (!sourceAndTargetTypesMatch) {
+		return cloneUnlessOtherwiseSpecified(source, options)
+	} else if (sourceIsArray) {
+		return options.arrayMerge(target, source, options)
+	} else {
+		return mergeObject(target, source, options)
+	}
+}
+
+deepmerge.all = function deepmergeAll(array, options) {
+	if (!Array.isArray(array)) {
+		throw new Error('first argument should be an array')
+	}
+
+	return array.reduce(function(prev, next) {
+		return deepmerge(prev, next, options)
+	}, {})
+};
+
+var deepmerge_1 = deepmerge;
+
+module.exports = deepmerge_1;

+ 139 - 0
node_modules/deepmerge/dist/umd.js

@@ -0,0 +1,139 @@
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+	typeof define === 'function' && define.amd ? define(factory) :
+	(global = global || self, global.deepmerge = factory());
+}(this, function () { 'use strict';
+
+	var isMergeableObject = function isMergeableObject(value) {
+		return isNonNullObject(value)
+			&& !isSpecial(value)
+	};
+
+	function isNonNullObject(value) {
+		return !!value && typeof value === 'object'
+	}
+
+	function isSpecial(value) {
+		var stringValue = Object.prototype.toString.call(value);
+
+		return stringValue === '[object RegExp]'
+			|| stringValue === '[object Date]'
+			|| isReactElement(value)
+	}
+
+	// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
+	var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
+	var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
+
+	function isReactElement(value) {
+		return value.$$typeof === REACT_ELEMENT_TYPE
+	}
+
+	function emptyTarget(val) {
+		return Array.isArray(val) ? [] : {}
+	}
+
+	function cloneUnlessOtherwiseSpecified(value, options) {
+		return (options.clone !== false && options.isMergeableObject(value))
+			? deepmerge(emptyTarget(value), value, options)
+			: value
+	}
+
+	function defaultArrayMerge(target, source, options) {
+		return target.concat(source).map(function(element) {
+			return cloneUnlessOtherwiseSpecified(element, options)
+		})
+	}
+
+	function getMergeFunction(key, options) {
+		if (!options.customMerge) {
+			return deepmerge
+		}
+		var customMerge = options.customMerge(key);
+		return typeof customMerge === 'function' ? customMerge : deepmerge
+	}
+
+	function getEnumerableOwnPropertySymbols(target) {
+		return Object.getOwnPropertySymbols
+			? Object.getOwnPropertySymbols(target).filter(function(symbol) {
+				return target.propertyIsEnumerable(symbol)
+			})
+			: []
+	}
+
+	function getKeys(target) {
+		return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
+	}
+
+	function propertyIsOnObject(object, property) {
+		try {
+			return property in object
+		} catch(_) {
+			return false
+		}
+	}
+
+	// Protects from prototype poisoning and unexpected merging up the prototype chain.
+	function propertyIsUnsafe(target, key) {
+		return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
+			&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
+				&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
+	}
+
+	function mergeObject(target, source, options) {
+		var destination = {};
+		if (options.isMergeableObject(target)) {
+			getKeys(target).forEach(function(key) {
+				destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
+			});
+		}
+		getKeys(source).forEach(function(key) {
+			if (propertyIsUnsafe(target, key)) {
+				return
+			}
+
+			if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
+				destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
+			} else {
+				destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
+			}
+		});
+		return destination
+	}
+
+	function deepmerge(target, source, options) {
+		options = options || {};
+		options.arrayMerge = options.arrayMerge || defaultArrayMerge;
+		options.isMergeableObject = options.isMergeableObject || isMergeableObject;
+		// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
+		// implementations can use it. The caller may not replace it.
+		options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
+
+		var sourceIsArray = Array.isArray(source);
+		var targetIsArray = Array.isArray(target);
+		var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
+
+		if (!sourceAndTargetTypesMatch) {
+			return cloneUnlessOtherwiseSpecified(source, options)
+		} else if (sourceIsArray) {
+			return options.arrayMerge(target, source, options)
+		} else {
+			return mergeObject(target, source, options)
+		}
+	}
+
+	deepmerge.all = function deepmergeAll(array, options) {
+		if (!Array.isArray(array)) {
+			throw new Error('first argument should be an array')
+		}
+
+		return array.reduce(function(prev, next) {
+			return deepmerge(prev, next, options)
+		}, {})
+	};
+
+	var deepmerge_1 = deepmerge;
+
+	return deepmerge_1;
+
+}));

+ 16 - 0
node_modules/deepmerge/index.d.ts

@@ -0,0 +1,16 @@
+declare function deepmerge<T>(x: Partial<T>, y: Partial<T>, options?: deepmerge.Options): T;
+declare function deepmerge<T1, T2>(x: Partial<T1>, y: Partial<T2>, options?: deepmerge.Options): T1 & T2;
+
+declare namespace deepmerge {
+	export interface Options {
+		arrayMerge?(target: any[], source: any[], options?: Options): any[];
+		clone?: boolean;
+		customMerge?: (key: string, options?: Options) => ((x: any, y: any) => any) | undefined;
+		isMergeableObject?(value: object): boolean;
+	}
+
+	export function all (objects: object[], options?: Options): object;
+	export function all<T> (objects: Partial<T>[], options?: Options): T;
+}
+
+export = deepmerge;

+ 106 - 0
node_modules/deepmerge/index.js

@@ -0,0 +1,106 @@
+var defaultIsMergeableObject = require('is-mergeable-object')
+
+function emptyTarget(val) {
+	return Array.isArray(val) ? [] : {}
+}
+
+function cloneUnlessOtherwiseSpecified(value, options) {
+	return (options.clone !== false && options.isMergeableObject(value))
+		? deepmerge(emptyTarget(value), value, options)
+		: value
+}
+
+function defaultArrayMerge(target, source, options) {
+	return target.concat(source).map(function(element) {
+		return cloneUnlessOtherwiseSpecified(element, options)
+	})
+}
+
+function getMergeFunction(key, options) {
+	if (!options.customMerge) {
+		return deepmerge
+	}
+	var customMerge = options.customMerge(key)
+	return typeof customMerge === 'function' ? customMerge : deepmerge
+}
+
+function getEnumerableOwnPropertySymbols(target) {
+	return Object.getOwnPropertySymbols
+		? Object.getOwnPropertySymbols(target).filter(function(symbol) {
+			return target.propertyIsEnumerable(symbol)
+		})
+		: []
+}
+
+function getKeys(target) {
+	return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
+}
+
+function propertyIsOnObject(object, property) {
+	try {
+		return property in object
+	} catch(_) {
+		return false
+	}
+}
+
+// Protects from prototype poisoning and unexpected merging up the prototype chain.
+function propertyIsUnsafe(target, key) {
+	return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
+		&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
+			&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
+}
+
+function mergeObject(target, source, options) {
+	var destination = {}
+	if (options.isMergeableObject(target)) {
+		getKeys(target).forEach(function(key) {
+			destination[key] = cloneUnlessOtherwiseSpecified(target[key], options)
+		})
+	}
+	getKeys(source).forEach(function(key) {
+		if (propertyIsUnsafe(target, key)) {
+			return
+		}
+
+		if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
+			destination[key] = getMergeFunction(key, options)(target[key], source[key], options)
+		} else {
+			destination[key] = cloneUnlessOtherwiseSpecified(source[key], options)
+		}
+	})
+	return destination
+}
+
+function deepmerge(target, source, options) {
+	options = options || {}
+	options.arrayMerge = options.arrayMerge || defaultArrayMerge
+	options.isMergeableObject = options.isMergeableObject || defaultIsMergeableObject
+	// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
+	// implementations can use it. The caller may not replace it.
+	options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified
+
+	var sourceIsArray = Array.isArray(source)
+	var targetIsArray = Array.isArray(target)
+	var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray
+
+	if (!sourceAndTargetTypesMatch) {
+		return cloneUnlessOtherwiseSpecified(source, options)
+	} else if (sourceIsArray) {
+		return options.arrayMerge(target, source, options)
+	} else {
+		return mergeObject(target, source, options)
+	}
+}
+
+deepmerge.all = function deepmergeAll(array, options) {
+	if (!Array.isArray(array)) {
+		throw new Error('first argument should be an array')
+	}
+
+	return array.reduce(function(prev, next) {
+		return deepmerge(prev, next, options)
+	}, {})
+}
+
+module.exports = deepmerge

+ 21 - 0
node_modules/deepmerge/license.txt

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2012 James Halliday, Josh Duff, and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 71 - 0
node_modules/deepmerge/package.json

@@ -0,0 +1,71 @@
+{
+  "_from": "deepmerge@^4.2.2",
+  "_id": "deepmerge@4.2.2",
+  "_inBundle": false,
+  "_integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+  "_location": "/deepmerge",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "deepmerge@^4.2.2",
+    "name": "deepmerge",
+    "escapedName": "deepmerge",
+    "rawSpec": "^4.2.2",
+    "saveSpec": null,
+    "fetchSpec": "^4.2.2"
+  },
+  "_requiredBy": [
+    "/vuex-persistedstate"
+  ],
+  "_resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+  "_shasum": "44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955",
+  "_spec": "deepmerge@^4.2.2",
+  "_where": "/Users/zhengmingwei/Desktop/Project/uni-app/uni-shop/node_modules/vuex-persistedstate",
+  "bugs": {
+    "url": "https://github.com/TehShrike/deepmerge/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {},
+  "deprecated": false,
+  "description": "A library for deep (recursive) merging of Javascript objects",
+  "devDependencies": {
+    "@types/node": "^8.10.54",
+    "is-mergeable-object": "1.1.0",
+    "is-plain-object": "^2.0.4",
+    "jsmd": "^1.0.2",
+    "rollup": "^1.23.1",
+    "rollup-plugin-commonjs": "^10.1.0",
+    "rollup-plugin-node-resolve": "^5.2.0",
+    "tape": "^4.11.0",
+    "ts-node": "7.0.1",
+    "typescript": "=2.2.2",
+    "uglify-js": "^3.6.1"
+  },
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "homepage": "https://github.com/TehShrike/deepmerge",
+  "keywords": [
+    "merge",
+    "deep",
+    "extend",
+    "copy",
+    "clone",
+    "recursive"
+  ],
+  "license": "MIT",
+  "main": "dist/cjs.js",
+  "name": "deepmerge",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/TehShrike/deepmerge.git"
+  },
+  "scripts": {
+    "build": "rollup -c",
+    "size": "npm run build && uglifyjs --compress --mangle -- ./dist/umd.js | gzip -c | wc -c",
+    "test": "npm run build && tape test/*.js && jsmd readme.md && npm run test:typescript",
+    "test:typescript": "tsc --noEmit test/typescript.ts && ts-node test/typescript.ts"
+  },
+  "version": "4.2.2"
+}

+ 264 - 0
node_modules/deepmerge/readme.md

@@ -0,0 +1,264 @@
+# deepmerge
+
+Merges the enumerable properties of two or more objects deeply.
+
+> UMD bundle is 723B minified+gzipped
+
+## Getting Started
+
+### Example Usage
+<!--js
+const merge = require('./')
+-->
+
+```js
+const x = {
+	foo: { bar: 3 },
+	array: [{
+		does: 'work',
+		too: [ 1, 2, 3 ]
+	}]
+}
+
+const y = {
+	foo: { baz: 4 },
+	quux: 5,
+	array: [{
+		does: 'work',
+		too: [ 4, 5, 6 ]
+	}, {
+		really: 'yes'
+	}]
+}
+
+const output = {
+	foo: {
+		bar: 3,
+		baz: 4
+	},
+	array: [{
+		does: 'work',
+		too: [ 1, 2, 3 ]
+	}, {
+		does: 'work',
+		too: [ 4, 5, 6 ]
+	}, {
+		really: 'yes'
+	}],
+	quux: 5
+}
+
+merge(x, y) // => output
+```
+
+
+### Installation
+
+With [npm](http://npmjs.org) do:
+
+```sh
+npm install deepmerge
+```
+
+deepmerge can be used directly in the browser without the use of package managers/bundlers as well:  [UMD version from unpkg.com](https://unpkg.com/deepmerge/dist/umd.js).
+
+
+### Include
+
+deepmerge exposes a CommonJS entry point:
+
+```
+const merge = require('deepmerge')
+```
+
+The ESM entry point was dropped due to a [Webpack bug](https://github.com/webpack/webpack/issues/6584).
+
+# API
+
+
+## `merge(x, y, [options])`
+
+Merge two objects `x` and `y` deeply, returning a new merged object with the
+elements from both `x` and `y`.
+
+If an element at the same key is present for both `x` and `y`, the value from
+`y` will appear in the result.
+
+Merging creates a new object, so that neither `x` or `y` is modified.
+
+**Note:** By default, arrays are merged by concatenating them.
+
+## `merge.all(arrayOfObjects, [options])`
+
+Merges any number of objects into a single result object.
+
+```js
+const foobar = { foo: { bar: 3 } }
+const foobaz = { foo: { baz: 4 } }
+const bar = { bar: 'yay!' }
+
+merge.all([ foobar, foobaz, bar ]) // => { foo: { bar: 3, baz: 4 }, bar: 'yay!' }
+```
+
+
+## Options
+
+### `arrayMerge`
+
+There are multiple ways to merge two arrays, below are a few examples but you can also create your own custom function.
+
+Your `arrayMerge` function will be called with three arguments: a `target` array, the `source` array, and an `options` object with these properties:
+
+- `isMergeableObject(value)`
+- `cloneUnlessOtherwiseSpecified(value, options)`
+
+#### `arrayMerge` example: overwrite target array
+
+Overwrites the existing array values completely rather than concatenating them:
+
+```js
+const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
+
+merge(
+	[1, 2, 3],
+	[3, 2, 1],
+	{ arrayMerge: overwriteMerge }
+) // => [3, 2, 1]
+```
+
+#### `arrayMerge` example: combine arrays
+
+Combines objects at the same index in the two arrays.
+
+This was the default array merging algorithm pre-version-2.0.0.
+
+```js
+const combineMerge = (target, source, options) => {
+	const destination = target.slice()
+
+	source.forEach((item, index) => {
+		if (typeof destination[index] === 'undefined') {
+			destination[index] = options.cloneUnlessOtherwiseSpecified(item, options)
+		} else if (options.isMergeableObject(item)) {
+			destination[index] = merge(target[index], item, options)
+		} else if (target.indexOf(item) === -1) {
+			destination.push(item)
+		}
+	})
+	return destination
+}
+
+merge(
+	[{ a: true }],
+	[{ b: true }, 'ah yup'],
+	{ arrayMerge: combineMerge }
+) // => [{ a: true, b: true }, 'ah yup']
+```
+
+### `isMergeableObject`
+
+By default, deepmerge clones every property from almost every kind of object.
+
+You may not want this, if your objects are of special types, and you want to copy the whole object instead of just copying its properties.
+
+You can accomplish this by passing in a function for the `isMergeableObject` option.
+
+If you only want to clone properties of plain objects, and ignore all "special" kinds of instantiated objects, you probably want to drop in [`is-plain-object`](https://github.com/jonschlinkert/is-plain-object).
+
+```js
+const isPlainObject = require('is-plain-object')
+
+function SuperSpecial() {
+	this.special = 'oh yeah man totally'
+}
+
+const instantiatedSpecialObject = new SuperSpecial()
+
+const target = {
+	someProperty: {
+		cool: 'oh for sure'
+	}
+}
+
+const source = {
+	someProperty: instantiatedSpecialObject
+}
+
+const defaultOutput = merge(target, source)
+
+defaultOutput.someProperty.cool // => 'oh for sure'
+defaultOutput.someProperty.special // => 'oh yeah man totally'
+defaultOutput.someProperty instanceof SuperSpecial // => false
+
+const customMergeOutput = merge(target, source, {
+	isMergeableObject: isPlainObject
+})
+
+customMergeOutput.someProperty.cool // => undefined
+customMergeOutput.someProperty.special // => 'oh yeah man totally'
+customMergeOutput.someProperty instanceof SuperSpecial // => true
+```
+
+### `customMerge`
+
+Specifies a function which can be used to override the default merge behavior for a property, based on the property name.
+
+The `customMerge` function will be passed the key for each property, and should return the function which should be used to merge the values for that property.
+
+It may also return undefined, in which case the default merge behaviour will be used.
+
+```js
+const alex = {
+	name: {
+		first: 'Alex',
+		last: 'Alexson'
+	},
+	pets: ['Cat', 'Parrot']
+}
+
+const tony = {
+	name: {
+		first: 'Tony',
+		last: 'Tonison'
+	},
+	pets: ['Dog']
+}
+
+const mergeNames = (nameA, nameB) => `${nameA.first} and ${nameB.first}`
+
+const options = {
+	customMerge: (key) => {
+		if (key === 'name') {
+			return mergeNames
+		}
+	}
+}
+
+const result = merge(alex, tony, options)
+
+result.name // => 'Alex and Tony'
+result.pets // => ['Cat', 'Parrot', 'Dog']
+```
+
+
+### `clone`
+
+*Deprecated.*
+
+Defaults to `true`.
+
+If `clone` is `false` then child objects will be copied directly instead of being cloned.  This was the default behavior before version 2.x.
+
+
+# Testing
+
+With [npm](http://npmjs.org) do:
+
+```sh
+npm test
+```
+
+
+# License
+
+MIT

+ 22 - 0
node_modules/deepmerge/rollup.config.js

@@ -0,0 +1,22 @@
+import resolve from 'rollup-plugin-node-resolve'
+import commonjs from 'rollup-plugin-commonjs'
+import pkg from './package.json'
+
+export default {
+	input: `index.js`,
+	plugins: [
+		commonjs(),
+		resolve(),
+	],
+	output: [
+		{
+			file: pkg.main,
+			format: `cjs`
+		},
+		{
+			name: 'deepmerge',
+			file: 'dist/umd.js',
+			format: `umd`
+		},
+	],
+}

+ 30 - 0
node_modules/jweixin-module/README.md

@@ -0,0 +1,30 @@
+# jweixin-module
+
+微信JS-SDK
+
+## 安装
+
+### NPM
+
+```shell
+npm install jweixin-module --save
+```
+
+### UMD
+
+```http
+https://unpkg.com/jweixin-module/out/index.js
+```
+
+## 使用
+
+```js
+var jweixin = require('jweixin-module')
+jweixin.ready(function(){
+    // TODO
+});
+```
+
+## 完整API
+
+>[微信JS-SDK说明文档](https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115)

File diff suppressed because it is too large
+ 1 - 0
node_modules/jweixin-module/lib/index.js


+ 54 - 0
node_modules/jweixin-module/package.json

@@ -0,0 +1,54 @@
+{
+  "_from": "jweixin-module",
+  "_id": "jweixin-module@1.6.0",
+  "_inBundle": false,
+  "_integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w==",
+  "_location": "/jweixin-module",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "jweixin-module",
+    "name": "jweixin-module",
+    "escapedName": "jweixin-module",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
+  "_shasum": "4a7ea614083e3c9c3f49e2fdc2bb882cfa58dfcd",
+  "_spec": "jweixin-module",
+  "_where": "/Users/zhengmingwei/Desktop/Project/uni-app/uni-shop",
+  "author": {
+    "name": "Shengqiang Guo"
+  },
+  "bugs": {
+    "url": "https://github.com/zhetengbiji/jweixin-module/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "微信JS-SDK",
+  "devDependencies": {},
+  "homepage": "https://github.com/zhetengbiji/jweixin-module#readme",
+  "keywords": [
+    "wxjssdk",
+    "weixin",
+    "jweixin",
+    "wechat",
+    "jssdk",
+    "wx"
+  ],
+  "license": "ISC",
+  "main": "lib/index.js",
+  "name": "jweixin-module",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/zhetengbiji/jweixin-module.git"
+  },
+  "scripts": {},
+  "version": "1.6.0"
+}

+ 21 - 0
node_modules/shvl/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017-2018 Robin van der Vleuten <robin@webstronauts.co>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 48 - 0
node_modules/shvl/README.md

@@ -0,0 +1,48 @@
+# shvl
+
+Get and set dot-notated properties within an object.
+
+<img src="https://media.giphy.com/media/3o85xLDQLoZD1rk07u/giphy-downsized.gif" width="350" />
+
+[![NPM version](https://img.shields.io/npm/v/shvl.svg)](https://www.npmjs.com/package/shvl)
+[![Build Status](https://travis-ci.org/robinvdvleuten/shvl.svg?branch=master)](https://travis-ci.org/robinvdvleuten/shvl)
+
+## Installation
+
+```
+npm install --save shvl
+```
+
+The [UMD](https://github.com/umdjs/umd) build is also available on [unpkg](https://unpkg.com/shvl/dist/shvl.umd.js):
+
+```
+<script src="//unpkg.com/shvl/dist/shvl.umd.js"></script>
+```
+
+This exposes the shlv object as a global.
+
+## Usage
+
+```js
+import * as shvl from 'shvl';
+
+let obj = {
+	a: {
+		b: {
+			c: 1
+			d: undefined
+			e: null
+		}
+	}
+};
+
+// Use dot notation for keys
+shvl.set(obj, 'a.b.c', 2);
+shvl.get(obj, 'a.b.c') === 2;
+
+// Or use an array as key
+shvl.get(obj, ['a', 'b', 'c']) === 1;
+
+// Returns undefined if the path does not exist and no default is specified
+shvl.get(obj, 'a.b.c.f') === undefined;
+```

+ 2 - 0
node_modules/shvl/dist/shvl.js

@@ -0,0 +1,2 @@
+exports.get=function(t,e,n){return void 0===(t=(e.split?e.split("."):e).reduce(function(t,e){return t&&t[e]},t))?n:t},exports.set=function(t,e,n,r){return(e=e.split?e.split("."):e).slice(0,-1).reduce(function(t,e){return t[e]=t[e]||{}},t)[e.pop()]=n,t};
+//# sourceMappingURL=shvl.js.map

File diff suppressed because it is too large
+ 1 - 0
node_modules/shvl/dist/shvl.js.map


+ 2 - 0
node_modules/shvl/dist/shvl.mjs

@@ -0,0 +1,2 @@
+function t(t,n,r){return void 0===(t=(n.split?n.split("."):n).reduce(function(t,n){return t&&t[n]},t))?r:t}function n(t,n,r,e){return(n=n.split?n.split("."):n).slice(0,-1).reduce(function(t,n){return t[n]=t[n]||{}},t)[n.pop()]=r,t}export{t as get,n as set};
+//# sourceMappingURL=shvl.mjs.map

File diff suppressed because it is too large
+ 1 - 0
node_modules/shvl/dist/shvl.mjs.map


+ 2 - 0
node_modules/shvl/dist/shvl.umd.js

@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.shvl={})}(this,function(e){e.get=function(e,t,n){return void 0===(e=(t.split?t.split("."):t).reduce(function(e,t){return e&&e[t]},e))?n:e},e.set=function(e,t,n,i){return(t=t.split?t.split("."):t).slice(0,-1).reduce(function(e,t){return e[t]=e[t]||{}},e)[t.pop()]=n,e}});
+//# sourceMappingURL=shvl.umd.js.map

File diff suppressed because it is too large
+ 1 - 0
node_modules/shvl/dist/shvl.umd.js.map


+ 2 - 0
node_modules/shvl/index.d.ts

@@ -0,0 +1,2 @@
+export function get (object: object, path: string|string[], def?: any): any;
+export function set (object: object, path: string|string[], val: any): any;

+ 11 - 0
node_modules/shvl/index.js

@@ -0,0 +1,11 @@
+export function get (object, path, def) {
+  return (object = (path.split ? path.split('.') : path).reduce(function (obj, p) {
+    return obj && obj[p]
+  }, object)) === undefined ? def : object;
+};
+
+export function set  (object, path, val, obj) {
+  return ((path = path.split ? path.split('.') : path).slice(0, -1).reduce(function (obj, p) {
+    return obj[p] = obj[p] || {};
+  }, obj = object)[path.pop()] = val), object;
+};

+ 87 - 0
node_modules/shvl/package.json

@@ -0,0 +1,87 @@
+{
+  "_from": "shvl@^2.0.0",
+  "_id": "shvl@2.0.0",
+  "_inBundle": false,
+  "_integrity": "sha512-WbpzSvI5XgVGJ3A4ySGe8hBxj0JgJktfnoLhhJmvITDdK21WPVWwgG8GPlYEh4xqdti3Ff7PJ5G0QrRAjNS0Ig==",
+  "_location": "/shvl",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "shvl@^2.0.0",
+    "name": "shvl",
+    "escapedName": "shvl",
+    "rawSpec": "^2.0.0",
+    "saveSpec": null,
+    "fetchSpec": "^2.0.0"
+  },
+  "_requiredBy": [
+    "/vuex-persistedstate"
+  ],
+  "_resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.0.tgz",
+  "_shasum": "55fd550b6e81bf7574f2f576b8b5c1ffae74e10f",
+  "_spec": "shvl@^2.0.0",
+  "_where": "/Users/zhengmingwei/Desktop/Project/uni-app/uni-shop/node_modules/vuex-persistedstate",
+  "author": {
+    "name": "Robin van der Vleuten",
+    "email": "robin@webstronauts.co"
+  },
+  "babel": {
+    "presets": [
+      "@babel/preset-env"
+    ]
+  },
+  "bugs": {
+    "url": "https://github.com/robinvdvleuten/shvl/issues"
+  },
+  "bundleDependencies": false,
+  "bundlesize": [
+    {
+      "path": "./dist/*.js",
+      "threshold": "300b"
+    }
+  ],
+  "deprecated": false,
+  "description": "Get and set dot-notated properties within an object",
+  "devDependencies": {
+    "@babel/core": "^7.0.0",
+    "@babel/preset-env": "^7.0.0",
+    "babel-jest": "^24.7.1",
+    "bundlesize": "^0.16.0",
+    "jest": "^24.7.1",
+    "jest-in-case": "^1.0.2",
+    "microbundle": "^0.11.0",
+    "npm-run-all": "^4.1.2"
+  },
+  "files": [
+    "dist",
+    "index.d.ts",
+    "index.js"
+  ],
+  "homepage": "https://github.com/robinvdvleuten/shvl#readme",
+  "keywords": [
+    "path",
+    "dot notation",
+    "dot"
+  ],
+  "license": "MIT",
+  "main": "dist/shvl.js",
+  "module": "dist/shvl.mjs",
+  "name": "shvl",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/robinvdvleuten/shvl.git"
+  },
+  "scripts": {
+    "build": "microbundle",
+    "prepublish": "run-s build",
+    "pretest": "run-s build",
+    "test": "run-p test:**",
+    "test:jest": "jest --env=jsdom",
+    "test:size": "bundlesize"
+  },
+  "source": "index.js",
+  "typings": "index.d.ts",
+  "unpkg": "dist/shvl.umd.js",
+  "version": "2.0.0"
+}

+ 21 - 0
node_modules/vuex-persistedstate/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) Robin van der Vleuten <robin@webstronauts.co>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

File diff suppressed because it is too large
+ 227 - 0
node_modules/vuex-persistedstate/README.md


+ 23 - 0
node_modules/vuex-persistedstate/dist/index.d.ts

@@ -0,0 +1,23 @@
+import { Store, MutationPayload } from "vuex";
+interface Storage {
+    getItem: (key: string) => any;
+    setItem: (key: string, value: any) => void;
+    removeItem: (key: string) => void;
+}
+interface Options {
+    key?: string;
+    paths?: string[];
+    reducer?: (state: any, paths: string[]) => object;
+    subscriber?: (store: typeof Store) => (handler: (mutation: any, state: any) => void) => void;
+    storage?: Storage;
+    getState?: (key: string, storage: Storage) => any;
+    setState?: (key: string, state: typeof Store, storage: Storage) => void;
+    filter?: (mutation: MutationPayload) => boolean;
+    arrayMerger?: (state: any, saved: any) => any;
+    rehydrated?: (store: typeof Store) => void;
+    fetchBeforeUse?: boolean;
+    overwrite?: boolean;
+    assertStorage?: (storage: Storage) => void | Error;
+}
+export default function (options?: Options): (store: any) => void;
+export {};

File diff suppressed because it is too large
+ 2 - 0
node_modules/vuex-persistedstate/dist/vuex-persistedstate.es.js


File diff suppressed because it is too large
+ 1 - 0
node_modules/vuex-persistedstate/dist/vuex-persistedstate.es.js.map


File diff suppressed because it is too large
+ 2 - 0
node_modules/vuex-persistedstate/dist/vuex-persistedstate.js


File diff suppressed because it is too large
+ 1 - 0
node_modules/vuex-persistedstate/dist/vuex-persistedstate.js.map


File diff suppressed because it is too large
+ 2 - 0
node_modules/vuex-persistedstate/dist/vuex-persistedstate.umd.js


File diff suppressed because it is too large
+ 1 - 0
node_modules/vuex-persistedstate/dist/vuex-persistedstate.umd.js.map


+ 112 - 0
node_modules/vuex-persistedstate/package.json

@@ -0,0 +1,112 @@
+{
+  "_from": "vuex-persistedstate",
+  "_id": "vuex-persistedstate@3.0.1",
+  "_inBundle": false,
+  "_integrity": "sha512-2dH77+fIecAXO8GeJEXiYnC++gx48PFGUayB5d7rWrN3fblRCOHQoVnmu/VV9DXbHHJcJth/0W/ofl8vw12j1A==",
+  "_location": "/vuex-persistedstate",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "vuex-persistedstate",
+    "name": "vuex-persistedstate",
+    "escapedName": "vuex-persistedstate",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-3.0.1.tgz",
+  "_shasum": "6eacc3c416fe8cfe63c40d3ee7b8ed13aac4f04f",
+  "_spec": "vuex-persistedstate",
+  "_where": "/Users/zhengmingwei/Desktop/Project/uni-app/uni-shop",
+  "author": {
+    "name": "Robin van der Vleuten",
+    "email": "robin@webstronauts.co",
+    "url": "robinvdvleuten.nl"
+  },
+  "babel": {
+    "presets": [
+      "@babel/preset-env"
+    ]
+  },
+  "bugs": {
+    "url": "https://github.com/robinvdvleuten/vuex-persistedstate/issues"
+  },
+  "bundleDependencies": false,
+  "bundlesize": [
+    {
+      "path": "./dist/*.js",
+      "threshold": "800b"
+    }
+  ],
+  "dependencies": {
+    "deepmerge": "^4.2.2",
+    "shvl": "^2.0.0"
+  },
+  "deprecated": false,
+  "description": "Persist and rehydrate your Vuex state between page reloads.",
+  "devDependencies": {
+    "@babel/core": "^7.0.0",
+    "@babel/preset-env": "^7.0.0",
+    "all-contributors-cli": "^6.9.3",
+    "babel-core": "^7.0.0-bridge.0",
+    "babel-jest": "^25.1.0",
+    "bundlesize": "^0.18.0",
+    "dom-storage": "^2.0.2",
+    "eslint": "^6.6.0",
+    "husky": "^4.2.1",
+    "jest": "^25.1.0",
+    "microbundle": "^0.11.0",
+    "npm-run-all": "^4.1.2",
+    "prettier": "^2.0.1",
+    "pretty-quick": "^2.0.0",
+    "rimraf": "^3.0.0",
+    "vue": "^2.5.15",
+    "vuex": "^3.0.1"
+  },
+  "files": [
+    "dist",
+    "src"
+  ],
+  "homepage": "https://github.com/robinvdvleuten/vuex-persistedstate#readme",
+  "husky": {
+    "hooks": {
+      "pre-commit": "npm run build && pretty-quick --staged"
+    }
+  },
+  "jest": {
+    "testURL": "http://localhost/"
+  },
+  "keywords": [
+    "vue",
+    "vuex",
+    "plugin"
+  ],
+  "license": "MIT",
+  "main": "dist/vuex-persistedstate.js",
+  "module": "dist/vuex-persistedstate.es.js",
+  "name": "vuex-persistedstate",
+  "peerDependencies": {
+    "vue": "^2.0.0",
+    "vuex": "^2.0.0 || ^3.0.0"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/robinvdvleuten/vuex-persistedstate.git"
+  },
+  "scripts": {
+    "build": "rimraf dist && microbundle --external all --name createPersistedState",
+    "prepare": "npm run build",
+    "test": "npm-run-all test:**",
+    "test:jest": "jest --env=jsdom",
+    "test:size": "bundlesize"
+  },
+  "source": "src/index.ts",
+  "types": "dist/index.d.ts",
+  "unpkg": "dist/vuex-persistedstate.umd.js",
+  "version": "3.0.1"
+}

+ 117 - 0
node_modules/vuex-persistedstate/src/index.ts

@@ -0,0 +1,117 @@
+import { Store, MutationPayload } from "vuex";
+import merge from "deepmerge";
+import * as shvl from "shvl";
+
+interface Storage {
+  getItem: (key: string) => any;
+  setItem: (key: string, value: any) => void;
+  removeItem: (key: string) => void;
+}
+
+interface Options {
+  key?: string;
+  paths?: string[];
+  reducer?: (state: any, paths: string[]) => object;
+  subscriber?: (
+    store: typeof Store
+  ) => (handler: (mutation: any, state: any) => void) => void;
+  storage?: Storage;
+  getState?: (key: string, storage: Storage) => any;
+  setState?: (key: string, state: typeof Store, storage: Storage) => void;
+  filter?: (mutation: MutationPayload) => boolean;
+  arrayMerger?: (state: any, saved: any) => any;
+  rehydrated?: (store: typeof Store) => void;
+  fetchBeforeUse?: boolean;
+  overwrite?: boolean;
+  assertStorage?: (storage: Storage) => void | Error;
+}
+
+export default function (options?: Options) {
+  options = options || {};
+
+  const storage = options.storage || (window && window.localStorage);
+  const key = options.key || "vuex";
+
+  function getState(key, storage) {
+    let value;
+
+    try {
+      return (value = storage.getItem(key)) && typeof value !== "undefined"
+        ? JSON.parse(value)
+        : undefined;
+    } catch (err) {}
+
+    return undefined;
+  }
+
+  function filter() {
+    return true;
+  }
+
+  function setState(key, state, storage) {
+    return storage.setItem(key, JSON.stringify(state));
+  }
+
+  function reducer(state, paths) {
+    return Array.isArray(paths)
+      ? paths.reduce(function (substate, path) {
+          return shvl.set(substate, path, shvl.get(state, path));
+        }, {})
+      : state;
+  }
+
+  function subscriber(store) {
+    return function (handler) {
+      return store.subscribe(handler);
+    };
+  }
+
+  const assertStorage =
+    options.assertStorage ||
+    (() => {
+      storage.setItem("@@", 1);
+      storage.removeItem("@@");
+    });
+
+  assertStorage(storage);
+
+  const fetchSavedState = () => (options.getState || getState)(key, storage);
+
+  let savedState;
+
+  if (options.fetchBeforeUse) {
+    savedState = fetchSavedState();
+  }
+
+  return function (store) {
+    if (!options.fetchBeforeUse) {
+      savedState = fetchSavedState();
+    }
+
+    if (typeof savedState === "object" && savedState !== null) {
+      store.replaceState(
+        options.overwrite
+          ? savedState
+          : merge(store.state, savedState, {
+              arrayMerge:
+                options.arrayMerger ||
+                function (store, saved) {
+                  return saved;
+                },
+              clone: false,
+            })
+      );
+      (options.rehydrated || function () {})(store);
+    }
+
+    (options.subscriber || subscriber)(store)(function (mutation, state) {
+      if ((options.filter || filter)(mutation)) {
+        (options.setState || setState)(
+          key,
+          (options.reducer || reducer)(state, options.paths),
+          storage
+        );
+      }
+    });
+  };
+}

+ 35 - 0
package-lock.json

@@ -0,0 +1,35 @@
+{
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "deepmerge": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+      "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
+    },
+    "jweixin-module": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/jweixin-module/-/jweixin-module-1.6.0.tgz",
+      "integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
+    },
+    "mpvue-citypicker": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/mpvue-citypicker/-/mpvue-citypicker-1.0.6.tgz",
+      "integrity": "sha512-V8TuUILYw7pFV0ii02tXKUtLmoa+mTxxJS85dEIc4sp85dVTLNi2GmXqBoz9MkT+QwKeOf3fPvFZzoucERz5rA=="
+    },
+    "shvl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.0.tgz",
+      "integrity": "sha512-WbpzSvI5XgVGJ3A4ySGe8hBxj0JgJktfnoLhhJmvITDdK21WPVWwgG8GPlYEh4xqdti3Ff7PJ5G0QrRAjNS0Ig=="
+    },
+    "vuex-persistedstate": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-3.0.1.tgz",
+      "integrity": "sha512-2dH77+fIecAXO8GeJEXiYnC++gx48PFGUayB5d7rWrN3fblRCOHQoVnmu/VV9DXbHHJcJth/0W/ofl8vw12j1A==",
+      "requires": {
+        "deepmerge": "^4.2.2",
+        "shvl": "^2.0.0"
+      }
+    }
+  }
+}

+ 459 - 0
pages.json

@@ -0,0 +1,459 @@
+{
+	"pages": [
+
+		{
+			"path": "pages/index/index",
+			"style": {
+				"enablePullDownRefresh": true,
+				// #ifdef MP 
+				"navigationBarTitleText": "八十一坊商城",
+				//"navigationStyle": "custom",
+				// #endif 
+				"app-plus": {
+					"titleNView": {
+						"titleText": "八十一坊商城"
+						//"type": "transparent"
+						// "searchInput": {
+						// 	"backgroundColor": "rgba(231, 231, 231,.7)",
+						// 	"borderRadius": "16px",
+						// 	"placeholder": "请输入地址 如:大钟寺",
+						// 	"disabled": true,
+						// 	"placeholderColor": "#606266"
+						// },
+						// "buttons": [{
+						// 		"fontSrc": "/static/yticon.ttf",
+						// 		"text": "\ue60d",
+						// 		"fontSize": "26",
+						// 		"color": "#303133",
+						// 		"float": "left",
+						// 		"background": "rgba(0,0,0,0)"
+						// 	},
+						// 	{
+						// 		"fontSrc": "/static/yticon.ttf",
+						// 		"text": "\ue744",
+						// 		"fontSize": "27",
+						// 		"color": "#303133",
+						// 		"background": "rgba(0,0,0,0)",
+						// 		"redDot": true
+						// 	}
+						// ]
+					}
+				}
+			}
+		},
+		{
+			"path": "pages/product/product",
+			"style": {
+				"navigationBarTitleText": "详情展示",
+				"enablePullDownRefresh": true,
+				"app-plus": {
+					"titleNView": {
+						"type": "transparent"
+					}
+				}
+			}
+		}, {
+			"path": "pages/set/set",
+			"style": {
+				"navigationBarTitleText": "设置"
+			}
+		},
+		{
+			"path": "pages/userinfo/userinfo",
+			"style": {
+				"navigationBarTitleText": "修改资料"
+			}
+		}, {
+			"path": "pages/cart/cart",
+			"style": {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "购物车"
+			}
+		}, {
+			"path": "pages/public/login",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom",
+				"app-plus": {
+					"titleNView": false,
+					"animationType": "slide-in-bottom"
+				}
+			}
+		}, {
+			"path": "pages/public/register",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom",
+				"app-plus": {
+					"titleNView": false,
+					"animationType": "slide-in-bottom"
+				}
+			}
+		}, {
+			"path": "pages/user/user",
+			"style": {
+				"navigationBarTitleText": "我的",
+				// #ifdef MP
+				"navigationStyle": "custom",
+				// #endif
+				"app-plus": {
+					"bounce": "none",
+					"titleNView": {
+						"type": "transparent"
+						// "buttons": [{
+						// 		"fontSrc": "/static/yticon.ttf",
+						// 		"text": "\ue60f",
+						// 		"fontSize": "24",
+						// 		"color": "#303133",
+						// 		"width": "46px",
+						// 		"background": "rgba(0,0,0,0)"
+						// 	},
+						// 	{
+						// 		"fontSrc": "/static/yticon.ttf",
+						// 		"text": "\ue744",
+						// 		"fontSize": "28",
+						// 		"color": "#303133",
+						// 		"background": "rgba(0,0,0,0)",
+						// 		"redDot": true
+						// 	}
+						// ]
+					}
+				}
+			}
+		}, {
+			"path": "pages/order/order",
+			"style": {
+				"navigationBarTitleText": "我的订单",
+				"enablePullDownRefresh": true,
+				"app-plus": {
+					"bounce": "none"
+				}
+			}
+		}, {
+			"path": "pages/order/express",
+			"style": {
+				"navigationBarTitleText": "查看物流",
+				"enablePullDownRefresh": true,
+				"app-plus": {
+					"bounce": "none"
+				}
+			}
+		}, 
+		{
+			"path": "pages/order/orderDetail",
+			"style": {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "订单详情",
+				"app-plus": {
+					"bounce": "none",
+					"titleNView": {
+						"type": "transparent"
+					}
+				}
+			}
+		},{
+			"path": "pages/money/money",
+			"style": {}
+		}, {
+			"path": "pages/order/createOrder",
+			"style": {
+				"navigationBarTitleText": "创建订单"
+			}
+		}, {
+			"path": "pages/address/address",
+			"style": {
+				"navigationBarTitleText": "收货地址"
+			}
+		}, {
+			"path": "pages/address/addressManage",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+		}, {
+			"path": "pages/money/pay",
+			"style": {
+				"navigationBarTitleText": "支付"
+			}
+		},
+		{
+			"path": "pages/money/paySuccess",
+			"style": {
+				"navigationBarTitleText": "支付成功"
+			}
+		}
+	    ,{
+            "path" : "pages/notice/notice",
+            "style" : {
+				"navigationBarTitleText": "通知"
+			}
+        }
+        ,{
+            "path" : "pages/category/category",
+            "style" : {
+				"navigationBarTitleText": "分类",
+				"enablePullDownRefresh": true,
+				"app-plus": {
+					"bounce": "none"
+				}
+			}
+        }
+        ,{
+            "path" : "pages/product/list",
+            "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "商品列表"
+			}
+        }
+		,{
+		    "path" : "pages/flash/list",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "限时秒杀"
+			}
+		},
+		{
+		    "path" : "pages/term/index",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "我的团队"
+			}
+		},
+		{
+		    "path" : "pages/wallet/index",
+		    "style" : { 
+				"navigationBarTitleText": "我的钱包",
+					"navigationStyle": "custom"
+			}
+		},
+		
+		
+		
+		{
+		    "path" : "pages/wallet/cashlist",
+		    "style" : { 
+				"navigationBarTitleText": "提现记录"
+			}
+		},
+		
+		
+		{
+		    "path" : "pages/wallet/paylist",
+		    "style" : { 
+				"navigationBarTitleText": "账单明细"
+			}
+		},
+		
+		
+		{
+		    "path" : "pages/wallet/integral",
+		    "style" : { 
+				"navigationBarTitleText": "积分明细"
+			}
+		},
+		
+	
+		{
+		    "path" : "pages/Withdrawal/index",
+		    "style" : { 
+				"navigationBarTitleText": "佣金提现"
+			}
+		},
+		
+		{
+		    "path" : "pages/Withdrawal/addbank",
+		    "style" : { 
+				"navigationBarTitleText": "添加银行卡"
+			}
+		},
+		
+		{
+		    "path" : "pages/Withdrawal/banklist",
+		    "style" : { 
+				"navigationBarTitleText": "银行卡列表"
+			}
+		},
+		
+		
+		
+		{
+		    "path" : "pages/intergalShop/index",
+		    "style" : { 
+				"navigationBarTitleText": "积分商城",
+					"navigationStyle": "custom"
+			}
+		},
+		
+		{
+		    "path" : "pages/intergalShop/goodsDetail",
+		    "style" : { 
+				"navigationBarTitleText": "商品详情"
+			}
+		},
+		
+		
+		{
+		    "path" : "pages/intergalShop/confirm",
+		    "style" : { 
+				"navigationBarTitleText": "确认订单"
+			}
+		},
+		
+		{
+		    "path" : "pages/intergalShop/orderDetail",
+		    "style" : { 
+				"navigationBarTitleText": "订单详情"
+			}
+		},
+		{
+		    "path" : "pages/intergalShop/logs",
+		    "style" : { 
+				"navigationBarTitleText": "我的兑换"
+			}
+		},
+		
+		{
+		    "path" : "pages/article/index",
+		    "style" : { 
+				"navigationBarTitleText": "酱本之源"
+			}
+		},
+		 
+		{
+		    "path" : "pages/article/detail",
+		    "style" : { 
+				"navigationBarTitleText": "文章详情"
+			}
+		},
+		
+		
+		{
+		    "path" : "pages/poster/index",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "我的海报"
+			}
+		},
+		{
+		    "path" : "pages/favorite/favorite",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "我的收藏"
+			}
+		},
+		{
+		    "path" : "pages/public/webview",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "物流"
+			}
+		},
+		{
+		    "path" : "pages/order/evaluate",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "发表评论"
+			}
+		},
+		{
+		    "path" : "pages/order/refund",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "申请售后"
+			}
+		},
+		{
+		    "path" : "pages/product/evaluate",
+		    "style" : {
+				"enablePullDownRefresh": true,
+				"navigationBarTitleText": "评价"
+			}
+		},
+		{
+		    "path" : "pages/order/delivery",
+		    "style" : {
+				"enablePullDownRefresh": false,
+				"navigationBarTitleText": "运费模板"
+			}
+		}
+    ],
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "uni-app",
+		"navigationBarBackgroundColor": "#FFFFFF",
+		"backgroundColor": "#f8f8f8"
+	},
+	"tabBar": {
+		"color": "#C0C4CC",
+		"selectedColor": "#fa436a",
+		"borderStyle": "black",
+		"backgroundColor": "#ffffff",
+		"list": [{
+				"pagePath": "pages/index/index",
+				"iconPath": "static/tab-home.png",
+				"selectedIconPath": "static/tab-home-current.png",
+				"text": "首页"
+			},
+			// {
+			// 	"pagePath": "pages/category/category",
+			// 	"iconPath": "static/tab-cate.png",
+			// 	"selectedIconPath": "static/tab-cate-current.png",
+			// 	"text": "分类"
+			// },
+			
+			{
+				"pagePath": "pages/intergalShop/index",
+				"iconPath": "static/tab-cate.png",
+				"selectedIconPath": "static/tab-cate-current.png",
+				"text": "积分"
+			},
+			
+			{
+				"pagePath": "pages/cart/cart",
+				"iconPath": "static/tab-cart.png",
+				"selectedIconPath": "static/tab-cart-current.png",
+				"text": "购物车"
+			},
+			{
+				"pagePath": "pages/user/user",
+				"iconPath": "static/tab-my.png",
+				"selectedIconPath": "static/tab-my-current.png",
+				"text": "我的"
+			}
+		]
+	},
+	"condition" : { //模式配置,仅开发期间生效
+		"current": 0, //当前激活的模式(list 的索引项)
+		"list": [
+			{
+				"name": "index", //模式名称
+				"path": "pages/index/index", //启动页面,必选
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "comment",
+				"path": "pages/order/comment",
+				"query":"order_id=nAyML8YWRXU1O2b&image=/shop/20200315/5507a02e4f1a43c72d8360e4194b42a5.png&title=万里无一万里无一万里无一万里无一万里无一万里无一苹果X&spec=白色"
+			},
+			{
+				"name": "orderDetail",
+				"path":"pages/order/orderDetail",
+				"query":"order_id=XDW6kZLJD4ijNEE"
+			},
+			{
+				"name":"orderRefund",
+				"path":"pages/order/refund",
+				"query":"order_id=7Rw23P1oW1CyPgO"
+			},
+			{
+				"name":"userinfo",
+				"path":"pages/userinfo/userinfo",
+				"query":""
+			},
+			{
+				"name": "deliveryTemplate",
+				"path":"pages/order/delivery",
+				"query":""
+			}
+		]
+	}
+}

+ 464 - 0
pages/Withdrawal/addbank.vue

@@ -0,0 +1,464 @@
+<template>
+    <block>
+        <view class="tip1">添加银行卡</view>
+        <view class="tip2">请绑定本人常用银行卡</view>
+
+        <view :style="'width:' + widths + ';overflow-x:hidden;'">
+            <view class="step1">
+                <view class="info">
+                    <view class="info-label info-content flex-row">
+                        <!-- <view class="info-left flex-y-center required">收件人</view> -->
+                        <view class="info-left flex-y-center">持卡人:</view>
+
+                        <view class="info-right flex-row flex-y-center">
+                            <input :value="name" class="name-input" @input="inputChange" data-name="name" placeholder="持卡人姓名" />
+                        </view>
+                    </view>
+
+                    <view class="info-label info-content flex-row">
+				<view class="info-left flex-y-center ">联系电话:</view>
+				<view class="info-right flex-row flex-y-center">
+					<input :value="mobile" class="mobile-input" data-name="mobile" @input="inputChange" placeholder="请输入您的手机号码" type="number"></input>
+				</view>
+			</view>
+
+                    <view class="info-label info-content flex-row">
+                        <view class="info-left flex-y-center">卡号:</view>
+                        <view class="info-right flex-row flex-y-center">
+							<input :value="card" class="name-input" @input="inputChange" data-name="card" placeholder="持卡人本人银行卡号" />
+							
+                            <!-- <textarea auto-height :value="addressDetail" class="name-input" @input="inputChange" data-name="card_no" placeholder="持卡人本人银行卡号"></textarea> -->
+                        </view>
+                    </view>
+
+                    <view class="info-label info-content flex-row">
+                        <view class="info-left flex-y-center">银行:</view>
+                        <view class="info-right flex-row flex-y-center">
+                            <input :value="bank" class="mobile-input" @input="inputChange" data-name="bank" placeholder="请输入开户行" />
+                        </view>
+                    </view>
+
+                    <!-- <view class="info-label info-content flex-row">
+				<view class="info-left flex-y-center">银行</view>
+				<view class="info-right flex-row flex-y-center">
+					<picker  bindchange="bindPickerChange" value="{{index}}"  range="{{array}}">
+						<view class="mobile-input {{title?'':'c999'}}">
+							{{title?title:"请选择开户行"}}
+						</view>
+					</picker>
+				</view>
+			</view> -->
+
+            <!--        <view class="switch">
+                        <view>设置默认银行卡:</view>
+                        <switch :checked="switch1Checked" @change="switch1Change" color="#1479FF" />
+                    </view> -->
+                </view>
+            </view>
+        </view>
+
+        <view class="addAddress" @tap="confirm">保存</view>
+    </block>
+</template>
+
+<script>
+var app = getApp(); // a = app.requirejs('core');
+
+var loading = false; // var b = app.requirejs("api/index");
+
+// import { request } from '../../../utils/request.js';
+export default {
+    data() {
+        return {
+			name: '',
+            mobile: '',
+            card: '',
+            bank: '',
+
+            // phone: "",
+            // title: "",
+            // array: ['农业银行', '赣州银行', '中国银行', '交通银行'],
+            // index: 0,
+            switch1Checked: false,
+
+     
+            widths: '',
+
+        };
+    },
+    onLoad: function (e) {
+        // this.setData(e);
+    },
+	
+	
+    onPullDownRefresh: function () {},
+    onReachBottom: function () {},
+    methods: {
+        bindPickerChange(e) {
+            console.log('picker发送选择改变,携带值为', e.detail.value);
+            this.setData({
+                index: e.detail.value,
+                title: this.array[e.detail.value]
+            });
+        },
+
+        switch1Change(e) {
+            this.setData({
+                switch1Checked: e.detail.value
+            });
+        },
+
+        async confirm () {
+            if (loading) {
+                return;
+            }
+
+            var that = this;
+
+            if (that.name == '') {
+                uni.showToast({
+                    title: '请填写持卡人姓名',
+                    icon: 'none'
+                });
+                return false;
+            }
+			
+			if (that.mobile  == '') {
+			    uni.showToast({
+			        title: '请填写手机号码',
+			        icon: 'none'
+			    });
+			    return false;
+			}
+			
+			
+
+            if (that.card  == '') {
+                uni.showToast({
+                    title: '请填写银行卡号',
+                    icon: 'none'
+                });
+                return false;
+            }
+
+            if (that.bank  == '') {
+                uni.showToast({
+                    title: '请填写银行卡姓名',
+                    icon: 'none'
+                });
+                return false;
+            }
+			
+			
+			let result = await this.$api.request('/bank/add', 'POST', {name:that.name,mobile:that.mobile,card:that.card,bank:that.bank});
+			if (result) {
+					this.$api.msg('添加成功');
+					        setTimeout(function () {
+					           uni.navigateBack({
+					           	delta:1
+					           })
+					        }, 1000);
+			}
+			
+			
+			
+			
+			
+
+            // var r = this.type == 1 ? 'agent.cash.add_bank' : 'fenxiao.cash.add_bank';
+            // loading = true;
+            // request({
+            //     method: 'get',
+            //     data: {
+            //         r,
+            //         account: that.account,
+            //         card_no: that.card_no,
+            //         bank_name: that.bank_name,
+            //         is_default: that.switch1Checked ? 1 : 0
+            //     }
+            // }).then((res) => {
+            //     console.log(res);
+
+            //     if (res.error == 0) {
+            //         uni.showToast({
+            //             title: '添加成功',
+            //             icon: 'none'
+            //         });
+            //         setTimeout(function () {
+            //             uni.navigateTo({
+            //                 url: '/pages/backstage/bankList/bankList?type=' + that.type
+            //             });
+            //         }, 1000);
+            //     } else {
+            //         uni.showToast({
+            //             title: res.message,
+            //             icon: 'none'
+            //         });
+            //     }
+            // });
+        },
+
+        inputChange(e) {
+            var name = e.currentTarget.dataset.name;
+            this[name] = e.detail.value;
+        }
+    }
+};
+</script>
+<style>
+.step1 .info {
+    background-color: #ffffff;
+    border-bottom: 1rpx #e4e5ee solid;
+    padding: 0 30rpx;
+}
+
+.info .info-label {
+    width: 100%;
+    height: 100rpx;
+    border-bottom: 1rpx #e3e3e3 solid;
+    color: #353535;
+}
+
+.info .info-label:last-child {
+    border-bottom: none;
+}
+
+.info .info-label .info-red {
+    color: #ff5200;
+}
+
+.info .info-label .info-gray {
+    color: #666666;
+}
+
+.info .info-label.info-content {
+    height: 100rpx;
+    padding-left: 10rpx;
+}
+
+.info-label .info-left {
+    width: 176rpx;
+    font-size: 28rpx;
+}
+.info-left {
+    width: 176rpx;
+}
+
+.info-label .info-left.required::after {
+    content: '*';
+    color: #ff5200;
+}
+
+.info-label .info-agree {
+    font-size: 10pt;
+}
+
+.info-btn {
+    padding: 24rpx;
+    background-color: #f7f7f7;
+}
+
+.info-btn .info-btn-content {
+    background-color: #e94443;
+    color: #ffffff;
+    font-weight: bold;
+    height: 100rpx;
+    line-height: 100rpx;
+    width: 100%;
+}
+
+.info-label .info-icon {
+    width: 60rpx;
+    height: 60rpx;
+    margin-right: 24rpx;
+}
+
+.info .bold {
+    font-weight: bold;
+}
+
+.info .info-label.info-height {
+    height: auto;
+}
+.textarea {
+    flex: 1;
+    min-height: 200rpx;
+}
+
+.info .info-label .info-block {
+    padding: 24rpx 0;
+}
+
+.info-block .info-top {
+    margin-bottom: 16rpx;
+}
+
+.info-block .info-bottom {
+    font-size: 9pt;
+}
+
+.step2 .info {
+    padding: 48rpx 24rpx;
+    text-align: center;
+}
+
+.step2 .info .info-title {
+    width: 100%;
+    padding: 40rpx 0;
+}
+
+.info-title .info-images {
+    width: 80rpx;
+    height: 80rpx;
+}
+
+.step2 .info-btn1 {
+    margin-top: 88rpx;
+    width: 100%;
+}
+
+.step2 .info-btn1 .btn {
+    width: 100%;
+    background-color: #820000;
+    color: #ffffff;
+    font-weight: bold;
+    height: 100rpx;
+    line-height: 100rpx;
+    border-radius: 10rpx;
+}
+.name-input {
+    /* padding: 12rpx 0; */
+    width: 100%;
+}
+
+.flex {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+}
+
+.flex-row {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-orient: horizontal;
+    flex-direction: row;
+}
+
+.flex-col {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-orient: vertical;
+    flex-direction: column;
+}
+
+.flex-grow-0 {
+    min-width: 0;
+    -webkit-box-flex: 0;
+    -ms-flex-positive: 0;
+    flex-grow: 0;
+    -ms-flex-negative: 0;
+    flex-shrink: 0;
+}
+
+.flex-grow-1 {
+    min-width: 0;
+    -webkit-box-flex: 1;
+    -ms-flex-positive: 1;
+    flex-grow: 1;
+    -ms-flex-negative: 1;
+    flex-shrink: 1;
+}
+
+.flex-x-center {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-pack: center;
+    -ms-flex-pack: center;
+    justify-content: center;
+    flex: 1;
+}
+
+.flex-y-center {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-align: center;
+    -ms-flex-align: center;
+    -ms-grid-row-align: center;
+    align-items: center;
+}
+
+.info-right {
+    flex: 1;
+}
+.flex-y-bottom {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: flex;
+    -webkit-box-align: end;
+    -ms-flex-align: end;
+    -ms-grid-row-align: flex-end;
+    align-items: flex-end;
+}
+
+.c999 {
+    color: #777;
+}
+
+.addAddress {
+    width: 670rpx;
+    height: 80rpx;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    color: #fff;
+    background: linear-gradient(to right,#F8A52B,#F8C657);
+    border-radius: 50rpx;
+    font-size: 30rpx;
+    position: fixed;
+    bottom: 80rpx;
+    left: 50%;
+    transform: translate(-50%, 0);
+    font-weight: 700;
+}
+
+.heng {
+    height: 20rpx;
+    background: #efefef;
+}
+
+textarea {
+    width: 480rpx;
+}
+
+.tip1 {
+    margin-top: 60rpx;
+    font-weight: 700;
+    font-size: 40rpx;
+    text-align: center;
+}
+
+.tip2 {
+    font-size: 28rpx;
+    text-align: center;
+    margin: 35rpx 0 100rpx;
+}
+
+.switch {
+    height: 100rpx;
+    padding: 0 10rpx;
+    border-bottom: 1px solid #e3e3ee;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.switch > view {
+    color: #353535;
+    font-size: 28rpx;
+}
+
+</style>

+ 244 - 0
pages/Withdrawal/banklist.vue

@@ -0,0 +1,244 @@
+<template>
+    <block>
+        <view :class="'mItem ' + ((index + 1) % 2 == 0 ? 'bg1' : (index + 1) % 2 == 0 ? 'bg2' : 'bg3')" v-for="(item, index) in list" :key="index">
+            <!-- <image
+    src="https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIibNthPtcRZKfZCjg4u4IbfezjPAZ9PQWLmRLcTsaFerR8sxOBs7fVibx7NJmEFZy9qXVaoWG82CjA/132">
+  </image> -->
+
+            <view class="mInfo">
+                <view class="info1">
+                    <view>
+                        {{ item.bank }}
+                        <text class="fz24">({{ item.name }})</text>
+                    </view>
+                </view>
+                <view class="info2">
+                    <view>{{ parse.filterNum(item.card) }}</view>
+                </view>
+
+                <!-- <view class="info3" v-if="item.is_default">默认账户</view> -->
+            </view>
+        </view>
+		
+		    <view v-if="!list.length" style='color:#999;text-align:center;margin:150rpx 0;font-size:30rpx'>暂无数据</view>
+
+        <view class="fb">
+            <view class="addAddress" :data-type="type" @tap="toPage" data-url="/pages/Withdrawal/addbank">
+                <image src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/a21445e2e3a4427ed6307bf3bb91cd75.png" mode="widthFix"></image>
+                <view>添加银行卡</view>
+            </view>
+        </view>
+    </block>
+</template>
+<script module="parse" lang="wxs">
+module.exports = {
+
+	filterNum: function(value) {
+
+
+       var value = value+''
+
+       console.log(value)
+
+
+       var card = value.replace(getRegExp('(/^(\d{4})\d+(\d{4})$/)','g'),'$1 **** **** $2')
+
+        return card
+
+
+	}
+
+
+}
+</script>
+<script>
+// pages/tabbar/index/index.js
+var app = getApp();
+
+export default {
+    data() {
+        return {
+            navIndex: 0,
+            list: [
+				// {
+				// 	account: "hhD",
+				// 	bank_name: "农业银行",
+				// 	card_no: "6228481561378773113",
+				// 	card_no_end: "3113",
+				// 	create_time: "1659088920",
+				// 	id: "7",
+				// 	is_default: "0",
+				// 	status: "1",
+				// 	uniacid: "3",
+				// 	update_time: "1659088920",
+				// 	user_id: "1"
+				// }
+			],
+            loaded: false,
+            page: 1,
+            type: '',
+			pageSize:10
+        };
+    },
+    onLoad: function (options) {
+
+    },
+	
+	onShow() {
+		this.init()
+		this.getlist();
+	},
+    onPullDownRefresh: function () {},
+    onReachBottom: function () {
+        this.loaded || this.getlist();
+    },
+    onShareAppMessage: function () {},
+    methods: {
+        toPage(e) {
+            app.globalData.toPage(e);
+        },
+
+        init() {
+    
+                this.page=1
+                this.loaded= false
+                this.list= []
+       
+        },
+
+        async getlist() {
+            var that = this;
+			         let res = await this.$api.request('/bank/index', 'GET', {
+			         	page: this.page,
+			         	pagesize: this.pageSize
+			         });
+					 
+					 console.log(res)
+			         if (res) {
+			         	if (res.length > 0) {
+			         
+			         		this.list = this.list.concat(res);
+			         
+			         		this.page++;
+			         		
+			         	} else {
+			         		this.loaded = true
+			         		this.$api.msg('没有更多数据');
+			         	}
+			         }
+        }
+    }
+};
+</script>
+<style>
+page {
+}
+
+.mItem {
+    margin: 30rpx 30rpx 0;
+
+    padding: 50rpx 48rpx;
+    display: flex;
+    align-items: center;
+    border-radius: 10rpx;
+    position: relative;
+}
+.info3 {
+    position: absolute;
+    font-size: 26rpx;
+    color: #fff;
+    right: 32rpx;
+    top: 25rpx;
+}
+.mItem > image {
+    width: 100rpx;
+    height: 100rpx;
+    border-radius: 50%;
+    margin-right: 25rpx;
+}
+
+.mInfo {
+    flex: 1;
+    height: 110rpx;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+}
+
+.info1 {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding-right: 36rpx;
+}
+
+.info1 > view:nth-child(1) {
+    font-size: 30rpx;
+    font-weight: 700;
+    color: #fff;
+}
+.fz24 {
+    font-size: 24rpx;
+    margin-left: 30rpx;
+}
+
+.info1 > view:nth-child(2) {
+    color: #1479ff;
+    font-size: 34rpx;
+}
+
+.info2 {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 26rpx;
+}
+
+.info2 > view:nth-child(1) {
+    color: #fff;
+    font-size: 36rpx;
+    font-weight: 700;
+}
+
+.fb {
+    height: 80rpx;
+    width: 100%;
+    position: fixed;
+    bottom: 48rpx;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.addAddress {
+    width: 670rpx;
+    height: 80rpx;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    background: linear-gradient(to right,#F8A52B,#F8C657);
+    border-radius: 50rpx;
+}
+
+.addAddress > view {
+    color: #fff;
+    font-size: 30rpx;
+}
+.addAddress > image {
+    width: 30rpx;
+    margin-right: 14rpx;
+}
+
+.bg1 {
+    background: #dd3b42;
+}
+.bg2 {
+    background: #018468;
+}
+
+.bg3 {
+    background: #0c3f9d;
+}
+
+</style>

+ 318 - 0
pages/Withdrawal/index.vue

@@ -0,0 +1,318 @@
+<template>
+	<block>
+		<view class="content">
+			<view class="cashInfo">
+				<view class="cTitle">提现金额</view>
+
+				<view class="cPrice" style="font-size: 24rpx;">
+					<view>
+						可提现金额
+						<text class="cWeight">{{ info.money }}</text>
+						元
+					</view>
+					<view @tap="cashAll">全部提现</view>
+				</view>
+			</view>
+
+			<view class="cInput">
+				<view>¥</view>
+				<input type="number" @input="cashinput" placeholder="请输入提现金额" placeholder-class="placeClass"
+					:value="cashmoney" />
+			</view>
+
+<!-- 			<view class="cItem">
+				<view class="cTip">
+					<view>税收(6%):</view>
+					<view>*平台代缴纳</view>
+				</view>
+				<view class="cNum">¥{{lessMoney}}</view>
+			</view>
+
+
+
+
+			<view class="cItem">
+				<view class="cTip">
+					<view>实际到账:</view>
+				</view>
+				<view class="cNum">¥{{realMoney}}</view>
+			</view> -->
+
+			<view class="cItem">
+				<view class="cTip">
+					<view>到账银行卡:</view>
+				</view>
+				<picker v-if="banklist.length" mode="selector" @change="bindBankConfirm" range-key="showtitle"
+					:value="bankindex" :range="banklist">
+					<view class="cNum fweigh">{{ bankTitle ? bankTitle : '请选择提现银行卡' }}</view>
+				</picker>
+
+				<view class="cNum fweigh" v-else @tap="toPage" data-url="/pages/Withdrawal/addbank" :data-type="type">
+					{{ bankTitle ? bankTitle : '请先添加银行卡' }}</view>
+
+				<image v-if="banklist.length"
+					src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/3c95e397fd285160c474c52ed2e3e4d1.png"
+					mode="widthFix" class="leftArrow"></image>
+			</view>
+		</view>
+
+		<view class="btn" @tap="confirm">立即提现</view>
+	</block>
+</template>
+
+<script>
+	var app = getApp(); // a = app.requirejs('core');
+
+	var loading = false;
+
+	export default {
+		data() {
+			return {
+
+
+				info: {
+					money: ''
+				},
+
+				cashmoney: '',
+				banklist: [],
+				bankindex: 0,
+				bankTitle: '',
+				name: '',
+				lessMoney:0,
+				realMoney:0
+				
+			};
+		},
+		onLoad: function(e) {},
+		onShow() {
+			this.getinfo();
+			this.getbank();
+		},
+		onPullDownRefresh: function() {},
+		onReachBottom: function() {},
+		methods: {
+			async confirm() {
+				var that = this;
+
+				if (!this.cashmoney) {
+					uni.showToast({
+						title: '请先填写提现金额',
+						icon: 'none'
+					});
+					return false;
+				}
+
+				if (!this.bankTitle) {
+					uni.showToast({
+						title: '请先选择银行卡',
+						icon: 'none'
+					});
+					return false;
+				}
+				
+				
+				let result = await this.$api.request('/withdraw/add', 'POST', {money:that.cashmoney,bid:that.banklist[that.bankindex].id});
+				console.log(result)
+				if (result) {
+						this.$api.msg('添加成功');
+						uni.redirectTo({
+							url:'/pages/wallet/index'
+						})
+						
+				}
+
+			
+			},
+
+			bindBankConfirm(e) {
+				console.log(e);
+
+				this.bankindex = e.detail.value,
+					this.bankTitle = this.banklist[e.detail.value].showtitle
+
+			},
+
+			async getbank() {
+				var that = this;
+				let res = await this.$api.request('/bank/index', 'GET', {
+					page: 1,
+					pagesize: 20
+				});
+
+				console.log(res)
+				if (res) {
+					if (res.length > 0) {
+
+
+						res.map(function(item) {
+							return item.showtitle = item.bank + '(' + item.card.substr(item.card.length - 4) +
+								')'
+						})
+
+						this.banklist = this.banklist.concat(res);
+
+						this.page++;
+
+					} else {
+						this.loaded = true
+						this.$api.msg('没有更多数据');
+					}
+				}
+
+			},
+
+			toPage(e) {
+				app.globalData.toPage(e);
+			},
+
+			cashAll() {
+
+				this.cashmoney = this.info.money
+
+			},
+
+			cashinput(e) {
+
+				this.cashmoney = e.detail.value
+
+			},
+
+			async getinfo() {
+
+				let data = await this.$api.request('/wallet/index');
+
+
+				console.log(data)
+
+				this.info = data;
+
+
+
+
+			},
+
+		}
+	};
+</script>
+<style>
+	page {
+		background: #f4f5f9;
+	}
+
+	.content {
+		padding: 36rpx 44rpx 0;
+		background: #fff;
+	}
+
+	.cashInfo {
+		display: flex;
+		align-items: center;
+		padding-bottom: 60rpx;
+		justify-content: space-between;
+	}
+
+	.cTitle {
+		font-size: 28rpx;
+		font-weight: 700;
+	}
+
+	.cPrice {
+		display: flex;
+		align-items: center;
+	}
+
+	.cPrice>view:nth-child(2) {
+		color: #253f8e;
+		margin-left: 30rpx;
+	}
+
+	.cWeight {
+		font-weight: 700;
+		font-size: 30rpx;
+	}
+
+	.cInput {
+		display: flex;
+		align-items: center;
+		padding-bottom: 30rpx;
+		border-bottom: 1px solid #e4e5ee;
+	}
+
+	.cInput>view {
+		font-size: 54rpx;
+		color: #011b33;
+		font-weight: 700;
+	}
+
+	.cInput>input {
+		font-size: 54rpx;
+		color: #011b33;
+		font-weight: 700;
+	}
+
+	.placeClass {
+		font-size: 35rpx;
+		font-weight: 500;
+		padding-left: 40rpx;
+	}
+
+	.cItem {
+		padding: 30rpx 0;
+		border-bottom: 1px solid #e4e5ee;
+		display: flex;
+		align-items: center;
+		position: relative;
+	}
+
+	.cItem:last-child {
+		border-bottom: none;
+	}
+
+	.cTip>view:nth-child(1) {
+		font-size: 28rpx;
+	}
+
+	.cTip>view:nth-child(2) {
+		margin-top: 8rpx;
+		color: #ff4c34;
+		font-size: 22rpx;
+	}
+
+	.cNum {
+		margin-left: 40rpx;
+		font-size: 36rpx;
+	}
+
+	.fweigh {
+		font-size: 28rpx;
+		font-weight: 700;
+	}
+
+	.leftArrow {
+		position: absolute;
+		right: 0;
+		width: 14rpx;
+	}
+
+	.btn {
+		width: 614rpx;
+		height: 88rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		background: linear-gradient(to right, #F8A52B, #F8C657);
+		color: #fff;
+		font-size: 30rpx;
+		border-radius: 40rpx;
+		margin: 72rpx auto;
+	}
+
+	picker {
+		flex: 1;
+	}
+
+	view {
+		font-size: 24rpx;
+	}
+</style>

+ 180 - 0
pages/address/address.vue

@@ -0,0 +1,180 @@
+<template>
+	<view class="content b-t">
+		<view class="list b-b" v-for="(item, index) in addressList" :key="index" @click="checkAddress(item)">
+			<view class="wrapper">
+				<view class="address-box">
+					<text v-if="item.is_default" class="tag">默认</text>
+					<text class="address">{{item.province.name+item.city.name+item.area.name+' '+item.address}}</text>
+				</view>
+				<view class="u-box">
+					<text class="name">{{item.name}}</text>
+					<text class="mobile">{{item.mobile}}</text>
+				</view>
+			</view>
+			<text class="yticon icon-bianji" @click.stop="addAddress('edit', item.id)"></text>
+
+			<text class="yticon icon-lajitong" @click.stop="deleteAddress(item.id,index)"></text>
+		</view>
+
+		<button class="add-btn" @click="addAddress('add')">新增地址</button>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				source: 0,
+				addressList: []
+			}
+		},
+		onLoad(option) {
+			console.log(option.source);
+			this.source = option.source;
+		},
+		onShow() {
+			this.getList();
+		},
+		methods: {
+			//获取我的收货地址
+			async getList() {
+				let list = await this.$api.request('/address/all', 'POST', {
+					page: 1,
+					pagesize: 50
+				});
+				if (list) {
+					this.addressList = list;
+				}
+			},
+			//选择地址
+			checkAddress(item) {
+				if (this.source == 1) {
+					//this.$api.prePage()获取上一页实例,在App.vue定义
+					this.$api.prePage().addressData = item;
+					uni.navigateBack()
+				}
+			},
+			addAddress(type, id = 0) {
+				uni.navigateTo({
+					url: `/pages/address/addressManage?type=${type}&id=${id}`
+				})
+			},
+			//添加或修改成功之后回调
+			refreshList(data, type) {
+				//添加或修改后事件,这里直接在最前面添加了一条数据,实际应用中直接刷新地址列表即可
+				this.addressList.unshift(data);
+
+				console.log(data, type);
+			},
+			async deleteAddress(id, index) {
+				let [error, res] = await uni.showModal({
+					title: '确定删除地址?',
+					content: this.addressList[index].address
+				})
+
+				if (res.confirm) {
+					let data = await this.$api.request('/address/delete?id=' + id);
+					if (data) {
+						if (this.$api.prePage().addressData && this.$api.prePage().addressData.id) {
+							if (this.$api.prePage().addressData.id == this.addressList[index].id) {
+								this.$api.prePage().addressData = {};
+							}
+						}
+						
+						this.addressList.splice(index, 1);
+					}
+				}
+
+			}
+		}
+	}
+</script>
+
+<style lang='scss'>
+	page {
+		padding-bottom: 120upx;
+	}
+
+	.content {
+		position: relative;
+	}
+
+	.list {
+		display: flex;
+		align-items: center;
+		padding: 20upx 30upx;
+		;
+		background: #fff;
+		position: relative;
+	}
+
+	.wrapper {
+		display: flex;
+		flex-direction: column;
+		flex: 1;
+	}
+
+	.address-box {
+		display: flex;
+		align-items: center;
+
+		.tag {
+			font-size: 24upx;
+			color: $base-color;
+			margin-right: 10upx;
+			background: #fffafb;
+			border: 1px solid #ffb4c7;
+			border-radius: 4upx;
+			padding: 4upx 10upx;
+			line-height: 1;
+		}
+
+		.address {
+			font-size: 30upx;
+			color: $font-color-dark;
+		}
+	}
+
+	.u-box {
+		font-size: 28upx;
+		color: $font-color-light;
+		margin-top: 16upx;
+
+		.name {
+			margin-right: 30upx;
+		}
+	}
+
+	.icon-bianji {
+		display: flex;
+		align-items: center;
+		height: 80upx;
+		font-size: 40upx;
+		color: $font-color-light;
+		padding-left: 30upx;
+	}
+
+	.icon-lajitong {
+		color: $font-color-light;
+		padding-left: 25rpx;
+	}
+
+
+	.add-btn {
+		position: fixed;
+		left: 30upx;
+		right: 30upx;
+		bottom: 16upx;
+		z-index: 95;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		width: 690upx;
+		height: 80upx;
+		font-size: 32upx;
+		color: #fff;
+		background-color: $base-color;
+		border-radius: 10upx;
+		box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
+	}
+</style>

+ 203 - 0
pages/address/addressManage.vue

@@ -0,0 +1,203 @@
+<template>
+	<view class="content">
+		<view class="row b-b">
+			<text class="tit">联系人</text>
+			<input class="input" type="text" v-model="addressData.name" placeholder="收货人姓名" placeholder-class="placeholder" />
+		</view>
+		<view class="row b-b">
+			<text class="tit">手机号</text>
+			<input class="input" type="number" v-model="addressData.mobile" placeholder="收货人手机号码" placeholder-class="placeholder" />
+		</view>
+		<view class="row b-b" v-on:click="showCityPicker()">
+			<text class="tit">地区</text>
+			<view class="input">
+				{{cityLebel}}
+			</view>
+		</view>
+		<view class="row b-b">
+			<text class="tit">详细</text>
+			<input class="input" type="text" v-model="addressData.address" placeholder="详细地址,楼号" placeholder-class="placeholder" />
+		</view>
+
+		<view class="row default-row">
+			<text class="tit">设为默认</text>
+			<switch :checked="addressData.is_default" color="#fa436a" @change="switchChange" />
+		</view>
+		<button class="add-btn" @click="confirm">提交</button>
+		
+		<mpvue-city-picker @onChange="onChange" @onCancel="onCancel"
+		 @onConfirm="onConfirm" ref="mpvueCityPicker" ></mpvue-city-picker>
+	</view>
+</template>
+
+<script>
+	import mpvueCityPicker from '@/components/mpvueCityPicker.vue';
+	export default {
+		components: {
+			mpvueCityPicker
+		},
+		data() {
+			return {
+				addressData: {
+					name: '',
+					mobile: '',
+					address: '',
+					province_id: 0,
+					city_id: 0,
+					area_id: 0,
+					is_default: false
+				},
+				pickerValueDefault: [0, 0, 0] ,//城市选择器默认值 省市区id
+				cityLebel:'请选择地区',
+			}
+		},
+		onLoad(option) {
+			let title = '新增收货地址';
+			if (option.type === 'edit') {
+				
+				this.getInfo(option.id);
+				
+				title = '编辑收货地址'
+			} else {
+
+				this.$refs.mpvueCityPicker.creat(this.pickerValueDefault);
+			}
+			this.manageType = option.type;
+			uni.setNavigationBarTitle({ 
+				title
+			})
+		},
+		methods: {
+			// 获取地址详情
+			async getInfo(id){
+				let addressData = await this.$api.request(`/address/info?id=${id}`);
+				if (addressData) {
+					console.log(addressData);
+					
+					this.addressData = addressData;
+					let pickerValueDefault = [];
+					pickerValueDefault.push(addressData.province_id);
+					pickerValueDefault.push(addressData.city_id);
+					pickerValueDefault.push(addressData.area_id);
+					this.pickerValueDefault = pickerValueDefault;
+					
+					this.$refs.mpvueCityPicker.creat(pickerValueDefault);
+				}
+			},
+			// 城市选择器
+			showCityPicker() {
+				this.$refs.mpvueCityPicker.show();
+			},
+			// 城市选择器改变值
+			onChange(e) {
+				// console.log('选择的值')
+				// console.log(e);
+			},
+			// 城市选择器关闭
+			onCancel(e) {
+				//console.log(e);
+			},
+			// 城市选择器确定
+			onConfirm(e) {
+				//console.log(e);
+				this.cityLebel = e.label;
+				this.pickerValueDefault = e.value;
+				
+				this.addressData.province_id = this.pickerValueDefault[0];
+				this.addressData.city_id = this.pickerValueDefault[1];
+				this.addressData.area_id = this.pickerValueDefault[2];
+			},
+			//默认地址
+			switchChange(e) {
+				this.addressData.is_default = e.detail.value;
+			},
+			//提交
+			async confirm() {
+				//Deep Clone
+				let data = JSON.parse(JSON.stringify(this.addressData));
+				if (!data.name) {
+					this.$api.msg('请填写收货人姓名');
+					return;
+				}
+				if (!/(^1[3|4|5|7|8][0-9]{9}$)/.test(data.mobile)) {
+					this.$api.msg('请输入正确的手机号码');
+					return;
+				}
+				if (!data.address) {
+					this.$api.msg('请填详细地址信息');
+					return;
+				}
+				console.log(data.is_default);
+				data.is_default = data.is_default == true ? 1 : 0;
+				let action = this.manageType == 'edit' ? 'edit' : 'add';
+				let result = await this.$api.request('/address/' + action, 'POST', data);
+				if (result) {
+					this.$api.prePage().refreshList(data, this.manageType);
+					setTimeout(() => {
+						uni.navigateBack()
+					}, 800)
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: $page-color-base;
+		padding-top: 16upx;
+	}
+
+	.row {
+		display: flex;
+		align-items: center;
+		position: relative;
+		padding: 0 30upx;
+		height: 110upx;
+		background: #fff;
+
+		.tit {
+			flex-shrink: 0;
+			width: 120upx;
+			font-size: 30upx;
+			color: $font-color-dark;
+		}
+
+		.input {
+			flex: 1;
+			font-size: 30upx;
+			color: $font-color-dark;
+		}
+
+		.icon-shouhuodizhi {
+			font-size: 36upx;
+			color: $font-color-light;
+		}
+	}
+
+	.default-row {
+		margin-top: 16upx;
+
+		.tit {
+			flex: 1;
+		}
+
+		switch {
+			transform: translateX(16upx) scale(.9);
+		}
+	}
+
+	.add-btn {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		width: 690upx;
+		height: 80upx;
+		margin: 60upx auto;
+		font-size: $font-lg;
+		color: #fff;
+		background-color: $base-color;
+		border-radius: 10upx;
+		box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
+	}
+</style>

+ 60 - 0
pages/article/detail.vue

@@ -0,0 +1,60 @@
+<template>
+	<block>
+		
+			<rich-text :nodes="content.content"></rich-text>
+
+	</block>
+</template>
+
+<script>
+	// pages/tabbar/index/index.js
+	var app = getApp();
+
+	export default {
+		data() {
+			return {
+					content:""
+			};
+		},
+		onLoad: function(options) {
+				this.id = options.id;
+				this.getinfo()
+		},
+
+		onShow() {
+	
+
+		},
+		onPullDownRefresh: function() {},
+		onReachBottom: function() {
+
+		},
+		onShareAppMessage: function() {},
+		methods: {
+		
+			async getinfo() {
+				var that = this;
+				let res = await this.$api.request('/article/detail', 'GET', {
+			 	id: this.id,
+			
+			 });
+			 
+				res.content = res.content.replace(/\<img/gi, '<img style="max-width:100%;height:auto;display:block;"');
+			
+			this.content = res
+
+			}
+		}
+	};
+</script>
+<style>
+	page {
+		background: #F5F5F5;
+		padding: 20rpx;
+		box-sizing: border-box;
+	}
+
+
+
+	
+</style>

+ 139 - 0
pages/article/index.vue

@@ -0,0 +1,139 @@
+<template>
+	<block>
+		<view class="item" v-for="(item,index) in list" :key='index' @tap="toPage" :data-id='item.id' data-url='/pages/article/detail'>
+			<image :src="item.image" mode=""></image>
+			<view class="">
+				八十一坊标题文字描述文案内容标题文字描述
+				文案内容
+			</view>
+		</view>
+
+
+	</block>
+</template>
+<script module="parse" lang="wxs">
+	module.exports = {
+
+		filterNum: function(value) {
+
+
+			var value = value + ''
+
+			console.log(value)
+
+
+			var card = value.replace(getRegExp('(/^(\d{4})\d+(\d{4})$/)', 'g'), '$1 **** **** $2')
+
+			return card
+
+
+		}
+
+
+	}
+</script>
+<script>
+	// pages/tabbar/index/index.js
+	var app = getApp();
+
+	export default {
+		data() {
+			return {
+				navIndex: 0,
+				list: [
+					// {
+					// 	account: "hhD",
+					// 	bank_name: "农业银行",
+					// 	card_no: "6228481561378773113",
+					// 	card_no_end: "3113",
+					// 	create_time: "1659088920",
+					// 	id: "7",
+					// 	is_default: "0",
+					// 	status: "1",
+					// 	uniacid: "3",
+					// 	update_time: "1659088920",
+					// 	user_id: "1"
+					// }
+				],
+				loaded: false,
+				page: 1,
+				type: '',
+				pageSize: 10
+			};
+		},
+		onLoad: function(options) {
+
+		},
+
+		onShow() {
+			this.init()
+			this.getlist();
+		},
+		onPullDownRefresh: function() {},
+		onReachBottom: function() {
+			this.loaded || this.getlist();
+		},
+		onShareAppMessage: function() {},
+		methods: {
+			toPage(e) {
+				app.globalData.toPage(e);
+			},
+
+			init() {
+
+				this.page = 1
+				this.loaded = false
+				this.list = []
+
+			},
+
+			async getlist() {
+				var that = this;
+				let res = await this.$api.request('/article/index', 'GET', {
+			 	page: this.page,
+				pagesize: this.pageSize
+			 });
+
+				console.log(res)
+				if (res) {
+					if (res.length > 0) {
+
+						this.list = this.list.concat(res);
+
+						this.page++;
+
+					} else {
+						this.loaded = true
+						this.$api.msg('没有更多数据');
+					}
+				}
+			}
+		}
+	};
+</script>
+<style>
+	page {
+		background: #F5F5F5;
+	}
+
+
+	.item {
+		background: #fff;
+		border-radius: 12rpx;
+		overflow: hidden;
+		margin: 30rpx;
+	}
+	
+	.item>view{
+		width: 100%;
+		padding: 30rpx 30rpx 50rpx 30rpx;
+		font-size: 34rpx;
+		color: #010101;
+	}
+	
+	.item>image{
+		width: 100%;
+		height: 400rpx;
+	}
+	
+</style>

+ 516 - 0
pages/cart/cart.vue

@@ -0,0 +1,516 @@
+<template>
+	<view class="container">
+		<!-- 空白页 -->
+		<view v-if="(!userInfo.group || empty===true) && state != 'load'" class="empty">
+			<image src="/static/emptyCart.jpg" mode="aspectFit"></image>
+			<view v-if="userInfo.group" class="empty-tips">
+				空空如也
+				<navigator class="navigator" url="../index/index" open-type="switchTab">随便逛逛></navigator>
+			</view>
+			<view v-else>
+				<view class="get-user-info-text">您还没有购物车,你可以提供您的微信资料初始化购物车!</view>
+				<button class="get-user-info" @click="getUserInfo">提供资料初始化购物车</button>
+			</view>
+		</view>
+		<view v-else>
+			<!-- 列表 -->
+			<view class="cart-list">
+				<block v-for="(item, index) in cartList" :key="item.id">
+					<view class="cart-item" :class="{'b-b': index!==cartList.length-1}" :style="{'background':item.isset?'':'#f5f5f5'}" 
+						@click="navTo(`/pages/product/product?id=${item.product_id}&flash=0`)"
+					>
+						<view class="image-wrapper">
+							<image :src="item.image" class="loaded" mode="aspectFill"></image>
+							<view v-if="item.isset == true" class="yticon icon-xuanzhong checkbox" :class="{checked: item.choose}" @click.stop="check('item', index)"></view>
+						</view>
+						<view class="item-right">
+							<text class="clamp title">{{item.title}}</text>
+							<text class="attr" v-if="item.spec">{{item.spec}}</text>
+							<text class="price">¥{{item.nowPrice}} <text style="color:red"> {{cartPrice(item.oldPrice, item.nowPrice)}}</text></text>
+							<uni-number-box class="step" :min="1" :max="item.stock" :disabled="item.number>=item.stock" :value="cartList[index].number"
+							 :isMax="item.number>=item.stock?true:false" :isMin="item.number===1" :index="index" @eventChange="numberChange"></uni-number-box>
+						</view>
+						<text class="del-btn yticon icon-lajitong" @click.stop="deleteCartItem(index)"></text>
+						<text class="invalid" v-if="item.isset == false">失效</text>
+						<text class="invalid" v-if="item.stock == 0 && item.isset == true">库存不足</text>
+					</view>
+				</block>
+			</view>
+			<!-- 底部菜单栏 -->
+			<view class="action-section" v-if="state != 'load'">
+				<view class="checkbox">
+					<image :src="allChoose?'/static/selected.png':'/static/select.png'" mode="aspectFit" @click="check('all')"></image>
+					<view class="clear-btn" :class="{show: allChoose}" @click="clearCart">
+						清空
+					</view>
+				</view>
+				<view class="total-box">
+					<text class="price">¥{{total}}</text>
+				</view>
+				<button type="primary" class="no-border confirm-btn" @click="createOrder">去结算</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		mapMutations,
+	    mapState 
+	} from 'vuex';
+	import uniNumberBox from '@/components/uni-number-box.vue'
+	export default {
+		components: {
+			uniNumberBox
+		},
+		data() {
+			return {
+				total: 0, //总价格
+				allChoose: false, //全选状态  true|false
+				empty: false, //空白页现实  true|false
+				cartList: [],
+				state : 'load',
+				userInfo: uni.getStorageSync('userInfo')
+			};
+		},
+		onLoad() {
+			
+		},
+		onPullDownRefresh() {
+			this.state = 'load';
+			this.cartList = [];
+			this.getCart();
+		},
+		onShow() {
+			this.state = 'load';
+			this.cartList = [];
+			this.getCart();
+		},
+		watch: {
+			//显示空白页
+			cartList(e) {
+				let empty = e.length === 0 ? true : false;
+				if (this.empty !== empty) {
+					this.empty = empty;
+				}
+			}
+		},
+		computed: {
+			...mapState(['hasLogin'])
+		},
+		methods: {
+			...mapMutations(['login', 'logout', 'setUserInfo']),
+			async getCart() {
+				let data = await this.$api.request('/cart');
+				await this.$api.checkLogin();
+				this.userInfo = uni.getStorageSync('userInfo');
+				uni.stopPullDownRefresh();
+				this.state = 'loaded';
+				if (data){
+					this.cartList = data;
+					this.calcTotal();
+				}
+			},
+			cartPrice(oldPrice, nowPrice) {
+				let string = '';
+				if (oldPrice < nowPrice) {
+					let number = (nowPrice - oldPrice).toFixed(2);
+					string = ' ↑涨价 ' + number + '元';
+				} else if (oldPrice > nowPrice) {
+					let number = (oldPrice - nowPrice).toFixed(2);
+					string = ' ↓降价 ' + number + '元';
+				}
+				return string;
+			},
+			navToLogin() {
+				uni.navigateTo({
+					url: '/pages/public/login'
+				})
+			},
+			//选中状态处理
+			async check(type, index) {
+				
+				let trueArr = [];
+				let falseArr = [];
+				let oldChoose = [];
+				const list = this.cartList;
+				//保存旧的数据
+				list.forEach(item => {
+					if(item.choose){
+						oldChoose.push(item.cart_id);
+					}
+				})
+				
+				//本地处理
+				if (type === 'item') {
+					this.cartList[index].choose = !this.cartList[index].choose;
+					if (this.cartList[index].choose) {
+						trueArr.push(this.cartList[index].cart_id);
+					} else {
+						falseArr.push(this.cartList[index].cart_id);
+					}
+				} else {
+					const choose = !this.allChoose
+					list.forEach(item => {
+						item.choose = choose;
+						if (item.isset) {
+							if (choose) {
+								trueArr.push(item.cart_id);
+							} else {
+								falseArr.push(item.cart_id);
+							}
+						}
+					})
+					this.allChoose = choose;
+				}
+				this.calcTotal(type);
+				
+				//远程处理
+				let result = await this.$api.request('/cart/choose_change', 'POST', {trueArr,falseArr});
+				if (!result) {
+					//恢复原来勾选的状态
+					list.forEach(item => {
+						if (oldChoose.indexOf(item.cart_id) >= 0) {
+							item.choose = 1;
+						} else {
+							item.choose = 0;
+						}
+					})
+					this.calcTotal(type);
+				}
+				
+			},
+			//数量
+			async numberChange(data) {
+				let oldNumber = this.cartList[data.index].number;
+				let newNumber = data.number;
+				this.cartList[data.index].number = newNumber;
+				this.calcTotal();
+				
+				let cart_id = this.cartList[data.index].cart_id;
+				let result = await this.$api.request('/cart/number_change?id='+cart_id, 'GET', {number:newNumber}, false);
+				if (!result) {
+					this.cartList[data.index].number = oldNumber;
+					this.calcTotal();
+				}
+				
+			},
+			//删除
+			async deleteCartItem(index) {
+				let list = this.cartList;
+				let row = list[index];
+				let id = row.cart_id;
+								
+				uni.showModal({
+					content: '确认删除 ' + list[index].title + '?' ,
+					success: async (e) => {
+						if (e.confirm) {
+							let result = await this.$api.request('/cart/delete?', 'POST', {id:id});
+							if (result) {
+								let tempCart = this.cartList.splice(index, 1);
+								this.calcTotal();
+							}
+						}
+					}
+				})
+
+			},
+			//清空
+			async clearCart() {
+				let [error, res] = await uni.showModal({
+					title: '确认清空?'
+				});
+				if (res.confirm) {
+					let id = [];
+					this.cartList.forEach(item=>{
+						id.push(item.cart_id);
+					});
+					let data = this.$api.request('/cart/delete', 'POST',{id:id});
+					let that = this;
+					if (data) {
+						setTimeout(function(){
+							that.state = 'load';
+							that.cartList = [];
+							that.getCart();
+						},300);
+					}
+				}
+			},
+			//计算总价
+			calcTotal() {
+				let list = this.cartList;
+				if (list.length === 0) {
+					this.empty = true;
+					return;
+				}
+				let total = 0;
+				let choose = true;
+				list.forEach(item => {
+					if (item.isset) {
+						if (item.choose == 1) {
+							total += item.nowPrice * item.number;
+						} else if (choose === true) {
+							choose = false;
+						}
+					}
+				})
+				this.allChoose = choose;
+				this.total = total.toFixed(2);
+			},
+			async getUserInfo() {
+				uni.getUserProfile({
+					desc: '系统将获取你的用户信息',
+					success: async (res) => {
+						let [error, loginRes] = await uni.login({
+							provider: 'weixin'
+						});
+						if (loginRes.hasOwnProperty('code')) {
+							let data = await this.$api.request('/user/registerUserGroup?code=' + loginRes.code, 'POST', res.userInfo);
+							const userInfo = await this.$wechatMiniLogin(true);
+							this.login(userInfo)
+							this.userInfo = userInfo
+						}
+					},
+					fail: (res) => {
+						this.$api.msg('注册失败')
+					}
+				})
+			},
+			//创建订单
+			createOrder() {
+				let list = this.cartList;
+				let cartId = [];
+				list.forEach(item => {
+					if (item.choose) {
+						cartId.push(item.cart_id);
+					}
+				})
+				if (cartId.length == 0) {
+					this.$api.msg('没有选中商品');
+					return;
+				}
+				this.$api.navTo(`/pages/order/createOrder?cart=${cartId.join(',')}`);
+			},
+			navTo(url){
+				this.$api.navTo(url);
+			}
+		}
+	}
+</script>
+
+<style lang='scss'>
+	.container {
+		padding-bottom: 134upx;
+		
+		/* 空白页 */
+		.empty {
+			position: fixed;
+			left: 0;
+			top: 0;
+			width: 100%;
+			height: 100vh;
+			padding-bottom: 100upx;
+			display: flex;
+			justify-content: center;
+			flex-direction: column;
+			align-items: center;
+			background: #fff;
+
+			image {
+				width: 240upx;
+				height: 160upx;
+				margin-bottom: 30upx;
+			}
+
+			.empty-tips {
+				display: flex;
+				font-size: $font-sm+2upx;
+				color: $font-color-disabled;
+
+				.navigator {
+					color: $uni-color-primary;
+					margin-left: 16upx;
+				}
+			}
+		}
+	}
+
+	/* 购物车列表项 */
+	.cart-item {
+		display: flex;
+		position: relative;
+		padding: 30upx 40upx;
+
+		.image-wrapper {
+			width: 230upx;
+			height: 230upx;
+			flex-shrink: 0;
+			position: relative;
+
+			image {
+				border-radius: 8upx;
+			}
+		}
+
+		.checkbox {
+			position: absolute;
+			left: -16upx;
+			top: -16upx;
+			z-index: 8;
+			font-size: 44upx;
+			line-height: 1;
+			padding: 4upx;
+			color: $font-color-disabled;
+			background: #fff;
+			border-radius: 50px;
+		}
+
+		.item-right {
+			display: flex;
+			flex-direction: column;
+			flex: 1;
+			overflow: hidden;
+			position: relative;
+			padding-left: 30upx;
+
+			.title,
+			.price {
+				font-size: $font-base + 2upx;
+				color: $font-color-dark;
+				height: 40upx;
+				line-height: 40upx;
+			}
+
+			.attr {
+				font-size: $font-sm + 2upx;
+				color: $font-color-light;
+				height: 50upx;
+				line-height: 50upx;
+			}
+
+			.price {
+				height: 50upx;
+				line-height: 50upx;
+			}
+		}
+
+		.del-btn {
+			padding: 4upx 10upx;
+			font-size: 34upx;
+			height: 50upx;
+			color: $font-color-light;
+		}
+
+		.invalid {
+			position: absolute;
+			right: 0;
+			bottom: 0;
+			background: #999999;
+			color: #ffffff;
+			padding: 6upx 12upx;
+			border-radius: 10upx;
+			font-size: 26upx;
+			margin-right: 50upx;
+			margin-bottom: 32upx;
+		}
+	}
+
+	/* 底部栏 */
+	.action-section {
+		/* #ifdef H5 */
+		margin-bottom: 100upx;
+		/* #endif */
+		position: fixed;
+		left: 30upx;
+		bottom: 30upx;
+		z-index: 95;
+		display: flex;
+		align-items: center;
+		width: 690upx;
+		height: 100upx;
+		padding: 0 30upx;
+		background: rgba(255, 255, 255, .9);
+		box-shadow: 0 0 20upx 0 rgba(0, 0, 0, .5);
+		border-radius: 16upx;
+
+		.checkbox {
+			height: 52upx;
+			position: relative;
+
+			image {
+				width: 52upx;
+				height: 100%;
+				position: relative;
+				z-index: 5;
+			}
+		}
+
+		.clear-btn {
+			position: absolute;
+			left: 26upx;
+			top: 0;
+			z-index: 4;
+			width: 0;
+			height: 52upx;
+			line-height: 52upx;
+			padding-left: 38upx;
+			font-size: $font-base;
+			color: #fff;
+			background: $font-color-disabled;
+			border-radius: 0 50px 50px 0;
+			opacity: 0;
+			transition: .2s;
+
+			&.show {
+				opacity: 1;
+				width: 120upx;
+			}
+		}
+
+		.total-box {
+			flex: 1;
+			display: flex;
+			flex-direction: column;
+			text-align: right;
+			padding-right: 40upx;
+
+			.price {
+				font-size: $font-lg;
+				color: $font-color-dark;
+			}
+
+		}
+
+		.confirm-btn {
+			padding: 0 38upx;
+			margin: 0;
+			border-radius: 100px;
+			height: 76upx;
+			line-height: 76upx;
+			font-size: $font-base + 2upx;
+			background: $uni-color-primary;
+			box-shadow: 1px 2px 5px rgba(217, 60, 93, 0.72)
+		}
+	}
+
+	/* 复选框选中状态 */
+	.action-section .checkbox.checked,
+	.cart-item .checkbox.checked {
+		color: $uni-color-primary;
+	}
+	
+	button.get-user-info {
+		margin: 0px auto;
+		width: 280rpx;
+		height: 60rpx;
+		line-height: 60rpx;
+		font-size: 14px;
+	}
+	
+	.get-user-info-text {
+		padding: 20px 80px;
+		font-size: 16px;
+		text-align: center;
+		line-height: 32px;
+	}
+</style>

+ 199 - 0
pages/category/category.vue

@@ -0,0 +1,199 @@
+<template>
+	<view class="content">
+		<scroll-view scroll-y class="left-aside">
+			<view v-for="item in flist" :key="item.id" class="f-item b-b" :class="{active: item.id === currentId}" @click="tabtap(item)">
+				{{item.name}}
+			</view>
+		</scroll-view>
+		<scroll-view scroll-with-animation scroll-y class="right-aside" @scroll="asideScroll" :scroll-top="tabScrollTop">
+			<view v-for="item in flist" :key="item.id" class="s-list" :id="'main-'+item.id">
+				<text class="s-item">{{item.name}}</text>
+				<view class="t-list">
+					<view @click="navToList(item.id, sitem.id)" v-if="sitem.pid === item.id" class="t-item" v-for="sitem in slist" :key="sitem.id">
+						<image :src="sitem.image"></image>
+						<text>{{sitem.name}}</text>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+
+	export default {
+		data() {
+			return {
+				sizeCalcState: false,
+				tabScrollTop: 0,
+				currentId: 0,
+				flist: [],
+				slist: [],
+			}
+		},
+		computed: {
+
+		},
+		onShareAppMessage(e){
+			
+		},
+		onLoad(){
+			this.loadData();
+		},
+		methods: {
+			async loadData(){
+				var that = this;
+				//let list = await this.$api.json('cateList');
+				let list = await this.$api.request('/category/all');
+				if (list) {
+					uni.stopPullDownRefresh();
+					list.forEach(item=>{
+						if(item.pid == 0){
+							if (that.currentId == 0) {
+								that.currentId = item.id;
+							}
+							this.flist.push(item);  //pid为父级id, 没有pid或者pid=0是一级分类
+						}else {
+							this.slist.push(item); //没有图的是2级分类
+						}
+					})
+					
+				}
+				
+			},
+			//一级分类点击
+			tabtap(item){
+				if(!this.sizeCalcState){
+					this.calcSize();
+				}
+				
+				this.currentId = item.id;
+				let index = this.flist.findIndex(fitem=>fitem.id === item.id);
+				this.tabScrollTop = this.flist[index].top;
+			},
+			//右侧栏滚动
+			asideScroll(e){
+				if(!this.sizeCalcState){
+					this.calcSize();
+				}
+				let scrollTop = e.detail.scrollTop;
+				let tabs = this.flist.filter(item=>item.top <= scrollTop).reverse();
+				if(tabs.length > 0){
+					this.currentId = tabs[0].id;
+				}
+			},
+			//计算右侧栏每个tab的高度等信息
+			calcSize(){
+				let h = 0;
+				this.flist.forEach(item=>{
+					let view = uni.createSelectorQuery().select("#main-" + item.id);
+					view.fields({
+						size: true
+					}, data => {
+						item.top = h;
+						h += data.height;
+						item.bottom = h;
+					}).exec();
+				})
+				this.sizeCalcState = true;
+			},
+			navToList(fid, sid) {
+				uni.navigateTo({
+					url: `/pages/product/list?fid=${fid}&sid=${sid}`
+				});
+			}
+		},
+		onPullDownRefresh() {
+			this.flist = [];
+			this.slist = [];
+			this.sizeCalcState = false;
+			this.loadData();
+		}
+	}
+</script>
+
+<style lang='scss'>
+	page,
+	.content {
+		height: 100%;
+		background-color: #f8f8f8;
+	}
+
+	.content {
+		display: flex;
+	}
+	.left-aside {
+		flex-shrink: 0;
+		width: 200upx;
+		height: 100%;
+		background-color: #fff;
+	}
+	.f-item {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		width: 100%;
+		height: 100upx;
+		font-size: 28upx;
+		color: $font-color-base;
+		position: relative;
+		&.active{
+			color: $base-color;
+			background: #f8f8f8;
+			&:before{
+				content: '';
+				position: absolute;
+				left: 0;
+				top: 50%;
+				transform: translateY(-50%);
+				height: 36upx;
+				width: 8upx;
+				background-color: $base-color;
+				border-radius: 0 4px 4px 0;
+				opacity: .8;
+			}
+		}
+	}
+
+	.right-aside{
+		flex: 1;
+		overflow: hidden;
+		padding-left: 20upx;
+	}
+	.s-item{
+		display: flex;
+		align-items: center;
+		height: 70upx;
+		padding-top: 8upx;
+		font-size: 28upx;
+		color: $font-color-dark;
+	}
+	.t-list{
+		display: flex;
+		flex-wrap: wrap;
+		width: 100%;
+		background: #fff;
+		padding-top: 12upx;
+		&:after{
+			content: '';
+			flex: 99;
+			height: 0;
+		}
+	}
+	.t-item{
+		flex-shrink: 0;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		flex-direction: column;
+		width: 176upx;
+		font-size: 26upx;
+		color: #666;
+		padding-bottom: 20upx;
+		
+		image{
+			width: 140upx;
+			height: 140upx;
+		}
+	}
+</style>

+ 355 - 0
pages/favorite/favorite.vue

@@ -0,0 +1,355 @@
+<template>
+	<view class="content">
+		<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData">
+			<!-- 空白页 -->
+			<empty v-if="favorite.loaded === true && favorite.list.length === 0"></empty>
+
+			<!-- 产品列表 -->
+			<view v-for="(item, index) in favorite.list" :key="index" class="order-item">
+				<view class="info" @click="navToDetailPage(item.product.product_id, item.status)">
+					<view class="image">
+						<image mode="aspectFill" :src="item.product.image"></image>
+					</view>
+					<view class="detail">
+						<view class="title">{{item.product.title}}</view>
+						<view class="price">
+							<view class="sales">¥{{item.product.sales_price}} </view>
+							<view class="market"> ¥{{item.product.market_price}}</view>
+						</view>
+						<view class="invalid" v-if="item.status == 0">失效</view>
+						<text class="del-btn yticon icon-lajitong" @click.stop="deleteFavorite(item.product.product_id,index)"></text>
+					</view>
+				</view>
+			</view>
+
+			<uni-load-more :status="favorite.loadingType"></uni-load-more>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
+	import empty from "@/components/empty";
+
+	export default {
+		components: {
+			uniLoadMore,
+			empty
+		},
+		computed: {
+		},
+		data() {
+			return {
+				favorite: {
+					list:[],
+					loadingType: 'more'
+				},
+				page: 1,
+				pageSize: 20
+			}
+		},
+		onLoad() {
+			this.loadData();
+		},
+		onPullDownRefresh() {
+			this.favorite = {};
+			this.favorite.list = [];
+			this.page = 1;
+			this.loadData();
+		},
+		methods: {
+			/**
+			 * 获取收藏数据
+			 */
+			async loadData(source = false) {
+				
+				uni.stopPullDownRefresh();
+
+				var favorite = this.favorite;
+
+				if (favorite.loadingType === 'loading') {
+					//防止重复加载
+					return;
+				}
+				if (favorite.loadingType == 'noMore') {
+					//没有更多数据
+					return;
+				}
+
+				favorite.loadingType = 'loading';
+
+				let list = await this.$api.request('/product/favoriteList', 'GET', {
+					page: this.page,
+					pagesize: this.pageSize
+				});
+				if (list && list.length > 0) {
+					if (list.length >= this.pageSize) {
+						//判断是否还有数据, 有改为 more, 没有改为noMore
+						favorite.loadingType = 'more';
+					} else {
+						favorite.loadingType = 'noMore';
+					}
+					// 页数加一
+					this.page++;
+
+					list.forEach((item, index) => {
+						favorite.list.push(item);
+					});
+
+				} else {
+					favorite.loadingType = 'noMore';
+				}
+			},
+			// 商品详情页
+			navToDetailPage(product_id, status) {
+				if (status == 0) {
+					this.$api.msg('此商品已失效');
+					return;
+				}
+				uni.navigateTo({
+					url: `/pages/product/product?id=${product_id}&flash=0`
+				});
+			},
+			// 删除
+			async deleteFavorite(id, index) {
+				let data = await this.$api.request('/product/favorite?id='+id);
+				if (data) {
+					this.favorite.list.splice(index,1);
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page,
+	.content {
+		background: #f5f5f5;
+		height: 100%;
+	}
+
+	.list-scroll-content{
+		height: 100%;
+	}
+	.order-item {
+		display: flex;
+		flex-direction: column;
+		padding-left: 30upx;
+		background: #fff;
+		margin-top: 16upx;
+
+		.info {
+			display: flex;
+			flex-direction: row;
+
+			.image {
+				image {
+					width: 250upx;
+					height: 250upx;
+					border-radius: 10upx;
+				}
+			}
+
+			.detail {
+				width: 440upx;
+				height: 250upx;
+				padding-left: 30upx;
+				padding-top: 6upx;
+				position: relative;
+
+				.title {
+					color: #303133;
+					width: 370rpx;
+					-webkit-line-clamp: 2;
+					overflow: hidden;
+					display: -webkit-box;
+					-webkit-box-orient: vertical;
+				}
+
+				.introduction {
+					color: #999999;
+					font-size: 26upx;
+				}
+
+				.price {
+					display: flex;
+					flex-direction: row;
+					margin-top: 20upx;
+					.sales {
+						font-size: 40upx;
+						color: $base-color;
+						font-weight: 500;
+					}
+
+					.market {
+						vertical-align: bottom;
+						font-size: 25rpx;
+						text-decoration: line-through;
+						line-height: 60rpx;
+					}
+				}
+
+				.ProgressBar {
+					position: absolute;
+					bottom: 0;
+				}
+
+				.loot {
+					position: absolute;
+					right: 0;
+					bottom: 14rpx;
+					background: $base-color;
+					color: #fff;
+					padding: 4upx 14upx;
+					border-radius: 4upx;
+					box-shadow: 2upx 2upx 8upx -2px #000;
+					font-size: 32rpx;
+				}
+				.invalid{
+					color: $base-color;
+					position: absolute;
+					right: 0;
+					bottom: 0;
+				}
+				.yticon{
+					position: absolute;
+					right: 0;
+					top: 20rpx;
+				}
+			}
+		}
+	}
+
+
+	/* load-more */
+	.uni-load-more {
+		display: flex;
+		flex-direction: row;
+		height: 80upx;
+		align-items: center;
+		justify-content: center
+	}
+
+	.uni-load-more__text {
+		font-size: 28upx;
+		color: #999
+	}
+
+	.uni-load-more__img {
+		height: 24px;
+		width: 24px;
+		margin-right: 10px
+	}
+
+	.uni-load-more__img>view {
+		position: absolute
+	}
+
+	.uni-load-more__img>view view {
+		width: 6px;
+		height: 2px;
+		border-top-left-radius: 1px;
+		border-bottom-left-radius: 1px;
+		background: #999;
+		position: absolute;
+		opacity: .2;
+		transform-origin: 50%;
+		animation: load 1.56s ease infinite
+	}
+
+	.uni-load-more__img>view view:nth-child(1) {
+		transform: rotate(90deg);
+		top: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(2) {
+		transform: rotate(180deg);
+		top: 11px;
+		right: 0
+	}
+
+	.uni-load-more__img>view view:nth-child(3) {
+		transform: rotate(270deg);
+		bottom: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(4) {
+		top: 11px;
+		left: 0
+	}
+
+	.load1,
+	.load2,
+	.load3 {
+		height: 24px;
+		width: 24px
+	}
+
+	.load2 {
+		transform: rotate(30deg)
+	}
+
+	.load3 {
+		transform: rotate(60deg)
+	}
+
+	.load1 view:nth-child(1) {
+		animation-delay: 0s
+	}
+
+	.load2 view:nth-child(1) {
+		animation-delay: .13s
+	}
+
+	.load3 view:nth-child(1) {
+		animation-delay: .26s
+	}
+
+	.load1 view:nth-child(2) {
+		animation-delay: .39s
+	}
+
+	.load2 view:nth-child(2) {
+		animation-delay: .52s
+	}
+
+	.load3 view:nth-child(2) {
+		animation-delay: .65s
+	}
+
+	.load1 view:nth-child(3) {
+		animation-delay: .78s
+	}
+
+	.load2 view:nth-child(3) {
+		animation-delay: .91s
+	}
+
+	.load3 view:nth-child(3) {
+		animation-delay: 1.04s
+	}
+
+	.load1 view:nth-child(4) {
+		animation-delay: 1.17s
+	}
+
+	.load2 view:nth-child(4) {
+		animation-delay: 1.3s
+	}
+
+	.load3 view:nth-child(4) {
+		animation-delay: 1.43s
+	}
+
+	@-webkit-keyframes load {
+		0% {
+			opacity: 1
+		}
+
+		100% {
+			opacity: .2
+		}
+	}
+</style>

+ 466 - 0
pages/flash/list.vue

@@ -0,0 +1,466 @@
+<template>
+	<view class="content">
+		<view class="navbar">
+			<view v-for="(item, index) in navList" :key="index" class="nav-item" :class="{current: tabCurrentIndex === index}"
+			 @click="tabClick(index)">
+				<view class="hour">
+					<view>{{item.starttime_hour}}</view>
+					<view class="text">{{state[item.state].text}}</view>
+				</view>
+			</view>
+		</view>
+
+		<swiper :current="tabCurrentIndex" class="swiper-box" duration="300" @change="changeTab">
+			<swiper-item v-for="(tabItem, tabIndex) in navList" :key="tabIndex">
+				<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData">
+					<!-- 空白页 -->
+					<empty v-if="tabItem.loaded === true && tabItem.list.length === 0"></empty>
+
+					<!-- 产品列表 -->
+					<view v-for="(item, index) in tabItem.list" :key="index" class="order-item">
+						<view class="info" @click="navToDetailPage(item.product.product_id, tabItem.flash_id)">
+							<view class="image">
+								<image mode="aspectFill" :src="item.product.image"></image>
+							</view>
+							<view class="detail">
+								<view class="title">{{item.product.title}}</view>
+								<view class="introduction">{{item.introduction}}</view>
+								<view class="price">
+									<view class="sales">¥{{item.product.sales_price}} </view>
+									<view class="market"> ¥{{item.product.market_price}}</view>
+								</view>
+								<ProgressBar class="ProgressBar" :Sold="item.sold" :widthUpx="250" :Width="percentage(item.number,item.sold)"
+								 Type="candy" :Vice="true"></ProgressBar>
+								<view class="loot">{{tabItem.state > 0 ? "马上抢" : "未开始"}}</view>
+							</view>
+						</view>
+					</view>
+
+					<uni-load-more :status="tabItem.loadingType"></uni-load-more>
+
+				</scroll-view>
+			</swiper-item>
+		</swiper>
+
+	</view>
+</template>
+
+<script>
+	import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
+	import empty from "@/components/empty";
+	import ProgressBar from '@/components/Progress-Bar/Progress-Bar';
+
+	export default {
+		components: {
+			uniLoadMore,
+			empty,
+			ProgressBar
+		},
+		computed: {},
+		data() {
+			return {
+				pageSize: 15,
+				tabCurrentIndex: 0,
+				navList: [],
+				state: [{
+					text: '未开始'
+				}, {
+					text: '已开抢'
+				}, {
+					text: '抢购进行中'
+				}]
+			}
+		},
+		onPullDownRefresh() {
+			this.loadNavBar();
+		},
+		onLoad(options) {
+			this.loadNavBar();
+		},
+		methods: {
+			// 加载标签
+			async loadNavBar() {
+				let navbar = await this.$api.request('/flash/navbar', 'GET');
+				uni.stopPullDownRefresh();
+				if (navbar) {
+					this.navList = navbar;
+					this.navList.forEach((item, index) => {
+						item = Object.assign(item, {
+							list: [],
+							page: 1,
+							loadingType: 'more'
+						}); //新增一个数组用来储存商品
+						if (item.current) {
+							this.tabCurrentIndex = index;
+						}
+						// 建议把后端处理的starttime_hour和text字段在这里用js处理
+					});
+					this.loadData('tabChange', this.navList[this.tabCurrentIndex].flash_id);
+					this.setNavigationBarTitle(this.navList[this.tabCurrentIndex].title);
+					//console.log(this.navList);
+				}
+			},
+			// 加载数据
+			async loadData(source = false, flash_id = 0) {
+				//这里是将订单挂载到tab列表下
+				let index = this.tabCurrentIndex;
+				let navItem = this.navList[index];
+
+				if (source === 'tabChange' && navItem.loaded === true) {
+					//tab切换只有第一次需要加载数据
+					return;
+				}
+				if (navItem.loadingType === 'loading') {
+					//防止重复加载
+					return;
+				}
+				if (navItem.loadingType == 'noMore') {
+					//没有更多数据
+					return;
+				}
+
+				navItem.loadingType = 'loading';
+
+				let result = await this.$api.request('/flash/product', 'GET', {
+					flash_id: flash_id,
+					page: navItem.page,
+					pagesize: this.pageSize
+				});
+				if (result) {
+					if (result.length >= this.pageSize) {
+						//判断是否还有数据, 有改为 more, 没有改为noMore
+						navItem.loadingType = 'more';
+					} else {
+						navItem.loadingType = 'noMore';
+					}
+					// 页数加一
+					navItem.page++;
+
+					result.forEach((item, index) => {
+						navItem.list.push(item);
+					})
+					//loaded新字段用于表示数据加载完毕,如果为空可以显示空白页
+					this.$set(navItem, 'loaded', true);
+				}
+			},
+			//顶部tab点击
+			tabClick(index) {
+				this.tabCurrentIndex = index;
+			},
+			//swiper 切换
+			changeTab(e) {
+				this.tabCurrentIndex = e.target.current;
+				this.loadData('tabChange', this.navList[this.tabCurrentIndex].flash_id);
+				this.setNavigationBarTitle(this.navList[this.tabCurrentIndex].title);
+
+			},
+			// 计算百分比
+			percentage(number, sold) {
+				if (sold == 0) {
+					return 0;
+				}
+				return parseInt(sold / number * 100);
+			},
+			// 商品详情页
+			navToDetailPage(product_id, flash_id = 0) {
+				uni.navigateTo({
+					url: `/pages/product/product?id=${product_id}&flash=${flash_id}`
+				});
+			},
+			// 设置导航栏名称
+			setNavigationBarTitle(title) {
+				uni.setNavigationBarTitle({
+					title: '限时秒杀|' + title
+				});
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	page,
+	.content {
+		//background: $page-color-base;
+		background: #f5f5f5;
+		height: 100%;
+	}
+
+	.swiper-box {
+		height: calc(100% - 50px);
+	}
+
+	.list-scroll-content {
+		height: 100%;
+	}
+
+	.navbar {
+		display: flex;
+		height: 50px;
+		padding: 0 5px;
+		background: #000;
+		box-shadow: 0 1px 5px rgba(0, 0, 0, .06);
+		position: relative;
+		z-index: 10;
+		overflow: auto;
+
+		.nav-item {
+			flex: 1;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+			height: 100%;
+			font-size: 15px;
+			//color: $font-color-dark;
+			color: #fff;
+			font-weight: 900;
+			position: relative;
+			text-align: center;
+			min-width: 150upx;
+
+			.hour {
+				flex-flow: column;
+				display: flex;
+
+				.text {
+					font-size: 10px;
+					font-weight: 400;
+				}
+			}
+
+			&.current {
+				//color: $base-color;
+				background-color: $base-color;
+
+				&:after {
+					content: '';
+					position: absolute;
+					//left: 50%;
+					bottom: -10upx;
+					//transform: translateX(-50%);
+					transform: rotate(45deg);
+					//width: 44px;
+					width: 20upx;
+					//height: 0;
+					height: 20upx;
+					background-color: $base-color;
+					//border-bottom: 2px solid $base-color;
+				}
+			}
+		}
+	}
+
+	.order-item {
+		display: flex;
+		flex-direction: column;
+		padding-left: 30upx;
+		background: #fff;
+		margin-top: 16upx;
+
+		.info {
+			display: flex;
+			flex-direction: row;
+
+			.image {
+				image {
+					width: 250upx;
+					height: 250upx;
+					border-radius: 10upx;
+				}
+			}
+
+			.detail {
+				width: 440upx;
+				height: 250upx;
+				padding-left: 30upx;
+				padding-top: 6upx;
+				position: relative;
+
+				.title {
+					color: #303133;
+					overflow: hidden;
+					text-overflow: ellipsis;
+					white-space: nowrap;
+				}
+
+				.introduction {
+					color: #999999;
+					font-size: 26upx;
+					-webkit-line-clamp: 2;
+					overflow: hidden;
+					display: -webkit-box;
+					-webkit-box-orient: vertical;
+				}
+
+				.price {
+					position: absolute;
+					bottom: 56upx;
+					display: flex;
+					flex-direction: row;
+
+					.sales {
+						font-size: 40upx;
+						color: $base-color;
+						font-weight: 500;
+					}
+
+					.market {
+						vertical-align: bottom;
+						font-size: 25upx;
+						text-decoration: line-through;
+					}
+				}
+
+				.ProgressBar {
+					position: absolute;
+					bottom: 0;
+				}
+
+				.loot {
+					position: absolute;
+					right: 0;
+					bottom: 14rpx;
+					background: $base-color;
+					color: #fff;
+					padding: 4upx 14upx;
+					border-radius: 4upx;
+					box-shadow: 2upx 2upx 8upx -2px #000;
+					font-size: 32rpx;
+				}
+			}
+		}
+	}
+
+
+	/* load-more */
+	.uni-load-more {
+		display: flex;
+		flex-direction: row;
+		height: 80upx;
+		align-items: center;
+		justify-content: center
+	}
+
+	.uni-load-more__text {
+		font-size: 28upx;
+		color: #999
+	}
+
+	.uni-load-more__img {
+		height: 24px;
+		width: 24px;
+		margin-right: 10px
+	}
+
+	.uni-load-more__img>view {
+		position: absolute
+	}
+
+	.uni-load-more__img>view view {
+		width: 6px;
+		height: 2px;
+		border-top-left-radius: 1px;
+		border-bottom-left-radius: 1px;
+		background: #999;
+		position: absolute;
+		opacity: .2;
+		transform-origin: 50%;
+		animation: load 1.56s ease infinite
+	}
+
+	.uni-load-more__img>view view:nth-child(1) {
+		transform: rotate(90deg);
+		top: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(2) {
+		transform: rotate(180deg);
+		top: 11px;
+		right: 0
+	}
+
+	.uni-load-more__img>view view:nth-child(3) {
+		transform: rotate(270deg);
+		bottom: 2px;
+		left: 9px
+	}
+
+	.uni-load-more__img>view view:nth-child(4) {
+		top: 11px;
+		left: 0
+	}
+
+	.load1,
+	.load2,
+	.load3 {
+		height: 24px;
+		width: 24px
+	}
+
+	.load2 {
+		transform: rotate(30deg)
+	}
+
+	.load3 {
+		transform: rotate(60deg)
+	}
+
+	.load1 view:nth-child(1) {
+		animation-delay: 0s
+	}
+
+	.load2 view:nth-child(1) {
+		animation-delay: .13s
+	}
+
+	.load3 view:nth-child(1) {
+		animation-delay: .26s
+	}
+
+	.load1 view:nth-child(2) {
+		animation-delay: .39s
+	}
+
+	.load2 view:nth-child(2) {
+		animation-delay: .52s
+	}
+
+	.load3 view:nth-child(2) {
+		animation-delay: .65s
+	}
+
+	.load1 view:nth-child(3) {
+		animation-delay: .78s
+	}
+
+	.load2 view:nth-child(3) {
+		animation-delay: .91s
+	}
+
+	.load3 view:nth-child(3) {
+		animation-delay: 1.04s
+	}
+
+	.load1 view:nth-child(4) {
+		animation-delay: 1.17s
+	}
+
+	.load2 view:nth-child(4) {
+		animation-delay: 1.3s
+	}
+
+	.load3 view:nth-child(4) {
+		animation-delay: 1.43s
+	}
+
+	@-webkit-keyframes load {
+		0% {
+			opacity: 1
+		}
+
+		100% {
+			opacity: .2
+		}
+	}
+</style>

File diff suppressed because it is too large
+ 773 - 0
pages/index/index.vue


File diff suppressed because it is too large
+ 1016 - 0
pages/intergalShop/confirm.vue


File diff suppressed because it is too large
+ 1219 - 0
pages/intergalShop/goodsDetail.vue


+ 589 - 0
pages/intergalShop/index.vue

@@ -0,0 +1,589 @@
+<template>
+	<block>
+		<view class="topBack" :style="'top: ' + menuButton.top + 'px'">
+			<!-- <text class="ico-moon icon-leftarrow" wx:if="{{pages > 1}}" bindtap="toPage" data-mold="back"></text> -->
+
+			<image v-if="pages > 1" @tap="toback"
+				src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/f566738e424f33a415dea22dc4e11eec.png"
+				class="ico-moon"></image>
+
+			<image mode="heightFix" :style="'height: ' + menuButton.height * 2 + 'rpx'" @tap="toPage"
+				data-url="/pages/tabbar/index/index" class="h-backBtn" v-else
+				src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/2847/41c5f36528b8f4204130c4977c1ec2c5.png">
+			</image>
+			<view class="userName">积分商城</view>
+		</view>
+
+		<view class="tpBg" :style="'padding-top: ' + (menuButton.top+menuButton.height) + 'px'">
+
+			<view class="userinfo">
+
+				<image class="userimg"
+					src="http://cdn.shop.weivee.com/shop/20200408/6162b21922f336ae9b320bc06582ab7f.png" mode=""></image>
+				<view class="userintergal" @click="toPage" data-url='/pages/wallet/integral'>
+					<view>
+						我的积分
+					</view>
+					<view>
+						{{info.score||0}}
+						<image class="usearrow"
+							src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/2e9b0e2d66ccbc9cdce81a5503262b83.png"
+							mode=""></image>
+					</view>
+				</view>
+			</view>
+
+
+		</view>
+
+		<view class="content">
+			<view class="box">
+
+
+				<view class="daitem" @click="toPage" data-url='/pages/wallet/integral'>
+					<image
+						src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/d17b79704d2bfbaa99e6c092b2bf2488.png"
+						mode=""></image>
+					<view>
+						积分明细
+					</view>
+				</view>
+
+
+				<view class="daitem" @click="toPage" data-url='/pages/intergalShop/logs'>
+					<image
+						src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/cb0958aaba111ea7ba861e3a1ad5e4e7.png"
+						mode=""></image>
+					<view>
+						我的兑换
+					</view>
+				</view>
+
+			</view>
+
+		</view>
+
+		<view class="content1">
+			<view class="iNav iflex">
+				<view class="iflexC aliCen tabItem" @tap="changeNav" :data-index="index" v-for="(item, index) in navs"
+					:key="index">
+					<text :class="'iNav-text ' + (navIndex == index ? 'ifontweight' : '')">{{ item.name }}</text>
+
+					<image
+						src="https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/0d08dcd267a9ecfb5aec198436d00646.png"
+						v-if="navIndex == index"></image>
+				</view>
+			</view>
+
+			<view class="goodsList">
+				<view class="goodsItem" @tap="toPage" data-url="/pages/intergalShop/goodsDetail" :data-id="item.product_id"
+					v-for="(item, index) in list" :key="index">
+					<image :src="item.image" class="goodsImg"></image>
+
+					<view class="goodsTitle">{{ item.title }}</view>
+
+					<view class="goodsInfo">
+						<view>¥{{ item.sales_price }}</view>
+						<view>已兑{{ item.sales }}</view>
+					</view>
+				</view>
+				
+				
+				    <view v-if="!list.length" style='width:100%;color:#999;text-align:center;margin:150rpx 0;font-size:30rpx'>暂无数据</view>
+
+			</view>
+		</view>
+
+
+	</block>
+</template>
+<script module="parse" lang="wxs">
+	module.exports = {
+		filterTime: function(time) {
+
+			console.log(time)
+
+			var nowDate = getDate(time * 1000);
+			var year = nowDate.getFullYear();
+			var month = nowDate.getMonth() + 1;
+			var date = nowDate.getDate();
+			var hours = nowDate.getHours();
+			var minutes = nowDate.getMinutes();
+			var seconds = nowDate.getSeconds();
+
+			month = month > 9 ? month : '0' + month;
+			date = date > 9 ? date : '0' + date;
+			hours = hours > 9 ? hours : '0' + hours;
+			minutes = minutes > 9 ? minutes : '0' + minutes;
+			seconds = seconds > 9 ? seconds : '0' + seconds;
+
+			return year + '-' + month + '-' + date + " " + hours + ":" + minutes + ":" + seconds;
+
+		}
+	}
+</script>
+<script>
+	// pages/backstage/index/index.js
+	var app = getApp();
+
+	export default {
+		data() {
+			return {
+				navs: [
+				],
+				navIndex: 0,
+				list: [
+
+				],
+				loaded: false,
+				page: 1,
+				info: {
+					
+				},
+
+
+
+				menuButton: {
+					top: '',
+					height: 0
+				},
+
+			};
+		}
+		/**
+		 * 生命周期函数--监听页面加载
+		 */
+		,
+		async onLoad(options) {
+			let page = getCurrentPages();
+			var menuButton = uni.getMenuButtonBoundingClientRect();
+			console.log(menuButton);
+
+			this.pages = page.length
+			this.menuButton = menuButton
+
+
+			this.getinfo();
+			
+			let data = await this.$api.request('/category/all','GET',{
+				type:"intergral"
+			});
+			
+			
+			
+			this.navs = data;
+			
+			
+			console.log(this.navs)
+			
+			this.getlist();
+			
+
+		},
+
+
+
+		/**
+		 * 生命周期函数--监听页面显示
+		 */
+		onShow: function() {},
+
+		onPullDownRefresh: function() {
+
+		},
+		/**
+		 * 页面上拉触底事件的处理函数
+		 */
+		onReachBottom: function() {
+        this.loaded || this.getlist();
+		},
+		/**
+		 * 用户点击右上角分享
+		 */
+		onShareAppMessage: function() {},
+		methods: {
+
+			async getlist() {
+        var that = this;
+			         let res = await this.$api.request('/product/lists', 'GET', {
+			         	page: this.page,
+			         	pagesize: 10,
+						type:1,
+							fid	:this.navs[this.navIndex].id
+			         });
+					 
+					 console.log(res)
+			         if (res) {
+			         	if (res.length > 0) {
+			         
+			         		this.list = this.list.concat(res);
+			         
+			         		this.page++;
+			         		
+			         	} else {
+			         		this.loaded = true
+			         		this.$api.msg('没有更多数据');
+			         	}
+			         }
+				
+				
+				
+				
+				
+					
+			},
+			
+
+			
+
+			changeNav(e) {
+				let index = e.currentTarget.dataset.index;
+				console.log(index);
+
+				if (this.navIndex != index) {
+
+					this.navIndex = index
+					this.page = 1
+					this.list = []
+					this.loaded = false
+
+					this.getlist();
+				}
+			},
+
+			async getinfo() {
+				let data = await this.$api.request('/wallet/index');
+				if (data) {
+					this.info = data;
+				}
+			},
+
+
+			toPage(e) {
+				app.globalData.toPage(e);
+			},
+
+			toback() {
+				uni.navigateBack({
+					delta: 1
+				});
+			},
+
+
+		}
+	};
+</script>
+<style>
+	page {
+		background: #F4F5F9;
+	}
+
+	.topBack {
+		position: absolute;
+		top: 0;
+		left: 0;
+		z-index: 1;
+		margin-top: 2rpx;
+		display: flex;
+		align-items: center;
+	}
+
+	.topBack .ico-moon {
+		padding: 0 0rpx 0 30rpx;
+		width: 70rpx;
+		height: 40rpx;
+	}
+
+	.h-backBtn {
+		margin-left: 30rpx;
+	}
+
+	.homeImg {
+		height: 40rpx;
+		width: 40rpx;
+		margin-right: 10rpx;
+	}
+
+
+
+
+	.userName {
+		font-size: 28rpx;
+		color: #fff;
+		margin-left: 20rpx;
+		font-size: 36rpx;
+	}
+
+	.tpBg {
+		background: url(https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/8/55fe2551ab3fd04275f3e1cc384081de.png);
+		background-size: 100% 100%;
+		width: 100%;
+		height: 456rpx;
+		box-sizing: border-box;
+	}
+
+	.content {
+		margin: -80rpx 30rpx 25rpx;
+	}
+
+	.box {
+		border-radius: 12rpx;
+		background: #fff;
+
+		padding: 40rpx 66rpx 50rpx 50rpx;
+
+		margin-bottom: 25rpx;
+		display: flex;
+
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.totalAllTitle {
+		color: #9194A6;
+		margin-bottom: 28rpx;
+		text-align: center;
+	}
+
+	.total {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		padding-bottom: 20rpx;
+
+	}
+
+	.totalNum {
+		font-size: 50rpx;
+	}
+
+	.totalJump {
+		display: flex;
+		align-items: center;
+		width: 220rpx;
+		height: 70rpx;
+		justify-content: center;
+		background: #FB4C6F;
+		border-radius: 12rpx;
+		border-radius: 12rpx;
+	}
+
+
+	.totalJump>view {
+		font-size: 28rpx;
+		color: #fff;
+
+	}
+
+
+
+	.totalJump>image {
+		width: 14rpx;
+		margin-left: 14rpx;
+		margin-top: 5rpx;
+	}
+
+
+	.tip {
+		font-size: 30rpx;
+		padding-bottom: 10rpx;
+	}
+
+
+
+	.box1 {
+		border-radius: 12rpx;
+		background: #fff;
+
+		padding: 50rpx;
+
+		margin-bottom: 25rpx;
+		padding-top: 0;
+	}
+
+
+
+
+	view {
+		font-size: 24rpx;
+	}
+
+	.rWrap {
+
+		display: flex;
+		align-items: center;
+
+	}
+
+	.intergal {
+		color: #000000;
+		font-size: 30rpx;
+		margin-right: 12rpx;
+	}
+
+
+	.userinfo {
+		display: flex;
+		align-items: center;
+		padding: 60rpx 0 0 50rpx;
+	}
+
+	.userimg {
+		width: 120rpx;
+		height: 120rpx;
+		border-radius: 50%;
+	}
+
+
+	.userintergal {
+		margin-left: 20rpx;
+	}
+
+	.userintergal>view:nth-child(1) {
+		font-size: 28rpx;
+		color: #fff;
+	}
+
+
+	.userintergal>view:nth-child(2) {
+		font-size: 80rpx;
+		font-weight: 700;
+		color: #fff;
+	}
+
+	.usearrow {
+		width: 10rpx;
+		height: 18rpx;
+		vertical-align: center;
+		margin: 0 0 20rpx 20rpx;
+	}
+
+
+	.daitem {
+
+		display: flex;
+		align-items: center;
+
+	}
+
+	.daitem>view {
+
+		font-size: 28rpx;
+		color: #000;
+		margin-left: 18rpx;
+
+	}
+
+	.daitem>image {
+
+		width: 60rpx;
+		height: 60rpx;
+
+	}
+
+
+
+	.iNav {
+		width: 710rpx;
+		/* padding: 0 20rpx 0; */
+		/* margin-top: 34rpx; */
+		line-height: 1;
+	}
+
+	.iNav .iNav-text {
+		padding: 30rpx 0rpx 28rpx;
+		/* padding-top: 34rpx;
+	  padding-bottom: 28rpx; */
+		color: #121212;
+		font-size: 34rpx;
+	}
+
+	.iNav image {
+		width: 68rpx;
+		height: 10rpx;
+		margin-top: -30rpx;
+		z-index: -1;
+	}
+
+	.jsbet {
+		justify-content: space-between;
+	}
+
+	.iflex {
+		display: flex;
+	}
+
+	.aliCen {
+		align-items: center;
+	}
+
+	.iflexC {
+		display: flex;
+		flex-direction: column;
+	}
+
+	.ifontweight {
+		font-weight: 700;
+	}
+
+	.content1 {
+		padding: 0 30rpx;
+		box-sizing: border-box;
+	}
+
+	.tabItem {
+		margin-right: 70rpx;
+	}
+
+	.goodsList {
+		display: flex;
+		justify-content: space-between;
+		flex-wrap: wrap;
+	}
+
+	.goodsItem {
+		width: 330rpx;
+		padding: 10rpx 12rpx 28rpx;
+		box-sizing: border-box;
+		margin-bottom: 20rpx;
+		background: #fff;
+		border-radius: 12rpx;
+	}
+
+	.goodsImg {
+		width: 308rpx;
+		height: 308rpx;
+		border-radius: 12rpx;
+	}
+
+	.goodsTitle {
+		margin-top: 22rpx;
+		color: #011b33;
+		font-weight: 700;
+		font-size: 30rpx;
+		width: 300rpx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+		-webkit-line-clamp: 2;
+	}
+
+	.goodsInfo {
+		margin-top: 22rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.goodsInfo>view:nth-child(1) {
+		color: #F15071;
+		font-size: 30rpx;
+	}
+
+	.goodsInfo>view:nth-child(2) {
+		font-size: 22rpx;
+		color: #999999;
+	}
+</style>

+ 665 - 0
pages/intergalShop/logs.vue

@@ -0,0 +1,665 @@
+<template>
+    <block>
+        <scroll-view class="scrollView" :scroll-x="true" style="width: 100%">
+            <view class="navs">
+                <text :class="'nav ' + (nowIndex == index ? 'bold' : '')" @tap="navChange" :data-index="index" :data-id="item.id" v-for="(item, index) in navs" :key="index">
+                    {{ item.name }}
+                </text>
+                <text class="borderLine" :style="'width: ' + (width + 'rpx') + ';left: ' + (45 + nowIndex * 150 + 'rpx')"></text>
+            </view>
+        </scroll-view>
+        <view class="content" v-if="list.length > 0">
+            <view
+                class="lists"
+                @tap="toPage"
+                :data-order_id="item.id"
+                data-url="/pages/operate/order_detail/order_detail"
+                :data-index="index"
+                v-for="(item, index) in list"
+                :key="index"
+            >
+                <!-- <view class="iflexC">
+			<text style="letter-spacing: 0px">订单编号:  {{item.order_no}}</text>
+			<text class="lists-time">下单时间:  {{item.create_time}}</text>
+			
+		</view> -->
+
+                <text class="lists-status" v-if="item.order_status == 0 && item.receive_type == 2">待发货</text>
+
+                <text class="lists-status" v-if="item.order_status == 0 && item.receive_type == 1">待核销</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 1">审核通过</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 2">已退款</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 3">拒绝退款</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 4">已核销</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 5">已发货</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 6">已完成</text>
+
+                <text class="lists-status" v-else-if="item.order_status == 7">退款待审</text>
+
+                <view :class="'iflexC lists-content ' + (item.order_status == 6 ? 'borderNone' : '')">
+                    <image class="lists-img" :src="item.goods_pic" mode="aspectFill"></image>
+                    <text class="lists-title over_2">{{ item.goods_name }}</text>
+                    <!-- <view class="lists-num">
+					<view class="lists-num1">数量: 1</view>
+
+					<view class="goDetail"  catchtap="goMovie" wx:if="{{item.order_status== 6&&item.is_film==1}}">查看电影票</view>
+					<view class="goDetail" wx:else>查看详情</view>
+			</view> -->
+                    <text class="lists-money">
+                        价格:
+                        <text class="red" v-if="item.pay_money != '0.00'">¥{{ item.pay_money }}+</text>
+                        <text class="red">{{ item.integral }}</text>
+                        {{ unit }} {{ item.sku ? '(' + item.sku + ')' : '' }}
+                    </text>
+                    <text class="lists-time">下单时间:{{ item.create_time }}</text>
+                </view>
+
+                <!-- <view class="iflexC" style="border-bottom:1px solid #eee;" wx:if="{{item.deliver_no}}">
+			<text class="lists-time1" style="padding-bottom:0">快递名称:{{item.send_comp}}</text>
+			<text  class="lists-time1">物流单号:{{item.deliver_no}} </text>
+		</view> -->
+
+                <view class="iflex l-btns" style="flex-direction: row-reverse">
+                    <button
+                        class="lists-btn btn2"
+                        @tap.stop.prevent="hexiao"
+                        :data-index="index"
+                        v-if="(item.order_status == 3 && item.receive_type == 1 && !item.is_film == 1) || (item.order_status == 0 && item.receive_type == 1 && !item.is_film == 1)"
+                    >
+                        核销码
+                    </button>
+
+                    <button class="lists-btn btn2" @tap.stop.prevent="getMovie" :data-id="id" v-if="item.order_status == 0 && item.is_film == 1">点击领取</button>
+
+                    <!-- <button class="lists-btn btn2" catchtap="confirm" data-order_id="{{item.id}}" wx:if="{{item.order_status==4}}">确认已核销</button> -->
+                    <button class="lists-btn btn2" @tap.stop.prevent="confirm" :data-order_id="item.id" v-if="item.order_status == 5">确认收货</button>
+
+                    <button
+                        class="lists-btn btn1"
+                        @tap.stop.prevent="refundConfirm"
+                        :data-id="item.id"
+                        :data-area_code="item.ssq_code"
+                        data-type="99"
+                        v-if="item.order_status == 0"
+                    >
+                        申请退款
+                    </button>
+
+                    <button
+                        class="lists-btn btn2"
+                        v-if="item.receive_type == 2 && item.order_status == 5"
+                        :data-phone="item.receiver_mobile"
+                        :data-no="item.deliver_no"
+                        @tap.stop.prevent="lookOrder"
+                    >
+                        查看物流
+                    </button>
+                </view>
+            </view>
+        </view>
+        <view style="margin-top: 100rpx" v-if="!list.length && loaded">
+            <msg status="1" icon="https://ms-oss.intelgice.com/yidu_tc/public/upload/12/8/c828dbb65be243c65117fa425e4937b6.png"></msg>
+        </view>
+        <!-- <msg status="2" v-if="list.length && loaded"></msg> -->
+
+        <!-- 去掉跳转同城运营中心的tabbar -->
+        <!-- <tabbar active='1'></tabbar> -->
+
+<!--        <view class="mask" v-if="flag">
+            <view class="qrcode">
+                <image mode="widthFix" :src="qr_img"></image>
+                <view class="close" @tap="close">关闭</view>
+                \
+            </view>
+        </view> -->
+    </block>
+</template>
+
+<script>
+
+var app = getApp();
+
+export default {
+
+    data() {
+        return {
+            list: [
+				{
+					create_time: "2022-03-26 15:45:59",
+					deliver_no: "",
+					goods_id: 1520,
+					goods_name: "寒铁10件套美容工具IRON-0100 IRON-0100",
+					goods_pic: "https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/2487/f04456f1d7360742a070f36b0901e0a7.png",
+					id: 1182,
+					integral: "0.00",
+					is_deliver: 0,
+					is_film: 0,
+					order_no: "31038957705405027625933",
+					order_status: 0,
+					pay_money: "0.00",
+					pay_time: "2022-03-26 15:45:59",
+					receive_type: 2,
+					receiver_mobile: "18779615160",
+					send_comp: "",
+					sku: "中号型",
+					ssq_code: "360702",
+				},
+				{
+					create_time: "2022-03-26 15:45:41",
+					deliver_no: "",
+					goods_id: 1520,
+					goods_name: "寒铁10件套美容工具IRON-0100 IRON-0100",
+					goods_pic: "https://ymyun-oss.oss-cn-hangzhou.aliyuncs.com/yidu_tc/public/upload/12/2487/f04456f1d7360742a070f36b0901e0a7.png",
+					id: 1181,
+					integral: "0.00",
+					is_deliver: 0,
+					is_film: 0,
+					order_no: "31038957690909207348985",
+					order_status: 0,
+					pay_money: "0.00",
+					pay_time: "2022-03-26 15:45:42",
+					receive_type: 1,
+					receiver_mobile: "18779615160",
+					send_comp: "",
+					sku: "中号型",
+					ssq_code: "360702",
+				}
+				
+				
+			],
+            page: 1,
+            loaded: false,
+            nowIndex: 0,
+            width: 60,
+
+            navs: [
+                {
+                    id: '4',
+                    name: '全部'
+                },
+                {
+                    id: 0,
+                    name: '待发货'
+                },
+                {
+                    id: 1,
+                    name: '待收货'
+                },
+                {
+                    id: '3',
+                    name: '已完成'
+                }
+            ],
+
+            is_deliver: 4,
+            unit: '积分',
+            flag: false,
+            qr_img: '',
+            show: false,
+            id: ''
+        };
+    },
+    onLoad: function () {
+        var that = this;
+        // that.getlist();
+    },
+    onPullDownRefresh: function () {
+        this.setData({
+            list: [],
+            page: 1,
+            loaded: false
+        });
+        this.getlist();
+    },
+    onReachBottom: function () {
+        this.loaded || this.getlist();
+    },
+    methods: {
+        lookOrder(e) {
+            var phone = e.currentTarget.dataset.phone;
+            var no = e.currentTarget.dataset.no;
+            uni.navigateTo({
+                url: `/pages/other/logistics/logistics?phone=${phone}&no=${no}`
+            });
+        },
+
+        refundConfirm(e) {
+            let ta = this;
+            a.jump('/yidu_tc/pages/order/order_refund/order_refund?area_code=' + a.pdata(e).area_code + '&id=' + a.pdata(e).id + '&type=' + a.pdata(e).type, 1); // wx.showToast({
+            //   title: '这是申请退款',
+            // })
+            // const that = this
+            // const order_id = e.currentTarget.dataset.order_id
+            // a.get('regionintegral/refund',
+            //   { uid: app.getCache('userinfo').uid, order_id: order_id },
+            //   function (res) {
+            //     const res1 = res ? JSON.parse(res.info) : ''
+            //     console.log(res1)
+            //     if (res1.code == 0) {
+            //       a.toast(res1.info, 'none')
+            //       setTimeout(function(){
+            //         that.initData()
+            //         that.getlist()
+            //       }, 1000)
+            //     }else{
+            //       a.toast(res1.info, 'none')
+            //     }
+            //   }
+            // )
+        },
+
+        getMovie(e) {
+            var id = e.currentTarget.dataset.id;
+            uni.navigateTo({
+                url: `/pages/movie/pages/receive/index?id=${id}&channel=integral`
+            });
+        },
+
+        hexiao(e) {
+            //点击核销弹出
+            var index = e.currentTarget.dataset.index;
+            var order_id = this.list[index].id;
+            uni.navigateTo({
+                url: '/pages/other/orderCode/orderCode?id=' + order_id + '&type=2'
+            }); //   var that = this;
+            //   wx.showLoading({
+            //     title: '加载中',
+            //   })
+            //   a.get('regionintegral/qrcode',
+            //   { uid: app.getCache('userinfo').uid, order_id: order_id},
+            //   function (res) {
+            //     if (res.code == 0) {
+            //       that.setData({
+            //         qr_img:res.info,
+            //         flag:true
+            //       })
+            //       wx.hideLoading({
+            //         complete: (res) => {},
+            //       })
+            //     }else{
+            //       a.toast(res.msg)
+            //     }
+            //   }
+            // )
+        },
+
+        close() {
+            this.setData({
+                flag: false
+            });
+        },
+
+        confirm(e) {
+            // 确认收货
+            const that = this;
+            const order_id = e.currentTarget.dataset.order_id;
+            a.get(
+                'regionintegral/confirm',
+                {
+                    uid: app.globalData.getCache('userinfo').uid,
+                    order_id: order_id
+                },
+                function (res) {
+                    // const res1 = res ? JSON.parse(res.info) : ''
+                    console.log(res);
+
+                    if (res.code == 0) {
+                        a.toast(res.msg, 'none');
+                        setTimeout(function () {
+                            that.initData();
+                            that.getlist();
+                        }, 1000);
+                    } else {
+                        a.toast(res.msg, 'none');
+                    }
+                }
+            );
+        },
+
+        navChange(e) {
+            if (this.nowIndex != e.currentTarget.dataset.index) {
+                this.setData({
+                    nowIndex: e.currentTarget.dataset.index,
+                    is_deliver: e.currentTarget.dataset.id
+                });
+                this.initData();
+                this.getlist();
+            }
+        },
+
+        initData() {
+            this.setData({
+                page: 1,
+                list: [],
+                loaded: false
+            });
+        },
+
+        getlist: function () {
+            var that = this;
+            var page = that.page; // Integral / exchangelog
+            a.get(
+                'regionintegral/exchange',
+                {
+                    page: page,
+                    uid: app.globalData.getCache('userinfo').uid,
+                    is_deliver: that.is_deliver
+                },
+                function (t) {
+                    uni.stopPullDownRefresh();
+
+                    if (t.code == 0) {
+                        if (t.info.length > 0) {
+                            // t.info[0].order_status = 6
+                            // t.info[0].is_film = 1
+                            that.setData({
+                                list: that.list.concat(t.info),
+                                page: page + 1,
+                                show: true
+                            });
+
+                            if (t.info.length < 10) {
+                                that.setData({
+                                    loaded: true
+                                });
+                            }
+                        } else {
+                            that.setData({
+                                loaded: true
+                            });
+                        }
+                    } else {
+                        a.alert(t.msg);
+                    }
+                },
+                !that.show
+            );
+        },
+
+        toPage(e) {
+            let index = e.currentTarget.dataset.index;
+
+            if (this.list[index].order_status == 6 && this.list[index].is_film == 1) {
+                e.currentTarget.dataset.url = '/pages/movie/pages/myMovie/index';
+            }
+
+            app.globalData.toPage(e);
+        }
+    }
+};
+</script>
+<style>
+page {
+    background: #f2f2f2;
+    padding-bottom: 140rpx;
+}
+.scrollView {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    z-index: 100;
+}
+.navs {
+    display: flex;
+    width: 100%;
+    position: relative;
+    border-top: 1px solid #e4e4e4;
+    background: white;
+}
+
+.lists-time1 {
+    font-size: 24rpx;
+    color: #666;
+    padding: 10rpx 0 16rpx;
+}
+
+.navs .nav {
+    flex: 1;
+    flex-shrink: 0;
+    text-align: center;
+    padding: 26rpx 0;
+    font-size: 28rpx;
+    color: #333;
+}
+.borderNone {
+    border-bottom: none !important;
+}
+.bold {
+    font-weight: bold;
+    color: #FB4C6F !important;
+}
+.borderLine {
+    width: 60rpx;
+    height: 4rpx;
+    background: rgba(234, 63, 51, 1);
+    opacity: 1;
+    display: block;
+    position: absolute;
+    bottom: 0;
+    transition: left 0.3s;
+    opacity: 0;
+}
+.content {
+    margin-top: 116rpx;
+}
+.lists {
+    background: white;
+    margin: 0 20rpx 20rpx;
+    padding: 22rpx;
+    border-radius: 15rpx;
+    font-size: 28rpx;
+    position: relative;
+}
+.lists-status {
+    position: absolute;
+    top: 22rpx;
+    right: 22rpx;
+    font-size: 26rpx;
+    color: #8E8E8E;
+}
+.lists-content {
+    padding: 0 0 0 156rpx;
+    position: relative;
+    min-height: 132rpx;
+}
+.lists-img {
+    height: 132rpx;
+    width: 132rpx;
+    position: absolute;
+    top: 0;
+    left: 0;
+    border-radius: 6rpx;
+}
+.lists-time {
+    font-size: 22rpx;
+    color: #666;
+}
+.lists-title {
+    font-size: 32rpx;
+    width: 410rpx;
+    line-height: 1.2;
+}
+.lists-num {
+    padding: 12rpx 0 24rpx;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+}
+
+.lists-num1 {
+    color: #666;
+}
+
+.goDetail {
+    width: 150rpx;
+    height: 65rpx;
+    color: #f62e2e;
+    border: 1px solid #f62e2e;
+    border-radius: 40rpx;
+    font-size: 24rpx;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.lists-money {
+    font-size: 26rpx;
+    padding: 6rpx 0 26rpx;
+}
+.lists-btn,
+.btn1 {
+    position: relative;
+    z-index: 1;
+    width: 140rpx;
+    height: 50rpx;
+    line-height: 50rpx;
+    opacity: 1;
+    border-radius: 24rpx;
+    margin: 12rpx 0 0 14rpx;
+    border: none;
+    font-size: 24rpx;
+    font-weight: 400;
+    padding: 0;
+    background: #FB4C6F;
+    color: white;
+    /*  */
+    overflow: inherit;
+}
+/* .lists-btn::before{
+  position: absolute;
+  content: '';
+  height: 1rpx;
+  width: 666rpx;
+  background-color: RGBA(220, 220, 220, 0.6);
+  display: block;
+  top: -12rpx;
+  z-index: 21;
+  left: -360rpx;
+} */
+.l-btns {
+    border-top: 1rpx solid RGBA(220, 220, 220, 0.6);
+    margin-top: 18rpx;
+}
+.btn1 {
+    line-height: 46rpx;
+    border: 1rpx solid #999999;
+    color: #333;
+    background: white;
+}
+/* .btn1::after{
+  border: none
+} */
+
+.integral {
+    background: #fff;
+    padding: 30rpx;
+    box-sizing: border-box;
+    width: 100%;
+    font-family: 微软雅黑;
+    margin: 0 auto 0;
+    font-size: 30rpx;
+    color: #333;
+    border-bottom: 1rpx solid #e5e5e5;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+}
+
+.integral-left {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+}
+
+.integral-left1 {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+}
+
+.integral-left image {
+    width: 180rpx;
+    height: 120rpx;
+    margin-right: 30rpx;
+}
+
+.integral-left view:nth-child(1) {
+    color: #333;
+}
+
+.integral-left view:nth-child(2) {
+    margin-top: 5rpx;
+    color: #999;
+    font-size: 25rpx;
+}
+
+.integral-right {
+    font-weight: bold;
+    font-size: 40rpx;
+}
+
+.integral-right1 {
+    font-weight: 100;
+    font-size: 26rpx;
+    margin-left: 5rpx;
+}
+.vice {
+    color: #999;
+    font-size: 25rpx;
+}
+
+.mask {
+    width: 100%;
+    height: 100vh;
+    position: fixed;
+    top: 0;
+    left: 0;
+    background: rgba(0, 0, 0, 0.5);
+    z-index: 999;
+}
+
+.qrcode {
+    width: 80%;
+    height: auto;
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+}
+.close {
+    margin: 30rpx auto;
+    width: 200rpx;
+    height: 70rpx;
+    background: #fff;
+    border-radius: 20rpx;
+    text-align: center;
+    line-height: 70rpx;
+}
+
+.qrcode image {
+    width: 100%;
+    height: auto;
+    border-radius: 10rpx;
+}
+
+.over_2{
+  overflow: hidden;
+text-overflow: ellipsis;
+display: -webkit-box;
+-webkit-box-orient: vertical;
+-webkit-line-clamp: 2;
+
+}
+.iflex{display: flex;}
+
+.iflexC{display: flex;flex-direction: column}
+
+</style>

File diff suppressed because it is too large
+ 1073 - 0
pages/intergalShop/orderDetail.vue


+ 22 - 0
pages/money/money.vue

@@ -0,0 +1,22 @@
+<template>
+	<view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 375 - 0
pages/money/pay.vue

@@ -0,0 +1,375 @@
+<template>
+	<view class="app">
+		<view class="price-box">
+			<text>支付金额</text>
+			<text class="price">{{total}}</text>
+		</view>
+
+		<view class="pay-type-list">
+			<view class="type-item b-b" @click="changePayType(1)" v-if="payTypeList.wxpay && total > 0">
+				<text class="icon yticon icon-wxpay"></text>
+				<view class="con">
+					<text class="tit">微信支付</text>
+				</view>
+				<label class="radio">
+					<radio value="" color="#fa436a" :checked='payType == 1' />
+					</radio>
+				</label>
+			</view>
+			<view class="type-item b-b" @click="changePayType(2)" v-if="payTypeList.alipay && total > 0">
+				<text class="icon yticon icon-alipay"></text>
+				<view class="con">
+					<text class="tit">支付宝支付</text>
+				</view>
+				<label class="radio">
+					<radio value="" color="#fa436a" :checked='payType == 2' />
+					</radio>
+				</label>
+			</view>
+			<!--
+			<view class="type-item b-b" @click="changePayType(3)" v-if="payTypeList.offline">
+				<text class="icon yticon icon-pay"></text>
+				<view class="con">
+					<text class="tit">货到付款</text>
+				</view>
+				<label class="radio">
+					<radio value="" color="#fa436a" :checked='payType == 3' />
+					</radio>
+				</label>
+			</view>
+			-->
+		</view>
+
+		<text class="mix-btn" @click="confirm">确认支付</text>
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	var jweixin = require('jweixin-module');
+	// #endif
+
+	export default {
+		data() {
+			return {
+				payType: 1,
+				orderInfo: {},
+				orderId: '',
+				payTypeList: {
+					wxpay: false,
+					alipay: false
+				},
+				total: 0.00
+			};
+		},
+		async onLoad(options) {
+			this.total = options.total;
+			this.orderId = options.order_id;
+			await this.getPayType();
+			// 如果传这个参数就直接支付了,(默认第一个是微信支付)
+			if (options.pay) {
+				this.confirm()
+			}
+		},
+		methods: {
+			// 获取支付方式
+			async getPayType() {
+				let type = await this.$api.request('/pay/getPayType');
+				if (type) {
+					this.payTypeList = type;
+				}
+			},
+			//选择支付方式
+			changePayType(type) {
+				this.payType = type;
+				switch (type) {
+					case 1: // 微信支付
+
+						break;
+					case 2: // 支付宝支付
+
+						break;
+					case 3: // 货到付款
+						break;
+				}
+			},
+			//确认支付
+			async confirm() {
+
+				if (this.payType == 1) {
+					// #ifdef H5 || APP-PLUS || MP-WEIXIN
+					this.weixinPay();
+					// #endif
+				} else if (this.payType == 2) {
+					// 支付宝支付
+					this.alipay();
+				} else if (this.payType == 3) {
+					// 货到付款
+					this.offlinePay();
+				}
+			},
+			async alipay() {
+				
+				// #ifdef H5
+				window.open(this.$unishow + '/pay/alipay?order_id='+this.orderId);
+				
+				setTimeout(function() {
+					uni.showModal({
+						title: '提示',
+						content: '是否已支付?',
+						cancelText: '否',
+						confirmText: '是',
+						success: function(res) {
+							if (res.confirm) {
+								uni.redirectTo({
+									url: '/pages/order/order?state=0'
+								});
+							} else if (res.cancel) {
+								//console.log('用户点击取消');
+							}
+						},
+						fail: function(res) {
+							//console.log(res)
+						}
+					});
+				}, 3000);
+				// #endif
+
+				// #ifdef APP-PLUS
+				let orderInfo = await this.$api.request('/pay/alipay', 'POST',{
+					order_id : this.orderId
+				});
+				if (orderInfo) {
+					//console.log(orderInfo);
+					uni.requestPayment({
+						provider: 'alipay',
+						orderInfo: orderInfo,
+						success: function (res) {
+							console.log('success:' + JSON.stringify(res));
+							uni.redirectTo({
+								url: '/pages/money/paySuccess'
+							})
+						},
+						fail: function (err) {
+							console.log('fail:' + JSON.stringify(err));
+							that.$api.msg('支付失败');
+						}
+					});
+				}
+				
+				// #endif
+				
+			},
+			async weixinPay() {
+				let data = await this.$api.request('/pay/unify', 'GET', {
+					order_id: this.orderId
+				});
+				let that = this;
+				if (data) {
+
+					if (data.trade_type == 'MWEB') {
+						// #ifdef H5
+						// 微信外的H5
+						location.href = data.mweb_url;
+						// #endif
+
+						// #ifdef APP-PLUS
+						// app 使用h5支付
+						var wv; //计划创建的webview 
+						wv = plus.webview.create("", "custom-webview", {
+							'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
+						})
+						wv.loadURL(data.mweb_url, {
+							Referer: data.referer
+						});
+
+						setTimeout(function() {
+							uni.showModal({
+								title: '提示',
+								content: '是否已支付?',
+								cancelText: '否',
+								confirmText: '是',
+								success: function(res) {
+									if (res.confirm) {
+										uni.redirectTo({
+											url: '/pages/order/order?state=0'
+										});
+									} else if (res.cancel) {
+										//console.log('用户点击取消');
+									}
+								},
+								fail: function(res) {
+									//console.log(res)
+								}
+							});
+						}, 3000);
+						// #endif
+
+					} else if (data.trade_type == 'JSAPI') {
+						if (data.weixinOauth2) {
+							// 微信oauth2授权(主要用来拿openid)
+							location.href = data.weixinOauth2
+							return;
+						}
+
+						// #ifdef H5
+						// 微信内的H5
+						let config = await this.$api.request('/pay/jssdkBuildConfig');
+						if (config) {
+							jweixin.config(config);
+							jweixin.ready(function() {
+								jweixin.chooseWXPay({
+									timestamp: data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
+									nonceStr: data.nonce_str, // 支付签名随机串,不长于 32 位
+									package: 'prepay_id=' + data.prepay_id, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
+									signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
+									paySign: data.paySign, // 支付签名
+									success: function(res) {
+										// 支付成功后的回调函数
+										uni.redirectTo({
+											url: '/pages/money/paySuccess'
+										})
+									},
+									fail: function(err) {
+										//console.log('fail:' + JSON.stringify(err));
+										//that.$api.msg('fail:' + JSON.stringify(err))
+										that.$api.msg('支付失败');
+									}
+								})
+							});
+							jweixin.error(function(res) {
+								//that.$api.msg(JSON.stringify(res));
+								that.$api.msg('支付失败');
+							});
+						} else {
+							that.$api.msg('支付失败');
+						}
+						// #endif
+
+						// #ifdef MP-WEIXIN
+						uni.requestPayment({
+							provider: 'wxpay',
+							timeStamp: data.timeStamp,
+							nonceStr: data.nonce_str,
+							package: 'prepay_id=' + data.prepay_id,
+							signType: 'MD5',
+							paySign: data.paySign,
+							success: function(res) {
+								uni.redirectTo({
+									url: '/pages/money/paySuccess'
+								})
+							},
+							fail: function(err) {
+								//console.log('fail:' + JSON.stringify(err));
+								//that.$api.msg('fail:' + JSON.stringify(err))
+								that.$api.msg('支付失败');
+							}
+						});
+						// #endif
+					}
+				}
+			},
+
+			async offlinePay() {
+				let data = await this.$api.request('/pay/offline', 'GET', {
+					order_id: this.orderId
+				});
+				if (data) {
+					uni.redirectTo({
+						url: '/pages/money/paySuccess'
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style lang='scss'>
+	.app {
+		width: 100%;
+	}
+
+	.price-box {
+		background-color: #fff;
+		height: 265upx;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		font-size: 28upx;
+		color: #909399;
+
+		.price {
+			font-size: 50upx;
+			color: #303133;
+			margin-top: 12upx;
+
+			&:before {
+				content: '¥';
+				font-size: 40upx;
+			}
+		}
+	}
+
+	.pay-type-list {
+		margin-top: 20upx;
+		background-color: #fff;
+		padding-left: 60upx;
+
+		.type-item {
+			height: 120upx;
+			padding: 20upx 0;
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			padding-right: 60upx;
+			font-size: 30upx;
+			position: relative;
+		}
+
+		.icon {
+			width: 100upx;
+			font-size: 52upx;
+		}
+
+		.icon-pay {
+			color: #fe8e2e;
+		}
+
+		.icon-wxpay {
+			color: #36cb59;
+		}
+
+		.icon-alipay {
+			color: #01aaef;
+		}
+
+		.tit {
+			font-size: $font-lg;
+			color: $font-color-dark;
+			margin-bottom: 4upx;
+		}
+
+		.con {
+			flex: 1;
+			display: flex;
+			flex-direction: column;
+			font-size: $font-sm;
+			color: $font-color-light;
+		}
+	}
+
+	.mix-btn {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		width: 630upx;
+		height: 80upx;
+		margin: 80upx auto 30upx;
+		font-size: $font-lg;
+		color: #fff;
+		background-color: $base-color;
+		border-radius: 10upx;
+		box-shadow: 1px 2px 5px rgba(219, 63, 96, 0.4);
+	}
+</style>

+ 61 - 0
pages/money/paySuccess.vue

@@ -0,0 +1,61 @@
+<template>
+	<view class="content">
+		<text class="success-icon yticon icon-xuanzhong"></text>
+		<text class="tit">支付成功</text>
+		<view class="btn-group">
+			<navigator url="/pages/order/order?state=0" open-type="redirect" class="mix-btn">查看订单</navigator>
+			<navigator url="/pages/index/index" open-type="switchTab" class="mix-btn hollow">返回首页</navigator>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang='scss'>
+	.content{
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+	.success-icon{
+		font-size: 160upx;
+		color: #fa436a;
+		margin-top: 100upx;
+	}
+	.tit{
+		font-size: 38upx;
+		color: #303133;
+	}
+	.btn-group{
+		padding-top: 100upx;
+	}
+	.mix-btn {
+		margin-top: 30upx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		width: 600upx;
+		height: 80upx;
+		font-size: $font-lg;
+		color: #fff;
+		background-color: $base-color;
+		border-radius: 10upx;
+		&.hollow{
+			background: #fff;
+			color: #303133;
+			border: 1px solid #ccc;
+		}
+	}
+</style>

+ 153 - 0
pages/notice/notice.vue

@@ -0,0 +1,153 @@
+<template>
+	<view>
+		<view class="notice-item">
+			<text class="time">11:30</text>
+			<view class="content">
+				<text class="title">新品上市,全场满199减50</text>
+				<view class="img-wrapper">
+					<image class="pic" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556465765776&di=57bb5ff70dc4f67dcdb856e5d123c9e7&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01fd015aa4d95fa801206d96069229.jpg%401280w_1l_2o_100sh.jpg"></image>
+				</view>
+				<text class="introduce">
+					虽然做了一件好事,但很有可能因此招来他人的无端猜测,例如被质疑是否藏有其他利己动机等,乃至谴责。即便如此,还是要做好事。
+				</text>
+				<view class="bot b-t">
+					<text>查看详情</text>
+					<text class="more-icon yticon icon-you"></text>
+				</view>
+			</view>
+		</view>
+		<view class="notice-item">
+			<text class="time">昨天 12:30</text>
+			<view class="content">
+				<text class="title">新品上市,全场满199减50</text>
+				<view class="img-wrapper">
+					<image class="pic" src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3761064275,227090144&fm=26&gp=0.jpg"></image>
+					<view class="cover">
+						活动结束
+					</view>
+				</view>
+				<view class="bot b-t">
+					<text>查看详情</text>
+					<text class="more-icon yticon icon-you"></text>
+				</view>
+			</view>
+		</view>
+		<view class="notice-item">
+			<text class="time">2019-07-26 12:30</text>
+			<view class="content">
+				<text class="title">新品上市,全场满199减50</text>
+				<view class="img-wrapper">
+					<image class="pic" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556465765776&di=57bb5ff70dc4f67dcdb856e5d123c9e7&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01fd015aa4d95fa801206d96069229.jpg%401280w_1l_2o_100sh.jpg"></image>
+					<view class="cover">
+						活动结束
+					</view>
+				</view>
+				<text class="introduce">新品上市全场2折起,新品上市全场2折起,新品上市全场2折起,新品上市全场2折起,新品上市全场2折起</text>
+				<view class="bot b-t">
+					<text>查看详情</text>
+					<text class="more-icon yticon icon-you"></text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style lang='scss'>
+	page {
+		background-color: #f7f7f7;
+		padding-bottom: 30upx;
+	}
+
+	.notice-item {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+	}
+
+	.time {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		height: 80upx;
+		padding-top: 10upx;
+		font-size: 26upx;
+		color: #7d7d7d;
+	}
+
+	.content {
+		width: 710upx;
+		padding: 0 24upx;
+		background-color: #fff;
+		border-radius: 4upx;
+	}
+
+	.title {
+		display: flex;
+		align-items: center;
+		height: 90upx;
+		font-size: 32upx;
+		color: #303133;
+	}
+
+	.img-wrapper {
+		width: 100%;
+		height: 260upx;
+		position: relative;
+	}
+
+	.pic {
+		display: block;
+		width: 100%;
+		height: 100%;
+		border-radius: 6upx;
+	}
+
+	.cover {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100%;
+		background-color: rgba(0, 0, 0, .5);
+		font-size: 36upx;
+		color: #fff;
+	}
+
+	.introduce {
+		display: inline-block;
+		padding: 16upx 0;
+		font-size: 28upx;
+		color: #606266;
+		line-height: 38upx;
+	}
+
+	.bot {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		height: 80upx;
+		font-size: 24upx;
+		color: #707070;
+		position: relative;
+	}
+
+	.more-icon {
+		font-size: 32upx;
+	}
+</style>

File diff suppressed because it is too large
+ 878 - 0
pages/order/createOrder.vue


+ 43 - 0
pages/order/delivery.vue

@@ -0,0 +1,43 @@
+<template>
+	<view>
+		<zTable :tableData="tableData" :columns="arr"></zTable>
+	</view>
+</template>
+
+<script>
+	import zTable from '@/components/z-table/z-table';
+	export default{
+		components:{
+			zTable
+		},
+		data() {
+			return{
+				tableData:['key1', 'key2'],
+				arr:[
+					{
+						"title": "title1",
+						"key" :"0"
+					},
+					{
+						"title": "title2",
+						"key" :"1"
+					}
+				]
+			}
+		},
+		onLoad() {
+			this.getTemplate();
+		},
+		methods:{
+			async getTemplate(){
+				let data = this.$api.request('');
+				if (data) {
+					
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+</style>

+ 172 - 0
pages/order/evaluate.vue

@@ -0,0 +1,172 @@
+<template>
+	<view class="bg">
+		<view class="header">
+			<image class="image" :src="image"></image>
+			<view class="right">
+				<view class="title">{{title}}</view>
+				<view class="spec">{{spec}}</view>
+			</view>
+		</view>
+		<view class="rate">
+			<view class="dec">描述相符</view>
+			<!-- 自定义星星大小 -->
+			<uni-rate class="start" active-color="#e64340" margin="10" size="30" :value="rate" @change="start"></uni-rate>
+		</view>
+		<view class="comment">
+			<textarea @input="input" maxlength="300" placeholder="写满20字,有机会被选为优质评价被更多人看到哦~" placeholder-class="placeholder"></textarea>
+		</view>
+		<view class="bottom">
+			<radio class="radio" color="#e64340" :checked='radio' @click="clickRadio" />公开</radio>
+			<view class="dec">公开头像昵称,大家可以看到我</view>
+		</view>
+		<button class="button" @click="submit" type="warn">提交</button>
+	</view>
+</template>
+
+<script>
+	import uniRate from '@/components/uni-rate/uni-rate.vue'
+
+	export default{
+		computed:{
+
+		},
+		components: {
+			uniRate
+		},
+		data(){
+			return {
+				order_id:0,
+				product_id:0,
+				title:'',
+				image:'',
+				spec:'',
+				rate:5,
+				radio:true,
+				textarea:''
+			}
+		},
+		onLoad(options) {
+			this.title = options.title;
+			this.image = options.image;
+			this.spec = options.spec;
+			this.order_id = options.order_id;
+			this.product_id = options.product_id;
+		},
+		methods:{
+			// 星星
+			start(e) {
+				this.rate = e.value;
+				switch (this.rate) {
+					case 3:
+						this.radio = false;
+						break;
+					case 5:
+						this.radio = true;
+						break;
+				}
+			},
+			// 单选
+			clickRadio(e) {
+				this.radio = !this.radio;
+			},
+			// 输入事件
+			input(e) {
+				this.textarea = e.detail.value;
+			},
+			// 提交
+			async submit(){
+				let data = this.$api.request('/order/comment', 'POST', 
+				{
+					order_id:this.order_id,
+					product_id:this.product_id,
+					rate:this.rate,
+					anonymous:!this.radio ? 1: 0,
+					comment:this.textarea,
+				});
+				if (data) {
+					let prePage = this.$api.prePage()
+					if (prePage.tabCurrentIndex) {
+						prePage.tabCurrentIndex = 0;
+					}
+					let that = this;
+					setTimeout(function(){
+						prePage.pullDownRefresh();
+						uni.navigateBack();
+					},2000)
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background: #f5f5f5;
+	}
+	.bg{
+		margin: 20rpx;
+		border-radius: 20rpx;
+		background-color: #ffffff;
+		padding-bottom: 10rpx;
+	}
+	.header {
+		padding: 20rpx;
+		.image{
+			width: 120rpx;
+			height: 120rpx;
+		}
+		.right{
+			display: inline-block;
+			line-height: 45rpx;
+			vertical-align: text-bottom;
+			padding-bottom: 10rpx; 
+			width: 550rpx;
+			padding-left:20rpx;
+			.title{
+				color: #707277;
+				font-size: 33rpx;
+				text-overflow: ellipsis;
+				white-space: nowrap;
+				overflow: hidden;
+			}
+			.spec{
+				color: #91949a;
+				font-size: 30rpx;
+			}
+		}
+	}
+	.rate{
+		padding:0 20rpx 20rpx;
+		.dec{
+			display: inline-block;
+			color: #707277;
+		}
+		.start{
+			width: 400rpx;
+			display: inline-block;
+
+		}
+	}
+	.comment{
+		padding: 20rpx;
+		textarea{
+			padding: 30rpx;
+			background-color: #f5f5f5;
+			width: 100%;
+		}
+	}
+	.bottom{
+		padding: 20rpx 20rpx 40rpx;
+		.radio{
+			vertical-align: bottom;
+			float: left;
+		}
+		.dec{
+			color: #91949a;
+			float: right;
+		}
+	}
+	.button{
+		margin: 20rpx;
+	}
+</style>

+ 0 - 0
pages/order/express.vue


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