ソースを参照

feat:任务页面编辑完成

DaMowang 3 年 前
コミット
7ed1a77f6d

+ 22 - 0
src/components/uni-popup/message.js

@@ -0,0 +1,22 @@
+export default {
+	created() {
+		if (this.type === 'message') {
+			// 不显示遮罩
+			this.maskShow = false 
+			// 获取子组件对象
+			this.childrenMsg = null
+		}
+	},
+	methods: {
+		customOpen() {
+			if (this.childrenMsg) {
+				this.childrenMsg.open()
+			}
+		},
+		customClose() {
+			if (this.childrenMsg) {
+				this.childrenMsg.close()
+			}
+		}
+	}
+}

+ 25 - 0
src/components/uni-popup/popup.js

@@ -0,0 +1,25 @@
+import message from './message.js';
+// 定义 type 类型:弹出类型:top/bottom/center
+const config = {
+	// 顶部弹出
+	top:'top',
+	// 底部弹出
+	bottom:'bottom',
+	// 居中弹出
+	center:'center',
+	// 消息提示
+	message:'top',
+	// 对话框
+	dialog:'center',
+	// 分享
+	share:'bottom',
+}
+
+export default {
+	data(){
+		return {
+			config:config
+		}
+	},
+	mixins: [message],
+}

+ 243 - 0
src/components/uni-popup/uni-popup-dialog.vue

@@ -0,0 +1,243 @@
+<template>
+	<view class="uni-popup-dialog">
+		<view class="uni-dialog-title">
+			<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{title}}</text>
+		</view>
+		<view class="uni-dialog-content">
+			<text class="uni-dialog-content-text" v-if="mode === 'base'">{{content}}</text>
+			<input v-else class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholder" :focus="focus" >
+		</view>
+		<view class="uni-dialog-button-group">
+			<view class="uni-dialog-button" @click="close">
+				<text class="uni-dialog-button-text">取消</text>
+			</view>
+			<view class="uni-dialog-button uni-border-left" @click="onOk">
+				<text class="uni-dialog-button-text uni-button-color">确定</text>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	/**
+	 * PopUp 弹出层-对话框样式
+	 * @description 弹出层-对话框样式
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} value input 模式下的默认值
+	 * @property {String} placeholder input 模式下输入提示
+	 * @property {String} type = [success|warning|info|error] 主题样式
+	 *  @value success 成功
+	 * 	@value warning 提示
+	 * 	@value info 消息
+	 * 	@value error 错误
+	 * @property {String} mode = [base|input] 模式、
+	 * 	@value base 基础对话框
+	 * 	@value input 可输入对话框
+	 * @property {String} content 对话框内容
+	 * @property {Boolean} beforeClose 是否拦截取消事件
+	 * @event {Function} confirm 点击确认按钮触发
+	 * @event {Function} close 点击取消按钮触发
+	 */
+
+	export default {
+		name: "uniPopupDialog",
+		props: {
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			placeholder: {
+				type: [String, Number],
+				default: '请输入内容'
+			},
+			/**
+			 * 对话框主题 success/warning/info/error	  默认 success
+			 */
+			type: {
+				type: String,
+				default: 'error'
+			},
+			/**
+			 * 对话框模式 base/input
+			 */
+			mode: {
+				type: String,
+				default: 'base'
+			},
+			/**
+			 * 对话框标题
+			 */
+			title: {
+				type: String,
+				default: '提示'
+			},
+			/**
+			 * 对话框内容
+			 */
+			content: {
+				type: String,
+				default: ''
+			},
+			/**
+			 * 拦截取消事件 ,如果拦截取消事件,必须监听close事件,执行 done()
+			 */
+			beforeClose: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				dialogType: 'error',
+				focus: false,
+				val: ""
+			}
+		},
+		inject: ['popup'],
+		watch: {
+			type(val) {
+				this.dialogType = val
+			},
+			mode(val) {
+				if (val === 'input') {
+					this.dialogType = 'info'
+				}
+			},
+			value(val) {
+				this.val = val
+			}
+		},
+		created() {
+			// 对话框遮罩不可点击
+			this.popup.mkclick = false
+			if (this.mode === 'input') {
+				this.dialogType = 'info'
+				this.val = this.value
+			} else {
+				this.dialogType = this.type
+			}
+		},
+		mounted() {
+			this.focus = true
+		},
+		methods: {
+			/**
+			 * 点击确认按钮
+			 */
+			onOk() {
+				this.$emit('confirm', () => {
+					this.popup.close()
+					if (this.mode === 'input') this.val = this.value
+				}, this.mode === 'input' ? this.val : '')
+			},
+			/**
+			 * 点击取消按钮
+			 */
+			close() {
+				if (this.beforeClose) {
+					this.$emit('close', () => {
+						this.popup.close()
+					})
+					return
+				}
+				this.popup.close()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-popup-dialog {
+		width: 300px;
+		border-radius: 15px;
+		background-color: #fff;
+	}
+
+	.uni-dialog-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		padding-top: 15px;
+		padding-bottom: 5px;
+	}
+
+	.uni-dialog-title-text {
+		font-size: 16px;
+		font-weight: 500;
+	}
+
+	.uni-dialog-content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		padding: 5px 15px 15px 15px;
+	}
+
+	.uni-dialog-content-text {
+		font-size: 14px;
+		color: #6e6e6e;
+	}
+
+	.uni-dialog-button-group {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		border-top-color: #f5f5f5;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-dialog-button {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+
+		flex: 1;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 45px;
+	}
+
+	.uni-border-left {
+		border-left-color: #f0f0f0;
+		border-left-style: solid;
+		border-left-width: 1px;
+	}
+
+	.uni-dialog-button-text {
+		font-size: 14px;
+	}
+
+	.uni-button-color {
+		color: $uni-color-primary;
+	}
+
+	.uni-dialog-input {
+		flex: 1;
+		font-size: 14px;
+	}
+
+	.uni-popup__success {
+		color: $uni-color-success;
+	}
+
+	.uni-popup__warn {
+		color: $uni-color-warning;
+	}
+
+	.uni-popup__error {
+		color: $uni-color-error;
+	}
+
+	.uni-popup__info {
+		color: #909399;
+	}
+</style>

+ 116 - 0
src/components/uni-popup/uni-popup-message.vue

@@ -0,0 +1,116 @@
+<template>
+	<view class="uni-popup-message" :class="'uni-popup__'+[type]">
+		<text class="uni-popup-message-text" :class="'uni-popup__'+[type]+'-text'">{{message}}</text>
+	</view>
+</template>
+
+<script>
+	
+	/**
+	 * PopUp 弹出层-消息提示
+	 * @description 弹出层-消息提示
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [success|warning|info|error] 主题样式
+	 *  @value success 成功
+	 * 	@value warning 提示
+	 * 	@value info 消息
+	 * 	@value error 错误
+	 * @property {String} message 消息提示文字
+	 * @property {String} duration 显示时间,设置为 0 则不会自动关闭
+	 */
+	
+	export default {
+		name: 'UniPopupMessage',
+		props: {
+			/**
+			 * 主题 success/warning/info/error	  默认 success
+			 */
+			type: {
+				type: String,
+				default: 'success'
+			},
+			/**
+			 * 消息文字
+			 */
+			message: {
+				type: String,
+				default: ''
+			},
+			/**
+			 * 显示时间,设置为 0 则不会自动关闭
+			 */
+			duration: {
+				type: Number,
+				default: 3000
+			}
+		},
+		inject: ['popup'],
+		data() {
+			return {}
+		},
+		created() {
+			this.popup.childrenMsg = this
+		},
+		methods: {
+			open() {
+				if (this.duration === 0) return
+				clearTimeout(this.popuptimer)
+				this.popuptimer = setTimeout(() => {
+					this.popup.close()
+				}, this.duration)
+			},
+			close() {
+				clearTimeout(this.popuptimer)
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.uni-popup-message {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		background-color: #e1f3d8;
+		padding: 10px 15px;
+		border-color: #eee;
+		border-style: solid;
+		border-width: 1px;
+	}
+	.uni-popup-message-text {
+		font-size: 14px;
+		padding: 0;
+	}
+
+	.uni-popup__success {
+		background-color: #e1f3d8;
+	}
+
+	.uni-popup__success-text {
+		color: #67C23A;
+	}
+
+	.uni-popup__warn {
+		background-color: #faecd8;
+	}
+
+	.uni-popup__warn-text {
+		color: #E6A23C;
+	}
+
+	.uni-popup__error {
+		background-color: #fde2e2;
+	}
+
+	.uni-popup__error-text {
+		color: #F56C6C;
+	}
+
+	.uni-popup__info {
+		background-color: #F2F6FC;
+	}
+
+	.uni-popup__info-text {
+		color: #909399;
+	}
+</style>

+ 165 - 0
src/components/uni-popup/uni-popup-share.vue

@@ -0,0 +1,165 @@
+<template>
+	<view class="uni-popup-share">
+		<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view>
+		<view class="uni-share-content">
+			<view class="uni-share-content-box">
+				<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
+					<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
+					<text class="uni-share-text">{{item.text}}</text>
+				</view>
+
+			</view>
+		</view>
+		<view class="uni-share-button-box">
+			<button class="uni-share-button" @click="close">取消</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'UniPopupShare',
+		props: {
+			title: {
+				type: String,
+				default: '分享到'
+			}
+		},
+		inject: ['popup'],
+		data() {
+			return {
+				bottomData: [{
+						text: '微信',
+						icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-2.png',
+						name: 'wx'
+					},
+					{
+						text: '支付宝',
+						icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-8.png',
+						name: 'wx'
+					},
+					{
+						text: 'QQ',
+						icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/gird-3.png',
+						name: 'qq'
+					},
+					{
+						text: '新浪',
+						icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-1.png',
+						name: 'sina'
+					},
+					{
+						text: '百度',
+						icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-7.png',
+						name: 'copy'
+					},
+					{
+						text: '其他',
+						icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-5.png',
+						name: 'more'
+					}
+				]
+			}
+		},
+		created() {},
+		methods: {
+			/**
+			 * 选择内容
+			 */
+			select(item, index) {
+				this.$emit('select', {
+					item,
+					index
+				}, () => {
+					this.popup.close()
+				})
+			},
+			/**
+			 * 关闭窗口
+			 */
+			close() {
+				this.popup.close()
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.uni-popup-share {
+		background-color: #fff;
+	}
+	.uni-share-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		height: 40px;
+	}
+	.uni-share-title-text {
+		font-size: 14px;
+		color: #666;
+	}
+	.uni-share-content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		padding-top: 10px;
+	}
+	
+	.uni-share-content-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: wrap;
+		width: 360px;
+	}
+	
+	.uni-share-content-item {
+		width: 90px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		padding: 10px 0;
+		align-items: center;
+	}
+	
+	.uni-share-content-item:active {
+		background-color: #f5f5f5;
+	}
+	
+	.uni-share-image {
+		width: 30px;
+		height: 30px;
+	}
+	
+	.uni-share-text {
+		margin-top: 10px;
+		font-size: 14px;
+		color: #3B4144;
+	}
+	
+	.uni-share-button-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		padding: 10px 15px;
+	}
+	
+	.uni-share-button {
+		flex: 1;
+		border-radius: 50px;
+		color: #666;
+		font-size: 16px;
+	}
+	
+	.uni-share-button::after {
+		border-radius: 50px;
+	}
+</style>

+ 294 - 0
src/components/uni-popup/uni-popup.vue

@@ -0,0 +1,294 @@
+<template>
+	<view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
+		<uni-transition v-if="maskShow" :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans"
+		 @click="onTap" />
+		<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
+			<view class="uni-popup__wrapper-box" @click.stop="clear">
+				<slot />
+			</view>
+		</uni-transition>
+	</view>
+</template>
+
+<script>
+	import uniTransition from '../uni-transition/uni-transition.vue'
+	import popup from './popup.js'
+	/**
+	 * PopUp 弹出层
+	 * @description 弹出层组件,为了解决遮罩弹层的问题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [top|center|bottom] 弹出方式
+	 * 	@value top 顶部弹出
+	 * 	@value center 中间弹出
+	 * 	@value bottom 底部弹出
+	 * 	@value message 消息提示
+	 * 	@value dialog 对话框
+	 * 	@value share 底部分享示例
+	 * @property {Boolean} animation = [ture|false] 是否开启动画
+	 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
+	 * @event {Function} change 打开关闭弹窗触发,e={show: false}
+	 */
+
+	export default {
+		name: 'UniPopup',
+		components: {
+			uniTransition
+		},
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			// message: 消息提示 ; dialog : 对话框
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			maskClick: {
+				type: Boolean,
+				default: true
+			}
+		},
+		provide() {
+			return {
+				popup: this
+			}
+		},
+		mixins: [popup],
+		watch: {
+			/**
+			 * 监听type类型
+			 */
+			type: {
+				handler: function(newVal) {
+					this[this.config[newVal]]()
+				},
+				immediate: true
+			},
+			/**
+			 * 监听遮罩是否可点击
+			 * @param {Object} val
+			 */
+			maskClick(val) {
+				this.mkclick = val
+			}
+		},
+		data() {
+			return {
+				duration: 300,
+				ani: [],
+				showPopup: false,
+				showTrans: false,
+				maskClass: {
+					'position': 'fixed',
+					'bottom': 0,
+					'top': 0,
+					'left': 0,
+					'right': 0,
+					'backgroundColor': 'rgba(0, 0, 0, 0.4)'
+				},
+				transClass: {
+					'position': 'fixed',
+					'left': 0,
+					'right': 0,
+				},
+				maskShow: true,
+				mkclick: true,
+				popupstyle: 'top'
+			}
+		},
+		created() {
+			this.mkclick = this.maskClick
+			if (this.animation) {
+				this.duration = 300
+			} else {
+				this.duration = 0
+			}
+		},
+		methods: {
+			clear(e) {
+				// TODO nvue 取消冒泡
+				e.stopPropagation()
+			},
+			open() {
+				this.showPopup = true
+				this.$nextTick(() => {
+					new Promise(resolve => {
+						clearTimeout(this.timer)
+						this.timer = setTimeout(() => {
+							this.showTrans = true
+							// fixed by mehaotian 兼容 app 端
+							this.$nextTick(() => {
+								resolve();
+							})
+						}, 50);
+					}).then(res => {
+						// 自定义打开事件
+						clearTimeout(this.msgtimer)
+						this.msgtimer = setTimeout(() => {
+							this.customOpen && this.customOpen()
+						}, 100)
+						this.$emit('change', {
+							show: true,
+							type: this.type
+						})
+					})
+				})
+			},
+			close(type) {
+				this.showTrans = false
+				this.$nextTick(() => {
+					this.$emit('change', {
+						show: false,
+						type: this.type
+					})
+					clearTimeout(this.timer)
+					// 自定义关闭事件
+					this.customOpen && this.customClose()
+					this.timer = setTimeout(() => {
+						this.showPopup = false
+					}, 300)
+				})
+			},
+			onTap() {
+				if (!this.mkclick) return
+				this.close()
+			},
+			/**
+			 * 顶部弹出样式处理
+			 */
+			top() {
+				this.popupstyle = 'top'
+				this.ani = ['slide-top']
+				this.transClass = {
+					'position': 'fixed',
+					'left': 0,
+					'right': 0,
+				}
+			},
+			/**
+			 * 底部弹出样式处理
+			 */
+			bottom() {
+				this.popupstyle = 'bottom'
+				this.ani = ['slide-bottom']
+				this.transClass = {
+					'position': 'fixed',
+					'left': 0,
+					'right': 0,
+					'bottom': 0
+				}
+			},
+			/**
+			 * 中间弹出样式处理
+			 */
+			center() {
+				this.popupstyle = 'center'
+				this.ani = ['zoom-out', 'fade']
+				this.transClass = {
+					'position': 'fixed',
+					/* #ifndef APP-NVUE */
+					'display': 'flex',
+					'flexDirection': 'column',
+					/* #endif */
+					'bottom': 0,
+					'left': 0,
+					'right': 0,
+					'top': 0,
+					'justifyContent': 'center',
+					'alignItems': 'center'
+				}
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.uni-popup {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-popup__mask {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: $uni-bg-color-mask;
+		opacity: 0;
+	}
+
+	.mask-ani {
+		transition-property: opacity;
+		transition-duration: 0.2s;
+	}
+
+	.uni-top-mask {
+		opacity: 1;
+	}
+
+	.uni-bottom-mask {
+		opacity: 1;
+	}
+
+	.uni-center-mask {
+		opacity: 1;
+	}
+
+	.uni-popup__wrapper {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: absolute;
+	}
+
+	.top {
+		/* #ifdef H5 */
+		top: var(--window-top);
+		/* #endif */
+		/* #ifndef H5 */
+		top: 0;
+		/* #endif */
+	}
+
+	.bottom {
+		bottom: 0;
+	}
+
+	.uni-popup__wrapper-box {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: relative;
+		/* iphonex 等安全区设置,底部安全区适配 */
+		/* #ifndef APP-NVUE */
+		padding-bottom: constant(safe-area-inset-bottom);
+		padding-bottom: env(safe-area-inset-bottom);
+		/* #endif */
+	}
+
+	.content-ani {
+		// transition: transform 0.3s;
+		transition-property: transform, opacity;
+		transition-duration: 0.2s;
+	}
+
+
+	.uni-top-content {
+		transform: translateY(0);
+	}
+
+	.uni-bottom-content {
+		transform: translateY(0);
+	}
+
+	.uni-center-content {
+		transform: scale(1);
+		opacity: 1;
+	}
+</style>

+ 279 - 0
src/components/uni-transition/uni-transition.vue

@@ -0,0 +1,279 @@
+<template>
+	<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
+	 @click="change">
+		 <slot></slot>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const animation = uni.requireNativePlugin('animation');
+	// #endif
+	/**
+	 * Transition 过渡动画
+	 * @description 简单过渡动画组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=985
+	 * @property {Boolean} show = [false|true] 控制组件显示或隐藏
+     * @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
+     *  @value fade 渐隐渐出过渡
+     *  @value slide-top 由上至下过渡
+     *  @value slide-right 由右至左过渡
+     *  @value slide-bottom 由下至上过渡
+     *  @value slide-left 由左至右过渡
+     *  @value zoom-in 由小到大过渡
+     *  @value zoom-out 由大到小过渡
+	 * @property {Number} duration 过渡动画持续时间
+	 * @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
+	 */
+	export default {
+		name: 'uniTransition',
+		props: {
+			show: {
+				type: Boolean,
+				default: false
+			},
+			modeClass: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			duration: {
+				type: Number,
+				default: 300
+			},
+			styles: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		data() {
+			return {
+				isShow: false,
+				transform: '',
+				ani: { in: '',
+					active: ''
+				}
+			};
+		},
+		watch: {
+			show: {
+				handler(newVal) {
+					if (newVal) {
+						this.open()
+					} else {
+						this.close()
+					}
+				},
+				immediate: true
+			}
+		},
+		computed: {
+			stylesObject() {
+				let styles = {
+					...this.styles,
+					'transition-duration': this.duration / 1000 + 's'
+				}
+				let transfrom = ''
+				for (let i in styles) {
+					let line = this.toLine(i)
+					transfrom += line + ':' + styles[i] + ';'
+				}
+				return transfrom
+			}
+		},
+		created() {
+			// this.timer = null
+			// this.nextTick = (time = 50) => new Promise(resolve => {
+			// 	clearTimeout(this.timer)
+			// 	this.timer = setTimeout(resolve, time)
+			// 	return this.timer
+			// });
+		},
+		methods: {
+			change() {
+				this.$emit('click', {
+					detail: this.isShow
+				})
+			},
+			open() {
+				clearTimeout(this.timer)
+				this.isShow = true
+				this.transform = ''
+				this.ani.in = ''
+				for (let i in this.getTranfrom(false)) {
+					if (i === 'opacity') {
+						this.ani.in = 'fade-in'
+					} else {
+						this.transform += `${this.getTranfrom(false)[i]} `
+					}
+				}
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this._animation(true)
+					}, 50)
+				})
+
+			},
+			close(type) {
+				clearTimeout(this.timer)
+				this._animation(false)
+			},
+			_animation(type) {
+				let styles = this.getTranfrom(type)
+				// #ifdef APP-NVUE
+				if(!this.$refs['ani']) return
+				animation.transition(this.$refs['ani'].ref, {
+					styles,
+					duration: this.duration, //ms
+					timingFunction: 'ease',
+					needLayout: false,
+					delay: 0 //ms
+				}, () => {
+					if (!type) {
+						this.isShow = false
+					}
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				})
+				// #endif
+				// #ifndef APP-NVUE
+				this.transform = ''
+				for (let i in styles) {
+					if (i === 'opacity') {
+						this.ani.in = `fade-${type?'out':'in'}`
+					} else {
+						this.transform += `${styles[i]} `
+					}
+				}
+				this.timer = setTimeout(() => {
+					if (!type) {
+						this.isShow = false
+					}
+					this.$emit('change', {
+						detail: this.isShow
+					})
+
+				}, this.duration)
+				// #endif
+
+			},
+			getTranfrom(type) {
+				let styles = {
+					transform: ''
+				}
+				this.modeClass.forEach((mode) => {
+					switch (mode) {
+						case 'fade':
+							styles.opacity = type ? 1 : 0
+							break;
+						case 'slide-top':
+							styles.transform += `translateY(${type?'0':'-100%'}) `
+							break;
+						case 'slide-right':
+							styles.transform += `translateX(${type?'0':'100%'}) `
+							break;
+						case 'slide-bottom':
+							styles.transform += `translateY(${type?'0':'100%'}) `
+							break;
+						case 'slide-left':
+							styles.transform += `translateX(${type?'0':'-100%'}) `
+							break;
+						case 'zoom-in':
+							styles.transform += `scale(${type?1:0.8}) `
+							break;
+						case 'zoom-out':
+							styles.transform += `scale(${type?1:1.2}) `
+							break;
+					}
+				})
+				return styles
+			},
+			_modeClassArr(type) {
+				let mode = this.modeClass
+				if (typeof(mode) !== "string") {
+					let modestr = ''
+					mode.forEach((item) => {
+						modestr += (item + '-' + type + ',')
+					})
+					return modestr.substr(0, modestr.length - 1)
+				} else {
+					return mode + '-' + type
+				}
+			},
+			// getEl(el) {
+			// 	console.log(el || el.ref || null);
+			// 	return el || el.ref || null
+			// },
+			toLine(name) {
+				return name.replace(/([A-Z])/g, "-$1").toLowerCase();
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-transition {
+		transition-timing-function: ease;
+		transition-duration: 0.3s;
+		transition-property: transform, opacity;
+	}
+
+	.fade-in {
+		opacity: 0;
+	}
+
+	.fade-active {
+		opacity: 1;
+	}
+
+	.slide-top-in {
+		/* transition-property: transform, opacity; */
+		transform: translateY(-100%);
+	}
+
+	.slide-top-active {
+		transform: translateY(0);
+		/* opacity: 1; */
+	}
+
+	.slide-right-in {
+		transform: translateX(100%);
+	}
+
+	.slide-right-active {
+		transform: translateX(0);
+	}
+
+	.slide-bottom-in {
+		transform: translateY(100%);
+	}
+
+	.slide-bottom-active {
+		transform: translateY(0);
+	}
+
+	.slide-left-in {
+		transform: translateX(-100%);
+	}
+
+	.slide-left-active {
+		transform: translateX(0);
+		opacity: 1;
+	}
+
+	.zoom-in-in {
+		transform: scale(0.8);
+	}
+
+	.zoom-out-active {
+		transform: scale(1);
+	}
+
+	.zoom-out-in {
+		transform: scale(1.2);
+	}
+</style>

+ 503 - 17
src/pages/sign/index.vue

@@ -1,21 +1,507 @@
 <template>
-  <div class='sign'></div>
+	<view class="container">
+		<!-- 页面标题 -->
+		<!-- <view class="pageTitle flex_r flex_ac flex_jc">签到</view> -->
+		<!-- 页面标题-end -->
+		
+		<!-- 用户信息 -->
+		<view class="userinfo flex_r flex_ac">
+			<image class="user_img" :src="userInof.headimgurl ? userInof.headimgurl : 'https://tea.soowin.com/mnt/image/m_avar.jpg'" mode=""></image>
+			<view class="user_info flex_c flex_jc">
+				<view class="user_name">{{userinfo.headimgurl}}</view>
+				<view class="level_con flex_r flex_ac">
+					<view class="level">{{userInof.level}}</view>
+				</view>
+			</view>
+			<!-- <view class="record flex_r flex_ac flex_jc" @tap="NavToSignList">积分记录</view> -->
+		</view>
+		<!-- 用户信息-end -->
+		
+		<!-- 签到信息 -->
+		<view class="sign_info flex_c">
+			<view class="info flex_r flex_ac flex_jb">
+				<view class="info_today flex_c flex_ac">
+					<view class="today_text g_color">{{integerInfo.todaySignIn || 0}}</view>
+					<view class="info_text">今日签到</view>
+				</view>
+				<view class="info_today flex_c flex_ac">
+					<view class="today_text">{{integerInfo.continueCount || 0}}</view>
+					<view class="info_text">累计签到({{integerInfo.continueCount || 0}}次)</view>
+				</view>
+				<view class="info_con">
+					<image class="info_img" :src="integerInfo.time > 0 ? '/static/sgin/p_back2.png' : '/static/sgin/p_back.png'" mode=""></image>
+					<view class="info_texts flex_r flex_ac flex_jc" @tap="setSignIn">{{integerInfo.time > 0 ? timer : ''}}<text v-if="integerInfo.time <= 0">立即签到</text></view>
+				</view>
+			</view>
+			<view class="sign_time flex_r flex_ac flex_je mar_t20">
+				<text></text>
+			</view>
+		</view>
+		<!-- 签到信息-end -->
+		
+		<!-- 积分兑好礼 -->
+		<view class="integral mar_t30" v-if="list.length != 0 && list[0] != ''">
+			<view class="inte_title flex_r flex_ae flex_jb">
+				积分兑好礼
+				<view class="more flex_r flex_ac" @tap="goToIntegralList">更多
+          <text class="not_ico iconfont">&#xe62e;</text>
+					<!-- <image class="more_img" src="/static/sgin/more.png" mode=""></image> -->
+				</view>
+			</view>
+			<view class="inte_con mar_t30 flex_r flex_ac">
+				<view class="inte_goods" v-for="(item,index) in list" :key="index" @tap="openConversion(item.goodsId)">
+					<image class="goods_img" :src="item.goodsThumbnailUrl" mode=""></image>
+					<view class="goods_name ellipsis">{{item.goodsName}}</view>
+					<view class="goods_price">{{item.integral}}<text>积分</text></view>
+				</view>
+			</view>
+		</view>
+		<!-- 积分兑好礼-end -->
+		
+		<!-- 精品推荐 -->
+		<view class="Boutique" v-if="goods.length != 0 && goods[0] != ''">
+			<view class="bou_head flex_r flex_ac flex_jc">
+				<image class="bou_img" src="/static/sgin/left.png" mode=""></image>
+				<view class="bou_title">精品推荐</view>
+				<image class="bou_img" src="/static/sgin/right.png" mode=""></image>
+			</view>
+			<view class="bou_con flex_r flex_ac flex_wrap">
+				<view class="bou_list" v-for="(item,index) in goods" :key="index" @tap="openConversion(item.goodsId)">
+					<image class="bou_l_img" :src="item.goodsThumbnailUrl" mode=""></image>
+					<view class="bou_l_con">
+						<view class="bou_l_name ellipsis">{{item.goodsName}}</view>
+						<!-- <view class="bou_l_info flex_r flex_ae mar_t16">
+							<view class="bou_l_price flex_r flex_ae"><text>¥</text>450</view>
+							<view class="bou_l_cost">¥414</view>
+						</view> -->
+						<view class="bou_l_msg">{{item.integral}}积分可兑换</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class='fz_w_text mar_b20 mar_t20'>茶,让生活更美好!</view>
+		<!-- 精品推荐-end -->
+		
+		<!-- 兑换弹窗 -->
+		<uni-popup type="center" ref="conversion">
+			<view class="const_con">
+				<image class="closePopup" src="/static/sgin/f_close.png" mode="" @tap="closePopup"></image>
+				<view class="const_head flex_r flex_ac flex_jc">请选择兑换方式</view>
+				<view class="const_info">
+					<view class="frist_info flex_r flex_wrap">
+						<view class="frist_list flex_c mar_b30" v-for="(item,index) in way_list" :key="index" @tap="setCurrent(index)">
+							<view class="flex_r flex_ac">
+								<image class="frist_img" :src="currrent == index ? '/static/sgin/xuanzhong_icon.png' : '/static/sgin/weixuanzhong_icon.png'" mode=""></image>
+								<view class="frist_text">{{item.name}}</view>
+							</view>
+							<view class="surplus">剩余({{item.Integral}}积分)</view>
+						</view>
+					</view>
+					<view class="hint" v-if="isShow">积分不足请用余额或现金支付</view>
+					<view class="pay_way flex_r flex_ac flex_wrap mar_t30" v-if="isShow">
+						<view class="frist_list flex_c">
+							<view class="flex_r flex_ac" @tap="setPayWay(0)">
+								<image class="frist_img" :src="pay_way == 0 ? '/static/sgin/xuanzhong_icon.png' : '/static/sgin/weixuanzhong_icon.png'" mode=""></image>
+								<view class="frist_text">余额</view>
+							</view>
+						</view>
+						<view class="frist_list flex_c">
+							<view class="flex_r flex_ac" @tap="setPayWay(1)">
+								<image class="frist_img" :src="pay_way == 1 ? '/static/sgin/xuanzhong_icon.png' : '/static/sgin/weixuanzhong_icon.png'" mode=""></image>
+								<view class="frist_text">现金</view>
+							</view>
+						</view>
+					</view>
+					<checkbox-group class="flex_r flex_ac flex_jc" @change="checkboxChange">
+						<label class="option_box mar_t30">
+							<checkbox value="1" :checked="checked" color="#2DB389" style="transform:scale(0.7)" /> 我已阅读同意<text @tap.stop="getProPage">《购买协议》</text>
+						</label>
+					</checkbox-group>
+					<view class="conversion flex_r flex_ac flex_jc" @tap="confimConver">确认兑换</view>
+				</view>
+			</view>
+		</uni-popup>
+		<!-- 兑换弹窗-end -->
+		
+		<!-- 授权 -->
+		<authorize-module v-if="showAuth" :shopInfo="shopInfo" @authSuccess="onAuthSuccess" @onGotUserInfo="onGotUserInfo" ></authorize-module>
+		<!-- 授权-end -->
+	</view>
 </template>
+
 <script>
-import { get, post } from '@/request/api.js';
-export default {
-  name: 'sign',
-  data () {
-    return {}
-  },
-  onLoad (option) {},
-  onLaunch () {},
-  onShow () {},
-  onHide () {},
-  methods: {},
-  computed: {},
-  watch: {}
-}
+var tim
+let page = 1;
+let app = getApp();
+var appEv = app.$vm.$options;
+import uniPopup from '@/components/uni-popup/uni-popup.vue'
+import authorizeModule from '@/components/authorize-module/index'
+import { get, post } from "@/request/api.js";
+	export default {
+		components:{uniPopup,authorizeModule},
+		data() {
+			return {
+				integerInfo:{}, // 积分详情
+				userInof:{} ,// 用户详情
+				timer:'00:00:00' ,// 倒计时
+				list:[] ,// 积分兑好礼
+				goods:[] ,// 精品推荐
+				haveGoods:false ,// 是否有商品
+				way_list:[] ,//兑换方式
+				checked:false, //是否选中协议
+				currrent:0 ,// 选中的兑换方式
+				pay_way:0 ,//选中的支付方式
+				isShow: false ,// 是否显示现金支付
+				goodsId:'' ,// 选中的商品Id
+				showAuth:true, //是否显示授权弹窗
+				shopInfo:{} // 商户信息
+			};
+		},
+		onShow:function(){
+			this.timer = '00:00:00'
+			this.loadData()
+			this.goodsDay()
+			this.getInteGoods()
+			this.integralMethodChange()
+			let that = this;
+			let userId = app.globalData.systemUserInfo && app.globalData.systemUserInfo.userId ? app.globalData.systemUserInfo.userId : '';
+			if (!userId || userId == '' || userId==undefined) {
+				that.showAuth=true
+				appEv.authorizeUserInfo(res=>{
+					if(res){
+						that.showAuth=false
+						that.shopInfo=app.globalData.shopInfo
+					}
+				},true)
+			}else{
+				that.showAuth=false
+				that.shopInfo=app.globalData.shopInfo
+			}
+		},
+		onHide:function(){
+			clearInterval(tim)
+		},
+		methods:{
+			loadData:function(){
+				let that = this;
+        post("ShuZiTeaIntegral/integral/integralInfoNew",{
+          userId: 2064
+        }).then(res => {
+          if(res.status == 200){
+            that.integerInfo = res.integerInfo
+            that.userInof = res.userInof
+            that.setTime()
+          }
+        })
+			},
+			//授权并登录
+			onAuthSuccess:function() {
+			    var that = this;
+			    uni.showLoading({ mask: true })
+			    appEv.setData((res) => {
+					uni.hideLoading()
+					that.loadData()
+					that.showAuth = false
+			    });
+			},
+			// 距可以签到倒计时
+			setTime:function(){
+				var date;
+				let that = this;
+				let timer = that.integerInfo.time / 1000
+				tim = setInterval(()=>{
+					if(timer>=1){
+						timer --
+					}else{
+						clearInterval(tim)
+					}
+					
+					let hour = parseInt(timer/3600) > 9 ? parseInt(timer/3600) : '0' + parseInt(timer/3600)
+					let min = parseInt(timer / 60 % 60) > 9 ? parseInt(timer / 60 % 60) : '0' + parseInt(timer / 60 % 60)
+					let sec = parseInt(timer % 60) > 9 ? parseInt(timer % 60) : '0' + parseInt(timer % 60)
+					
+					date = hour + ':' + min + ':' + sec;
+					this.timer = date
+				},999)
+			},
+			// 签到
+			setSignIn:function(){
+				let that = this;
+        post("ShuZiTeaIntegral/integral/reportNew",{
+          userId: 2064
+        }).then(res => {
+          if(res.status == 200){
+            console.log(res)
+            appEv.errTips(res.msg)
+            that.loadData()
+          }else{
+            appEv.errTips(res.msg)
+          }
+        })
+			},
+			// 获取积分兑好礼商品列表
+			getInteGoods:function(){
+				let that = this;
+				let data = {
+					page:1,
+					limit:3
+				}
+        post("ShuZiTeaIntegral/integral/goods",data).then(res => {
+          if(res.status == 200){
+            that.list = res.goods
+          }else{
+            appEv.errTips(res.msg)
+          }
+        })
+			},
+			// 获取精品推荐
+			goodsDay:function(){
+				let that = this;
+				let data = {
+					page: page,
+					limit: 10
+				}
+        post("/ShuZiTeaIntegral/integral/goodsDay",data).then(res => {
+          if(res.status == 200){
+            let obj = res.goods
+            that.goods = []
+            if(obj.length>0){
+              for(var i in obj){
+                that.goods.push(obj[i])
+              }
+            }else{
+              if(page == 1){
+                that.haveGoods = true
+                page = -1
+              }else{
+                page = -1
+                appEv.errTips('暂无更多')
+              }
+            }
+          }else{
+            if(page == 1){
+              that.haveGoods = true
+              page = -1
+            }else{
+              page = -1
+              appEv.errTips('暂无更多')
+            }
+          }
+        })
+			},
+			// 获取兑换方式
+			integralMethodChange:function(){
+				let that = this;
+        post("ShuZiTeaIntegral/integral/integralMethodChange").then(res => {
+          if(res.status == 200){
+            that.way_list = res.data
+          }
+        })
+			},
+			// 更改方式
+			setCurrent:function(e){
+				this.currrent = e;
+				this.pay_way = '';
+				this.isShow = false;
+			},
+			// 更改支付方式
+			setPayWay:function(e){
+				this.pay_way = e;
+			},
+			// 确认兑换
+			confimConver:function(){
+				let that = this;
+				let isShow = this.isShow;
+				let pay_way = this.pay_way;
+				let checked = this.checked;
+				let currrent = this.currrent;
+				if(currrent === ''){
+					appEv.errTips('请选择兑换方式')
+					return false;
+				}
+				if(isShow && pay_way === ''){
+					appEv.errTips('请选择支付方式')
+					return false;
+				}
+				if(!checked){
+					appEv.errTips('请阅读并同意购买协议')
+					return false;
+				}
+				let data = {
+					goodsId:this.goodsId,
+					xyType:1,
+					integralType:this.way_list[this.currrent].type,
+					count:1
+				}
+				if(isShow){
+					data.jeType = this.pay_way == 0 ? 4 : 5
+				}else{
+					data.jeType = 3
+				}
+				
+				const info = reqApi.integralClickExchange(data)
+				if(info){
+					info.then(res => {
+						if(res.status == 200){
+							appEv.errTips(res.msg)
+							let goodsId = that.goodsId;
+							let count = 1;
+							let goodsType = 5;
+							let ojsType = 1;
+							let payType = !isShow ? 3 : isShow && pay_way == 0 ? 4 : isShow && pay_way == 1 ? 5 : isShow && that.way_list[that.currrent].Integral == 0 ? 6 : ''
+							setTimeout(() => {
+								uni.navigateTo({
+									url:'/pages/to-pay-list/index?goodsId=' + goodsId + "&count=" + count + '&goodsType=' + goodsType + '&ojsType=' + ojsType + '&payType=' + payType
+								})
+							},800)
+						}else{
+							appEv.errTips(res.msg)
+							that.isShow = true;
+						}
+					})
+				}
+			},
+			// 更改协议选中情况
+			checkboxChange:function(e){
+				let index = e.detail.value.indexOf('1');
+				if(index != -1){
+					this.checked = true
+				}else{
+					this.checked = false
+				}
+			},
+			// 点击立即兑换打开弹窗
+			openConversion:function(e){
+				this.goodsId = e
+				this.$refs.conversion.open()
+			},
+			// 关闭立即兑换弹窗
+			closePopup:function(){
+				this.$refs.conversion.close()
+			},
+			// 跳转到积分明细列表
+			NavToSignList:function(){
+				uni.navigateTo({
+					url:'/pages/sign-list/index'
+				})
+			},
+			// 跳转到积分列表页面
+			goToIntegralList:function(){
+				uni.navigateTo({
+					url:'/pages/integral-list/index'
+				})
+			},
+			getProPage:function(){
+				uni.navigateTo({
+					url:'/pages/protocol/index?type=' + 4
+				})
+			}
+		}
+	}
 </script>
-<style scoped lang='scss'>
-</style>
+
+<style lang="scss">
+// 页面配置
+page{background: #f5f5f5;}
+.container{padding:var(--status-bar-height) 30rpx 30rpx;box-sizing: border-box;background: url('https://tea.soowin.com/mnt/image/sign_back.png');background-repeat: no-repeat;background-size: 100% 427rpx;}
+// 页面配置-end
+
+// 页面标题
+.pageTitle{font-size: 28rpx;color:#fff;height: 64rpx;}
+// 页面标题-end
+
+// 用户信息
+.userinfo{
+  width: 100%;
+  // margin-top: 24rpx;
+  position: relative;
+}
+.user_img{width: 101.5rpx;height: 101.5rpx;margin-right: 20rpx;border-radius: 50%;}
+.level{background: rgba(0,0,0,.18);padding:6rpx 24rpx;font-size: 24rpx;color:#fff;border-radius: 100rpx;}
+.user_name{font-size: 30rpx;color:#fff;font-family: "SourceHanSansSC-Medium";font-weight: 500;margin-bottom: 18rpx;line-height: 1;}
+.record{width: 136rpx;height: 54rpx;background: rgba(0,0,0,.18);color:#fff;font-size: 24rpx;border-radius: 27rpx 0 0 27rpx;position: absolute;bottom:calc(50% - 27rpx);right:-30rpx;}
+// 用户信息-end
+
+// 签到信息
+.info{width: 100%;overflow: hidden;}
+.info_text{font-size: 24rpx;color:#404040;}
+.info_con{width: 185rpx;height: 185rpx;position: relative;}
+.info_img{width: 100%;height: 185rpx;animation: myfirst 1s infinite;}
+.info_texts{width:100%;height: 100%;position: absolute;top: 0;left: 0;}
+.today_text{font-family: "SourceHanSansCN-Medium";font-size: 53rpx;color:#373737;}
+.info_texts text{width: 56rpx;text-align: justify;font-size: 28rpx;color:#12B381;}
+.sign_time text{width: 185rpx;overflow: hidden;font-size: 36rpx;color:#353535;font-family: "SourceHanSansCN-Bold";font-weight: bold;}
+.sign_info{width: 100%;overflow: hidden;background: #fff;border-radius: 16rpx;box-shadow: 0px 3px 0px 0px rgba(16, 178, 127, 0.36), 0px 6px 10px 0px rgba(17, 179, 129, 0.2);padding:24rpx 40rpx;box-sizing: border-box;margin-top: 44rpx;}
+
+.g_color{color:#12B381;}
+.gr_color{color:#999 !important;}
+// 签到信息-end
+
+
+// 动画效果
+@keyframes myfirst
+{
+	0%   {transform: rotate(0);}
+	10%  {transform: rotate(-36deg);}
+	20%  {transform: rotate(-72deg);}
+	30%  {transform: rotate(-108deg);}
+	40%  {transform: rotate(-144deg);}
+	50%  {transform: rotate(-180deg);}
+	60%  {transform: rotate(-216deg);}
+	70%  {transform: rotate(-252deg);}
+	80%  {transform: rotate(-288deg);}
+	90%  {transform: rotate(-324deg);}
+	100% {transform: rotate(-360deg);}
+}
+// 动画效果-end
+
+// 积分兑好礼
+.more{font-size: 24rpx;color:#313131;}
+.inte_con{width: 100%;overflow: hidden;}
+.goods_price{font-size: 30rpx;color:#F15C21;}
+.inte_goods:nth-last-child(1){margin-right: 0;}
+.goods_price text{font-size: 18rpx;color:#F15C21;}
+.more_img{width: 9rpx;height: 16rpx;margin-left: 10rpx;}
+.goods_img{width: 100%;height: 141rpx;margin-bottom: 16rpx;}
+.goods_name{width: 100%;overflow: hidden;color:#1D1D1D;font-size: 24rpx;}
+.inte_goods{width: calc((100% - 28rpx) / 3);margin-right: 14rpx;overflow: hidden;}
+.inte_title{font-size: 36rpx;color:#2A2A2A;font-family: "SourceHanSansSC-Bold";font-weight: bold;}
+.integral{width: 100%;overflow: hidden;background:#fff;padding: 30rpx;box-sizing: border-box;border-radius: 20rpx;}
+// 积分兑好礼-end
+
+// 精品推荐
+.bou_img{width: 89rpx;height: 30rpx;}
+.bou_head{width: 100%;height: 114rpx;}
+.bou_con{width: 100%;overflow: hidden;}
+.Boutique{width: 100%;overflow: hidden;}
+.bou_list:nth-child(2n){margin-right: 0;}
+.bou_l_info{width: 100%;overflow: hidden;}
+.bou_l_img{width: 100%;height: 238rpx;display: block;}
+.bou_l_price text{font-size: 24rpx;color:#F15C21;line-height: 1;}
+.bou_l_name{width: 100%;overflow: hidden;font-size: 28rpx;color:#121212;}
+.bou_l_con{width: 100%;overflow: hidden;padding: 20rpx;box-sizing: border-box;}
+.bou_l_msg{width: 100%;overflow: hidden;font-size: 22rpx;color:#F15C21;margin-top: 10rpx;}
+.bou_l_cost{font-size: 24rpx;color:#CCCCCC;text-decoration: line-through;line-height: 1;margin-left: 11rpx;}
+.bou_l_price{font-size: 32rpx;color:#F15C21;font-size:"SourceHanSansSC-Bold";font-weight: bold;line-height: 1;}
+.bou_title{font-size: 36rpx;color:#121212;font-family: "SourceHanSansSC-Bold";font-weight: bold;margin: 0 49rpx;}
+.bou_list{width: calc((100% - 10rpx) / 2);margin-right: 10rpx;margin-bottom: 30rpx;background: #fff;border-radius: 6rpx;overflow: hidden;}
+// 精品推荐-end
+
+
+// 兑换弹窗
+.option_box{font-size: 26rpx;}
+.option_box text{color:#2DB389;}
+.hint{font-size: 20rpx;color:#D54912;}
+.pay_way{width: 100%;overflow: hidden;}
+.frist_list{width: 50%;overflow: hidden;}
+.surplus{font-size: 22rpx;color:#A8A8A8;}
+.frist_text{font-size: 28rpx;color:#302F2F;}
+.frist_img{width: 35rpx;height: 35rpx;margin-right: 32rpx;}
+.frist_info{width: 100%;overflow: hidden;align-items: initial;}
+.closePopup{width: 42rpx;height: 42rpx;position: absolute;right: 0;top: -65rpx;}
+.const_con{width: 689rpx;border-radius: 10rpx;background: #fff;position: relative;}
+.const_info{width: 100%;overflow: hidden;padding:30rpx 50rpx;box-sizing: border-box;}
+.const_head{width: 100%;height: 97rpx;border-bottom:3rpx solid rgba(0,0,0,.15);font-size: 40rpx;color:#1BBD89;font-family: "SourceHanSansCN-Medium";}
+.conversion{width: 269rpx;height: 68rpx;background: #1BBE8A;font-family: "SourceHanSansCN-Medium";color:#fff;font-size: 32rpx;border-radius: 34rpx;margin: 40rpx auto 0;}
+// 兑换弹窗-end
+</style>

BIN
src/static/sgin/f_close.png


BIN
src/static/sgin/left.png


BIN
src/static/sgin/p_back.png


BIN
src/static/sgin/p_back2.png


BIN
src/static/sgin/right.png


BIN
src/static/sgin/weixuanzhong_icon.png


BIN
src/static/sgin/xuanzhong_icon.png