Ver código fonte

最后修改:整理首页代码,添加跳方向代码等

slambb 4 anos atrás
commit
f8558bd69d
100 arquivos alterados com 46114 adições e 0 exclusões
  1. 94 0
      App.vue
  2. 22 0
      common/checker.js
  3. 164 0
      common/config.js
  4. 475 0
      components/code-elf-guide/code-elf-guide.vue
  5. 111 0
      components/code-elf-guide/uni-guide.md
  6. 123 0
      components/effectHit/hitEffect.vue
  7. 402 0
      components/effectHit/hitFistEffect.vue
  8. 110 0
      components/electAni/character.vue
  9. 371 0
      components/electAni/electAnimation.vue
  10. 66 0
      components/fruitMachine/fruit.js
  11. 242 0
      components/fruitMachine/fruitMachine.vue
  12. 41 0
      components/keyboard-listener/keyboard-listener.vue
  13. 377 0
      components/m-icon/m-icon.css
  14. 41 0
      components/m-icon/m-icon.vue
  15. 162 0
      components/m-input.vue
  16. 61 0
      components/modal-tip/modalTip.vue
  17. 304 0
      components/modal/action-jump/action-jump.vue
  18. 1444 0
      components/modal/boxing-hit/boxing-hit.vue
  19. 1295 0
      components/modal/boxing-post/boxing-post.vue
  20. 376 0
      components/modal/boxing-post/ef-bone.vue
  21. 100 0
      components/my-control-buttons/my-control-buttons.vue
  22. 76 0
      components/my-custom-step/my-custom-step.vue
  23. 198 0
      components/prompt-box/prompt-box.vue
  24. 374 0
      components/round-fab/round-fab.vue
  25. 361 0
      components/round-menu/round-menu.vue
  26. 79 0
      components/side-bar/mp.js
  27. 337 0
      components/side-bar/side-bar.vue
  28. 171 0
      components/side-bar/side-wxs.wxs
  29. 55 0
      components/side-bar/sideBar.js
  30. 12545 0
      components/slambb-picker/city-data/area.js
  31. 1503 0
      components/slambb-picker/city-data/city.js
  32. 139 0
      components/slambb-picker/city-data/province.js
  33. 72 0
      components/slambb-picker/picker.js
  34. 177 0
      components/slambb-picker/slambb-picker-city.vue
  35. 234 0
      components/slambb-picker/slambb-picker-date.vue
  36. 143 0
      components/slambb-picker/slambb-picker-item.vue
  37. 163 0
      components/slambb-picker/slambb-picker.vue
  38. 165 0
      components/u-charts/component.vue
  39. 6023 0
      components/u-charts/u-charts.js
  40. 0 0
      components/u-charts/u-charts.min.js
  41. 206 0
      components/uni-count-down/uni-count-down.vue
  42. 96 0
      components/uni-icons/icons.js
  43. 10 0
      components/uni-icons/uni-icons.vue
  44. 225 0
      components/uni-nav-bar/uni-nav-bar.vue
  45. 193 0
      components/uni-popup/uni-popup.vue
  46. 25 0
      components/uni-status-bar/uni-status-bar.vue
  47. 223 0
      components/uni-swipe-action/bindingx.js
  48. 186 0
      components/uni-swipe-action/index.wxs
  49. 83 0
      components/uni-swipe-action/mp.js
  50. 160 0
      components/uni-swipe-action/mpother.js
  51. 214 0
      components/uni-swipe-action/uni-swipe-action.vue
  52. 18 0
      main.js
  53. 114 0
      manifest.json
  54. 245 0
      pages.json
  55. 103 0
      pages/Loading-page/Loading/Loading.vue
  56. 250 0
      pages/conversion-page/conversion/conversion.vue
  57. 311 0
      pages/fc-page/fc-list/fc-list.vue
  58. 702 0
      pages/fc-page/fc/fc.vue
  59. 135 0
      pages/game-page/game-comment/game-comment.vue
  60. 358 0
      pages/game-page/game-detail/game-detail.vue
  61. 116 0
      pages/game-page/game-play-sub/game-play-sub.vue
  62. 1049 0
      pages/game-page/game-play-sub/subGame/subGame.nvue
  63. 415 0
      pages/game-page/game-play/game-play-web.nvue
  64. 558 0
      pages/game-page/game-ranking/game-ranking.vue
  65. 62 0
      pages/game-page/game-search/game-search.vue
  66. 521 0
      pages/game-page/game/game.vue
  67. 57 0
      pages/info-page/app-info/app-info.vue
  68. 290 0
      pages/login-page/bindPhone/bindPhone.vue
  69. 205 0
      pages/login-page/feedback/feedback.vue
  70. 1000 0
      pages/login-page/login/login.vue
  71. 150 0
      pages/login-page/main/main.vue
  72. 53 0
      pages/login-page/pwd/pwd.vue
  73. 288 0
      pages/login-page/reg/reg.vue
  74. 44 0
      pages/login-page/user/user.vue
  75. 353 0
      pages/login-page/userAgreement/userAgreement.vue
  76. 435 0
      pages/my-page/firstPlan/firstPlan.vue
  77. 316 0
      pages/my-page/homepage/homepage.vue
  78. 448 0
      pages/my-page/perfectInfo/perfectInfo.vue
  79. 801 0
      pages/my-page/userInfo/userInfo.vue
  80. 81 0
      pages/personal-page/devices-category/devices-category.vue
  81. 782 0
      pages/personal-page/devices-hardware/devices-hardware.vue
  82. 814 0
      pages/personal-page/devices-update/devices-update.vue
  83. 295 0
      pages/personal-page/devices/devices.vue
  84. 105 0
      pages/personal-page/favorites/favorites.vue
  85. 145 0
      pages/personal-page/list/list.vue
  86. 230 0
      pages/personal-page/more/more.vue
  87. 3005 0
      pages/personal-page/personal/personal.vue
  88. 443 0
      pages/personal-page/plan/plan.vue
  89. BIN
      static/add-purple.png
  90. BIN
      static/add.png
  91. BIN
      static/add_w.png
  92. BIN
      static/asterisk.png
  93. BIN
      static/avatar/1.png
  94. BIN
      static/avatar/10.png
  95. BIN
      static/avatar/11.png
  96. BIN
      static/avatar/2.png
  97. BIN
      static/avatar/3.png
  98. BIN
      static/avatar/4.png
  99. BIN
      static/avatar/5.png
  100. BIN
      static/avatar/6.png

+ 94 - 0
App.vue

@@ -0,0 +1,94 @@
+<script>
+	import config from 'common/config.js';
+	import {
+		mapMutations
+	} from 'vuex'
+	export default {
+
+		methods: {
+			...mapMutations(['onLuanchLogin', 'getBLEDeviceList','getFinalUseDevice']),
+
+		},
+		onLaunch: function() {
+			console.log('App Launch');
+			// 先判断 系统版本
+			uni.getSystemInfo({
+				success: (res) => {
+					console.log("系统信息:", res);
+					this.$store.state.clientName = res.model
+					this.$store.state.system = res.system
+					this.$store.state.platform = res.platform
+					
+				},
+				fail: (err) => {},
+				complete: () => {}
+			})
+			//获取记录的最后一次连接
+			this.getFinalUseDevice();
+			//获取记录的蓝牙列表数据
+			this.getBLEDeviceList();
+
+			// #ifdef APP-PLUS
+			plus.runtime.getProperty(plus.runtime.appid, (info)=> {
+				console.log("version:",info);
+				this.$store.state.version = info.version;
+				this.$store.state.versionCode = info.versionCode;
+				this.$store.state.appName = info.name;
+			});
+			
+			// 锁住屏幕正方向
+			plus.screen.lockOrientation('portrait-primary');
+			// 屏幕常亮
+			// 下面这个打包要开启手机设置权限
+			plus.device.setWakelock(true);
+			// #endif
+
+			// #ifdef MP
+			//开始登陆
+			this.onLuanchLogin({});
+			// #endif
+		},
+		onShow: function() {
+			console.log('App Show');
+			// #ifdef APP-PLUS
+			// 锁住屏幕正方向
+			// plus.screen.lockOrientation('portrait-primary');
+			// 屏幕常亮
+			// plus.device.setWakelock(true);
+			// 下面这个打包要开启手机设置权限
+			// uni.setScreenBrightness({
+			//     value: 0.8,
+			//     success: function () {
+			//         console.log('setScreenBrightness success');
+			//     }
+			// });
+			// uni.setKeepScreenOn({
+			// 	keepScreenOn: true,
+			// 	success: function () {
+			// 	    console.log('setKeepScreenOn success');
+			// 	}
+			// });
+			// let self = this;
+			// uni.getScreenBrightness({
+			//     success: function (res) {
+			//         console.log('屏幕亮度值:' + res.value);
+			// 		self.Test = '=='+plus.device.isWakelock()+ '=getScreenBrightness success';
+			// 		self.screenValue = res.value;
+			//     }
+			// });
+			// #endif
+		},
+		onHide: function() {
+			console.log('App Hide')
+		}
+
+	}
+</script>
+
+<style>
+	/*每个页面公共css */
+	// #ifndef APP-PLUS-NVUE
+	@import "util/util-css/main.css";
+	@import "util/util-css/icon.css";
+	// #endif
+</style>

+ 22 - 0
common/checker.js

@@ -0,0 +1,22 @@
+module.exports = {
+	error:'',
+	isJSON : function (str){
+		if (typeof str == 'string') {
+			try {
+				var obj=JSON.parse(str);
+				if(typeof obj == 'object' && obj ){
+					return true;
+				}else{
+					return false;
+				}
+			} catch(e) {
+				console.log('error:'+str+'!!!'+e);
+				return false;
+			}
+		}
+	},
+	isNumber : function (checkVal){
+		var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
+		return reg.test(checkVal);
+	}
+}

+ 164 - 0
common/config.js

@@ -0,0 +1,164 @@
+//设置游戏列表的更新时间,超过这个时间,不显示出来
+//"2020-07-14"
+//************* ios 注意此时间设置,目前设置2021-01-24,暂时用于处理游戏显示 *************
+const endTime = "2021-03-01"
+//************* 默认的蓝牙设备刷新间隔 再config 设置 a:10ms,b:20ms*************
+const refreshRate = "a";
+//*******当前活动环境,需要和根据地址设置!!环境 dev,prd
+const active = "dev";
+//线上地址,腾讯云服务器
+// const host="https://www.9527fun.cn/api_prd"
+//测试地址,阿里云服务器
+const host="https://www.9527fun.cn/api_dev"
+//本地测试地址
+// const host = "http://192.168.0.112:9090/api_dev"
+// const host = "http://47.104.216.192:9090/api_dev"
+// const host = "http://121.4.103.151:9090/api_prd"
+
+const URL = {
+	//验证token,获取服务器返回的信息
+	VERIFICATION: `${host}/program/Verification_Info`,
+	//注册登录
+	SMSLOGIN: `${host}/program/SMS_login`,
+	//获取验证码
+	GETCODE: `${host}/program/getCode`,
+	//短信绑定手机号
+	BINDPHONE: `${host}/program/SMS_bind_phone`,
+	// 解绑手机号
+	DELETEPHONE: `${host}/program/delete_phone`,
+	//绑定微信信息
+	BINDWXINFO: `${host}/program/bind_wx_info`,
+	//密码登录
+	PASSWORDlOGIN: `${host}/program/password_login`,
+	// 小程序用户登录
+	USERlOGINURL: `${host}/program/client_login`,
+	// 苹果用户登录
+	APPLElOGINURL: `${host}/program/client_apple_login`,
+	//android 端微信登录
+	ANDROIDLOGINURL: `${host}/program/client_wx_login`,
+	// 用户删除token
+	USERLOGINOUT: `${host}/program/delete_token`,
+	// 微信端解密信息接口
+	WXGETUSERINFO: `${host}/program/wx_getUserInfo`,
+	
+	//添加前端设备的信息
+	ADDCLIENTINFO:`${host}/program/add_client_info`,
+	
+	//获取version code 状态,用于处理特定信息显示
+	GETVERSIONCODE:`${host}/program/get_version_code_state`,
+	
+	
+	// 获取用户信息
+	USERINFOURL: `${host}/user_info/get`,
+	// 添加用户信息
+	USERINFOADD: `${host}/user_info/add`,
+	// 添加url 用户等信息
+	USERINFOADDAVATARINFO: `${host}/user_info/add_wx_avatar_info`,
+	// 添加apple用户信息
+	USERINFOAPPLEADD: `${host}/user_info/appleAdd`,
+
+	// 添加用户头像
+	USERINFOADDAVATAR: `${host}/user_info/add_avatar`,
+
+	//添加更新自身体重
+	USERADDWEIGHT: `${host}/user_info/add_weight`,
+
+	//获取体重列表
+	USERGETWEIGHT: `${host}/user_info/get_weight`,
+
+	//添加修改计划信息
+	FITNESSPROGRAM: `${host}/fitness_program/add`,
+
+	FITNESSPROGRAMGET: `${host}/fitness_program/get`,
+
+	//游戏页面部分
+	//获取全部游戏
+	GAMELIST: `${host}/game/list`,
+	//获取游戏详情
+	GAMEDETAIL: `${host}/game/detail`,
+	//获取推荐列表
+	GAMERECOMMEND: `${host}/game/recommend_list`,
+	GAMERECOMMENDBYPLATFORM: `${host}/game/recommend_list_platform`,
+	//获取游戏类目
+	GAMECATEGORY: `${host}/game/game_category_list`,
+	//根据游戏类目获取游戏列表
+	GAMELIST_FROM_CATEGORY: `${host}/game/list_from_category`,
+	GAMELIST_FROM_CATEGORY_PLATFORM: `${host}/game/list_from_category_platform`,
+	
+	//根据游戏显示获取游戏列表
+	GAMELIST_BY_RANKING_SHOW: `${host}/game/list_by_ranking_show`,
+	GAMELIST_BY_RANKING_SHOW_AND_PLATFORM: `${host}/game/list_by_ranking_show_and_platform`,
+	
+	//收藏
+	//添加
+	FAVORITESADD: `${host}/favorites/add`,
+	//修改
+	FAVORITESMODIFY: `${host}/favorites/modify`,
+	//获取收藏 列表
+	FAVORITESGET: `${host}/favorites/get`,
+	FAVORITESGETBYPLATFORM: `${host}/favorites/get_by_platform`,
+	//添加 最近玩 列表
+	RECENTLYPLAYINGADD: `${host}/recently_playing/add`,
+	//获取 最近玩 列表
+	RECENTLYPLAYINGGET: `${host}/recently_playing/get`,
+	RECENTLYPLAYINGGETBYPLATFORM: `${host}/recently_playing/get_by_platform`,
+	//添加当前排行榜游戏,
+	MOTIFYRANKGAME: `${host}/ranking/add_rank_game`,
+	//获取排行榜里面的游戏
+	GETRANKGAME: `${host}/ranking/get_rank_game`,
+
+	//更新 排行榜
+	UPLOADRANKING: `${host}/ranking/upload`,
+	//获取 排行榜
+	GETRANKRANGR: `${host}/ranking/get_range`,
+
+	//获取 ai的随机信息
+	AIRANDOMINFO: `${host}/client_game/ai_random_info`,
+	//给webview 图片中转接口
+	TRANSFERPICTURE: `${host}/client_game/transfer_picture`,
+	
+	//设备操作
+	//绑定二维码设备
+	DEVICEBIND:`${host}/device/bind`,
+	//获取绑定的设备
+	DEVICEBINDINGLIST:`${host}/device/binding_list`,
+	
+	//绑定蓝牙设备
+	BLEBIND:`${host}/bluetooth/bind`,
+	//查看是否可以绑定此设备
+	BLEFINDHASBIND:`${host}/bluetooth/findHasBind`,
+	//获取绑定的设备
+	BLEBINDINGLIST:`${host}/bluetooth/binding_list`,
+	
+	
+	/**
+	 * fc 游戏接口
+	 */
+	//根据种类获取对应的分类菜单
+	FCCATEGORYBYTYPE:`${host}/FC/category_by_type`,
+	
+	FCListByCategory:`${host}/FC/list_by_category`,
+	
+	
+	/**
+	 * ota
+	 */
+	GETOTA:`${host}/OTA/get_ota`,
+	/**
+	 * 版本更新信息
+	 */
+	APPVERSIONUPDATE:`${host}/app/version_update`,
+	
+	/**
+	 * 上传反馈信息
+	 */
+	UPLOADFEEDBACK:`${host}/manager/upload_feedback`,
+}
+
+
+export default {
+	active,
+	URL,
+	endTime,
+	refreshRate
+}

+ 475 - 0
components/code-elf-guide/code-elf-guide.vue

@@ -0,0 +1,475 @@
+<template>
+	<view class="content">
+		<view class="swiper">
+			<!-- 计划 -->
+			<view class="swiper-item" v-if="thisCurrent==0">
+				<view class="swiper-project" :class="thisCurrent==0&&bShow?'active':''">
+					<view style="display: flex;flex-direction: column;" :style="{'margin-top' :projectTop+'px'}">
+						<view @tap="launchFlag(false)">
+							<image style="margin-top: -35rpx;" :style="{width:projectWith+'px', height:projectHeight+'px'}" src="/static/guide/project_target.png"></image>
+						</view>
+
+						<image style="width: 80rpx;height: 80rpx; margin: 35rpx 0 0 75rpx;" src="/static/guide/project_handle.png" mode="aspectFit"></image>
+					</view>
+
+					<view style="display: flex; flex-direction: column;margin-top: 200rpx;">
+						<image style="width: 120rpx;height: 80rpx;" src="/static/guide/project_arrow.png" mode="aspectFit"></image>
+						<image style="margin-left: 90rpx; width: 340rpx;height: 200rpx;" src="/static/guide/project_tip.png" mode="aspectFit"></image>
+					</view>
+
+				</view>
+				<view style="position: absolute;  bottom: 200rpx; width: 100%; display:flex; justify-content: center;">
+					<view @tap="launchFlag(true)">
+						<image style="width: 120px;height: 45px;" src="/static/guide/BLE_tip.png"></image>
+					</view>
+				</view>
+			</view>
+			<!-- 下滑连接蓝牙提示 -->
+			<view class="swiper-item" v-if="thisCurrent==1">
+				<view class="swiper-bluetooth">
+					<image style="margin: 10rpx;  width: 50rpx;height: 50rpx;" src="/static/guide/BLE_arrow.png" mode="aspectFit"></image>
+					<image style="width: 292rpx;height: 48rpx;" src="/static/guide/BLE_text_1.png" mode="aspectFit"></image>
+					<image style="width: 80rpx;height: 80rpx; margin: 188rpx 0 17rpx 0;" src="/static/guide/BLE_icon.png" mode="aspectFit"></image>
+					<image style="width: 571rpx;height: 52rpx;" src="/static/guide/BLE_text_2.png" mode="aspectFit"></image>
+					<view @tap="launchFlag(true)">
+						<image style=" width: 243rpx;height: 90rpx;margin-top: 54rpx;" src="/static/guide/BLE_tip.png"></image>
+					</view>
+				</view>
+			</view>
+			<!-- 提示调整添加蓝牙设备 -->
+			<view class="swiper-item" v-if="thisCurrent==3">
+				<!-- <button>{{deviceTop}}</button> -->
+				<view class="swiper-device active">
+
+					<view style="display: flex;flex-direction: column;margin-top: 403px;" :style="{'margin-top' :deviceTop+'px'}">
+						<view @tap="launchFlag(false)">
+							<image style="margin-top: -35rpx;" :style="{width:deviceWith+'px', height:deviceHeight+'px'}" src="/static/guide/device_target.png"></image>
+						</view>
+						<image style="width: 80rpx;height: 80rpx; margin: 35rpx 0 0 75rpx;" src="/static/guide/project_handle.png" mode="aspectFit"></image>
+					</view>
+					<view style="display: flex; flex-direction: row; margin-top: -500rpx;">
+						<image style="margin: 90rpx 30rpx 0 150rpx;  width: 120rpx;height: 80rpx;" src="/static/guide/device_arrow.png"
+						 mode="aspectFit"></image>
+						<image style="width: 394rpx;height: 123rpx;" src="/static/guide/device_tip.png" mode="aspectFit"></image>
+					</view>
+
+					<view style="display: flex;align-self: center;margin-top: -200px;">
+						<view @tap="launchFlag(true)">
+							<image style="width: 120px;height: 45px;" src="/static/guide/BLE_tip.png"></image>
+						</view>
+					</view>
+				</view>
+
+			</view>
+			<!-- 连接设备提示 -->
+			<view class="swiper-item" v-if="thisCurrent==4">
+				<!-- <button>{{deviceTop}}</button> -->
+				<view class="swiper-device active">
+					<!-- <view style="display: flex;align-self: center;margin-top: 80px;"> -->
+					<!-- <view @tap="launchFlag(true)">
+							<image style="width: 120px;height: 45px;" src="/static/guide/BLE_tip.png"></image>
+						</view> -->
+					<!-- </view> -->
+					<!-- 125 -->
+					<view style="display: flex;flex-direction: column;margin-top: 403px;" :style="{'margin-top' :deviceTop+'px'}">
+						<view @tap="launchFlag(false)">
+							<image style="margin-top: -35rpx;" :style="{width:deviceWith+'px', height:deviceHeight+'px'}" src="/static/guide/device_target.png"></image>
+						</view>
+						<image style="width: 80rpx;height: 80rpx; margin: 35rpx 0 0 75rpx;" src="/static/guide/project_handle.png" mode="aspectFit"></image>
+					</view>
+					<view style="display: flex; flex-direction: row; margin-top: -500rpx;">
+						<image style="margin: 90rpx 30rpx 0 150rpx;  width: 120rpx;height: 80rpx;" src="/static/guide/device_arrow.png"
+						 mode="aspectFit"></image>
+						<image style="width: 394rpx;height: 123rpx;" src="/static/guide/device_tip.png" mode="aspectFit"></image>
+					</view>
+
+					<view style="display: flex;align-self: center;margin-top: 200px;">
+						<view @tap="launchFlag(true)">
+							<image style="width: 120px;height: 45px;" src="/static/guide/BLE_tip.png"></image>
+						</view>
+					</view>
+
+				</view>
+
+			</view>
+			<!-- 拳击血量提示 -->
+			<view class="swiper-item" v-if="thisCurrent==5">
+				<view class="swiper-device active">
+					<view class="guide-vertical-container">
+						<view class="guide-vertical-bar">
+							<view class="guide-vertical-child" v-for="(item, index) in 15" :key="index">
+								<view :class="20>=index+1? 'guide-vertical-active':'guide-vertical-inactive'"></view>
+								<!-- :class="index%5 == 0?'':'guide-text-hidden'" -->
+								<view  class="guide-vertical-text guide-text-hidden">{{index+1}}</view>
+							</view>
+							<view style="height:30rpx"></view>
+							<image class="guide-vertical-boxing" src="/static/guide/boxingHitUp.png"></image>
+						</view>
+						<view class="guide-vertical-mid ">
+							<view style="margin: 80rpx 0 120rpx 30rpx; position: relative;"  @tap="launchFlag(false)">
+								<image style="position: relative; width: 280rpx;height: 88rpx;" src="/static/guide/boxingHitButton.png"></image>
+								<view style="position: absolute;top: 25rpx; left: 120rpx;right:35rpx; color: #FFF;">立即体验</view>
+							</view>
+							
+							<view style="position: relative;" >
+								<image style="position: relative; width: 400rpx;height: 170rpx;" src="/static/guide/boxingHitMid.png"></image>
+								<!-- 打击拳击柱越快或力量越大力量条会越快增长哦! -->
+								<view v-if="thisCurrentMode == 'calorieMode'" style="position: absolute;top: 70rpx; left: 45rpx;right:35rpx; color: #000;">跑的越快速度条会增长越快哦!</view>
+								<view v-else style="position: absolute;top: 70rpx; left: 45rpx;right:35rpx; color: #000;">对着沙袋拳拳到肉,让对方的飙血吧!</view>
+							
+							</view>
+						</view>
+						<view class="guide-vertical-bar">
+							<view class="guide-vertical-child" v-for="(item, index) in 15" :key="index">
+								<!-- :class="index%5 == 0?'':'guide-text-hidden'" -->
+								<view  class="guide-vertical-text guide-text-hidden">{{index+16}}</view>
+								<view :class="20>=index+16? 'guide-vertical-active':'guide-vertical-inactive'"></view>
+							</view>
+							<image class="guide-vertical-boxing" src="/static/guide/boxingHitUp.png"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- <swiper v-if="false" class="swiper" :autoplay="autoplay" :duration="duration" :current="thisCurrent" @change="onChange">
+		
+			<swiper-item>
+				<view class="swiper-project" :class="thisCurrent==0&&bShow?'active':''">
+					<view style="display: flex;flex-direction: column;" :style="{'margin-top' :projectTop+'px'}">
+						<image @tap="launchFlag(false)" style="margin-top: -35rpx;" :style="{width:projectWith+'px', height:projectHeight+'px'}" src="/static/guide/project_target.png"></image>
+						<image style="width: 80rpx;height: 80rpx; margin: 35rpx 0 0 75rpx;" src="/static/guide/project_handle.png"
+						 mode="aspectFit"></image>
+					</view>
+
+					<view style="display: flex; flex-direction: column;margin-top: 200rpx;">
+						<image style="width: 120rpx;height: 80rpx;" src="/static/guide/project_arrow.png" mode="aspectFit"></image>
+						<image style="margin-left: 90rpx; width: 340rpx;height: 200rpx;" src="/static/guide/project_tip.png" mode="aspectFit"></image>
+					</view>
+					
+				</view>
+				<view style="position: absolute;  bottom: 200rpx; width: 100%; display:flex; justify-content: center;">
+					<image @tap="launchFlag(true)" style="width: 120px;height: 45px;" src="/static/guide/BLE_tip.png"></image>
+				</view>
+			</swiper-item>
+			<swiper-item v-if="false">
+				<view class="swiper-device" :class="thisCurrent==1&&bShow?'':''">
+					<view style="display: flex;align-self: center;margin-top: 80px;">
+						<image @tap="launchFlag(true)" style="width: 120px;height: 45px;" src="/static/guide/BLE_tip.png"></image>
+					</view>
+					<view style="display: flex;flex-direction: column;margin-top: 403px;" :style="{'margin-top' :deviceTop-125+'px'}">
+						<image @tap="launchFlag(false)" style="margin-top: -35rpx;" :style="{width:deviceWith+'px', height:deviceHeight+'px'}" src="/static/guide/device_target.png"></image>
+						<image style="width: 80rpx;height: 80rpx; margin: 35rpx 0 0 75rpx;" src="/static/guide/project_handle.png"
+						 mode="aspectFit"></image>
+					</view>
+					<view style="display: flex; flex-direction: row; margin-top: -500rpx;">
+						<image style="margin: 90rpx 30rpx 0 150rpx;  width: 120rpx;height: 80rpx;" src="/static/guide/device_arrow.png"
+						 mode="aspectFit"></image>
+						<image style="width: 394rpx;height: 123rpx;" src="/static/guide/device_tip.png" mode="aspectFit"></image>
+					</view>
+				</view>
+			</swiper-item>
+			<swiper-item>
+				<view class="swiper-bluetooth">
+					<image style="margin: 10rpx;  width: 50rpx;height: 50rpx;" src="/static/guide/BLE_arrow.png" mode="aspectFit"></image>
+					<image style="width: 292rpx;height: 48rpx;" src="/static/guide/BLE_text_1.png" mode="aspectFit"></image>
+					<image style="width: 80rpx;height: 80rpx; margin: 188rpx 0 17rpx 0;" src="/static/guide/BLE_icon.png" mode="aspectFit"></image>
+					<image style="width: 571rpx;height: 52rpx;" src="/static/guide/BLE_text_2.png" mode="aspectFit"></image>
+					<image @tap="launchFlag(true)" style="width: 243rpx;height: 90rpx;margin-top: 54rpx;" src="/static/guide/BLE_tip.png"></image>
+				</view>
+			</swiper-item>
+		</swiper> -->
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			current: {
+				type: Number,
+				default: 0
+			},
+			modeIndex: {
+				type: Number,
+				default: 0
+			},
+			
+			currentMode:{
+				type: String,
+				default:"calorieMode"
+			}
+
+		},
+		data() {
+			return {
+				background: ['color1', 'color2', 'color3'],
+				autoplay: false,
+				duration: 0,
+				thisCurrent: 0,
+				bShow: false,
+				jumpover: '跳过',
+				experience: '立即体验',
+				deviceWith: 202,
+				deviceHeight: 103,
+				deviceTop: 503,
+				projectTop: 95,
+				projectWith: 106,
+				projectHeight: 60,
+				//设备对象
+				DeviceObj: null,
+				
+				modalObj:null,
+				
+				thisCurrentMode:'',
+
+			}
+		},
+		created() {
+			this.thisCurrent = this.current;
+			this.thisCurrentMode = this.currentMode;
+		},
+		watch: {
+
+			current(val) {
+				// console.log("====",val);
+				this.thisCurrent = val;
+			},
+			currentMode(val) {
+				// console.log("====",val);
+				this.thisCurrentMode = val;
+			}
+		},
+		methods: {
+			setProjectObj(val) {
+				this.bShow = true;
+				this.projectTop = val.top;
+				this.projectWith = val.width + 20;
+				this.projectHeight = val.height + 30;
+			},
+			setDeviceObj(val) {
+				this.bShow = true;
+				this.deviceWith = val.width + 40;
+				this.deviceHeight = val.height + 40;
+				this.deviceTop = val.top;
+				this.DeviceObj = val;
+
+			},
+			setModalObj(val){
+				console.log("setModalObj:",val);
+				this.modalObj = val;
+			},
+			setCurrent(val) {
+				// console.log("设置val:",val);
+				this.thisCurrent = val;
+			},
+			launchFlag: function(bOnlyHide) {
+				/**
+				 * 向本地存储中设置launchFlag的值,即启动标识;
+				 */
+				// uni.setStorage({
+				// 	key: 'launchFlag',
+				// 	data: true,1
+				// });
+				console.log(bOnlyHide, this.thisCurrent);
+				this.bShow = false;
+				this.$emit("hide", {
+					current: this.thisCurrent,
+					onlyHide: bOnlyHide,
+					device: this.DeviceObj
+				});
+			},
+			onChange(e) {
+				this.thisCurrent = e.detail.current;
+				// console.log("this.thisCurrent=",this.thisCurrent);
+				this.$emit("change", e);
+			}
+		}
+	}
+</script>
+<style>
+	.content {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		width: 100%;
+		height: 100%;
+		background-size: 100% auto;
+		padding: 0;
+		z-index: 9999;
+		box-sizing: border-box;
+	}
+
+	.swiper {
+		width: 100%;
+		height: 100%;
+		background: rgba(0, 0, 0, 0.71);
+	}
+
+	.swiper-item {
+		width: 100%;
+		height: 100%;
+		position: relative;
+		display: flex;
+		justify-content: center;
+		align-content: center;
+		align-items: center;
+		flex-direction: column;
+		/* border: 1rpx solid #FFFFFF; */
+	}
+
+	.swiper-project {
+		width: 100%;
+		height: 100%;
+		position: relative;
+		display: flex;
+		/* justify-content: center; */
+		align-items: flex-start;
+		flex-direction: row;
+		opacity: 0;
+		transition: opacity 1s;
+	}
+
+	.swiper-device {
+		width: 100%;
+		height: 100%;
+		position: relative;
+		display: flex;
+		align-items: flex-start;
+		flex-direction: column;
+		opacity: 0;
+		transition: opacity 1s;
+	}
+
+	.active {
+		opacity: 1;
+	}
+
+	.swiper-bluetooth {
+		width: 100%;
+		height: 100%;
+		position: relative;
+		display: flex;
+		align-items: center;
+		flex-direction: column;
+	}
+
+	.swiper-item-img {
+		width: 100%;
+		height: auto;
+		margin: 0 auto;
+	}
+
+	.swiper-item-img image {
+		width: 80%;
+		height: 500rpx;
+		border: 1rpx solid #000000;
+	}
+
+	.uniapp-img {
+		height: 20%;
+		background: #FFFFFF;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		overflow: hidden;
+	}
+
+	.uniapp-img image {
+		width: 40%;
+	}
+
+	.jump-over,
+	.experience {
+		position: absolute;
+		height: 60upx;
+		line-height: 60upx;
+		padding: 0 40upx;
+		border-radius: 30upx;
+		font-size: 32upx;
+		color: #FFFFFF;
+		border: 1px solid #FFFFFF;
+		z-index: 999;
+	}
+
+	.jump-over {
+		right: 45upx;
+		top: 125upx;
+	}
+
+	.experience {
+		right: 50%;
+		margin-right: -105upx;
+		bottom: 125upx;
+	}
+	
+	
+	/* Loader Bar */
+	.guide-vertical-container {
+		display: flex;
+		position: absolute;
+		top: 390rpx;
+		left: 0;
+		right: 0;
+		/* bottom: 0; */
+		display: flex;
+		justify-content: space-between;
+		/* border: 1rpx solid #000000; */
+		/* pointer-events: none; */
+	}
+	
+	.guide-vertical-bar {
+		display: flex;
+		flex-direction: column-reverse;
+		position: relative;
+	}
+	
+	.guide-vertical-mid{
+		display: flex;
+		flex-direction: column-reverse;
+		position: relative;
+	}
+	
+	.guide-vertical-boxing{
+		position: absolute;
+		/* top: 0; */
+		left: 0;
+		right: 0;
+		bottom: -30rpx;
+		height: 560rpx;
+	}
+	
+	.guide-vertical-child {
+		/* position: relative; */
+		width: 70rpx;
+		height: 20rpx;
+		margin: 14rpx 24rpx 0 24rpx;
+		display: flex;
+		/* align-content: center; */
+		justify-content: space-between;
+	
+	
+	}
+	
+	.guide-vertical-text {
+		color: #FFFFFF;
+		font-size: 8px;
+	}
+	
+	.guide-text-hidden {
+		visibility: hidden;
+	}
+	
+	.guide-vertical-active {
+		background-color: #FFFFFF;
+		width: 30rpx;
+		height: 100%;
+	}
+	
+	.guide-vertical-inactive {
+		width: 30rpx;
+		height: 100%;
+		background: rgba(255, 255, 255, 0.3);
+	}
+</style>

+ 111 - 0
components/code-elf-guide/uni-guide.md

@@ -0,0 +1,111 @@
+# 引导页
+
+###  基于uni-app框架的swiper组件打开的时候启动。
+
+> 首次启动展示引导页,之后启动不再展示。那么就意味着,我们需要一个标识来确定,App是否已经启动过。
+
+> 我们可以在本地存储一个key来做为已经启动过App的标识。那么,我们在入口这里,就可以读取这个key,来决定是否展示引导页。
+
+> 因工作繁忙目前该程序金对安卓做了适配,IOS可根据环境自己适配。谢谢
+
+## 目录结构
+* /pages/index/index.vue //入口页
+### 存储key
+* 向本地存储中设置launchFlag的值,即启动标识;
+### 获取key
+* 向本地存储中设置launchFlag的值,即启动标识;
+* 获取本地存储中launchFlag的值
+* 若存在,说明不是首次启动,直接进入首页;
+* 若不存在,说明是首次启动,进入引导页;
+
+```html
+	<view class="main">
+		<code-elf-guide v-if="guidePages"></code-elf-guide>
+	</view>
+
+```
+
+```javascript
+	import codeElfGuide from '@/components/code-elf-guide/code-elf-guide.vue'
+	export default {
+		components: {
+			codeElfGuide
+		  },
+		data() {
+			return {
+				guidePages:true
+			}
+		},
+		onLoad(){
+			this.loadExecution()
+		},
+		methods: {
+			loadExecution: function(){
+				/**
+				 * 获取本地存储中launchFlag的值
+				 * 若存在,说明不是首次启动,直接进入首页;
+				 * 若不存在,说明是首次启动,进入引导页;
+				 */
+				try {
+					// 获取本地存储中launchFlag标识
+					const value = uni.getStorageSync('launchFlag');
+					if (value) {
+						// launchFlag=true直接跳转到首页
+						uni.switchTab({
+							url: '/pages/tabBar/component/component'
+						});
+					} else {
+						// launchFlag!=true显示引导页
+						this.guidePages = true
+					}
+				} catch(e) { 
+					// error 
+					uni.setStorage({ 
+						key: 'launchFlag', 
+						data: true, 
+						success: function () {
+							console.log('error时存储launchFlag');
+						} 
+					}); 
+					this.guidePages = true
+				}
+			}
+		}
+	}
+```
+```css
+	page,.main{
+		width: 100%;
+		height: 100%;
+	}
+
+```
+
+### 首页清除key,进行测试
+* 清除本地存储中设置launchFlag的值,即启动标识;
+* 两秒后重启APP,进行测试
+```javascript
+	uni.showModal({
+        title: '清除launchFlag值',
+        content: '确定要清除launchFlag值,进行重启测试?',
+        success: function (res) {
+            if (res.confirm) {
+                console.log('用户点击确定');
+                // 清除缓存
+                uni.clearStorage();
+                uni.showToast({
+                    icon: 'none',
+                    duration:3000,
+                    title: '清除成功2秒后重启'
+                });
+                // 两秒后重启
+                setTimeout(function() {
+                    uni.hideToast();
+                    plus.runtime.restart();
+                }, 2000);
+            } else if (res.cancel) {
+                console.log('用户点击取消');
+            }
+        }
+    });
+```

+ 123 - 0
components/effectHit/hitEffect.vue

@@ -0,0 +1,123 @@
+<template>
+	<view>
+		<view v-if="bPlay" class="HitEffect-parent">
+			<view class="HitEffect-container" :style="{'animation-duration': 0+'s'}">
+				<view class="HitEffect" :id="1" :style="{ 
+					 '--time':1,
+					 backgroundImage:`url(${imageSrc})`}"
+				 :class=" bPlay?' play ':''">
+				</view>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	import imageSrc from "@/static/effectHit/hitEffect.png"
+
+	export default {
+		props: {
+			
+		},
+		data() {
+			return {
+				imageSrc: imageSrc,
+				bPlay:false,
+				hitTimeOut:null,
+				hitAudioContext:null,
+				myHit: "/static/effectHit/pkHit.mp3",
+				aiHit: "/static/effectHit/pkStricken.mp3",
+			};
+		},
+		created() {
+			this.hitAudioContext = uni.createInnerAudioContext();
+			this.hitAudioContext.autoplay = false;
+			this.hitAudioContext.src = this.myHit;
+			
+		},
+		beforeDestroy() {
+			if (this.hitAudioContext)
+				this.hitAudioContext.destroy();
+		},
+		methods: {
+			onAIHit(){
+				this.hitAudioContext.stop();
+				this.hitAudioContext.volume = 0.8;
+				this.hitAudioContext.src = this.aiHit;
+				this.hitAudioContext.play();
+				
+			},
+			onMyHit(){
+				this.hitAudioContext.stop();
+				this.hitAudioContext.volume = 0.4;
+				this.hitAudioContext.src = this.myHit;
+				this.hitAudioContext.play();
+			},
+			onPlay(){
+				this.bPlay = true;
+				if(this.hitTimeOut){
+					clearTimeout(this.hitTimeOut);
+					this.hitTimeOut = null;
+				}
+				
+				this.hitTimeOut = setTimeout(()=>{
+					this.bPlay = false;
+				},1000);
+			},
+			onStop(){
+				this.bPlay = false;
+				if(this.hitTimeOut){
+					clearTimeout(this.hitTimeOut);
+					this.hitTimeOut = null;
+				}
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.HitEffect-parent {
+		// border: 1rpx solid #ffaa7f;
+		position: absolute;
+		display: flex;
+		justify-content: center;
+		overflow: hidden;
+		top: -50px;
+		left: -35px;
+		transform: scale(0.5);
+	}
+
+	.HitEffect-container {
+		width: 100%;
+		height: 167px;
+		// border: 1rpx solid #000000;
+		position: relative;
+
+	}
+
+	.HitEffect {
+		// background-color: #007AFF;
+		background-size: cover;
+		height: 167px;
+		width: 146px;
+		position: relative;
+		top: 0;
+		left: 0;
+		
+	}
+
+	.play {
+		animation: hitEffectRun calc(var(--time) * 1s) steps(1, start) infinite;
+		animation-play-state: running;
+	}
+
+	@keyframes hitEffectRun {
+		@for $i from 0 through 9 {
+			#{$i*11.1}% {
+				background-position: -0px -167px*$i;
+			}
+		}
+	}
+</style>

+ 402 - 0
components/effectHit/hitFistEffect.vue

@@ -0,0 +1,402 @@
+<template>
+	<view>
+		<view class="HitFistEffect-parent">
+			<view class="HitFistEffect-container">
+				<canvas canvas-id="fistCanvas" style="width: 375px;height: 100px;"></canvas>
+			</view>
+		</view>
+
+		<!-- <view>
+			<button style="width: 200rpx;" @tap="onTestRed">onTestRed</button>
+			<button style="width: 200rpx;" @tap="onTestBlue">onTestBlue</button>
+		</view> -->
+
+	</view>
+
+</template>
+
+<script>
+	var Timing = {
+		easeIn: function easeIn(pos) {
+			return Math.pow(pos, 3);
+		},
+		easeOut: function easeOut(pos) {
+			return Math.pow(pos - 1, 3) + 1;
+		},
+		easeInOut: function easeInOut(pos) {
+			if ((pos /= 0.5) < 1) {
+				return 0.5 * Math.pow(pos, 3);
+			} else {
+				return 0.5 * (Math.pow(pos - 2, 3) + 2);
+			}
+		},
+		linear: function linear(pos) {
+			return pos;
+		}
+	};
+
+	function Animation(opts) {
+		// console.log(opts);
+		this.isStop = false;
+		opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
+		opts.timing = opts.timing || 'linear';
+		var delay = 17;
+
+		function createAnimationFrame() {
+			if (typeof setTimeout !== 'undefined') {
+				return function(step, delay) {
+					setTimeout(function() {
+						var timeStamp = +new Date();
+						step(timeStamp);
+					}, delay);
+				};
+			} else if (typeof requestAnimationFrame !== 'undefined') {
+				return requestAnimationFrame;
+			} else {
+				return function(step) {
+					step(null);
+				};
+			}
+		};
+		var animationFrame = createAnimationFrame();
+		var startTimeStamp = null;
+		var _step = function step(timestamp) {
+			if (timestamp === null || this.isStop === true) {
+				opts.onProcess && opts.onProcess(1);
+				opts.onAnimationFinish && opts.onAnimationFinish();
+				return;
+			}
+			if (startTimeStamp === null) {
+				startTimeStamp = timestamp;
+			}
+			if (timestamp - startTimeStamp < opts.duration) {
+				var process = (timestamp - startTimeStamp) / opts.duration;
+				var timingFunction = Timing[opts.timing];
+				process = timingFunction(process);
+
+				opts.onProcess && opts.onProcess(process);
+				animationFrame(_step, delay);
+			} else {
+				opts.onProcess && opts.onProcess(1);
+				opts.onAnimationFinish && opts.onAnimationFinish();
+			}
+		};
+		_step = _step.bind(this);
+		animationFrame(_step, delay);
+	}
+	export default {
+
+		props: {
+			bLeft: {
+				type: Boolean,
+				default: false
+			},
+		},
+		data() {
+			return {
+				//拳头
+				fistRedImage: "/static/effectHit/fist-red.png",
+				fistBlueImage: "/static/effectHit/fist-blue.png",
+				animation: 'left-play',
+
+				fistList: [],
+				fistBlueList: [],
+
+				//限制生成个数
+				createRedFistLimit: 5,
+				createBlueFistLimit: 5,
+				//已经生成的对象
+				createRedList: {
+					'small': [],
+					'medium': [],
+					'large': []
+				},
+				createBlueList: {
+					'small': [],
+					'medium': [],
+					'large': []
+				},
+
+				fistRed: null,
+				fistBlue: null,
+				setInterval: null,
+
+			};
+		},
+		created() {
+			let _self = this;
+			this.fistCanvas = uni.createCanvasContext("fistCanvas", this);
+
+			uni.getImageInfo({
+				src: "../../../static/effectHit/fist-red.png",
+				success: function(image) {
+					_self.fistRed = image;
+				}
+			});
+			uni.getImageInfo({
+				src: "../../../static/effectHit/fist-blue.png",
+				success: function(image) {
+					_self.fistBlue = image;
+				}
+			});
+			
+			//{scale:1, red:{x:260,y:0} blue:{x:30,y:0}}
+			//{scale:0.8, red:{x:350,y:20} blue:{x:50,y:20}}
+			//{scale:0.6, red:{x:490,y:40} blue:{x:90,y:40}}
+
+			// setTimeout(() => {
+			// 	let _scale = 0.6;
+			// 	let _dWidth = _scale * _self.fistRed.width;
+			// 	let _dHeight = _scale * _self.fistRed.height;
+			// 	_self.fistCanvas.save();
+			// 	_self.fistCanvas.scale(_scale, _scale);
+			// 	// _self.fistCanvas.translate(x,  0);
+			// 	_self.fistCanvas.drawImage(_self.fistRed.path, 490, 40, _dWidth, _dHeight);
+			// 	_self.fistCanvas.restore();
+			// 	_self.fistCanvas.save();
+			// 	_self.fistCanvas.scale(-_scale, _scale);
+			// 	_self.fistCanvas.drawImage(_self.fistBlue.path, -90 - _dWidth, 40,
+			// 		_dWidth, _dHeight);
+			// 	_self.fistCanvas.restore();
+			// 	_self.fistCanvas.draw();
+			// }, 1000)
+
+			this.onDetectionPosition();
+
+			// setInterval(()=>{
+			// 	this.onTestBlue();
+			// },500)
+		},
+		beforeDestroy() {},
+		methods: {
+			onDetectionPosition() {
+				let _self = this;
+				if (_self.setInterval != null) {
+					clearInterval(_self.setInterval);
+					_self.setInterval = null;
+				}
+
+				//100毫秒检测一次位置
+				_self.setInterval = setInterval(() => {
+					_self.fistCanvas.clearRect(0, 0, 750, 150);
+					drawFistType('small');
+					drawFistType('medium');
+					drawFistType('large');
+					_self.fistCanvas.draw();
+				}, 20)
+
+				function drawFistType(type) {
+					let smallRedList = _self.createRedList[type];
+					let smallBlueList = _self.createBlueList[type];
+					for (let i = 0; i < smallRedList.length; i++) {
+						let _scale = smallRedList[i].scale;
+						let _dWidth = _scale * _self.fistRed.width;
+						let _dHeight = _scale * _self.fistRed.height;
+						_self.fistCanvas.save();
+						_self.fistCanvas.scale(_scale, _scale);
+						_self.fistCanvas.drawImage(_self.fistRed.path, smallRedList[i].red.x, smallRedList[i].red.y, _dWidth, _dHeight);
+						_self.fistCanvas.restore();
+						if (smallBlueList.length > i) {
+							if (smallRedList[i].red.x.sub(smallBlueList[i].blue.x) < 0.5) {
+								smallRedList[i].animationInstance.isStop = true;
+								smallBlueList[i].animationInstance.isStop = true;
+							}
+						}
+					}
+					for (let i = 0; i < smallBlueList.length; i++) {
+						let _scale = smallBlueList[i].scale;
+						let _dWidth = _scale * _self.fistBlue.width;
+						let _dHeight = _scale * _self.fistBlue.height;
+						_self.fistCanvas.save();
+						_self.fistCanvas.scale(-_scale, _scale);
+						_self.fistCanvas.drawImage(_self.fistBlue.path, - smallBlueList[i].blue.x - _dWidth, smallBlueList[i].blue.y,
+							_dWidth, _dHeight);
+						_self.fistCanvas.restore();
+					}
+				}
+			},
+			
+
+			onCreateFist(data, callback) {
+				if (data.createFistLimit > 0) {
+					data.createFistLimit--;
+					let _item = {
+						scale: data.scale,
+						type: data.type, //尺寸 small, medium and large
+						time: data.time,
+						red:data.red,
+						blue:data.blue,
+						animationInstance: null
+					};
+					data.createList[_item.type].push(_item);
+					_item.animationInstance = new Animation({
+						timing: 'linear',
+						duration: _item.time,
+						onProcess: function(process) {
+							if (data.createType == 'red') {
+								_item.red.x -= process * 15;
+							} else {
+								_item.blue.x += process * 15;
+							}
+						},
+						onAnimationFinish: function onAnimationFinish() {
+							// console.log("finishblue:",_item.animationInstance.isStop);
+							if (!_item.animationInstance.isStop) {
+								//如果isStop 是false 的,说明没有抵消,则击中
+
+								if (callback) {
+									callback({
+										hit: true
+									})
+								}
+							}
+							data.createFistLimit++;
+							data.createList[_item.type].shift();
+						}
+					});
+				}
+
+			},
+
+			onTestRed() {
+				let num = Math.floor(Math.random() * 3) + 1;
+				// console.log("num:", num);
+
+				this.onPlay({
+					bloodPoint: num,
+					createType: 'red',
+					callback: (res) => {
+						console.log("红色拳头击中对方:", res);
+					}
+				});
+			},
+			onTestBlue() {
+				let num = Math.floor(Math.random() * 3) + 1;
+				// console.log("num:", num);
+
+				this.onPlay({
+					bloodPoint: num,
+					createType: 'blue',
+					callback: (res) => {
+						console.log("蓝色拳头击中对方:", res);
+					}
+				});
+			},
+
+			onPlay(context) {
+				let {
+					bloodPoint,
+					callback,
+					createType
+				} = context;
+
+				//{scale:1, red:{x:260,y:0} blue:{x:30,y:0}}
+				//{scale:0.8, red:{x:350,y:20} blue:{x:50,y:20}}
+				//{scale:0.6, red:{x:490,y:40} blue:{x:90,y:40}}
+
+				let temp = {};
+				if (bloodPoint == 3) {
+					//大拳头
+					temp.scale = 1;
+					temp.time = 500;
+					temp.type = 'large';
+					temp.red = {x: 260,y: 0};
+					temp.blue = {x: 30,y: 0};
+				} else if (bloodPoint == 2) {
+					//中拳头
+					temp.scale = 0.8;
+					temp.time = 700;
+					temp.type = 'medium';
+					temp.red = {x:350,y:20};
+					temp.blue = {x:50,y:20};
+				} else {
+					//小拳头
+					temp.scale = 0.6;
+					temp.time = 900;
+					temp.type = 'small';
+					temp.red = {x:490,y:40};
+					temp.blue = {x:90,y:40};
+				}
+				if (createType == 'red') {
+					temp.createFistLimit = this.createRedFistLimit;
+					temp.createList = this.createRedList;
+					temp.createType = "red";
+					this.onCreateFist(temp, callback);
+				} else {
+					temp.createFistLimit = this.createBlueFistLimit;
+					temp.createList = this.createBlueList;
+					temp.createType = "blue";
+					this.onCreateFist(temp, callback);
+				}
+
+			},
+			onStop() {
+
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.HitFistEffect-parent {
+		// border: 1rpx solid #ffaa7f;
+		position: absolute;
+		display: flex;
+		justify-content: center;
+		overflow: hidden;
+		top: 0;
+		width: 750rpx;
+	}
+
+	.HitFistEffect-container {
+		width: 100%;
+		height: 65px;
+		// border: 1rpx solid #000000;
+		position: relative;
+		// display: flex;
+	}
+
+	.HitFistEffect {
+		// background-color: #007AFF;
+		position: absolute;
+		background-size: cover;
+		height: 65px;
+		width: 86px;
+		// position: relative;
+		top: 0;
+
+		// left: -500rpx;
+
+	}
+
+	.left-play {
+		animation: leftHitFistEffectRun calc(var(--time) * 1s) ease calc(var(--delay) * 1s) 1;
+		animation-play-state: running;
+	}
+
+	.right-play {
+		animation: rightHitFistEffectRun calc(var(--time) * 1s) ease calc(var(--delay) * 1s) 1;
+		animation-play-state: running;
+	}
+
+	@keyframes leftHitFistEffectRun {
+		0% {
+			left: 150rpx;
+		}
+
+		100% {
+			left: 450rpx;
+		}
+	}
+
+	@keyframes rightHitFistEffectRun {
+		0% {
+			left: 450rpx;
+		}
+
+		100% {
+			left: 150rpx;
+		}
+	}
+</style>

+ 110 - 0
components/electAni/character.vue

@@ -0,0 +1,110 @@
+<template>
+	<view class="character-parent">
+		<view class="character-container">
+			<view class="character" :class="deley?'play':''" :style="{backgroundImage:`url(${imageSrc})`}"></view>
+		</view>
+		<!-- <button @tap="onplay()">play</button> -->
+	</view>
+</template>
+
+<script>
+
+	import imageSrc from "@/static/character/character.png"
+
+	export default {
+		props: {
+			parentLeft: {
+				type: Number,
+				default: 0
+			},
+			electLeft: {
+				type: Number,
+				default: 150
+			},
+			backgroundColor: {
+				type: String,
+				default: '#007AFF'
+			},
+			borderColor: {
+				type: String,
+				default: '#000000'
+			},
+			color: {
+				type: String,
+				default: '#000000'
+			},
+			duration:{
+				type: Number,
+				default: 3000
+			}
+		},
+		data() {
+
+
+			return {
+				// 心电图实列数组
+				elects: [],
+				bRun:false,
+				deley:true,
+				imageSrc:imageSrc
+			};
+		},
+		created() {
+			// setTimeout(()=>{
+			// 	this.deley = true;
+			// 	console.log("character created");
+			// },5000)
+		},
+		methods: {
+			onplay(){
+				this.deley = true;
+				console.log("character created");
+			}
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.character-parent {
+		// border: 1rpx solid #ffaa7f;
+		position: relative;
+		display: flex;
+		justify-content: center;
+		
+	}
+
+	.character-container {
+		width: 125px;
+		// height: 830px;
+		// border: 1rpx solid #000000;
+		position: relative;
+		overflow: hidden;
+	}
+
+	.character {
+		background-repeat: no-repeat;
+		width: 125px;
+		height: 138px;
+		position: relative;
+	
+		// background-color: #007AFF;
+	}
+	
+	.play{
+		animation: character-run 1s steps(1, start) infinite;
+		animation-play-state: running;
+	}
+	
+	@keyframes character-run {
+		0%,100% {
+			background-position: 0 0;
+		}
+		@for $i from 1 through 34 {
+			
+			#{$i*3.03}% {
+				background-position: 0 -138px*$i;
+			}
+		}
+	}
+</style>

+ 371 - 0
components/electAni/electAnimation.vue

@@ -0,0 +1,371 @@
+<template>
+	<view>
+		<view class="elect-parent">
+			<view class="elect-container" :class="[elect._start?' playMove ':'',elect._running?'movePaused':' movePlay ']"
+			 :style="{'animation-duration': elect.allSecond+'s'}">
+				<view class="elect" :id="elect._id" :style="{ 
+					 borderColor: borderColor, 
+				     color: color,
+					 '--time':elect._remainingTime,
+					 backgroundImage:`url(${imageSrc})`}"
+				 :class=" elect._running?' play ':''">
+				</view>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	// 创建对象
+	function createElectObj(props) {
+		return new ElectObj(props || {})
+	}
+
+	function ElectObj(props) {
+		this.animationData = props.animationData || null;
+		this.allDuration = props.allDuration || 1000;
+		this.allSecond = props.allDuration / 1000;
+		console.log("this.allSecond=", this.allSecond);
+		// 页面对象
+		this._id = props.id || 0;
+		// return;
+		//是否运行心电图
+		this._running = false;
+		this._left = 0;
+		this._startLeft = 0;
+		this._start = false;
+		this._play = false;
+		// 是否在进行播放
+		this._bPlaying = false;
+		// 移动的距离
+		this._Distance = 350;
+		//心电图走的时间
+		this._remainingTime = 0;
+		this.moveTime = 0;
+
+		//计算器
+		this._interval = null;
+
+		// 心电图走的速度,
+		this._speed = this._Distance / props.allDuration;
+		//实列对象的参数
+		this.animation = uni.createAnimation();
+
+
+		//实列音频对象
+		this.hitUrl = "../../../static/elect/hit.mp3";
+		this.hitTenUrl = "../../../static/elect/hit-ten.mp3";
+		this.createUrl = "../../../static/elect/create.mp3";
+		this.missUrl = "../../../static/elect/miss.mp3";
+
+		this.playAudioContext = uni.createInnerAudioContext();
+		this.playAudioContext.autoplay = false;
+		this.playAudioContext.src = this.hitUrl;
+		this.playAudioContext.volume = 1;
+
+		// this.missAudioContext = uni.createInnerAudioContext();
+		// this.missAudioContext.autoplay = false;
+		// this.missAudioContext.src = "../../../static/elect/miss.mp3";
+		// this.missAudioContext.volume = 1;
+
+		this.playCount = 0;
+
+	}
+	ElectObj.prototype = {
+		setVolume: function(volume) {
+			// this.missAudioContext.volume = volume;
+			this.playAudioContext.volume = volume;
+		},
+		setDuration: function(_allduration) {
+			this.allDuration = _allduration;
+			this.allSecond = _allduration / 1000;
+			this._speed = this._Distance / _allduration;
+		},
+		//结束时候重置对应状态
+		electEnd: function() {
+			console.log("心电图结束");
+			this.playCount = 0;
+			this.playAudioContext.stop();
+			// this.missAudioContext.stop();
+			this.setVolume(0);
+		},
+		//播放序列帧动画
+		play: function(_self, _parentLeft) {
+			// console.log('play');
+			if (this._play) return;
+			// 用执行时间来判断
+			if (this.moveTime < this.allDuration * 0.1) return;
+
+			this._play = true;
+			_self.$emit('onElectPlay');
+
+			if (this.playCount < 5) {
+				this.playAudioContext.src = this.hitUrl;
+				this.playAudioContext.stop();
+				this.playAudioContext.play();
+				this.playCount++;
+			} else {
+				this.playAudioContext.src = this.hitTenUrl;
+				this.playAudioContext.stop();
+				this.playAudioContext.play();
+				this.playCount = 0;
+				// console.log("播放特殊音效");
+
+			}
+			// 计算点击后剩余的时间
+			this._remainingTime = (this.allDuration - this.moveTime) / 1000;
+
+			this._running = true;
+		},
+
+
+		// 移动动画
+		move: function(callback) {
+
+			if (this._bPlaying) return;
+			this._bPlaying = true;
+
+			this.playAudioContext.src = this.createUrl;
+			this.playAudioContext.stop();
+			this.playAudioContext.play();
+
+			// 移动前初始化一部分默认参数
+			this._play = false;
+			this._start = true;
+
+			// console.log("this.allDuration==", this.allDuration);
+			let timeUnit = 300;
+			this._interval = setInterval(() => {
+
+				this.moveTime += timeUnit;
+				if (this.moveTime >= this.allDuration) {
+					this._running = false;
+					this._start = false;
+					// 完成后,初始化到位置最初状态
+					clearInterval(this._interval);
+					this._interval = null;
+					this.moveTime = 0;
+					setTimeout(() => {
+						if (callback)
+							callback();
+					}, 100)
+
+				}
+			}, timeUnit);
+		}
+	}
+	import imageSrc from "@/static/elect/elect.png"
+
+	export default {
+		props: {
+			parentLeft: {
+				type: Number,
+				default: 0
+			},
+			electLeft: {
+				type: Number,
+				default: 150
+			},
+			backgroundColor: {
+				type: String,
+				default: '#007AFF'
+			},
+			borderColor: {
+				type: String,
+				default: '#000000'
+			},
+			color: {
+				type: String,
+				default: '#000000'
+			},
+			duration: {
+				type: Number,
+				default: 3000
+			}
+		},
+		data() {
+			return {
+				// 心电图实列数组
+				elects: [],
+				elect: null,
+				bRun: false,
+				bInitMissAudio: false,
+				bPlayMissAudio: false,
+				imageSrc: imageSrc
+
+			};
+		},
+		created() {
+			// 动画要最开始实例化
+			this.animation = uni.createAnimation();
+			// let initElects = [];
+			// for (var i = 0; i < 1; i++) {
+			// 	var temp = createElectObj({
+			// 		id: 'elect' + i,
+			// 		allDuration: this.duration,
+			// 	});
+			// 	initElects.push(temp);
+			// }
+
+			// this.elects = initElects; //Object.assign({},this.elects,initElects);
+			this.elect = createElectObj({
+				id: 'elect0',
+				allDuration: this.duration,
+			});
+
+			// setTimeout(() => {
+			// 	this.playElect();
+			// }, 100)
+		},
+		methods: {
+			/**
+			 * 调用移动心电图整体的动画
+			 */
+			moveElect() {
+				// 从数组一个数据做操作,开始循环
+				if (!this.bRun) return;
+				console.log(this.bRun);
+				this.elect.move(() => {
+					if (!this.elect._play) {
+						// this.elect.missAudioContext.play();
+						this.elect.playAudioContext.src = this.elect.missUrl;
+						this.elect.playAudioContext.stop();
+						this.elect.playAudioContext.play();
+						// console.log(11);
+						// if (!this.bInitMissAudio) {
+						// 	this.elect.playAudioContext.onEnded(() => {
+						// 		//最后一个音效播放完后,在继续下一个线段出来
+						// 		this.elect._bPlaying = false;
+						// 		this.moveElect();
+						// 	});
+						// 	this.bInitMissAudio = true;
+						// }
+						setTimeout(() => {
+							//最后一个音效播放完后,在继续下一个线段出来
+							this.elect._bPlaying = false;
+							this.moveElect();
+						}, 500);
+						this.$emit('onElectMiss')
+					} else {
+						this.elect._bPlaying = false;
+						// this.elect.playAudioContext.offEnded();
+						this.moveElect();
+					}
+				});
+
+			},
+			/**
+			 * 播放心电图序列帧动画
+			 */
+			jumpElect() {
+				// console.log(11);
+				this.elect.play(this, this.parentLeft);
+			},
+
+			/**
+			 * 暂停播放心电图
+			 */
+			pausedElect(bEnd) {
+				this.bRun = false;
+				//声音要暂停
+				if (bEnd) {
+					this.elect.electEnd();
+				}
+			},
+			/**
+			 * 开始播放
+			 */
+			playElect() {
+				this.bRun = true;
+				this.moveElect();
+
+			},
+			/**
+			 * 修改时间
+			 * @param {Object} changeDuration
+			 */
+			changeDuration(changeDuration) {
+				this.elect.setDuration(changeDuration);
+			},
+
+			/**
+			 * 禁音
+			 */
+			setVolume(volume) {
+				this.elect.setVolume(volume);
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.elect-parent {
+		// border: 1rpx solid #ffaa7f;
+		position: relative;
+		display: flex;
+		justify-content: center;
+		overflow: hidden;
+	}
+
+	.elect-container {
+		width: 100%;
+		height: 68px;
+		// border: 1rpx solid #000000;
+		position: relative;
+
+	}
+
+	.elect {
+		// background-color: #007AFF;
+		background-size: cover;
+		height: 68px;
+		width: 337px;
+		position: relative;
+		top: 0;
+		left: -156px;
+	}
+
+	.playMove {
+		// animation: move linear calc(var(--mTime) / 1000 * 1s) both;
+		animation-name: move;
+		animation-timing-function: linear;
+		animation-fill-mode: both;
+	}
+
+	.movePlay {
+		animation-play-state: running;
+	}
+
+	.movePaused {
+		animation-play-state: paused;
+	}
+
+	.play {
+		animation: run calc(var(--time) * 1s) steps(1, start) both;
+		animation-play-state: running;
+	}
+
+	@keyframes move {
+		0% {
+			transform: translateX(0);
+		}
+
+		100% {
+			transform: translateX(350px);
+		}
+	}
+
+	@keyframes run {
+		@for $i from 0 through 49 {
+			#{$i*2}% {
+				background-position: -0px -68px*$i;
+			}
+		}
+
+		100% {
+			background-position: -0px -3400px;
+		}
+	}
+</style>

+ 66 - 0
components/fruitMachine/fruit.js

@@ -0,0 +1,66 @@
+
+const getFruitIndex = function(calorie) {
+	let  fruitIndex = [0,0,0];
+	let currentCalorie = calorie;
+	// console.log(currentCalorie);
+	for (let i = 0; i < 3; i++) {
+		for (let j = 0; j < this.fruitArray.length; j++) {
+			if (currentCalorie >= this.fruitArray[j].value) {
+				fruitIndex[i] = j;
+			}
+	
+			if (currentCalorie >= this.fruitArray[fruitIndex[i]].value && j == this.fruitArray.length - 1) {
+				currentCalorie -= this.fruitArray[fruitIndex[i]].value;
+	
+				// console.log("this.currentCalorie:"+i+"=", currentCalorie);
+			}
+	
+		}
+	}
+	
+	return fruitIndex;
+}
+
+export default {
+	getFruitIndex,
+	fruitArray: [{
+		name: '问号',
+		value: 0
+	}, {
+		name: '花生',
+		value: 10
+	}, {
+		name: '虾饺',
+		value: 50
+	}, {
+		name: '煎蛋',
+		value: 100
+	}, {
+		name: '火腿',
+		value: 150
+	}, {
+		name: '冰淇淋',
+		value: 200
+	}, {
+		name: '中薯',
+		value: 250
+	}, {
+		name: '炸鸡',
+		value: 300
+	}, {
+		name: '可乐',
+		value: 350
+	}, {
+		name: '奶油',
+		value: 400
+	}, {
+		name: '炒饭',
+		value: 450
+	}, {
+		name: '汉堡',
+		value: 500
+	}, {
+		name: '东陂肉',
+		value: 550
+	}]
+}

+ 242 - 0
components/fruitMachine/fruitMachine.vue

@@ -0,0 +1,242 @@
+<template>
+	<view >
+		<view class="fruit-container">
+			<view class="fruitBg-container">
+				<view class="fruitBg"></view>
+				<view class="fruitBg"></view>
+				<view class="fruitBg"></view>
+			</view>
+			<view class="fruit" :class="runing1?'fruitPlay':'fruitPaused'" :style="{backgroundImage:`url(${imageSrc})`,'--i':fruitIndex[0]}"></view>
+			<view class="fruit" :class="runing2?'fruitPlay':'fruitPaused'" :style="{backgroundImage:`url(${imageSrc})`,'--i':fruitIndex[1]}"></view>
+			<view class="fruit" :class="runing3?'fruitPlay':'fruitPaused'" :style="{backgroundImage:`url(${imageSrc})`,'--i':fruitIndex[2]}"></view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import imageSrc from "@/static/fruitMachine/fruitMachine.png"
+	import fruit from "./fruit.js"
+	
+	export default {
+		props: {
+			calorie: {
+				type: Number,
+				default: 10
+			},
+
+		
+		},
+		data() {
+			return {
+				
+				runing1: false,
+				runing2: false,
+				runing3: false,
+				imageSrc: imageSrc,
+				fruitIndex: [0, 0, 0],
+				// 水果卡路里数组,对应图片
+				// 问号,花生,虾饺,煎蛋,火腿,冰淇淋,中薯,炸鸡,可乐,奶油,炒饭,汉堡,东陂肉
+				// fruitArray: [{
+				// 	name: '问号',
+				// 	value: 0
+				// }, {
+				// 	name: '花生',
+				// 	value: 10
+				// }, {
+				// 	name: '虾饺',
+				// 	value: 50
+				// }, {
+				// 	name: '煎蛋',
+				// 	value: 100
+				// }, {
+				// 	name: '火腿',
+				// 	value: 150
+				// }, {
+				// 	name: '冰淇淋',
+				// 	value: 200
+				// }, {
+				// 	name: '中薯',
+				// 	value: 250
+				// }, {
+				// 	name: '炸鸡',
+				// 	value: 300
+				// }, {
+				// 	name: '可乐',
+				// 	value: 350
+				// }, {
+				// 	name: '奶油',
+				// 	value: 400
+				// }, {
+				// 	name: '炒饭',
+				// 	value: 450
+				// }, {
+				// 	name: '汉堡',
+				// 	value: 500
+				// }, {
+				// 	name: '东陂肉',
+				// 	value: 550
+				// }],
+				// currentCalorie: this.calorie
+				
+				//击打状态音效
+				fruitRuningUrl: "/static/elect/hit-ten.mp3",
+				fruitAudioContext:null,
+				bCanPlay:false,
+			};
+		},
+		watch: {
+			calorie(newVal,oldVal) {
+				// console.log("fruitMachine",newVal,oldVal);
+				// let _temp = Number(newVal).sub(oldVal);
+				// if(Number(_temp)>=10)
+				// {
+				this.onPlayAudio();
+				// }
+				this.onPlay();
+			}
+		},
+		created() {
+			this.onPlay();
+			// console.log("=======",imageSrc);
+			
+			this.fruitAudioContext = uni.createInnerAudioContext();
+			this.fruitAudioContext.autoplay = false;
+			this.fruitAudioContext.src = this.fruitRuningUrl;
+			this.fruitAudioContext.volume = 0.5;
+
+		},
+		methods: {
+			onPersonalHide(){
+			},
+			onPersonalShow(){
+			},
+			onCanPlay(){
+				this.bCanPlay = true;
+			},
+			onPlayAudio(){
+				if(this.fruitAudioContext && this.bCanPlay){
+					this.bCanPlay = false;
+					this.fruitAudioContext.stop();
+					this.fruitAudioContext.play();
+				}
+			
+			},
+			onUpdateCalorie() {
+				this.fruitIndex = [0, 0, 0];
+				this.fruitIndex=fruit.getFruitIndex(this.calorie);
+				// console.log("this.fruitIndex:",this.fruitIndex);
+			},
+			onPlay() {
+				if (!this.runing1 && !this.runing2 && !this.runing3) {
+					
+					if(this.calorie < 10  )
+						return;
+					
+					// this.onPlayAudio();
+					
+					this.runing1 = true
+					setTimeout(() => {
+						this.runing2 = true;
+					}, 500)
+					setTimeout(() => {
+						this.runing3 = true;
+					}, 1000)
+					setTimeout(() => {
+						this.onUpdateCalorie();
+						this.onPaused();
+					}, 2000)
+				}
+			},
+			onPaused() {
+
+				if (this.runing1 && this.runing2 && this.runing3) {
+					this.runing1 = false
+					setTimeout(() => {
+						this.runing2 = false;
+					}, 1000)
+					setTimeout(() => {
+						this.runing3 = false;
+					}, 2000)
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+
+
+	.fruit-container {
+		width: 400px;
+		height: 100px;
+		margin-top: 60px;
+		// border: 1rpx solid #000000;
+		position: relative;
+		overflow: hidden;
+		display: flex;
+		transform: scale(0.3);
+		justify-content: center;
+		flex-direction: row;
+	}
+
+	.fruitBg-container {
+		position: absolute;
+		left: 0;
+		top: 0;
+		width: 100%;
+		height: 100%;
+		display: flex;
+		justify-content: center;
+		flex-direction: row;
+	}
+
+	.fruitBg {
+		width: 100px;
+		height: 100px;
+		position: relative;
+		// background-color: #007AFF;
+		background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba($color: #FFFFFF, $alpha: 0.3), rgba(0, 0, 0, 0));
+		margin: 5px;
+	}
+
+	.fruit {
+		background-repeat: no-repeat;
+		width: 100px;
+		height: 100px;
+		position: relative;
+		margin: 5px;
+		// animation: fruit-run 10s infinite;
+		// background-color: #007AFF;
+
+	}
+
+	.fruitPlay {
+		animation-name: fruit-run;
+		animation-duration: 1s;
+		animation-iteration-count: infinite;
+		animation-timing-function: linear;
+		animation-play-state: running;
+	}
+
+	.fruitPaused {
+		background-position: 0 calc(-100px * var(--i));
+		transition: background-position 2s;
+	}
+
+	@keyframes fruit-run {
+		0% {
+			background-position: 0 0;
+		}
+
+		@for $i from 1 through 11 {
+
+			#{$i*9.09}% {
+				background-position: 0 -100px*$i;
+			}
+		}
+
+		100% {
+			background-position: -0px -1200px;
+		}
+	}
+</style>

+ 41 - 0
components/keyboard-listener/keyboard-listener.vue

@@ -0,0 +1,41 @@
+<template>
+  <view></view>
+</template>
+
+<script>
+export default {
+  methods: {
+    onEvent(event) {
+      this.$emit(event.type, event)
+    },
+  },
+}
+</script>
+
+<script module="keyboard" lang="renderjs">
+export default {
+  mounted () {
+    const onKey = (event) => {
+      const keys1 = ['type', 'timeStamp']
+      const keys2 = ['altKey', 'code', 'ctrlKey', 'isComposing', 'key', 'location', 'metaKey', 'repeat', 'shiftKey']
+      const keys3 = ['char', 'charCode', 'keyCode', 'keyIdentifier', 'keyLocation', 'which']
+      const data = {}
+      keys1.concat(keys2, keys3).forEach(key => data[key] = event[key])
+	  // console.log("data:",data);
+      this.$ownerInstance.callMethod('onEvent', data)
+    }
+    const names = ['keydown', 'keyup']
+    names.forEach(name => {
+      document.addEventListener(name, onKey, false)
+    })
+    this.$on('hook:beforeDestroy', () => {
+      names.forEach(name => {
+        document.removeEventListener(name, onKey, false)
+      })
+    })
+  }
+}
+</script>
+
+<style>
+</style>

+ 377 - 0
components/m-icon/m-icon.css

@@ -0,0 +1,377 @@
+@font-face {
+	font-family: uniicons;
+	font-weight: normal;
+	font-style: normal;
+	src: url('https://img-cdn-qiniu.dcloud.net.cn/fonts/uni.ttf?t=1536565627510') format('truetype');
+}
+
+.m-icon {
+	font-family: uniicons;
+	font-size: 48upx;
+	font-weight: normal;
+	font-style: normal;
+	line-height: 1;
+	display: inline-block;
+	text-decoration: none;
+	-webkit-font-smoothing: antialiased;
+}
+
+.m-icon.uni-active {
+	color: #007aff;
+}
+
+.m-icon-contact:before {
+	content: '\e100';
+}
+
+.m-icon-person:before {
+	content: '\e101';
+}
+
+.m-icon-personadd:before {
+	content: '\e102';
+}
+
+.m-icon-contact-filled:before {
+	content: '\e130';
+}
+
+.m-icon-person-filled:before {
+	content: '\e131';
+}
+
+.m-icon-personadd-filled:before {
+	content: '\e132';
+}
+
+.m-icon-phone:before {
+	content: '\e200';
+}
+
+.m-icon-email:before {
+	content: '\e201';
+}
+
+.m-icon-chatbubble:before {
+	content: '\e202';
+}
+
+.m-icon-chatboxes:before {
+	content: '\e203';
+}
+
+.m-icon-phone-filled:before {
+	content: '\e230';
+}
+
+.m-icon-email-filled:before {
+	content: '\e231';
+}
+
+.m-icon-chatbubble-filled:before {
+	content: '\e232';
+}
+
+.m-icon-chatboxes-filled:before {
+	content: '\e233';
+}
+
+.m-icon-weibo:before {
+	content: '\e260';
+}
+
+.m-icon-weixin:before {
+	content: '\e261';
+}
+
+.m-icon-pengyouquan:before {
+	content: '\e262';
+}
+
+.m-icon-chat:before {
+	content: '\e263';
+}
+
+.m-icon-qq:before {
+	content: '\e264';
+}
+
+.m-icon-videocam:before {
+	content: '\e300';
+}
+
+.m-icon-camera:before {
+	content: '\e301';
+}
+
+.m-icon-mic:before {
+	content: '\e302';
+}
+
+.m-icon-location:before {
+	content: '\e303';
+}
+
+.m-icon-mic-filled:before,
+.m-icon-speech:before {
+	content: '\e332';
+}
+
+.m-icon-location-filled:before {
+	content: '\e333';
+}
+
+.m-icon-micoff:before {
+	content: '\e360';
+}
+
+.m-icon-image:before {
+	content: '\e363';
+}
+
+.m-icon-map:before {
+	content: '\e364';
+}
+
+.m-icon-compose:before {
+	content: '\e400';
+}
+
+.m-icon-trash:before {
+	content: '\e401';
+}
+
+.m-icon-upload:before {
+	content: '\e402';
+}
+
+.m-icon-download:before {
+	content: '\e403';
+}
+
+.m-icon-close:before {
+	content: '\e404';
+}
+
+.m-icon-redo:before {
+	content: '\e405';
+}
+
+.m-icon-undo:before {
+	content: '\e406';
+}
+
+.m-icon-refresh:before {
+	content: '\e407';
+}
+
+.m-icon-star:before {
+	content: '\e408';
+}
+
+.m-icon-plus:before {
+	content: '\e409';
+}
+
+.m-icon-minus:before {
+	content: '\e410';
+}
+
+.m-icon-circle:before,
+.m-icon-checkbox:before {
+	content: '\e411';
+}
+
+.m-icon-close-filled:before,
+.m-icon-clear:before {
+	content: '\e434';
+}
+
+.m-icon-refresh-filled:before {
+	content: '\e437';
+}
+
+.m-icon-star-filled:before {
+	content: '\e438';
+}
+
+.m-icon-plus-filled:before {
+	content: '\e439';
+}
+
+.m-icon-minus-filled:before {
+	content: '\e440';
+}
+
+.m-icon-circle-filled:before {
+	content: '\e441';
+}
+
+.m-icon-checkbox-filled:before {
+	content: '\e442';
+}
+
+.m-icon-closeempty:before {
+	content: '\e460';
+}
+
+.m-icon-refreshempty:before {
+	content: '\e461';
+}
+
+.m-icon-reload:before {
+	content: '\e462';
+}
+
+.m-icon-starhalf:before {
+	content: '\e463';
+}
+
+.m-icon-spinner:before {
+	content: '\e464';
+}
+
+.m-icon-spinner-cycle:before {
+	content: '\e465';
+}
+
+.m-icon-search:before {
+	content: '\e466';
+}
+
+.m-icon-plusempty:before {
+	content: '\e468';
+}
+
+.m-icon-forward:before {
+	content: '\e470';
+}
+
+.m-icon-back:before,
+.m-icon-left-nav:before {
+	content: '\e471';
+}
+
+.m-icon-checkmarkempty:before {
+	content: '\e472';
+}
+
+.m-icon-home:before {
+	content: '\e500';
+}
+
+.m-icon-navigate:before {
+	content: '\e501';
+}
+
+.m-icon-gear:before {
+	content: '\e502';
+}
+
+.m-icon-paperplane:before {
+	content: '\e503';
+}
+
+.m-icon-info:before {
+	content: '\e504';
+}
+
+.m-icon-help:before {
+	content: '\e505';
+}
+
+.m-icon-locked:before {
+	content: '\e506';
+}
+
+.m-icon-more:before {
+	content: '\e507';
+}
+
+.m-icon-flag:before {
+	content: '\e508';
+}
+
+.m-icon-home-filled:before {
+	content: '\e530';
+}
+
+.m-icon-gear-filled:before {
+	content: '\e532';
+}
+
+.m-icon-info-filled:before {
+	content: '\e534';
+}
+
+.m-icon-help-filled:before {
+	content: '\e535';
+}
+
+.m-icon-more-filled:before {
+	content: '\e537';
+}
+
+.m-icon-settings:before {
+	content: '\e560';
+}
+
+.m-icon-list:before {
+	content: '\e562';
+}
+
+.m-icon-bars:before {
+	content: '\e563';
+}
+
+.m-icon-loop:before {
+	content: '\e565';
+}
+
+.m-icon-paperclip:before {
+	content: '\e567';
+}
+
+.m-icon-eye:before {
+	content: '\e568';
+}
+
+.m-icon-arrowup:before {
+	content: '\e580';
+}
+
+.m-icon-arrowdown:before {
+	content: '\e581';
+}
+
+.m-icon-arrowleft:before {
+	content: '\e582';
+}
+
+.m-icon-arrowright:before {
+	content: '\e583';
+}
+
+.m-icon-arrowthinup:before {
+	content: '\e584';
+}
+
+.m-icon-arrowthindown:before {
+	content: '\e585';
+}
+
+.m-icon-arrowthinleft:before {
+	content: '\e586';
+}
+
+.m-icon-arrowthinright:before {
+	content: '\e587';
+}
+
+.m-icon-pulldown:before {
+	content: '\e588';
+}
+
+.m-icon-scan:before {
+    content: "\e612";
+}

+ 41 - 0
components/m-icon/m-icon.vue

@@ -0,0 +1,41 @@
+<template>
+	<view class="m-icon" :class="['m-icon-'+type]" :style="{color:color,'font-size':fontSize}" @click="onClick()"></view>
+</template>
+
+<script>
+	export default {
+		props: {
+			/**
+			 * 图标类型
+			 */
+			type: String,
+			/**
+			 * 图标颜色
+			 */
+			color: String,
+			/**
+			 * 图标大小
+			 */
+			size: {
+				type: [Number, String],
+				default: 24
+			}
+		},
+		computed: {
+			fontSize() {
+				var size = Number(this.size)
+				size = isNaN(size) ? 24 : size
+				return `${size}px`
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style>
+	@import "./m-icon.css";
+</style>

+ 162 - 0
components/m-input.vue

@@ -0,0 +1,162 @@
+<template>
+	<view class="m-input-view">
+		<input :focus="focus_" :maxlength="maxlength" :type="inputType" :value="value" @input="onInput" class="m-input-input"
+		 placeholder-style="color:rgba(170, 170, 170, 1);" :placeholder="placeholder" :password="type==='password'&&!showPassword"
+		 @focus="onFocus" @blur="onBlur" />
+		<!-- 优先显示密码可见按钮 -->
+		<view v-if="clearable_&&!displayable_&&value.length" class="m-input-icon">
+			<!-- <m-icon color="rgba(170, 170, 170, 1)" type="clear" size="20" @click="clear"></m-icon> -->
+
+			<text class="cuIcon-roundclose" @click="clear"></text>
+		</view>
+		<view v-if="displayable_" class="m-input-icon">
+			<!-- <m-icon :color="showPassword?'rgba(170, 170, 170, 1)':'#cccccc'" type="eye" size="20" @click="display"></m-icon> -->
+			<!-- <image mode="scaleToFill" class="password-img" v-if="showPassword" src="../static/m-icon/sPassword.png" @click="display"></image> -->
+			<!-- <image mode="scaleToFill" class="password-img" v-else src="../static/m-icon/cPassword.png"  @click="display"></image> -->
+			<text :class="showPassword?'cuIcon-attention':'cuIcon-attentionfill'" @click="display"></text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import mIcon from './m-icon/m-icon.vue'
+
+	export default {
+		components: {
+			mIcon
+		},
+		props: {
+			/**
+			 * 输入类型
+			 */
+			type: String,
+			/**
+			 * 值
+			 */
+			value: String,
+			/**
+			 * 占位符
+			 */
+			placeholder: String,
+
+			maxlength: {
+				type: String,
+				default: "-1"
+			},
+			/**
+			 * 是否显示清除按钮
+			 */
+			clearable: {
+				type: [Boolean, String],
+				default: false
+			},
+			/**
+			 * 是否显示密码可见按钮
+			 */
+			displayable: {
+				type: [Boolean, String],
+				default: false
+			},
+			/**
+			 * 自动获取焦点
+			 */
+			focus: {
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		model: {
+			prop: 'value',
+			event: 'input'
+		},
+		data() {
+			return {
+				/**
+				 * 显示密码明文
+				 */
+				showPassword: false,
+				/**
+				 * 是否获取焦点
+				 */
+				isFocus: false
+			}
+		},
+		computed: {
+			inputType() {
+				const type = this.type
+				return type === 'password' ? 'text' : type
+			},
+			clearable_() {
+				return String(this.clearable) !== 'false'
+			},
+			displayable_() {
+				return String(this.displayable) !== 'false'
+			},
+			focus_() {
+				return String(this.focus) !== 'false'
+			}
+		},
+		methods: {
+			clear() {
+				this.$emit('input', '')
+			},
+			display() {
+				this.showPassword = !this.showPassword
+			},
+			onFocus() {
+				this.isFocus = true
+			},
+			onBlur() {
+				this.$nextTick(() => {
+					this.isFocus = false
+				})
+			},
+			onInput(e) {
+				this.$emit('input', e.target.value)
+			}
+		}
+	}
+</script>
+
+<style>
+	.m-input-view {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		width: 580rpx;
+		flex: 1;
+		padding: 0 10rpx;
+		/* position: relative; */
+	}
+
+	.m-input-input {
+		flex: 1;
+		width: 100%;
+		height: 25px;
+		color: rgba(170, 170, 170, 1);
+		color: 18px;
+		/* border: 1rpx solid #007AFF; */
+	}
+
+	.m-input-icon {
+		width: 30px;
+		/* height: 30px; */
+		/* 	position: absolute;
+		 */
+		margin-right: 40rpx;
+		margin-left: 10rpx;
+	}
+
+	.m-input-icon text {
+		font-size: 20px;
+		color: rgba(170, 170, 170, 1)
+	}
+
+	.password-img {
+		/* background-color: #007AFF; */
+		width: 18px;
+		height: 14px;
+
+
+	}
+</style>

+ 61 - 0
components/modal-tip/modalTip.vue

@@ -0,0 +1,61 @@
+<template>
+	<view class="cu-modal "  @touchmove.stop.prevent="moveBoxingHandle">
+		<view class="cu-bind-modal">
+			<view style="position: absolute; top: 0; left: 0; width: 100%; height:100%;">
+				<image style="position: absolute;top: 0;left: 0; width: 100%;height: 100%;" src="/static/modelBg.png"></image>
+			</view>
+			<view class="flex flex-direction justify-between " style="position: relative; height: 100%;">
+				<view class="flex justify-around justify-center align-center" style="margin: 170rpx 30rpx 0 30rpx;">
+					<view style="width: 80rpx;height: 2rpx;border-radius: 2px; background-color: #cbcdcf;"></view>
+					<view class="make-text-bPurple" style=" font-size: 20px;">{{title}}</view>
+					<view style="width: 80rpx;height: 2rpx;border-radius: 2px;background-color: #cbcdcf;"></view>
+				</view>
+				<view class="text-16px" style="align-self: center; max-width: 200px; word-break: break-all;">{{context}}</view>
+	
+				<view class="flex justify-around align-center" style=" border-top: 1rpx solid #EEEEEE; margin-bottom: 2px;">
+					<view class="flex justify-center align-center  text-16px" style="width: 100%;height: 123rpx;" @tap="hideModalTip">取消</view>
+					<view style="height: 123rpx;width: 1px;background-color: #EEEEEE;"></view>
+					<view class="flex justify-center align-center  text-16px" style="width: 100%;height: 123rpx;" @tap="confirmModalTip">确定</view>
+				</view>
+			</view>
+	
+	
+		</view>
+	</view>
+
+</template>
+
+<script>
+	export default {
+		props: {
+		
+		},
+		data() {
+			return {
+				title:'提示',
+				context:''
+			};
+		},
+		created() {
+
+		},
+		methods: {
+			setShowData(data){
+				let {title,context} = data;
+				this.title = title;
+				this.context = context;
+			},
+			hideModalTip(){
+				this.$emit('hide')
+			},
+			confirmModalTip(){
+				this.$emit('confirm')
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	
+</style>

+ 304 - 0
components/modal/action-jump/action-jump.vue

@@ -0,0 +1,304 @@
+<template>
+	<view>
+		<view style="display: flex;justify-content: space-between;">
+			<button  @click="startJumpGame">startGame</button>
+			<button  @click="onClear">onClear</button>
+		</view>
+
+		<view style="display: flex;justify-content: space-between;" class="margin-top margin-bottom">
+			<button @click="onJumpType(0)">jump</button>
+			<button @click="onJumpType(1)">left</button>
+			<button @click="onJumpType(2)">right</button>
+			<button @click="onJumpType(3)">rLeft</button>
+			<button @click="onJumpType(4)">rRight</button>
+		</view>
+		
+		<view style="display: flex;justify-content: space-around;">
+			<view style="font-size: 14px;">t:{{countdown}}</view>
+			<view style="font-size: 14px;">e:{{eliminationCount}}</view>
+			<view style="font-size: 14px;">f:{{faultCount}}</view>
+		</view>
+		
+		<view class="action-jump-parent margin-top margin-bottom">
+			<view class="action-jump-container">
+				<canvas canvas-id="actionJumpCanvas" style="width: 375px;height: 50px; background-color: #1CBBB4;"></canvas>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				directionJump: null,
+				midJump: null,
+				rotateJump: null,
+				jumpTypeArray: [{
+					jumpName: 'NORMAL',
+					jumpCode: 0,
+					icon: 'midJump',
+					scaleX: 1,
+					bTrigger: false,
+				}, {
+					jumpName: 'LEFT',
+					jumpCode: 1,
+					icon: 'directionJump',
+					scaleX: -1,
+					bTrigger: false,
+				}, {
+					jumpName: 'RIGHT',
+					jumpCode: 2,
+					icon: 'directionJump',
+					scaleX: 1,
+					bTrigger: false,
+				}, {
+					jumpName: 'LEFT_ROTATE',
+					jumpCode: 3,
+					icon: 'rotateJump',
+					scaleX: 1,
+					bTrigger: false,
+				}, {
+					jumpName: 'RIGHT_ROTATE',
+					jumpCode: 4,
+					icon: 'rotateJump',
+					scaleX: -1,
+					bTrigger: false,
+				}],
+				spawnArray: [],
+
+				//下一个生成是相反的方向
+				bNextSpawnRightDirection: false,
+				bNextSpawnRightRotateDirection: false,
+
+				level: 3,
+				countdown: 60,
+				countdownInterval: null,
+				
+				faultCount:0,
+				eliminationCount:0,
+			}
+		},
+		created() {
+			let _self = this;
+			uni.getImageInfo({
+				src: "../../../static/modal/action-jump/directionJump.png",
+				success: function(image) {
+					_self.directionJump = image;
+				}
+			});
+			uni.getImageInfo({
+				src: "../../../static/modal/action-jump/midJump.png",
+				success: function(image) {
+					_self.midJump = image;
+					console.log("==============", image);
+				}
+			});
+			uni.getImageInfo({
+				src: "../../../static/modal/action-jump/rotateJump.png",
+				success: function(image) {
+					_self.rotateJump = image;
+				}
+			});
+			this.actionJumpCanvas = uni.createCanvasContext("actionJumpCanvas", this);
+			console.log("this.actionJumpCanvas:", this.actionJumpCanvas);
+
+		},
+		methods: {
+			/**
+			 * 重置生成数组,重置倒计时
+			 */
+			resetJumpGame() {
+
+				this.spawnArray = [];
+				if (this.countdownInterval) {
+					clearInterval(this.countdownInterval);
+					this.countdownInterval = null;
+				}
+
+				this.resetCountdown(60);
+			},
+			startJumpGame() {
+				this.resetJumpGame();
+				//开始游戏
+
+				this.index = 0;
+				// this.levelLabel.string = '关卡' + this.level;
+				if (this.level == 1) {
+					for (let i = 0; i < 2; i++) {
+						this.spawnJumpPrefabs(i);
+					}
+					// this.buttonLabel.string = '下一关';
+
+				} else if (this.level == 2) {
+					for (let i = 0; i < 4; i++) {
+						this.spawnJumpPrefabs(i);
+					}
+					// this.buttonLabel.string = '下一关';
+				} else if (this.level == 3) {
+					for (let i = 0; i < 6; i++) {
+						this.spawnJumpPrefabs(i);
+					}
+					// this.buttonLabel.string = '最后一关';
+					//todo 暂时给循环
+					this.level = 0;
+				}
+
+				this.level++;
+
+				//倒计时
+				this.countdownInterval = setInterval(() => {
+					if (this.countdown <= 0) {
+						clearInterval(this.countdownInterval);
+						this.countdownInterval = null;
+						//处理下一个关卡
+						// console.warn('时间到,处理下一个关卡');
+						this.startJumpGame();
+						return;
+					}
+					this.setCountdown(1);
+				}, 1000);
+				
+				this.onDraw();
+			},
+			spawnJumpPrefabs(index) {
+
+				let ran = Math.floor(Math.random() * 5);
+				//todo 生成的节点,后面再处理节奏问题。比如生成顺序
+				let _jumpPrefab = Object.assign({},this.jumpTypeArray[ran]);
+				//这里处理相反方向,比如生成了一个左旋转,下一个右旋转
+
+				if (_jumpPrefab.jumpName == 'LEFT') {
+					if (this.bNextSpawnRightDirection) {
+						//如果是对应的需要记录一个对应的准确值
+						this.bNextSpawnRightDirection = false;
+					} else {
+						ran = 2; //RIGHT;
+						this.bNextSpawnRightDirection = true;
+					}
+
+				} else if (_jumpPrefab.jumpName == 'RIGHT') {
+
+					if (this.bNextSpawnRightDirection) {
+						ran = 1; //LEFT;
+						this.bNextSpawnRightDirection = false;
+
+					} else {
+						this.bNextSpawnRightDirection = true;
+					}
+				}
+				if (_jumpPrefab.jumpName == 'LEFT_ROTATE') {
+					if (this.bNextSpawnRightRotateDirection) {
+						//如果是对应的需要记录一个对应的准确值
+						this.bNextSpawnRightRotateDirection = false;
+					} else {
+						ran = 4; //RIGHT_ROTATE;
+						this.bNextSpawnRightRotateDirection = true;
+					}
+					// console.log('l==rotate', ran);
+				} else if (_jumpPrefab.jumpName == 'RIGHT_ROTATE') {
+					if (this.bNextSpawnRightRotateDirection) {
+						ran = 3; //LEFT_ROTATE;
+						this.bNextSpawnRightRotateDirection = false;
+					} else {
+						//如果是对应的需要记录一个对应的准确值
+						this.bNextSpawnRightRotateDirection = true;
+					}
+				}
+				this.spawnArray.push(_jumpPrefab);
+			},
+			onDraw() {
+				this.actionJumpCanvas.clearRect(0, 0, 375, 50);
+				for (let i = 0; i < this.spawnArray.length; i++) {
+					//默认 mid 图标
+					let _temp = this.midJump;
+					if (this.spawnArray[i].icon == 'directionJump') {
+						_temp = this.directionJump;
+					} else if (this.spawnArray[i].icon == 'rotateJump') {
+						_temp = this.rotateJump;
+					}
+					this.actionJumpCanvas.save();
+					this.actionJumpCanvas.globalAlpha = this.spawnArray[i].bTrigger ? 0.5 : 1;
+					this.actionJumpCanvas.scale(this.spawnArray[i].scaleX, 1);
+					//如果是相反绘制,需要加多一个自身位置偏移
+					let _pos = this.spawnArray[i].scaleX < 0 ? i + 1 : i;
+					this.actionJumpCanvas.drawImage(_temp.path, (_pos * 50 + 20) * this.spawnArray[i].scaleX, 0, 50, 50);
+					this.actionJumpCanvas.restore();
+				}
+				// console.log('draw');
+				this.actionJumpCanvas.draw();
+			},
+			onClear() {
+				this.resetJumpGame();
+				
+				this.onDraw();
+			},
+
+			onJumpType(event) {
+				// console.log("onJumpType:", event);
+				this.eliminateJumpPrefab(event);
+			},
+
+			// update (dt) {}
+
+			eliminateJumpPrefab(_jumpType) {
+				//如果消除完,需要重新生成
+				if (this.index >= this.spawnArray.length) return;
+				let _temp = this.spawnArray[this.index];
+				_temp.bTrigger = true;
+				this.index++;
+				//绘制新触发状态
+				this.onDraw();
+				//如果当前的跳类型和预制目标一样
+				if (_jumpType == _temp.jumpCode) {
+					//成功
+					this.setEliminationCount(1);
+				} else {
+					//失误
+					this.setFaultCount(1);
+				}
+
+			},
+
+			//设置倒计时
+			setCountdown(value) {
+				this.countdown -= value;
+				// this.countdownLabel.string = '倒计时:' + this.countdown;
+			},
+			resetCountdown(value) {
+				this.countdown = value;
+				// this.countdownLabel.string = '倒计时:' + this.countdown;
+			},
+			//设置ui信息
+			setEliminationCount(value) {
+				this.eliminationCount += value;
+				// this.eliminationLabel.string = '消除数量:' + this.eliminationCount.toString();
+			},
+			setFaultCount(value) {
+				this.faultCount += value;
+				// this.faultLabel.string = '失误:' + this.faultCount;
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.action-jump-parent {
+		border: 1rpx solid #ffaa7f;
+		position: relative;
+		display: flex;
+		justify-content: center;
+		overflow: hidden;
+		top: 0;
+		width: 750rpx;
+	}
+
+	.action-jump-container {
+		width: 100%;
+		height: 50px;
+		border: 1rpx solid #000000;
+		position: relative;
+		// display: flex;
+	}
+</style>

+ 1444 - 0
components/modal/boxing-hit/boxing-hit.vue

@@ -0,0 +1,1444 @@
+<template>
+	<view style="width:100%; margin-bottom: 50rpx;">
+
+		<!-- 计时器 -->
+		<view class="hitBoxingTimer flex justify-center">
+			<boxingCountDown ref="boxingCountDownRef" :show-day="false" :second="showSportTime" color="#9695f7" background-color="#FFFFFF"
+			 border-color="#007AFF" splitorColor="#FFFFFF" />
+		</view>
+
+
+		<view v-if="mode == 'pkMode'" style="height: 50rpx;"></view>
+		<view v-else style="height: 20rpx;"></view>
+
+		<view style="display: flex; flex-direction: column; justify-content: center;align-items: center;
+		 position: relative; width: 100%;">
+
+			<!-- 波动 -->
+			<view v-if="mode !== 'pkMode'" class="flex justify-around align-center" style="width: 600rpx;height: 100rpx; margin: 20rpx;">
+				<view style="height: 1rpx;width: 80rpx;background-color: #FFFFFF;"></view>
+				<view style="display: flex; justify-content: center; align-self: center; height: 100%;">
+					<view style="display: flex; justify-content: center; align-items: center;">
+						<view class="wave-d-item  " v-for="(item, index) in wave_d_time" :key="index" :class="wave_d_play?'hit-wave':''"
+						 :style="{'--time': item.run * wave_run_ratio,'--delay':item.delay * wave_run_ratio,'height': wave_d_play?item.sHeight+'rpx':'20rpx'}"></view>
+					</view>
+					<view style="display: flex; justify-content: center; align-items: center; flex-direction: row-reverse;">
+						<view class="wave-d-item  " v-for="(item, index) in wave_d_time" :key="index" :class="wave_d_play?'hit-wave':''"
+						 :style="{'--time': item.run * wave_run_ratio,'--delay':item.delay * wave_run_ratio,'height': wave_d_play?item.sHeight+'rpx':'20rpx'}"></view>
+					</view>
+				</view>
+
+				<view style="height: 1rpx;width: 80rpx;background-color: #FFFFFF;"></view>
+			</view>
+			<view v-if="mode == 'pkMode'" style="height: 30rpx;"></view>
+
+			<!-- 当前拳击力-->
+			<view v-if="mode == 'pkMode'" class="flex justify-center align-center " style="margin-top: 40rpx; background-color: rgba(255,255,255,0.1); width: 420rpx; height: 90rpx;border-radius: 60rpx;">
+				<image src="/static/modal/boxing-hit/b.png" style="width: 50rpx; height: 50rpx;" mode="aspectFit"></image>
+
+				<view class="hit-current-count">
+					{{currentHitStrength}}
+				</view>
+			</view>
+			<!-- <view v-else style="position: relative; width: 100%;" :style="{'opacity': hitStrengthOpacity}">
+				<view style="position: absolute;
+				left: 0;
+				top: 0;
+				bottom: 0;
+				right: 0;" class="flex justify-center">
+					<view class="flex justify-center align-center " style="background-color: rgba(0,0,0,0.4); width: 300rpx; height: 90rpx;border-radius: 60rpx;">
+						<view class="hit-current-count-power">力量</view>
+						<view class="hit-current-count">
+							{{currentHitStrength}}
+						</view>
+					</view>
+				</view>
+			</view> -->
+
+
+			<view v-if="mode == 'pkMode'" style="height: 110rpx;"></view>
+			<view v-else style="height: 20rpx;"></view>
+
+			<!-- 控制按钮 -->
+			<view class="flex justify-center " :class="mode == 'pkMode'?'big':''" style="margin-top: 40rpx;" @tap="onControlPlay">
+				<view style="position: relative; width: 260rpx; height: 260rpx;">
+					<image style="width: 100%; height: 100%;" src="/static/modal/boxing-hit/hit-button-bg.png"></image>
+					<image class="hit-button-rotate " :class="bRingAnimation?'hit-button-bg-play':'hit-button-bg-paused'" style="position: absolute;top: 10%;left: 10%;bottom: 0;right: 0;width: 80%; height: 80%;"
+					 src="/static/modal/boxing-hit/hit-button-ef.png"></image>
+					<view style="position: absolute;top: 0;left: 0;bottom: 0;right: 0;width: 100%; height: 100%; display: flex;justify-content: center; align-items: center;">
+						<image style="width: 50rpx; height: 50rpx; transform: scale(-1,1);" :src="bControlRun?'/static/modal/boxing-hit/hit-pause.png':'/static/modal/boxing-hit/hit-play.png'"></image>
+					</view>
+				</view>
+			</view>
+			<!-- <view v-if="mode == 'pkMode'" style="height: 160rpx;"></view> -->
+			<!-- <view style="margin-top: 40rpx;width: 310rpx; height: 90rpx;"></view> -->
+			<!-- 模式按钮  @tap="onChangeMode"-->
+			<!-- <view class="flex justify-center " style="margin-top: 40rpx;">
+				<view style="position: relative; width: 310rpx; height: 90rpx;background-color: #FFFFFF; display: flex;flex-direction: row;justify-content: center;align-items: center; border-radius: 50rpx;">
+					<image style="width: 45rpx; height: 45rpx;" src="/static/personal/switch.png"></image>
+					<view style="margin-left: 20rpx;color:#9797FF; font-weight: bold;font-size: 17px;">{{mode=="pkMode"?'健身模式':'PK模式'}}
+					</view>
+				</view>
+			</view> -->
+			<!-- <view v-if="mode == 'pkMode'" style="height: 20rpx;"></view> -->
+			<view v-if="mode == 'pkMode'" style="height: 170rpx;"></view>
+			<!-- <view v-else style="height: 110rpx;"></view> -->
+			<view v-else style="height: 80rpx;"></view>
+
+			<view v-if="mode == 'pkMode'" class="hit-vertical-container" :style="{'top': mode == 'pkMode'?'-120rpx':'-300rpx'}">
+				<view class="hit-vertical-bar">
+					<view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
+						<view :class="25-aiShowCount>=index+1? 'hit-vertical-active':'hit-vertical-inactive'"></view>
+						<view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{index+1}}</view>
+					</view>
+				</view>
+				<view class="hit-vertical-bar">
+					<view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
+						<view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{index+1}}</view>
+						<view :class="25-myShowCount>=index+1? 'hit-vertical-active':'hit-vertical-inactive'"></view>
+					</view>
+				</view>
+			</view>
+			<view v-else class="hit-vertical-container" :style="{'top': mode == 'pkMode'?'-120rpx':'-300rpx'}">
+				<view class="hit-vertical-bar">
+					<view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
+						<view :class="showCount>=index+1? 'hit-vertical-active':'hit-vertical-inactive'"></view>
+						<view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{(index+1)*2}}</view>
+					</view>
+				</view>
+				<view class="hit-vertical-bar">
+					<view class="hit-vertical-child" v-for="(item, index) in 25" :key="index">
+						<view :class="index%5 == 0?'':'hit-text-hidden'" class="hit-vertical-text">{{(index+26)*2}}</view>
+						<view :class="showCount>=index+26? 'hit-vertical-active':'hit-vertical-inactive'"></view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<!-- <button style="margin-top: 100rpx;" @tap="onTestHit('left')">击中</button> -->
+
+		<!-- 显示数据 -->
+		<view v-if="mode == 'pkMode'" class="flex justify-around " style="margin: 0rpx 15rpx;">
+			<view class="boxing-item-bg">
+				<image src="/static/modal/boxing-hit/f.png" class="boxing-hit-png " mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">最大力量</view>
+				<view class="hit-count">
+					{{mode == 'pkMode'?PKMaxStrength:maxStrength}}
+				</view>
+			</view>
+			<view class="boxing-item-bg">
+				<image src="/static/modal/boxing-hit/b.png" class="boxing-hit-png " mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">平均力量</view>
+				<view class="hit-count">
+					{{mode == 'pkMode'?PKAverageStrength:averageStrength}}
+				</view>
+			</view>
+			<view class="boxing-item-bg">
+				<image src="/static/modal/boxing-hit/e.png" class="boxing-hit-png " mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">平均速度</view>
+				<view class="hit-count">
+					{{mode == 'pkMode'?PKAverageSpeed:averageSpeed}}
+				</view>
+			</view>
+			<view class="boxing-item-bg">
+				<image src="/static/modal/boxing-hit/n.png" class="boxing-hit-png " mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">击打数</view>
+				<view class="hit-count">
+					{{mode == 'pkMode'?PKAllShowHitCount:allShowHitCount}}
+				</view>
+			</view>
+		</view>
+		<view v-else class="flex margin-bottom-sm justify-center align-center">
+			<view class="flex align-center">
+				<view class="flex justify-start flex-direction align-center">
+					<image src="/static/mileageIcon-w.png" class="data-png-26 margin-sm" mode="aspectFit"></image>
+					<text style="text-align: start; line-height: 24px; font-weight: 400;color: #FFFFFF;">{{mode == 'calorieMode'?'里程':'计数'}}</text>
+				</view>
+				<view class="flex justify-start flex-direction">
+					<view style="height: 26px;" class="margin-top-sm margin-bottom-sm">
+						<view class="cu-progress" style="height: 6rpx; width: 140rpx; border-radius: 45rpx;"></view>
+					</view>
+					<text style="text-align: start; line-height: 24px; font-weight: 400;color: #FFFFFF;">{{mode == 'calorieMode'?runMileage+'km':ropeJumpCount}}</text>
+				</view>
+			</view>
+			<view style="width: 40rpx;"></view>
+			<view class="flex align-center">
+				<view class="flex justify-start flex-direction align-center">
+					<image src="/static/icon-run-normal.png" class="data-png-26 margin-sm" mode="aspectFit"></image>
+					<text style="text-align: start; line-height: 24px; font-weight: 400; color: #FFFFFF;">速度</text>
+				</view>
+				<view class="flex justify-start flex-direction">
+					<view style="height: 26px;" class="margin-top-sm margin-bottom-sm">
+						<view class="cu-progress" style="height: 6rpx; width: 140rpx; border-radius: 45rpx;"></view>
+					</view>
+					<text style="text-align: start; line-height: 24px; font-weight: 400;color: #FFFFFF;">{{runSpeed}}m/s</text>
+				</view>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	import boxingCountDown from '@/components/uni-count-down/uni-count-down.vue'
+
+	import hitCharts from '@/components/u-charts/u-charts.js';
+
+	import puchConfig from "@/util/util-js/puchConfig.js"
+
+	import EquipmentAction from "@/util/util-js/EquipmentAction.js"
+
+
+	export default {
+		components: {
+			boxingCountDown
+		},
+		props: {
+			bUpdate: {
+				type: Boolean,
+				default: false
+			},
+			showTime: {
+				type: Number,
+				default: 0
+			},
+			//默认是防回弹更新
+			bRebound: {
+				type: Boolean,
+				default: true,
+			}
+		},
+		data() {
+			return {
+				mode: 'calorieMode', //pkMode calorieMode
+				//满格的数值是 25
+				maxShowCount: 25,
+				//pk模式下,两边涨的区分,自己和ai
+				myShowCount: 0,
+				myPowerCount: 0,
+				aiShowCount: 0,
+				aiPowerCount: 0,
+
+				//显示的点
+				showCount: 0,
+				//记录打击的次数
+				powerCount: 0,
+				//当前打击的最大值
+				powerMaxCount: 0,
+
+				xA1: 0,
+				yA1: 0,
+				zA1: 0,
+
+				xA: 0,
+				yA: 0,
+				zA: 0,
+				xO: 0,
+				yO: 0,
+				zO: 0,
+
+				mass: 5,
+
+				//大概消耗的卡路里
+				calorie: 0,
+				//与加速度相关的卡路里
+				otherCalorie: 0,
+
+				//大概消耗的卡路里
+				PKCalorie: 0,
+				//与加速度相关的卡路里
+				PKOtherCalorie: 0,
+
+				leftHookUrl: "/static/modal/boxing-post/left-hook.mp3",
+				rightHookUrl: "/static/modal/boxing-post/right-hook.mp3",
+				straightHookUrl: "/static/modal/boxing-post/straight-hook.mp3",
+				hookAudioContext: null,
+				//新手语音提示
+				leftTipUrl: "/static/modal/boxing-post/tipLeft.mp3",
+				rightTipUrl: "/static/modal/boxing-post/tipRight.mp3",
+				straightTipUrl: "/static/modal/boxing-post/tipStraight.mp3",
+				greatTipUrl: "/static/modal/boxing-post/tipGreat.mp3",
+				giveGoTipUrl: "/static/modal/boxing-post/tipGiveItAGo.mp3",
+				startTraining: "/static/modal/boxing-post/tipStartTraining.mp3",
+				//击打状态音效
+				hitUrl: "/static/elect/hit.mp3",
+				missUrl: "/static/elect/miss.mp3",
+
+
+				//是否在播放
+				bPlay: false,
+				//新手
+				bGuide: false,
+				//是否是特殊拳击
+				bGuideEF: false,
+
+				//运动时间
+				showSportTime: this.showTime,
+				sportTimeInterval: null,
+
+				//拳击数据判断对象
+				EquipmentActionObj: null,
+
+				wave_array: [{
+						wPlay: false
+					},
+					{
+						wPlay: false
+					},
+					{
+						wPlay: false
+					},
+					{
+						wPlay: false
+					},
+				],
+				wave_run_array: [],
+
+				wave_time: [{
+						run: 0.5,
+						delay: 3,
+						height: 20
+					},
+					{
+						run: 1,
+						delay: 3,
+						height: 30
+					},
+					{
+						run: 2,
+						delay: 3,
+						height: 80
+					},
+					{
+						run: 0.5,
+						delay: 2,
+						height: 50
+					},
+					{
+						run: 1,
+						delay: 2,
+						height: 35
+					},
+					{
+						run: 2,
+						delay: 2,
+						height: 20
+					}
+				],
+
+				wave_d_play: false,
+				wave_d_timeout: null,
+
+				wave_run_ratio: 0.4,
+
+				wave_d_time: [{
+						run: 1,
+						delay: 1.1,
+						height: 20,
+						sHeight: 20,
+						play: false
+					},
+					{
+						run: 1,
+						delay: 1,
+						height: 30,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1,
+						delay: 0.9,
+						height: 15,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1,
+						delay: 0.8,
+						height: 50,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.3,
+						delay: 0.7,
+						height: 35,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.4,
+						delay: 0.6,
+						height: 20,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.5,
+						delay: 0.5,
+						height: 25,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.6,
+						delay: 0.4,
+						height: 40,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.7,
+						delay: 0.3,
+						height: 60,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.8,
+						delay: 0.2,
+						height: 50,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.9,
+						delay: 0.1,
+						height: 80,
+						sHeight: 20,
+						play: true
+					},
+					{
+						run: 1.8,
+						delay: 0,
+						height: 70,
+						sHeight: 20,
+						play: true
+					}
+				],
+
+				bControlRun: false,
+				bRingAnimation: false,
+
+				maxStrength: 0,
+				averageStrength: 0,
+				allStrength: 0,
+				averageSpeed: 0,
+				averageSpeedInterval: null,
+				tempHitCount: 0,
+				allTempHitCount: 0,
+				allShowHitCount: 0,
+
+				currentHitStrength: 0,
+				
+				// testHitInterval: null,
+				aiHitInterval: null,
+				//击打时候动画对象
+				hitStrengthOpacityInterval: null,
+				hitStrengthOpacity: 0,
+
+				//pk 模式下的数据
+				PKMaxStrength: 0,
+				PKAverageStrength: 0,
+				PKAllStrength: 0,
+				PKAverageSpeed: 0,
+				PKAverageSpeedInterval: null,
+				PKTempHitCount: 0,
+				PKAllTempHitCount: 0,
+				PKAllShowHitCount: 0,
+
+				BLENum: 0,
+				BLEACX: 0,
+				BLEACYL: 0,
+				
+				/** 跑步参数*/
+				runMileage:0,
+				runSpeed:0,
+				runTempCount:0,
+				runAllTempCount:0,
+				runAllCount:0,
+				
+				/**
+				 * 跳绳参数
+				 */
+				ropeJumpCount:0
+
+			}
+		},
+		watch: {
+			bUpdate(val) {
+
+			},
+			showTime(val) {
+				this.showSportTime = val;
+			}
+		},
+		created() {
+			let _self = this;
+
+			_self.hookAudioContext = uni.createInnerAudioContext();
+			_self.hookAudioContext.autoplay = false;
+			_self.hookAudioContext.src = _self.straightHookUrl;
+			_self.hookAudioContext.volume = 0.5;
+
+			console.log(" ***** boxing-post created ******");
+			_self.onBindAcc();
+
+			_self.EquipmentActionObj = new EquipmentAction();
+			_self.EquipmentActionObj.addEventListener("resultantHit", (e) => {
+
+				// console.log("acc:",this.xA,this.yA,this.zA);
+				// console.log("data:", this.xA1, this.yA1, this.zA1);
+
+				if (this.mode == "pkMode") {
+					this._pkHitOnly(e.acc, e.power);
+				} else {
+					this._HitOnly(e.acc, e.power);
+				}
+			})
+
+			if (this.averageSpeedInterval) {
+				clearInterval(this.averageSpeedInterval);
+				this.averageSpeedInterval = null;
+			}
+
+			//计算平均速度
+			this.averageSpeedInterval = setInterval(() => {
+				if (this.mode == 'PKMode') {
+					this.PKAverageSpeed = this.PKTempHitCount;
+					this.PKTempHitCount = 0;
+				} else {
+					this.averageSpeed = this.tempHitCount;
+					this.tempHitCount = 0;
+					
+					//跑步速度 70cm步长 速度:步长*步数/5秒
+					this.runSpeed = this.runTempCount * 70 / 100;
+					this.runTempCount = 0;
+				}
+
+			}, 5000)
+
+		},
+		beforeDestroy() {
+			console.log(" ***** boxing-post destroyed ******");
+			this.onUnbindAcc();
+			// this.onUnbindOri();
+
+			let _self = this;
+
+
+
+			if (_self.hookAudioContext)
+				_self.hookAudioContext.destroy();
+
+			if (_self.sportTimeInterval) {
+				clearInterval(_self.sportTimeInterval);
+				_self.sportTimeInterval = null;
+			}
+
+
+
+			if (_self.averageSpeedInterval) {
+				clearInterval(_self.averageSpeedInterval);
+				_self.averageSpeedInterval = null;
+			}
+
+
+			// if (_self.testHitInterval) {
+			// 	clearInterval(_self.testHitInterval);
+			// 	_self.testHitInterval = null;
+			// }
+
+			if (this.aiHitInterval) {
+				clearInterval(this.aiHitInterval);
+				this.aiHitInterval = null;
+			}
+		},
+		methods: {
+
+			onSetRingAnimation(booleanValue) {
+				this.bRingAnimation = booleanValue;
+			},
+			moveBoxingHandle() {
+				return;
+			},
+			//测试打击
+			onTestHit(data) {
+				let _self = this;
+				let maxPower = Math.floor(Math.random() * 13);
+				// console.log("maxPower:", maxPower);
+
+				if (this.mode == "pkMode") {
+					this._pkHitOnly(maxPower, maxPower * 10);
+				} else {
+					for(let i=0;i<100;i++){
+						this._HitOnly(maxPower, maxPower * 10);
+					}
+				}
+			},
+			//平时击打的力量槽动画播放
+			onPlayPowerAnimation(bGreat) {
+				// 暂时去掉 跑步声音
+				// if (bGreat) {
+				// 	this.hookAudioContext.stop();
+				// 	this.hookAudioContext.src = this.greatTipUrl;
+				// 	this.hookAudioContext.play();
+				// } else {
+				// 	this.hookAudioContext.stop();
+				// 	this.hookAudioContext.src = this.hitUrl;
+				// 	this.hookAudioContext.play();
+				// }
+				let _self = this;
+
+				if (_self.powerInterval) {
+					clearInterval(_self.powerInterval);
+					_self.powerInterval = null;
+				}
+
+				let bAdd = true;
+				let _oldPowerCount = _self.powerCount;
+				let _currentMaxCount = _oldPowerCount + 10;
+				let _duraciotn = 300 / _currentMaxCount;
+
+				_self.powerInterval = setInterval(function() {
+
+					if (_self.showCount >= _currentMaxCount) {
+						bAdd = false;
+					} else if (_self.showCount <= _oldPowerCount && !bAdd) {
+						_self.showCount = _self.powerCount;
+						clearInterval(_self.powerInterval);
+						_self.powerInterval = null;
+						return;
+					}
+
+					if (bAdd)
+						_self.showCount++;
+					else
+						_self.showCount--;
+
+				}, _duraciotn); //300ms/40格
+			},
+			//pk模式击打的力量槽动画播放
+			onPKModePlayPowerAnimation(bGreat) {
+				if (bGreat) {
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.greatTipUrl;
+					this.hookAudioContext.play();
+				} else {
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.hitUrl;
+					this.hookAudioContext.play();
+				}
+
+
+
+				let _self = this;
+				_self.myShowCount = _self.myPowerCount;
+				// if (_self.powerInterval) {
+				// 	clearInterval(_self.powerInterval);
+				// 	_self.powerInterval = null;
+				// }
+
+				// let bAdd = true;
+				// let _oldPowerCount = _self.myPowerCount;
+				// let _currentMaxCount = _oldPowerCount + 10;
+				// let _duraciotn = 300 / _currentMaxCount;
+
+				// _self.powerInterval = setInterval(function() {
+
+				// 	if (_self.myShowCount >= _currentMaxCount) {
+				// 		bAdd = false;
+				// 	} else if (_self.myShowCount <= _oldPowerCount && !bAdd) {
+				// 		_self.myShowCount = _self.myPowerCount;
+				// 		clearInterval(_self.powerInterval);
+				// 		_self.powerInterval = null;
+				// 		return;
+				// 	}
+
+				// 	if (bAdd)
+				// 		_self.myShowCount++;
+				// 	else
+				// 		_self.myShowCount--;
+
+				// }, _duraciotn); //300ms/40格
+			},
+			onBindAcc(globalAcc) {
+				uni.$on('watchAcceleration', this.updateAcc);
+			},
+			onUnbindAcc() {
+				uni.$off('watchAcceleration', this.updateAcc);
+			},
+			onBindOri(globalOri) {
+				uni.$on('watchOrientation', this.updateOri);
+			},
+			onUnbindOri() {
+				uni.$off('watchOrientation', this.updateOri);
+			},
+			updateAcc(acc) {
+
+				// console.log("acc:" ,acc.xAxis,acc.yAxis,acc.zAxis);
+
+
+				this.xA = acc.xAxis;
+				this.yA = acc.yAxis;
+				this.zA = acc.zAxis;
+
+				// return;
+				if (!this.bUpdate || !this.bPlay) return;
+
+				this.EquipmentActionObj.updateAcc({
+					xA: acc.xAxis,
+					zA: acc.yAxis,
+					yA: acc.zAxis,
+					bLimitRebound: this.bRebound
+				})
+
+
+			},
+			//旧的蓝牙模块更新数据
+			onBLEUpdate(data) {
+
+				if (!this.bPlay) return;
+
+				if (data.num)
+					this.BLENum = data.num;
+
+				if (data.acx)
+					this.BLEACX = data.acx;
+
+				if (data.acy) {
+					this.BLEACYL = data.acy;
+
+					// let acc = Math.ceil((Math.abs(this.BLEACX) + Math.abs(this.BLEACYL))*0.0005);
+					let _abs = (Math.abs(this.BLEACX) + Math.abs(this.BLEACYL));
+					let _ratioAbs = _abs > 65000 ? 1 : _abs / 65000;
+					// console.log("当前值:",(Math.abs(this.BLEACX) + Math.abs(this.BLEACYL)),acc,this._onReducedBlood(acc),_ratioAbs,Math.ceil(_ratioAbs*30));
+					let acc = Math.ceil(_ratioAbs * 30);
+					if (this.mode == "pkMode") {
+						this._pkHitOnly(acc, acc * 10);
+					} else {
+						this._HitOnly(acc, acc * 10);
+					}
+				}
+
+
+
+			},
+			
+			//hotman 情景下刷新
+			onBLEHotmanUpdate(data) {
+				console.log("onBLEHotmanUpdate:",data ,this.bUpdate,this.bPlay);
+				if (!this.bUpdate || !this.bPlay) return;
+
+				let {
+					hit
+				} = data;
+				let power = parseInt(hit);
+				let acc = power * 0.1;
+
+				if (this.mode == "pkMode") {
+					this._pkHitOnly(acc, power);
+				} else {
+					this._HitOnly(acc, power);
+				}
+			},
+			//蓝牙更新数据
+			onBLEHandleUpdate(data) {
+
+				if (!this.bUpdate || !this.bPlay) return;
+
+				let {
+					ax,
+					ay,
+					az
+				} = data.acc;
+
+				let xA = ax * 9.80665;
+				let yA = ay * 9.80665;
+				let zA = az * 9.80665;
+
+				this.xA1 = xA;
+				this.yA1 = yA;
+				this.zA1 = zA;
+				// console.log("data:" ,xA,yA,zA);
+				// updateAcc updateTriaxialAcc
+				this.EquipmentActionObj.updateTriaxialAcc({
+					xA: xA,
+					zA: yA,
+					yA: zA,
+					bLimitRebound: true
+				})
+			},
+			//rope 情景下刷新
+			onBLERopeUpdate(data) {
+				if (!this.bUpdate || !this.bPlay) return;
+			
+				let {
+					jump
+				} = data;
+				let power = parseInt(jump);
+				let acc = power * 0.1;
+				
+				console.log(jump,this.mode,acc,power);
+				if (this.mode == "pkMode") {
+					this._pkHitOnly(acc, power);
+				} else {
+					this._HitOnly(acc, power);
+				}
+			},
+
+			updateOri(ori) {
+				this.xO = ori.beta;
+				this.zO = ori.alpha;
+				this.yO = ori.gamma;
+			},
+			onControlPlay() {
+				this._customControlPlay({
+					bControlRun: this.bControlRun
+				});
+			},
+			onCloseDevices() {
+				let _self = this;
+
+				if (!_self.bPlay) return;
+
+				if (_self.sportTimeInterval) {
+					clearInterval(_self.sportTimeInterval);
+					_self.sportTimeInterval = null;
+				}
+				if (_self.aiHitInterval) {
+					clearInterval(_self.aiHitInterval);
+					_self.aiHitInterval = null;
+				}
+				_self.bPlay = false;
+				_self.bControlRun = false;
+
+				//如果是新手教程,也直接停掉
+				_self.bGuide = false;
+				_self.bGuideEF = false;
+
+				if (_self.mode == "pkMode") {
+					_self.myShowCount = 0;
+					_self.myPowerCount = 0;
+					_self.aiShowCount = 0;
+					_self.aiPowerCount = 0;
+				}
+
+				_self.$emit("closeBoxingControl");
+			},
+			onHitPlay(bPlaying) {
+				if (bPlaying) {
+					this.bControlRun = bPlaying;
+				} else {
+					this.bControlRun = !this.bControlRun;
+				}
+			},
+			_customControlPlay(data) {
+				let _self = this;
+				//1.检查是否符合要求,再进行训练
+				if (data.bControlRun) {
+
+					if (_self.sportTimeInterval) {
+						clearInterval(_self.sportTimeInterval);
+						_self.sportTimeInterval = null;
+					}
+
+					this.bPlay = false;
+					// this.$refs.customControlButtons.onPlay();
+					this.onHitPlay();
+
+					//如果是新手教程,也直接停掉
+					this.bGuide = false;
+					this.bGuideEF = false;
+
+
+					// if (this.testHitInterval) {
+					// 	clearInterval(this.testHitInterval);
+					// 	this.testHitInterval = null;
+					// }
+
+					if (this.mode == "pkMode") {
+						this.myShowCount = 0;
+						this.myPowerCount = 0;
+						this.aiShowCount = 0;
+						this.aiPowerCount = 0;
+					}
+
+
+					if (this.aiHitInterval) {
+						clearInterval(this.aiHitInterval);
+						this.aiHitInterval = null;
+					}
+
+					this.$emit("boxingPostControlPlay", false);
+				} else {
+					this.$emit("boxingPostCheck");
+				}
+
+			},
+
+			_PKOver(data) {
+				let _self = this;
+				//1.检查是否符合要求,再进行训练
+				if (_self.sportTimeInterval) {
+					clearInterval(_self.sportTimeInterval);
+					_self.sportTimeInterval = null;
+				}
+				this.bPlay = false;
+				this.onHitPlay();
+
+				//如果是新手教程,也直接停掉
+				this.bGuide = false;
+				this.bGuideEF = false;
+
+				if (this.aiHitInterval) {
+					clearInterval(this.aiHitInterval);
+					this.aiHitInterval = null;
+				}
+			},
+			//新手引导
+			onGuideBoxingPostPlay() {
+				console.log("onGuideBoxingPostPlay");
+				let _self = this;
+				_self.bPlay = true;
+				//
+				_self.bGuide = true;
+				// 按钮事件
+				// _self.$refs.customControlButtons.onPlay();
+				_self.onHitPlay();
+
+			},
+			//训练退出时候,重新信息
+			onBoxingPostStop() {
+
+
+			},
+
+			//调用播放
+			onBoxingPostPlay(bPlaying) {
+				let _self = this;
+
+				//判断是否是pk模式,如果是pk模式,则用pk模式播放
+
+				if (bPlaying) {
+					_self.bPlay = true;
+					// 按钮事件
+					// _self.$refs.customControlButtons.onPlay(true);
+					_self.onHitPlay(true);
+
+					// if (_self.testHitInterval) {
+					// 	clearInterval(_self.testHitInterval);
+					// 	_self.testHitInterval = null;
+					// }
+					// _self.testHitInterval = setInterval(() => {
+					// 	this.onTestHit();
+					// }, 300)
+
+					if (_self.sportTimeInterval) {
+						clearInterval(_self.sportTimeInterval);
+						_self.sportTimeInterval = null;
+					}
+
+					if (this.mode == 'pkMode') {
+						if (this.aiHitInterval) {
+							clearInterval(this.aiHitInterval);
+							this.aiHitInterval = null;
+						}
+						this.aiHitInterval = setInterval(() => {
+							let _random = Math.floor(Math.random() * 10);
+							if (_random < 5) {
+								this.onAiHitEvent();
+							}
+						}, 500)
+					}
+
+					//play true 时候,开启时间计算
+					_self.sportTimeInterval = setInterval(() => {
+						_self.showSportTime++;
+						if (_self.showSportTime >= 20 && _self.showSportTime % 20 == 0) {
+							_self.$emit("updateSportTime", _self.showSportTime);
+						}
+					}, 1000)
+				}
+			},
+			//自由模式下的打击
+			//首页现在尝试用于跑步
+			_HitOnly(acc, power) {
+
+				//动画的高度
+				let _ratio = acc / 10;
+				if (_ratio > 1) _ratio = 1;
+				if (_ratio < 0.5) _ratio = 0.5;
+
+				for (let i = 0; i < this.wave_d_time.length; i++) {
+					this.wave_d_time[i].sHeight = this.wave_d_time[i].height * _ratio;
+				}
+
+				this.onPlayPowerAnimation();
+
+				// this.allTempHitCount++;
+				this.runAllTempCount++;
+				this.allShowHitCount++;
+				this.tempHitCount++;
+				
+				this.runTempCount ++;
+				
+				this.runAllCount = this.allShowHitCount;
+				
+				if(this.mode == 'calorieMode'){
+					//里面转换千米
+					//175公分的bai成人一般两步间距du为70厘米,zhi170公分为65厘米,180公分为75厘米。
+					this.runMileage =  this.runAllCount*70 / 100000;
+				}else {
+					this.ropeJumpCount = this.runAllCount;
+				}
+				
+
+				this.currentHitStrength = power;
+				if (this.maxStrength < power) {
+					this.maxStrength = power;
+				}
+				this.allStrength += power;
+				
+				this.averageStrength = (this.allStrength / this.allShowHitCount).toFixed(1);
+
+				//跑步的卡路里,allTempHiCount
+				this.calorie = puchConfig.getRunCalorie(this.runAllTempCount);
+				//击打的加速度添加的卡路里,是额外计算的卡路里
+				// this.otherCalorie += puchConfig.getAccCalorie(acc);
+				let _all = this.calorie;// this.calorie.add(this.otherCalorie);
+
+				//100 大卡,为一个周期 分50份
+				//现在显示1格子是2大卡,所以 _all要 除去一半
+				this.powerCount = parseInt(_all / 2);
+
+				if (this.powerCount >= 50) {
+					console.log("同步卡路里");
+					console.log("this.calorie:", this.calorie, this.otherCalorie, _all);
+					this.$emit('updateCalorie', _all);
+					// this.allTempHitCount = 0;
+					this.runAllTempCount = 0;
+					this.powerCount = 0;
+					// this.otherCalorie = 0;
+				}
+
+				if (!this.wave_d_play) {
+					if (this.wave_d_timeout) {
+						clearTimeout(this.wave_d_timeout);
+						this.wave_d_timeout = null;
+					}
+
+					this.wave_d_play = true;
+					this.wave_d_timeout = setTimeout(() => {
+						this.wave_d_play = false;
+					}, 1000 * this.wave_run_ratio)
+				}
+
+				if (this.hitStrengthOpacityInterval) {
+					clearTimeout(this.hitStrengthOpacityInterval);
+					this.hitStrengthOpacityInterval = null;
+				}
+				this.hitStrengthOpacity = 1;
+				this.hitStrengthOpacityInterval = setTimeout(() => {
+					this.hitStrengthOpacity = 0;
+				}, 1000)
+			},
+
+			//pk模式下的打击
+			_pkHitOnly(acc, power) {
+
+				this.onPKModePlayPowerAnimation();
+
+				this.PKAllTempHitCount++;
+				this.PKAllShowHitCount++;
+				this.PKTempHitCount++;
+
+				this.currentHitStrength = power;
+				if (this.PKMaxStrength < power) {
+					this.PKMaxStrength = power;
+				}
+				this.PKAllStrength += power;
+
+				this.PKAverageStrength = (this.PKAllStrength / this.PKAllShowHitCount).toFixed(1);
+
+				//击打次数一个卡路里,就是基础卡路里
+				this.PKCalorie = puchConfig.getBoxingCalorie(this.PKAllTempHitCount);
+				//击打的加速度添加的卡路里,是额外计算的卡路里
+				// this.PKOtherCalorie += puchConfig.getAccCalorie(acc);
+				// console.log( puchConfig.getAccCalorie(acc),this.calorie);
+				let _all = this.PKCalorie; // this.PKCalorie.add(this.PKOtherCalorie);
+
+				//10 大卡,为一个周期 分25份
+				// this.myPowerCount = parseInt(_all * 2.5 * 20);
+
+				//中一个小拳头扣一滴血,中一个中拳头去2滴血,中一个大拳头去3滴血。
+				let _myBloodPoint = this._onReducedBlood(acc);
+				this.myPowerCount += _myBloodPoint;
+
+				//用户打击完成
+				if (this.myPowerCount >= this.maxShowCount) {
+					console.log("this.calorie:", this.PKCalorie, this.PKOtherCalorie, _all);
+					this.$emit('updateCalorie', _all);
+					this.PKAllTempHitCount = 0;
+					this.myPowerCount = 0;
+					this.myShowCount = 0;
+					this.PKOtherCalorie = 0;
+					//通知结果
+
+					this.$emit('gameOver', {
+						myWin: true
+					});
+					this._PKOver();
+
+					this.aiPowerCount = 0;
+					this.aiShowCount = 0;
+				}
+
+				this.$emit('hitEvent', _myBloodPoint);
+			},
+
+			onAiHitEvent() {
+				let _acc = Math.ceil(Math.random() * 30);
+				let _aiBloodPoint = this._onReducedBlood(_acc);
+				this.aiPowerCount += _aiBloodPoint;
+				// this.aiPowerCount += 20;
+
+				this.$emit('aiHitEvent', _aiBloodPoint);
+				this.aiShowCount = this.aiPowerCount; // parseInt(this.aiPowerCount / 10);
+
+				if (this.aiShowCount >= this.maxShowCount) {
+					this.$emit('gameOver', {
+						myWin: false
+					});
+					this._PKOver();
+					this.aiPowerCount = 0;
+					this.aiShowCount = 0;
+					this.myPowerCount = 0;
+					this.myShowCount = 0;
+				}
+			},
+			//根据加速度计算血量
+			_onReducedBlood(acc) {
+				let _ratio = acc > 30 ? 1 : acc / 30;
+				// console.log("_ratio:", _ratio);
+				if (_ratio > 0.9) {
+					//大拳头
+					return 3;
+				} else if (_ratio > 0.7) {
+					//中拳头
+					return 2;
+				} else {
+					//小拳头
+					return 1;
+				}
+			},
+			onChangeMode() {
+				//todo 切换模式时候,停止当前运行状态
+				if (this.bControlRun) {
+					uni.showToast({
+						title: '先停止,再切换模式',
+						mask: true,
+						icon: 'none',
+						duration: 2000,
+					})
+
+					return;
+				}
+				//当前的拳击力设置为0
+				this.currentHitStrength = 0;
+
+				let _name = 'pk模式';
+				if (this.mode == 'pkMode') {
+					this.mode = 'calorieMode';
+					_name = '长跑模式'; //健身模式
+				} else if (this.mode == 'calorieMode') {
+					this.mode = 'pkMode';
+					_name = 'pk模式';
+				}
+				let _data = {
+					mode: this.mode,
+					name: _name
+
+				}
+				this.$emit('modeEvent', _data);
+			},
+			//设置一个切换模式
+			onSetMode(modeValue) {
+				console.log("modeValue =====", modeValue);
+				//todo 切换模式时候,停止当前运行状态
+				if (this.bControlRun) {
+					uni.showToast({
+						title: '先停止,再切换模式',
+						mask: true,
+						icon: 'none',
+						duration: 2000,
+					})
+
+					return;
+				}
+				//当前的拳击力设置为0
+				this.currentHitStrength = 0;
+
+				let _name = 'pk模式';
+				if (modeValue == 'calorieMode') {
+					this.mode = 'calorieMode';
+					_name = '长跑模式';
+				} else if (modeValue == 'pkMode') {
+					this.mode = 'pkMode';
+					_name = 'pk模式';
+				} else if(modeValue == 'ropeMode'){
+					this.mode = 'ropeMode';
+					_name = '跳绳模式'
+				}
+				let _data = {
+					mode: this.mode,
+					name: _name
+
+				}
+				this.$emit('modeEvent', _data);
+			}
+
+		}
+	}
+</script>
+
+<style>
+	/* Loader Bar */
+	.hit-vertical-container {
+		position: absolute;
+		top: -50rpx;
+		left: 0;
+		right: 0;
+		display: flex;
+		justify-content: space-between;
+		/* border: 1rpx solid #000000; */
+		pointer-events: none;
+	}
+
+	.hit-vertical-bar {
+		display: flex;
+		flex-direction: column-reverse;
+	}
+
+	.hit-vertical-child {
+		/* position: relative; */
+		width: 70rpx;
+		height: 20rpx;
+		margin: 14rpx 24rpx 0 24rpx;
+		display: flex;
+		/* align-content: center; */
+		justify-content: space-between;
+
+
+	}
+
+	.hit-vertical-text {
+		color: #FFFFFF;
+		font-size: 8px;
+	}
+
+	.hit-text-hidden {
+		visibility: hidden;
+	}
+
+	.hit-vertical-active {
+		background-color: #FFFFFF;
+		width: 30rpx;
+		height: 100%;
+	}
+
+	.hit-vertical-inactive {
+		width: 30rpx;
+		height: 100%;
+		background: rgba(144, 141, 246, 1);
+	}
+
+	.boxing-item-bg {
+		border-radius: 15rpx;
+		background-color: rgba(255, 255, 255, 0.1);
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		/* width: 160rpx; */
+	}
+
+	.hit-count {
+		width: 160rpx;
+		height: 60rpx;
+		font-size: 22px;
+		font-weight: bold;
+		color: #FFFFFF;
+		line-height: 60rpx;
+	}
+
+	.hit-current-count-power {
+		/* margin: 0 5rpx; */
+		font-size: 19px;
+		line-height: 60rpx;
+
+		/* font-weight: bold; */
+		color: #FFFFFF;
+	}
+
+	.hit-current-count {
+		/* width: 160rpx; */
+		/* height: 100rpx; */
+		margin: 0 30rpx;
+		font-size: 22px;
+		line-height: 60rpx;
+		font-weight: bold;
+		color: #FFFFFF;
+		/* line-height: 22px; */
+	}
+
+	#loadbar {
+		list-style: none;
+		width: 400rpx;
+		margin: 0 20rpx;
+	}
+
+	#loadbar-child {
+		float: left;
+		position: relative;
+		width: 60rpx;
+		height: 10rpx;
+		margin-left: 1px;
+		background: rgba(255, 255, 255, 0.5);
+	}
+
+	#loadbar-child:first-child {
+		margin-left: 0;
+	}
+
+	.bar {
+		background-color: #FFFFFF;
+		width: 60rpx;
+		height: 10rpx;
+	}
+
+
+	.show-png {
+		width: 78rpx;
+		height: 78rpx;
+		margin: 0 10px;
+	}
+
+	.boxing-hit-png {
+		margin-top: 40rpx;
+		width: 50rpx;
+		height: 50rpx;
+		transition: transform 0.15s;
+	}
+
+	.boxing-change {
+		transform: scale(1.58);
+	}
+
+
+	.hitBoxingTimer {
+		position: absolute;
+		top: -60rpx;
+		left: 0;
+		right: 0;
+	}
+
+
+	.wave-item {
+		width: 8rpx;
+		height: 20rpx;
+		margin: 5rpx;
+		background-color: #FFFFFF;
+		border-radius: 10rpx;
+		transition: height 0.5s;
+	}
+
+	.wave-d-item {
+		width: 8rpx;
+		height: 20rpx;
+		margin: 5rpx;
+		background-color: #FFFFFF;
+		border-radius: 10rpx;
+		transition: height 0.5s;
+	}
+
+
+
+	.hit-wave {
+		animation: hit-d-scale calc(var(--time) * 0.5s) linear calc(var(--delay) * 1s) 1 alternate;
+	}
+
+	.wave-play {
+		animation-play-state: running;
+	}
+
+	.wave-pause {
+		animation-play-state: paused;
+	}
+
+	@keyframes hit-scale {
+		0% {
+			transform: scale(1, 1);
+			/* background-color: #999; */
+		}
+
+		100% {
+			transform: scale(1, 3);
+			/* background-color: #333; */
+		}
+	}
+
+
+	@keyframes hit-d-scale {
+		0% {
+			transform: scale(1, 1);
+		}
+
+		25% {
+			transform: scale(1, 3);
+		}
+
+		50% {
+			transform: scale(1, 1);
+		}
+
+		75% {
+			transform: scale(1, 3);
+		}
+
+		100% {
+			transform: scale(1, 1);
+		}
+	}
+
+
+	.hit-button-rotate {
+		animation: hit-rotate 2s steps(16, end) infinite;
+	}
+
+	.hit-button-bg-play {
+		animation-play-state: running;
+	}
+
+	.hit-button-bg-paused {
+		animation-play-state: paused;
+	}
+
+	@keyframes hit-rotate {
+		from {
+			transform: rotate(0deg);
+		}
+
+		to {
+			transform: rotate(360deg);
+		}
+	}
+
+	.big {
+		transform: scale(1.2);
+	}
+	
+
+	/* .progress-bar-container{
+		
+	} */
+</style>

+ 1295 - 0
components/modal/boxing-post/boxing-post.vue

@@ -0,0 +1,1295 @@
+<template>
+	<view style="width: 90%; margin-bottom: 50rpx;">
+
+		<!-- 计时器 -->
+		<view class="boxingTimer flex justify-center">
+			<boxingCountDown ref="boxingCountDownRef" :show-day="false" :second="showSportTime" color="#9695f7" background-color="#FFFFFF"
+			 border-color="#007AFF" splitorColor="#FFFFFF" />
+		</view>
+		<!-- 拳头特效 -->
+		<!-- <efBone v-if="bGuideEF||(doubleHitCount>0&&doubleHitCount%doubleHitLimit == 0)" ref="refEfBone" @randomIndex="_efRandomIndex"></efBone> -->
+		<!-- v-else 拳击部分 -->
+		<view class="flex justify-around " style="margin-bottom: 16rpx; height: 300rpx;">
+			<view class="flex flex-direction justify-between">
+				<image :src="bLAnimation?'/static/modal/boxing-post/left-hook-h@2x.png':'/static/modal/boxing-post/left-hook-m@2x.png'"
+				 class="boxing-png " :class="bLAnimation?' boxing-change ':''" mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 35rpx 0;">左勾拳</view>
+			</view>
+			<view class="flex flex-direction justify-between">
+				<image :src="bMAnimation?'/static/modal/boxing-post/straight-h@2x.png':'/static/modal/boxing-post/straight-m@2x.png'"
+				 class="boxing-png " :class="bMAnimation?' boxing-change ':''" mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 35rpx 0;">直拳</view>
+			</view>
+			<view class="flex flex-direction justify-between">
+				<image :src="bRAnimation?'/static/modal/boxing-post/right-hook-h@2x.png':'/static/modal/boxing-post/right-hook-m@2x.png'"
+				 class="boxing-png " :class="bRAnimation?' boxing-change ':''" mode="aspectFit"></image>
+				<view class="text-white text-13px" style="margin: 35rpx 0;">右勾拳</view>
+			</view>
+		</view>
+
+
+		<!-- 显示数据 -->
+		<view class="flex justify-around " style="margin-bottom: 16rpx;">
+			<view class="flex flex-direction justify-between">
+				<view class="boxing-count-bg">
+					{{hitCount}}
+				</view>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">击中</view>
+			</view>
+			<view class="flex flex-direction justify-between">
+				<view class="boxing-count-bg">
+					{{doubleHitCount}}
+				</view>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">连</view>
+			</view>
+			<view class="flex flex-direction justify-between">
+				<view class="boxing-count-bg">
+					{{missCount}}
+				</view>
+				<view class="text-white text-13px" style="margin: 10rpx 0;">失误</view>
+			</view>
+		</view>
+		<!-- 对话框 -->
+		<view class="flex justify-center " style="margin-bottom: 32rpx;">
+			<view class="boxing-post-talkbubble">
+				你离{{evaluateName}}还差{{evaluatePower}}公斤
+			</view>
+		</view>
+
+		<!-- 步骤条 -->
+		<!-- <customStep ref="customStepRef" @onCustomSetBasics="_customSetBasics"></customStep> -->
+		<!-- 控制按钮 -->
+		<controlButtons ref="customControlButtons" :showLeftRight='false' @onControlPlayTap="_customControlPlay"></controlButtons>
+
+		<view class="vertical-container">
+			<view class="vertical-bar">
+				<view class="vertical-child" v-for="(item, index) in 20" :key="index">
+					<view :class="powerCount>=index+1? 'vertical-active':'vertical-inactive'"></view>
+					<view :class="index%5 == 0?'':'text-hidden'" class="vertical-text">{{index+1}}</view>
+				</view>
+			</view>
+			<view class="vertical-bar">
+				<view class="vertical-child" v-for="(item, index) in 20" :key="index">
+					<view :class="index%5 == 0?'':'text-hidden'" class="vertical-text">{{index+21}}</view>
+					<view :class="powerCount>=index+21? 'vertical-active':'vertical-inactive'"></view>
+				</view>
+			</view>
+		</view>
+		<button @tap="onTestHit('left')">左</button>
+		<!-- <button @tap="onTestHit('mid')">中({{accHitCountAdd}})</button>
+		<button @tap="onTestHit('right')">右</button> -->
+
+	</view>
+</template>
+
+<script>
+	import customStep from "@/components/my-custom-step/my-custom-step.vue"
+	import controlButtons from "@/components/my-control-buttons/my-control-buttons.vue"
+	import efBone from "./ef-bone.vue"
+
+	import boxingCountDown from '@/components/uni-count-down/uni-count-down.vue'
+
+	import puchConfig from "@/util/util-js/puchConfig.js"
+
+	import EquipmentAction from "@/util/util-js/EquipmentAction.js"
+
+
+	export default {
+		components: {
+			customStep,
+			controlButtons,
+			efBone,
+			boxingCountDown
+		},
+		props: {
+			bUpdate: {
+				type: Boolean,
+				default: false
+			},
+			// 默认男性
+			bMan: {
+				type: Boolean,
+				default: true
+			},
+			showTime: {
+				type: Number,
+				default: 0
+			},
+		},
+		data() {
+			return {
+				hitCount: 0,
+				addCount: 0,
+				missCount: 0,
+				doubleHitCount: 0,
+				powerCount: 0,
+				//当前打击的最大值
+				powerMaxCount: 0,
+				//连击数的限制值
+				doubleHitLimit: 10,
+
+				bRAnimation: false,
+				bLAnimation: false,
+				bMAnimation: false,
+
+				xA: 0,
+				yA: 0,
+				zA: 0,
+				xO: 0,
+				yO: 0,
+				zO: 0,
+
+				calZVector: 0,
+				calXVector: 0,
+
+				bCanXL: false,
+				bCanXR: false,
+				bCanZ: false,
+
+				ZCount: 0,
+				LCount: 0,
+				RCount: 0,
+
+				//临时值
+				addZCount: 0,
+				addLCount: 0,
+				addRCount: 0,
+
+				mass: 5,
+
+				//大概消耗的卡路里
+				calorie: 0,
+
+				leftHookUrl: "/static/modal/boxing-post/left-hook.mp3",
+				rightHookUrl: "/static/modal/boxing-post/right-hook.mp3",
+				straightHookUrl: "/static/modal/boxing-post/straight-hook.mp3",
+				hookAudioContext: null,
+				//新手语音提示
+				leftTipUrl: "/static/modal/boxing-post/tipLeft.mp3",
+				rightTipUrl: "/static/modal/boxing-post/tipRight.mp3",
+				straightTipUrl: "/static/modal/boxing-post/tipStraight.mp3",
+				greatTipUrl: "/static/modal/boxing-post/tipGreat.mp3",
+				giveGoTipUrl: "/static/modal/boxing-post/tipGiveItAGo.mp3",
+				startTraining: "/static/modal/boxing-post/tipStartTraining.mp3",
+				//击打状态音效
+				hitUrl: "/static/elect/hit.mp3",
+				missUrl: "/static/elect/miss.mp3",
+
+
+				oldxA: 0,
+				oldzA: 0,
+				bUpdateOnce: false,
+				bDelayOnce: false,
+
+				autoBoxingTip: null,
+				//播放时间
+				autoDuration: 800,
+				//是否在播放
+				bPlay: false,
+				//新手
+				bGuide: false,
+				//是否是特殊拳击
+				bGuideEF: false,
+
+				//动画
+				powerInterval: null,
+				//特殊一击
+				powerEFTimeObj: null,
+
+				evaluateName: "平民战五渣",
+				evaluatePower: 5,
+
+				//男拳击显示的名字
+				manNameList: [
+					'平民战五渣',
+					'鹰眼侠',
+					'蝙蝠侠',
+					'金刚狼',
+					'美国队长',
+					'蜘蛛侠',
+					'钢铁侠',
+					'闪电侠',
+					'毒液',
+					'绿巨人',
+					'超人',
+					'雷神',
+					'众神之王奥丁',
+					'灭霸',
+					'天启'
+				],
+				//女拳击显示的名字
+				womanNameList: [
+					'平民战五渣',
+					'豹女',
+					'毒藤女',
+					'猫女',
+					'小丑女',
+					'黑寡妇',
+					'蜘蛛女',
+					'暴风女',
+					'美杜莎',
+					'女浩克',
+					'女武神',
+					'雅典娜',
+					'绯红女巫',
+					'惊奇队长',
+					'爱神维纳斯'
+				],
+
+				//全力一击随机对象
+				efRandomObj: null,
+				bHitEFRandomObj: false,
+
+				//运动时间
+				showSportTime: this.showTime,
+				sportTimeInterval: null,
+
+				//下一个进行播放的对象
+				endSetTimeout: null,
+
+				//X轴的变化数组值
+				xAccArray: [],
+				xMax: 0,
+				maxTimeoutId: null,
+				bMaxPause: false,
+				xMin: 0,
+				minTimeoutId: null,
+				bMinPause: false,
+				bCalculation: false,
+				calTimeout: null,
+
+				//动态变化的角度比 z/x
+				angleRatio: 1,
+
+				//当前basic
+				basic: 0,
+
+				//拳击数据判断对象
+				EquipmentActionObj: null,
+
+				accHitCountAdd: 0
+			}
+		},
+		watch: {
+			bUpdate(val) {
+
+			},
+			showTime(val) {
+				this.showSportTime = val;
+			}
+		},
+		created() {
+			let _self = this;
+
+			_self.hookAudioContext = uni.createInnerAudioContext();
+			_self.hookAudioContext.autoplay = false;
+			_self.hookAudioContext.src = _self.straightHookUrl;
+			_self.hookAudioContext.volume = 1;
+
+			console.log(" ***** boxing-post created ******");
+			_self.onBindAcc();
+			// this.onBindOri();
+
+			_self.EquipmentActionObj = new EquipmentAction();
+			// console.warn("_self.EquipmentActionObj:", _self.EquipmentActionObj);
+			_self.EquipmentActionObj.addEventListener("resultantHit", (e) => {
+				// console.warn("_self.EquipmentActionObj11.addEventListener:", e);
+				// this.accHitCountAdd = e.acc;
+				if (((this.doubleHitCount > 0 && this.doubleHitCount % this.doubleHitLimit == 0) ||
+						this.bGuide) && this.efRandomObj) {
+					this.onHit(this.efRandomObj.direction, e.acc, e.power);
+				} else {
+					if (this.bLAnimation)
+						this.onHit("xRCount", e.acc, e.power);
+					else if (this.bRAnimation)
+						this.onHit("xLCount", e.acc, e.power);
+					else if (this.bMAnimation)
+						this.onHit("zLCount", e.acc, e.power);
+				}
+
+
+			})
+
+		},
+		beforeDestroy() {
+			console.log(" ***** boxing-post destroyed ******");
+			this.onUnbindAcc();
+			// this.onUnbindOri();
+
+			let _self = this;
+			if (_self.powerInterval) {
+				clearInterval(_self.powerInterval);
+				_self.powerInterval = null;
+			}
+
+			//停掉当前的随机播放
+			if (_self.autoBoxingTip) {
+				clearInterval(_self.autoBoxingTip);
+				_self.autoBoxingTip = null;
+			}
+
+			if (_self.hookAudioContext)
+				_self.hookAudioContext.destroy();
+
+			if (_self.sportTimeInterval) {
+				clearInterval(_self.sportTimeInterval);
+				_self.sportTimeInterval = null;
+			}
+
+			if (_self.endSetTimeout) {
+				clearTimeout(_self.endSetTimeout);
+				_self.endSetTimeout = null;
+			}
+		},
+		methods: {
+			moveBoxingHandle() {
+				return;
+			},
+			//测试打击
+			onTestHit(data) {
+				let _self = this;
+				let maxPower = Math.floor(Math.random() * 300);
+				console.log("maxPower:", maxPower);
+				// if (data == "left")
+				// 	this.onHit("xRCount", 0, maxPower);
+				// else if (data == "right")
+				// 	this.onHit("xLCount", 0, maxPower);
+				// else if (data == "mid")
+				// 	this.onHit("zLCount", 0, maxPower);
+				if (this.bLAnimation)
+					this.onHit("xRCount", 0, maxPower);
+				else if (this.bRAnimation)
+					this.onHit("xLCount", 0, maxPower);
+				else if (this.bMAnimation)
+					this.onHit("zLCount", 0, maxPower);
+			},
+			//平时击打的力量槽动画播放
+			onPlayPowerAnimation(bGreat) {
+				if (bGreat) {
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.greatTipUrl;
+					this.hookAudioContext.play();
+				} else {
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.hitUrl;
+					this.hookAudioContext.play();
+				}
+
+
+				let _self = this;
+
+
+				// if (_self.powerInterval) {
+				// 	clearInterval(_self.powerInterval);
+				// 	_self.powerInterval = null;
+				// }
+
+				// let bAdd = true;
+				// _self.powerCount = 0;
+				// let _duraciotn = 300 / _self.powerMaxCount;
+
+				// _self.powerInterval = setInterval(function() {
+
+				// 	// if (_self.powerCount >= _self.powerMaxCount) {
+				// 	// 	bAdd = false;
+				// 	// } else if (_self.powerCount == 0 && !bAdd) {
+				// 	// 	clearInterval(_self.powerInterval);
+				// 	// 	_self.powerInterval = null;
+				// 	// 	return;
+				// 	// }
+
+				// 	// if (bAdd)
+				// 	// 	_self.powerCount++;
+				// 	// else
+				// 	// 	_self.powerCount--;
+				// 	//递增
+				// 	if (_self.powerCount >= _self.powerMaxCount) {
+				// 		clearInterval(_self.powerInterval);
+				// 		_self.powerInterval = null;
+				// 		return;
+				// 	}
+				// 	_self.powerCount++;
+
+				// }, _duraciotn); //300ms/40格
+			},
+			//特殊一击时候力量槽
+			onPlayEFHitAnimation() {
+				let _self = this;
+
+				if (_self.powerEFTimeObj) {
+					clearTimeout(_self.powerEFTimeObj);
+					_self.powerEFTimeObj = null;
+				}
+
+				let _duraciotn = 300 / (_self.powerMaxCount - _self.powerCount);
+
+				if (_self.powerCount > _self.powerMaxCount - 2) {
+					_duraciotn = 1000;
+				} else if (_self.powerCount > _self.powerMaxCount / 2) {
+					_duraciotn *= 5;
+				}
+
+				_self.powerEFTimeObj = setTimeout(() => {
+
+					if (_self.powerCount == _self.powerMaxCount) {
+						clearTimeout(_self.powerEFTimeObj);
+						_self.powerEFTimeObj = null;
+						_self.powerCount = 0;
+						return;
+					}
+
+					_self.powerCount++;
+
+					_self.onPlayEFHitAnimation();
+
+				}, _duraciotn); //300ms/40格
+			},
+			onBindAcc(globalAcc) {
+				uni.$on('watchAcceleration', this.updateAcc);
+			},
+			onUnbindAcc() {
+				uni.$off('watchAcceleration', this.updateAcc);
+			},
+			onBindOri(globalOri) {
+				uni.$on('watchOrientation', this.updateOri);
+			},
+			onUnbindOri() {
+				uni.$off('watchOrientation', this.updateOri);
+			},
+			onResetCal() {
+				this.xAccArray = [];
+				this.xMax = 0;
+				this.xMin = 0;
+				this.bCalculation = false;
+				this.oldxA = 0;
+				this.oldzA = 0;
+				this.calTimeout = null;
+			},
+			updateAcc(acc) {
+				this.xA = acc.xAxis;
+				this.yA = acc.yAxis;
+				this.zA = acc.zAxis;
+
+				//在acc 中更新数据
+				// this.updateData();
+
+				if (!this.bUpdate || !this.bPlay) return;
+
+				this.EquipmentActionObj.updateAcc({
+					xA: acc.xAxis,
+					zA: acc.yAxis,
+					yA: acc.zAxis
+				})
+
+				// if (Math.abs(this.xA) > 8 && this.oldxA != this.xA && !this.bCalculation) {
+				// 	this.xAccArray.push(this.xA);
+				// 	this.oldxA = this.xA;
+
+				// 	if (this.calTimeout == null) {
+				// 		this.calTimeout = setTimeout(() => {
+				// 			this.bCalculation = true;
+				// 			for (let i = 0; i < this.xAccArray.length; i++) {
+				// 				if (this.xAccArray[i] < 0 && this.xAccArray[i] < this.xAccArray[this.xMin]) {
+				// 					this.xMin = i;
+				// 				} else if (this.xAccArray[i] > 0 && this.xAccArray[i] > this.xAccArray[this.xMax]) {
+				// 					this.xMax = i;
+				// 				}
+				// 			}
+				// 			console.log(this.xAccArray, "==", this.xMin, "==", this.xMax);
+				// 			if (this.xAccArray[this.xMin] < 0 && this.xAccArray[this.xMax] > 0) {
+				// 				if (this.xMin > this.xMax)
+				// 					this.onHit("xRCount", this.xAccArray[this.xMin], Math.ceil(Math.abs(this.xAccArray[this.xMin]) * puchConfig.BOXING_MASS));
+				// 				else if (this.xMin < this.xMax)
+				// 					this.onHit("xLCount", this.xAccArray[this.xMax], Math.ceil(Math.abs(this.xAccArray[this.xMax]) * puchConfig.BOXING_MASS));
+				// 			} else if (this.xAccArray[this.xMin] < 0) {
+				// 				this.onHit("xLCount", this.xAccArray[this.xMin], Math.ceil(Math.abs(this.xAccArray[this.xMin]) * puchConfig.BOXING_MASS));
+				// 			} else if (this.xAccArray[this.xMax] > 0) {
+				// 				this.onHit("xRCount", this.xAccArray[this.xMax], Math.ceil(Math.abs(this.xAccArray[this.xMax]) * puchConfig.BOXING_MASS));
+				// 			}
+				// 			setTimeout(() => {
+				// 				this.onResetCal();
+				// 			}, 100);
+				// 			this.calTimeout = null;
+				// 		}, 200);
+				// 	}
+				// } else if (this.zA < -10 && this.oldzA != this.zA && this.xAccArray.length == 0) {
+				// 	console.log("this.zA:", this.zA);
+				// 	this.oldzA = this.zA;
+				// 	setTimeout(() => {
+				// 		this.onResetCal();
+				// 	}, 200);
+				// 	this.onHit("zLCount", this.zA, Math.ceil(Math.abs(this.zA) * puchConfig.BOXING_MASS));
+				// }
+			},
+			updateOri(ori) {
+				this.xO = ori.beta;
+				this.zO = ori.alpha;
+				this.yO = ori.gamma;
+			},
+			//步骤条调整速度
+			_customSetBasics(data) {
+				console.log(data);
+				let _self = this;
+				if (_self.autoBoxingTip) {
+					clearInterval(_self.autoBoxingTip);
+					_self.autoBoxingTip = null;
+				}
+
+				if (0 === data.basics)
+					_self.autoDuration = 800;
+				else
+					_self.autoDuration = 3000 - data.basics * 260;
+				console.log("_self.autoDuration:", _self.autoDuration);
+
+				_self.basic = data.basics;
+
+				if (!_self.bPlay || _self.bGuide) return;
+
+				if (0 != _self.basic) {
+					//自动调用拳击图标
+					_self.autoBoxingTip = setInterval(function() {
+						_self.onAutoPlayBoxingTip();
+					}, _self.autoDuration);
+				}
+
+			},
+			_customControlButton(data) {
+				//修改步骤条,绑定回调 _customSetBasics 
+				this.$refs.customStepRef.onChangeBasicsFromDirection(data);
+			},
+			_customControlPlay(data) {
+				let _self = this;
+				//1.检查是否符合要求,再进行训练
+				if (data.bControlRun) {
+					//如果运行中直接停掉
+					if (_self.autoBoxingTip) {
+						clearInterval(_self.autoBoxingTip);
+						_self.autoBoxingTip = null;
+					}
+
+					if (_self.sportTimeInterval) {
+						clearInterval(_self.sportTimeInterval);
+						_self.sportTimeInterval = null;
+					}
+
+					this.bPlay = false;
+					this.$refs.customControlButtons.onPlay();
+
+					//如果是新手教程,也直接停掉
+					this.bGuide = false;
+					this.bGuideEF = false;
+
+					this.bRAnimation = false;
+					this.bLAnimation = false;
+					this.bMAnimation = false;
+
+					this.$emit("boxingPostControlPlay", false);
+				} else {
+					this.$emit("boxingPostCheck");
+				}
+
+			},
+			//新手引导
+			onGuideBoxingPostPlay() {
+				console.log("onGuideBoxingPostPlay");
+				let _self = this;
+				_self.bPlay = true;
+				//
+				_self.bGuide = true;
+				// 按钮事件
+				_self.$refs.customControlButtons.onPlay();
+
+				// 右勾拳
+				_self.onPlayBoxingTipIndex(0, () => {
+
+				});
+
+
+			},
+			//训练退出时候,重新信息
+			onBoxingPostStop() {
+				this.addLCount = 0;
+				this.addRCount = 0;
+				this.addZCount = 0;
+				// this.calorie = 0;
+				this.powerCount = 0;
+			},
+
+			//调用播放
+			onBoxingPostPlay(bPlaying) {
+
+				let _self = this;
+
+				if (bPlaying) {
+					_self.bPlay = true;
+					// 按钮事件
+					_self.$refs.customControlButtons.onPlay(true);
+
+					if (_self.sportTimeInterval) {
+						clearInterval(_self.sportTimeInterval);
+						_self.sportTimeInterval = null;
+					}
+
+					//play true 时候,开启时间计算
+					_self.sportTimeInterval = setInterval(() => {
+						_self.showSportTime++;
+
+						if (_self.showSportTime >= 20 && _self.showSportTime % 20 == 0) {
+							_self.$emit("updateSportTime", _self.showSportTime);
+						}
+					}, 1000)
+				}
+
+				if (_self.autoBoxingTip) {
+					clearInterval(_self.autoBoxingTip);
+					_self.autoBoxingTip = null;
+				}
+
+				//如果是0,打一拳调用一次
+				if (0 == _self.basic) {
+					_self.onAutoPlayBoxingTip();
+				} else {
+					_self.onAutoPlayBoxingTip();
+					_self.autoBoxingTip = setInterval(function() {
+						_self.onAutoPlayBoxingTip();
+					}, _self.autoDuration);
+				}
+
+
+			},
+			//新手定时播放
+			onPlayBoxingTipIndex(_index, callback) {
+				if (_index === 0) {
+					//右勾拳
+					this.bRAnimation = true;
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.rightTipUrl;
+					this.hookAudioContext.play();
+					if (callback)
+						callback();
+
+					//
+					this.angleRatio = 10;
+
+				} else if (_index === 1) {
+					//左勾拳
+					this.bLAnimation = true;
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.leftTipUrl;
+					this.hookAudioContext.play();
+					if (callback)
+						callback();
+
+					this.angleRatio = 10;
+
+				} else if (_index === 2) {
+					//直拳
+					this.bMAnimation = true;
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.straightTipUrl;
+					this.hookAudioContext.play();
+					if (callback)
+						callback();
+
+					this.angleRatio = 0.5;
+
+				} else if (_index === 3) {
+					this.bGuideEF = true;
+					this.hookAudioContext.stop();
+					this.hookAudioContext.src = this.giveGoTipUrl;
+					this.hookAudioContext.play();
+					if (callback)
+						callback();
+
+				}
+				console.log("this.hookAudioContext:", this.hookAudioContext);
+
+			},
+
+			//随机播放
+			onAutoPlayBoxingTip() {
+				// console.log("onAutoPlayBoxingTip .powerCount:",this.powerCount);
+				//重置动画
+				this.bRAnimation = false;
+				this.bLAnimation = false;
+				this.bMAnimation = false;
+
+				let _index = Math.floor(Math.random() * 3);
+				// console.log("_index==",_index);
+				// return;
+				if (_index === 0) {
+
+					//右勾拳
+					if (!this.bRAnimation) {
+						this.bRAnimation = true;
+						this.hookAudioContext.stop();
+						this.hookAudioContext.src = this.rightHookUrl;
+						this.hookAudioContext.play();
+					}
+
+					this.angleRatio = 10;
+
+				} else if (_index === 1) {
+
+					//左勾拳
+					if (!this.bLAnimation) {
+						this.bLAnimation = true;
+						this.hookAudioContext.stop();
+						this.hookAudioContext.src = this.leftHookUrl;
+						this.hookAudioContext.play();
+					}
+
+					this.angleRatio = 10;
+				} else if (_index === 2) {
+
+					//直拳
+					if (!this.bMAnimation) {
+						this.bMAnimation = true;
+						this.hookAudioContext.stop();
+						this.hookAudioContext.src = this.straightHookUrl;
+						this.hookAudioContext.play();
+					}
+
+					this.angleRatio = 0.5;
+				}
+			},
+
+			onHit(direction, direValue, power) {
+
+				// console.log(direction, direValue, power);
+				let temp = {
+					direction: direction,
+					value: direValue,
+					mass: this.mass, //质量
+					hitPower: power //计算的力
+				}
+
+				//设置200 为最大值,最大值时候分为40份。即单位是 7.5
+				let _maxPower = 200;
+				if (power >= _maxPower) {
+					this.powerMaxCount = 40;
+				} else {
+					this.powerMaxCount = Math.ceil(power / 5);
+				}
+
+				//如果是男性用户
+				let _nameList = this.manNameList;
+				if (!this.bMan) {
+					_nameList = this.womanNameList;
+				}
+				//名字相对于最大力量 的 间隔单位
+				let _nameUnit = _maxPower / _nameList.length;
+				let _nameIndex = Math.ceil(power / _nameUnit);
+
+				if (_nameIndex < _nameList.length - 1) {
+					//console.log("名称下标:", _nameList[_nameIndex], "下一个目标:", _nameList[_nameIndex + 1]);
+					this.evaluateName = _nameList[_nameIndex + 1];
+					//下一个目标的公斤值
+					let _nextPower = Math.ceil((_nameIndex + 1) * _nameUnit);
+					//console.log("_nextPower:", _nextPower, power);
+					this.evaluatePower = _nextPower - power;
+				} else {
+					this.evaluateName = _nameList[_nameList.length - 1];
+					this.evaluatePower = 0;
+				}
+
+				//如果是新手流程
+				if (this.bGuide) {
+
+					// if (this.bGuideEF) {
+
+					// 	if (!this.efRandomObj) return;
+
+					// 	let bHitEF = false;
+					// 	if (this.efRandomObj.direction == direction) {
+					// 		// this.RCount++;
+					// 		bHitEF = true;
+					// 	} else if (this.efRandomObj.direction == direction) {
+					// 		// this.LCount++;
+					// 		bHitEF = true;
+					// 	} else if (this.efRandomObj.direction == direction) {
+					// 		// this.ZCount++;
+					// 		bHitEF = true;
+					// 	}
+					// 	//播放全力一击特效,特效完成后回调
+					// 	if (bHitEF) {
+					// 		this.bHitEFRandomObj = true;
+					// 		//播放进度动画
+					// 		this.onPlayEFHitAnimation();
+
+					// 		//爆炸同时抖动
+					// 		this.$emit("shake");
+
+					// 		this.$refs.refEfBone.onEFHit(() => {
+					// 			// this.doubleHitCount++;
+					// 			this.bGuideEF = false;
+					// 			this.bGuide = false;
+
+					// 			this.hookAudioContext.stop();
+					// 			this.hookAudioContext.src = this.greatTipUrl;
+					// 			this.hookAudioContext.play();
+					// 			setTimeout(() => {
+					// 				this.hookAudioContext.stop();
+					// 				this.hookAudioContext.src = this.startTraining;
+					// 				this.hookAudioContext.play();
+					// 				setTimeout(() => {
+					// 					this.$emit("boxingGuideFinish");
+					// 				}, 3000);
+					// 			}, 1000)
+
+					// 			this.bHitEFRandomObj = false;
+
+
+					// 		});
+					// 	}
+					// } else {
+					//根据是否播放的拳击,来判断是否击中
+					if (direction == "xLCount" && this.bRAnimation) {
+						//右勾拳
+						// this.RCount++;
+						// this.doubleHitCount++;
+						this.bRAnimation = false;
+						//播放进度动画
+						this.onPlayPowerAnimation(true);
+
+						setTimeout(() => {
+							//播放下一个拳击
+							this.onPlayBoxingTipIndex(1);
+
+						}, 1500)
+
+					} else if (direction == "xRCount" && this.bLAnimation) {
+						//左勾拳
+						// this.LCount++;
+						// this.doubleHitCount++;
+						this.bLAnimation = false;
+						//播放进度动画
+						this.onPlayPowerAnimation(true);
+						//播放下一个拳击
+						setTimeout(() => {
+							//播放下一个拳击
+							this.onPlayBoxingTipIndex(2);
+
+						}, 1500)
+
+					} else if (direction == "zLCount" && this.bMAnimation) {
+						//直拳
+						// this.ZCount++;
+						// this.doubleHitCount++;
+						this.bMAnimation = false;
+						//播放进度动画
+						this.onPlayPowerAnimation(true);
+						//全力一击
+						setTimeout(() => {
+							//播放下一个拳击
+							// this.onPlayBoxingTipIndex(3);
+							this.bGuide = false;
+							this.$emit("boxingGuideFinish");
+						}, 1500)
+					}
+					// }
+
+
+
+				} else {
+					// //如果单次是特殊一击
+					// if (this.doubleHitCount > 0 && this.doubleHitCount % this.doubleHitLimit == 0) {
+
+					// 	if (this.bHitEFRandomObj) return;
+					// 	if (!this.efRandomObj) return;
+
+					// 	let bHitEF = false;
+					// 	if (this.efRandomObj.direction == direction) {
+					// 		this.RCount++;
+					// 		bHitEF = true;
+					// 	} else if (this.efRandomObj.direction == direction) {
+					// 		this.LCount++;
+					// 		bHitEF = true;
+					// 	} else if (this.efRandomObj.direction == direction) {
+					// 		this.ZCount++;
+					// 		bHitEF = true;
+					// 	}
+					// 	//播放全力一击特效,特效完成后回调
+					// 	if (bHitEF) {
+					// 		this.bHitEFRandomObj = true;
+					// 		//播放进度动画
+					// 		this.onPlayEFHitAnimation();
+
+					// 		//爆炸同时抖动
+					// 		this.$emit("shake");
+
+					// 		this.$refs.refEfBone.onEFHit(() => {
+					// 			this.doubleHitCount++;
+					// 			setTimeout(() => {
+					// 				//新手教程,恢复随机播放
+					// 				this.onBoxingPostPlay();
+					// 			}, 1000);
+
+					// 			this.bHitEFRandomObj = false;
+
+
+					// 		});
+					// 	}
+
+					// } else 
+					// {
+					//如果没有显示动画,不能打击
+					if (!this.bRAnimation && !this.bLAnimation && !this.bMAnimation)
+						return;
+
+					//如果力量槽达到最大值,同步卡路里,并且清空记录值
+					if (this.powerCount >= 40) {
+						console.log("同步卡路里");
+						this.$emit('updateCalorie', this.calorie);
+
+						this.addLCount = 0;
+						this.addRCount = 0;
+						this.addZCount = 0;
+
+					}
+
+					//根据是否播放的拳击,来判断是否击中
+					if (direction == "xLCount" && this.bRAnimation) {
+						//右勾拳
+						this.RCount++;
+						this.addRCount++;
+						this.doubleHitCount++;
+						this.bRAnimation = false;
+						//播放进度动画
+						this.onPlayPowerAnimation();
+					} else if (direction == "xRCount" && this.bLAnimation) {
+						//左勾拳
+						this.LCount++;
+						this.addLCount++;
+						this.doubleHitCount++;
+						this.bLAnimation = false;
+						//播放进度动画
+						this.onPlayPowerAnimation();
+						// console.log("xRCount");
+					} else if (direction == "zLCount" && this.bMAnimation) {
+						//直拳
+						this.ZCount++;
+						this.addZCount++;
+						this.doubleHitCount++;
+						this.bMAnimation = false;
+						//播放进度动画
+						this.onPlayPowerAnimation();
+						// console.log("zLCount");
+					}
+					// else if (this.bRAnimation || this.bLAnimation || this.bMAnimation) {
+					// 	//如果没有击打的,设置miss
+					// 	this.missCount++;
+					// 	this.doubleHitCount = 0;
+
+					// 	this.hookAudioContext.stop();
+					// 	this.hookAudioContext.src = this.missUrl;
+					// 	this.hookAudioContext.play();
+					// 	console.log("miss");
+					// 	this.bRAnimation = false;
+					// 	this.bLAnimation = false;
+					// 	this.bMAnimation = false;
+					// }
+					//停掉当前的随机播放
+					if (this.autoBoxingTip) {
+						clearInterval(this.autoBoxingTip);
+						this.autoBoxingTip = null;
+					}
+					// console.log(11111);
+					//判断当前连击数
+					// if (this.doubleHitCount > 0 && this.doubleHitCount % this.doubleHitLimit == 0) {
+
+					// 	this.hookAudioContext.stop();
+					// 	this.hookAudioContext.src = this.giveGoTipUrl;
+					// 	this.hookAudioContext.play();
+					// } else {
+					this.endSetTimeout = setTimeout(() => {
+
+						// console.log("start");
+						//更新随机播放
+						this.onBoxingPostPlay();
+					}, 400);
+
+					// }
+
+					// }
+
+					//每10次更新一次卡路里
+					// if (this.hitCount !==0 && 0 == this.hitCount % 10) {
+					// 	//打一拳,大约消耗的热量,是450*4/60=1.875 焦耳。 
+					// 	//因为打拳一小时,需要消耗的热量是450大卡,而一分钟约打一下,一大卡是4焦耳。
+					// 	//现在大概是2s 打一下,1.875/30
+					// 	// this.calorie = Math.floor((10 * 1.875) / (4*30));
+					// 	this.calorie = puchConfig.getBoxingCalorie(10);
+					// 	console.log("更新卡路里======:", this.calorie);
+					// 	this.$emit('updateCalorie', this.calorie);
+					// }
+
+					this.hitCount = this.ZCount + this.LCount + this.RCount;
+					this.addCount = this.addZCount + this.addLCount + this.addRCount;
+					this.calorie = puchConfig.getBoxingCalorie(this.addCount);
+					//10 大卡,为一个周期 分40份
+					console.log("this.calorie:", this.calorie, this.calorie * 4);
+					this.powerCount = parseInt(this.calorie * 4);
+				}
+
+
+			},
+
+			updateData() {
+				if (!this.bUpdate || !this.bPlay) return;
+
+				//1.求出z 和 x 的加速度矢量
+				//z轴的重力加速度矢量分量
+				// this.calZVector = (Math.cos(this.xO / 180 * Math.PI) * 9.8);
+				//x轴的重力加速度的矢量分量
+				// if (this.yA > 9.8)
+				// 	this.yA = 9.8;
+				// let tempXVector = Math.pow(9.8, 2) - (Math.pow(this.calZVector, 2) + Math.pow(this.yA, 2));
+				// this.calXVector = Math.sqrt(Math.abs(tempXVector));
+				//2.当前的加速度矢量减去分量,就是打击的加速度
+				// let tempZ = Math.abs(this.zA) - Math.abs(this.calZVector);
+				// let tempX = Math.abs(this.xA) - Math.abs(this.calXVector);
+				let tempZ = Math.abs(this.zA);
+				let tempX = Math.abs(this.xA);
+				//3.判断 那个轴的打击方向,就走哪个轴的计算流程
+				//直拳判断 
+				let zAcc = Math.abs(this.zA) - Math.abs(this.oldzA);
+				let leftAcc = Math.abs(this.xA) - Math.abs(this.oldxA);
+				let rightAcc = this.xA - this.oldxA;
+
+				let tempLimit = puchConfig.SENDITIVITY; //灵敏度
+				//判断方位,用比值 直拳方向 和 左右方向 比。
+				//如果比值相同 等于约定的数值,以1为标准,则是正勾拳
+				if (Math.abs(leftAcc) != 0) {
+					let tempDirection = Math.abs(zAcc) / Math.abs(leftAcc);
+					if (tempDirection > this.angleRatio) {
+						if (zAcc > tempLimit && this.zA < -tempLimit) {
+							if (this.bUpdateOnce)
+								return;
+							console.log("走直拳");
+							this.bUpdateOnce = true;
+							let _endPower = Math.abs(tempZ) * this.mass;
+							this.onHit("zLCount", tempZ, Math.ceil(_endPower));
+							// console.log("zLCount:", this.zA, leftAcc, rightAcc, zAcc);
+							// console.log("xA:", this.xA, " zA:", this.zA, " leftAcc:", leftAcc, " rightAcc:", rightAcc, " zAcc:", zAcc);
+
+						}
+					} else {
+						if ((leftAcc > tempLimit || zAcc > tempLimit) && this.xA > tempLimit) {
+							if (this.bUpdateOnce)
+								return;
+							console.log("走左勾拳");
+							this.bUpdateOnce = true;
+							let _endPower = (Math.abs(tempX) + Math.abs(tempZ)) * this.mass;
+							this.onHit("xRCount", tempX, Math.ceil(_endPower));
+							// console.log("xRCount:", this.xA, leftAcc, rightAcc);
+							// console.log("xA:", this.xA, " zA:", this.zA, " leftAcc:", leftAcc, " rightAcc:", rightAcc, " zAcc:", zAcc);
+
+						}
+						if ((rightAcc < -tempLimit || zAcc > tempLimit) && this.xA < -tempLimit) {
+							if (this.bUpdateOnce)
+								return;
+							console.log("走右勾拳");
+							this.bUpdateOnce = true;
+							let _endPower = (Math.abs(tempX) + Math.abs(tempZ)) * this.mass;
+							this.onHit("xLCount", tempX, Math.ceil(_endPower));
+							// console.log("xLCount:", this.xA, leftAcc, rightAcc);
+							// console.log("xA:", this.xA, " zA:", this.zA, " leftAcc:", leftAcc, " rightAcc:", rightAcc, " zAcc:", zAcc);
+
+						}
+
+					}
+				}
+
+				this.oldxA = this.xA;
+				this.oldzA = this.zA;
+
+				if (!this.bDelayOnce && this.bUpdateOnce) {
+					this.bDelayOnce = true;
+					setTimeout(() => {
+						this.bUpdateOnce = false;
+						this.bDelayOnce = false;
+					}, 500);
+				}
+			},
+			_efRandomIndex(res) {
+				console.log("_efRandomIndex:", res);
+				this.efRandomObj = res;
+
+				if (res.direction == "xRCount") {
+					//左勾拳音效
+					this.angleRatio = 10;
+				} else if (res.direction == "xLCount") {
+					this.angleRatio = 10;
+				} else if (res.direction == "zLCount") {
+					this.angleRatio = 0.5;
+				}
+
+
+				setTimeout(() => {
+					if (res.direction == "xRCount") {
+						//左勾拳音效
+						this.hookAudioContext.stop();
+						this.hookAudioContext.src = this.leftHookUrl;
+						this.hookAudioContext.play();
+					} else if (res.direction == "xLCount") {
+						this.hookAudioContext.stop();
+						this.hookAudioContext.src = this.rightHookUrl;
+						this.hookAudioContext.play();
+					} else if (res.direction == "zLCount") {
+						this.hookAudioContext.stop();
+						this.hookAudioContext.src = this.straightHookUrl;
+						this.hookAudioContext.play();
+					}
+				}, 2000);
+
+			},
+		}
+	}
+</script>
+
+<style>
+	/* Loader Bar */
+	.vertical-container {
+		position: absolute;
+		top: -50px;
+		left: 0;
+		right: 0;
+		/* bottom: 0; */
+		display: flex;
+		/* flex-direction: column; */
+		justify-content: space-between;
+		/* border: 1rpx solid #000000; */
+		pointer-events: none;
+	}
+
+	.vertical-bar {
+		/* list-style: none; */
+		/* height: 570px; */
+		/* width: 100%; */
+		/* border: 1rpx solid #007AFF; */
+		/* margin: 0 20rpx; */
+		display: flex;
+		flex-direction: column-reverse;
+		/* justify-content: space-between; */
+	}
+
+	.vertical-child {
+		/* position: relative; */
+		width: 70rpx;
+		height: 20rpx;
+		margin-top: 6px;
+		display: flex;
+		/* align-content: center; */
+		justify-content: space-between;
+
+
+	}
+
+	.vertical-text {
+		color: #FFFFFF;
+		font-size: 8px;
+	}
+
+	.text-hidden {
+		visibility: hidden;
+	}
+
+	.vertical-active {
+		background-color: #FFFFFF;
+		width: 30rpx;
+		height: 100%;
+	}
+
+	.vertical-inactive {
+		width: 30rpx;
+		height: 100%;
+		background: rgba(144, 141, 246, 1);
+	}
+
+	.boxing-count-bg {
+		border-radius: 45rpx;
+		background-color: rgba(0, 0, 0, 0.1);
+		width: 160rpx;
+		height: 60rpx;
+		font-size: 22px;
+		font-weight: bold;
+		color: #FFFFFF;
+		line-height: 60rpx;
+	}
+
+	#loadbar {
+		list-style: none;
+		width: 400rpx;
+		margin: 0 20rpx;
+	}
+
+	#loadbar-child {
+		float: left;
+		position: relative;
+		width: 60rpx;
+		height: 10rpx;
+		margin-left: 1px;
+		background: rgba(255, 255, 255, 0.5);
+	}
+
+	#loadbar-child:first-child {
+		margin-left: 0;
+	}
+
+	.bar {
+		background-color: #FFFFFF;
+		width: 60rpx;
+		height: 10rpx;
+	}
+
+
+	.show-png {
+		width: 78rpx;
+		height: 78rpx;
+		margin: 0 10px;
+	}
+
+	.boxing-png {
+		margin-top: 40rpx;
+		width: 133rpx;
+		height: 133rpx;
+		transition: transform 0.15s;
+	}
+
+	.boxing-change {
+		transform: scale(1.58);
+	}
+
+	.boxing-post-talkbubble {
+		margin-top: 30px;
+		width: 260px;
+		height: 40px;
+		background: rgba(255, 255, 255, 0.13);
+		position: relative;
+		border-radius: 4px;
+
+		font-size: 14px;
+		color: #FFFFFF;
+		line-height: 40px;
+	}
+
+	.boxing-post-talkbubble:before {
+		content: "";
+		position: absolute;
+		bottom: 100%;
+		left: 120px;
+		width: 0;
+		height: 0;
+		border-bottom: 13px solid rgba(255, 255, 255, 0.13);
+		border-right: 10px solid transparent;
+		border-left: 10px solid transparent;
+	}
+
+	.boxingTimer {
+		position: absolute;
+		top: -60rpx;
+		left: 0;
+		right: 0;
+	}
+</style>

+ 376 - 0
components/modal/boxing-post/ef-bone.vue

@@ -0,0 +1,376 @@
+<template>
+	<view style="position: relative;">
+		<view v-if="!bHit&&bMove" class="ef-abs">
+			<view class="ef-parent">
+				<view class="ef-container">
+					<view class="focusEnergy playEnergy" :style="{
+						 '--time':duration,
+						 backgroundImage:`url(${energyImageSrc})`}">
+					</view>
+				</view>
+			</view>
+		</view>
+		
+		<view :class="bHit?' ef-hidden ':''" class="flex justify-around " style="margin-bottom: 16rpx; height: 300rpx;">
+			<view style="position: relative;width: 133rpx;">
+				<view :class="[bLeftHidden?'ef-hidden ':'',efLeftValue==0?'':'ef-ani']" class="flex flex-direction justify-between ef-leftHand"
+				 :style="{'left': efLeftValue+'px'}">
+					<image src="/static/modal/boxing-post/left-hook-h@2x.png" :class="bLeftHidden?'':' ef-image-change '" class="ef-png " mode="aspectFit"></image>
+					<view class="text-white text-13px" style="margin: 35rpx 0;">左勾拳</view>
+				</view>
+			</view>
+			<view>
+				<view :class="bMidHidden?'ef-mid-ani ':''" class="flex flex-direction justify-between ef-midHand">
+					<image src="/static/modal/boxing-post/straight-h@2x.png" :class="bMidHidden?'':' ef-image-change '" class="ef-png " mode="aspectFit"></image>
+					<view class="text-white text-13px" style="margin: 35rpx 0;">直拳</view>
+				</view>
+			</view>
+			<view style="position: relative;width: 133rpx;">
+				<view :class="[bRightHidden?'ef-hidden ':'',efRightValue==0?'':'ef-ani']" class="flex flex-direction justify-between ef-rightHand"
+				 :style="{'left': efRightValue+'px'}">
+					<image src="/static/modal/boxing-post/right-hook-h@2x.png" :class="bRightHidden?'':' ef-image-change '" class="ef-png " mode="aspectFit"></image>
+					<view class="text-white text-13px" style="margin: 35rpx 0;">右勾拳</view>
+				</view>
+			</view>
+
+		</view>
+		<!-- <button @tap="onMoveLeftAndRightPos">123</button> -->
+		<!-- <button @tap="onReset">reset</button> -->
+		<!-- <button @tap="onEFHit">hit</button> -->
+
+		<view v-if="bHit" class="ef-abs" style="left: 50rpx;top: 100rpx;">
+			<view class="ef-parent">
+				<view class="ef-container">
+					<view class="ef-bone playBone" :style="{ 
+						 '--time':duration,
+						 backgroundImage:`url(${boneImageSrc})`}">
+					</view>
+				</view>
+			</view>
+		</view>
+
+
+	</view>
+
+</template>
+
+<script>
+	import boneImageSrc from "@/static/modal/boxing-post/ef/bone.png"
+	import energyImageSrc from "@/static/modal/boxing-post/ef/focusEnergy.png"
+
+	export default {
+		props: {
+			duration: {
+				type: Number,
+				default: 0.8
+			}
+		},
+		data() {
+			return {
+				boneImageSrc: boneImageSrc,
+				energyImageSrc: energyImageSrc,
+				efLeftHand: null,
+				efRightHand: null,
+				efMidHand: null,
+				efLeftValue: 0,
+				efRightValue: 0,
+				randomIndex: 0,
+				bLeftHidden: false,
+				bMidHidden: false,
+				bRightHidden: false,
+
+				bMove: false,
+				bHit: false,
+
+				gasUrl: "/static/modal/boxing-post/ef/gas.mp3",
+				gasUpUrl: "/static/modal/boxing-post/ef/gasUp.mp3",
+				hitBoneUrl: "/static/modal/boxing-post/ef/hitBone.mp3",
+				giveGoTipUrl: "/static/modal/boxing-post/tipGiveItAGo.mp3",
+
+				efAudioContext: null,
+				efAudioLoop: null,
+				efTimeout: null,
+			};
+		},
+		created() {
+			
+		},
+		beforeDestroy() {
+			// this.efAudioContext.stop();
+			if (this.efAudioContext)
+				this.efAudioContext.destroy();
+			if (this.efTimeout)
+				clearTimeout(this.efTimeout);
+			// if(this.efAudioLoop)
+			// 	clearInterval(this.efAudioLoop);
+		},
+		mounted() {
+			setTimeout(() => {
+				this.getMidHandSize()
+			}, 100)
+			
+			let _self = this;
+
+			_self.efAudioContext = uni.createInnerAudioContext();
+			_self.efAudioContext.autoplay = true;
+			_self.efAudioContext.src = _self.gasUpUrl;
+			_self.efAudioContext.volume = 0.5;
+
+			_self.efTimeout = setTimeout(() => {
+				_self.efAudioContext.stop();
+				_self.efAudioContext.src = _self.gasUrl;
+				_self.efAudioContext.loop = true;
+				_self.efAudioContext.volume = 0.2;
+				_self.efAudioContext.play();
+			}, 1500);
+
+		},
+		methods: {
+			getMidHandSize() {
+				let _self = this;
+
+				const views1 = uni.createSelectorQuery().in(this).select('.ef-midHand')
+				views1.boundingClientRect(data => {
+					console.log("ef-midHand:", data);
+					_self.efMidHand = data;
+				}).exec();
+
+				const views2 = uni.createSelectorQuery().in(this).select('.ef-leftHand');
+				views2.boundingClientRect(data => {
+					console.log("ef-leftHand:", data);
+					_self.efLeftHand = data;
+				}).exec();
+
+				const views3 = uni.createSelectorQuery().in(this).select('.ef-rightHand');
+				views3.boundingClientRect(data => {
+					console.log("ef-rightHand:", data);
+					_self.efRightHand = data;
+				}).exec();
+
+				setTimeout(() => {
+					this.onMoveLeftAndRightPos();
+				}, 200);
+			},
+			onReset() {
+				let _self = this;
+				_self.efLeftValue = 0;
+				_self.efRightValue = 0;
+
+				_self.bLeftHidden = false;
+				_self.bRightHidden = false;
+				_self.bMidHidden = false;
+
+				_self.bMove = false;
+				_self.bHit = false;
+			},
+			//移动位置
+			onMoveLeftAndRightPos() {
+				let _self = this;
+				_self.efLeftValue = _self.efMidHand.left - _self.efLeftHand.left;
+				_self.efRightValue = _self.efMidHand.left - _self.efRightHand.left;
+
+				_self.bMove = true;
+
+				//随机一个
+				_self.randomIndex = Math.floor(Math.random() * 3);
+				let _randomName = "";
+				let _direction = "";
+				if (0 === _self.randomIndex) {
+					//显示左
+					_self.bRightHidden = true;
+					_self.bMidHidden = true;
+					_randomName = "左勾拳";
+					_direction = "xRCount";
+				} else if (1 === _self.randomIndex) {
+					//显示右
+					_self.bLeftHidden = true;
+					_self.bMidHidden = true;
+					_randomName = "右勾拳";
+					_direction = "xLCount";
+				} else if (2 === _self.randomIndex) {
+					//显示中
+					_self.bLeftHidden = true;
+					_self.bRightHidden = true;
+					_randomName = "直拳";
+					_direction = "zLCount";
+				}
+
+				this.$emit("randomIndex", {
+					index: _self.randomIndex,
+					name: _randomName,
+					direction: _direction
+				});
+
+			},
+			onEFHit(callback) {
+				this.bHit = true;
+
+				this.efAudioContext.stop();
+				this.efAudioContext.src = this.hitBoneUrl;
+				this.efAudioContext.loop = false;
+				this.efAudioContext.volume = 0.7;
+				this.efAudioContext.play();
+
+				setTimeout(() => {
+					this.onReset();
+					if (callback)
+						callback();
+				}, this.duration * 1000);
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.ef-abs {
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+		display: flex;
+		justify-content: center;
+		pointer-events: none;
+		transform: scale(2.5);
+	}
+
+	.ef-parent {
+		// border: 1rpx solid #ffaa7f;
+		position: relative;
+		display: flex;
+		justify-content: center;
+		overflow: hidden;
+		pointer-events: none;
+	}
+
+	.ef-container {
+		width: 100%;
+		height: 187px;
+		position: relative;
+
+	}
+
+	.ef-bone {
+		// background-color: #007AFF;
+		background-size: cover;
+		height: 112px;
+		width: 102px;
+		position: relative;
+		top: 0;
+		left: 0;
+	}
+
+
+	.playBone {
+		animation: runBone calc(var(--time) * 1s) steps(1, start) forwards;
+		-webkit-animation: runBone calc(var(--time) * 1s) steps(1, start) forwards;
+	}
+
+	.focusEnergy {
+		// background-color: #007AFF;
+		background-size: cover;
+		height: 152px;
+		width: 105px;
+		position: relative;
+		top: 0;
+		left: 0;
+	}
+
+	.playEnergy {
+		animation: runEnergy calc(var(--time) * 1s) steps(1, start) infinite;
+		-webkit-animation: runEnergy calc(var(--time) * 1s) steps(1, start) infinite;
+		animation-play-state: running;
+		
+	}
+
+	@keyframes runBone {
+		@for $i from 0 through 13 {
+			#{$i*8.3}% {
+				background-position: -0px -112px*$i;
+			}
+		}
+	}
+	@-webkit-keyframes runBone {
+		@for $i from 0 through 13 {
+			#{$i*8.3}% {
+				background-position: -0px -112px*$i;
+			}
+		}
+	}
+
+	@keyframes runEnergy {
+		@for $i from 0 through 14 {
+			#{$i*7.14}% {
+				background-position: -0px -152px*$i;
+			}
+		}
+	}
+	
+	@-webkit-keyframes runEnergy {
+		@for $i from 0 through 14 {
+			#{$i*7.14}% {
+				background-position: -0px -152px*$i;
+			}
+		}
+	}
+
+	.ef-png {
+		margin-top: 40rpx;
+		width: 133rpx;
+		height: 133rpx;
+		transition: transform 1s;
+	}
+
+	.ef-change {
+		transform: scale(1.58);
+	}
+
+	.ef-image-change {
+		animation-name: myEfImagechange;
+		/*动画的名字*/
+		animation-duration: 300ms;
+		/*定义动画完成一个周期所需要的时间,以秒或毫秒计*/
+		animation-iteration-count: infinite;
+		/*定义动画的播放次数,这里是无限播放*/
+		animation-direction: alternate;
+		/*定义是否应该轮流反向播放动画,这里是动画轮流播放*/
+	}
+
+	@keyframes myEfImagechange {
+		0% {
+			transform: scale(1);
+		}
+
+		100% {
+			transform: scale(1.4);
+		}
+	}
+
+	.ef-leftHand {
+		position: absolute;
+		left: 0px;
+	}
+
+	.ef-ani {
+		transition: opacity 1s, left 1s;
+	}
+
+	.ef-rightHand {
+		position: absolute;
+		left: 0px;
+	}
+
+	.ef-mid-ani {
+		transition: opacity 1s;
+		opacity: 0;
+	}
+
+	.ef-opacity-ani {
+		transition: opacity 1s;
+	}
+
+	.ef-hidden {
+		// visibility: hidden;
+		opacity: 0;
+	}
+</style>

+ 100 - 0
components/my-control-buttons/my-control-buttons.vue

@@ -0,0 +1,100 @@
+<template>
+	<!-- 按钮控制 -->
+	<view class="flex justify-center" style="margin-top: 16px;">
+		<view v-if="showLeftRight" class="my-control-button" style=" width: 90rpx;" @tap="_controlButtonTap(false)">
+			<image class="data-png-26" src="/static/e-left.png"></image>
+		</view>
+		<view class="my-control-button " :class="bPlanFinish?'my-custom-breathing-lamp':''" style=" width:256rpx;" @tap="_controlPlayTap()">
+			<image :class="bControlRun?'data-png-26':'my-control-play'" :src="bControlRun?'/static/e-pause.png':'/static/play.png' "></image>
+		</view>
+		<view v-if="showLeftRight" class="my-control-button" style=" width: 90rpx;" @tap="_controlButtonTap(true)">
+			<image class="data-png-26" src="/static/e-right.png"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+	export default {
+		computed: mapState(['bPlanFinish'
+		]),
+		props:{
+			showLeftRight: {
+				type: [Boolean, String],
+				default: true
+			},
+		},
+		data() {
+			return {
+				// 默认不运行
+				bControlRun: false,
+			}
+		},
+		methods:{
+			_controlButtonTap(bRight){
+				console.log("right==",bRight);
+				this.$emit('onControlButtonTap',{bRight:bRight});
+			},
+			_controlPlayTap(){
+				console.log("onControlPlayTap");
+				this.$emit('onControlPlayTap',{bControlRun:this.bControlRun});
+			},
+			onPlay(bPlaying){
+				if(bPlaying){
+					this.bControlRun = bPlaying;
+				}else{
+					this.bControlRun = !this.bControlRun;
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	
+	.my-control-button {
+		background-color: rgba(255, 255, 255, 0.25);
+		border-radius: 45px;
+		margin: 5px 12px;
+		box-shadow: 1px 1px 3px #888888;
+		display: flex;
+		justify-content: center;
+		height: 26px;
+	}
+	
+	/* 图标大小 */
+	.my-control-play {
+		width: 16px;
+		height: 16px;
+		margin-top: 10rpx;
+	}
+	
+	
+	/* 呼吸灯 */
+	.my-custom-breathing-lamp {
+		animation-duration: 1s;
+		animation-timing-function: ease-out;
+		animation-fill-mode: inherit;
+		animation-iteration-count: infinite;
+		animation-name: my-custom-run-lamp;
+		animation-play-state: running;
+	}
+	
+	@keyframes my-custom-run-lamp {
+	
+		0%,
+		100% {
+			opacity: 1;
+			transform: scale(1);
+		}
+	
+		50% {
+			opacity: 0.6;
+			transform: scale(0.9);
+		}
+	
+	}
+</style>

+ 76 - 0
components/my-custom-step/my-custom-step.vue

@@ -0,0 +1,76 @@
+<template>
+	<!-- 步骤条 -->
+	<view>
+		<view class="text-11px text-white text-left" style="width: 100%;margin-left: 40rpx;">调整速度</view>
+		<view class="my-cu-steps">
+			<view class="my-cu-item" :class="index>basics?'':'make-text-r-blue'" v-for="(item,index) in basicsList" :key="index">
+				<view style="position: relative;" @tap="_customSetBasics(index)">
+					<view style="position: absolute; top:0;bottom:0;right: 0;left: 0; margin: auto; width: 10px;height: 10px; border-radius: 45px; background-color: #FFFFFF;"></view>
+					<text :class="'cuIcon-' + item.cuIcon"></text>
+				</view>
+				<view style="color: #FFFFFF;">{{item.name}}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+
+		data() {
+			return {
+				//步骤点
+				basicsList: [{
+					cuIcon: 'radioboxfill',
+					name: '0'
+				}, {
+					cuIcon: 'radioboxfill',
+					name: '1'
+				}, {
+					cuIcon: 'radioboxfill',
+					name: '2'
+				}, {
+					cuIcon: 'radioboxfill',
+					name: '3'
+				}, {
+					cuIcon: 'radioboxfill',
+					name: '4'
+				}, {
+					cuIcon: 'radioboxfill',
+					name: '5'
+				}, {
+					cuIcon: 'radioboxfill',
+					name: '6'
+				}],
+				basics: 0,
+			}
+		},
+		
+		methods:{
+			//操作心电图
+			_customSetBasics(index) {
+				// if (!this.bElectRun) return;
+				this.basics = index;
+			
+				// this.electro.duration = 2000 - (this.basics + 1) * 150;
+				// this.$refs.electRef.changeDuration(this.electro.duration);
+				// callback
+				
+				this.$emit('onCustomSetBasics',{basics:this.basics});
+			},
+			
+			onChangeBasicsFromDirection(data){
+				let _bRight = data.bRight;
+				if (_bRight) {
+					this.basics = this.basics == this.basicsList.length - 1 ? 0 : this.basics + 1;
+				} else {
+					this.basics = this.basics == 0 ? 6 : this.basics - 1;
+				}
+				this.$emit('onCustomSetBasics',{basics:this.basics});
+			}
+		}
+	}
+</script>
+
+<style>
+</style>

+ 198 - 0
components/prompt-box/prompt-box.vue

@@ -0,0 +1,198 @@
+<template>
+	<view>
+		<canvas style="width: 375px; height: 270px;" canvas-id="promptCanvas"></canvas>
+	</view>
+</template>
+
+<script>
+	import utilData from "../../util/util-js/util-data.js"
+	export default {
+		props: {
+			calorie: {
+				type: Number,
+				default: 0
+			},
+		},
+		data() {
+			return {
+				tipCanvasInterval: null,
+				context: null,
+				bShow: false,
+				promptInterval:null,
+			}
+		},
+		watch: {
+			calorie(val) {
+				// this.onPlay();
+			}
+		},
+		created() {
+			var context = uni.createCanvasContext('promptCanvas')
+			this.context = context;
+			
+			setTimeout(()=>{
+				//循环一个提示
+				this.promptInterval = setInterval(() => {
+					if (this.bShow) {
+						this.hideDraw();
+					} else {
+						this.Draw();
+					}
+					this.bShow = !this.bShow;
+				}, 60000)
+			},500)
+
+		},
+		beforeDestroy() {
+			clearInterval(this.promptInterval);
+			this.promptInterval = null;
+		},
+		methods: {
+			hideDraw() {
+				// console.log("hide draw");
+				clearInterval(this.tipCanvasInterval);
+				this.tipCanvasInterval = null;
+				this.context.beginPath();
+				this.context.clearRect(0, 0, 1000, 1000);
+				this.context.draw();
+			},
+			Draw() {
+				// console.log("Draw");
+				var context = this.context;
+				let pos = {
+					x: 200,
+					y: 90
+				};
+				let tempCount = 0;
+				let index = 0;
+				this.tipCanvasInterval = setInterval(() => {
+
+					if (30 <= tempCount) {
+						if (index == 0) {
+							index++;
+							tempCount = 0;
+						} else if (index == 1) {
+							//最后绘制背景板和文字
+							index++;
+							tempCount = 0;
+						} else {
+							clearInterval(this.tipCanvasInterval);
+							this.tipCanvasInterval = null;
+						}
+						return;
+					}
+					tempCount++;
+					context.setStrokeStyle("#FFFFFF")
+					context.setLineWidth(0.33)
+					//线段最后一个点位置
+					let endPos = {
+						x: pos.x,
+						y: pos.y
+					};
+					//起始点
+					context.beginPath();
+					context.setStrokeStyle("rgba(255,255,255,0)")
+					context.setLineWidth(0.33)
+					context.moveTo(endPos.x + 5, endPos.y)
+					context.arc(endPos.x, endPos.y, 5, 0, 2 * Math.PI, true)
+					context.fillStyle = "rgba(255,255,255,0.3)"
+					context.fill()
+					context.stroke()
+
+					context.beginPath();
+					context.setStrokeStyle("#FFFFFF")
+					context.moveTo(endPos.x + 2, endPos.y)
+					context.arc(endPos.x, endPos.y, 2, 0, 2 * Math.PI, true)
+					context.fillStyle = "#FFFFFF"
+					context.fill()
+					context.stroke()
+
+					if (index == 0) {
+						endPos.x = pos.x + tempCount;
+						endPos.y = pos.y - tempCount * 2;
+						context.beginPath();
+						context.moveTo(pos.x, pos.y)
+						context.lineTo(endPos.x, pos.y - tempCount * 2)
+						context.stroke()
+					} else if (index == 1) {
+						let x = pos.x + 30;
+						let y = pos.y - 60;
+						endPos.x = x + tempCount;
+						endPos.y = y;
+						context.beginPath();
+						context.moveTo(pos.x, pos.y)
+						context.lineTo(x, y)
+						context.stroke()
+						context.beginPath();
+						context.moveTo(x, y)
+						context.lineTo(x + tempCount, y)
+						context.stroke()
+					} else if (index == 2) {
+
+						let x = pos.x + 30;
+						let y = pos.y - 60;
+						//白点的位置
+						endPos.x = x + 30;
+						endPos.y = y;
+
+						context.beginPath();
+						context.moveTo(pos.x, pos.y)
+						context.lineTo(x, y)
+						context.stroke()
+						context.beginPath();
+						context.moveTo(x, y)
+						context.lineTo(x + 30, y)
+						context.stroke()
+						//偏移量调整
+						let yPos = 0;
+						let xPos = 15;
+						context.setStrokeStyle("#FFFFFF")
+						context.setLineWidth(1)
+						context.beginPath();
+						context.moveTo(endPos.x + xPos, endPos.y - 10 + yPos)
+						context.lineTo(endPos.x + 7 + xPos, endPos.y - 20 + yPos)
+						context.lineTo(endPos.x + 85 + xPos, endPos.y - 20 + yPos)
+						context.lineTo(endPos.x + 85 + xPos, endPos.y + yPos)
+						context.lineTo(endPos.x + 73 + xPos, endPos.y + 10 + yPos)
+						context.lineTo(endPos.x + xPos, endPos.y + 10 + yPos)
+						context.lineTo(endPos.x + xPos, endPos.y - 10 + yPos)
+						// context.fillStyle = "#FFFFFF"
+						// context.fill()
+						context.stroke()
+
+						context.fillStyle = "#FFFFFF"
+						context.font = "12px Arial";
+						let kg = utilData.calorieConversionKg(this.calorie);
+						context.fillText("约 "+kg.toFixed(2)+" 公斤", endPos.x + 10 + xPos, endPos.y + yPos);
+
+					}
+
+					//绘制点移动
+
+					context.beginPath();
+					context.setStrokeStyle("rgba(255,255,255,0)")
+					context.setLineWidth(0.33)
+					context.moveTo(endPos.x + 5, endPos.y)
+					context.arc(endPos.x, endPos.y, 5, 0, 2 * Math.PI, true)
+					context.fillStyle = "rgba(255,255,255,0.3)"
+					context.fill()
+					context.stroke()
+
+					context.beginPath();
+					context.setStrokeStyle("#FFFFFF")
+					context.moveTo(endPos.x + 2, endPos.y)
+					context.arc(endPos.x, endPos.y, 2, 0, 2 * Math.PI, true)
+					context.fillStyle = "#FFFFFF"
+					context.fill()
+					context.stroke()
+
+					context.draw()
+				}, 10)
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 374 - 0
components/round-fab/round-fab.vue

@@ -0,0 +1,374 @@
+<template>
+	<view>
+		<view v-if="leftBottom||rightBottom||leftTop||rightTop" :class="{
+        'uni-fab--leftBottom': leftBottom,
+        'uni-fab--rightBottom': rightBottom,
+        'uni-fab--leftTop': leftTop,
+        'uni-fab--rightTop': rightTop
+      }"
+		 class="uni-fab">
+			<view :class="{
+          'uni-fab__content--left': horizontal === 'left',
+          'uni-fab__content--right': horizontal === 'right',
+          'uni-fab__content--flexDirection': direction === 'vertical',
+          'uni-fab__content--flexDirectionStart': flexDirectionStart,
+          'uni-fab__content--flexDirectionEnd': flexDirectionEnd,
+		  'uni-fab__content--other-platform': !isAndroidNvue
+        }"
+			 :style="{ width: boxWidth, height: boxHeight, backgroundColor: styles.backgroundColor }" class="uni-fab__content">
+				<view v-if="flexDirectionStart || horizontalLeft" class="uni-fab__item uni-fab__item--first" />
+				<view v-for="(item, index) in content" :key="index" :class="{ 'uni-fab__item--active': isShow }" class="uni-fab__item"
+				 @click="_onItemClick(index, item)">
+					<image :src="item.active ? item.selectedIconPath : item.iconPath" class="uni-fab__item-image" mode="widthFix" />
+					<text class="uni-fab__item-text" :style="{ color: item.active ? styles.selectedColor : styles.color }">{{ item.text }}</text>
+				</view>
+				<view v-if="flexDirectionEnd || horizontalRight" class="uni-fab__item uni-fab__item--first" />
+			</view>
+			<view :class="{
+          'uni-fab__circle--left': horizontal === 'left' && direction === 'horizontal',
+          'uni-fab__circle--top': vertical === 'top' && direction === 'vertical',
+          'uni-fab__circle--bottom': vertical === 'bottom' && direction === 'vertical',
+          'uni-fab__circle--right': horizontal === 'right' && direction === 'horizontal',
+		  'uni-fab__plus--active': isShow,
+		  'uni-fab__content--other-platform': !isAndroidNvue
+        }"
+			 class="uni-fab__circle uni-fab__plus" :style="{ 'background-color': styles.buttonColor }" @click="_onClick">
+				<view class="fab-circle-v"></view>
+				<view class="fab-circle-h"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	let platform = 'other'
+	// #ifdef APP-NVUE
+	platform = uni.getSystemInfoSync().platform
+	// #endif
+	export default {
+		name: 'UniFab',
+		props: {
+			pattern: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			horizontal: {
+				type: String,
+				default: 'left'
+			},
+			vertical: {
+				type: String,
+				default: 'bottom'
+			},
+			direction: {
+				type: String,
+				default: 'horizontal'
+			},
+			content: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			show: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				fabShow: false,
+				isShow: false,
+				isAndroidNvue: platform === 'android',
+				styles: {
+					color: '#3c3e49',
+					selectedColor: '#007AFF',
+					backgroundColor: '#fff',
+					buttonColor: '#3c3e49'
+				}
+			}
+		},
+		computed: {
+			contentWidth(e) {
+				return (this.content.length + 1) * 55 + 10 + 'px'
+			},
+			contentWidthMin() {
+				return 55 + 'px'
+			},
+			// 动态计算宽度
+			boxWidth() {
+				return this.getPosition(3, 'horizontal')
+			},
+			// 动态计算高度
+			boxHeight() {
+				return this.getPosition(3, 'vertical')
+			},
+			// 计算左下位置
+			leftBottom() {
+				return this.getPosition(0, 'left', 'bottom')
+			},
+			// 计算右下位置
+			rightBottom() {
+				return this.getPosition(0, 'right', 'bottom')
+			},
+			// 计算左上位置
+			leftTop() {
+				return this.getPosition(0, 'left', 'top')
+			},
+			rightTop() {
+				return this.getPosition(0, 'right', 'top')
+			},
+			flexDirectionStart() {
+				return this.getPosition(1, 'vertical', 'top')
+			},
+			flexDirectionEnd() {
+				return this.getPosition(1, 'vertical', 'bottom')
+			},
+			horizontalLeft() {
+				return this.getPosition(2, 'horizontal', 'left')
+			},
+			horizontalRight() {
+				return this.getPosition(2, 'horizontal', 'right')
+			}
+		},
+		watch: {
+			pattern(newValue, oldValue) {
+				//console.log(JSON.stringify(newValue))
+				this.styles = Object.assign({}, this.styles, newValue)
+			}
+		},
+		created() {
+			this.isShow = this.show
+			if (this.top === 0) {
+				this.fabShow = true
+			}
+			// 初始化样式
+			this.styles = Object.assign({}, this.styles, this.pattern)
+		},
+		methods: {
+			_onClick() {
+				this.isShow = !this.isShow
+			},
+			open() {
+				this.isShow = true
+			},
+			close() {
+				this.isShow = false
+			},
+			/**
+			 * 按钮点击事件
+			 */
+			_onItemClick(index, item) {
+				this.$emit('trigger', {
+					index,
+					item
+				})
+			},
+			/**
+			 * 获取 位置信息
+			 */
+			getPosition(types, paramA, paramB) {
+				if (types === 0) {
+					return this.horizontal === paramA && this.vertical === paramB
+				} else if (types === 1) {
+					return this.direction === paramA && this.vertical === paramB
+				} else if (types === 2) {
+					return this.direction === paramA && this.horizontal === paramB
+				} else {
+					return this.isShow && this.direction === paramA ? this.contentWidth : this.contentWidthMin
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.uni-fab {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		z-index: 10;
+	}
+
+	.uni-fab--top {
+		width: 30px;
+		height: 30px;
+		right: 15px;
+		bottom: 30px;
+		border-style: solid;
+		border-width: 1px;
+		border-color: #5989b9;
+		border-radius: 5px;
+		transition: opacity 0.3;
+		opacity: 0;
+	}
+
+	.uni-fab--active {
+		opacity: 1;
+	}
+
+	.uni-fab--leftBottom {
+		left: 15px;
+		bottom: 30px;
+	}
+
+	.uni-fab--leftTop {
+		left: 15px;
+		top: 40px;
+		/* #ifdef H5 */
+		top: calc(40px + var(--window-top));
+		/* #endif */
+	}
+
+	.uni-fab--rightBottom {
+		right: 15px;
+		bottom: 30px;
+	}
+
+	.uni-fab--rightTop {
+		right: 15px;
+		top: 40px;
+		/* #ifdef H5 */
+		top: calc(40px + var(--window-top));
+		/* #endif */
+	}
+
+	.uni-fab__circle {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		width: 55px;
+		height: 55px;
+		background-color: #3c3e49;
+		border-radius: 55px;
+		z-index: 11;
+	}
+
+	.uni-fab__circle--left {
+		left: 0;
+	}
+
+	.uni-fab__circle--right {
+		right: 0;
+	}
+
+	.uni-fab__circle--top {
+		top: 0;
+	}
+
+	.uni-fab__circle--bottom {
+		bottom: 0;
+	}
+
+	.uni-fab__plus {
+		transform: rotate(0deg);
+		transition: transform 0.3s;
+		font-weight: bold;
+	}
+
+	.uni-fab__plus--active {
+		transform: rotate(135deg);
+	}
+
+	.fab-circle-v {
+		position: absolute;
+		width: 3px;
+		height: 31px;
+		left: 26px;
+		top: 12px;
+		background-color: white;
+	}
+
+	.fab-circle-h {
+		position: absolute;
+		width: 31px;
+		height: 3px;
+		left: 12px;
+		top: 26px;
+		background-color: white;
+	}
+
+	.uni-fab__content {
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		border-radius: 55px;
+		overflow: hidden;
+		transition-property: width, height;
+		transition-duration: 0.2s;
+		width: 55px;
+		border-color: #DDDDDD;
+		border-width: 1rpx;
+		border-style: solid;
+	}
+
+	.uni-fab__content--other-platform {
+		border-width: 0px;
+		box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.2);
+	}
+
+	.uni-fab__content--left {
+		justify-content: flex-start;
+	}
+
+	.uni-fab__content--right {
+		justify-content: flex-end;
+	}
+
+	.uni-fab__content--flexDirection {
+		flex-direction: column;
+		justify-content: flex-end;
+	}
+
+	.uni-fab__content--flexDirectionStart {
+		flex-direction: column;
+		justify-content: flex-start;
+	}
+
+	.uni-fab__content--flexDirectionEnd {
+		flex-direction: column;
+		justify-content: flex-end;
+	}
+
+	.uni-fab__item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 55px;
+		height: 55px;
+		opacity: 0;
+		transition: opacity 0.2s;
+	}
+
+	.uni-fab__item--active {
+		opacity: 1;
+	}
+
+	.uni-fab__item-image {
+		width: 25px;
+		height: 25px;
+		margin-bottom: 3px;
+	}
+
+	.uni-fab__item-text {
+		color: #FFFFFF;
+		font-size: 12px;
+	}
+
+	.uni-fab__item--first {
+		width: 55px;
+	}
+</style>

+ 361 - 0
components/round-menu/round-menu.vue

@@ -0,0 +1,361 @@
+<template>
+	<view>
+		<view class="round-mask" v-if="isShow"  @click="_onClick"></view>
+		<view class="uni-menu--rightBottom uni-round-menu ">
+		
+			<view style="position: absolute;left: 6px;top: 6px; width: 200px;height: 200px; ">
+				<view :class="{'uni-menu-bg--active':isShow}" class="uni-menu-white-bg"></view>
+				<view :class="{'uni-menu-bg--active':isShow}" class="uni-menu-blue-bg"></view>
+				<view :class="{'uni-menu--close':!isShow}" class="uni-menu-content">
+			
+					<view v-for="(item, index) in content" :key="index" class="surround-box">
+					
+						<view class="circle-line"></view>
+						<view class="circle" :style="{'--rotate':item.rotate}" @click="_onItemClick(index, item)">
+							<view class="chircle-item">
+								<image style="width: 20px;height: 20px;" :src="item.iconPath"></image>
+								<view style="font-size: 11px; line-height: 15px; ">{{item.text}}</view>
+							</view>
+						</view>
+					</view>
+			
+				</view>
+			</view>
+			
+			<view style="position: absolute;left: 6px;top: 6px;width: 100px;height: 100px;">
+				<view :class="{'uni-click-white-bg':!isShow}"></view>
+				<view class="uni-click-grey-bg" :class="{'uni-click-bg-menu':!isShow}"></view>
+				<view v-if="isShow" class="uni-click__circle " @click="_onClick">
+					<view class="click-circle-v"></view>
+					<view class="click-circle-h"></view>
+				</view>
+				<view v-else class="uni-click__image" @click="_onClick">
+					<image style="width: 30px;height: 30px;" src="/static/round-menu/menu.png"></image>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			middleIcon: {
+				type: String,
+				default: ''
+			},
+			// content: {
+			// 	type: Array,
+			// 	default () {
+			// 		return []
+			// 	}
+			// },
+		},
+		data() {
+			return {
+				isShow: false,
+				// 按钮
+				content: [
+					{
+						iconPath: '/static/round-menu/home.png',
+						text: '首页',
+						rotate: "155deg",
+						type:'persnal'
+					},{
+						iconPath: '/static/round-menu/video.png',
+						text: '娱乐',
+						rotate: "115deg",
+						type:'game'
+					}
+				]
+			}
+		},
+		methods: {
+			_onClick() {
+				// console.log("_onClick");
+				this.isShow = !this.isShow
+			},
+			open() {
+				this.isShow = true
+			},
+			close() {
+				this.isShow = false
+			},
+			/**
+			 * 按钮点击事件
+			 */
+			_onItemClick(index, item) {
+				// console.log(index, item);
+				this.close();
+				this.$emit('trigger', {
+					index,
+					item
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	* {
+		margin: 0;
+		padding: 0;
+		box-sizing: border-box;
+	}
+
+	.round-mask{
+		position: fixed;
+		background-color: rgba(0,0,0,0.3);
+		left: 0;
+		top: 0;
+		bottom: 0;
+		right: 0;
+		width: 100%;
+		height: 100%;
+		z-index: 999;
+		/* pointer-events: none; */
+	}
+
+
+	.uni-round-menu {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		z-index: 1000;
+
+		width: 106px;
+		height: 106px;
+		/* background-color: #3c3e49; */
+		pointer-events: none;
+		overflow: hidden;
+		
+	}
+
+	.uni-menu--rightBottom {
+		right: 0;
+		bottom: 0;
+	}
+
+	.uni-menu--leftTop {
+		left: 100px;
+		top: 200px;
+	}
+	.uni-menu-blue-bg {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		width: 200px;
+		height: 200px;
+		background: #ffffff;
+		box-sizing: border-box;
+		border: 50px solid #33bdfb;
+		border-radius: 50%;
+		opacity: 0;
+		transition: opacity 0.2s;
+	}
+	.uni-menu-white-bg {
+		position: absolute;
+		right: -4px;
+		bottom:-4px;
+		width: 208px;
+		height: 208px;
+		background: #ffffff;
+		box-sizing: border-box;
+		border: 50px solid #ffffff;
+		border-radius: 50%;
+		/* border-color: #ffc107;
+		border-bottom: 60px solid transparent;
+		border-left: 60px solid #99edd1;
+		border-top: 60px solid transparent;
+		border-right: 60px solid transparent;
+		border-radius: 100% 0 0 0; */
+		opacity: 0;
+		transition: opacity 0.2s;
+		box-shadow:0px 0px 5px #888888;
+	}
+
+	.uni-menu-bg--active {
+		opacity: 1;
+	}
+
+	.uni-menu-content {
+		position: absolute;
+		z-index: 20;
+		width: 200px;
+		height: 200px;
+		display: flex;
+		transform: rotate(0);
+		transition: transform 0.2s;
+
+	}
+
+	.uni-menu--close {
+		transform: rotate(100deg);
+	}
+
+	
+
+	.uni-click-white-bg {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		width: 50px;
+		height: 50px;
+		border-radius: 100% 0 0 0;
+		border: 2px solid rgba(255,255,255,0.5);
+		box-shadow:0px 0px 5px #888888;
+	}
+
+	.uni-click-grey-bg {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		z-index: 11;
+		width: 48px;
+		height: 48px;
+		border-radius: 100% 0 0 0;
+		background-color: rgba(0, 0, 0, 0.3);
+		transition: background-color 0.2s;
+	}
+
+	.uni-click-bg-menu {
+		background-color: rgba(117, 117, 249, 255);
+	}
+
+	.uni-click__circle {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		width: 55px;
+		height: 55px;
+		z-index: 30;
+		transform: rotate(135deg) scale(0.5) translateY(-20px);
+		pointer-events: all;
+	}
+
+	.uni-click__image {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		right: -8px;
+		bottom: -2px;
+		width: 55px;
+		height: 55px;
+		z-index: 29;
+		transform: scale(0.5) translateY(10px);
+		pointer-events: all;
+	}
+
+	.click-circle-v {
+		position: absolute;
+		width: 3px;
+		height: 31px;
+		left: 26px;
+		top: 12px;
+		background-color: white;
+	}
+
+	.click-circle-h {
+		position: absolute;
+		width: 31px;
+		height: 3px;
+		left: 12px;
+		top: 26px;
+		background-color: white;
+	}
+
+	.uni-fab__item--active {
+		opacity: 1;
+	}
+
+	.uni-content__item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 55px;
+		height: 55px;
+		opacity: 1;
+		/* transition: opacity 0.2s; */
+	}
+
+	.content-child {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 40px;
+		height: 40px;
+		line-height: 40px;
+		border-radius: 50%;
+		text-align: center;
+		color: #fff;
+		/* border: 1rpx solid #000000; */
+		background-color: red;
+		transform: rotateZ(var(--rotate)) translateY(80px);
+	}
+
+
+
+
+	.surround-box {
+		position: absolute;
+		top: 50%;
+		left: 50%;
+		width: 20px;
+		height: 20px;
+		margin-left: -10px;
+		margin-top: -10px;
+		border-radius: 50%;
+		z-index: 50;
+		/* background-color: #000; */
+	}
+
+	.circle {
+		/* 这里一定要绝对定位,这样位置才能铺开来 */
+		position: absolute;
+		top: -10px;
+		left: -10px;
+		width: 40px;
+		height: 40px;
+		line-height: 40px;
+		border-radius: 50%;
+		text-align: center;
+		z-index: 50;
+		color: #fff;
+		transform: rotateZ(var(--rotate)) translateY(80px);
+		pointer-events: all;
+	}
+
+	.circle-line {
+		position: absolute;
+		top: -15px;
+		left: 10px;
+		width: 1px;
+		height: 50px;
+		text-align: center;
+		background-image: linear-gradient(to top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1));
+		color: #fff;
+		transform: rotateZ(135deg) translateY(80px);
+	}
+
+	.chircle-item {
+		transform: rotate(180deg);
+		display: flex;
+		justify-content: center;
+		flex-direction: column;
+		align-items: center;
+	}
+</style>

+ 79 - 0
components/side-bar/mp.js

@@ -0,0 +1,79 @@
+export default {
+	data() {
+		return {
+			position: [],
+		}
+	},
+	computed: {
+		pos() {
+			return JSON.stringify(this.position)
+		}
+	},
+	watch: {
+		show(newVal) {
+			let valueObj = this.position[0]
+			if (!valueObj) return
+			valueObj.show = newVal
+			valueObj.once_change = true;
+			// console.log("show newVal:",newVal);
+			this.$set(this.position, 0, valueObj)
+		}
+	},
+	mounted() {
+		this.init()
+		setTimeout(()=>{
+			this.getSize()
+		},50)
+	
+	},
+	methods: {
+		init() {
+			//多个页面监听到这个方法时候,需要 判断是不是this
+			uni.$on('__uni__swipe__event', (res) => {
+				if (res !== this) {
+					let valueObj = this.position[0]
+					valueObj.show = false
+					this.$set(this.position, 0, valueObj)
+					
+				}else{
+					//如果是自己,设置bshow
+					this.bshow = true;
+					// console.log("__uni__swipe__event",this.show);
+				}
+				// this.bshow = true;
+			})
+			//开始设置隐藏
+			this.show = false
+		},
+		openSwipe() {
+			uni.$emit('__uni__swipe__event', this)
+		},
+		change(e) {
+			// this.$emit('change', e.close)
+			let valueObj = this.position[0]
+			valueObj.show = !e.close
+			valueObj.once_change = false;
+			// console.log("e.close:",e.close);
+			this.$set(this.position, 0, valueObj)
+			// console.log('改变', e);
+		},
+		onClick(index, item) {
+			this.$emit('click', {
+				content: item,
+				index
+			})
+		},
+		getSize() {
+			const views = uni.createSelectorQuery().in(this)
+			views
+				.selectAll('.selector-query-hock')
+				.boundingClientRect(data => {
+					data[0].show = false
+					data[0].once_change = false;
+					data[0].bInit = true;
+					this.position = data
+				})
+				.exec()
+		}
+	}
+}

+ 337 - 0
components/side-bar/side-bar.vue

@@ -0,0 +1,337 @@
+<template>
+	<!-- @touchmove.stop.prevent="moveHandle" -->
+	<view class="content">
+		<view class="side-left" :data-position="pos" :prop="pos" :change:prop="side.sizeReady" @touchstart="side.touchstart"
+		 @touchmove="side.touchmove" @touchend="side.touchend" @change="change">
+			<!-- 侧边栏 bshow-->
+			<view class="side-mask" v-if="bshow" @tap="closeSide"></view>
+			<view class="side-handle">
+				<view id="my-side-dialog" class="basis-xl bg-white selector-query-hock" :class="bOpen?'side-pointer':''" @tap.stop="">
+					<scroll-view scroll-y="true" class="selector-query-hock" style="height: 100%;width: 100%;">
+						<view class="cu-list menu text-left ">
+							<view class="bg-image text-white" style="margin-bottom: 60rpx; padding-bottom: 60rpx;">
+								<view class="blank-space"></view>
+								<view class="flex-sub text-center">
+									<view class="cu-avatar-group" style="position: relative; margin: 10rpx;">
+										<view class="cu-avatar round " style="width: 146rpx;height: 146rpx;" :style="[{ backgroundImage:'url('+avatarUrl+')' }]"></view>
+
+									</view>
+
+									<!-- <view class="text-xsl">
+										<image class="avatar-img bg-black" mode="aspectFit" :src="avatarUrl"></image>
+									</view> -->
+									<view class="flex justify-center align-center" @tap="onNavEditInfoPage">
+										<view style="font-weight: bold; color: #000000; font-size: 22px;">{{userName}}</view>
+										<image style="width: 34rpx;height: 34rpx; margin-left: 22rpx;" src="/static/sideEdit.png"></image>
+									</view>
+								</view>
+								<view class="flex flex-direction justify-center align-center">
+									<view class="bg-days margin">{{days}}天</view>
+									<view class="text-more text-gray">
+										{{signature!=='null'?signature:''}}
+									</view>
+								</view>
+
+							</view>
+
+							<view class="cu-item myarrow margin-view" v-for="(item,index) in sideList" :key="index" @tap="onNavListItem(item.page_type)">
+								<view class="content flex align-center margin-top margin-bottom">
+									<image :src="item.url" style="width: 34rpx;width: 34rpx; margin-bottom: 2rpx;margin-right:44rpx;" mode="aspectFit"></image>
+									<text class="text-black text-16px text-bold">{{item.name}}</text>
+								</view>
+
+							</view>
+
+							<view class="flex justify-center align-center " style="margin: 60px 0px;">
+								<button class="cu-btn round text-16px line-mGrey" style="width: 250rpx; height: 80rpx;" @tap="onExit"> <span
+									 style="color:#000000;">退出登录</span> </button>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script src="./side-wxs.wxs" module="side" lang="wxs"></script>
+<script>
+	import sideBarData from '@/components/side-bar/sideBar.js';
+	import config from '@/common/config.js'
+	import reqUtil from '@/util/util-js/requstUtil.js';
+	import mp from './mp'
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+
+	export default {
+		mixins: [mp],
+
+		computed: mapState(['bCanvasShow', 'token', 'userName', 'avatarUrl', 'days', 'signature', 'weight',
+			'height'
+		]),
+
+
+
+		data() {
+			return {
+				sideList: sideBarData.getSideBarList,
+				bshow: false,
+				bOpen: false,
+				left: 0,
+				/**
+				 * 变量控制开关
+				 */
+				show: {
+					type: Boolean,
+					default: false
+				}
+			}
+		},
+		mounted() {
+			// console.log("******",this.bshow);
+		},
+		methods: {
+			...mapMutations(['loginUserInfo', 'onLuanchLogin', 'delectToken']),
+			// 跳转我的页面
+			onNavMyPage() {
+				uni.navigateTo({
+					url: '../../my-page/homepage/homepage',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+
+			},
+			// 跳转编辑信息页面
+			onNavEditInfoPage() {
+				uni.navigateTo({
+					url: '../../my-page/userInfo/userInfo',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			//侧边栏对应页面跳转
+			onNavListItem(pageType) {
+				// console.log(pageType);
+				if (pageType == "my") {
+					this.onNavMyPage();
+					return;
+				}
+				// return;
+				let url = '';
+				switch (pageType) {
+					case "recently":
+					case "watchGame":
+						url = '/pages/personal-page/list/list?type=' + pageType;
+						break;
+					case "ranking":
+						url = '/pages/game-page/game-ranking/game-ranking';
+						break;
+					case "feedback":
+						url = '/pages/login-page/feedback/feedback';
+						break;
+				}
+				uni.navigateTo({
+					url: url,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+			/**
+			 * 退出登录
+			 */
+			onExit() {
+				console.log("退出登录");
+				// 清除token,退回首页
+				this.delectToken({
+					success: (res) => {
+						uni.reLaunch({
+							url: '../../login-page/login/login'
+						})
+					}
+				});
+			},
+
+			showModal() {
+				// console.log("showModal:",this.show);
+				this.bshow = true;
+				this.show = true;
+			},
+			hideModal() {
+				// console.log("hideModal");
+				this.bshow = false;
+				this.show = false;
+				this.$store.state.bCanvasShow = true;
+				this.$emit("hideSideBar");
+			},
+
+			change(e) {
+				// console.log("side change:", e);
+
+				if (e.close) {
+					this.hideModal();
+					this.bOpen = false;
+				} else {
+					this.bOpen = true;
+					this.show = true;
+				}
+			},
+			closeSide() {
+				if (!this.bOpen) return;
+				// console.log("close side.");
+				this.show = false;
+			},
+			moveHandle() {}
+		}
+	}
+</script>
+
+<style>
+	.blank-space {
+		height: 150rpx;
+	}
+
+	.bg-image {
+		background-size: cover;
+		background-position: center;
+		background-repeat: no-repeat;
+		background-image: url(../../static/sidebar_white.png);
+		opacity: 1;
+	}
+
+	.bg-days {
+		background-size: cover;
+		background-position: center;
+		background-repeat: no-repeat;
+		background-image: url(../../static/bg-days.png);
+		opacity: 1;
+		width: 126rpx;
+		height: 48rpx;
+		font-size: 11px;
+		line-height: 48rpx;
+		text-align: right;
+		padding-right: 14rpx;
+	}
+
+	.avatar-img {
+		width: 146rpx;
+		height: 146rpx;
+		/* border: 8rpx solid rgba(255, 255, 255, 1); */
+		border-radius: 50%;
+	}
+
+	.text-more {
+		/* width: 200px; */
+		font-size: 12px;
+		line-height: 20px;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box; //必须结合的属性,将对象作为弹性伸缩盒子模型显示
+		-webkit-line-clamp: 2; //控制文本的行数
+		-webkit-box-orient: vertical; //必须结合的属性,设置或检索伸缩盒对象的子元素的排列方式 
+		/* border: 1rpx solid #aaa; */
+	}
+
+	.text-cut {
+		font-size: 14px;
+		line-height: 30px;
+		width: 100px;
+		height: 100px;
+		/* font-weight: bold; */
+		border: 1rpx solid #aaa;
+		display: -webkit-box;
+		/* 允许任意非CJK(Chinese/Japanese/Korean)文本间的单词断行 */
+		word-break: break-all;
+		/* 设置或检索伸缩盒对象的子元素的排列方式 */
+		-webkit-box-orient: vertical;
+		/* 可显示的最多行数 */
+		-webkit-line-clamp: 2;
+		/* 超出的文本内容隐藏 */
+		overflow: hidden;
+		/* 超出显示省略号 */
+		text-overflow: ellipsis;
+		/* background: rgba(0, 0, 0, 0.3); */
+	}
+
+	.margin-view {
+		margin: 10px 114rpx 10px 70rpx;
+	}
+
+	.side-mask {
+		display: flex;
+		position: fixed;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		z-index: 1100;
+		outline: 0;
+		text-align: center;
+		overflow-x: hidden;
+		overflow-y: auto;
+		backface-visibility: hidden;
+		background: rgba(0, 0, 0, 0.6);
+		opacity: 1;
+		pointer-events: auto;
+	}
+
+	.side-handle {
+		display: flex;
+		position: fixed;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		z-index: 1110;
+		outline: 0;
+		text-align: center;
+		backface-visibility: hidden;
+		opacity: 1;
+		pointer-events: none;
+	}
+
+	.side-opacity {
+		opacity: 1;
+	}
+
+	.side-pointer {
+		pointer-events: auto;
+	}
+
+	/* .side-handle::before {
+		content: "\200B";
+		display: inline-block;
+		height: 100%;
+		vertical-align: middle;
+	} */
+
+
+	.side-left {
+		position: absolute;
+		left: 0;
+		top: 0;
+		display: flex;
+		/* border: 1rpx solid #007AFF; */
+		width: 10px;
+		height: 100%;
+		z-index: 1110;
+	}
+
+
+	.ani {
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
+	}
+
+	/* 开始设置一个x偏移值 */
+	#my-side-dialog {
+		transform: translateX(-500px);
+		-webkit-transform: translateX(-500px)
+	}
+</style>

+ 171 - 0
components/side-bar/side-wxs.wxs

@@ -0,0 +1,171 @@
+/**
+ * 监听页面内值的变化,主要用于动态开关swipe-action
+ * @param {Object} newValue
+ * @param {Object} oldValue
+ * @param {Object} ownerInstance
+ * @param {Object} instance
+ */
+function sizeReady(newValue, oldValue, ownerInstance, instance) {
+	var state = instance.getState()
+	state.position = JSON.parse(newValue)
+	if (!state.position || state.position.length === 0) return
+	var show = state.position[0].show
+	var onceChange = state.position[0].once_change;
+	state.left = state.left || state.position[0].left;
+	//初始化 bMove
+	state.bMove = false;
+	// 通过用户变量,开启或关闭
+	// console.log("sizeReady",onceChange,show,state);
+	if(state.position[0].bInit){
+		var x = -state.position[0].width;
+		var test = ownerInstance.selectComponent('#my-side-dialog');
+		test.setStyle({
+			transform: 'translateX(' + x + 'px)',
+			'-webkit-transform': 'translateX(' + x + 'px)'
+		})
+		state.left = x;
+		// #my-side-dialog 设置 -500px ,这里要重置为0
+		state.position[0].left = 0;
+		state.position[0].bInit = false;
+	}
+	if(!onceChange)return;
+	if (show) {
+		openState(false, instance, ownerInstance)
+	} else {
+		openState(true, instance, ownerInstance)
+	}
+}
+
+/**
+ * 开始触摸操作
+ * @param {Object} e
+ * @param {Object} ins
+ */
+function touchstart(e, ins) {
+	var instance = e.instance;
+	var state = instance.getState();
+	var pageX = e.touches[0].pageX;
+	
+	//触发一次
+	if(state.bMove)return;
+	state.bMove = true;
+	
+	state.left = state.left || state.position[0].left;
+	// console.log(state);
+	// 获取最终按钮组的宽度
+	state.width = pageX - state.left;
+	// console.log("width:",pageX,state.left,state.position[0].left);
+	ins.callMethod('openSwipe')
+	var test = instance.selectComponent('#my-side-dialog');
+	test.removeClass('ani');
+	
+}
+
+/**
+ * 开始滑动操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchmove(e, ownerInstance) {
+	var instance = e.instance;
+	var state = instance.getState()
+	var pageX = e.touches[0].pageX;
+	
+	if(!state.bMove)return;
+	move(pageX - state.width, instance, ownerInstance)
+}
+
+/**
+ * 结束触摸操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchend(e, ownerInstance) {
+	var instance = e.instance;
+	var state = instance.getState();
+	
+	if(!state.bMove)return;
+	state.bMove = false;
+	// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
+	moveDirection(state.left, -200, instance, ownerInstance);
+}
+
+/**-
+ * 设置移动距离
+ * @param {Object} value
+ * @param {Object} instance
+ * @param {Object} ownerInstance
+ */
+function move(value, instance, ownerInstance) {
+	var state = instance.getState()
+	// 获取可滑动范围
+	var x = Math.max(-state.position[0].width, Math.min((value), 0));
+	// console.log(x);
+	state.left = x;
+	var test = ownerInstance.selectComponent('#my-side-dialog');
+	test.setStyle({
+		transform: 'translateX(' + x + 'px)',
+		'-webkit-transform': 'translateX(' + x + 'px)'
+	})
+	
+}
+
+/**
+ * 移动方向判断
+ * @param {Object} left
+ * @param {Object} value
+ * @param {Object} ownerInstance
+ * @param {Object} ins
+ */
+function moveDirection(left, value, ins, ownerInstance) {
+	var state = ins.getState()
+	var position = state.position
+	var isclose = state.isclose
+	// 如果是关闭状态,进行判断是否打开,还是保留关闭状态
+	if (isclose) {
+		if (left >= value) {
+			openState(false, ins, ownerInstance)
+		} else {
+			openState(true, ins, ownerInstance)
+		}
+		return
+	}
+	// 如果已经是打开状态,进行判断是否关闭,还是保留打开状态
+	if (left <= value) {
+		openState(true, ins, ownerInstance)
+	} else {
+		openState(false, ins, ownerInstance)
+	}
+	
+}
+
+/**
+ * 开启状态
+ * @param {Boolean} type
+ * @param {Object} ins
+ * @param {Object} ownerInstance
+ */
+function openState(type, ins, ownerInstance) {
+	var state = ins.getState()
+	var position = state.position
+	// 设置打开和移动状态
+	state.isclose = type
+	// console.log("openState",type);
+	// 通知页面,已经打开
+	ownerInstance.callMethod('change', {
+		close: type
+	})
+	// 添加动画类
+	var test = ownerInstance.selectComponent('#my-side-dialog');
+	test.addClass('ani');
+	// 设置最终移动位置
+	move(type ? -position[0].width : 0, ins, ownerInstance)
+
+}
+
+module.exports = {
+	sizeReady: sizeReady,
+	touchstart: touchstart,
+	touchmove: touchmove,
+	touchend: touchend
+}

+ 55 - 0
components/side-bar/sideBar.js

@@ -0,0 +1,55 @@
+// picker组件数据信息
+
+
+export default {
+	//侧边栏对应列表
+	getSideBarList: [{
+		id: 0,
+		type: 'image',
+		url: '/static/item-my.png',
+		name: "我的",
+		page_type: "my",
+	}, {
+		id: 1,
+		type: 'image',
+		url: '/static/recently-playing.png',
+		name: "最近在玩",
+		page_type: "recently",
+	}, {
+		id: 2,
+		type: 'image',
+		url: '/static/watch-game.png',
+		name: '关注',
+		page_type: "watchGame",
+	},
+	// {
+	// 	id: 3,
+	// 	type: 'image',
+	// 	url: '/static/focus-video.png',
+	// 	name: '关注视频',
+	// 	page_type: "focusVideo",
+	// }, 
+	{
+		id: 4,
+		type: 'image',
+		url: '/static/ranking.png',
+		name: '排行榜',
+		page_type: "ranking",
+	}
+	 ,
+	// {
+	// 	id: 5,
+	// 	type: 'image',
+	// 	url: '/static/qrscan.png',
+	// 	name: '扫一扫',
+	// 	page_type: "QRCode",
+	// },
+	{
+		id: 6,
+		type: 'image',
+		url: '/static/feedback@2x.png',
+		name: '意见反馈',
+		page_type: "feedback",
+	}
+	]
+}

+ 12545 - 0
components/slambb-picker/city-data/area.js

@@ -0,0 +1,12545 @@
+/* eslint-disable */
+var areaData = [
+  [
+    [{
+        "label": "东城区",
+        "value": "110101"
+      },
+      {
+        "label": "西城区",
+        "value": "110102"
+      },
+      {
+        "label": "朝阳区",
+        "value": "110105"
+      },
+      {
+        "label": "丰台区",
+        "value": "110106"
+      },
+      {
+        "label": "石景山区",
+        "value": "110107"
+      },
+      {
+        "label": "海淀区",
+        "value": "110108"
+      },
+      {
+        "label": "门头沟区",
+        "value": "110109"
+      },
+      {
+        "label": "房山区",
+        "value": "110111"
+      },
+      {
+        "label": "通州区",
+        "value": "110112"
+      },
+      {
+        "label": "顺义区",
+        "value": "110113"
+      },
+      {
+        "label": "昌平区",
+        "value": "110114"
+      },
+      {
+        "label": "大兴区",
+        "value": "110115"
+      },
+      {
+        "label": "怀柔区",
+        "value": "110116"
+      },
+      {
+        "label": "平谷区",
+        "value": "110117"
+      },
+      {
+        "label": "密云区",
+        "value": "110118"
+      },
+      {
+        "label": "延庆区",
+        "value": "110119"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "和平区",
+        "value": "120101"
+      },
+      {
+        "label": "河东区",
+        "value": "120102"
+      },
+      {
+        "label": "河西区",
+        "value": "120103"
+      },
+      {
+        "label": "南开区",
+        "value": "120104"
+      },
+      {
+        "label": "河北区",
+        "value": "120105"
+      },
+      {
+        "label": "红桥区",
+        "value": "120106"
+      },
+      {
+        "label": "东丽区",
+        "value": "120110"
+      },
+      {
+        "label": "西青区",
+        "value": "120111"
+      },
+      {
+        "label": "津南区",
+        "value": "120112"
+      },
+      {
+        "label": "北辰区",
+        "value": "120113"
+      },
+      {
+        "label": "武清区",
+        "value": "120114"
+      },
+      {
+        "label": "宝坻区",
+        "value": "120115"
+      },
+      {
+        "label": "滨海新区",
+        "value": "120116"
+      },
+      {
+        "label": "宁河区",
+        "value": "120117"
+      },
+      {
+        "label": "静海区",
+        "value": "120118"
+      },
+      {
+        "label": "蓟州区",
+        "value": "120119"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "长安区",
+        "value": "130102"
+      },
+      {
+        "label": "桥西区",
+        "value": "130104"
+      },
+      {
+        "label": "新华区",
+        "value": "130105"
+      },
+      {
+        "label": "井陉矿区",
+        "value": "130107"
+      },
+      {
+        "label": "裕华区",
+        "value": "130108"
+      },
+      {
+        "label": "藁城区",
+        "value": "130109"
+      },
+      {
+        "label": "鹿泉区",
+        "value": "130110"
+      },
+      {
+        "label": "栾城区",
+        "value": "130111"
+      },
+      {
+        "label": "井陉县",
+        "value": "130121"
+      },
+      {
+        "label": "正定县",
+        "value": "130123"
+      },
+      {
+        "label": "行唐县",
+        "value": "130125"
+      },
+      {
+        "label": "灵寿县",
+        "value": "130126"
+      },
+      {
+        "label": "高邑县",
+        "value": "130127"
+      },
+      {
+        "label": "深泽县",
+        "value": "130128"
+      },
+      {
+        "label": "赞皇县",
+        "value": "130129"
+      },
+      {
+        "label": "无极县",
+        "value": "130130"
+      },
+      {
+        "label": "平山县",
+        "value": "130131"
+      },
+      {
+        "label": "元氏县",
+        "value": "130132"
+      },
+      {
+        "label": "赵县",
+        "value": "130133"
+      },
+      {
+        "label": "石家庄高新技术产业开发区",
+        "value": "130171"
+      },
+      {
+        "label": "石家庄循环化工园区",
+        "value": "130172"
+      },
+      {
+        "label": "辛集市",
+        "value": "130181"
+      },
+      {
+        "label": "晋州市",
+        "value": "130183"
+      },
+      {
+        "label": "新乐市",
+        "value": "130184"
+      }
+    ],
+    [{
+        "label": "路南区",
+        "value": "130202"
+      },
+      {
+        "label": "路北区",
+        "value": "130203"
+      },
+      {
+        "label": "古冶区",
+        "value": "130204"
+      },
+      {
+        "label": "开平区",
+        "value": "130205"
+      },
+      {
+        "label": "丰南区",
+        "value": "130207"
+      },
+      {
+        "label": "丰润区",
+        "value": "130208"
+      },
+      {
+        "label": "曹妃甸区",
+        "value": "130209"
+      },
+      {
+        "label": "滦县",
+        "value": "130223"
+      },
+      {
+        "label": "滦南县",
+        "value": "130224"
+      },
+      {
+        "label": "乐亭县",
+        "value": "130225"
+      },
+      {
+        "label": "迁西县",
+        "value": "130227"
+      },
+      {
+        "label": "玉田县",
+        "value": "130229"
+      },
+      {
+        "label": "唐山市芦台经济技术开发区",
+        "value": "130271"
+      },
+      {
+        "label": "唐山市汉沽管理区",
+        "value": "130272"
+      },
+      {
+        "label": "唐山高新技术产业开发区",
+        "value": "130273"
+      },
+      {
+        "label": "河北唐山海港经济开发区",
+        "value": "130274"
+      },
+      {
+        "label": "遵化市",
+        "value": "130281"
+      },
+      {
+        "label": "迁安市",
+        "value": "130283"
+      }
+    ],
+    [{
+        "label": "海港区",
+        "value": "130302"
+      },
+      {
+        "label": "山海关区",
+        "value": "130303"
+      },
+      {
+        "label": "北戴河区",
+        "value": "130304"
+      },
+      {
+        "label": "抚宁区",
+        "value": "130306"
+      },
+      {
+        "label": "青龙满族自治县",
+        "value": "130321"
+      },
+      {
+        "label": "昌黎县",
+        "value": "130322"
+      },
+      {
+        "label": "卢龙县",
+        "value": "130324"
+      },
+      {
+        "label": "秦皇岛市经济技术开发区",
+        "value": "130371"
+      },
+      {
+        "label": "北戴河新区",
+        "value": "130372"
+      }
+    ],
+    [{
+        "label": "邯山区",
+        "value": "130402"
+      },
+      {
+        "label": "丛台区",
+        "value": "130403"
+      },
+      {
+        "label": "复兴区",
+        "value": "130404"
+      },
+      {
+        "label": "峰峰矿区",
+        "value": "130406"
+      },
+      {
+        "label": "肥乡区",
+        "value": "130407"
+      },
+      {
+        "label": "永年区",
+        "value": "130408"
+      },
+      {
+        "label": "临漳县",
+        "value": "130423"
+      },
+      {
+        "label": "成安县",
+        "value": "130424"
+      },
+      {
+        "label": "大名县",
+        "value": "130425"
+      },
+      {
+        "label": "涉县",
+        "value": "130426"
+      },
+      {
+        "label": "磁县",
+        "value": "130427"
+      },
+      {
+        "label": "邱县",
+        "value": "130430"
+      },
+      {
+        "label": "鸡泽县",
+        "value": "130431"
+      },
+      {
+        "label": "广平县",
+        "value": "130432"
+      },
+      {
+        "label": "馆陶县",
+        "value": "130433"
+      },
+      {
+        "label": "魏县",
+        "value": "130434"
+      },
+      {
+        "label": "曲周县",
+        "value": "130435"
+      },
+      {
+        "label": "邯郸经济技术开发区",
+        "value": "130471"
+      },
+      {
+        "label": "邯郸冀南新区",
+        "value": "130473"
+      },
+      {
+        "label": "武安市",
+        "value": "130481"
+      }
+    ],
+    [{
+        "label": "桥东区",
+        "value": "130502"
+      },
+      {
+        "label": "桥西区",
+        "value": "130503"
+      },
+      {
+        "label": "邢台县",
+        "value": "130521"
+      },
+      {
+        "label": "临城县",
+        "value": "130522"
+      },
+      {
+        "label": "内丘县",
+        "value": "130523"
+      },
+      {
+        "label": "柏乡县",
+        "value": "130524"
+      },
+      {
+        "label": "隆尧县",
+        "value": "130525"
+      },
+      {
+        "label": "任县",
+        "value": "130526"
+      },
+      {
+        "label": "南和县",
+        "value": "130527"
+      },
+      {
+        "label": "宁晋县",
+        "value": "130528"
+      },
+      {
+        "label": "巨鹿县",
+        "value": "130529"
+      },
+      {
+        "label": "新河县",
+        "value": "130530"
+      },
+      {
+        "label": "广宗县",
+        "value": "130531"
+      },
+      {
+        "label": "平乡县",
+        "value": "130532"
+      },
+      {
+        "label": "威县",
+        "value": "130533"
+      },
+      {
+        "label": "清河县",
+        "value": "130534"
+      },
+      {
+        "label": "临西县",
+        "value": "130535"
+      },
+      {
+        "label": "河北邢台经济开发区",
+        "value": "130571"
+      },
+      {
+        "label": "南宫市",
+        "value": "130581"
+      },
+      {
+        "label": "沙河市",
+        "value": "130582"
+      }
+    ],
+    [{
+        "label": "竞秀区",
+        "value": "130602"
+      },
+      {
+        "label": "莲池区",
+        "value": "130606"
+      },
+      {
+        "label": "满城区",
+        "value": "130607"
+      },
+      {
+        "label": "清苑区",
+        "value": "130608"
+      },
+      {
+        "label": "徐水区",
+        "value": "130609"
+      },
+      {
+        "label": "涞水县",
+        "value": "130623"
+      },
+      {
+        "label": "阜平县",
+        "value": "130624"
+      },
+      {
+        "label": "定兴县",
+        "value": "130626"
+      },
+      {
+        "label": "唐县",
+        "value": "130627"
+      },
+      {
+        "label": "高阳县",
+        "value": "130628"
+      },
+      {
+        "label": "容城县",
+        "value": "130629"
+      },
+      {
+        "label": "涞源县",
+        "value": "130630"
+      },
+      {
+        "label": "望都县",
+        "value": "130631"
+      },
+      {
+        "label": "安新县",
+        "value": "130632"
+      },
+      {
+        "label": "易县",
+        "value": "130633"
+      },
+      {
+        "label": "曲阳县",
+        "value": "130634"
+      },
+      {
+        "label": "蠡县",
+        "value": "130635"
+      },
+      {
+        "label": "顺平县",
+        "value": "130636"
+      },
+      {
+        "label": "博野县",
+        "value": "130637"
+      },
+      {
+        "label": "雄县",
+        "value": "130638"
+      },
+      {
+        "label": "保定高新技术产业开发区",
+        "value": "130671"
+      },
+      {
+        "label": "保定白沟新城",
+        "value": "130672"
+      },
+      {
+        "label": "涿州市",
+        "value": "130681"
+      },
+      {
+        "label": "定州市",
+        "value": "130682"
+      },
+      {
+        "label": "安国市",
+        "value": "130683"
+      },
+      {
+        "label": "高碑店市",
+        "value": "130684"
+      }
+    ],
+    [{
+        "label": "桥东区",
+        "value": "130702"
+      },
+      {
+        "label": "桥西区",
+        "value": "130703"
+      },
+      {
+        "label": "宣化区",
+        "value": "130705"
+      },
+      {
+        "label": "下花园区",
+        "value": "130706"
+      },
+      {
+        "label": "万全区",
+        "value": "130708"
+      },
+      {
+        "label": "崇礼区",
+        "value": "130709"
+      },
+      {
+        "label": "张北县",
+        "value": "130722"
+      },
+      {
+        "label": "康保县",
+        "value": "130723"
+      },
+      {
+        "label": "沽源县",
+        "value": "130724"
+      },
+      {
+        "label": "尚义县",
+        "value": "130725"
+      },
+      {
+        "label": "蔚县",
+        "value": "130726"
+      },
+      {
+        "label": "阳原县",
+        "value": "130727"
+      },
+      {
+        "label": "怀安县",
+        "value": "130728"
+      },
+      {
+        "label": "怀来县",
+        "value": "130730"
+      },
+      {
+        "label": "涿鹿县",
+        "value": "130731"
+      },
+      {
+        "label": "赤城县",
+        "value": "130732"
+      },
+      {
+        "label": "张家口市高新技术产业开发区",
+        "value": "130771"
+      },
+      {
+        "label": "张家口市察北管理区",
+        "value": "130772"
+      },
+      {
+        "label": "张家口市塞北管理区",
+        "value": "130773"
+      }
+    ],
+    [{
+        "label": "双桥区",
+        "value": "130802"
+      },
+      {
+        "label": "双滦区",
+        "value": "130803"
+      },
+      {
+        "label": "鹰手营子矿区",
+        "value": "130804"
+      },
+      {
+        "label": "承德县",
+        "value": "130821"
+      },
+      {
+        "label": "兴隆县",
+        "value": "130822"
+      },
+      {
+        "label": "滦平县",
+        "value": "130824"
+      },
+      {
+        "label": "隆化县",
+        "value": "130825"
+      },
+      {
+        "label": "丰宁满族自治县",
+        "value": "130826"
+      },
+      {
+        "label": "宽城满族自治县",
+        "value": "130827"
+      },
+      {
+        "label": "围场满族蒙古族自治县",
+        "value": "130828"
+      },
+      {
+        "label": "承德高新技术产业开发区",
+        "value": "130871"
+      },
+      {
+        "label": "平泉市",
+        "value": "130881"
+      }
+    ],
+    [{
+        "label": "新华区",
+        "value": "130902"
+      },
+      {
+        "label": "运河区",
+        "value": "130903"
+      },
+      {
+        "label": "沧县",
+        "value": "130921"
+      },
+      {
+        "label": "青县",
+        "value": "130922"
+      },
+      {
+        "label": "东光县",
+        "value": "130923"
+      },
+      {
+        "label": "海兴县",
+        "value": "130924"
+      },
+      {
+        "label": "盐山县",
+        "value": "130925"
+      },
+      {
+        "label": "肃宁县",
+        "value": "130926"
+      },
+      {
+        "label": "南皮县",
+        "value": "130927"
+      },
+      {
+        "label": "吴桥县",
+        "value": "130928"
+      },
+      {
+        "label": "献县",
+        "value": "130929"
+      },
+      {
+        "label": "孟村回族自治县",
+        "value": "130930"
+      },
+      {
+        "label": "河北沧州经济开发区",
+        "value": "130971"
+      },
+      {
+        "label": "沧州高新技术产业开发区",
+        "value": "130972"
+      },
+      {
+        "label": "沧州渤海新区",
+        "value": "130973"
+      },
+      {
+        "label": "泊头市",
+        "value": "130981"
+      },
+      {
+        "label": "任丘市",
+        "value": "130982"
+      },
+      {
+        "label": "黄骅市",
+        "value": "130983"
+      },
+      {
+        "label": "河间市",
+        "value": "130984"
+      }
+    ],
+    [{
+        "label": "安次区",
+        "value": "131002"
+      },
+      {
+        "label": "广阳区",
+        "value": "131003"
+      },
+      {
+        "label": "固安县",
+        "value": "131022"
+      },
+      {
+        "label": "永清县",
+        "value": "131023"
+      },
+      {
+        "label": "香河县",
+        "value": "131024"
+      },
+      {
+        "label": "大城县",
+        "value": "131025"
+      },
+      {
+        "label": "文安县",
+        "value": "131026"
+      },
+      {
+        "label": "大厂回族自治县",
+        "value": "131028"
+      },
+      {
+        "label": "廊坊经济技术开发区",
+        "value": "131071"
+      },
+      {
+        "label": "霸州市",
+        "value": "131081"
+      },
+      {
+        "label": "三河市",
+        "value": "131082"
+      }
+    ],
+    [{
+        "label": "桃城区",
+        "value": "131102"
+      },
+      {
+        "label": "冀州区",
+        "value": "131103"
+      },
+      {
+        "label": "枣强县",
+        "value": "131121"
+      },
+      {
+        "label": "武邑县",
+        "value": "131122"
+      },
+      {
+        "label": "武强县",
+        "value": "131123"
+      },
+      {
+        "label": "饶阳县",
+        "value": "131124"
+      },
+      {
+        "label": "安平县",
+        "value": "131125"
+      },
+      {
+        "label": "故城县",
+        "value": "131126"
+      },
+      {
+        "label": "景县",
+        "value": "131127"
+      },
+      {
+        "label": "阜城县",
+        "value": "131128"
+      },
+      {
+        "label": "河北衡水经济开发区",
+        "value": "131171"
+      },
+      {
+        "label": "衡水滨湖新区",
+        "value": "131172"
+      },
+      {
+        "label": "深州市",
+        "value": "131182"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "小店区",
+        "value": "140105"
+      },
+      {
+        "label": "迎泽区",
+        "value": "140106"
+      },
+      {
+        "label": "杏花岭区",
+        "value": "140107"
+      },
+      {
+        "label": "尖草坪区",
+        "value": "140108"
+      },
+      {
+        "label": "万柏林区",
+        "value": "140109"
+      },
+      {
+        "label": "晋源区",
+        "value": "140110"
+      },
+      {
+        "label": "清徐县",
+        "value": "140121"
+      },
+      {
+        "label": "阳曲县",
+        "value": "140122"
+      },
+      {
+        "label": "娄烦县",
+        "value": "140123"
+      },
+      {
+        "label": "山西转型综合改革示范区",
+        "value": "140171"
+      },
+      {
+        "label": "古交市",
+        "value": "140181"
+      }
+    ],
+    [{
+        "label": "城区",
+        "value": "140202"
+      },
+      {
+        "label": "矿区",
+        "value": "140203"
+      },
+      {
+        "label": "南郊区",
+        "value": "140211"
+      },
+      {
+        "label": "新荣区",
+        "value": "140212"
+      },
+      {
+        "label": "阳高县",
+        "value": "140221"
+      },
+      {
+        "label": "天镇县",
+        "value": "140222"
+      },
+      {
+        "label": "广灵县",
+        "value": "140223"
+      },
+      {
+        "label": "灵丘县",
+        "value": "140224"
+      },
+      {
+        "label": "浑源县",
+        "value": "140225"
+      },
+      {
+        "label": "左云县",
+        "value": "140226"
+      },
+      {
+        "label": "大同县",
+        "value": "140227"
+      },
+      {
+        "label": "山西大同经济开发区",
+        "value": "140271"
+      }
+    ],
+    [{
+        "label": "城区",
+        "value": "140302"
+      },
+      {
+        "label": "矿区",
+        "value": "140303"
+      },
+      {
+        "label": "郊区",
+        "value": "140311"
+      },
+      {
+        "label": "平定县",
+        "value": "140321"
+      },
+      {
+        "label": "盂县",
+        "value": "140322"
+      },
+      {
+        "label": "山西阳泉经济开发区",
+        "value": "140371"
+      }
+    ],
+    [{
+        "label": "城区",
+        "value": "140402"
+      },
+      {
+        "label": "郊区",
+        "value": "140411"
+      },
+      {
+        "label": "长治县",
+        "value": "140421"
+      },
+      {
+        "label": "襄垣县",
+        "value": "140423"
+      },
+      {
+        "label": "屯留县",
+        "value": "140424"
+      },
+      {
+        "label": "平顺县",
+        "value": "140425"
+      },
+      {
+        "label": "黎城县",
+        "value": "140426"
+      },
+      {
+        "label": "壶关县",
+        "value": "140427"
+      },
+      {
+        "label": "长子县",
+        "value": "140428"
+      },
+      {
+        "label": "武乡县",
+        "value": "140429"
+      },
+      {
+        "label": "沁县",
+        "value": "140430"
+      },
+      {
+        "label": "沁源县",
+        "value": "140431"
+      },
+      {
+        "label": "山西长治高新技术产业园区",
+        "value": "140471"
+      },
+      {
+        "label": "潞城市",
+        "value": "140481"
+      }
+    ],
+    [{
+        "label": "城区",
+        "value": "140502"
+      },
+      {
+        "label": "沁水县",
+        "value": "140521"
+      },
+      {
+        "label": "阳城县",
+        "value": "140522"
+      },
+      {
+        "label": "陵川县",
+        "value": "140524"
+      },
+      {
+        "label": "泽州县",
+        "value": "140525"
+      },
+      {
+        "label": "高平市",
+        "value": "140581"
+      }
+    ],
+    [{
+        "label": "朔城区",
+        "value": "140602"
+      },
+      {
+        "label": "平鲁区",
+        "value": "140603"
+      },
+      {
+        "label": "山阴县",
+        "value": "140621"
+      },
+      {
+        "label": "应县",
+        "value": "140622"
+      },
+      {
+        "label": "右玉县",
+        "value": "140623"
+      },
+      {
+        "label": "怀仁县",
+        "value": "140624"
+      },
+      {
+        "label": "山西朔州经济开发区",
+        "value": "140671"
+      }
+    ],
+    [{
+        "label": "榆次区",
+        "value": "140702"
+      },
+      {
+        "label": "榆社县",
+        "value": "140721"
+      },
+      {
+        "label": "左权县",
+        "value": "140722"
+      },
+      {
+        "label": "和顺县",
+        "value": "140723"
+      },
+      {
+        "label": "昔阳县",
+        "value": "140724"
+      },
+      {
+        "label": "寿阳县",
+        "value": "140725"
+      },
+      {
+        "label": "太谷县",
+        "value": "140726"
+      },
+      {
+        "label": "祁县",
+        "value": "140727"
+      },
+      {
+        "label": "平遥县",
+        "value": "140728"
+      },
+      {
+        "label": "灵石县",
+        "value": "140729"
+      },
+      {
+        "label": "介休市",
+        "value": "140781"
+      }
+    ],
+    [{
+        "label": "盐湖区",
+        "value": "140802"
+      },
+      {
+        "label": "临猗县",
+        "value": "140821"
+      },
+      {
+        "label": "万荣县",
+        "value": "140822"
+      },
+      {
+        "label": "闻喜县",
+        "value": "140823"
+      },
+      {
+        "label": "稷山县",
+        "value": "140824"
+      },
+      {
+        "label": "新绛县",
+        "value": "140825"
+      },
+      {
+        "label": "绛县",
+        "value": "140826"
+      },
+      {
+        "label": "垣曲县",
+        "value": "140827"
+      },
+      {
+        "label": "夏县",
+        "value": "140828"
+      },
+      {
+        "label": "平陆县",
+        "value": "140829"
+      },
+      {
+        "label": "芮城县",
+        "value": "140830"
+      },
+      {
+        "label": "永济市",
+        "value": "140881"
+      },
+      {
+        "label": "河津市",
+        "value": "140882"
+      }
+    ],
+    [{
+        "label": "忻府区",
+        "value": "140902"
+      },
+      {
+        "label": "定襄县",
+        "value": "140921"
+      },
+      {
+        "label": "五台县",
+        "value": "140922"
+      },
+      {
+        "label": "代县",
+        "value": "140923"
+      },
+      {
+        "label": "繁峙县",
+        "value": "140924"
+      },
+      {
+        "label": "宁武县",
+        "value": "140925"
+      },
+      {
+        "label": "静乐县",
+        "value": "140926"
+      },
+      {
+        "label": "神池县",
+        "value": "140927"
+      },
+      {
+        "label": "五寨县",
+        "value": "140928"
+      },
+      {
+        "label": "岢岚县",
+        "value": "140929"
+      },
+      {
+        "label": "河曲县",
+        "value": "140930"
+      },
+      {
+        "label": "保德县",
+        "value": "140931"
+      },
+      {
+        "label": "偏关县",
+        "value": "140932"
+      },
+      {
+        "label": "五台山风景名胜区",
+        "value": "140971"
+      },
+      {
+        "label": "原平市",
+        "value": "140981"
+      }
+    ],
+    [{
+        "label": "尧都区",
+        "value": "141002"
+      },
+      {
+        "label": "曲沃县",
+        "value": "141021"
+      },
+      {
+        "label": "翼城县",
+        "value": "141022"
+      },
+      {
+        "label": "襄汾县",
+        "value": "141023"
+      },
+      {
+        "label": "洪洞县",
+        "value": "141024"
+      },
+      {
+        "label": "古县",
+        "value": "141025"
+      },
+      {
+        "label": "安泽县",
+        "value": "141026"
+      },
+      {
+        "label": "浮山县",
+        "value": "141027"
+      },
+      {
+        "label": "吉县",
+        "value": "141028"
+      },
+      {
+        "label": "乡宁县",
+        "value": "141029"
+      },
+      {
+        "label": "大宁县",
+        "value": "141030"
+      },
+      {
+        "label": "隰县",
+        "value": "141031"
+      },
+      {
+        "label": "永和县",
+        "value": "141032"
+      },
+      {
+        "label": "蒲县",
+        "value": "141033"
+      },
+      {
+        "label": "汾西县",
+        "value": "141034"
+      },
+      {
+        "label": "侯马市",
+        "value": "141081"
+      },
+      {
+        "label": "霍州市",
+        "value": "141082"
+      }
+    ],
+    [{
+        "label": "离石区",
+        "value": "141102"
+      },
+      {
+        "label": "文水县",
+        "value": "141121"
+      },
+      {
+        "label": "交城县",
+        "value": "141122"
+      },
+      {
+        "label": "兴县",
+        "value": "141123"
+      },
+      {
+        "label": "临县",
+        "value": "141124"
+      },
+      {
+        "label": "柳林县",
+        "value": "141125"
+      },
+      {
+        "label": "石楼县",
+        "value": "141126"
+      },
+      {
+        "label": "岚县",
+        "value": "141127"
+      },
+      {
+        "label": "方山县",
+        "value": "141128"
+      },
+      {
+        "label": "中阳县",
+        "value": "141129"
+      },
+      {
+        "label": "交口县",
+        "value": "141130"
+      },
+      {
+        "label": "孝义市",
+        "value": "141181"
+      },
+      {
+        "label": "汾阳市",
+        "value": "141182"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "新城区",
+        "value": "150102"
+      },
+      {
+        "label": "回民区",
+        "value": "150103"
+      },
+      {
+        "label": "玉泉区",
+        "value": "150104"
+      },
+      {
+        "label": "赛罕区",
+        "value": "150105"
+      },
+      {
+        "label": "土默特左旗",
+        "value": "150121"
+      },
+      {
+        "label": "托克托县",
+        "value": "150122"
+      },
+      {
+        "label": "和林格尔县",
+        "value": "150123"
+      },
+      {
+        "label": "清水河县",
+        "value": "150124"
+      },
+      {
+        "label": "武川县",
+        "value": "150125"
+      },
+      {
+        "label": "呼和浩特金海工业园区",
+        "value": "150171"
+      },
+      {
+        "label": "呼和浩特经济技术开发区",
+        "value": "150172"
+      }
+    ],
+    [{
+        "label": "东河区",
+        "value": "150202"
+      },
+      {
+        "label": "昆都仑区",
+        "value": "150203"
+      },
+      {
+        "label": "青山区",
+        "value": "150204"
+      },
+      {
+        "label": "石拐区",
+        "value": "150205"
+      },
+      {
+        "label": "白云鄂博矿区",
+        "value": "150206"
+      },
+      {
+        "label": "九原区",
+        "value": "150207"
+      },
+      {
+        "label": "土默特右旗",
+        "value": "150221"
+      },
+      {
+        "label": "固阳县",
+        "value": "150222"
+      },
+      {
+        "label": "达尔罕茂明安联合旗",
+        "value": "150223"
+      },
+      {
+        "label": "包头稀土高新技术产业开发区",
+        "value": "150271"
+      }
+    ],
+    [{
+        "label": "海勃湾区",
+        "value": "150302"
+      },
+      {
+        "label": "海南区",
+        "value": "150303"
+      },
+      {
+        "label": "乌达区",
+        "value": "150304"
+      }
+    ],
+    [{
+        "label": "红山区",
+        "value": "150402"
+      },
+      {
+        "label": "元宝山区",
+        "value": "150403"
+      },
+      {
+        "label": "松山区",
+        "value": "150404"
+      },
+      {
+        "label": "阿鲁科尔沁旗",
+        "value": "150421"
+      },
+      {
+        "label": "巴林左旗",
+        "value": "150422"
+      },
+      {
+        "label": "巴林右旗",
+        "value": "150423"
+      },
+      {
+        "label": "林西县",
+        "value": "150424"
+      },
+      {
+        "label": "克什克腾旗",
+        "value": "150425"
+      },
+      {
+        "label": "翁牛特旗",
+        "value": "150426"
+      },
+      {
+        "label": "喀喇沁旗",
+        "value": "150428"
+      },
+      {
+        "label": "宁城县",
+        "value": "150429"
+      },
+      {
+        "label": "敖汉旗",
+        "value": "150430"
+      }
+    ],
+    [{
+        "label": "科尔沁区",
+        "value": "150502"
+      },
+      {
+        "label": "科尔沁左翼中旗",
+        "value": "150521"
+      },
+      {
+        "label": "科尔沁左翼后旗",
+        "value": "150522"
+      },
+      {
+        "label": "开鲁县",
+        "value": "150523"
+      },
+      {
+        "label": "库伦旗",
+        "value": "150524"
+      },
+      {
+        "label": "奈曼旗",
+        "value": "150525"
+      },
+      {
+        "label": "扎鲁特旗",
+        "value": "150526"
+      },
+      {
+        "label": "通辽经济技术开发区",
+        "value": "150571"
+      },
+      {
+        "label": "霍林郭勒市",
+        "value": "150581"
+      }
+    ],
+    [{
+        "label": "东胜区",
+        "value": "150602"
+      },
+      {
+        "label": "康巴什区",
+        "value": "150603"
+      },
+      {
+        "label": "达拉特旗",
+        "value": "150621"
+      },
+      {
+        "label": "准格尔旗",
+        "value": "150622"
+      },
+      {
+        "label": "鄂托克前旗",
+        "value": "150623"
+      },
+      {
+        "label": "鄂托克旗",
+        "value": "150624"
+      },
+      {
+        "label": "杭锦旗",
+        "value": "150625"
+      },
+      {
+        "label": "乌审旗",
+        "value": "150626"
+      },
+      {
+        "label": "伊金霍洛旗",
+        "value": "150627"
+      }
+    ],
+    [{
+        "label": "海拉尔区",
+        "value": "150702"
+      },
+      {
+        "label": "扎赉诺尔区",
+        "value": "150703"
+      },
+      {
+        "label": "阿荣旗",
+        "value": "150721"
+      },
+      {
+        "label": "莫力达瓦达斡尔族自治旗",
+        "value": "150722"
+      },
+      {
+        "label": "鄂伦春自治旗",
+        "value": "150723"
+      },
+      {
+        "label": "鄂温克族自治旗",
+        "value": "150724"
+      },
+      {
+        "label": "陈巴尔虎旗",
+        "value": "150725"
+      },
+      {
+        "label": "新巴尔虎左旗",
+        "value": "150726"
+      },
+      {
+        "label": "新巴尔虎右旗",
+        "value": "150727"
+      },
+      {
+        "label": "满洲里市",
+        "value": "150781"
+      },
+      {
+        "label": "牙克石市",
+        "value": "150782"
+      },
+      {
+        "label": "扎兰屯市",
+        "value": "150783"
+      },
+      {
+        "label": "额尔古纳市",
+        "value": "150784"
+      },
+      {
+        "label": "根河市",
+        "value": "150785"
+      }
+    ],
+    [{
+        "label": "临河区",
+        "value": "150802"
+      },
+      {
+        "label": "五原县",
+        "value": "150821"
+      },
+      {
+        "label": "磴口县",
+        "value": "150822"
+      },
+      {
+        "label": "乌拉特前旗",
+        "value": "150823"
+      },
+      {
+        "label": "乌拉特中旗",
+        "value": "150824"
+      },
+      {
+        "label": "乌拉特后旗",
+        "value": "150825"
+      },
+      {
+        "label": "杭锦后旗",
+        "value": "150826"
+      }
+    ],
+    [{
+        "label": "集宁区",
+        "value": "150902"
+      },
+      {
+        "label": "卓资县",
+        "value": "150921"
+      },
+      {
+        "label": "化德县",
+        "value": "150922"
+      },
+      {
+        "label": "商都县",
+        "value": "150923"
+      },
+      {
+        "label": "兴和县",
+        "value": "150924"
+      },
+      {
+        "label": "凉城县",
+        "value": "150925"
+      },
+      {
+        "label": "察哈尔右翼前旗",
+        "value": "150926"
+      },
+      {
+        "label": "察哈尔右翼中旗",
+        "value": "150927"
+      },
+      {
+        "label": "察哈尔右翼后旗",
+        "value": "150928"
+      },
+      {
+        "label": "四子王旗",
+        "value": "150929"
+      },
+      {
+        "label": "丰镇市",
+        "value": "150981"
+      }
+    ],
+    [{
+        "label": "乌兰浩特市",
+        "value": "152201"
+      },
+      {
+        "label": "阿尔山市",
+        "value": "152202"
+      },
+      {
+        "label": "科尔沁右翼前旗",
+        "value": "152221"
+      },
+      {
+        "label": "科尔沁右翼中旗",
+        "value": "152222"
+      },
+      {
+        "label": "扎赉特旗",
+        "value": "152223"
+      },
+      {
+        "label": "突泉县",
+        "value": "152224"
+      }
+    ],
+    [{
+        "label": "二连浩特市",
+        "value": "152501"
+      },
+      {
+        "label": "锡林浩特市",
+        "value": "152502"
+      },
+      {
+        "label": "阿巴嘎旗",
+        "value": "152522"
+      },
+      {
+        "label": "苏尼特左旗",
+        "value": "152523"
+      },
+      {
+        "label": "苏尼特右旗",
+        "value": "152524"
+      },
+      {
+        "label": "东乌珠穆沁旗",
+        "value": "152525"
+      },
+      {
+        "label": "西乌珠穆沁旗",
+        "value": "152526"
+      },
+      {
+        "label": "太仆寺旗",
+        "value": "152527"
+      },
+      {
+        "label": "镶黄旗",
+        "value": "152528"
+      },
+      {
+        "label": "正镶白旗",
+        "value": "152529"
+      },
+      {
+        "label": "正蓝旗",
+        "value": "152530"
+      },
+      {
+        "label": "多伦县",
+        "value": "152531"
+      },
+      {
+        "label": "乌拉盖管委会",
+        "value": "152571"
+      }
+    ],
+    [{
+        "label": "阿拉善左旗",
+        "value": "152921"
+      },
+      {
+        "label": "阿拉善右旗",
+        "value": "152922"
+      },
+      {
+        "label": "额济纳旗",
+        "value": "152923"
+      },
+      {
+        "label": "内蒙古阿拉善经济开发区",
+        "value": "152971"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "和平区",
+        "value": "210102"
+      },
+      {
+        "label": "沈河区",
+        "value": "210103"
+      },
+      {
+        "label": "大东区",
+        "value": "210104"
+      },
+      {
+        "label": "皇姑区",
+        "value": "210105"
+      },
+      {
+        "label": "铁西区",
+        "value": "210106"
+      },
+      {
+        "label": "苏家屯区",
+        "value": "210111"
+      },
+      {
+        "label": "浑南区",
+        "value": "210112"
+      },
+      {
+        "label": "沈北新区",
+        "value": "210113"
+      },
+      {
+        "label": "于洪区",
+        "value": "210114"
+      },
+      {
+        "label": "辽中区",
+        "value": "210115"
+      },
+      {
+        "label": "康平县",
+        "value": "210123"
+      },
+      {
+        "label": "法库县",
+        "value": "210124"
+      },
+      {
+        "label": "新民市",
+        "value": "210181"
+      }
+    ],
+    [{
+        "label": "中山区",
+        "value": "210202"
+      },
+      {
+        "label": "西岗区",
+        "value": "210203"
+      },
+      {
+        "label": "沙河口区",
+        "value": "210204"
+      },
+      {
+        "label": "甘井子区",
+        "value": "210211"
+      },
+      {
+        "label": "旅顺口区",
+        "value": "210212"
+      },
+      {
+        "label": "金州区",
+        "value": "210213"
+      },
+      {
+        "label": "普兰店区",
+        "value": "210214"
+      },
+      {
+        "label": "长海县",
+        "value": "210224"
+      },
+      {
+        "label": "瓦房店市",
+        "value": "210281"
+      },
+      {
+        "label": "庄河市",
+        "value": "210283"
+      }
+    ],
+    [{
+        "label": "铁东区",
+        "value": "210302"
+      },
+      {
+        "label": "铁西区",
+        "value": "210303"
+      },
+      {
+        "label": "立山区",
+        "value": "210304"
+      },
+      {
+        "label": "千山区",
+        "value": "210311"
+      },
+      {
+        "label": "台安县",
+        "value": "210321"
+      },
+      {
+        "label": "岫岩满族自治县",
+        "value": "210323"
+      },
+      {
+        "label": "海城市",
+        "value": "210381"
+      }
+    ],
+    [{
+        "label": "新抚区",
+        "value": "210402"
+      },
+      {
+        "label": "东洲区",
+        "value": "210403"
+      },
+      {
+        "label": "望花区",
+        "value": "210404"
+      },
+      {
+        "label": "顺城区",
+        "value": "210411"
+      },
+      {
+        "label": "抚顺县",
+        "value": "210421"
+      },
+      {
+        "label": "新宾满族自治县",
+        "value": "210422"
+      },
+      {
+        "label": "清原满族自治县",
+        "value": "210423"
+      }
+    ],
+    [{
+        "label": "平山区",
+        "value": "210502"
+      },
+      {
+        "label": "溪湖区",
+        "value": "210503"
+      },
+      {
+        "label": "明山区",
+        "value": "210504"
+      },
+      {
+        "label": "南芬区",
+        "value": "210505"
+      },
+      {
+        "label": "本溪满族自治县",
+        "value": "210521"
+      },
+      {
+        "label": "桓仁满族自治县",
+        "value": "210522"
+      }
+    ],
+    [{
+        "label": "元宝区",
+        "value": "210602"
+      },
+      {
+        "label": "振兴区",
+        "value": "210603"
+      },
+      {
+        "label": "振安区",
+        "value": "210604"
+      },
+      {
+        "label": "宽甸满族自治县",
+        "value": "210624"
+      },
+      {
+        "label": "东港市",
+        "value": "210681"
+      },
+      {
+        "label": "凤城市",
+        "value": "210682"
+      }
+    ],
+    [{
+        "label": "古塔区",
+        "value": "210702"
+      },
+      {
+        "label": "凌河区",
+        "value": "210703"
+      },
+      {
+        "label": "太和区",
+        "value": "210711"
+      },
+      {
+        "label": "黑山县",
+        "value": "210726"
+      },
+      {
+        "label": "义县",
+        "value": "210727"
+      },
+      {
+        "label": "凌海市",
+        "value": "210781"
+      },
+      {
+        "label": "北镇市",
+        "value": "210782"
+      }
+    ],
+    [{
+        "label": "站前区",
+        "value": "210802"
+      },
+      {
+        "label": "西市区",
+        "value": "210803"
+      },
+      {
+        "label": "鲅鱼圈区",
+        "value": "210804"
+      },
+      {
+        "label": "老边区",
+        "value": "210811"
+      },
+      {
+        "label": "盖州市",
+        "value": "210881"
+      },
+      {
+        "label": "大石桥市",
+        "value": "210882"
+      }
+    ],
+    [{
+        "label": "海州区",
+        "value": "210902"
+      },
+      {
+        "label": "新邱区",
+        "value": "210903"
+      },
+      {
+        "label": "太平区",
+        "value": "210904"
+      },
+      {
+        "label": "清河门区",
+        "value": "210905"
+      },
+      {
+        "label": "细河区",
+        "value": "210911"
+      },
+      {
+        "label": "阜新蒙古族自治县",
+        "value": "210921"
+      },
+      {
+        "label": "彰武县",
+        "value": "210922"
+      }
+    ],
+    [{
+        "label": "白塔区",
+        "value": "211002"
+      },
+      {
+        "label": "文圣区",
+        "value": "211003"
+      },
+      {
+        "label": "宏伟区",
+        "value": "211004"
+      },
+      {
+        "label": "弓长岭区",
+        "value": "211005"
+      },
+      {
+        "label": "太子河区",
+        "value": "211011"
+      },
+      {
+        "label": "辽阳县",
+        "value": "211021"
+      },
+      {
+        "label": "灯塔市",
+        "value": "211081"
+      }
+    ],
+    [{
+        "label": "双台子区",
+        "value": "211102"
+      },
+      {
+        "label": "兴隆台区",
+        "value": "211103"
+      },
+      {
+        "label": "大洼区",
+        "value": "211104"
+      },
+      {
+        "label": "盘山县",
+        "value": "211122"
+      }
+    ],
+    [{
+        "label": "银州区",
+        "value": "211202"
+      },
+      {
+        "label": "清河区",
+        "value": "211204"
+      },
+      {
+        "label": "铁岭县",
+        "value": "211221"
+      },
+      {
+        "label": "西丰县",
+        "value": "211223"
+      },
+      {
+        "label": "昌图县",
+        "value": "211224"
+      },
+      {
+        "label": "调兵山市",
+        "value": "211281"
+      },
+      {
+        "label": "开原市",
+        "value": "211282"
+      }
+    ],
+    [{
+        "label": "双塔区",
+        "value": "211302"
+      },
+      {
+        "label": "龙城区",
+        "value": "211303"
+      },
+      {
+        "label": "朝阳县",
+        "value": "211321"
+      },
+      {
+        "label": "建平县",
+        "value": "211322"
+      },
+      {
+        "label": "喀喇沁左翼蒙古族自治县",
+        "value": "211324"
+      },
+      {
+        "label": "北票市",
+        "value": "211381"
+      },
+      {
+        "label": "凌源市",
+        "value": "211382"
+      }
+    ],
+    [{
+        "label": "连山区",
+        "value": "211402"
+      },
+      {
+        "label": "龙港区",
+        "value": "211403"
+      },
+      {
+        "label": "南票区",
+        "value": "211404"
+      },
+      {
+        "label": "绥中县",
+        "value": "211421"
+      },
+      {
+        "label": "建昌县",
+        "value": "211422"
+      },
+      {
+        "label": "兴城市",
+        "value": "211481"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "南关区",
+        "value": "220102"
+      },
+      {
+        "label": "宽城区",
+        "value": "220103"
+      },
+      {
+        "label": "朝阳区",
+        "value": "220104"
+      },
+      {
+        "label": "二道区",
+        "value": "220105"
+      },
+      {
+        "label": "绿园区",
+        "value": "220106"
+      },
+      {
+        "label": "双阳区",
+        "value": "220112"
+      },
+      {
+        "label": "九台区",
+        "value": "220113"
+      },
+      {
+        "label": "农安县",
+        "value": "220122"
+      },
+      {
+        "label": "长春经济技术开发区",
+        "value": "220171"
+      },
+      {
+        "label": "长春净月高新技术产业开发区",
+        "value": "220172"
+      },
+      {
+        "label": "长春高新技术产业开发区",
+        "value": "220173"
+      },
+      {
+        "label": "长春汽车经济技术开发区",
+        "value": "220174"
+      },
+      {
+        "label": "榆树市",
+        "value": "220182"
+      },
+      {
+        "label": "德惠市",
+        "value": "220183"
+      }
+    ],
+    [{
+        "label": "昌邑区",
+        "value": "220202"
+      },
+      {
+        "label": "龙潭区",
+        "value": "220203"
+      },
+      {
+        "label": "船营区",
+        "value": "220204"
+      },
+      {
+        "label": "丰满区",
+        "value": "220211"
+      },
+      {
+        "label": "永吉县",
+        "value": "220221"
+      },
+      {
+        "label": "吉林经济开发区",
+        "value": "220271"
+      },
+      {
+        "label": "吉林高新技术产业开发区",
+        "value": "220272"
+      },
+      {
+        "label": "吉林中国新加坡食品区",
+        "value": "220273"
+      },
+      {
+        "label": "蛟河市",
+        "value": "220281"
+      },
+      {
+        "label": "桦甸市",
+        "value": "220282"
+      },
+      {
+        "label": "舒兰市",
+        "value": "220283"
+      },
+      {
+        "label": "磐石市",
+        "value": "220284"
+      }
+    ],
+    [{
+        "label": "铁西区",
+        "value": "220302"
+      },
+      {
+        "label": "铁东区",
+        "value": "220303"
+      },
+      {
+        "label": "梨树县",
+        "value": "220322"
+      },
+      {
+        "label": "伊通满族自治县",
+        "value": "220323"
+      },
+      {
+        "label": "公主岭市",
+        "value": "220381"
+      },
+      {
+        "label": "双辽市",
+        "value": "220382"
+      }
+    ],
+    [{
+        "label": "龙山区",
+        "value": "220402"
+      },
+      {
+        "label": "西安区",
+        "value": "220403"
+      },
+      {
+        "label": "东丰县",
+        "value": "220421"
+      },
+      {
+        "label": "东辽县",
+        "value": "220422"
+      }
+    ],
+    [{
+        "label": "东昌区",
+        "value": "220502"
+      },
+      {
+        "label": "二道江区",
+        "value": "220503"
+      },
+      {
+        "label": "通化县",
+        "value": "220521"
+      },
+      {
+        "label": "辉南县",
+        "value": "220523"
+      },
+      {
+        "label": "柳河县",
+        "value": "220524"
+      },
+      {
+        "label": "梅河口市",
+        "value": "220581"
+      },
+      {
+        "label": "集安市",
+        "value": "220582"
+      }
+    ],
+    [{
+        "label": "浑江区",
+        "value": "220602"
+      },
+      {
+        "label": "江源区",
+        "value": "220605"
+      },
+      {
+        "label": "抚松县",
+        "value": "220621"
+      },
+      {
+        "label": "靖宇县",
+        "value": "220622"
+      },
+      {
+        "label": "长白朝鲜族自治县",
+        "value": "220623"
+      },
+      {
+        "label": "临江市",
+        "value": "220681"
+      }
+    ],
+    [{
+        "label": "宁江区",
+        "value": "220702"
+      },
+      {
+        "label": "前郭尔罗斯蒙古族自治县",
+        "value": "220721"
+      },
+      {
+        "label": "长岭县",
+        "value": "220722"
+      },
+      {
+        "label": "乾安县",
+        "value": "220723"
+      },
+      {
+        "label": "吉林松原经济开发区",
+        "value": "220771"
+      },
+      {
+        "label": "扶余市",
+        "value": "220781"
+      }
+    ],
+    [{
+        "label": "洮北区",
+        "value": "220802"
+      },
+      {
+        "label": "镇赉县",
+        "value": "220821"
+      },
+      {
+        "label": "通榆县",
+        "value": "220822"
+      },
+      {
+        "label": "吉林白城经济开发区",
+        "value": "220871"
+      },
+      {
+        "label": "洮南市",
+        "value": "220881"
+      },
+      {
+        "label": "大安市",
+        "value": "220882"
+      }
+    ],
+    [{
+        "label": "延吉市",
+        "value": "222401"
+      },
+      {
+        "label": "图们市",
+        "value": "222402"
+      },
+      {
+        "label": "敦化市",
+        "value": "222403"
+      },
+      {
+        "label": "珲春市",
+        "value": "222404"
+      },
+      {
+        "label": "龙井市",
+        "value": "222405"
+      },
+      {
+        "label": "和龙市",
+        "value": "222406"
+      },
+      {
+        "label": "汪清县",
+        "value": "222424"
+      },
+      {
+        "label": "安图县",
+        "value": "222426"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "道里区",
+        "value": "230102"
+      },
+      {
+        "label": "南岗区",
+        "value": "230103"
+      },
+      {
+        "label": "道外区",
+        "value": "230104"
+      },
+      {
+        "label": "平房区",
+        "value": "230108"
+      },
+      {
+        "label": "松北区",
+        "value": "230109"
+      },
+      {
+        "label": "香坊区",
+        "value": "230110"
+      },
+      {
+        "label": "呼兰区",
+        "value": "230111"
+      },
+      {
+        "label": "阿城区",
+        "value": "230112"
+      },
+      {
+        "label": "双城区",
+        "value": "230113"
+      },
+      {
+        "label": "依兰县",
+        "value": "230123"
+      },
+      {
+        "label": "方正县",
+        "value": "230124"
+      },
+      {
+        "label": "宾县",
+        "value": "230125"
+      },
+      {
+        "label": "巴彦县",
+        "value": "230126"
+      },
+      {
+        "label": "木兰县",
+        "value": "230127"
+      },
+      {
+        "label": "通河县",
+        "value": "230128"
+      },
+      {
+        "label": "延寿县",
+        "value": "230129"
+      },
+      {
+        "label": "尚志市",
+        "value": "230183"
+      },
+      {
+        "label": "五常市",
+        "value": "230184"
+      }
+    ],
+    [{
+        "label": "龙沙区",
+        "value": "230202"
+      },
+      {
+        "label": "建华区",
+        "value": "230203"
+      },
+      {
+        "label": "铁锋区",
+        "value": "230204"
+      },
+      {
+        "label": "昂昂溪区",
+        "value": "230205"
+      },
+      {
+        "label": "富拉尔基区",
+        "value": "230206"
+      },
+      {
+        "label": "碾子山区",
+        "value": "230207"
+      },
+      {
+        "label": "梅里斯达斡尔族区",
+        "value": "230208"
+      },
+      {
+        "label": "龙江县",
+        "value": "230221"
+      },
+      {
+        "label": "依安县",
+        "value": "230223"
+      },
+      {
+        "label": "泰来县",
+        "value": "230224"
+      },
+      {
+        "label": "甘南县",
+        "value": "230225"
+      },
+      {
+        "label": "富裕县",
+        "value": "230227"
+      },
+      {
+        "label": "克山县",
+        "value": "230229"
+      },
+      {
+        "label": "克东县",
+        "value": "230230"
+      },
+      {
+        "label": "拜泉县",
+        "value": "230231"
+      },
+      {
+        "label": "讷河市",
+        "value": "230281"
+      }
+    ],
+    [{
+        "label": "鸡冠区",
+        "value": "230302"
+      },
+      {
+        "label": "恒山区",
+        "value": "230303"
+      },
+      {
+        "label": "滴道区",
+        "value": "230304"
+      },
+      {
+        "label": "梨树区",
+        "value": "230305"
+      },
+      {
+        "label": "城子河区",
+        "value": "230306"
+      },
+      {
+        "label": "麻山区",
+        "value": "230307"
+      },
+      {
+        "label": "鸡东县",
+        "value": "230321"
+      },
+      {
+        "label": "虎林市",
+        "value": "230381"
+      },
+      {
+        "label": "密山市",
+        "value": "230382"
+      }
+    ],
+    [{
+        "label": "向阳区",
+        "value": "230402"
+      },
+      {
+        "label": "工农区",
+        "value": "230403"
+      },
+      {
+        "label": "南山区",
+        "value": "230404"
+      },
+      {
+        "label": "兴安区",
+        "value": "230405"
+      },
+      {
+        "label": "东山区",
+        "value": "230406"
+      },
+      {
+        "label": "兴山区",
+        "value": "230407"
+      },
+      {
+        "label": "萝北县",
+        "value": "230421"
+      },
+      {
+        "label": "绥滨县",
+        "value": "230422"
+      }
+    ],
+    [{
+        "label": "尖山区",
+        "value": "230502"
+      },
+      {
+        "label": "岭东区",
+        "value": "230503"
+      },
+      {
+        "label": "四方台区",
+        "value": "230505"
+      },
+      {
+        "label": "宝山区",
+        "value": "230506"
+      },
+      {
+        "label": "集贤县",
+        "value": "230521"
+      },
+      {
+        "label": "友谊县",
+        "value": "230522"
+      },
+      {
+        "label": "宝清县",
+        "value": "230523"
+      },
+      {
+        "label": "饶河县",
+        "value": "230524"
+      }
+    ],
+    [{
+        "label": "萨尔图区",
+        "value": "230602"
+      },
+      {
+        "label": "龙凤区",
+        "value": "230603"
+      },
+      {
+        "label": "让胡路区",
+        "value": "230604"
+      },
+      {
+        "label": "红岗区",
+        "value": "230605"
+      },
+      {
+        "label": "大同区",
+        "value": "230606"
+      },
+      {
+        "label": "肇州县",
+        "value": "230621"
+      },
+      {
+        "label": "肇源县",
+        "value": "230622"
+      },
+      {
+        "label": "林甸县",
+        "value": "230623"
+      },
+      {
+        "label": "杜尔伯特蒙古族自治县",
+        "value": "230624"
+      },
+      {
+        "label": "大庆高新技术产业开发区",
+        "value": "230671"
+      }
+    ],
+    [{
+        "label": "伊春区",
+        "value": "230702"
+      },
+      {
+        "label": "南岔区",
+        "value": "230703"
+      },
+      {
+        "label": "友好区",
+        "value": "230704"
+      },
+      {
+        "label": "西林区",
+        "value": "230705"
+      },
+      {
+        "label": "翠峦区",
+        "value": "230706"
+      },
+      {
+        "label": "新青区",
+        "value": "230707"
+      },
+      {
+        "label": "美溪区",
+        "value": "230708"
+      },
+      {
+        "label": "金山屯区",
+        "value": "230709"
+      },
+      {
+        "label": "五营区",
+        "value": "230710"
+      },
+      {
+        "label": "乌马河区",
+        "value": "230711"
+      },
+      {
+        "label": "汤旺河区",
+        "value": "230712"
+      },
+      {
+        "label": "带岭区",
+        "value": "230713"
+      },
+      {
+        "label": "乌伊岭区",
+        "value": "230714"
+      },
+      {
+        "label": "红星区",
+        "value": "230715"
+      },
+      {
+        "label": "上甘岭区",
+        "value": "230716"
+      },
+      {
+        "label": "嘉荫县",
+        "value": "230722"
+      },
+      {
+        "label": "铁力市",
+        "value": "230781"
+      }
+    ],
+    [{
+        "label": "向阳区",
+        "value": "230803"
+      },
+      {
+        "label": "前进区",
+        "value": "230804"
+      },
+      {
+        "label": "东风区",
+        "value": "230805"
+      },
+      {
+        "label": "郊区",
+        "value": "230811"
+      },
+      {
+        "label": "桦南县",
+        "value": "230822"
+      },
+      {
+        "label": "桦川县",
+        "value": "230826"
+      },
+      {
+        "label": "汤原县",
+        "value": "230828"
+      },
+      {
+        "label": "同江市",
+        "value": "230881"
+      },
+      {
+        "label": "富锦市",
+        "value": "230882"
+      },
+      {
+        "label": "抚远市",
+        "value": "230883"
+      }
+    ],
+    [{
+        "label": "新兴区",
+        "value": "230902"
+      },
+      {
+        "label": "桃山区",
+        "value": "230903"
+      },
+      {
+        "label": "茄子河区",
+        "value": "230904"
+      },
+      {
+        "label": "勃利县",
+        "value": "230921"
+      }
+    ],
+    [{
+        "label": "东安区",
+        "value": "231002"
+      },
+      {
+        "label": "阳明区",
+        "value": "231003"
+      },
+      {
+        "label": "爱民区",
+        "value": "231004"
+      },
+      {
+        "label": "西安区",
+        "value": "231005"
+      },
+      {
+        "label": "林口县",
+        "value": "231025"
+      },
+      {
+        "label": "牡丹江经济技术开发区",
+        "value": "231071"
+      },
+      {
+        "label": "绥芬河市",
+        "value": "231081"
+      },
+      {
+        "label": "海林市",
+        "value": "231083"
+      },
+      {
+        "label": "宁安市",
+        "value": "231084"
+      },
+      {
+        "label": "穆棱市",
+        "value": "231085"
+      },
+      {
+        "label": "东宁市",
+        "value": "231086"
+      }
+    ],
+    [{
+        "label": "爱辉区",
+        "value": "231102"
+      },
+      {
+        "label": "嫩江县",
+        "value": "231121"
+      },
+      {
+        "label": "逊克县",
+        "value": "231123"
+      },
+      {
+        "label": "孙吴县",
+        "value": "231124"
+      },
+      {
+        "label": "北安市",
+        "value": "231181"
+      },
+      {
+        "label": "五大连池市",
+        "value": "231182"
+      }
+    ],
+    [{
+        "label": "北林区",
+        "value": "231202"
+      },
+      {
+        "label": "望奎县",
+        "value": "231221"
+      },
+      {
+        "label": "兰西县",
+        "value": "231222"
+      },
+      {
+        "label": "青冈县",
+        "value": "231223"
+      },
+      {
+        "label": "庆安县",
+        "value": "231224"
+      },
+      {
+        "label": "明水县",
+        "value": "231225"
+      },
+      {
+        "label": "绥棱县",
+        "value": "231226"
+      },
+      {
+        "label": "安达市",
+        "value": "231281"
+      },
+      {
+        "label": "肇东市",
+        "value": "231282"
+      },
+      {
+        "label": "海伦市",
+        "value": "231283"
+      }
+    ],
+    [{
+        "label": "加格达奇区",
+        "value": "232701"
+      },
+      {
+        "label": "松岭区",
+        "value": "232702"
+      },
+      {
+        "label": "新林区",
+        "value": "232703"
+      },
+      {
+        "label": "呼中区",
+        "value": "232704"
+      },
+      {
+        "label": "呼玛县",
+        "value": "232721"
+      },
+      {
+        "label": "塔河县",
+        "value": "232722"
+      },
+      {
+        "label": "漠河县",
+        "value": "232723"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "黄浦区",
+        "value": "310101"
+      },
+      {
+        "label": "徐汇区",
+        "value": "310104"
+      },
+      {
+        "label": "长宁区",
+        "value": "310105"
+      },
+      {
+        "label": "静安区",
+        "value": "310106"
+      },
+      {
+        "label": "普陀区",
+        "value": "310107"
+      },
+      {
+        "label": "虹口区",
+        "value": "310109"
+      },
+      {
+        "label": "杨浦区",
+        "value": "310110"
+      },
+      {
+        "label": "闵行区",
+        "value": "310112"
+      },
+      {
+        "label": "宝山区",
+        "value": "310113"
+      },
+      {
+        "label": "嘉定区",
+        "value": "310114"
+      },
+      {
+        "label": "浦东新区",
+        "value": "310115"
+      },
+      {
+        "label": "金山区",
+        "value": "310116"
+      },
+      {
+        "label": "松江区",
+        "value": "310117"
+      },
+      {
+        "label": "青浦区",
+        "value": "310118"
+      },
+      {
+        "label": "奉贤区",
+        "value": "310120"
+      },
+      {
+        "label": "崇明区",
+        "value": "310151"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "玄武区",
+        "value": "320102"
+      },
+      {
+        "label": "秦淮区",
+        "value": "320104"
+      },
+      {
+        "label": "建邺区",
+        "value": "320105"
+      },
+      {
+        "label": "鼓楼区",
+        "value": "320106"
+      },
+      {
+        "label": "浦口区",
+        "value": "320111"
+      },
+      {
+        "label": "栖霞区",
+        "value": "320113"
+      },
+      {
+        "label": "雨花台区",
+        "value": "320114"
+      },
+      {
+        "label": "江宁区",
+        "value": "320115"
+      },
+      {
+        "label": "六合区",
+        "value": "320116"
+      },
+      {
+        "label": "溧水区",
+        "value": "320117"
+      },
+      {
+        "label": "高淳区",
+        "value": "320118"
+      }
+    ],
+    [{
+        "label": "锡山区",
+        "value": "320205"
+      },
+      {
+        "label": "惠山区",
+        "value": "320206"
+      },
+      {
+        "label": "滨湖区",
+        "value": "320211"
+      },
+      {
+        "label": "梁溪区",
+        "value": "320213"
+      },
+      {
+        "label": "新吴区",
+        "value": "320214"
+      },
+      {
+        "label": "江阴市",
+        "value": "320281"
+      },
+      {
+        "label": "宜兴市",
+        "value": "320282"
+      }
+    ],
+    [{
+        "label": "鼓楼区",
+        "value": "320302"
+      },
+      {
+        "label": "云龙区",
+        "value": "320303"
+      },
+      {
+        "label": "贾汪区",
+        "value": "320305"
+      },
+      {
+        "label": "泉山区",
+        "value": "320311"
+      },
+      {
+        "label": "铜山区",
+        "value": "320312"
+      },
+      {
+        "label": "丰县",
+        "value": "320321"
+      },
+      {
+        "label": "沛县",
+        "value": "320322"
+      },
+      {
+        "label": "睢宁县",
+        "value": "320324"
+      },
+      {
+        "label": "徐州经济技术开发区",
+        "value": "320371"
+      },
+      {
+        "label": "新沂市",
+        "value": "320381"
+      },
+      {
+        "label": "邳州市",
+        "value": "320382"
+      }
+    ],
+    [{
+        "label": "天宁区",
+        "value": "320402"
+      },
+      {
+        "label": "钟楼区",
+        "value": "320404"
+      },
+      {
+        "label": "新北区",
+        "value": "320411"
+      },
+      {
+        "label": "武进区",
+        "value": "320412"
+      },
+      {
+        "label": "金坛区",
+        "value": "320413"
+      },
+      {
+        "label": "溧阳市",
+        "value": "320481"
+      }
+    ],
+    [{
+        "label": "虎丘区",
+        "value": "320505"
+      },
+      {
+        "label": "吴中区",
+        "value": "320506"
+      },
+      {
+        "label": "相城区",
+        "value": "320507"
+      },
+      {
+        "label": "姑苏区",
+        "value": "320508"
+      },
+      {
+        "label": "吴江区",
+        "value": "320509"
+      },
+      {
+        "label": "苏州工业园区",
+        "value": "320571"
+      },
+      {
+        "label": "常熟市",
+        "value": "320581"
+      },
+      {
+        "label": "张家港市",
+        "value": "320582"
+      },
+      {
+        "label": "昆山市",
+        "value": "320583"
+      },
+      {
+        "label": "太仓市",
+        "value": "320585"
+      }
+    ],
+    [{
+        "label": "崇川区",
+        "value": "320602"
+      },
+      {
+        "label": "港闸区",
+        "value": "320611"
+      },
+      {
+        "label": "通州区",
+        "value": "320612"
+      },
+      {
+        "label": "海安县",
+        "value": "320621"
+      },
+      {
+        "label": "如东县",
+        "value": "320623"
+      },
+      {
+        "label": "南通经济技术开发区",
+        "value": "320671"
+      },
+      {
+        "label": "启东市",
+        "value": "320681"
+      },
+      {
+        "label": "如皋市",
+        "value": "320682"
+      },
+      {
+        "label": "海门市",
+        "value": "320684"
+      }
+    ],
+    [{
+        "label": "连云区",
+        "value": "320703"
+      },
+      {
+        "label": "海州区",
+        "value": "320706"
+      },
+      {
+        "label": "赣榆区",
+        "value": "320707"
+      },
+      {
+        "label": "东海县",
+        "value": "320722"
+      },
+      {
+        "label": "灌云县",
+        "value": "320723"
+      },
+      {
+        "label": "灌南县",
+        "value": "320724"
+      },
+      {
+        "label": "连云港经济技术开发区",
+        "value": "320771"
+      },
+      {
+        "label": "连云港高新技术产业开发区",
+        "value": "320772"
+      }
+    ],
+    [{
+        "label": "淮安区",
+        "value": "320803"
+      },
+      {
+        "label": "淮阴区",
+        "value": "320804"
+      },
+      {
+        "label": "清江浦区",
+        "value": "320812"
+      },
+      {
+        "label": "洪泽区",
+        "value": "320813"
+      },
+      {
+        "label": "涟水县",
+        "value": "320826"
+      },
+      {
+        "label": "盱眙县",
+        "value": "320830"
+      },
+      {
+        "label": "金湖县",
+        "value": "320831"
+      },
+      {
+        "label": "淮安经济技术开发区",
+        "value": "320871"
+      }
+    ],
+    [{
+        "label": "亭湖区",
+        "value": "320902"
+      },
+      {
+        "label": "盐都区",
+        "value": "320903"
+      },
+      {
+        "label": "大丰区",
+        "value": "320904"
+      },
+      {
+        "label": "响水县",
+        "value": "320921"
+      },
+      {
+        "label": "滨海县",
+        "value": "320922"
+      },
+      {
+        "label": "阜宁县",
+        "value": "320923"
+      },
+      {
+        "label": "射阳县",
+        "value": "320924"
+      },
+      {
+        "label": "建湖县",
+        "value": "320925"
+      },
+      {
+        "label": "盐城经济技术开发区",
+        "value": "320971"
+      },
+      {
+        "label": "东台市",
+        "value": "320981"
+      }
+    ],
+    [{
+        "label": "广陵区",
+        "value": "321002"
+      },
+      {
+        "label": "邗江区",
+        "value": "321003"
+      },
+      {
+        "label": "江都区",
+        "value": "321012"
+      },
+      {
+        "label": "宝应县",
+        "value": "321023"
+      },
+      {
+        "label": "扬州经济技术开发区",
+        "value": "321071"
+      },
+      {
+        "label": "仪征市",
+        "value": "321081"
+      },
+      {
+        "label": "高邮市",
+        "value": "321084"
+      }
+    ],
+    [{
+        "label": "京口区",
+        "value": "321102"
+      },
+      {
+        "label": "润州区",
+        "value": "321111"
+      },
+      {
+        "label": "丹徒区",
+        "value": "321112"
+      },
+      {
+        "label": "镇江新区",
+        "value": "321171"
+      },
+      {
+        "label": "丹阳市",
+        "value": "321181"
+      },
+      {
+        "label": "扬中市",
+        "value": "321182"
+      },
+      {
+        "label": "句容市",
+        "value": "321183"
+      }
+    ],
+    [{
+        "label": "海陵区",
+        "value": "321202"
+      },
+      {
+        "label": "高港区",
+        "value": "321203"
+      },
+      {
+        "label": "姜堰区",
+        "value": "321204"
+      },
+      {
+        "label": "泰州医药高新技术产业开发区",
+        "value": "321271"
+      },
+      {
+        "label": "兴化市",
+        "value": "321281"
+      },
+      {
+        "label": "靖江市",
+        "value": "321282"
+      },
+      {
+        "label": "泰兴市",
+        "value": "321283"
+      }
+    ],
+    [{
+        "label": "宿城区",
+        "value": "321302"
+      },
+      {
+        "label": "宿豫区",
+        "value": "321311"
+      },
+      {
+        "label": "沭阳县",
+        "value": "321322"
+      },
+      {
+        "label": "泗阳县",
+        "value": "321323"
+      },
+      {
+        "label": "泗洪县",
+        "value": "321324"
+      },
+      {
+        "label": "宿迁经济技术开发区",
+        "value": "321371"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "上城区",
+        "value": "330102"
+      },
+      {
+        "label": "下城区",
+        "value": "330103"
+      },
+      {
+        "label": "江干区",
+        "value": "330104"
+      },
+      {
+        "label": "拱墅区",
+        "value": "330105"
+      },
+      {
+        "label": "西湖区",
+        "value": "330106"
+      },
+      {
+        "label": "滨江区",
+        "value": "330108"
+      },
+      {
+        "label": "萧山区",
+        "value": "330109"
+      },
+      {
+        "label": "余杭区",
+        "value": "330110"
+      },
+      {
+        "label": "富阳区",
+        "value": "330111"
+      },
+      {
+        "label": "临安区",
+        "value": "330112"
+      },
+      {
+        "label": "桐庐县",
+        "value": "330122"
+      },
+      {
+        "label": "淳安县",
+        "value": "330127"
+      },
+      {
+        "label": "建德市",
+        "value": "330182"
+      }
+    ],
+    [{
+        "label": "海曙区",
+        "value": "330203"
+      },
+      {
+        "label": "江北区",
+        "value": "330205"
+      },
+      {
+        "label": "北仑区",
+        "value": "330206"
+      },
+      {
+        "label": "镇海区",
+        "value": "330211"
+      },
+      {
+        "label": "鄞州区",
+        "value": "330212"
+      },
+      {
+        "label": "奉化区",
+        "value": "330213"
+      },
+      {
+        "label": "象山县",
+        "value": "330225"
+      },
+      {
+        "label": "宁海县",
+        "value": "330226"
+      },
+      {
+        "label": "余姚市",
+        "value": "330281"
+      },
+      {
+        "label": "慈溪市",
+        "value": "330282"
+      }
+    ],
+    [{
+        "label": "鹿城区",
+        "value": "330302"
+      },
+      {
+        "label": "龙湾区",
+        "value": "330303"
+      },
+      {
+        "label": "瓯海区",
+        "value": "330304"
+      },
+      {
+        "label": "洞头区",
+        "value": "330305"
+      },
+      {
+        "label": "永嘉县",
+        "value": "330324"
+      },
+      {
+        "label": "平阳县",
+        "value": "330326"
+      },
+      {
+        "label": "苍南县",
+        "value": "330327"
+      },
+      {
+        "label": "文成县",
+        "value": "330328"
+      },
+      {
+        "label": "泰顺县",
+        "value": "330329"
+      },
+      {
+        "label": "温州经济技术开发区",
+        "value": "330371"
+      },
+      {
+        "label": "瑞安市",
+        "value": "330381"
+      },
+      {
+        "label": "乐清市",
+        "value": "330382"
+      }
+    ],
+    [{
+        "label": "南湖区",
+        "value": "330402"
+      },
+      {
+        "label": "秀洲区",
+        "value": "330411"
+      },
+      {
+        "label": "嘉善县",
+        "value": "330421"
+      },
+      {
+        "label": "海盐县",
+        "value": "330424"
+      },
+      {
+        "label": "海宁市",
+        "value": "330481"
+      },
+      {
+        "label": "平湖市",
+        "value": "330482"
+      },
+      {
+        "label": "桐乡市",
+        "value": "330483"
+      }
+    ],
+    [{
+        "label": "吴兴区",
+        "value": "330502"
+      },
+      {
+        "label": "南浔区",
+        "value": "330503"
+      },
+      {
+        "label": "德清县",
+        "value": "330521"
+      },
+      {
+        "label": "长兴县",
+        "value": "330522"
+      },
+      {
+        "label": "安吉县",
+        "value": "330523"
+      }
+    ],
+    [{
+        "label": "越城区",
+        "value": "330602"
+      },
+      {
+        "label": "柯桥区",
+        "value": "330603"
+      },
+      {
+        "label": "上虞区",
+        "value": "330604"
+      },
+      {
+        "label": "新昌县",
+        "value": "330624"
+      },
+      {
+        "label": "诸暨市",
+        "value": "330681"
+      },
+      {
+        "label": "嵊州市",
+        "value": "330683"
+      }
+    ],
+    [{
+        "label": "婺城区",
+        "value": "330702"
+      },
+      {
+        "label": "金东区",
+        "value": "330703"
+      },
+      {
+        "label": "武义县",
+        "value": "330723"
+      },
+      {
+        "label": "浦江县",
+        "value": "330726"
+      },
+      {
+        "label": "磐安县",
+        "value": "330727"
+      },
+      {
+        "label": "兰溪市",
+        "value": "330781"
+      },
+      {
+        "label": "义乌市",
+        "value": "330782"
+      },
+      {
+        "label": "东阳市",
+        "value": "330783"
+      },
+      {
+        "label": "永康市",
+        "value": "330784"
+      }
+    ],
+    [{
+        "label": "柯城区",
+        "value": "330802"
+      },
+      {
+        "label": "衢江区",
+        "value": "330803"
+      },
+      {
+        "label": "常山县",
+        "value": "330822"
+      },
+      {
+        "label": "开化县",
+        "value": "330824"
+      },
+      {
+        "label": "龙游县",
+        "value": "330825"
+      },
+      {
+        "label": "江山市",
+        "value": "330881"
+      }
+    ],
+    [{
+        "label": "定海区",
+        "value": "330902"
+      },
+      {
+        "label": "普陀区",
+        "value": "330903"
+      },
+      {
+        "label": "岱山县",
+        "value": "330921"
+      },
+      {
+        "label": "嵊泗县",
+        "value": "330922"
+      }
+    ],
+    [{
+        "label": "椒江区",
+        "value": "331002"
+      },
+      {
+        "label": "黄岩区",
+        "value": "331003"
+      },
+      {
+        "label": "路桥区",
+        "value": "331004"
+      },
+      {
+        "label": "三门县",
+        "value": "331022"
+      },
+      {
+        "label": "天台县",
+        "value": "331023"
+      },
+      {
+        "label": "仙居县",
+        "value": "331024"
+      },
+      {
+        "label": "温岭市",
+        "value": "331081"
+      },
+      {
+        "label": "临海市",
+        "value": "331082"
+      },
+      {
+        "label": "玉环市",
+        "value": "331083"
+      }
+    ],
+    [{
+        "label": "莲都区",
+        "value": "331102"
+      },
+      {
+        "label": "青田县",
+        "value": "331121"
+      },
+      {
+        "label": "缙云县",
+        "value": "331122"
+      },
+      {
+        "label": "遂昌县",
+        "value": "331123"
+      },
+      {
+        "label": "松阳县",
+        "value": "331124"
+      },
+      {
+        "label": "云和县",
+        "value": "331125"
+      },
+      {
+        "label": "庆元县",
+        "value": "331126"
+      },
+      {
+        "label": "景宁畲族自治县",
+        "value": "331127"
+      },
+      {
+        "label": "龙泉市",
+        "value": "331181"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "瑶海区",
+        "value": "340102"
+      },
+      {
+        "label": "庐阳区",
+        "value": "340103"
+      },
+      {
+        "label": "蜀山区",
+        "value": "340104"
+      },
+      {
+        "label": "包河区",
+        "value": "340111"
+      },
+      {
+        "label": "长丰县",
+        "value": "340121"
+      },
+      {
+        "label": "肥东县",
+        "value": "340122"
+      },
+      {
+        "label": "肥西县",
+        "value": "340123"
+      },
+      {
+        "label": "庐江县",
+        "value": "340124"
+      },
+      {
+        "label": "合肥高新技术产业开发区",
+        "value": "340171"
+      },
+      {
+        "label": "合肥经济技术开发区",
+        "value": "340172"
+      },
+      {
+        "label": "合肥新站高新技术产业开发区",
+        "value": "340173"
+      },
+      {
+        "label": "巢湖市",
+        "value": "340181"
+      }
+    ],
+    [{
+        "label": "镜湖区",
+        "value": "340202"
+      },
+      {
+        "label": "弋江区",
+        "value": "340203"
+      },
+      {
+        "label": "鸠江区",
+        "value": "340207"
+      },
+      {
+        "label": "三山区",
+        "value": "340208"
+      },
+      {
+        "label": "芜湖县",
+        "value": "340221"
+      },
+      {
+        "label": "繁昌县",
+        "value": "340222"
+      },
+      {
+        "label": "南陵县",
+        "value": "340223"
+      },
+      {
+        "label": "无为县",
+        "value": "340225"
+      },
+      {
+        "label": "芜湖经济技术开发区",
+        "value": "340271"
+      },
+      {
+        "label": "安徽芜湖长江大桥经济开发区",
+        "value": "340272"
+      }
+    ],
+    [{
+        "label": "龙子湖区",
+        "value": "340302"
+      },
+      {
+        "label": "蚌山区",
+        "value": "340303"
+      },
+      {
+        "label": "禹会区",
+        "value": "340304"
+      },
+      {
+        "label": "淮上区",
+        "value": "340311"
+      },
+      {
+        "label": "怀远县",
+        "value": "340321"
+      },
+      {
+        "label": "五河县",
+        "value": "340322"
+      },
+      {
+        "label": "固镇县",
+        "value": "340323"
+      },
+      {
+        "label": "蚌埠市高新技术开发区",
+        "value": "340371"
+      },
+      {
+        "label": "蚌埠市经济开发区",
+        "value": "340372"
+      }
+    ],
+    [{
+        "label": "大通区",
+        "value": "340402"
+      },
+      {
+        "label": "田家庵区",
+        "value": "340403"
+      },
+      {
+        "label": "谢家集区",
+        "value": "340404"
+      },
+      {
+        "label": "八公山区",
+        "value": "340405"
+      },
+      {
+        "label": "潘集区",
+        "value": "340406"
+      },
+      {
+        "label": "凤台县",
+        "value": "340421"
+      },
+      {
+        "label": "寿县",
+        "value": "340422"
+      }
+    ],
+    [{
+        "label": "花山区",
+        "value": "340503"
+      },
+      {
+        "label": "雨山区",
+        "value": "340504"
+      },
+      {
+        "label": "博望区",
+        "value": "340506"
+      },
+      {
+        "label": "当涂县",
+        "value": "340521"
+      },
+      {
+        "label": "含山县",
+        "value": "340522"
+      },
+      {
+        "label": "和县",
+        "value": "340523"
+      }
+    ],
+    [{
+        "label": "杜集区",
+        "value": "340602"
+      },
+      {
+        "label": "相山区",
+        "value": "340603"
+      },
+      {
+        "label": "烈山区",
+        "value": "340604"
+      },
+      {
+        "label": "濉溪县",
+        "value": "340621"
+      }
+    ],
+    [{
+        "label": "铜官区",
+        "value": "340705"
+      },
+      {
+        "label": "义安区",
+        "value": "340706"
+      },
+      {
+        "label": "郊区",
+        "value": "340711"
+      },
+      {
+        "label": "枞阳县",
+        "value": "340722"
+      }
+    ],
+    [{
+        "label": "迎江区",
+        "value": "340802"
+      },
+      {
+        "label": "大观区",
+        "value": "340803"
+      },
+      {
+        "label": "宜秀区",
+        "value": "340811"
+      },
+      {
+        "label": "怀宁县",
+        "value": "340822"
+      },
+      {
+        "label": "潜山县",
+        "value": "340824"
+      },
+      {
+        "label": "太湖县",
+        "value": "340825"
+      },
+      {
+        "label": "宿松县",
+        "value": "340826"
+      },
+      {
+        "label": "望江县",
+        "value": "340827"
+      },
+      {
+        "label": "岳西县",
+        "value": "340828"
+      },
+      {
+        "label": "安徽安庆经济开发区",
+        "value": "340871"
+      },
+      {
+        "label": "桐城市",
+        "value": "340881"
+      }
+    ],
+    [{
+        "label": "屯溪区",
+        "value": "341002"
+      },
+      {
+        "label": "黄山区",
+        "value": "341003"
+      },
+      {
+        "label": "徽州区",
+        "value": "341004"
+      },
+      {
+        "label": "歙县",
+        "value": "341021"
+      },
+      {
+        "label": "休宁县",
+        "value": "341022"
+      },
+      {
+        "label": "黟县",
+        "value": "341023"
+      },
+      {
+        "label": "祁门县",
+        "value": "341024"
+      }
+    ],
+    [{
+        "label": "琅琊区",
+        "value": "341102"
+      },
+      {
+        "label": "南谯区",
+        "value": "341103"
+      },
+      {
+        "label": "来安县",
+        "value": "341122"
+      },
+      {
+        "label": "全椒县",
+        "value": "341124"
+      },
+      {
+        "label": "定远县",
+        "value": "341125"
+      },
+      {
+        "label": "凤阳县",
+        "value": "341126"
+      },
+      {
+        "label": "苏滁现代产业园",
+        "value": "341171"
+      },
+      {
+        "label": "滁州经济技术开发区",
+        "value": "341172"
+      },
+      {
+        "label": "天长市",
+        "value": "341181"
+      },
+      {
+        "label": "明光市",
+        "value": "341182"
+      }
+    ],
+    [{
+        "label": "颍州区",
+        "value": "341202"
+      },
+      {
+        "label": "颍东区",
+        "value": "341203"
+      },
+      {
+        "label": "颍泉区",
+        "value": "341204"
+      },
+      {
+        "label": "临泉县",
+        "value": "341221"
+      },
+      {
+        "label": "太和县",
+        "value": "341222"
+      },
+      {
+        "label": "阜南县",
+        "value": "341225"
+      },
+      {
+        "label": "颍上县",
+        "value": "341226"
+      },
+      {
+        "label": "阜阳合肥现代产业园区",
+        "value": "341271"
+      },
+      {
+        "label": "阜阳经济技术开发区",
+        "value": "341272"
+      },
+      {
+        "label": "界首市",
+        "value": "341282"
+      }
+    ],
+    [{
+        "label": "埇桥区",
+        "value": "341302"
+      },
+      {
+        "label": "砀山县",
+        "value": "341321"
+      },
+      {
+        "label": "萧县",
+        "value": "341322"
+      },
+      {
+        "label": "灵璧县",
+        "value": "341323"
+      },
+      {
+        "label": "泗县",
+        "value": "341324"
+      },
+      {
+        "label": "宿州马鞍山现代产业园区",
+        "value": "341371"
+      },
+      {
+        "label": "宿州经济技术开发区",
+        "value": "341372"
+      }
+    ],
+    [{
+        "label": "金安区",
+        "value": "341502"
+      },
+      {
+        "label": "裕安区",
+        "value": "341503"
+      },
+      {
+        "label": "叶集区",
+        "value": "341504"
+      },
+      {
+        "label": "霍邱县",
+        "value": "341522"
+      },
+      {
+        "label": "舒城县",
+        "value": "341523"
+      },
+      {
+        "label": "金寨县",
+        "value": "341524"
+      },
+      {
+        "label": "霍山县",
+        "value": "341525"
+      }
+    ],
+    [{
+        "label": "谯城区",
+        "value": "341602"
+      },
+      {
+        "label": "涡阳县",
+        "value": "341621"
+      },
+      {
+        "label": "蒙城县",
+        "value": "341622"
+      },
+      {
+        "label": "利辛县",
+        "value": "341623"
+      }
+    ],
+    [{
+        "label": "贵池区",
+        "value": "341702"
+      },
+      {
+        "label": "东至县",
+        "value": "341721"
+      },
+      {
+        "label": "石台县",
+        "value": "341722"
+      },
+      {
+        "label": "青阳县",
+        "value": "341723"
+      }
+    ],
+    [{
+        "label": "宣州区",
+        "value": "341802"
+      },
+      {
+        "label": "郎溪县",
+        "value": "341821"
+      },
+      {
+        "label": "广德县",
+        "value": "341822"
+      },
+      {
+        "label": "泾县",
+        "value": "341823"
+      },
+      {
+        "label": "绩溪县",
+        "value": "341824"
+      },
+      {
+        "label": "旌德县",
+        "value": "341825"
+      },
+      {
+        "label": "宣城市经济开发区",
+        "value": "341871"
+      },
+      {
+        "label": "宁国市",
+        "value": "341881"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "鼓楼区",
+        "value": "350102"
+      },
+      {
+        "label": "台江区",
+        "value": "350103"
+      },
+      {
+        "label": "仓山区",
+        "value": "350104"
+      },
+      {
+        "label": "马尾区",
+        "value": "350105"
+      },
+      {
+        "label": "晋安区",
+        "value": "350111"
+      },
+      {
+        "label": "闽侯县",
+        "value": "350121"
+      },
+      {
+        "label": "连江县",
+        "value": "350122"
+      },
+      {
+        "label": "罗源县",
+        "value": "350123"
+      },
+      {
+        "label": "闽清县",
+        "value": "350124"
+      },
+      {
+        "label": "永泰县",
+        "value": "350125"
+      },
+      {
+        "label": "平潭县",
+        "value": "350128"
+      },
+      {
+        "label": "福清市",
+        "value": "350181"
+      },
+      {
+        "label": "长乐市",
+        "value": "350182"
+      }
+    ],
+    [{
+        "label": "思明区",
+        "value": "350203"
+      },
+      {
+        "label": "海沧区",
+        "value": "350205"
+      },
+      {
+        "label": "湖里区",
+        "value": "350206"
+      },
+      {
+        "label": "集美区",
+        "value": "350211"
+      },
+      {
+        "label": "同安区",
+        "value": "350212"
+      },
+      {
+        "label": "翔安区",
+        "value": "350213"
+      }
+    ],
+    [{
+        "label": "城厢区",
+        "value": "350302"
+      },
+      {
+        "label": "涵江区",
+        "value": "350303"
+      },
+      {
+        "label": "荔城区",
+        "value": "350304"
+      },
+      {
+        "label": "秀屿区",
+        "value": "350305"
+      },
+      {
+        "label": "仙游县",
+        "value": "350322"
+      }
+    ],
+    [{
+        "label": "梅列区",
+        "value": "350402"
+      },
+      {
+        "label": "三元区",
+        "value": "350403"
+      },
+      {
+        "label": "明溪县",
+        "value": "350421"
+      },
+      {
+        "label": "清流县",
+        "value": "350423"
+      },
+      {
+        "label": "宁化县",
+        "value": "350424"
+      },
+      {
+        "label": "大田县",
+        "value": "350425"
+      },
+      {
+        "label": "尤溪县",
+        "value": "350426"
+      },
+      {
+        "label": "沙县",
+        "value": "350427"
+      },
+      {
+        "label": "将乐县",
+        "value": "350428"
+      },
+      {
+        "label": "泰宁县",
+        "value": "350429"
+      },
+      {
+        "label": "建宁县",
+        "value": "350430"
+      },
+      {
+        "label": "永安市",
+        "value": "350481"
+      }
+    ],
+    [{
+        "label": "鲤城区",
+        "value": "350502"
+      },
+      {
+        "label": "丰泽区",
+        "value": "350503"
+      },
+      {
+        "label": "洛江区",
+        "value": "350504"
+      },
+      {
+        "label": "泉港区",
+        "value": "350505"
+      },
+      {
+        "label": "惠安县",
+        "value": "350521"
+      },
+      {
+        "label": "安溪县",
+        "value": "350524"
+      },
+      {
+        "label": "永春县",
+        "value": "350525"
+      },
+      {
+        "label": "德化县",
+        "value": "350526"
+      },
+      {
+        "label": "金门县",
+        "value": "350527"
+      },
+      {
+        "label": "石狮市",
+        "value": "350581"
+      },
+      {
+        "label": "晋江市",
+        "value": "350582"
+      },
+      {
+        "label": "南安市",
+        "value": "350583"
+      }
+    ],
+    [{
+        "label": "芗城区",
+        "value": "350602"
+      },
+      {
+        "label": "龙文区",
+        "value": "350603"
+      },
+      {
+        "label": "云霄县",
+        "value": "350622"
+      },
+      {
+        "label": "漳浦县",
+        "value": "350623"
+      },
+      {
+        "label": "诏安县",
+        "value": "350624"
+      },
+      {
+        "label": "长泰县",
+        "value": "350625"
+      },
+      {
+        "label": "东山县",
+        "value": "350626"
+      },
+      {
+        "label": "南靖县",
+        "value": "350627"
+      },
+      {
+        "label": "平和县",
+        "value": "350628"
+      },
+      {
+        "label": "华安县",
+        "value": "350629"
+      },
+      {
+        "label": "龙海市",
+        "value": "350681"
+      }
+    ],
+    [{
+        "label": "延平区",
+        "value": "350702"
+      },
+      {
+        "label": "建阳区",
+        "value": "350703"
+      },
+      {
+        "label": "顺昌县",
+        "value": "350721"
+      },
+      {
+        "label": "浦城县",
+        "value": "350722"
+      },
+      {
+        "label": "光泽县",
+        "value": "350723"
+      },
+      {
+        "label": "松溪县",
+        "value": "350724"
+      },
+      {
+        "label": "政和县",
+        "value": "350725"
+      },
+      {
+        "label": "邵武市",
+        "value": "350781"
+      },
+      {
+        "label": "武夷山市",
+        "value": "350782"
+      },
+      {
+        "label": "建瓯市",
+        "value": "350783"
+      }
+    ],
+    [{
+        "label": "新罗区",
+        "value": "350802"
+      },
+      {
+        "label": "永定区",
+        "value": "350803"
+      },
+      {
+        "label": "长汀县",
+        "value": "350821"
+      },
+      {
+        "label": "上杭县",
+        "value": "350823"
+      },
+      {
+        "label": "武平县",
+        "value": "350824"
+      },
+      {
+        "label": "连城县",
+        "value": "350825"
+      },
+      {
+        "label": "漳平市",
+        "value": "350881"
+      }
+    ],
+    [{
+        "label": "蕉城区",
+        "value": "350902"
+      },
+      {
+        "label": "霞浦县",
+        "value": "350921"
+      },
+      {
+        "label": "古田县",
+        "value": "350922"
+      },
+      {
+        "label": "屏南县",
+        "value": "350923"
+      },
+      {
+        "label": "寿宁县",
+        "value": "350924"
+      },
+      {
+        "label": "周宁县",
+        "value": "350925"
+      },
+      {
+        "label": "柘荣县",
+        "value": "350926"
+      },
+      {
+        "label": "福安市",
+        "value": "350981"
+      },
+      {
+        "label": "福鼎市",
+        "value": "350982"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "东湖区",
+        "value": "360102"
+      },
+      {
+        "label": "西湖区",
+        "value": "360103"
+      },
+      {
+        "label": "青云谱区",
+        "value": "360104"
+      },
+      {
+        "label": "湾里区",
+        "value": "360105"
+      },
+      {
+        "label": "青山湖区",
+        "value": "360111"
+      },
+      {
+        "label": "新建区",
+        "value": "360112"
+      },
+      {
+        "label": "南昌县",
+        "value": "360121"
+      },
+      {
+        "label": "安义县",
+        "value": "360123"
+      },
+      {
+        "label": "进贤县",
+        "value": "360124"
+      }
+    ],
+    [{
+        "label": "昌江区",
+        "value": "360202"
+      },
+      {
+        "label": "珠山区",
+        "value": "360203"
+      },
+      {
+        "label": "浮梁县",
+        "value": "360222"
+      },
+      {
+        "label": "乐平市",
+        "value": "360281"
+      }
+    ],
+    [{
+        "label": "安源区",
+        "value": "360302"
+      },
+      {
+        "label": "湘东区",
+        "value": "360313"
+      },
+      {
+        "label": "莲花县",
+        "value": "360321"
+      },
+      {
+        "label": "上栗县",
+        "value": "360322"
+      },
+      {
+        "label": "芦溪县",
+        "value": "360323"
+      }
+    ],
+    [{
+        "label": "濂溪区",
+        "value": "360402"
+      },
+      {
+        "label": "浔阳区",
+        "value": "360403"
+      },
+      {
+        "label": "柴桑区",
+        "value": "360404"
+      },
+      {
+        "label": "武宁县",
+        "value": "360423"
+      },
+      {
+        "label": "修水县",
+        "value": "360424"
+      },
+      {
+        "label": "永修县",
+        "value": "360425"
+      },
+      {
+        "label": "德安县",
+        "value": "360426"
+      },
+      {
+        "label": "都昌县",
+        "value": "360428"
+      },
+      {
+        "label": "湖口县",
+        "value": "360429"
+      },
+      {
+        "label": "彭泽县",
+        "value": "360430"
+      },
+      {
+        "label": "瑞昌市",
+        "value": "360481"
+      },
+      {
+        "label": "共青城市",
+        "value": "360482"
+      },
+      {
+        "label": "庐山市",
+        "value": "360483"
+      }
+    ],
+    [{
+        "label": "渝水区",
+        "value": "360502"
+      },
+      {
+        "label": "分宜县",
+        "value": "360521"
+      }
+    ],
+    [{
+        "label": "月湖区",
+        "value": "360602"
+      },
+      {
+        "label": "余江县",
+        "value": "360622"
+      },
+      {
+        "label": "贵溪市",
+        "value": "360681"
+      }
+    ],
+    [{
+        "label": "章贡区",
+        "value": "360702"
+      },
+      {
+        "label": "南康区",
+        "value": "360703"
+      },
+      {
+        "label": "赣县区",
+        "value": "360704"
+      },
+      {
+        "label": "信丰县",
+        "value": "360722"
+      },
+      {
+        "label": "大余县",
+        "value": "360723"
+      },
+      {
+        "label": "上犹县",
+        "value": "360724"
+      },
+      {
+        "label": "崇义县",
+        "value": "360725"
+      },
+      {
+        "label": "安远县",
+        "value": "360726"
+      },
+      {
+        "label": "龙南县",
+        "value": "360727"
+      },
+      {
+        "label": "定南县",
+        "value": "360728"
+      },
+      {
+        "label": "全南县",
+        "value": "360729"
+      },
+      {
+        "label": "宁都县",
+        "value": "360730"
+      },
+      {
+        "label": "于都县",
+        "value": "360731"
+      },
+      {
+        "label": "兴国县",
+        "value": "360732"
+      },
+      {
+        "label": "会昌县",
+        "value": "360733"
+      },
+      {
+        "label": "寻乌县",
+        "value": "360734"
+      },
+      {
+        "label": "石城县",
+        "value": "360735"
+      },
+      {
+        "label": "瑞金市",
+        "value": "360781"
+      }
+    ],
+    [{
+        "label": "吉州区",
+        "value": "360802"
+      },
+      {
+        "label": "青原区",
+        "value": "360803"
+      },
+      {
+        "label": "吉安县",
+        "value": "360821"
+      },
+      {
+        "label": "吉水县",
+        "value": "360822"
+      },
+      {
+        "label": "峡江县",
+        "value": "360823"
+      },
+      {
+        "label": "新干县",
+        "value": "360824"
+      },
+      {
+        "label": "永丰县",
+        "value": "360825"
+      },
+      {
+        "label": "泰和县",
+        "value": "360826"
+      },
+      {
+        "label": "遂川县",
+        "value": "360827"
+      },
+      {
+        "label": "万安县",
+        "value": "360828"
+      },
+      {
+        "label": "安福县",
+        "value": "360829"
+      },
+      {
+        "label": "永新县",
+        "value": "360830"
+      },
+      {
+        "label": "井冈山市",
+        "value": "360881"
+      }
+    ],
+    [{
+        "label": "袁州区",
+        "value": "360902"
+      },
+      {
+        "label": "奉新县",
+        "value": "360921"
+      },
+      {
+        "label": "万载县",
+        "value": "360922"
+      },
+      {
+        "label": "上高县",
+        "value": "360923"
+      },
+      {
+        "label": "宜丰县",
+        "value": "360924"
+      },
+      {
+        "label": "靖安县",
+        "value": "360925"
+      },
+      {
+        "label": "铜鼓县",
+        "value": "360926"
+      },
+      {
+        "label": "丰城市",
+        "value": "360981"
+      },
+      {
+        "label": "樟树市",
+        "value": "360982"
+      },
+      {
+        "label": "高安市",
+        "value": "360983"
+      }
+    ],
+    [{
+        "label": "临川区",
+        "value": "361002"
+      },
+      {
+        "label": "东乡区",
+        "value": "361003"
+      },
+      {
+        "label": "南城县",
+        "value": "361021"
+      },
+      {
+        "label": "黎川县",
+        "value": "361022"
+      },
+      {
+        "label": "南丰县",
+        "value": "361023"
+      },
+      {
+        "label": "崇仁县",
+        "value": "361024"
+      },
+      {
+        "label": "乐安县",
+        "value": "361025"
+      },
+      {
+        "label": "宜黄县",
+        "value": "361026"
+      },
+      {
+        "label": "金溪县",
+        "value": "361027"
+      },
+      {
+        "label": "资溪县",
+        "value": "361028"
+      },
+      {
+        "label": "广昌县",
+        "value": "361030"
+      }
+    ],
+    [{
+        "label": "信州区",
+        "value": "361102"
+      },
+      {
+        "label": "广丰区",
+        "value": "361103"
+      },
+      {
+        "label": "上饶县",
+        "value": "361121"
+      },
+      {
+        "label": "玉山县",
+        "value": "361123"
+      },
+      {
+        "label": "铅山县",
+        "value": "361124"
+      },
+      {
+        "label": "横峰县",
+        "value": "361125"
+      },
+      {
+        "label": "弋阳县",
+        "value": "361126"
+      },
+      {
+        "label": "余干县",
+        "value": "361127"
+      },
+      {
+        "label": "鄱阳县",
+        "value": "361128"
+      },
+      {
+        "label": "万年县",
+        "value": "361129"
+      },
+      {
+        "label": "婺源县",
+        "value": "361130"
+      },
+      {
+        "label": "德兴市",
+        "value": "361181"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "历下区",
+        "value": "370102"
+      },
+      {
+        "label": "市中区",
+        "value": "370103"
+      },
+      {
+        "label": "槐荫区",
+        "value": "370104"
+      },
+      {
+        "label": "天桥区",
+        "value": "370105"
+      },
+      {
+        "label": "历城区",
+        "value": "370112"
+      },
+      {
+        "label": "长清区",
+        "value": "370113"
+      },
+      {
+        "label": "章丘区",
+        "value": "370114"
+      },
+      {
+        "label": "平阴县",
+        "value": "370124"
+      },
+      {
+        "label": "济阳县",
+        "value": "370125"
+      },
+      {
+        "label": "商河县",
+        "value": "370126"
+      },
+      {
+        "label": "济南高新技术产业开发区",
+        "value": "370171"
+      }
+    ],
+    [{
+        "label": "市南区",
+        "value": "370202"
+      },
+      {
+        "label": "市北区",
+        "value": "370203"
+      },
+      {
+        "label": "黄岛区",
+        "value": "370211"
+      },
+      {
+        "label": "崂山区",
+        "value": "370212"
+      },
+      {
+        "label": "李沧区",
+        "value": "370213"
+      },
+      {
+        "label": "城阳区",
+        "value": "370214"
+      },
+      {
+        "label": "即墨区",
+        "value": "370215"
+      },
+      {
+        "label": "青岛高新技术产业开发区",
+        "value": "370271"
+      },
+      {
+        "label": "胶州市",
+        "value": "370281"
+      },
+      {
+        "label": "平度市",
+        "value": "370283"
+      },
+      {
+        "label": "莱西市",
+        "value": "370285"
+      }
+    ],
+    [{
+        "label": "淄川区",
+        "value": "370302"
+      },
+      {
+        "label": "张店区",
+        "value": "370303"
+      },
+      {
+        "label": "博山区",
+        "value": "370304"
+      },
+      {
+        "label": "临淄区",
+        "value": "370305"
+      },
+      {
+        "label": "周村区",
+        "value": "370306"
+      },
+      {
+        "label": "桓台县",
+        "value": "370321"
+      },
+      {
+        "label": "高青县",
+        "value": "370322"
+      },
+      {
+        "label": "沂源县",
+        "value": "370323"
+      }
+    ],
+    [{
+        "label": "市中区",
+        "value": "370402"
+      },
+      {
+        "label": "薛城区",
+        "value": "370403"
+      },
+      {
+        "label": "峄城区",
+        "value": "370404"
+      },
+      {
+        "label": "台儿庄区",
+        "value": "370405"
+      },
+      {
+        "label": "山亭区",
+        "value": "370406"
+      },
+      {
+        "label": "滕州市",
+        "value": "370481"
+      }
+    ],
+    [{
+        "label": "东营区",
+        "value": "370502"
+      },
+      {
+        "label": "河口区",
+        "value": "370503"
+      },
+      {
+        "label": "垦利区",
+        "value": "370505"
+      },
+      {
+        "label": "利津县",
+        "value": "370522"
+      },
+      {
+        "label": "广饶县",
+        "value": "370523"
+      },
+      {
+        "label": "东营经济技术开发区",
+        "value": "370571"
+      },
+      {
+        "label": "东营港经济开发区",
+        "value": "370572"
+      }
+    ],
+    [{
+        "label": "芝罘区",
+        "value": "370602"
+      },
+      {
+        "label": "福山区",
+        "value": "370611"
+      },
+      {
+        "label": "牟平区",
+        "value": "370612"
+      },
+      {
+        "label": "莱山区",
+        "value": "370613"
+      },
+      {
+        "label": "长岛县",
+        "value": "370634"
+      },
+      {
+        "label": "烟台高新技术产业开发区",
+        "value": "370671"
+      },
+      {
+        "label": "烟台经济技术开发区",
+        "value": "370672"
+      },
+      {
+        "label": "龙口市",
+        "value": "370681"
+      },
+      {
+        "label": "莱阳市",
+        "value": "370682"
+      },
+      {
+        "label": "莱州市",
+        "value": "370683"
+      },
+      {
+        "label": "蓬莱市",
+        "value": "370684"
+      },
+      {
+        "label": "招远市",
+        "value": "370685"
+      },
+      {
+        "label": "栖霞市",
+        "value": "370686"
+      },
+      {
+        "label": "海阳市",
+        "value": "370687"
+      }
+    ],
+    [{
+        "label": "潍城区",
+        "value": "370702"
+      },
+      {
+        "label": "寒亭区",
+        "value": "370703"
+      },
+      {
+        "label": "坊子区",
+        "value": "370704"
+      },
+      {
+        "label": "奎文区",
+        "value": "370705"
+      },
+      {
+        "label": "临朐县",
+        "value": "370724"
+      },
+      {
+        "label": "昌乐县",
+        "value": "370725"
+      },
+      {
+        "label": "潍坊滨海经济技术开发区",
+        "value": "370772"
+      },
+      {
+        "label": "青州市",
+        "value": "370781"
+      },
+      {
+        "label": "诸城市",
+        "value": "370782"
+      },
+      {
+        "label": "寿光市",
+        "value": "370783"
+      },
+      {
+        "label": "安丘市",
+        "value": "370784"
+      },
+      {
+        "label": "高密市",
+        "value": "370785"
+      },
+      {
+        "label": "昌邑市",
+        "value": "370786"
+      }
+    ],
+    [{
+        "label": "任城区",
+        "value": "370811"
+      },
+      {
+        "label": "兖州区",
+        "value": "370812"
+      },
+      {
+        "label": "微山县",
+        "value": "370826"
+      },
+      {
+        "label": "鱼台县",
+        "value": "370827"
+      },
+      {
+        "label": "金乡县",
+        "value": "370828"
+      },
+      {
+        "label": "嘉祥县",
+        "value": "370829"
+      },
+      {
+        "label": "汶上县",
+        "value": "370830"
+      },
+      {
+        "label": "泗水县",
+        "value": "370831"
+      },
+      {
+        "label": "梁山县",
+        "value": "370832"
+      },
+      {
+        "label": "济宁高新技术产业开发区",
+        "value": "370871"
+      },
+      {
+        "label": "曲阜市",
+        "value": "370881"
+      },
+      {
+        "label": "邹城市",
+        "value": "370883"
+      }
+    ],
+    [{
+        "label": "泰山区",
+        "value": "370902"
+      },
+      {
+        "label": "岱岳区",
+        "value": "370911"
+      },
+      {
+        "label": "宁阳县",
+        "value": "370921"
+      },
+      {
+        "label": "东平县",
+        "value": "370923"
+      },
+      {
+        "label": "新泰市",
+        "value": "370982"
+      },
+      {
+        "label": "肥城市",
+        "value": "370983"
+      }
+    ],
+    [{
+        "label": "环翠区",
+        "value": "371002"
+      },
+      {
+        "label": "文登区",
+        "value": "371003"
+      },
+      {
+        "label": "威海火炬高技术产业开发区",
+        "value": "371071"
+      },
+      {
+        "label": "威海经济技术开发区",
+        "value": "371072"
+      },
+      {
+        "label": "威海临港经济技术开发区",
+        "value": "371073"
+      },
+      {
+        "label": "荣成市",
+        "value": "371082"
+      },
+      {
+        "label": "乳山市",
+        "value": "371083"
+      }
+    ],
+    [{
+        "label": "东港区",
+        "value": "371102"
+      },
+      {
+        "label": "岚山区",
+        "value": "371103"
+      },
+      {
+        "label": "五莲县",
+        "value": "371121"
+      },
+      {
+        "label": "莒县",
+        "value": "371122"
+      },
+      {
+        "label": "日照经济技术开发区",
+        "value": "371171"
+      },
+      {
+        "label": "日照国际海洋城",
+        "value": "371172"
+      }
+    ],
+    [{
+        "label": "莱城区",
+        "value": "371202"
+      },
+      {
+        "label": "钢城区",
+        "value": "371203"
+      }
+    ],
+    [{
+        "label": "兰山区",
+        "value": "371302"
+      },
+      {
+        "label": "罗庄区",
+        "value": "371311"
+      },
+      {
+        "label": "河东区",
+        "value": "371312"
+      },
+      {
+        "label": "沂南县",
+        "value": "371321"
+      },
+      {
+        "label": "郯城县",
+        "value": "371322"
+      },
+      {
+        "label": "沂水县",
+        "value": "371323"
+      },
+      {
+        "label": "兰陵县",
+        "value": "371324"
+      },
+      {
+        "label": "费县",
+        "value": "371325"
+      },
+      {
+        "label": "平邑县",
+        "value": "371326"
+      },
+      {
+        "label": "莒南县",
+        "value": "371327"
+      },
+      {
+        "label": "蒙阴县",
+        "value": "371328"
+      },
+      {
+        "label": "临沭县",
+        "value": "371329"
+      },
+      {
+        "label": "临沂高新技术产业开发区",
+        "value": "371371"
+      },
+      {
+        "label": "临沂经济技术开发区",
+        "value": "371372"
+      },
+      {
+        "label": "临沂临港经济开发区",
+        "value": "371373"
+      }
+    ],
+    [{
+        "label": "德城区",
+        "value": "371402"
+      },
+      {
+        "label": "陵城区",
+        "value": "371403"
+      },
+      {
+        "label": "宁津县",
+        "value": "371422"
+      },
+      {
+        "label": "庆云县",
+        "value": "371423"
+      },
+      {
+        "label": "临邑县",
+        "value": "371424"
+      },
+      {
+        "label": "齐河县",
+        "value": "371425"
+      },
+      {
+        "label": "平原县",
+        "value": "371426"
+      },
+      {
+        "label": "夏津县",
+        "value": "371427"
+      },
+      {
+        "label": "武城县",
+        "value": "371428"
+      },
+      {
+        "label": "德州经济技术开发区",
+        "value": "371471"
+      },
+      {
+        "label": "德州运河经济开发区",
+        "value": "371472"
+      },
+      {
+        "label": "乐陵市",
+        "value": "371481"
+      },
+      {
+        "label": "禹城市",
+        "value": "371482"
+      }
+    ],
+    [{
+        "label": "东昌府区",
+        "value": "371502"
+      },
+      {
+        "label": "阳谷县",
+        "value": "371521"
+      },
+      {
+        "label": "莘县",
+        "value": "371522"
+      },
+      {
+        "label": "茌平县",
+        "value": "371523"
+      },
+      {
+        "label": "东阿县",
+        "value": "371524"
+      },
+      {
+        "label": "冠县",
+        "value": "371525"
+      },
+      {
+        "label": "高唐县",
+        "value": "371526"
+      },
+      {
+        "label": "临清市",
+        "value": "371581"
+      }
+    ],
+    [{
+        "label": "滨城区",
+        "value": "371602"
+      },
+      {
+        "label": "沾化区",
+        "value": "371603"
+      },
+      {
+        "label": "惠民县",
+        "value": "371621"
+      },
+      {
+        "label": "阳信县",
+        "value": "371622"
+      },
+      {
+        "label": "无棣县",
+        "value": "371623"
+      },
+      {
+        "label": "博兴县",
+        "value": "371625"
+      },
+      {
+        "label": "邹平县",
+        "value": "371626"
+      }
+    ],
+    [{
+        "label": "牡丹区",
+        "value": "371702"
+      },
+      {
+        "label": "定陶区",
+        "value": "371703"
+      },
+      {
+        "label": "曹县",
+        "value": "371721"
+      },
+      {
+        "label": "单县",
+        "value": "371722"
+      },
+      {
+        "label": "成武县",
+        "value": "371723"
+      },
+      {
+        "label": "巨野县",
+        "value": "371724"
+      },
+      {
+        "label": "郓城县",
+        "value": "371725"
+      },
+      {
+        "label": "鄄城县",
+        "value": "371726"
+      },
+      {
+        "label": "东明县",
+        "value": "371728"
+      },
+      {
+        "label": "菏泽经济技术开发区",
+        "value": "371771"
+      },
+      {
+        "label": "菏泽高新技术开发区",
+        "value": "371772"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "中原区",
+        "value": "410102"
+      },
+      {
+        "label": "二七区",
+        "value": "410103"
+      },
+      {
+        "label": "管城回族区",
+        "value": "410104"
+      },
+      {
+        "label": "金水区",
+        "value": "410105"
+      },
+      {
+        "label": "上街区",
+        "value": "410106"
+      },
+      {
+        "label": "惠济区",
+        "value": "410108"
+      },
+      {
+        "label": "中牟县",
+        "value": "410122"
+      },
+      {
+        "label": "郑州经济技术开发区",
+        "value": "410171"
+      },
+      {
+        "label": "郑州高新技术产业开发区",
+        "value": "410172"
+      },
+      {
+        "label": "郑州航空港经济综合实验区",
+        "value": "410173"
+      },
+      {
+        "label": "巩义市",
+        "value": "410181"
+      },
+      {
+        "label": "荥阳市",
+        "value": "410182"
+      },
+      {
+        "label": "新密市",
+        "value": "410183"
+      },
+      {
+        "label": "新郑市",
+        "value": "410184"
+      },
+      {
+        "label": "登封市",
+        "value": "410185"
+      }
+    ],
+    [{
+        "label": "龙亭区",
+        "value": "410202"
+      },
+      {
+        "label": "顺河回族区",
+        "value": "410203"
+      },
+      {
+        "label": "鼓楼区",
+        "value": "410204"
+      },
+      {
+        "label": "禹王台区",
+        "value": "410205"
+      },
+      {
+        "label": "祥符区",
+        "value": "410212"
+      },
+      {
+        "label": "杞县",
+        "value": "410221"
+      },
+      {
+        "label": "通许县",
+        "value": "410222"
+      },
+      {
+        "label": "尉氏县",
+        "value": "410223"
+      },
+      {
+        "label": "兰考县",
+        "value": "410225"
+      }
+    ],
+    [{
+        "label": "老城区",
+        "value": "410302"
+      },
+      {
+        "label": "西工区",
+        "value": "410303"
+      },
+      {
+        "label": "瀍河回族区",
+        "value": "410304"
+      },
+      {
+        "label": "涧西区",
+        "value": "410305"
+      },
+      {
+        "label": "吉利区",
+        "value": "410306"
+      },
+      {
+        "label": "洛龙区",
+        "value": "410311"
+      },
+      {
+        "label": "孟津县",
+        "value": "410322"
+      },
+      {
+        "label": "新安县",
+        "value": "410323"
+      },
+      {
+        "label": "栾川县",
+        "value": "410324"
+      },
+      {
+        "label": "嵩县",
+        "value": "410325"
+      },
+      {
+        "label": "汝阳县",
+        "value": "410326"
+      },
+      {
+        "label": "宜阳县",
+        "value": "410327"
+      },
+      {
+        "label": "洛宁县",
+        "value": "410328"
+      },
+      {
+        "label": "伊川县",
+        "value": "410329"
+      },
+      {
+        "label": "洛阳高新技术产业开发区",
+        "value": "410371"
+      },
+      {
+        "label": "偃师市",
+        "value": "410381"
+      }
+    ],
+    [{
+        "label": "新华区",
+        "value": "410402"
+      },
+      {
+        "label": "卫东区",
+        "value": "410403"
+      },
+      {
+        "label": "石龙区",
+        "value": "410404"
+      },
+      {
+        "label": "湛河区",
+        "value": "410411"
+      },
+      {
+        "label": "宝丰县",
+        "value": "410421"
+      },
+      {
+        "label": "叶县",
+        "value": "410422"
+      },
+      {
+        "label": "鲁山县",
+        "value": "410423"
+      },
+      {
+        "label": "郏县",
+        "value": "410425"
+      },
+      {
+        "label": "平顶山高新技术产业开发区",
+        "value": "410471"
+      },
+      {
+        "label": "平顶山市新城区",
+        "value": "410472"
+      },
+      {
+        "label": "舞钢市",
+        "value": "410481"
+      },
+      {
+        "label": "汝州市",
+        "value": "410482"
+      }
+    ],
+    [{
+        "label": "文峰区",
+        "value": "410502"
+      },
+      {
+        "label": "北关区",
+        "value": "410503"
+      },
+      {
+        "label": "殷都区",
+        "value": "410505"
+      },
+      {
+        "label": "龙安区",
+        "value": "410506"
+      },
+      {
+        "label": "安阳县",
+        "value": "410522"
+      },
+      {
+        "label": "汤阴县",
+        "value": "410523"
+      },
+      {
+        "label": "滑县",
+        "value": "410526"
+      },
+      {
+        "label": "内黄县",
+        "value": "410527"
+      },
+      {
+        "label": "安阳高新技术产业开发区",
+        "value": "410571"
+      },
+      {
+        "label": "林州市",
+        "value": "410581"
+      }
+    ],
+    [{
+        "label": "鹤山区",
+        "value": "410602"
+      },
+      {
+        "label": "山城区",
+        "value": "410603"
+      },
+      {
+        "label": "淇滨区",
+        "value": "410611"
+      },
+      {
+        "label": "浚县",
+        "value": "410621"
+      },
+      {
+        "label": "淇县",
+        "value": "410622"
+      },
+      {
+        "label": "鹤壁经济技术开发区",
+        "value": "410671"
+      }
+    ],
+    [{
+        "label": "红旗区",
+        "value": "410702"
+      },
+      {
+        "label": "卫滨区",
+        "value": "410703"
+      },
+      {
+        "label": "凤泉区",
+        "value": "410704"
+      },
+      {
+        "label": "牧野区",
+        "value": "410711"
+      },
+      {
+        "label": "新乡县",
+        "value": "410721"
+      },
+      {
+        "label": "获嘉县",
+        "value": "410724"
+      },
+      {
+        "label": "原阳县",
+        "value": "410725"
+      },
+      {
+        "label": "延津县",
+        "value": "410726"
+      },
+      {
+        "label": "封丘县",
+        "value": "410727"
+      },
+      {
+        "label": "长垣县",
+        "value": "410728"
+      },
+      {
+        "label": "新乡高新技术产业开发区",
+        "value": "410771"
+      },
+      {
+        "label": "新乡经济技术开发区",
+        "value": "410772"
+      },
+      {
+        "label": "新乡市平原城乡一体化示范区",
+        "value": "410773"
+      },
+      {
+        "label": "卫辉市",
+        "value": "410781"
+      },
+      {
+        "label": "辉县市",
+        "value": "410782"
+      }
+    ],
+    [{
+        "label": "解放区",
+        "value": "410802"
+      },
+      {
+        "label": "中站区",
+        "value": "410803"
+      },
+      {
+        "label": "马村区",
+        "value": "410804"
+      },
+      {
+        "label": "山阳区",
+        "value": "410811"
+      },
+      {
+        "label": "修武县",
+        "value": "410821"
+      },
+      {
+        "label": "博爱县",
+        "value": "410822"
+      },
+      {
+        "label": "武陟县",
+        "value": "410823"
+      },
+      {
+        "label": "温县",
+        "value": "410825"
+      },
+      {
+        "label": "焦作城乡一体化示范区",
+        "value": "410871"
+      },
+      {
+        "label": "沁阳市",
+        "value": "410882"
+      },
+      {
+        "label": "孟州市",
+        "value": "410883"
+      }
+    ],
+    [{
+        "label": "华龙区",
+        "value": "410902"
+      },
+      {
+        "label": "清丰县",
+        "value": "410922"
+      },
+      {
+        "label": "南乐县",
+        "value": "410923"
+      },
+      {
+        "label": "范县",
+        "value": "410926"
+      },
+      {
+        "label": "台前县",
+        "value": "410927"
+      },
+      {
+        "label": "濮阳县",
+        "value": "410928"
+      },
+      {
+        "label": "河南濮阳工业园区",
+        "value": "410971"
+      },
+      {
+        "label": "濮阳经济技术开发区",
+        "value": "410972"
+      }
+    ],
+    [{
+        "label": "魏都区",
+        "value": "411002"
+      },
+      {
+        "label": "建安区",
+        "value": "411003"
+      },
+      {
+        "label": "鄢陵县",
+        "value": "411024"
+      },
+      {
+        "label": "襄城县",
+        "value": "411025"
+      },
+      {
+        "label": "许昌经济技术开发区",
+        "value": "411071"
+      },
+      {
+        "label": "禹州市",
+        "value": "411081"
+      },
+      {
+        "label": "长葛市",
+        "value": "411082"
+      }
+    ],
+    [{
+        "label": "源汇区",
+        "value": "411102"
+      },
+      {
+        "label": "郾城区",
+        "value": "411103"
+      },
+      {
+        "label": "召陵区",
+        "value": "411104"
+      },
+      {
+        "label": "舞阳县",
+        "value": "411121"
+      },
+      {
+        "label": "临颍县",
+        "value": "411122"
+      },
+      {
+        "label": "漯河经济技术开发区",
+        "value": "411171"
+      }
+    ],
+    [{
+        "label": "湖滨区",
+        "value": "411202"
+      },
+      {
+        "label": "陕州区",
+        "value": "411203"
+      },
+      {
+        "label": "渑池县",
+        "value": "411221"
+      },
+      {
+        "label": "卢氏县",
+        "value": "411224"
+      },
+      {
+        "label": "河南三门峡经济开发区",
+        "value": "411271"
+      },
+      {
+        "label": "义马市",
+        "value": "411281"
+      },
+      {
+        "label": "灵宝市",
+        "value": "411282"
+      }
+    ],
+    [{
+        "label": "宛城区",
+        "value": "411302"
+      },
+      {
+        "label": "卧龙区",
+        "value": "411303"
+      },
+      {
+        "label": "南召县",
+        "value": "411321"
+      },
+      {
+        "label": "方城县",
+        "value": "411322"
+      },
+      {
+        "label": "西峡县",
+        "value": "411323"
+      },
+      {
+        "label": "镇平县",
+        "value": "411324"
+      },
+      {
+        "label": "内乡县",
+        "value": "411325"
+      },
+      {
+        "label": "淅川县",
+        "value": "411326"
+      },
+      {
+        "label": "社旗县",
+        "value": "411327"
+      },
+      {
+        "label": "唐河县",
+        "value": "411328"
+      },
+      {
+        "label": "新野县",
+        "value": "411329"
+      },
+      {
+        "label": "桐柏县",
+        "value": "411330"
+      },
+      {
+        "label": "南阳高新技术产业开发区",
+        "value": "411371"
+      },
+      {
+        "label": "南阳市城乡一体化示范区",
+        "value": "411372"
+      },
+      {
+        "label": "邓州市",
+        "value": "411381"
+      }
+    ],
+    [{
+        "label": "梁园区",
+        "value": "411402"
+      },
+      {
+        "label": "睢阳区",
+        "value": "411403"
+      },
+      {
+        "label": "民权县",
+        "value": "411421"
+      },
+      {
+        "label": "睢县",
+        "value": "411422"
+      },
+      {
+        "label": "宁陵县",
+        "value": "411423"
+      },
+      {
+        "label": "柘城县",
+        "value": "411424"
+      },
+      {
+        "label": "虞城县",
+        "value": "411425"
+      },
+      {
+        "label": "夏邑县",
+        "value": "411426"
+      },
+      {
+        "label": "豫东综合物流产业聚集区",
+        "value": "411471"
+      },
+      {
+        "label": "河南商丘经济开发区",
+        "value": "411472"
+      },
+      {
+        "label": "永城市",
+        "value": "411481"
+      }
+    ],
+    [{
+        "label": "浉河区",
+        "value": "411502"
+      },
+      {
+        "label": "平桥区",
+        "value": "411503"
+      },
+      {
+        "label": "罗山县",
+        "value": "411521"
+      },
+      {
+        "label": "光山县",
+        "value": "411522"
+      },
+      {
+        "label": "新县",
+        "value": "411523"
+      },
+      {
+        "label": "商城县",
+        "value": "411524"
+      },
+      {
+        "label": "固始县",
+        "value": "411525"
+      },
+      {
+        "label": "潢川县",
+        "value": "411526"
+      },
+      {
+        "label": "淮滨县",
+        "value": "411527"
+      },
+      {
+        "label": "息县",
+        "value": "411528"
+      },
+      {
+        "label": "信阳高新技术产业开发区",
+        "value": "411571"
+      }
+    ],
+    [{
+        "label": "川汇区",
+        "value": "411602"
+      },
+      {
+        "label": "扶沟县",
+        "value": "411621"
+      },
+      {
+        "label": "西华县",
+        "value": "411622"
+      },
+      {
+        "label": "商水县",
+        "value": "411623"
+      },
+      {
+        "label": "沈丘县",
+        "value": "411624"
+      },
+      {
+        "label": "郸城县",
+        "value": "411625"
+      },
+      {
+        "label": "淮阳县",
+        "value": "411626"
+      },
+      {
+        "label": "太康县",
+        "value": "411627"
+      },
+      {
+        "label": "鹿邑县",
+        "value": "411628"
+      },
+      {
+        "label": "河南周口经济开发区",
+        "value": "411671"
+      },
+      {
+        "label": "项城市",
+        "value": "411681"
+      }
+    ],
+    [{
+        "label": "驿城区",
+        "value": "411702"
+      },
+      {
+        "label": "西平县",
+        "value": "411721"
+      },
+      {
+        "label": "上蔡县",
+        "value": "411722"
+      },
+      {
+        "label": "平舆县",
+        "value": "411723"
+      },
+      {
+        "label": "正阳县",
+        "value": "411724"
+      },
+      {
+        "label": "确山县",
+        "value": "411725"
+      },
+      {
+        "label": "泌阳县",
+        "value": "411726"
+      },
+      {
+        "label": "汝南县",
+        "value": "411727"
+      },
+      {
+        "label": "遂平县",
+        "value": "411728"
+      },
+      {
+        "label": "新蔡县",
+        "value": "411729"
+      },
+      {
+        "label": "河南驻马店经济开发区",
+        "value": "411771"
+      }
+    ],
+    [{
+      "label": "济源市",
+      "value": "419001"
+    }]
+  ],
+  [
+    [{
+        "label": "江岸区",
+        "value": "420102"
+      },
+      {
+        "label": "江汉区",
+        "value": "420103"
+      },
+      {
+        "label": "硚口区",
+        "value": "420104"
+      },
+      {
+        "label": "汉阳区",
+        "value": "420105"
+      },
+      {
+        "label": "武昌区",
+        "value": "420106"
+      },
+      {
+        "label": "青山区",
+        "value": "420107"
+      },
+      {
+        "label": "洪山区",
+        "value": "420111"
+      },
+      {
+        "label": "东西湖区",
+        "value": "420112"
+      },
+      {
+        "label": "汉南区",
+        "value": "420113"
+      },
+      {
+        "label": "蔡甸区",
+        "value": "420114"
+      },
+      {
+        "label": "江夏区",
+        "value": "420115"
+      },
+      {
+        "label": "黄陂区",
+        "value": "420116"
+      },
+      {
+        "label": "新洲区",
+        "value": "420117"
+      }
+    ],
+    [{
+        "label": "黄石港区",
+        "value": "420202"
+      },
+      {
+        "label": "西塞山区",
+        "value": "420203"
+      },
+      {
+        "label": "下陆区",
+        "value": "420204"
+      },
+      {
+        "label": "铁山区",
+        "value": "420205"
+      },
+      {
+        "label": "阳新县",
+        "value": "420222"
+      },
+      {
+        "label": "大冶市",
+        "value": "420281"
+      }
+    ],
+    [{
+        "label": "茅箭区",
+        "value": "420302"
+      },
+      {
+        "label": "张湾区",
+        "value": "420303"
+      },
+      {
+        "label": "郧阳区",
+        "value": "420304"
+      },
+      {
+        "label": "郧西县",
+        "value": "420322"
+      },
+      {
+        "label": "竹山县",
+        "value": "420323"
+      },
+      {
+        "label": "竹溪县",
+        "value": "420324"
+      },
+      {
+        "label": "房县",
+        "value": "420325"
+      },
+      {
+        "label": "丹江口市",
+        "value": "420381"
+      }
+    ],
+    [{
+        "label": "西陵区",
+        "value": "420502"
+      },
+      {
+        "label": "伍家岗区",
+        "value": "420503"
+      },
+      {
+        "label": "点军区",
+        "value": "420504"
+      },
+      {
+        "label": "猇亭区",
+        "value": "420505"
+      },
+      {
+        "label": "夷陵区",
+        "value": "420506"
+      },
+      {
+        "label": "远安县",
+        "value": "420525"
+      },
+      {
+        "label": "兴山县",
+        "value": "420526"
+      },
+      {
+        "label": "秭归县",
+        "value": "420527"
+      },
+      {
+        "label": "长阳土家族自治县",
+        "value": "420528"
+      },
+      {
+        "label": "五峰土家族自治县",
+        "value": "420529"
+      },
+      {
+        "label": "宜都市",
+        "value": "420581"
+      },
+      {
+        "label": "当阳市",
+        "value": "420582"
+      },
+      {
+        "label": "枝江市",
+        "value": "420583"
+      }
+    ],
+    [{
+        "label": "襄城区",
+        "value": "420602"
+      },
+      {
+        "label": "樊城区",
+        "value": "420606"
+      },
+      {
+        "label": "襄州区",
+        "value": "420607"
+      },
+      {
+        "label": "南漳县",
+        "value": "420624"
+      },
+      {
+        "label": "谷城县",
+        "value": "420625"
+      },
+      {
+        "label": "保康县",
+        "value": "420626"
+      },
+      {
+        "label": "老河口市",
+        "value": "420682"
+      },
+      {
+        "label": "枣阳市",
+        "value": "420683"
+      },
+      {
+        "label": "宜城市",
+        "value": "420684"
+      }
+    ],
+    [{
+        "label": "梁子湖区",
+        "value": "420702"
+      },
+      {
+        "label": "华容区",
+        "value": "420703"
+      },
+      {
+        "label": "鄂城区",
+        "value": "420704"
+      }
+    ],
+    [{
+        "label": "东宝区",
+        "value": "420802"
+      },
+      {
+        "label": "掇刀区",
+        "value": "420804"
+      },
+      {
+        "label": "京山县",
+        "value": "420821"
+      },
+      {
+        "label": "沙洋县",
+        "value": "420822"
+      },
+      {
+        "label": "钟祥市",
+        "value": "420881"
+      }
+    ],
+    [{
+        "label": "孝南区",
+        "value": "420902"
+      },
+      {
+        "label": "孝昌县",
+        "value": "420921"
+      },
+      {
+        "label": "大悟县",
+        "value": "420922"
+      },
+      {
+        "label": "云梦县",
+        "value": "420923"
+      },
+      {
+        "label": "应城市",
+        "value": "420981"
+      },
+      {
+        "label": "安陆市",
+        "value": "420982"
+      },
+      {
+        "label": "汉川市",
+        "value": "420984"
+      }
+    ],
+    [{
+        "label": "沙市区",
+        "value": "421002"
+      },
+      {
+        "label": "荆州区",
+        "value": "421003"
+      },
+      {
+        "label": "公安县",
+        "value": "421022"
+      },
+      {
+        "label": "监利县",
+        "value": "421023"
+      },
+      {
+        "label": "江陵县",
+        "value": "421024"
+      },
+      {
+        "label": "荆州经济技术开发区",
+        "value": "421071"
+      },
+      {
+        "label": "石首市",
+        "value": "421081"
+      },
+      {
+        "label": "洪湖市",
+        "value": "421083"
+      },
+      {
+        "label": "松滋市",
+        "value": "421087"
+      }
+    ],
+    [{
+        "label": "黄州区",
+        "value": "421102"
+      },
+      {
+        "label": "团风县",
+        "value": "421121"
+      },
+      {
+        "label": "红安县",
+        "value": "421122"
+      },
+      {
+        "label": "罗田县",
+        "value": "421123"
+      },
+      {
+        "label": "英山县",
+        "value": "421124"
+      },
+      {
+        "label": "浠水县",
+        "value": "421125"
+      },
+      {
+        "label": "蕲春县",
+        "value": "421126"
+      },
+      {
+        "label": "黄梅县",
+        "value": "421127"
+      },
+      {
+        "label": "龙感湖管理区",
+        "value": "421171"
+      },
+      {
+        "label": "麻城市",
+        "value": "421181"
+      },
+      {
+        "label": "武穴市",
+        "value": "421182"
+      }
+    ],
+    [{
+        "label": "咸安区",
+        "value": "421202"
+      },
+      {
+        "label": "嘉鱼县",
+        "value": "421221"
+      },
+      {
+        "label": "通城县",
+        "value": "421222"
+      },
+      {
+        "label": "崇阳县",
+        "value": "421223"
+      },
+      {
+        "label": "通山县",
+        "value": "421224"
+      },
+      {
+        "label": "赤壁市",
+        "value": "421281"
+      }
+    ],
+    [{
+        "label": "曾都区",
+        "value": "421303"
+      },
+      {
+        "label": "随县",
+        "value": "421321"
+      },
+      {
+        "label": "广水市",
+        "value": "421381"
+      }
+    ],
+    [{
+        "label": "恩施市",
+        "value": "422801"
+      },
+      {
+        "label": "利川市",
+        "value": "422802"
+      },
+      {
+        "label": "建始县",
+        "value": "422822"
+      },
+      {
+        "label": "巴东县",
+        "value": "422823"
+      },
+      {
+        "label": "宣恩县",
+        "value": "422825"
+      },
+      {
+        "label": "咸丰县",
+        "value": "422826"
+      },
+      {
+        "label": "来凤县",
+        "value": "422827"
+      },
+      {
+        "label": "鹤峰县",
+        "value": "422828"
+      }
+    ],
+    [{
+        "label": "仙桃市",
+        "value": "429004"
+      },
+      {
+        "label": "潜江市",
+        "value": "429005"
+      },
+      {
+        "label": "天门市",
+        "value": "429006"
+      },
+      {
+        "label": "神农架林区",
+        "value": "429021"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "芙蓉区",
+        "value": "430102"
+      },
+      {
+        "label": "天心区",
+        "value": "430103"
+      },
+      {
+        "label": "岳麓区",
+        "value": "430104"
+      },
+      {
+        "label": "开福区",
+        "value": "430105"
+      },
+      {
+        "label": "雨花区",
+        "value": "430111"
+      },
+      {
+        "label": "望城区",
+        "value": "430112"
+      },
+      {
+        "label": "长沙县",
+        "value": "430121"
+      },
+      {
+        "label": "浏阳市",
+        "value": "430181"
+      },
+      {
+        "label": "宁乡市",
+        "value": "430182"
+      }
+    ],
+    [{
+        "label": "荷塘区",
+        "value": "430202"
+      },
+      {
+        "label": "芦淞区",
+        "value": "430203"
+      },
+      {
+        "label": "石峰区",
+        "value": "430204"
+      },
+      {
+        "label": "天元区",
+        "value": "430211"
+      },
+      {
+        "label": "株洲县",
+        "value": "430221"
+      },
+      {
+        "label": "攸县",
+        "value": "430223"
+      },
+      {
+        "label": "茶陵县",
+        "value": "430224"
+      },
+      {
+        "label": "炎陵县",
+        "value": "430225"
+      },
+      {
+        "label": "云龙示范区",
+        "value": "430271"
+      },
+      {
+        "label": "醴陵市",
+        "value": "430281"
+      }
+    ],
+    [{
+        "label": "雨湖区",
+        "value": "430302"
+      },
+      {
+        "label": "岳塘区",
+        "value": "430304"
+      },
+      {
+        "label": "湘潭县",
+        "value": "430321"
+      },
+      {
+        "label": "湖南湘潭高新技术产业园区",
+        "value": "430371"
+      },
+      {
+        "label": "湘潭昭山示范区",
+        "value": "430372"
+      },
+      {
+        "label": "湘潭九华示范区",
+        "value": "430373"
+      },
+      {
+        "label": "湘乡市",
+        "value": "430381"
+      },
+      {
+        "label": "韶山市",
+        "value": "430382"
+      }
+    ],
+    [{
+        "label": "珠晖区",
+        "value": "430405"
+      },
+      {
+        "label": "雁峰区",
+        "value": "430406"
+      },
+      {
+        "label": "石鼓区",
+        "value": "430407"
+      },
+      {
+        "label": "蒸湘区",
+        "value": "430408"
+      },
+      {
+        "label": "南岳区",
+        "value": "430412"
+      },
+      {
+        "label": "衡阳县",
+        "value": "430421"
+      },
+      {
+        "label": "衡南县",
+        "value": "430422"
+      },
+      {
+        "label": "衡山县",
+        "value": "430423"
+      },
+      {
+        "label": "衡东县",
+        "value": "430424"
+      },
+      {
+        "label": "祁东县",
+        "value": "430426"
+      },
+      {
+        "label": "衡阳综合保税区",
+        "value": "430471"
+      },
+      {
+        "label": "湖南衡阳高新技术产业园区",
+        "value": "430472"
+      },
+      {
+        "label": "湖南衡阳松木经济开发区",
+        "value": "430473"
+      },
+      {
+        "label": "耒阳市",
+        "value": "430481"
+      },
+      {
+        "label": "常宁市",
+        "value": "430482"
+      }
+    ],
+    [{
+        "label": "双清区",
+        "value": "430502"
+      },
+      {
+        "label": "大祥区",
+        "value": "430503"
+      },
+      {
+        "label": "北塔区",
+        "value": "430511"
+      },
+      {
+        "label": "邵东县",
+        "value": "430521"
+      },
+      {
+        "label": "新邵县",
+        "value": "430522"
+      },
+      {
+        "label": "邵阳县",
+        "value": "430523"
+      },
+      {
+        "label": "隆回县",
+        "value": "430524"
+      },
+      {
+        "label": "洞口县",
+        "value": "430525"
+      },
+      {
+        "label": "绥宁县",
+        "value": "430527"
+      },
+      {
+        "label": "新宁县",
+        "value": "430528"
+      },
+      {
+        "label": "城步苗族自治县",
+        "value": "430529"
+      },
+      {
+        "label": "武冈市",
+        "value": "430581"
+      }
+    ],
+    [{
+        "label": "岳阳楼区",
+        "value": "430602"
+      },
+      {
+        "label": "云溪区",
+        "value": "430603"
+      },
+      {
+        "label": "君山区",
+        "value": "430611"
+      },
+      {
+        "label": "岳阳县",
+        "value": "430621"
+      },
+      {
+        "label": "华容县",
+        "value": "430623"
+      },
+      {
+        "label": "湘阴县",
+        "value": "430624"
+      },
+      {
+        "label": "平江县",
+        "value": "430626"
+      },
+      {
+        "label": "岳阳市屈原管理区",
+        "value": "430671"
+      },
+      {
+        "label": "汨罗市",
+        "value": "430681"
+      },
+      {
+        "label": "临湘市",
+        "value": "430682"
+      }
+    ],
+    [{
+        "label": "武陵区",
+        "value": "430702"
+      },
+      {
+        "label": "鼎城区",
+        "value": "430703"
+      },
+      {
+        "label": "安乡县",
+        "value": "430721"
+      },
+      {
+        "label": "汉寿县",
+        "value": "430722"
+      },
+      {
+        "label": "澧县",
+        "value": "430723"
+      },
+      {
+        "label": "临澧县",
+        "value": "430724"
+      },
+      {
+        "label": "桃源县",
+        "value": "430725"
+      },
+      {
+        "label": "石门县",
+        "value": "430726"
+      },
+      {
+        "label": "常德市西洞庭管理区",
+        "value": "430771"
+      },
+      {
+        "label": "津市市",
+        "value": "430781"
+      }
+    ],
+    [{
+        "label": "永定区",
+        "value": "430802"
+      },
+      {
+        "label": "武陵源区",
+        "value": "430811"
+      },
+      {
+        "label": "慈利县",
+        "value": "430821"
+      },
+      {
+        "label": "桑植县",
+        "value": "430822"
+      }
+    ],
+    [{
+        "label": "资阳区",
+        "value": "430902"
+      },
+      {
+        "label": "赫山区",
+        "value": "430903"
+      },
+      {
+        "label": "南县",
+        "value": "430921"
+      },
+      {
+        "label": "桃江县",
+        "value": "430922"
+      },
+      {
+        "label": "安化县",
+        "value": "430923"
+      },
+      {
+        "label": "益阳市大通湖管理区",
+        "value": "430971"
+      },
+      {
+        "label": "湖南益阳高新技术产业园区",
+        "value": "430972"
+      },
+      {
+        "label": "沅江市",
+        "value": "430981"
+      }
+    ],
+    [{
+        "label": "北湖区",
+        "value": "431002"
+      },
+      {
+        "label": "苏仙区",
+        "value": "431003"
+      },
+      {
+        "label": "桂阳县",
+        "value": "431021"
+      },
+      {
+        "label": "宜章县",
+        "value": "431022"
+      },
+      {
+        "label": "永兴县",
+        "value": "431023"
+      },
+      {
+        "label": "嘉禾县",
+        "value": "431024"
+      },
+      {
+        "label": "临武县",
+        "value": "431025"
+      },
+      {
+        "label": "汝城县",
+        "value": "431026"
+      },
+      {
+        "label": "桂东县",
+        "value": "431027"
+      },
+      {
+        "label": "安仁县",
+        "value": "431028"
+      },
+      {
+        "label": "资兴市",
+        "value": "431081"
+      }
+    ],
+    [{
+        "label": "零陵区",
+        "value": "431102"
+      },
+      {
+        "label": "冷水滩区",
+        "value": "431103"
+      },
+      {
+        "label": "祁阳县",
+        "value": "431121"
+      },
+      {
+        "label": "东安县",
+        "value": "431122"
+      },
+      {
+        "label": "双牌县",
+        "value": "431123"
+      },
+      {
+        "label": "道县",
+        "value": "431124"
+      },
+      {
+        "label": "江永县",
+        "value": "431125"
+      },
+      {
+        "label": "宁远县",
+        "value": "431126"
+      },
+      {
+        "label": "蓝山县",
+        "value": "431127"
+      },
+      {
+        "label": "新田县",
+        "value": "431128"
+      },
+      {
+        "label": "江华瑶族自治县",
+        "value": "431129"
+      },
+      {
+        "label": "永州经济技术开发区",
+        "value": "431171"
+      },
+      {
+        "label": "永州市金洞管理区",
+        "value": "431172"
+      },
+      {
+        "label": "永州市回龙圩管理区",
+        "value": "431173"
+      }
+    ],
+    [{
+        "label": "鹤城区",
+        "value": "431202"
+      },
+      {
+        "label": "中方县",
+        "value": "431221"
+      },
+      {
+        "label": "沅陵县",
+        "value": "431222"
+      },
+      {
+        "label": "辰溪县",
+        "value": "431223"
+      },
+      {
+        "label": "溆浦县",
+        "value": "431224"
+      },
+      {
+        "label": "会同县",
+        "value": "431225"
+      },
+      {
+        "label": "麻阳苗族自治县",
+        "value": "431226"
+      },
+      {
+        "label": "新晃侗族自治县",
+        "value": "431227"
+      },
+      {
+        "label": "芷江侗族自治县",
+        "value": "431228"
+      },
+      {
+        "label": "靖州苗族侗族自治县",
+        "value": "431229"
+      },
+      {
+        "label": "通道侗族自治县",
+        "value": "431230"
+      },
+      {
+        "label": "怀化市洪江管理区",
+        "value": "431271"
+      },
+      {
+        "label": "洪江市",
+        "value": "431281"
+      }
+    ],
+    [{
+        "label": "娄星区",
+        "value": "431302"
+      },
+      {
+        "label": "双峰县",
+        "value": "431321"
+      },
+      {
+        "label": "新化县",
+        "value": "431322"
+      },
+      {
+        "label": "冷水江市",
+        "value": "431381"
+      },
+      {
+        "label": "涟源市",
+        "value": "431382"
+      }
+    ],
+    [{
+        "label": "吉首市",
+        "value": "433101"
+      },
+      {
+        "label": "泸溪县",
+        "value": "433122"
+      },
+      {
+        "label": "凤凰县",
+        "value": "433123"
+      },
+      {
+        "label": "花垣县",
+        "value": "433124"
+      },
+      {
+        "label": "保靖县",
+        "value": "433125"
+      },
+      {
+        "label": "古丈县",
+        "value": "433126"
+      },
+      {
+        "label": "永顺县",
+        "value": "433127"
+      },
+      {
+        "label": "龙山县",
+        "value": "433130"
+      },
+      {
+        "label": "湖南吉首经济开发区",
+        "value": "433172"
+      },
+      {
+        "label": "湖南永顺经济开发区",
+        "value": "433173"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "荔湾区",
+        "value": "440103"
+      },
+      {
+        "label": "越秀区",
+        "value": "440104"
+      },
+      {
+        "label": "海珠区",
+        "value": "440105"
+      },
+      {
+        "label": "天河区",
+        "value": "440106"
+      },
+      {
+        "label": "白云区",
+        "value": "440111"
+      },
+      {
+        "label": "黄埔区",
+        "value": "440112"
+      },
+      {
+        "label": "番禺区",
+        "value": "440113"
+      },
+      {
+        "label": "花都区",
+        "value": "440114"
+      },
+      {
+        "label": "南沙区",
+        "value": "440115"
+      },
+      {
+        "label": "从化区",
+        "value": "440117"
+      },
+      {
+        "label": "增城区",
+        "value": "440118"
+      }
+    ],
+    [{
+        "label": "武江区",
+        "value": "440203"
+      },
+      {
+        "label": "浈江区",
+        "value": "440204"
+      },
+      {
+        "label": "曲江区",
+        "value": "440205"
+      },
+      {
+        "label": "始兴县",
+        "value": "440222"
+      },
+      {
+        "label": "仁化县",
+        "value": "440224"
+      },
+      {
+        "label": "翁源县",
+        "value": "440229"
+      },
+      {
+        "label": "乳源瑶族自治县",
+        "value": "440232"
+      },
+      {
+        "label": "新丰县",
+        "value": "440233"
+      },
+      {
+        "label": "乐昌市",
+        "value": "440281"
+      },
+      {
+        "label": "南雄市",
+        "value": "440282"
+      }
+    ],
+    [{
+        "label": "罗湖区",
+        "value": "440303"
+      },
+      {
+        "label": "福田区",
+        "value": "440304"
+      },
+      {
+        "label": "南山区",
+        "value": "440305"
+      },
+      {
+        "label": "宝安区",
+        "value": "440306"
+      },
+      {
+        "label": "龙岗区",
+        "value": "440307"
+      },
+      {
+        "label": "盐田区",
+        "value": "440308"
+      },
+      {
+        "label": "龙华区",
+        "value": "440309"
+      },
+      {
+        "label": "坪山区",
+        "value": "440310"
+      }
+    ],
+    [{
+        "label": "香洲区",
+        "value": "440402"
+      },
+      {
+        "label": "斗门区",
+        "value": "440403"
+      },
+      {
+        "label": "金湾区",
+        "value": "440404"
+      }
+    ],
+    [{
+        "label": "龙湖区",
+        "value": "440507"
+      },
+      {
+        "label": "金平区",
+        "value": "440511"
+      },
+      {
+        "label": "濠江区",
+        "value": "440512"
+      },
+      {
+        "label": "潮阳区",
+        "value": "440513"
+      },
+      {
+        "label": "潮南区",
+        "value": "440514"
+      },
+      {
+        "label": "澄海区",
+        "value": "440515"
+      },
+      {
+        "label": "南澳县",
+        "value": "440523"
+      }
+    ],
+    [{
+        "label": "禅城区",
+        "value": "440604"
+      },
+      {
+        "label": "南海区",
+        "value": "440605"
+      },
+      {
+        "label": "顺德区",
+        "value": "440606"
+      },
+      {
+        "label": "三水区",
+        "value": "440607"
+      },
+      {
+        "label": "高明区",
+        "value": "440608"
+      }
+    ],
+    [{
+        "label": "蓬江区",
+        "value": "440703"
+      },
+      {
+        "label": "江海区",
+        "value": "440704"
+      },
+      {
+        "label": "新会区",
+        "value": "440705"
+      },
+      {
+        "label": "台山市",
+        "value": "440781"
+      },
+      {
+        "label": "开平市",
+        "value": "440783"
+      },
+      {
+        "label": "鹤山市",
+        "value": "440784"
+      },
+      {
+        "label": "恩平市",
+        "value": "440785"
+      }
+    ],
+    [{
+        "label": "赤坎区",
+        "value": "440802"
+      },
+      {
+        "label": "霞山区",
+        "value": "440803"
+      },
+      {
+        "label": "坡头区",
+        "value": "440804"
+      },
+      {
+        "label": "麻章区",
+        "value": "440811"
+      },
+      {
+        "label": "遂溪县",
+        "value": "440823"
+      },
+      {
+        "label": "徐闻县",
+        "value": "440825"
+      },
+      {
+        "label": "廉江市",
+        "value": "440881"
+      },
+      {
+        "label": "雷州市",
+        "value": "440882"
+      },
+      {
+        "label": "吴川市",
+        "value": "440883"
+      }
+    ],
+    [{
+        "label": "茂南区",
+        "value": "440902"
+      },
+      {
+        "label": "电白区",
+        "value": "440904"
+      },
+      {
+        "label": "高州市",
+        "value": "440981"
+      },
+      {
+        "label": "化州市",
+        "value": "440982"
+      },
+      {
+        "label": "信宜市",
+        "value": "440983"
+      }
+    ],
+    [{
+        "label": "端州区",
+        "value": "441202"
+      },
+      {
+        "label": "鼎湖区",
+        "value": "441203"
+      },
+      {
+        "label": "高要区",
+        "value": "441204"
+      },
+      {
+        "label": "广宁县",
+        "value": "441223"
+      },
+      {
+        "label": "怀集县",
+        "value": "441224"
+      },
+      {
+        "label": "封开县",
+        "value": "441225"
+      },
+      {
+        "label": "德庆县",
+        "value": "441226"
+      },
+      {
+        "label": "四会市",
+        "value": "441284"
+      }
+    ],
+    [{
+        "label": "惠城区",
+        "value": "441302"
+      },
+      {
+        "label": "惠阳区",
+        "value": "441303"
+      },
+      {
+        "label": "博罗县",
+        "value": "441322"
+      },
+      {
+        "label": "惠东县",
+        "value": "441323"
+      },
+      {
+        "label": "龙门县",
+        "value": "441324"
+      }
+    ],
+    [{
+        "label": "梅江区",
+        "value": "441402"
+      },
+      {
+        "label": "梅县区",
+        "value": "441403"
+      },
+      {
+        "label": "大埔县",
+        "value": "441422"
+      },
+      {
+        "label": "丰顺县",
+        "value": "441423"
+      },
+      {
+        "label": "五华县",
+        "value": "441424"
+      },
+      {
+        "label": "平远县",
+        "value": "441426"
+      },
+      {
+        "label": "蕉岭县",
+        "value": "441427"
+      },
+      {
+        "label": "兴宁市",
+        "value": "441481"
+      }
+    ],
+    [{
+        "label": "城区",
+        "value": "441502"
+      },
+      {
+        "label": "海丰县",
+        "value": "441521"
+      },
+      {
+        "label": "陆河县",
+        "value": "441523"
+      },
+      {
+        "label": "陆丰市",
+        "value": "441581"
+      }
+    ],
+    [{
+        "label": "源城区",
+        "value": "441602"
+      },
+      {
+        "label": "紫金县",
+        "value": "441621"
+      },
+      {
+        "label": "龙川县",
+        "value": "441622"
+      },
+      {
+        "label": "连平县",
+        "value": "441623"
+      },
+      {
+        "label": "和平县",
+        "value": "441624"
+      },
+      {
+        "label": "东源县",
+        "value": "441625"
+      }
+    ],
+    [{
+        "label": "江城区",
+        "value": "441702"
+      },
+      {
+        "label": "阳东区",
+        "value": "441704"
+      },
+      {
+        "label": "阳西县",
+        "value": "441721"
+      },
+      {
+        "label": "阳春市",
+        "value": "441781"
+      }
+    ],
+    [{
+        "label": "清城区",
+        "value": "441802"
+      },
+      {
+        "label": "清新区",
+        "value": "441803"
+      },
+      {
+        "label": "佛冈县",
+        "value": "441821"
+      },
+      {
+        "label": "阳山县",
+        "value": "441823"
+      },
+      {
+        "label": "连山壮族瑶族自治县",
+        "value": "441825"
+      },
+      {
+        "label": "连南瑶族自治县",
+        "value": "441826"
+      },
+      {
+        "label": "英德市",
+        "value": "441881"
+      },
+      {
+        "label": "连州市",
+        "value": "441882"
+      }
+    ],
+    [{
+      "label": "东莞市",
+      "value": "441900"
+    }],
+    [{
+      "label": "中山市",
+      "value": "442000"
+    }],
+    [{
+        "label": "湘桥区",
+        "value": "445102"
+      },
+      {
+        "label": "潮安区",
+        "value": "445103"
+      },
+      {
+        "label": "饶平县",
+        "value": "445122"
+      }
+    ],
+    [{
+        "label": "榕城区",
+        "value": "445202"
+      },
+      {
+        "label": "揭东区",
+        "value": "445203"
+      },
+      {
+        "label": "揭西县",
+        "value": "445222"
+      },
+      {
+        "label": "惠来县",
+        "value": "445224"
+      },
+      {
+        "label": "普宁市",
+        "value": "445281"
+      }
+    ],
+    [{
+        "label": "云城区",
+        "value": "445302"
+      },
+      {
+        "label": "云安区",
+        "value": "445303"
+      },
+      {
+        "label": "新兴县",
+        "value": "445321"
+      },
+      {
+        "label": "郁南县",
+        "value": "445322"
+      },
+      {
+        "label": "罗定市",
+        "value": "445381"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "兴宁区",
+        "value": "450102"
+      },
+      {
+        "label": "青秀区",
+        "value": "450103"
+      },
+      {
+        "label": "江南区",
+        "value": "450105"
+      },
+      {
+        "label": "西乡塘区",
+        "value": "450107"
+      },
+      {
+        "label": "良庆区",
+        "value": "450108"
+      },
+      {
+        "label": "邕宁区",
+        "value": "450109"
+      },
+      {
+        "label": "武鸣区",
+        "value": "450110"
+      },
+      {
+        "label": "隆安县",
+        "value": "450123"
+      },
+      {
+        "label": "马山县",
+        "value": "450124"
+      },
+      {
+        "label": "上林县",
+        "value": "450125"
+      },
+      {
+        "label": "宾阳县",
+        "value": "450126"
+      },
+      {
+        "label": "横县",
+        "value": "450127"
+      }
+    ],
+    [{
+        "label": "城中区",
+        "value": "450202"
+      },
+      {
+        "label": "鱼峰区",
+        "value": "450203"
+      },
+      {
+        "label": "柳南区",
+        "value": "450204"
+      },
+      {
+        "label": "柳北区",
+        "value": "450205"
+      },
+      {
+        "label": "柳江区",
+        "value": "450206"
+      },
+      {
+        "label": "柳城县",
+        "value": "450222"
+      },
+      {
+        "label": "鹿寨县",
+        "value": "450223"
+      },
+      {
+        "label": "融安县",
+        "value": "450224"
+      },
+      {
+        "label": "融水苗族自治县",
+        "value": "450225"
+      },
+      {
+        "label": "三江侗族自治县",
+        "value": "450226"
+      }
+    ],
+    [{
+        "label": "秀峰区",
+        "value": "450302"
+      },
+      {
+        "label": "叠彩区",
+        "value": "450303"
+      },
+      {
+        "label": "象山区",
+        "value": "450304"
+      },
+      {
+        "label": "七星区",
+        "value": "450305"
+      },
+      {
+        "label": "雁山区",
+        "value": "450311"
+      },
+      {
+        "label": "临桂区",
+        "value": "450312"
+      },
+      {
+        "label": "阳朔县",
+        "value": "450321"
+      },
+      {
+        "label": "灵川县",
+        "value": "450323"
+      },
+      {
+        "label": "全州县",
+        "value": "450324"
+      },
+      {
+        "label": "兴安县",
+        "value": "450325"
+      },
+      {
+        "label": "永福县",
+        "value": "450326"
+      },
+      {
+        "label": "灌阳县",
+        "value": "450327"
+      },
+      {
+        "label": "龙胜各族自治县",
+        "value": "450328"
+      },
+      {
+        "label": "资源县",
+        "value": "450329"
+      },
+      {
+        "label": "平乐县",
+        "value": "450330"
+      },
+      {
+        "label": "荔浦县",
+        "value": "450331"
+      },
+      {
+        "label": "恭城瑶族自治县",
+        "value": "450332"
+      }
+    ],
+    [{
+        "label": "万秀区",
+        "value": "450403"
+      },
+      {
+        "label": "长洲区",
+        "value": "450405"
+      },
+      {
+        "label": "龙圩区",
+        "value": "450406"
+      },
+      {
+        "label": "苍梧县",
+        "value": "450421"
+      },
+      {
+        "label": "藤县",
+        "value": "450422"
+      },
+      {
+        "label": "蒙山县",
+        "value": "450423"
+      },
+      {
+        "label": "岑溪市",
+        "value": "450481"
+      }
+    ],
+    [{
+        "label": "海城区",
+        "value": "450502"
+      },
+      {
+        "label": "银海区",
+        "value": "450503"
+      },
+      {
+        "label": "铁山港区",
+        "value": "450512"
+      },
+      {
+        "label": "合浦县",
+        "value": "450521"
+      }
+    ],
+    [{
+        "label": "港口区",
+        "value": "450602"
+      },
+      {
+        "label": "防城区",
+        "value": "450603"
+      },
+      {
+        "label": "上思县",
+        "value": "450621"
+      },
+      {
+        "label": "东兴市",
+        "value": "450681"
+      }
+    ],
+    [{
+        "label": "钦南区",
+        "value": "450702"
+      },
+      {
+        "label": "钦北区",
+        "value": "450703"
+      },
+      {
+        "label": "灵山县",
+        "value": "450721"
+      },
+      {
+        "label": "浦北县",
+        "value": "450722"
+      }
+    ],
+    [{
+        "label": "港北区",
+        "value": "450802"
+      },
+      {
+        "label": "港南区",
+        "value": "450803"
+      },
+      {
+        "label": "覃塘区",
+        "value": "450804"
+      },
+      {
+        "label": "平南县",
+        "value": "450821"
+      },
+      {
+        "label": "桂平市",
+        "value": "450881"
+      }
+    ],
+    [{
+        "label": "玉州区",
+        "value": "450902"
+      },
+      {
+        "label": "福绵区",
+        "value": "450903"
+      },
+      {
+        "label": "容县",
+        "value": "450921"
+      },
+      {
+        "label": "陆川县",
+        "value": "450922"
+      },
+      {
+        "label": "博白县",
+        "value": "450923"
+      },
+      {
+        "label": "兴业县",
+        "value": "450924"
+      },
+      {
+        "label": "北流市",
+        "value": "450981"
+      }
+    ],
+    [{
+        "label": "右江区",
+        "value": "451002"
+      },
+      {
+        "label": "田阳县",
+        "value": "451021"
+      },
+      {
+        "label": "田东县",
+        "value": "451022"
+      },
+      {
+        "label": "平果县",
+        "value": "451023"
+      },
+      {
+        "label": "德保县",
+        "value": "451024"
+      },
+      {
+        "label": "那坡县",
+        "value": "451026"
+      },
+      {
+        "label": "凌云县",
+        "value": "451027"
+      },
+      {
+        "label": "乐业县",
+        "value": "451028"
+      },
+      {
+        "label": "田林县",
+        "value": "451029"
+      },
+      {
+        "label": "西林县",
+        "value": "451030"
+      },
+      {
+        "label": "隆林各族自治县",
+        "value": "451031"
+      },
+      {
+        "label": "靖西市",
+        "value": "451081"
+      }
+    ],
+    [{
+        "label": "八步区",
+        "value": "451102"
+      },
+      {
+        "label": "平桂区",
+        "value": "451103"
+      },
+      {
+        "label": "昭平县",
+        "value": "451121"
+      },
+      {
+        "label": "钟山县",
+        "value": "451122"
+      },
+      {
+        "label": "富川瑶族自治县",
+        "value": "451123"
+      }
+    ],
+    [{
+        "label": "金城江区",
+        "value": "451202"
+      },
+      {
+        "label": "宜州区",
+        "value": "451203"
+      },
+      {
+        "label": "南丹县",
+        "value": "451221"
+      },
+      {
+        "label": "天峨县",
+        "value": "451222"
+      },
+      {
+        "label": "凤山县",
+        "value": "451223"
+      },
+      {
+        "label": "东兰县",
+        "value": "451224"
+      },
+      {
+        "label": "罗城仫佬族自治县",
+        "value": "451225"
+      },
+      {
+        "label": "环江毛南族自治县",
+        "value": "451226"
+      },
+      {
+        "label": "巴马瑶族自治县",
+        "value": "451227"
+      },
+      {
+        "label": "都安瑶族自治县",
+        "value": "451228"
+      },
+      {
+        "label": "大化瑶族自治县",
+        "value": "451229"
+      }
+    ],
+    [{
+        "label": "兴宾区",
+        "value": "451302"
+      },
+      {
+        "label": "忻城县",
+        "value": "451321"
+      },
+      {
+        "label": "象州县",
+        "value": "451322"
+      },
+      {
+        "label": "武宣县",
+        "value": "451323"
+      },
+      {
+        "label": "金秀瑶族自治县",
+        "value": "451324"
+      },
+      {
+        "label": "合山市",
+        "value": "451381"
+      }
+    ],
+    [{
+        "label": "江州区",
+        "value": "451402"
+      },
+      {
+        "label": "扶绥县",
+        "value": "451421"
+      },
+      {
+        "label": "宁明县",
+        "value": "451422"
+      },
+      {
+        "label": "龙州县",
+        "value": "451423"
+      },
+      {
+        "label": "大新县",
+        "value": "451424"
+      },
+      {
+        "label": "天等县",
+        "value": "451425"
+      },
+      {
+        "label": "凭祥市",
+        "value": "451481"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "秀英区",
+        "value": "460105"
+      },
+      {
+        "label": "龙华区",
+        "value": "460106"
+      },
+      {
+        "label": "琼山区",
+        "value": "460107"
+      },
+      {
+        "label": "美兰区",
+        "value": "460108"
+      }
+    ],
+    [{
+        "label": "海棠区",
+        "value": "460202"
+      },
+      {
+        "label": "吉阳区",
+        "value": "460203"
+      },
+      {
+        "label": "天涯区",
+        "value": "460204"
+      },
+      {
+        "label": "崖州区",
+        "value": "460205"
+      }
+    ],
+    [{
+        "label": "西沙群岛",
+        "value": "460321"
+      },
+      {
+        "label": "南沙群岛",
+        "value": "460322"
+      },
+      {
+        "label": "中沙群岛的岛礁及其海域",
+        "value": "460323"
+      }
+    ],
+    [{
+      "label": "儋州市",
+      "value": "460400"
+    }],
+    [{
+        "label": "五指山市",
+        "value": "469001"
+      },
+      {
+        "label": "琼海市",
+        "value": "469002"
+      },
+      {
+        "label": "文昌市",
+        "value": "469005"
+      },
+      {
+        "label": "万宁市",
+        "value": "469006"
+      },
+      {
+        "label": "东方市",
+        "value": "469007"
+      },
+      {
+        "label": "定安县",
+        "value": "469021"
+      },
+      {
+        "label": "屯昌县",
+        "value": "469022"
+      },
+      {
+        "label": "澄迈县",
+        "value": "469023"
+      },
+      {
+        "label": "临高县",
+        "value": "469024"
+      },
+      {
+        "label": "白沙黎族自治县",
+        "value": "469025"
+      },
+      {
+        "label": "昌江黎族自治县",
+        "value": "469026"
+      },
+      {
+        "label": "乐东黎族自治县",
+        "value": "469027"
+      },
+      {
+        "label": "陵水黎族自治县",
+        "value": "469028"
+      },
+      {
+        "label": "保亭黎族苗族自治县",
+        "value": "469029"
+      },
+      {
+        "label": "琼中黎族苗族自治县",
+        "value": "469030"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "万州区",
+        "value": "500101"
+      },
+      {
+        "label": "涪陵区",
+        "value": "500102"
+      },
+      {
+        "label": "渝中区",
+        "value": "500103"
+      },
+      {
+        "label": "大渡口区",
+        "value": "500104"
+      },
+      {
+        "label": "江北区",
+        "value": "500105"
+      },
+      {
+        "label": "沙坪坝区",
+        "value": "500106"
+      },
+      {
+        "label": "九龙坡区",
+        "value": "500107"
+      },
+      {
+        "label": "南岸区",
+        "value": "500108"
+      },
+      {
+        "label": "北碚区",
+        "value": "500109"
+      },
+      {
+        "label": "綦江区",
+        "value": "500110"
+      },
+      {
+        "label": "大足区",
+        "value": "500111"
+      },
+      {
+        "label": "渝北区",
+        "value": "500112"
+      },
+      {
+        "label": "巴南区",
+        "value": "500113"
+      },
+      {
+        "label": "黔江区",
+        "value": "500114"
+      },
+      {
+        "label": "长寿区",
+        "value": "500115"
+      },
+      {
+        "label": "江津区",
+        "value": "500116"
+      },
+      {
+        "label": "合川区",
+        "value": "500117"
+      },
+      {
+        "label": "永川区",
+        "value": "500118"
+      },
+      {
+        "label": "南川区",
+        "value": "500119"
+      },
+      {
+        "label": "璧山区",
+        "value": "500120"
+      },
+      {
+        "label": "铜梁区",
+        "value": "500151"
+      },
+      {
+        "label": "潼南区",
+        "value": "500152"
+      },
+      {
+        "label": "荣昌区",
+        "value": "500153"
+      },
+      {
+        "label": "开州区",
+        "value": "500154"
+      },
+      {
+        "label": "梁平区",
+        "value": "500155"
+      },
+      {
+        "label": "武隆区",
+        "value": "500156"
+      }
+    ],
+    [{
+        "label": "梁平县",
+        "value": "500228"
+      },{
+        "label": "城口县",
+        "value": "500229"
+      },
+      {
+        "label": "丰都县",
+        "value": "500230"
+      },
+      {
+        "label": "垫江县",
+        "value": "500231"
+      },
+      {
+        "label": "忠县",
+        "value": "500233"
+      },
+      {
+        "label": "云阳县",
+        "value": "500235"
+      },
+      {
+        "label": "奉节县",
+        "value": "500236"
+      },
+      {
+        "label": "巫山县",
+        "value": "500237"
+      },
+      {
+        "label": "巫溪县",
+        "value": "500238"
+      },
+      {
+        "label": "石柱土家族自治县",
+        "value": "500240"
+      },
+      {
+        "label": "秀山土家族苗族自治县",
+        "value": "500241"
+      },
+      {
+        "label": "酉阳土家族苗族自治县",
+        "value": "500242"
+      },
+      {
+        "label": "彭水苗族土家族自治县",
+        "value": "500243"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "锦江区",
+        "value": "510104"
+      },
+      {
+        "label": "青羊区",
+        "value": "510105"
+      },
+      {
+        "label": "金牛区",
+        "value": "510106"
+      },
+      {
+        "label": "武侯区",
+        "value": "510107"
+      },
+      {
+        "label": "成华区",
+        "value": "510108"
+      },
+      {
+        "label": "龙泉驿区",
+        "value": "510112"
+      },
+      {
+        "label": "青白江区",
+        "value": "510113"
+      },
+      {
+        "label": "新都区",
+        "value": "510114"
+      },
+      {
+        "label": "温江区",
+        "value": "510115"
+      },
+      {
+        "label": "双流区",
+        "value": "510116"
+      },
+      {
+        "label": "郫都区",
+        "value": "510117"
+      },
+      {
+        "label": "金堂县",
+        "value": "510121"
+      },
+      {
+        "label": "大邑县",
+        "value": "510129"
+      },
+      {
+        "label": "蒲江县",
+        "value": "510131"
+      },
+      {
+        "label": "新津县",
+        "value": "510132"
+      },
+      {
+        "label": "都江堰市",
+        "value": "510181"
+      },
+      {
+        "label": "彭州市",
+        "value": "510182"
+      },
+      {
+        "label": "邛崃市",
+        "value": "510183"
+      },
+      {
+        "label": "崇州市",
+        "value": "510184"
+      },
+      {
+        "label": "简阳市",
+        "value": "510185"
+      }
+    ],
+    [{
+        "label": "自流井区",
+        "value": "510302"
+      },
+      {
+        "label": "贡井区",
+        "value": "510303"
+      },
+      {
+        "label": "大安区",
+        "value": "510304"
+      },
+      {
+        "label": "沿滩区",
+        "value": "510311"
+      },
+      {
+        "label": "荣县",
+        "value": "510321"
+      },
+      {
+        "label": "富顺县",
+        "value": "510322"
+      }
+    ],
+    [{
+        "label": "东区",
+        "value": "510402"
+      },
+      {
+        "label": "西区",
+        "value": "510403"
+      },
+      {
+        "label": "仁和区",
+        "value": "510411"
+      },
+      {
+        "label": "米易县",
+        "value": "510421"
+      },
+      {
+        "label": "盐边县",
+        "value": "510422"
+      }
+    ],
+    [{
+        "label": "江阳区",
+        "value": "510502"
+      },
+      {
+        "label": "纳溪区",
+        "value": "510503"
+      },
+      {
+        "label": "龙马潭区",
+        "value": "510504"
+      },
+      {
+        "label": "泸县",
+        "value": "510521"
+      },
+      {
+        "label": "合江县",
+        "value": "510522"
+      },
+      {
+        "label": "叙永县",
+        "value": "510524"
+      },
+      {
+        "label": "古蔺县",
+        "value": "510525"
+      }
+    ],
+    [{
+        "label": "旌阳区",
+        "value": "510603"
+      },
+      {
+        "label": "罗江区",
+        "value": "510604"
+      },
+      {
+        "label": "中江县",
+        "value": "510623"
+      },
+      {
+        "label": "广汉市",
+        "value": "510681"
+      },
+      {
+        "label": "什邡市",
+        "value": "510682"
+      },
+      {
+        "label": "绵竹市",
+        "value": "510683"
+      }
+    ],
+    [{
+        "label": "涪城区",
+        "value": "510703"
+      },
+      {
+        "label": "游仙区",
+        "value": "510704"
+      },
+      {
+        "label": "安州区",
+        "value": "510705"
+      },
+      {
+        "label": "三台县",
+        "value": "510722"
+      },
+      {
+        "label": "盐亭县",
+        "value": "510723"
+      },
+      {
+        "label": "梓潼县",
+        "value": "510725"
+      },
+      {
+        "label": "北川羌族自治县",
+        "value": "510726"
+      },
+      {
+        "label": "平武县",
+        "value": "510727"
+      },
+      {
+        "label": "江油市",
+        "value": "510781"
+      }
+    ],
+    [{
+        "label": "利州区",
+        "value": "510802"
+      },
+      {
+        "label": "昭化区",
+        "value": "510811"
+      },
+      {
+        "label": "朝天区",
+        "value": "510812"
+      },
+      {
+        "label": "旺苍县",
+        "value": "510821"
+      },
+      {
+        "label": "青川县",
+        "value": "510822"
+      },
+      {
+        "label": "剑阁县",
+        "value": "510823"
+      },
+      {
+        "label": "苍溪县",
+        "value": "510824"
+      }
+    ],
+    [{
+        "label": "船山区",
+        "value": "510903"
+      },
+      {
+        "label": "安居区",
+        "value": "510904"
+      },
+      {
+        "label": "蓬溪县",
+        "value": "510921"
+      },
+      {
+        "label": "射洪县",
+        "value": "510922"
+      },
+      {
+        "label": "大英县",
+        "value": "510923"
+      }
+    ],
+    [{
+        "label": "市中区",
+        "value": "511002"
+      },
+      {
+        "label": "东兴区",
+        "value": "511011"
+      },
+      {
+        "label": "威远县",
+        "value": "511024"
+      },
+      {
+        "label": "资中县",
+        "value": "511025"
+      },
+      {
+        "label": "内江经济开发区",
+        "value": "511071"
+      },
+      {
+        "label": "隆昌市",
+        "value": "511083"
+      }
+    ],
+    [{
+        "label": "市中区",
+        "value": "511102"
+      },
+      {
+        "label": "沙湾区",
+        "value": "511111"
+      },
+      {
+        "label": "五通桥区",
+        "value": "511112"
+      },
+      {
+        "label": "金口河区",
+        "value": "511113"
+      },
+      {
+        "label": "犍为县",
+        "value": "511123"
+      },
+      {
+        "label": "井研县",
+        "value": "511124"
+      },
+      {
+        "label": "夹江县",
+        "value": "511126"
+      },
+      {
+        "label": "沐川县",
+        "value": "511129"
+      },
+      {
+        "label": "峨边彝族自治县",
+        "value": "511132"
+      },
+      {
+        "label": "马边彝族自治县",
+        "value": "511133"
+      },
+      {
+        "label": "峨眉山市",
+        "value": "511181"
+      }
+    ],
+    [{
+        "label": "顺庆区",
+        "value": "511302"
+      },
+      {
+        "label": "高坪区",
+        "value": "511303"
+      },
+      {
+        "label": "嘉陵区",
+        "value": "511304"
+      },
+      {
+        "label": "南部县",
+        "value": "511321"
+      },
+      {
+        "label": "营山县",
+        "value": "511322"
+      },
+      {
+        "label": "蓬安县",
+        "value": "511323"
+      },
+      {
+        "label": "仪陇县",
+        "value": "511324"
+      },
+      {
+        "label": "西充县",
+        "value": "511325"
+      },
+      {
+        "label": "阆中市",
+        "value": "511381"
+      }
+    ],
+    [{
+        "label": "东坡区",
+        "value": "511402"
+      },
+      {
+        "label": "彭山区",
+        "value": "511403"
+      },
+      {
+        "label": "仁寿县",
+        "value": "511421"
+      },
+      {
+        "label": "洪雅县",
+        "value": "511423"
+      },
+      {
+        "label": "丹棱县",
+        "value": "511424"
+      },
+      {
+        "label": "青神县",
+        "value": "511425"
+      }
+    ],
+    [{
+        "label": "翠屏区",
+        "value": "511502"
+      },
+      {
+        "label": "南溪区",
+        "value": "511503"
+      },
+      {
+        "label": "宜宾县",
+        "value": "511521"
+      },
+      {
+        "label": "江安县",
+        "value": "511523"
+      },
+      {
+        "label": "长宁县",
+        "value": "511524"
+      },
+      {
+        "label": "高县",
+        "value": "511525"
+      },
+      {
+        "label": "珙县",
+        "value": "511526"
+      },
+      {
+        "label": "筠连县",
+        "value": "511527"
+      },
+      {
+        "label": "兴文县",
+        "value": "511528"
+      },
+      {
+        "label": "屏山县",
+        "value": "511529"
+      }
+    ],
+    [{
+        "label": "广安区",
+        "value": "511602"
+      },
+      {
+        "label": "前锋区",
+        "value": "511603"
+      },
+      {
+        "label": "岳池县",
+        "value": "511621"
+      },
+      {
+        "label": "武胜县",
+        "value": "511622"
+      },
+      {
+        "label": "邻水县",
+        "value": "511623"
+      },
+      {
+        "label": "华蓥市",
+        "value": "511681"
+      }
+    ],
+    [{
+        "label": "通川区",
+        "value": "511702"
+      },
+      {
+        "label": "达川区",
+        "value": "511703"
+      },
+      {
+        "label": "宣汉县",
+        "value": "511722"
+      },
+      {
+        "label": "开江县",
+        "value": "511723"
+      },
+      {
+        "label": "大竹县",
+        "value": "511724"
+      },
+      {
+        "label": "渠县",
+        "value": "511725"
+      },
+      {
+        "label": "达州经济开发区",
+        "value": "511771"
+      },
+      {
+        "label": "万源市",
+        "value": "511781"
+      }
+    ],
+    [{
+        "label": "雨城区",
+        "value": "511802"
+      },
+      {
+        "label": "名山区",
+        "value": "511803"
+      },
+      {
+        "label": "荥经县",
+        "value": "511822"
+      },
+      {
+        "label": "汉源县",
+        "value": "511823"
+      },
+      {
+        "label": "石棉县",
+        "value": "511824"
+      },
+      {
+        "label": "天全县",
+        "value": "511825"
+      },
+      {
+        "label": "芦山县",
+        "value": "511826"
+      },
+      {
+        "label": "宝兴县",
+        "value": "511827"
+      }
+    ],
+    [{
+        "label": "巴州区",
+        "value": "511902"
+      },
+      {
+        "label": "恩阳区",
+        "value": "511903"
+      },
+      {
+        "label": "通江县",
+        "value": "511921"
+      },
+      {
+        "label": "南江县",
+        "value": "511922"
+      },
+      {
+        "label": "平昌县",
+        "value": "511923"
+      },
+      {
+        "label": "巴中经济开发区",
+        "value": "511971"
+      }
+    ],
+    [{
+        "label": "雁江区",
+        "value": "512002"
+      },
+      {
+        "label": "安岳县",
+        "value": "512021"
+      },
+      {
+        "label": "乐至县",
+        "value": "512022"
+      }
+    ],
+    [{
+        "label": "马尔康市",
+        "value": "513201"
+      },
+      {
+        "label": "汶川县",
+        "value": "513221"
+      },
+      {
+        "label": "理县",
+        "value": "513222"
+      },
+      {
+        "label": "茂县",
+        "value": "513223"
+      },
+      {
+        "label": "松潘县",
+        "value": "513224"
+      },
+      {
+        "label": "九寨沟县",
+        "value": "513225"
+      },
+      {
+        "label": "金川县",
+        "value": "513226"
+      },
+      {
+        "label": "小金县",
+        "value": "513227"
+      },
+      {
+        "label": "黑水县",
+        "value": "513228"
+      },
+      {
+        "label": "壤塘县",
+        "value": "513230"
+      },
+      {
+        "label": "阿坝县",
+        "value": "513231"
+      },
+      {
+        "label": "若尔盖县",
+        "value": "513232"
+      },
+      {
+        "label": "红原县",
+        "value": "513233"
+      }
+    ],
+    [{
+        "label": "康定市",
+        "value": "513301"
+      },
+      {
+        "label": "泸定县",
+        "value": "513322"
+      },
+      {
+        "label": "丹巴县",
+        "value": "513323"
+      },
+      {
+        "label": "九龙县",
+        "value": "513324"
+      },
+      {
+        "label": "雅江县",
+        "value": "513325"
+      },
+      {
+        "label": "道孚县",
+        "value": "513326"
+      },
+      {
+        "label": "炉霍县",
+        "value": "513327"
+      },
+      {
+        "label": "甘孜县",
+        "value": "513328"
+      },
+      {
+        "label": "新龙县",
+        "value": "513329"
+      },
+      {
+        "label": "德格县",
+        "value": "513330"
+      },
+      {
+        "label": "白玉县",
+        "value": "513331"
+      },
+      {
+        "label": "石渠县",
+        "value": "513332"
+      },
+      {
+        "label": "色达县",
+        "value": "513333"
+      },
+      {
+        "label": "理塘县",
+        "value": "513334"
+      },
+      {
+        "label": "巴塘县",
+        "value": "513335"
+      },
+      {
+        "label": "乡城县",
+        "value": "513336"
+      },
+      {
+        "label": "稻城县",
+        "value": "513337"
+      },
+      {
+        "label": "得荣县",
+        "value": "513338"
+      }
+    ],
+    [{
+        "label": "西昌市",
+        "value": "513401"
+      },
+      {
+        "label": "木里藏族自治县",
+        "value": "513422"
+      },
+      {
+        "label": "盐源县",
+        "value": "513423"
+      },
+      {
+        "label": "德昌县",
+        "value": "513424"
+      },
+      {
+        "label": "会理县",
+        "value": "513425"
+      },
+      {
+        "label": "会东县",
+        "value": "513426"
+      },
+      {
+        "label": "宁南县",
+        "value": "513427"
+      },
+      {
+        "label": "普格县",
+        "value": "513428"
+      },
+      {
+        "label": "布拖县",
+        "value": "513429"
+      },
+      {
+        "label": "金阳县",
+        "value": "513430"
+      },
+      {
+        "label": "昭觉县",
+        "value": "513431"
+      },
+      {
+        "label": "喜德县",
+        "value": "513432"
+      },
+      {
+        "label": "冕宁县",
+        "value": "513433"
+      },
+      {
+        "label": "越西县",
+        "value": "513434"
+      },
+      {
+        "label": "甘洛县",
+        "value": "513435"
+      },
+      {
+        "label": "美姑县",
+        "value": "513436"
+      },
+      {
+        "label": "雷波县",
+        "value": "513437"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "南明区",
+        "value": "520102"
+      },
+      {
+        "label": "云岩区",
+        "value": "520103"
+      },
+      {
+        "label": "花溪区",
+        "value": "520111"
+      },
+      {
+        "label": "乌当区",
+        "value": "520112"
+      },
+      {
+        "label": "白云区",
+        "value": "520113"
+      },
+      {
+        "label": "观山湖区",
+        "value": "520115"
+      },
+      {
+        "label": "开阳县",
+        "value": "520121"
+      },
+      {
+        "label": "息烽县",
+        "value": "520122"
+      },
+      {
+        "label": "修文县",
+        "value": "520123"
+      },
+      {
+        "label": "清镇市",
+        "value": "520181"
+      }
+    ],
+    [{
+        "label": "钟山区",
+        "value": "520201"
+      },
+      {
+        "label": "六枝特区",
+        "value": "520203"
+      },
+      {
+        "label": "水城县",
+        "value": "520221"
+      },
+      {
+        "label": "盘州市",
+        "value": "520281"
+      }
+    ],
+    [{
+        "label": "红花岗区",
+        "value": "520302"
+      },
+      {
+        "label": "汇川区",
+        "value": "520303"
+      },
+      {
+        "label": "播州区",
+        "value": "520304"
+      },
+      {
+        "label": "桐梓县",
+        "value": "520322"
+      },
+      {
+        "label": "绥阳县",
+        "value": "520323"
+      },
+      {
+        "label": "正安县",
+        "value": "520324"
+      },
+      {
+        "label": "道真仡佬族苗族自治县",
+        "value": "520325"
+      },
+      {
+        "label": "务川仡佬族苗族自治县",
+        "value": "520326"
+      },
+      {
+        "label": "凤冈县",
+        "value": "520327"
+      },
+      {
+        "label": "湄潭县",
+        "value": "520328"
+      },
+      {
+        "label": "余庆县",
+        "value": "520329"
+      },
+      {
+        "label": "习水县",
+        "value": "520330"
+      },
+      {
+        "label": "赤水市",
+        "value": "520381"
+      },
+      {
+        "label": "仁怀市",
+        "value": "520382"
+      }
+    ],
+    [{
+        "label": "西秀区",
+        "value": "520402"
+      },
+      {
+        "label": "平坝区",
+        "value": "520403"
+      },
+      {
+        "label": "普定县",
+        "value": "520422"
+      },
+      {
+        "label": "镇宁布依族苗族自治县",
+        "value": "520423"
+      },
+      {
+        "label": "关岭布依族苗族自治县",
+        "value": "520424"
+      },
+      {
+        "label": "紫云苗族布依族自治县",
+        "value": "520425"
+      }
+    ],
+    [{
+        "label": "七星关区",
+        "value": "520502"
+      },
+      {
+        "label": "大方县",
+        "value": "520521"
+      },
+      {
+        "label": "黔西县",
+        "value": "520522"
+      },
+      {
+        "label": "金沙县",
+        "value": "520523"
+      },
+      {
+        "label": "织金县",
+        "value": "520524"
+      },
+      {
+        "label": "纳雍县",
+        "value": "520525"
+      },
+      {
+        "label": "威宁彝族回族苗族自治县",
+        "value": "520526"
+      },
+      {
+        "label": "赫章县",
+        "value": "520527"
+      }
+    ],
+    [{
+        "label": "碧江区",
+        "value": "520602"
+      },
+      {
+        "label": "万山区",
+        "value": "520603"
+      },
+      {
+        "label": "江口县",
+        "value": "520621"
+      },
+      {
+        "label": "玉屏侗族自治县",
+        "value": "520622"
+      },
+      {
+        "label": "石阡县",
+        "value": "520623"
+      },
+      {
+        "label": "思南县",
+        "value": "520624"
+      },
+      {
+        "label": "印江土家族苗族自治县",
+        "value": "520625"
+      },
+      {
+        "label": "德江县",
+        "value": "520626"
+      },
+      {
+        "label": "沿河土家族自治县",
+        "value": "520627"
+      },
+      {
+        "label": "松桃苗族自治县",
+        "value": "520628"
+      }
+    ],
+    [{
+        "label": "兴义市",
+        "value": "522301"
+      },
+      {
+        "label": "兴仁县",
+        "value": "522322"
+      },
+      {
+        "label": "普安县",
+        "value": "522323"
+      },
+      {
+        "label": "晴隆县",
+        "value": "522324"
+      },
+      {
+        "label": "贞丰县",
+        "value": "522325"
+      },
+      {
+        "label": "望谟县",
+        "value": "522326"
+      },
+      {
+        "label": "册亨县",
+        "value": "522327"
+      },
+      {
+        "label": "安龙县",
+        "value": "522328"
+      }
+    ],
+    [{
+        "label": "凯里市",
+        "value": "522601"
+      },
+      {
+        "label": "黄平县",
+        "value": "522622"
+      },
+      {
+        "label": "施秉县",
+        "value": "522623"
+      },
+      {
+        "label": "三穗县",
+        "value": "522624"
+      },
+      {
+        "label": "镇远县",
+        "value": "522625"
+      },
+      {
+        "label": "岑巩县",
+        "value": "522626"
+      },
+      {
+        "label": "天柱县",
+        "value": "522627"
+      },
+      {
+        "label": "锦屏县",
+        "value": "522628"
+      },
+      {
+        "label": "剑河县",
+        "value": "522629"
+      },
+      {
+        "label": "台江县",
+        "value": "522630"
+      },
+      {
+        "label": "黎平县",
+        "value": "522631"
+      },
+      {
+        "label": "榕江县",
+        "value": "522632"
+      },
+      {
+        "label": "从江县",
+        "value": "522633"
+      },
+      {
+        "label": "雷山县",
+        "value": "522634"
+      },
+      {
+        "label": "麻江县",
+        "value": "522635"
+      },
+      {
+        "label": "丹寨县",
+        "value": "522636"
+      }
+    ],
+    [{
+        "label": "都匀市",
+        "value": "522701"
+      },
+      {
+        "label": "福泉市",
+        "value": "522702"
+      },
+      {
+        "label": "荔波县",
+        "value": "522722"
+      },
+      {
+        "label": "贵定县",
+        "value": "522723"
+      },
+      {
+        "label": "瓮安县",
+        "value": "522725"
+      },
+      {
+        "label": "独山县",
+        "value": "522726"
+      },
+      {
+        "label": "平塘县",
+        "value": "522727"
+      },
+      {
+        "label": "罗甸县",
+        "value": "522728"
+      },
+      {
+        "label": "长顺县",
+        "value": "522729"
+      },
+      {
+        "label": "龙里县",
+        "value": "522730"
+      },
+      {
+        "label": "惠水县",
+        "value": "522731"
+      },
+      {
+        "label": "三都水族自治县",
+        "value": "522732"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "五华区",
+        "value": "530102"
+      },
+      {
+        "label": "盘龙区",
+        "value": "530103"
+      },
+      {
+        "label": "官渡区",
+        "value": "530111"
+      },
+      {
+        "label": "西山区",
+        "value": "530112"
+      },
+      {
+        "label": "东川区",
+        "value": "530113"
+      },
+      {
+        "label": "呈贡区",
+        "value": "530114"
+      },
+      {
+        "label": "晋宁区",
+        "value": "530115"
+      },
+      {
+        "label": "富民县",
+        "value": "530124"
+      },
+      {
+        "label": "宜良县",
+        "value": "530125"
+      },
+      {
+        "label": "石林彝族自治县",
+        "value": "530126"
+      },
+      {
+        "label": "嵩明县",
+        "value": "530127"
+      },
+      {
+        "label": "禄劝彝族苗族自治县",
+        "value": "530128"
+      },
+      {
+        "label": "寻甸回族彝族自治县",
+        "value": "530129"
+      },
+      {
+        "label": "安宁市",
+        "value": "530181"
+      }
+    ],
+    [{
+        "label": "麒麟区",
+        "value": "530302"
+      },
+      {
+        "label": "沾益区",
+        "value": "530303"
+      },
+      {
+        "label": "马龙县",
+        "value": "530321"
+      },
+      {
+        "label": "陆良县",
+        "value": "530322"
+      },
+      {
+        "label": "师宗县",
+        "value": "530323"
+      },
+      {
+        "label": "罗平县",
+        "value": "530324"
+      },
+      {
+        "label": "富源县",
+        "value": "530325"
+      },
+      {
+        "label": "会泽县",
+        "value": "530326"
+      },
+      {
+        "label": "宣威市",
+        "value": "530381"
+      }
+    ],
+    [{
+        "label": "红塔区",
+        "value": "530402"
+      },
+      {
+        "label": "江川区",
+        "value": "530403"
+      },
+      {
+        "label": "澄江县",
+        "value": "530422"
+      },
+      {
+        "label": "通海县",
+        "value": "530423"
+      },
+      {
+        "label": "华宁县",
+        "value": "530424"
+      },
+      {
+        "label": "易门县",
+        "value": "530425"
+      },
+      {
+        "label": "峨山彝族自治县",
+        "value": "530426"
+      },
+      {
+        "label": "新平彝族傣族自治县",
+        "value": "530427"
+      },
+      {
+        "label": "元江哈尼族彝族傣族自治县",
+        "value": "530428"
+      }
+    ],
+    [{
+        "label": "隆阳区",
+        "value": "530502"
+      },
+      {
+        "label": "施甸县",
+        "value": "530521"
+      },
+      {
+        "label": "龙陵县",
+        "value": "530523"
+      },
+      {
+        "label": "昌宁县",
+        "value": "530524"
+      },
+      {
+        "label": "腾冲市",
+        "value": "530581"
+      }
+    ],
+    [{
+        "label": "昭阳区",
+        "value": "530602"
+      },
+      {
+        "label": "鲁甸县",
+        "value": "530621"
+      },
+      {
+        "label": "巧家县",
+        "value": "530622"
+      },
+      {
+        "label": "盐津县",
+        "value": "530623"
+      },
+      {
+        "label": "大关县",
+        "value": "530624"
+      },
+      {
+        "label": "永善县",
+        "value": "530625"
+      },
+      {
+        "label": "绥江县",
+        "value": "530626"
+      },
+      {
+        "label": "镇雄县",
+        "value": "530627"
+      },
+      {
+        "label": "彝良县",
+        "value": "530628"
+      },
+      {
+        "label": "威信县",
+        "value": "530629"
+      },
+      {
+        "label": "水富县",
+        "value": "530630"
+      }
+    ],
+    [{
+        "label": "古城区",
+        "value": "530702"
+      },
+      {
+        "label": "玉龙纳西族自治县",
+        "value": "530721"
+      },
+      {
+        "label": "永胜县",
+        "value": "530722"
+      },
+      {
+        "label": "华坪县",
+        "value": "530723"
+      },
+      {
+        "label": "宁蒗彝族自治县",
+        "value": "530724"
+      }
+    ],
+    [{
+        "label": "思茅区",
+        "value": "530802"
+      },
+      {
+        "label": "宁洱哈尼族彝族自治县",
+        "value": "530821"
+      },
+      {
+        "label": "墨江哈尼族自治县",
+        "value": "530822"
+      },
+      {
+        "label": "景东彝族自治县",
+        "value": "530823"
+      },
+      {
+        "label": "景谷傣族彝族自治县",
+        "value": "530824"
+      },
+      {
+        "label": "镇沅彝族哈尼族拉祜族自治县",
+        "value": "530825"
+      },
+      {
+        "label": "江城哈尼族彝族自治县",
+        "value": "530826"
+      },
+      {
+        "label": "孟连傣族拉祜族佤族自治县",
+        "value": "530827"
+      },
+      {
+        "label": "澜沧拉祜族自治县",
+        "value": "530828"
+      },
+      {
+        "label": "西盟佤族自治县",
+        "value": "530829"
+      }
+    ],
+    [{
+        "label": "临翔区",
+        "value": "530902"
+      },
+      {
+        "label": "凤庆县",
+        "value": "530921"
+      },
+      {
+        "label": "云县",
+        "value": "530922"
+      },
+      {
+        "label": "永德县",
+        "value": "530923"
+      },
+      {
+        "label": "镇康县",
+        "value": "530924"
+      },
+      {
+        "label": "双江拉祜族佤族布朗族傣族自治县",
+        "value": "530925"
+      },
+      {
+        "label": "耿马傣族佤族自治县",
+        "value": "530926"
+      },
+      {
+        "label": "沧源佤族自治县",
+        "value": "530927"
+      }
+    ],
+    [{
+        "label": "楚雄市",
+        "value": "532301"
+      },
+      {
+        "label": "双柏县",
+        "value": "532322"
+      },
+      {
+        "label": "牟定县",
+        "value": "532323"
+      },
+      {
+        "label": "南华县",
+        "value": "532324"
+      },
+      {
+        "label": "姚安县",
+        "value": "532325"
+      },
+      {
+        "label": "大姚县",
+        "value": "532326"
+      },
+      {
+        "label": "永仁县",
+        "value": "532327"
+      },
+      {
+        "label": "元谋县",
+        "value": "532328"
+      },
+      {
+        "label": "武定县",
+        "value": "532329"
+      },
+      {
+        "label": "禄丰县",
+        "value": "532331"
+      }
+    ],
+    [{
+        "label": "个旧市",
+        "value": "532501"
+      },
+      {
+        "label": "开远市",
+        "value": "532502"
+      },
+      {
+        "label": "蒙自市",
+        "value": "532503"
+      },
+      {
+        "label": "弥勒市",
+        "value": "532504"
+      },
+      {
+        "label": "屏边苗族自治县",
+        "value": "532523"
+      },
+      {
+        "label": "建水县",
+        "value": "532524"
+      },
+      {
+        "label": "石屏县",
+        "value": "532525"
+      },
+      {
+        "label": "泸西县",
+        "value": "532527"
+      },
+      {
+        "label": "元阳县",
+        "value": "532528"
+      },
+      {
+        "label": "红河县",
+        "value": "532529"
+      },
+      {
+        "label": "金平苗族瑶族傣族自治县",
+        "value": "532530"
+      },
+      {
+        "label": "绿春县",
+        "value": "532531"
+      },
+      {
+        "label": "河口瑶族自治县",
+        "value": "532532"
+      }
+    ],
+    [{
+        "label": "文山市",
+        "value": "532601"
+      },
+      {
+        "label": "砚山县",
+        "value": "532622"
+      },
+      {
+        "label": "西畴县",
+        "value": "532623"
+      },
+      {
+        "label": "麻栗坡县",
+        "value": "532624"
+      },
+      {
+        "label": "马关县",
+        "value": "532625"
+      },
+      {
+        "label": "丘北县",
+        "value": "532626"
+      },
+      {
+        "label": "广南县",
+        "value": "532627"
+      },
+      {
+        "label": "富宁县",
+        "value": "532628"
+      }
+    ],
+    [{
+        "label": "景洪市",
+        "value": "532801"
+      },
+      {
+        "label": "勐海县",
+        "value": "532822"
+      },
+      {
+        "label": "勐腊县",
+        "value": "532823"
+      }
+    ],
+    [{
+        "label": "大理市",
+        "value": "532901"
+      },
+      {
+        "label": "漾濞彝族自治县",
+        "value": "532922"
+      },
+      {
+        "label": "祥云县",
+        "value": "532923"
+      },
+      {
+        "label": "宾川县",
+        "value": "532924"
+      },
+      {
+        "label": "弥渡县",
+        "value": "532925"
+      },
+      {
+        "label": "南涧彝族自治县",
+        "value": "532926"
+      },
+      {
+        "label": "巍山彝族回族自治县",
+        "value": "532927"
+      },
+      {
+        "label": "永平县",
+        "value": "532928"
+      },
+      {
+        "label": "云龙县",
+        "value": "532929"
+      },
+      {
+        "label": "洱源县",
+        "value": "532930"
+      },
+      {
+        "label": "剑川县",
+        "value": "532931"
+      },
+      {
+        "label": "鹤庆县",
+        "value": "532932"
+      }
+    ],
+    [{
+        "label": "瑞丽市",
+        "value": "533102"
+      },
+      {
+        "label": "芒市",
+        "value": "533103"
+      },
+      {
+        "label": "梁河县",
+        "value": "533122"
+      },
+      {
+        "label": "盈江县",
+        "value": "533123"
+      },
+      {
+        "label": "陇川县",
+        "value": "533124"
+      }
+    ],
+    [{
+        "label": "泸水市",
+        "value": "533301"
+      },
+      {
+        "label": "福贡县",
+        "value": "533323"
+      },
+      {
+        "label": "贡山独龙族怒族自治县",
+        "value": "533324"
+      },
+      {
+        "label": "兰坪白族普米族自治县",
+        "value": "533325"
+      }
+    ],
+    [{
+        "label": "香格里拉市",
+        "value": "533401"
+      },
+      {
+        "label": "德钦县",
+        "value": "533422"
+      },
+      {
+        "label": "维西傈僳族自治县",
+        "value": "533423"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "城关区",
+        "value": "540102"
+      },
+      {
+        "label": "堆龙德庆区",
+        "value": "540103"
+      },
+      {
+        "label": "林周县",
+        "value": "540121"
+      },
+      {
+        "label": "当雄县",
+        "value": "540122"
+      },
+      {
+        "label": "尼木县",
+        "value": "540123"
+      },
+      {
+        "label": "曲水县",
+        "value": "540124"
+      },
+      {
+        "label": "达孜县",
+        "value": "540126"
+      },
+      {
+        "label": "墨竹工卡县",
+        "value": "540127"
+      },
+      {
+        "label": "格尔木藏青工业园区",
+        "value": "540171"
+      },
+      {
+        "label": "拉萨经济技术开发区",
+        "value": "540172"
+      },
+      {
+        "label": "西藏文化旅游创意园区",
+        "value": "540173"
+      },
+      {
+        "label": "达孜工业园区",
+        "value": "540174"
+      }
+    ],
+    [{
+        "label": "桑珠孜区",
+        "value": "540202"
+      },
+      {
+        "label": "南木林县",
+        "value": "540221"
+      },
+      {
+        "label": "江孜县",
+        "value": "540222"
+      },
+      {
+        "label": "定日县",
+        "value": "540223"
+      },
+      {
+        "label": "萨迦县",
+        "value": "540224"
+      },
+      {
+        "label": "拉孜县",
+        "value": "540225"
+      },
+      {
+        "label": "昂仁县",
+        "value": "540226"
+      },
+      {
+        "label": "谢通门县",
+        "value": "540227"
+      },
+      {
+        "label": "白朗县",
+        "value": "540228"
+      },
+      {
+        "label": "仁布县",
+        "value": "540229"
+      },
+      {
+        "label": "康马县",
+        "value": "540230"
+      },
+      {
+        "label": "定结县",
+        "value": "540231"
+      },
+      {
+        "label": "仲巴县",
+        "value": "540232"
+      },
+      {
+        "label": "亚东县",
+        "value": "540233"
+      },
+      {
+        "label": "吉隆县",
+        "value": "540234"
+      },
+      {
+        "label": "聂拉木县",
+        "value": "540235"
+      },
+      {
+        "label": "萨嘎县",
+        "value": "540236"
+      },
+      {
+        "label": "岗巴县",
+        "value": "540237"
+      }
+    ],
+    [{
+        "label": "卡若区",
+        "value": "540302"
+      },
+      {
+        "label": "江达县",
+        "value": "540321"
+      },
+      {
+        "label": "贡觉县",
+        "value": "540322"
+      },
+      {
+        "label": "类乌齐县",
+        "value": "540323"
+      },
+      {
+        "label": "丁青县",
+        "value": "540324"
+      },
+      {
+        "label": "察雅县",
+        "value": "540325"
+      },
+      {
+        "label": "八宿县",
+        "value": "540326"
+      },
+      {
+        "label": "左贡县",
+        "value": "540327"
+      },
+      {
+        "label": "芒康县",
+        "value": "540328"
+      },
+      {
+        "label": "洛隆县",
+        "value": "540329"
+      },
+      {
+        "label": "边坝县",
+        "value": "540330"
+      }
+    ],
+    [{
+        "label": "巴宜区",
+        "value": "540402"
+      },
+      {
+        "label": "工布江达县",
+        "value": "540421"
+      },
+      {
+        "label": "米林县",
+        "value": "540422"
+      },
+      {
+        "label": "墨脱县",
+        "value": "540423"
+      },
+      {
+        "label": "波密县",
+        "value": "540424"
+      },
+      {
+        "label": "察隅县",
+        "value": "540425"
+      },
+      {
+        "label": "朗县",
+        "value": "540426"
+      }
+    ],
+    [{
+        "label": "乃东区",
+        "value": "540502"
+      },
+      {
+        "label": "扎囊县",
+        "value": "540521"
+      },
+      {
+        "label": "贡嘎县",
+        "value": "540522"
+      },
+      {
+        "label": "桑日县",
+        "value": "540523"
+      },
+      {
+        "label": "琼结县",
+        "value": "540524"
+      },
+      {
+        "label": "曲松县",
+        "value": "540525"
+      },
+      {
+        "label": "措美县",
+        "value": "540526"
+      },
+      {
+        "label": "洛扎县",
+        "value": "540527"
+      },
+      {
+        "label": "加查县",
+        "value": "540528"
+      },
+      {
+        "label": "隆子县",
+        "value": "540529"
+      },
+      {
+        "label": "错那县",
+        "value": "540530"
+      },
+      {
+        "label": "浪卡子县",
+        "value": "540531"
+      }
+    ],
+    [{
+        "label": "那曲县",
+        "value": "542421"
+      },
+      {
+        "label": "嘉黎县",
+        "value": "542422"
+      },
+      {
+        "label": "比如县",
+        "value": "542423"
+      },
+      {
+        "label": "聂荣县",
+        "value": "542424"
+      },
+      {
+        "label": "安多县",
+        "value": "542425"
+      },
+      {
+        "label": "申扎县",
+        "value": "542426"
+      },
+      {
+        "label": "索县",
+        "value": "542427"
+      },
+      {
+        "label": "班戈县",
+        "value": "542428"
+      },
+      {
+        "label": "巴青县",
+        "value": "542429"
+      },
+      {
+        "label": "尼玛县",
+        "value": "542430"
+      },
+      {
+        "label": "双湖县",
+        "value": "542431"
+      }
+    ],
+    [{
+        "label": "普兰县",
+        "value": "542521"
+      },
+      {
+        "label": "札达县",
+        "value": "542522"
+      },
+      {
+        "label": "噶尔县",
+        "value": "542523"
+      },
+      {
+        "label": "日土县",
+        "value": "542524"
+      },
+      {
+        "label": "革吉县",
+        "value": "542525"
+      },
+      {
+        "label": "改则县",
+        "value": "542526"
+      },
+      {
+        "label": "措勤县",
+        "value": "542527"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "新城区",
+        "value": "610102"
+      },
+      {
+        "label": "碑林区",
+        "value": "610103"
+      },
+      {
+        "label": "莲湖区",
+        "value": "610104"
+      },
+      {
+        "label": "灞桥区",
+        "value": "610111"
+      },
+      {
+        "label": "未央区",
+        "value": "610112"
+      },
+      {
+        "label": "雁塔区",
+        "value": "610113"
+      },
+      {
+        "label": "阎良区",
+        "value": "610114"
+      },
+      {
+        "label": "临潼区",
+        "value": "610115"
+      },
+      {
+        "label": "长安区",
+        "value": "610116"
+      },
+      {
+        "label": "高陵区",
+        "value": "610117"
+      },
+      {
+        "label": "鄠邑区",
+        "value": "610118"
+      },
+      {
+        "label": "蓝田县",
+        "value": "610122"
+      },
+      {
+        "label": "周至县",
+        "value": "610124"
+      }
+    ],
+    [{
+        "label": "王益区",
+        "value": "610202"
+      },
+      {
+        "label": "印台区",
+        "value": "610203"
+      },
+      {
+        "label": "耀州区",
+        "value": "610204"
+      },
+      {
+        "label": "宜君县",
+        "value": "610222"
+      }
+    ],
+    [{
+        "label": "渭滨区",
+        "value": "610302"
+      },
+      {
+        "label": "金台区",
+        "value": "610303"
+      },
+      {
+        "label": "陈仓区",
+        "value": "610304"
+      },
+      {
+        "label": "凤翔县",
+        "value": "610322"
+      },
+      {
+        "label": "岐山县",
+        "value": "610323"
+      },
+      {
+        "label": "扶风县",
+        "value": "610324"
+      },
+      {
+        "label": "眉县",
+        "value": "610326"
+      },
+      {
+        "label": "陇县",
+        "value": "610327"
+      },
+      {
+        "label": "千阳县",
+        "value": "610328"
+      },
+      {
+        "label": "麟游县",
+        "value": "610329"
+      },
+      {
+        "label": "凤县",
+        "value": "610330"
+      },
+      {
+        "label": "太白县",
+        "value": "610331"
+      }
+    ],
+    [{
+        "label": "秦都区",
+        "value": "610402"
+      },
+      {
+        "label": "杨陵区",
+        "value": "610403"
+      },
+      {
+        "label": "渭城区",
+        "value": "610404"
+      },
+      {
+        "label": "三原县",
+        "value": "610422"
+      },
+      {
+        "label": "泾阳县",
+        "value": "610423"
+      },
+      {
+        "label": "乾县",
+        "value": "610424"
+      },
+      {
+        "label": "礼泉县",
+        "value": "610425"
+      },
+      {
+        "label": "永寿县",
+        "value": "610426"
+      },
+      {
+        "label": "彬县",
+        "value": "610427"
+      },
+      {
+        "label": "长武县",
+        "value": "610428"
+      },
+      {
+        "label": "旬邑县",
+        "value": "610429"
+      },
+      {
+        "label": "淳化县",
+        "value": "610430"
+      },
+      {
+        "label": "武功县",
+        "value": "610431"
+      },
+      {
+        "label": "兴平市",
+        "value": "610481"
+      }
+    ],
+    [{
+        "label": "临渭区",
+        "value": "610502"
+      },
+      {
+        "label": "华州区",
+        "value": "610503"
+      },
+      {
+        "label": "潼关县",
+        "value": "610522"
+      },
+      {
+        "label": "大荔县",
+        "value": "610523"
+      },
+      {
+        "label": "合阳县",
+        "value": "610524"
+      },
+      {
+        "label": "澄城县",
+        "value": "610525"
+      },
+      {
+        "label": "蒲城县",
+        "value": "610526"
+      },
+      {
+        "label": "白水县",
+        "value": "610527"
+      },
+      {
+        "label": "富平县",
+        "value": "610528"
+      },
+      {
+        "label": "韩城市",
+        "value": "610581"
+      },
+      {
+        "label": "华阴市",
+        "value": "610582"
+      }
+    ],
+    [{
+        "label": "宝塔区",
+        "value": "610602"
+      },
+      {
+        "label": "安塞区",
+        "value": "610603"
+      },
+      {
+        "label": "延长县",
+        "value": "610621"
+      },
+      {
+        "label": "延川县",
+        "value": "610622"
+      },
+      {
+        "label": "子长县",
+        "value": "610623"
+      },
+      {
+        "label": "志丹县",
+        "value": "610625"
+      },
+      {
+        "label": "吴起县",
+        "value": "610626"
+      },
+      {
+        "label": "甘泉县",
+        "value": "610627"
+      },
+      {
+        "label": "富县",
+        "value": "610628"
+      },
+      {
+        "label": "洛川县",
+        "value": "610629"
+      },
+      {
+        "label": "宜川县",
+        "value": "610630"
+      },
+      {
+        "label": "黄龙县",
+        "value": "610631"
+      },
+      {
+        "label": "黄陵县",
+        "value": "610632"
+      }
+    ],
+    [{
+        "label": "汉台区",
+        "value": "610702"
+      },
+      {
+        "label": "南郑区",
+        "value": "610703"
+      },
+      {
+        "label": "城固县",
+        "value": "610722"
+      },
+      {
+        "label": "洋县",
+        "value": "610723"
+      },
+      {
+        "label": "西乡县",
+        "value": "610724"
+      },
+      {
+        "label": "勉县",
+        "value": "610725"
+      },
+      {
+        "label": "宁强县",
+        "value": "610726"
+      },
+      {
+        "label": "略阳县",
+        "value": "610727"
+      },
+      {
+        "label": "镇巴县",
+        "value": "610728"
+      },
+      {
+        "label": "留坝县",
+        "value": "610729"
+      },
+      {
+        "label": "佛坪县",
+        "value": "610730"
+      }
+    ],
+    [{
+        "label": "榆阳区",
+        "value": "610802"
+      },
+      {
+        "label": "横山区",
+        "value": "610803"
+      },
+      {
+        "label": "府谷县",
+        "value": "610822"
+      },
+      {
+        "label": "靖边县",
+        "value": "610824"
+      },
+      {
+        "label": "定边县",
+        "value": "610825"
+      },
+      {
+        "label": "绥德县",
+        "value": "610826"
+      },
+      {
+        "label": "米脂县",
+        "value": "610827"
+      },
+      {
+        "label": "佳县",
+        "value": "610828"
+      },
+      {
+        "label": "吴堡县",
+        "value": "610829"
+      },
+      {
+        "label": "清涧县",
+        "value": "610830"
+      },
+      {
+        "label": "子洲县",
+        "value": "610831"
+      },
+      {
+        "label": "神木市",
+        "value": "610881"
+      }
+    ],
+    [{
+        "label": "汉滨区",
+        "value": "610902"
+      },
+      {
+        "label": "汉阴县",
+        "value": "610921"
+      },
+      {
+        "label": "石泉县",
+        "value": "610922"
+      },
+      {
+        "label": "宁陕县",
+        "value": "610923"
+      },
+      {
+        "label": "紫阳县",
+        "value": "610924"
+      },
+      {
+        "label": "岚皋县",
+        "value": "610925"
+      },
+      {
+        "label": "平利县",
+        "value": "610926"
+      },
+      {
+        "label": "镇坪县",
+        "value": "610927"
+      },
+      {
+        "label": "旬阳县",
+        "value": "610928"
+      },
+      {
+        "label": "白河县",
+        "value": "610929"
+      }
+    ],
+    [{
+        "label": "商州区",
+        "value": "611002"
+      },
+      {
+        "label": "洛南县",
+        "value": "611021"
+      },
+      {
+        "label": "丹凤县",
+        "value": "611022"
+      },
+      {
+        "label": "商南县",
+        "value": "611023"
+      },
+      {
+        "label": "山阳县",
+        "value": "611024"
+      },
+      {
+        "label": "镇安县",
+        "value": "611025"
+      },
+      {
+        "label": "柞水县",
+        "value": "611026"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "城关区",
+        "value": "620102"
+      },
+      {
+        "label": "七里河区",
+        "value": "620103"
+      },
+      {
+        "label": "西固区",
+        "value": "620104"
+      },
+      {
+        "label": "安宁区",
+        "value": "620105"
+      },
+      {
+        "label": "红古区",
+        "value": "620111"
+      },
+      {
+        "label": "永登县",
+        "value": "620121"
+      },
+      {
+        "label": "皋兰县",
+        "value": "620122"
+      },
+      {
+        "label": "榆中县",
+        "value": "620123"
+      },
+      {
+        "label": "兰州新区",
+        "value": "620171"
+      }
+    ],
+    [{
+      "label": "嘉峪关市",
+      "value": "620201"
+    }],
+    [{
+        "label": "金川区",
+        "value": "620302"
+      },
+      {
+        "label": "永昌县",
+        "value": "620321"
+      }
+    ],
+    [{
+        "label": "白银区",
+        "value": "620402"
+      },
+      {
+        "label": "平川区",
+        "value": "620403"
+      },
+      {
+        "label": "靖远县",
+        "value": "620421"
+      },
+      {
+        "label": "会宁县",
+        "value": "620422"
+      },
+      {
+        "label": "景泰县",
+        "value": "620423"
+      }
+    ],
+    [{
+        "label": "秦州区",
+        "value": "620502"
+      },
+      {
+        "label": "麦积区",
+        "value": "620503"
+      },
+      {
+        "label": "清水县",
+        "value": "620521"
+      },
+      {
+        "label": "秦安县",
+        "value": "620522"
+      },
+      {
+        "label": "甘谷县",
+        "value": "620523"
+      },
+      {
+        "label": "武山县",
+        "value": "620524"
+      },
+      {
+        "label": "张家川回族自治县",
+        "value": "620525"
+      }
+    ],
+    [{
+        "label": "凉州区",
+        "value": "620602"
+      },
+      {
+        "label": "民勤县",
+        "value": "620621"
+      },
+      {
+        "label": "古浪县",
+        "value": "620622"
+      },
+      {
+        "label": "天祝藏族自治县",
+        "value": "620623"
+      }
+    ],
+    [{
+        "label": "甘州区",
+        "value": "620702"
+      },
+      {
+        "label": "肃南裕固族自治县",
+        "value": "620721"
+      },
+      {
+        "label": "民乐县",
+        "value": "620722"
+      },
+      {
+        "label": "临泽县",
+        "value": "620723"
+      },
+      {
+        "label": "高台县",
+        "value": "620724"
+      },
+      {
+        "label": "山丹县",
+        "value": "620725"
+      }
+    ],
+    [{
+        "label": "崆峒区",
+        "value": "620802"
+      },
+      {
+        "label": "泾川县",
+        "value": "620821"
+      },
+      {
+        "label": "灵台县",
+        "value": "620822"
+      },
+      {
+        "label": "崇信县",
+        "value": "620823"
+      },
+      {
+        "label": "华亭县",
+        "value": "620824"
+      },
+      {
+        "label": "庄浪县",
+        "value": "620825"
+      },
+      {
+        "label": "静宁县",
+        "value": "620826"
+      },
+      {
+        "label": "平凉工业园区",
+        "value": "620871"
+      }
+    ],
+    [{
+        "label": "肃州区",
+        "value": "620902"
+      },
+      {
+        "label": "金塔县",
+        "value": "620921"
+      },
+      {
+        "label": "瓜州县",
+        "value": "620922"
+      },
+      {
+        "label": "肃北蒙古族自治县",
+        "value": "620923"
+      },
+      {
+        "label": "阿克塞哈萨克族自治县",
+        "value": "620924"
+      },
+      {
+        "label": "玉门市",
+        "value": "620981"
+      },
+      {
+        "label": "敦煌市",
+        "value": "620982"
+      }
+    ],
+    [{
+        "label": "西峰区",
+        "value": "621002"
+      },
+      {
+        "label": "庆城县",
+        "value": "621021"
+      },
+      {
+        "label": "环县",
+        "value": "621022"
+      },
+      {
+        "label": "华池县",
+        "value": "621023"
+      },
+      {
+        "label": "合水县",
+        "value": "621024"
+      },
+      {
+        "label": "正宁县",
+        "value": "621025"
+      },
+      {
+        "label": "宁县",
+        "value": "621026"
+      },
+      {
+        "label": "镇原县",
+        "value": "621027"
+      }
+    ],
+    [{
+        "label": "安定区",
+        "value": "621102"
+      },
+      {
+        "label": "通渭县",
+        "value": "621121"
+      },
+      {
+        "label": "陇西县",
+        "value": "621122"
+      },
+      {
+        "label": "渭源县",
+        "value": "621123"
+      },
+      {
+        "label": "临洮县",
+        "value": "621124"
+      },
+      {
+        "label": "漳县",
+        "value": "621125"
+      },
+      {
+        "label": "岷县",
+        "value": "621126"
+      }
+    ],
+    [{
+        "label": "武都区",
+        "value": "621202"
+      },
+      {
+        "label": "成县",
+        "value": "621221"
+      },
+      {
+        "label": "文县",
+        "value": "621222"
+      },
+      {
+        "label": "宕昌县",
+        "value": "621223"
+      },
+      {
+        "label": "康县",
+        "value": "621224"
+      },
+      {
+        "label": "西和县",
+        "value": "621225"
+      },
+      {
+        "label": "礼县",
+        "value": "621226"
+      },
+      {
+        "label": "徽县",
+        "value": "621227"
+      },
+      {
+        "label": "两当县",
+        "value": "621228"
+      }
+    ],
+    [{
+        "label": "临夏市",
+        "value": "622901"
+      },
+      {
+        "label": "临夏县",
+        "value": "622921"
+      },
+      {
+        "label": "康乐县",
+        "value": "622922"
+      },
+      {
+        "label": "永靖县",
+        "value": "622923"
+      },
+      {
+        "label": "广河县",
+        "value": "622924"
+      },
+      {
+        "label": "和政县",
+        "value": "622925"
+      },
+      {
+        "label": "东乡族自治县",
+        "value": "622926"
+      },
+      {
+        "label": "积石山保安族东乡族撒拉族自治县",
+        "value": "622927"
+      }
+    ],
+    [{
+        "label": "合作市",
+        "value": "623001"
+      },
+      {
+        "label": "临潭县",
+        "value": "623021"
+      },
+      {
+        "label": "卓尼县",
+        "value": "623022"
+      },
+      {
+        "label": "舟曲县",
+        "value": "623023"
+      },
+      {
+        "label": "迭部县",
+        "value": "623024"
+      },
+      {
+        "label": "玛曲县",
+        "value": "623025"
+      },
+      {
+        "label": "碌曲县",
+        "value": "623026"
+      },
+      {
+        "label": "夏河县",
+        "value": "623027"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "城东区",
+        "value": "630102"
+      },
+      {
+        "label": "城中区",
+        "value": "630103"
+      },
+      {
+        "label": "城西区",
+        "value": "630104"
+      },
+      {
+        "label": "城北区",
+        "value": "630105"
+      },
+      {
+        "label": "大通回族土族自治县",
+        "value": "630121"
+      },
+      {
+        "label": "湟中县",
+        "value": "630122"
+      },
+      {
+        "label": "湟源县",
+        "value": "630123"
+      }
+    ],
+    [{
+        "label": "乐都区",
+        "value": "630202"
+      },
+      {
+        "label": "平安区",
+        "value": "630203"
+      },
+      {
+        "label": "民和回族土族自治县",
+        "value": "630222"
+      },
+      {
+        "label": "互助土族自治县",
+        "value": "630223"
+      },
+      {
+        "label": "化隆回族自治县",
+        "value": "630224"
+      },
+      {
+        "label": "循化撒拉族自治县",
+        "value": "630225"
+      }
+    ],
+    [{
+        "label": "门源回族自治县",
+        "value": "632221"
+      },
+      {
+        "label": "祁连县",
+        "value": "632222"
+      },
+      {
+        "label": "海晏县",
+        "value": "632223"
+      },
+      {
+        "label": "刚察县",
+        "value": "632224"
+      }
+    ],
+    [{
+        "label": "同仁县",
+        "value": "632321"
+      },
+      {
+        "label": "尖扎县",
+        "value": "632322"
+      },
+      {
+        "label": "泽库县",
+        "value": "632323"
+      },
+      {
+        "label": "河南蒙古族自治县",
+        "value": "632324"
+      }
+    ],
+    [{
+        "label": "共和县",
+        "value": "632521"
+      },
+      {
+        "label": "同德县",
+        "value": "632522"
+      },
+      {
+        "label": "贵德县",
+        "value": "632523"
+      },
+      {
+        "label": "兴海县",
+        "value": "632524"
+      },
+      {
+        "label": "贵南县",
+        "value": "632525"
+      }
+    ],
+    [{
+        "label": "玛沁县",
+        "value": "632621"
+      },
+      {
+        "label": "班玛县",
+        "value": "632622"
+      },
+      {
+        "label": "甘德县",
+        "value": "632623"
+      },
+      {
+        "label": "达日县",
+        "value": "632624"
+      },
+      {
+        "label": "久治县",
+        "value": "632625"
+      },
+      {
+        "label": "玛多县",
+        "value": "632626"
+      }
+    ],
+    [{
+        "label": "玉树市",
+        "value": "632701"
+      },
+      {
+        "label": "杂多县",
+        "value": "632722"
+      },
+      {
+        "label": "称多县",
+        "value": "632723"
+      },
+      {
+        "label": "治多县",
+        "value": "632724"
+      },
+      {
+        "label": "囊谦县",
+        "value": "632725"
+      },
+      {
+        "label": "曲麻莱县",
+        "value": "632726"
+      }
+    ],
+    [{
+        "label": "格尔木市",
+        "value": "632801"
+      },
+      {
+        "label": "德令哈市",
+        "value": "632802"
+      },
+      {
+        "label": "乌兰县",
+        "value": "632821"
+      },
+      {
+        "label": "都兰县",
+        "value": "632822"
+      },
+      {
+        "label": "天峻县",
+        "value": "632823"
+      },
+      {
+        "label": "大柴旦行政委员会",
+        "value": "632857"
+      },
+      {
+        "label": "冷湖行政委员会",
+        "value": "632858"
+      },
+      {
+        "label": "茫崖行政委员会",
+        "value": "632859"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "兴庆区",
+        "value": "640104"
+      },
+      {
+        "label": "西夏区",
+        "value": "640105"
+      },
+      {
+        "label": "金凤区",
+        "value": "640106"
+      },
+      {
+        "label": "永宁县",
+        "value": "640121"
+      },
+      {
+        "label": "贺兰县",
+        "value": "640122"
+      },
+      {
+        "label": "灵武市",
+        "value": "640181"
+      }
+    ],
+    [{
+        "label": "大武口区",
+        "value": "640202"
+      },
+      {
+        "label": "惠农区",
+        "value": "640205"
+      },
+      {
+        "label": "平罗县",
+        "value": "640221"
+      }
+    ],
+    [{
+        "label": "利通区",
+        "value": "640302"
+      },
+      {
+        "label": "红寺堡区",
+        "value": "640303"
+      },
+      {
+        "label": "盐池县",
+        "value": "640323"
+      },
+      {
+        "label": "同心县",
+        "value": "640324"
+      },
+      {
+        "label": "青铜峡市",
+        "value": "640381"
+      }
+    ],
+    [{
+        "label": "原州区",
+        "value": "640402"
+      },
+      {
+        "label": "西吉县",
+        "value": "640422"
+      },
+      {
+        "label": "隆德县",
+        "value": "640423"
+      },
+      {
+        "label": "泾源县",
+        "value": "640424"
+      },
+      {
+        "label": "彭阳县",
+        "value": "640425"
+      }
+    ],
+    [{
+        "label": "沙坡头区",
+        "value": "640502"
+      },
+      {
+        "label": "中宁县",
+        "value": "640521"
+      },
+      {
+        "label": "海原县",
+        "value": "640522"
+      }
+    ]
+  ],
+  [
+    [{
+        "label": "天山区",
+        "value": "650102"
+      },
+      {
+        "label": "沙依巴克区",
+        "value": "650103"
+      },
+      {
+        "label": "新市区",
+        "value": "650104"
+      },
+      {
+        "label": "水磨沟区",
+        "value": "650105"
+      },
+      {
+        "label": "头屯河区",
+        "value": "650106"
+      },
+      {
+        "label": "达坂城区",
+        "value": "650107"
+      },
+      {
+        "label": "米东区",
+        "value": "650109"
+      },
+      {
+        "label": "乌鲁木齐县",
+        "value": "650121"
+      },
+      {
+        "label": "乌鲁木齐经济技术开发区",
+        "value": "650171"
+      },
+      {
+        "label": "乌鲁木齐高新技术产业开发区",
+        "value": "650172"
+      }
+    ],
+    [{
+        "label": "独山子区",
+        "value": "650202"
+      },
+      {
+        "label": "克拉玛依区",
+        "value": "650203"
+      },
+      {
+        "label": "白碱滩区",
+        "value": "650204"
+      },
+      {
+        "label": "乌尔禾区",
+        "value": "650205"
+      }
+    ],
+    [{
+        "label": "高昌区",
+        "value": "650402"
+      },
+      {
+        "label": "鄯善县",
+        "value": "650421"
+      },
+      {
+        "label": "托克逊县",
+        "value": "650422"
+      }
+    ],
+    [{
+        "label": "伊州区",
+        "value": "650502"
+      },
+      {
+        "label": "巴里坤哈萨克自治县",
+        "value": "650521"
+      },
+      {
+        "label": "伊吾县",
+        "value": "650522"
+      }
+    ],
+    [{
+        "label": "昌吉市",
+        "value": "652301"
+      },
+      {
+        "label": "阜康市",
+        "value": "652302"
+      },
+      {
+        "label": "呼图壁县",
+        "value": "652323"
+      },
+      {
+        "label": "玛纳斯县",
+        "value": "652324"
+      },
+      {
+        "label": "奇台县",
+        "value": "652325"
+      },
+      {
+        "label": "吉木萨尔县",
+        "value": "652327"
+      },
+      {
+        "label": "木垒哈萨克自治县",
+        "value": "652328"
+      }
+    ],
+    [{
+        "label": "博乐市",
+        "value": "652701"
+      },
+      {
+        "label": "阿拉山口市",
+        "value": "652702"
+      },
+      {
+        "label": "精河县",
+        "value": "652722"
+      },
+      {
+        "label": "温泉县",
+        "value": "652723"
+      }
+    ],
+    [{
+        "label": "库尔勒市",
+        "value": "652801"
+      },
+      {
+        "label": "轮台县",
+        "value": "652822"
+      },
+      {
+        "label": "尉犁县",
+        "value": "652823"
+      },
+      {
+        "label": "若羌县",
+        "value": "652824"
+      },
+      {
+        "label": "且末县",
+        "value": "652825"
+      },
+      {
+        "label": "焉耆回族自治县",
+        "value": "652826"
+      },
+      {
+        "label": "和静县",
+        "value": "652827"
+      },
+      {
+        "label": "和硕县",
+        "value": "652828"
+      },
+      {
+        "label": "博湖县",
+        "value": "652829"
+      },
+      {
+        "label": "库尔勒经济技术开发区",
+        "value": "652871"
+      }
+    ],
+    [{
+        "label": "阿克苏市",
+        "value": "652901"
+      },
+      {
+        "label": "温宿县",
+        "value": "652922"
+      },
+      {
+        "label": "库车县",
+        "value": "652923"
+      },
+      {
+        "label": "沙雅县",
+        "value": "652924"
+      },
+      {
+        "label": "新和县",
+        "value": "652925"
+      },
+      {
+        "label": "拜城县",
+        "value": "652926"
+      },
+      {
+        "label": "乌什县",
+        "value": "652927"
+      },
+      {
+        "label": "阿瓦提县",
+        "value": "652928"
+      },
+      {
+        "label": "柯坪县",
+        "value": "652929"
+      }
+    ],
+    [{
+        "label": "阿图什市",
+        "value": "653001"
+      },
+      {
+        "label": "阿克陶县",
+        "value": "653022"
+      },
+      {
+        "label": "阿合奇县",
+        "value": "653023"
+      },
+      {
+        "label": "乌恰县",
+        "value": "653024"
+      }
+    ],
+    [{
+        "label": "喀什市",
+        "value": "653101"
+      },
+      {
+        "label": "疏附县",
+        "value": "653121"
+      },
+      {
+        "label": "疏勒县",
+        "value": "653122"
+      },
+      {
+        "label": "英吉沙县",
+        "value": "653123"
+      },
+      {
+        "label": "泽普县",
+        "value": "653124"
+      },
+      {
+        "label": "莎车县",
+        "value": "653125"
+      },
+      {
+        "label": "叶城县",
+        "value": "653126"
+      },
+      {
+        "label": "麦盖提县",
+        "value": "653127"
+      },
+      {
+        "label": "岳普湖县",
+        "value": "653128"
+      },
+      {
+        "label": "伽师县",
+        "value": "653129"
+      },
+      {
+        "label": "巴楚县",
+        "value": "653130"
+      },
+      {
+        "label": "塔什库尔干塔吉克自治县",
+        "value": "653131"
+      }
+    ],
+    [{
+        "label": "和田市",
+        "value": "653201"
+      },
+      {
+        "label": "和田县",
+        "value": "653221"
+      },
+      {
+        "label": "墨玉县",
+        "value": "653222"
+      },
+      {
+        "label": "皮山县",
+        "value": "653223"
+      },
+      {
+        "label": "洛浦县",
+        "value": "653224"
+      },
+      {
+        "label": "策勒县",
+        "value": "653225"
+      },
+      {
+        "label": "于田县",
+        "value": "653226"
+      },
+      {
+        "label": "民丰县",
+        "value": "653227"
+      }
+    ],
+    [{
+        "label": "伊宁市",
+        "value": "654002"
+      },
+      {
+        "label": "奎屯市",
+        "value": "654003"
+      },
+      {
+        "label": "霍尔果斯市",
+        "value": "654004"
+      },
+      {
+        "label": "伊宁县",
+        "value": "654021"
+      },
+      {
+        "label": "察布查尔锡伯自治县",
+        "value": "654022"
+      },
+      {
+        "label": "霍城县",
+        "value": "654023"
+      },
+      {
+        "label": "巩留县",
+        "value": "654024"
+      },
+      {
+        "label": "新源县",
+        "value": "654025"
+      },
+      {
+        "label": "昭苏县",
+        "value": "654026"
+      },
+      {
+        "label": "特克斯县",
+        "value": "654027"
+      },
+      {
+        "label": "尼勒克县",
+        "value": "654028"
+      }
+    ],
+    [{
+        "label": "塔城市",
+        "value": "654201"
+      },
+      {
+        "label": "乌苏市",
+        "value": "654202"
+      },
+      {
+        "label": "额敏县",
+        "value": "654221"
+      },
+      {
+        "label": "沙湾县",
+        "value": "654223"
+      },
+      {
+        "label": "托里县",
+        "value": "654224"
+      },
+      {
+        "label": "裕民县",
+        "value": "654225"
+      },
+      {
+        "label": "和布克赛尔蒙古自治县",
+        "value": "654226"
+      }
+    ],
+    [{
+        "label": "阿勒泰市",
+        "value": "654301"
+      },
+      {
+        "label": "布尔津县",
+        "value": "654321"
+      },
+      {
+        "label": "富蕴县",
+        "value": "654322"
+      },
+      {
+        "label": "福海县",
+        "value": "654323"
+      },
+      {
+        "label": "哈巴河县",
+        "value": "654324"
+      },
+      {
+        "label": "青河县",
+        "value": "654325"
+      },
+      {
+        "label": "吉木乃县",
+        "value": "654326"
+      }
+    ],
+    [{
+        "label": "石河子市",
+        "value": "659001"
+      },
+      {
+        "label": "阿拉尔市",
+        "value": "659002"
+      },
+      {
+        "label": "图木舒克市",
+        "value": "659003"
+      },
+      {
+        "label": "五家渠市",
+        "value": "659004"
+      },
+      {
+        "label": "铁门关市",
+        "value": "659006"
+      }
+    ]
+  ],
+  [
+    [{
+      "label": "台北",
+      "value": "660101"
+    }],
+    [{
+      "label": "高雄",
+      "value": "660201"
+    }],
+    [{
+      "label": "基隆",
+      "value": "660301"
+    }],
+    [{
+      "label": "台中",
+      "value": "660401"
+    }],
+    [{
+      "label": "台南",
+      "value": "660501"
+    }],
+    [{
+      "label": "新竹",
+      "value": "660601"
+    }],
+    [{
+      "label": "嘉义",
+      "value": "660701"
+    }],
+    [{
+      "label": "宜兰",
+      "value": "660801"
+    }],
+    [{
+      "label": "桃园",
+      "value": "660901"
+    }],
+    [{
+      "label": "苗栗",
+      "value": "661001"
+    }],
+    [{
+      "label": "彰化",
+      "value": "661101"
+    }],
+    [{
+      "label": "南投",
+      "value": "661201"
+    }],
+    [{
+      "label": "云林",
+      "value": "661301"
+    }],
+    [{
+      "label": "屏东",
+      "value": "661401"
+    }],
+    [{
+      "label": "台东",
+      "value": "661501"
+    }],
+    [{
+      "label": "花莲",
+      "value": "661601"
+    }],
+    [{
+      "label": "澎湖",
+      "value": "661701"
+    }]
+  ],
+  [
+    [{
+      "label": "香港岛",
+      "value": "670101"
+    }],
+    [{
+      "label": "九龙",
+      "value": "670201"
+    }],
+    [{
+      "label": "新界",
+      "value": "670301"
+    }]
+  ],
+  [
+    [{
+      "label": "澳门半岛",
+      "value": "680101"
+    }],
+    [{
+      "label": "氹仔岛",
+      "value": "680201"
+    }],
+    [{
+      "label": "路环岛",
+      "value": "680301"
+    }],
+    [{
+      "label": "路氹城",
+      "value": "680401"
+    }]
+  ]
+]
+export default areaData;

+ 1503 - 0
components/slambb-picker/city-data/city.js

@@ -0,0 +1,1503 @@
+/* eslint-disable */
+var cityData = [
+  [{
+    "label": "北京市",
+    "value": "1101"
+  }],
+  [{
+    "label": "天津市",
+    "value": "1201"
+  }],
+  [{
+      "label": "石家庄市",
+      "value": "1301"
+    },
+    {
+      "label": "唐山市",
+      "value": "1302"
+    },
+    {
+      "label": "秦皇岛市",
+      "value": "1303"
+    },
+    {
+      "label": "邯郸市",
+      "value": "1304"
+    },
+    {
+      "label": "邢台市",
+      "value": "1305"
+    },
+    {
+      "label": "保定市",
+      "value": "1306"
+    },
+    {
+      "label": "张家口市",
+      "value": "1307"
+    },
+    {
+      "label": "承德市",
+      "value": "1308"
+    },
+    {
+      "label": "沧州市",
+      "value": "1309"
+    },
+    {
+      "label": "廊坊市",
+      "value": "1310"
+    },
+    {
+      "label": "衡水市",
+      "value": "1311"
+    }
+  ],
+  [{
+      "label": "太原市",
+      "value": "1401"
+    },
+    {
+      "label": "大同市",
+      "value": "1402"
+    },
+    {
+      "label": "阳泉市",
+      "value": "1403"
+    },
+    {
+      "label": "长治市",
+      "value": "1404"
+    },
+    {
+      "label": "晋城市",
+      "value": "1405"
+    },
+    {
+      "label": "朔州市",
+      "value": "1406"
+    },
+    {
+      "label": "晋中市",
+      "value": "1407"
+    },
+    {
+      "label": "运城市",
+      "value": "1408"
+    },
+    {
+      "label": "忻州市",
+      "value": "1409"
+    },
+    {
+      "label": "临汾市",
+      "value": "1410"
+    },
+    {
+      "label": "吕梁市",
+      "value": "1411"
+    }
+  ],
+  [{
+      "label": "呼和浩特市",
+      "value": "1501"
+    },
+    {
+      "label": "包头市",
+      "value": "1502"
+    },
+    {
+      "label": "乌海市",
+      "value": "1503"
+    },
+    {
+      "label": "赤峰市",
+      "value": "1504"
+    },
+    {
+      "label": "通辽市",
+      "value": "1505"
+    },
+    {
+      "label": "鄂尔多斯市",
+      "value": "1506"
+    },
+    {
+      "label": "呼伦贝尔市",
+      "value": "1507"
+    },
+    {
+      "label": "巴彦淖尔市",
+      "value": "1508"
+    },
+    {
+      "label": "乌兰察布市",
+      "value": "1509"
+    },
+    {
+      "label": "兴安盟",
+      "value": "1522"
+    },
+    {
+      "label": "锡林郭勒盟",
+      "value": "1525"
+    },
+    {
+      "label": "阿拉善盟",
+      "value": "1529"
+    }
+  ],
+  [{
+      "label": "沈阳市",
+      "value": "2101"
+    },
+    {
+      "label": "大连市",
+      "value": "2102"
+    },
+    {
+      "label": "鞍山市",
+      "value": "2103"
+    },
+    {
+      "label": "抚顺市",
+      "value": "2104"
+    },
+    {
+      "label": "本溪市",
+      "value": "2105"
+    },
+    {
+      "label": "丹东市",
+      "value": "2106"
+    },
+    {
+      "label": "锦州市",
+      "value": "2107"
+    },
+    {
+      "label": "营口市",
+      "value": "2108"
+    },
+    {
+      "label": "阜新市",
+      "value": "2109"
+    },
+    {
+      "label": "辽阳市",
+      "value": "2110"
+    },
+    {
+      "label": "盘锦市",
+      "value": "2111"
+    },
+    {
+      "label": "铁岭市",
+      "value": "2112"
+    },
+    {
+      "label": "朝阳市",
+      "value": "2113"
+    },
+    {
+      "label": "葫芦岛市",
+      "value": "2114"
+    }
+  ],
+  [{
+      "label": "长春市",
+      "value": "2201"
+    },
+    {
+      "label": "吉林市",
+      "value": "2202"
+    },
+    {
+      "label": "四平市",
+      "value": "2203"
+    },
+    {
+      "label": "辽源市",
+      "value": "2204"
+    },
+    {
+      "label": "通化市",
+      "value": "2205"
+    },
+    {
+      "label": "白山市",
+      "value": "2206"
+    },
+    {
+      "label": "松原市",
+      "value": "2207"
+    },
+    {
+      "label": "白城市",
+      "value": "2208"
+    },
+    {
+      "label": "延边朝鲜族自治州",
+      "value": "2224"
+    }
+  ],
+  [{
+      "label": "哈尔滨市",
+      "value": "2301"
+    },
+    {
+      "label": "齐齐哈尔市",
+      "value": "2302"
+    },
+    {
+      "label": "鸡西市",
+      "value": "2303"
+    },
+    {
+      "label": "鹤岗市",
+      "value": "2304"
+    },
+    {
+      "label": "双鸭山市",
+      "value": "2305"
+    },
+    {
+      "label": "大庆市",
+      "value": "2306"
+    },
+    {
+      "label": "伊春市",
+      "value": "2307"
+    },
+    {
+      "label": "佳木斯市",
+      "value": "2308"
+    },
+    {
+      "label": "七台河市",
+      "value": "2309"
+    },
+    {
+      "label": "牡丹江市",
+      "value": "2310"
+    },
+    {
+      "label": "黑河市",
+      "value": "2311"
+    },
+    {
+      "label": "绥化市",
+      "value": "2312"
+    },
+    {
+      "label": "大兴安岭地区",
+      "value": "2327"
+    }
+  ],
+  [{
+    "label": "上海市",
+    "value": "3101"
+  }],
+  [{
+      "label": "南京市",
+      "value": "3201"
+    },
+    {
+      "label": "无锡市",
+      "value": "3202"
+    },
+    {
+      "label": "徐州市",
+      "value": "3203"
+    },
+    {
+      "label": "常州市",
+      "value": "3204"
+    },
+    {
+      "label": "苏州市",
+      "value": "3205"
+    },
+    {
+      "label": "南通市",
+      "value": "3206"
+    },
+    {
+      "label": "连云港市",
+      "value": "3207"
+    },
+    {
+      "label": "淮安市",
+      "value": "3208"
+    },
+    {
+      "label": "盐城市",
+      "value": "3209"
+    },
+    {
+      "label": "扬州市",
+      "value": "3210"
+    },
+    {
+      "label": "镇江市",
+      "value": "3211"
+    },
+    {
+      "label": "泰州市",
+      "value": "3212"
+    },
+    {
+      "label": "宿迁市",
+      "value": "3213"
+    }
+  ],
+  [{
+      "label": "杭州市",
+      "value": "3301"
+    },
+    {
+      "label": "宁波市",
+      "value": "3302"
+    },
+    {
+      "label": "温州市",
+      "value": "3303"
+    },
+    {
+      "label": "嘉兴市",
+      "value": "3304"
+    },
+    {
+      "label": "湖州市",
+      "value": "3305"
+    },
+    {
+      "label": "绍兴市",
+      "value": "3306"
+    },
+    {
+      "label": "金华市",
+      "value": "3307"
+    },
+    {
+      "label": "衢州市",
+      "value": "3308"
+    },
+    {
+      "label": "舟山市",
+      "value": "3309"
+    },
+    {
+      "label": "台州市",
+      "value": "3310"
+    },
+    {
+      "label": "丽水市",
+      "value": "3311"
+    }
+  ],
+  [{
+      "label": "合肥市",
+      "value": "3401"
+    },
+    {
+      "label": "芜湖市",
+      "value": "3402"
+    },
+    {
+      "label": "蚌埠市",
+      "value": "3403"
+    },
+    {
+      "label": "淮南市",
+      "value": "3404"
+    },
+    {
+      "label": "马鞍山市",
+      "value": "3405"
+    },
+    {
+      "label": "淮北市",
+      "value": "3406"
+    },
+    {
+      "label": "铜陵市",
+      "value": "3407"
+    },
+    {
+      "label": "安庆市",
+      "value": "3408"
+    },
+    {
+      "label": "黄山市",
+      "value": "3410"
+    },
+    {
+      "label": "滁州市",
+      "value": "3411"
+    },
+    {
+      "label": "阜阳市",
+      "value": "3412"
+    },
+    {
+      "label": "宿州市",
+      "value": "3413"
+    },
+    {
+      "label": "六安市",
+      "value": "3415"
+    },
+    {
+      "label": "亳州市",
+      "value": "3416"
+    },
+    {
+      "label": "池州市",
+      "value": "3417"
+    },
+    {
+      "label": "宣城市",
+      "value": "3418"
+    }
+  ],
+  [{
+      "label": "福州市",
+      "value": "3501"
+    },
+    {
+      "label": "厦门市",
+      "value": "3502"
+    },
+    {
+      "label": "莆田市",
+      "value": "3503"
+    },
+    {
+      "label": "三明市",
+      "value": "3504"
+    },
+    {
+      "label": "泉州市",
+      "value": "3505"
+    },
+    {
+      "label": "漳州市",
+      "value": "3506"
+    },
+    {
+      "label": "南平市",
+      "value": "3507"
+    },
+    {
+      "label": "龙岩市",
+      "value": "3508"
+    },
+    {
+      "label": "宁德市",
+      "value": "3509"
+    }
+  ],
+  [{
+      "label": "南昌市",
+      "value": "3601"
+    },
+    {
+      "label": "景德镇市",
+      "value": "3602"
+    },
+    {
+      "label": "萍乡市",
+      "value": "3603"
+    },
+    {
+      "label": "九江市",
+      "value": "3604"
+    },
+    {
+      "label": "新余市",
+      "value": "3605"
+    },
+    {
+      "label": "鹰潭市",
+      "value": "3606"
+    },
+    {
+      "label": "赣州市",
+      "value": "3607"
+    },
+    {
+      "label": "吉安市",
+      "value": "3608"
+    },
+    {
+      "label": "宜春市",
+      "value": "3609"
+    },
+    {
+      "label": "抚州市",
+      "value": "3610"
+    },
+    {
+      "label": "上饶市",
+      "value": "3611"
+    }
+  ],
+  [{
+      "label": "济南市",
+      "value": "3701"
+    },
+    {
+      "label": "青岛市",
+      "value": "3702"
+    },
+    {
+      "label": "淄博市",
+      "value": "3703"
+    },
+    {
+      "label": "枣庄市",
+      "value": "3704"
+    },
+    {
+      "label": "东营市",
+      "value": "3705"
+    },
+    {
+      "label": "烟台市",
+      "value": "3706"
+    },
+    {
+      "label": "潍坊市",
+      "value": "3707"
+    },
+    {
+      "label": "济宁市",
+      "value": "3708"
+    },
+    {
+      "label": "泰安市",
+      "value": "3709"
+    },
+    {
+      "label": "威海市",
+      "value": "3710"
+    },
+    {
+      "label": "日照市",
+      "value": "3711"
+    },
+    {
+      "label": "莱芜市",
+      "value": "3712"
+    },
+    {
+      "label": "临沂市",
+      "value": "3713"
+    },
+    {
+      "label": "德州市",
+      "value": "3714"
+    },
+    {
+      "label": "聊城市",
+      "value": "3715"
+    },
+    {
+      "label": "滨州市",
+      "value": "3716"
+    },
+    {
+      "label": "菏泽市",
+      "value": "3717"
+    }
+  ],
+  [{
+      "label": "郑州市",
+      "value": "4101"
+    },
+    {
+      "label": "开封市",
+      "value": "4102"
+    },
+    {
+      "label": "洛阳市",
+      "value": "4103"
+    },
+    {
+      "label": "平顶山市",
+      "value": "4104"
+    },
+    {
+      "label": "安阳市",
+      "value": "4105"
+    },
+    {
+      "label": "鹤壁市",
+      "value": "4106"
+    },
+    {
+      "label": "新乡市",
+      "value": "4107"
+    },
+    {
+      "label": "焦作市",
+      "value": "4108"
+    },
+    {
+      "label": "濮阳市",
+      "value": "4109"
+    },
+    {
+      "label": "许昌市",
+      "value": "4110"
+    },
+    {
+      "label": "漯河市",
+      "value": "4111"
+    },
+    {
+      "label": "三门峡市",
+      "value": "4112"
+    },
+    {
+      "label": "南阳市",
+      "value": "4113"
+    },
+    {
+      "label": "商丘市",
+      "value": "4114"
+    },
+    {
+      "label": "信阳市",
+      "value": "4115"
+    },
+    {
+      "label": "周口市",
+      "value": "4116"
+    },
+    {
+      "label": "驻马店市",
+      "value": "4117"
+    },
+    {
+      "label": "省直辖县级行政区划",
+      "value": "4190"
+    }
+  ],
+  [{
+      "label": "武汉市",
+      "value": "4201"
+    },
+    {
+      "label": "黄石市",
+      "value": "4202"
+    },
+    {
+      "label": "十堰市",
+      "value": "4203"
+    },
+    {
+      "label": "宜昌市",
+      "value": "4205"
+    },
+    {
+      "label": "襄阳市",
+      "value": "4206"
+    },
+    {
+      "label": "鄂州市",
+      "value": "4207"
+    },
+    {
+      "label": "荆门市",
+      "value": "4208"
+    },
+    {
+      "label": "孝感市",
+      "value": "4209"
+    },
+    {
+      "label": "荆州市",
+      "value": "4210"
+    },
+    {
+      "label": "黄冈市",
+      "value": "4211"
+    },
+    {
+      "label": "咸宁市",
+      "value": "4212"
+    },
+    {
+      "label": "随州市",
+      "value": "4213"
+    },
+    {
+      "label": "恩施土家族苗族自治州",
+      "value": "4228"
+    },
+    {
+      "label": "省直辖县级行政区划",
+      "value": "4290"
+    }
+  ],
+  [{
+      "label": "长沙市",
+      "value": "4301"
+    },
+    {
+      "label": "株洲市",
+      "value": "4302"
+    },
+    {
+      "label": "湘潭市",
+      "value": "4303"
+    },
+    {
+      "label": "衡阳市",
+      "value": "4304"
+    },
+    {
+      "label": "邵阳市",
+      "value": "4305"
+    },
+    {
+      "label": "岳阳市",
+      "value": "4306"
+    },
+    {
+      "label": "常德市",
+      "value": "4307"
+    },
+    {
+      "label": "张家界市",
+      "value": "4308"
+    },
+    {
+      "label": "益阳市",
+      "value": "4309"
+    },
+    {
+      "label": "郴州市",
+      "value": "4310"
+    },
+    {
+      "label": "永州市",
+      "value": "4311"
+    },
+    {
+      "label": "怀化市",
+      "value": "4312"
+    },
+    {
+      "label": "娄底市",
+      "value": "4313"
+    },
+    {
+      "label": "湘西土家族苗族自治州",
+      "value": "4331"
+    }
+  ],
+  [{
+      "label": "广州市",
+      "value": "4401"
+    },
+    {
+      "label": "韶关市",
+      "value": "4402"
+    },
+    {
+      "label": "深圳市",
+      "value": "4403"
+    },
+    {
+      "label": "珠海市",
+      "value": "4404"
+    },
+    {
+      "label": "汕头市",
+      "value": "4405"
+    },
+    {
+      "label": "佛山市",
+      "value": "4406"
+    },
+    {
+      "label": "江门市",
+      "value": "4407"
+    },
+    {
+      "label": "湛江市",
+      "value": "4408"
+    },
+    {
+      "label": "茂名市",
+      "value": "4409"
+    },
+    {
+      "label": "肇庆市",
+      "value": "4412"
+    },
+    {
+      "label": "惠州市",
+      "value": "4413"
+    },
+    {
+      "label": "梅州市",
+      "value": "4414"
+    },
+    {
+      "label": "汕尾市",
+      "value": "4415"
+    },
+    {
+      "label": "河源市",
+      "value": "4416"
+    },
+    {
+      "label": "阳江市",
+      "value": "4417"
+    },
+    {
+      "label": "清远市",
+      "value": "4418"
+    },
+    {
+      "label": "东莞市",
+      "value": "4419"
+    },
+    {
+      "label": "中山市",
+      "value": "4420"
+    },
+    {
+      "label": "潮州市",
+      "value": "4451"
+    },
+    {
+      "label": "揭阳市",
+      "value": "4452"
+    },
+    {
+      "label": "云浮市",
+      "value": "4453"
+    }
+  ],
+  [{
+      "label": "南宁市",
+      "value": "4501"
+    },
+    {
+      "label": "柳州市",
+      "value": "4502"
+    },
+    {
+      "label": "桂林市",
+      "value": "4503"
+    },
+    {
+      "label": "梧州市",
+      "value": "4504"
+    },
+    {
+      "label": "北海市",
+      "value": "4505"
+    },
+    {
+      "label": "防城港市",
+      "value": "4506"
+    },
+    {
+      "label": "钦州市",
+      "value": "4507"
+    },
+    {
+      "label": "贵港市",
+      "value": "4508"
+    },
+    {
+      "label": "玉林市",
+      "value": "4509"
+    },
+    {
+      "label": "百色市",
+      "value": "4510"
+    },
+    {
+      "label": "贺州市",
+      "value": "4511"
+    },
+    {
+      "label": "河池市",
+      "value": "4512"
+    },
+    {
+      "label": "来宾市",
+      "value": "4513"
+    },
+    {
+      "label": "崇左市",
+      "value": "4514"
+    }
+  ],
+  [{
+      "label": "海口市",
+      "value": "4601"
+    },
+    {
+      "label": "三亚市",
+      "value": "4602"
+    },
+    {
+      "label": "三沙市",
+      "value": "4603"
+    },
+    {
+      "label": "儋州市",
+      "value": "4604"
+    },
+    {
+      "label": "省直辖县级行政区划",
+      "value": "4690"
+    }
+  ],
+  [{
+      "label": "重庆市",
+      "value": "5001"
+    },
+    {
+      "label": "县",
+      "value": "5002"
+    }
+  ],
+  [{
+      "label": "成都市",
+      "value": "5101"
+    },
+    {
+      "label": "自贡市",
+      "value": "5103"
+    },
+    {
+      "label": "攀枝花市",
+      "value": "5104"
+    },
+    {
+      "label": "泸州市",
+      "value": "5105"
+    },
+    {
+      "label": "德阳市",
+      "value": "5106"
+    },
+    {
+      "label": "绵阳市",
+      "value": "5107"
+    },
+    {
+      "label": "广元市",
+      "value": "5108"
+    },
+    {
+      "label": "遂宁市",
+      "value": "5109"
+    },
+    {
+      "label": "内江市",
+      "value": "5110"
+    },
+    {
+      "label": "乐山市",
+      "value": "5111"
+    },
+    {
+      "label": "南充市",
+      "value": "5113"
+    },
+    {
+      "label": "眉山市",
+      "value": "5114"
+    },
+    {
+      "label": "宜宾市",
+      "value": "5115"
+    },
+    {
+      "label": "广安市",
+      "value": "5116"
+    },
+    {
+      "label": "达州市",
+      "value": "5117"
+    },
+    {
+      "label": "雅安市",
+      "value": "5118"
+    },
+    {
+      "label": "巴中市",
+      "value": "5119"
+    },
+    {
+      "label": "资阳市",
+      "value": "5120"
+    },
+    {
+      "label": "阿坝藏族羌族自治州",
+      "value": "5132"
+    },
+    {
+      "label": "甘孜藏族自治州",
+      "value": "5133"
+    },
+    {
+      "label": "凉山彝族自治州",
+      "value": "5134"
+    }
+  ],
+  [{
+      "label": "贵阳市",
+      "value": "5201"
+    },
+    {
+      "label": "六盘水市",
+      "value": "5202"
+    },
+    {
+      "label": "遵义市",
+      "value": "5203"
+    },
+    {
+      "label": "安顺市",
+      "value": "5204"
+    },
+    {
+      "label": "毕节市",
+      "value": "5205"
+    },
+    {
+      "label": "铜仁市",
+      "value": "5206"
+    },
+    {
+      "label": "黔西南布依族苗族自治州",
+      "value": "5223"
+    },
+    {
+      "label": "黔东南苗族侗族自治州",
+      "value": "5226"
+    },
+    {
+      "label": "黔南布依族苗族自治州",
+      "value": "5227"
+    }
+  ],
+  [{
+      "label": "昆明市",
+      "value": "5301"
+    },
+    {
+      "label": "曲靖市",
+      "value": "5303"
+    },
+    {
+      "label": "玉溪市",
+      "value": "5304"
+    },
+    {
+      "label": "保山市",
+      "value": "5305"
+    },
+    {
+      "label": "昭通市",
+      "value": "5306"
+    },
+    {
+      "label": "丽江市",
+      "value": "5307"
+    },
+    {
+      "label": "普洱市",
+      "value": "5308"
+    },
+    {
+      "label": "临沧市",
+      "value": "5309"
+    },
+    {
+      "label": "楚雄彝族自治州",
+      "value": "5323"
+    },
+    {
+      "label": "红河哈尼族彝族自治州",
+      "value": "5325"
+    },
+    {
+      "label": "文山壮族苗族自治州",
+      "value": "5326"
+    },
+    {
+      "label": "西双版纳傣族自治州",
+      "value": "5328"
+    },
+    {
+      "label": "大理白族自治州",
+      "value": "5329"
+    },
+    {
+      "label": "德宏傣族景颇族自治州",
+      "value": "5331"
+    },
+    {
+      "label": "怒江傈僳族自治州",
+      "value": "5333"
+    },
+    {
+      "label": "迪庆藏族自治州",
+      "value": "5334"
+    }
+  ],
+  [{
+      "label": "拉萨市",
+      "value": "5401"
+    },
+    {
+      "label": "日喀则市",
+      "value": "5402"
+    },
+    {
+      "label": "昌都市",
+      "value": "5403"
+    },
+    {
+      "label": "林芝市",
+      "value": "5404"
+    },
+    {
+      "label": "山南市",
+      "value": "5405"
+    },
+    {
+      "label": "那曲地区",
+      "value": "5424"
+    },
+    {
+      "label": "阿里地区",
+      "value": "5425"
+    }
+  ],
+  [{
+      "label": "西安市",
+      "value": "6101"
+    },
+    {
+      "label": "铜川市",
+      "value": "6102"
+    },
+    {
+      "label": "宝鸡市",
+      "value": "6103"
+    },
+    {
+      "label": "咸阳市",
+      "value": "6104"
+    },
+    {
+      "label": "渭南市",
+      "value": "6105"
+    },
+    {
+      "label": "延安市",
+      "value": "6106"
+    },
+    {
+      "label": "汉中市",
+      "value": "6107"
+    },
+    {
+      "label": "榆林市",
+      "value": "6108"
+    },
+    {
+      "label": "安康市",
+      "value": "6109"
+    },
+    {
+      "label": "商洛市",
+      "value": "6110"
+    }
+  ],
+  [{
+      "label": "兰州市",
+      "value": "6201"
+    },
+    {
+      "label": "嘉峪关市",
+      "value": "6202"
+    },
+    {
+      "label": "金昌市",
+      "value": "6203"
+    },
+    {
+      "label": "白银市",
+      "value": "6204"
+    },
+    {
+      "label": "天水市",
+      "value": "6205"
+    },
+    {
+      "label": "武威市",
+      "value": "6206"
+    },
+    {
+      "label": "张掖市",
+      "value": "6207"
+    },
+    {
+      "label": "平凉市",
+      "value": "6208"
+    },
+    {
+      "label": "酒泉市",
+      "value": "6209"
+    },
+    {
+      "label": "庆阳市",
+      "value": "6210"
+    },
+    {
+      "label": "定西市",
+      "value": "6211"
+    },
+    {
+      "label": "陇南市",
+      "value": "6212"
+    },
+    {
+      "label": "临夏回族自治州",
+      "value": "6229"
+    },
+    {
+      "label": "甘南藏族自治州",
+      "value": "6230"
+    }
+  ],
+  [{
+      "label": "西宁市",
+      "value": "6301"
+    },
+    {
+      "label": "海东市",
+      "value": "6302"
+    },
+    {
+      "label": "海北藏族自治州",
+      "value": "6322"
+    },
+    {
+      "label": "黄南藏族自治州",
+      "value": "6323"
+    },
+    {
+      "label": "海南藏族自治州",
+      "value": "6325"
+    },
+    {
+      "label": "果洛藏族自治州",
+      "value": "6326"
+    },
+    {
+      "label": "玉树藏族自治州",
+      "value": "6327"
+    },
+    {
+      "label": "海西蒙古族藏族自治州",
+      "value": "6328"
+    }
+  ],
+  [{
+      "label": "银川市",
+      "value": "6401"
+    },
+    {
+      "label": "石嘴山市",
+      "value": "6402"
+    },
+    {
+      "label": "吴忠市",
+      "value": "6403"
+    },
+    {
+      "label": "固原市",
+      "value": "6404"
+    },
+    {
+      "label": "中卫市",
+      "value": "6405"
+    }
+  ],
+  [{
+      "label": "乌鲁木齐市",
+      "value": "6501"
+    },
+    {
+      "label": "克拉玛依市",
+      "value": "6502"
+    },
+    {
+      "label": "吐鲁番市",
+      "value": "6504"
+    },
+    {
+      "label": "哈密市",
+      "value": "6505"
+    },
+    {
+      "label": "昌吉回族自治州",
+      "value": "6523"
+    },
+    {
+      "label": "博尔塔拉蒙古自治州",
+      "value": "6527"
+    },
+    {
+      "label": "巴音郭楞蒙古自治州",
+      "value": "6528"
+    },
+    {
+      "label": "阿克苏地区",
+      "value": "6529"
+    },
+    {
+      "label": "克孜勒苏柯尔克孜自治州",
+      "value": "6530"
+    },
+    {
+      "label": "喀什地区",
+      "value": "6531"
+    },
+    {
+      "label": "和田地区",
+      "value": "6532"
+    },
+    {
+      "label": "伊犁哈萨克自治州",
+      "value": "6540"
+    },
+    {
+      "label": "塔城地区",
+      "value": "6542"
+    },
+    {
+      "label": "阿勒泰地区",
+      "value": "6543"
+    },
+    {
+      "label": "自治区直辖县级行政区划",
+      "value": "6590"
+    }
+  ],
+  [{
+      "label": "台北",
+      "value": "6601"
+    },
+    {
+      "label": "高雄",
+      "value": "6602"
+    },
+    {
+      "label": "基隆",
+      "value": "6603"
+    },
+    {
+      "label": "台中",
+      "value": "6604"
+    },
+    {
+      "label": "台南",
+      "value": "6605"
+    },
+    {
+      "label": "新竹",
+      "value": "6606"
+    },
+    {
+      "label": "嘉义",
+      "value": "6607"
+    },
+    {
+      "label": "宜兰",
+      "value": "6608"
+    },
+    {
+      "label": "桃园",
+      "value": "6609"
+    },
+    {
+      "label": "苗栗",
+      "value": "6610"
+    },
+    {
+      "label": "彰化",
+      "value": "6611"
+    },
+    {
+      "label": "南投",
+      "value": "6612"
+    },
+    {
+      "label": "云林",
+      "value": "6613"
+    },
+    {
+      "label": "屏东",
+      "value": "6614"
+    },
+    {
+      "label": "台东",
+      "value": "6615"
+    },
+    {
+      "label": "花莲",
+      "value": "6616"
+    },
+    {
+      "label": "澎湖",
+      "value": "6617"
+    }
+  ],
+  [{
+      "label": "香港岛",
+      "value": "6701"
+    },
+    {
+      "label": "九龙",
+      "value": "6702"
+    },
+    {
+      "label": "新界",
+      "value": "6703"
+    }
+  ],
+  [{
+      "label": "澳门半岛",
+      "value": "6801"
+    },
+    {
+      "label": "氹仔岛",
+      "value": "6802"
+    },
+    {
+      "label": "路环岛",
+      "value": "6803"
+    },
+    {
+      "label": "路氹城",
+      "value": "6804"
+    }
+  ]
+]
+export default cityData;

+ 139 - 0
components/slambb-picker/city-data/province.js

@@ -0,0 +1,139 @@
+/* eslint-disable */
+var provinceData = [{
+    "label": "北京市",
+    "value": "11"
+  },
+  {
+    "label": "天津市",
+    "value": "12"
+  },
+  {
+    "label": "河北省",
+    "value": "13"
+  },
+  {
+    "label": "山西省",
+    "value": "14"
+  },
+  {
+    "label": "内蒙古自治区",
+    "value": "15"
+  },
+  {
+    "label": "辽宁省",
+    "value": "21"
+  },
+  {
+    "label": "吉林省",
+    "value": "22"
+  },
+  {
+    "label": "黑龙江省",
+    "value": "23"
+  },
+  {
+    "label": "上海市",
+    "value": "31"
+  },
+  {
+    "label": "江苏省",
+    "value": "32"
+  },
+  {
+    "label": "浙江省",
+    "value": "33"
+  },
+  {
+    "label": "安徽省",
+    "value": "34"
+  },
+  {
+    "label": "福建省",
+    "value": "35"
+  },
+  {
+    "label": "江西省",
+    "value": "36"
+  },
+  {
+    "label": "山东省",
+    "value": "37"
+  },
+  {
+    "label": "河南省",
+    "value": "41"
+  },
+  {
+    "label": "湖北省",
+    "value": "42"
+  },
+  {
+    "label": "湖南省",
+    "value": "43"
+  },
+  {
+    "label": "广东省",
+    "value": "44"
+  },
+  {
+    "label": "广西壮族自治区",
+    "value": "45"
+  },
+  {
+    "label": "海南省",
+    "value": "46"
+  },
+  {
+    "label": "重庆市",
+    "value": "50"
+  },
+  {
+    "label": "四川省",
+    "value": "51"
+  },
+  {
+    "label": "贵州省",
+    "value": "52"
+  },
+  {
+    "label": "云南省",
+    "value": "53"
+  },
+  {
+    "label": "西藏自治区",
+    "value": "54"
+  },
+  {
+    "label": "陕西省",
+    "value": "61"
+  },
+  {
+    "label": "甘肃省",
+    "value": "62"
+  },
+  {
+    "label": "青海省",
+    "value": "63"
+  },
+  {
+    "label": "宁夏回族自治区",
+    "value": "64"
+  },
+  {
+    "label": "新疆维吾尔自治区",
+    "value": "65"
+  },
+  {
+    "label": "台湾",
+    "value": "66"
+  },
+  {
+    "label": "香港",
+    "value": "67"
+  },
+  {
+    "label": "澳门",
+    "value": "68"
+  }
+]
+export default provinceData;

+ 72 - 0
components/slambb-picker/picker.js

@@ -0,0 +1,72 @@
+// picker组件数据信息
+
+const getWeightList = function() {
+	const leftList = []
+	const rightList = []
+	for (let i = 0; i <= 300; i++) {
+		leftList.push(i)
+	}
+	for (let i = 0; i <= 9; i++) {
+		rightList.push(i)
+	}
+	return {
+		leftList,
+		rightList
+	}
+}
+const getHeightList = function() {
+	const leftList = []
+	const rightList = []
+	for (let i = 0; i <= 300; i++) {
+		leftList.push(i)
+	}
+	for (let i = 0; i <= 9; i++) {
+		rightList.push(i)
+	}
+	return {
+		leftList,
+		rightList
+	}
+}
+const getGenderList = function() {
+	const genderList = [];
+	genderList.push('男');
+	genderList.push('女');
+	// genderList.push('其他')
+
+	return {
+		genderList
+	}
+}
+
+const getCalorieList = function() {
+	const calorieList = []
+	for (let i = 1; i <= 1000; i+=1) {
+		calorieList.push(i)
+	}
+
+	return {
+		calorieList
+	}
+}
+
+const getMinuteList = function() {
+	const minuteList = []
+	for (let i = 0; i < 100; i++) {
+		if(i==0)
+			minuteList.push(1);
+		else
+			minuteList.push(i*5)
+	}
+
+	return {
+		minuteList
+	}
+}
+export default {
+	getWeightList,
+	getHeightList,
+	getGenderList,
+	getCalorieList,
+	getMinuteList
+}

+ 177 - 0
components/slambb-picker/slambb-picker-city.vue

@@ -0,0 +1,177 @@
+<template>
+	<view class="city-container ">
+		<view class="city-view">
+			<picker-view class="city-picker-view" v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange">
+				<picker-view-column>
+					<view class="city-item" v-for="(picker_item,picker_index) in provinceDataList" :key="picker_index">{{picker_item.label}}</view>
+				</picker-view-column>
+				<picker-view-column>
+					<view class="city-item" v-for="(picker_item,picker_index) in cityDataList" :key="picker_index">{{picker_item.label}}</view>
+				</picker-view-column>
+				<picker-view-column>
+					<view class="city-item" v-for="(picker_item,picker_index) in areaDataList" :key="picker_index">{{picker_item.label}}</view>
+				</picker-view-column>
+			</picker-view>
+		</view>
+	</view>
+</template>
+-
+<script>
+	var minDate = 1950;
+	var provinceData = {};
+	var cityData = {};
+	var areaData = {};
+
+	export default {
+		props: {
+			itemObj: { //各类型携带的数据
+				type: Object,
+				default () {
+					return {};
+				}
+			}
+		},
+		data() {
+			return {
+				provinceDataList: [],
+				cityDataList: [],
+				areaDataList: [],
+				// 年月日
+				value: [],
+				visible: true,
+				indicatorStyle: `height: 65rpx; `,
+			}
+		},
+		//组件生命周期
+		// created: function(e) {
+		// 	console.log("created itemObj=", this.bInit);
+		// },
+		// destroyed:function(e){
+		// 	console.log("destroyed itemObj=", this.bInit);
+		// },
+		mounted() {
+			let value = [];
+			let provinceDataList;
+			let cityDataList;
+			let areaDataList;
+
+			provinceData = require('./city-data/province.js').default;
+			cityData = require('./city-data/city.js').default;
+			areaData = require('./city-data/area.js').default;
+
+			value =  this.itemObj.defaultValue || [0, 0, 0];
+			// 解析citycode
+			// for (let i = 0; i < provinceData.length; i++) {
+			// 	if (provinceData[i].value == this.itemObj.defaultValue.substr(0, 2)) {
+			// 		let currentCityData = cityData[i];
+			// 		for (let j = 0; j < currentCityData.length; j++) {
+			// 			if (currentCityData[j].value == this.itemObj.defaultValue.substr(0, 4)) {
+			// 				let areaDataTemp = areaData[i][j];
+			// 				for (let k = 0; k < areaDataTemp.length; k++) {
+			// 					if (areaDataTemp[k].value == this.itemObj.defaultValue) {
+			// 						value = [i, j, k];
+			// 						break;
+			// 					}
+			// 				}
+			// 				break;
+			// 			}
+			// 		}
+			// 		break;
+			// 	}
+			// }
+
+			provinceDataList = provinceData;
+			cityDataList = cityData[value[0]];
+			areaDataList = areaData[value[0]][value[1]];
+
+			//city、provincialStreet
+			this.provinceDataList = provinceDataList;
+			this.cityDataList = cityDataList;
+			this.areaDataList = areaDataList;
+			this.value = value;
+			// console.log('显示时候更新一次数据');
+			this.$emit('bindChangeCity', {
+				label: this._getLabel(),
+				value: this.value,
+				cityCode: this._getCityCode()
+			});
+		},
+		methods: {
+			_getLabel() {
+				let pcikerLabel =
+					this.provinceDataList[this.value[0]].label +
+					'-' +
+					this.cityDataList[this.value[1]].label +
+					'-' +
+					this.areaDataList[this.value[2]].label;
+				return pcikerLabel;
+			},
+			_getCityCode() {
+				return this.areaDataList[this.value[2]].value;
+			},
+			bindChange({
+				detail: {
+					value
+				}
+			}) {
+				// console.log(JSON.stringify(e))
+				let changevalue;
+				changevalue = value;
+				if (this.value[0] !== changevalue[0]) {
+					// 第一级发生滚动
+					this.cityDataList = cityData[changevalue[0]];
+					this.areaDataList = areaData[changevalue[0]][0];
+					changevalue[1] = 0;
+					changevalue[2] = 0;
+				} else if (this.value[1] !== changevalue[1]) {
+					// 第二级滚动
+					this.areaDataList = areaData[changevalue[0]][changevalue[1]];
+					changevalue[2] = 0;
+				}
+				this.value = changevalue;
+
+				this.$emit('bindChangeCity', {
+					label: this._getLabel(),
+					value: this.value,
+					cityCode: this._getCityCode()
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	/* picker */
+	.city-container {
+		position: relative;
+		display: flex;
+		justify-content: center;
+	}
+
+	.city-view {
+		background: #FFFFFF;
+		width: 100%;
+		height: 300rpx;
+		display: flex;
+		justify-content: center;
+		border-radius: 20upx;
+	}
+
+	.city-picker-view {
+		width: 100%;
+		height: 300rpx;
+		border-radius: 20px;
+	}
+
+	.city-item {
+		text-align: center;
+		width: calc(100% - 0px);
+		height: 65rpx;
+		line-height: 65rpx;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		font-size: 20px;
+		color: rgba(164, 136, 220, 1);
+	}
+
+</style>

+ 234 - 0
components/slambb-picker/slambb-picker-date.vue

@@ -0,0 +1,234 @@
+<template>
+	<view class="date-container ">
+		<view class="date-view">
+			<picker-view class="mpvue-picker-view" v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange">
+				<picker-view-column>
+					<view class="item" v-for="(item,index) in years" :key="index">{{item}}</view>
+				</picker-view-column>
+				<picker-view-column>
+					<view class="item" v-for="(item,index) in months" :key="index">{{item}}</view>
+				</picker-view-column>
+				<picker-view-column>
+					<view class="item" v-for="(item,index) in days" :key="index">{{item}}</view>
+				</picker-view-column>
+			</picker-view>
+		</view>
+		<view class="picker-unit text-gray">年 月 日</view>
+		<!-- <view class="picker-unit-center">年月日 </view> -->
+	</view>
+</template>
+
+<script>
+	var minDate = 1950;
+	export default {
+
+		data() {
+			const date = new Date()
+			const years = []
+			const year = date.getFullYear()
+			const months = []
+			const month = date.getMonth() + 1
+			const days = []
+			const day = date.getDate()
+			// for (let i = 2040; i >= 1950; i--) {
+			// 	years.push(i)
+			// }
+			// for (let i = 12; i > 0; i--) {
+			// 	months.push(i)
+			// }
+			// for (let i = 31; i > 0; i--) {
+			// 	days.push(i)
+			// }
+
+			for (let i = minDate; i <= date.getFullYear()+10; i++) {
+				years.push(i)
+			}
+			for (let i = 1; i <= 12; i++) {
+				months.push(i)
+			}
+			for (let i = 1; i <= 31; i++) {
+				days.push(i)
+			}
+
+			return {
+
+				// 年月日
+				years,
+				year,
+				months,
+				month,
+				days,
+				day,
+				value: [year-minDate, month - 1, day - 1],
+				// value: [2040 - year, 12 - (month - 1), 30 - (day - 1)],
+				visible: true,
+				indicatorStyle: `height: 65rpx; `
+			}
+		},
+		mounted() {
+			// console.log('显示时候更新一次数据');
+			this.value=[this.year-minDate, this.month - 1, this.day - 1];
+			this.$emit('bindChangeDate', [this.year, this.month, this.day]);
+		},
+		methods: {
+			bindChange: function(e) {
+				const val = e.detail.value
+				this.year = this.years[val[0]]
+				this.month = this.months[val[1]]
+				this.day = this.days[val[2]]
+				
+				//将选择的年月日变为number形式,便于比较之用
+				var y = parseInt(this.year)
+				var m = parseInt(this.month)
+				var d = parseInt(this.day)
+
+				//选择不同月份显示的天数不同
+				if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
+					if (this.days.length != 31) {
+						this.days = []
+						for (let i = 1; i <= 31; i++) {
+							this.days.push(i)
+						}
+						// for (let i = 31; i > 0; i--) {
+						// 	this.days.push(i)
+						// }
+					}
+				} else if (m == 4 || m == 6 || m == 9 || m == 11) {
+					if (this.days.length != 30) {
+						this.days = []
+						for (let i = 1; i <= 30; i++) {
+							this.days.push(i)
+						}
+						// for (let i = 30; i > 0; i--) {
+						// 	this.days.push(i)
+						// }
+					}
+				} else if (m == 2) {
+					if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) { //闰年
+						if (this.days.length != 29) {
+							this.days = []
+							for (let i = 1; i <= 29; i++) {
+								this.days.push(i)
+							}
+							// for (let i = 29; i > 0; i--) {
+							// 	this.days.push(i)
+							// }
+						}
+					} else { //平年
+						if (this.days.length != 28) {
+							this.days = []
+							for (let i = 1; i <= 28; i++) {
+								this.days.push(i)
+							}
+							// for (let i = 28; i > 0; i--) {
+							// 	this.days.push(i)
+							// }
+						}
+					}
+				}
+
+
+				//处理选择今年的情况
+				if (y == this.currentYear) {
+
+					//最多显示到当前月份
+					if (this.months.length != this.currentMonth) {
+						this.months = []
+						for (let i = 1; i <= this.currentMonth; i++) {
+							this.months.push(i)
+						}
+						// for (let i = this.currentMonth; i > 0; i--) {
+						// 	this.months.push(i)
+						// }
+					}
+
+					//如果选择的是当前月份,那么日最多显示到今天
+					if (m == this.currentMonth) {
+						if (this.days.length != this.currentDay) {
+							this.days = []
+							for (let i = 1; i <= this.currentDay; i++) {
+								this.days.push(i)
+							}
+							// for (let i = this.currentDay; i > 0; i--) {
+							// 	this.days.push(i)
+							// }
+						}
+					}
+
+				} else {
+					this.months = []
+					for (let i = 1; i <= 12; i++) {
+						this.months.push(i)
+					}
+					// for (let i = 12; i > 0; i--) {
+					// 	this.months.push(i)
+					// }
+				}
+
+				this.$emit('bindChangeDate', [this.year, this.month, this.day])
+			},
+		}
+	}
+</script>
+
+<style>
+	/* picker */
+	.date-container {
+		position: relative;
+		display: flex;
+		justify-content: center;
+	}
+
+	.date-view {
+		background: #FFFFFF;
+		width: 100%;
+		height: 300rpx;
+		display: flex;
+		justify-content: center;
+		border-radius: 20upx;
+	}
+
+	.mpvue-picker-view {
+		width: calc(80% - 200rpx);
+		/* padding-top: 10px; */
+		height: 300rpx;
+		/* background-color: rgba(255, 85, 0, 1); */
+		border-radius: 20px;
+		/* display: flex; */
+	}
+
+	.item {
+		text-align: center;
+		width: calc(100% - 0px);
+		/* background-color: rgba(255, 170, 127, 1); */
+		height: 65rpx;
+		line-height: 65rpx;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		font-size: 20px;
+		color: rgba(164, 136, 220, 1);
+		/* padding-right: 10upx; */
+		/* border: 1rpx solid #007AFF; */
+	}
+
+	.picker-unit {
+		position: absolute;
+		left: 20px;
+		top: 20px;
+		font-size: 13px;
+		line-height: 26px;
+		z-index: 100;
+	}
+
+	.picker-unit-center {
+		position: absolute;
+		left: 90rpx;
+		top: 120rpx;
+		width: 100%;
+		font-size: 13px;
+		color: rgba(164, 136, 220, 1);
+		line-height: 40px;
+		z-index: 100;
+		letter-spacing: 80rpx;
+	}
+</style>

+ 143 - 0
components/slambb-picker/slambb-picker-item.vue

@@ -0,0 +1,143 @@
+<template>
+	<view class="padding-sm">
+		<view class="flex justify-between" style="position: relative;height: 100%; width: 100%;">
+			<picker-view class="mpvue-picker-view " :value="leftValue" :style="[{'--multiple': rightVisible ? 1 : 2}]"
+			 :indicator-style="indicatorStyle" @change="bindChange('left',$event)">
+				<picker-view-column>
+					<view class="item" v-for="(item,index) in currentItemobj.pickerLeftList" :key="index">{{item}}</view>
+				</picker-view-column>
+			</picker-view>
+			<picker-view class="mpvue-picker-view " :value="rightValue" :style="[{'--multiple': rightVisible ? 1 : 2}]" v-if="rightVisible"
+			 :indicator-style="indicatorStyle" @change="bindChange('right',$event)">
+				<picker-view-column>
+					<view class="item" v-for="(item,index) in currentItemobj.pickerRightList" :key="index">.{{item}}
+					</view>
+				</picker-view-column>
+			</picker-view>
+			<view v-if="currentItemobj.pickerUnit" class="picker-unit text-sm text-purple" style="z-index: 10;">{{currentItemobj.pickerUnit}}</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+
+		props: {
+			leftList: Array,
+			rightList: Array,
+			showUnit: {
+				type: String,
+				default: ""
+			},
+			itemObj: Object,
+			bDouble: true
+		},
+		data() {
+			let LIndex = 0;
+			let RIndex = 0;
+			if (this.bDouble) {
+				// console.log(this.itemObj.defaultValue);
+				if(this.itemObj.defaultValue){
+					var valueArr = this.itemObj.defaultValue.toString().split(".");
+					for (let i = 0; i < this.itemObj.pickerLeftList.length; i++) {
+						if (valueArr[0] == this.itemObj.pickerLeftList[i]) {
+							LIndex = i;
+							break;
+						}
+					}
+					for (let i = 0; i < this.itemObj.pickerRightList.length; i++) {
+						if (valueArr[1] == this.itemObj.pickerRightList[i]) {
+							RIndex = i;
+							break;
+						}
+					}
+				}
+				
+			} else {
+				for (let i = 0; i < this.itemObj.pickerLeftList.length; i++) {
+					if (this.itemObj.defaultValue == this.itemObj.pickerLeftList[i]) {
+						LIndex = i;
+						break;
+					}
+				}
+
+
+			}
+			this.$emit("bindChangeItem", this.itemObj.defaultValue,LIndex);
+			return {
+				leftValue: [LIndex],
+				rightValue: [RIndex],
+				oldLeftValue: this.itemObj.pickerLeftList[LIndex],
+				oldRightValue: this.itemObj.pickerRightList[RIndex],
+				visible: true,
+				rightVisible: this.bDouble,
+				// indicatorStyle: `height: ${Math.round(uni.getSystemInfoSync().screenWidth/(750/100))}px;`
+				indicatorStyle: `height:40px;`,
+				currentItemobj: this.itemObj
+			}
+		},
+		watch: {
+			bDouble(val) {
+				// console.log('watch bDouble:', val);
+				this.rightVisible = val;
+			},
+			itemObj(val) {
+				// 重新赋值
+				// console.log('watch itemObj:', val);
+				this.currentItemobj = val;
+			}
+		},
+
+		methods: {
+			bindChange: function(direction, e) {
+				const val = e.detail.value
+				if (direction == "left") {
+					this.oldLeftValue = this.itemObj.pickerLeftList[val[0]];
+				} else {
+					// console.log(this.itemObj.pickerRightList[val[0]]);
+					this.oldRightValue = this.itemObj.pickerRightList[val[0]];
+				}
+				// console.log("==",this.oldLeftValue,"==",this.oldRightValue);
+				if (this.rightVisible) {
+					this.$emit("bindChangeItem", this.oldLeftValue + (this.oldRightValue / 10),val[0]);
+				} else {
+					this.$emit("bindChangeItem", this.oldLeftValue,val[0]);
+				}
+			},
+		}
+	}
+</script>
+
+<style>
+	/* picker */
+	.mpvue-picker-view {
+		width: calc(50% * var(--multiple) - 5px);
+		height: calc(300px / var(--multiple));
+		border-radius: 20px;
+	}
+
+	.item {
+		text-align: center;
+		width: calc(100% - 0px);
+		background-color: rgba(255, 255, 255, 1);
+		height: 88upx;
+		line-height: 88upx;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		font-size: 40upx;
+		/* border-radius: 5px; */
+		/* margin-top: 5px; */
+
+	}
+
+	.picker-unit {
+		position: absolute;
+		top: 0;
+		right: 30rpx;
+		/* left: 0; */
+		bottom: 0;
+		margin: auto;
+		display: flex;
+		align-items: center;
+	}
+</style>

+ 163 - 0
components/slambb-picker/slambb-picker.vue

@@ -0,0 +1,163 @@
+<template>
+	<view>
+		<view class="padding-sm">
+			<view class=" text-center text-black text-bold padding-bottom-sm margin-sm">{{currentPicker.pickerTitle}}</view>
+			<view v-if="currentPicker.showInput" class="flex justify-center">
+				<input class="picker-input" maxlength="4" @input="onKeyInput" placeholder-style="font-size:10px;" placeholder="直接输入" />
+				<view class="make-text-bPurple">{{currentPicker.pickerUnit}}</view>
+			</view>
+			<pickerItem v-if="currentPicker.pickerType=='doubleItem'" :itemObj="currentPicker" :bDouble="true" @bindChangeItem="bindChange"
+			 @touchstart="onStart">
+			</pickerItem>
+			<pickerItem v-else-if="currentPicker.pickerType=='singleItem'" :itemObj="currentPicker" :bDouble="false"
+			 @bindChangeItem="bindChange" @touchstart="onStart">
+			</pickerItem>
+			<pickerCity v-else-if="currentPicker.pickerType == 'city'" :itemObj="currentPicker" @bindChangeCity="bindChange"></pickerCity>
+			<pickerDateItem v-else @bindChangeDate="bindChange" @touchstart="onStart"></pickerDateItem>
+		</view>
+		<view class="flex justify-center cu-bar margin-bottom">
+			<view class="action  left-button " :class="bRolling?'bDisable':''" @tap="onConfirm">确定</view>
+			<view class="action  right-button" @tap="onCancel">取消</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import pickerItem from "@/components/slambb-picker/slambb-picker-item.vue";
+	import pickerDateItem from "@/components/slambb-picker/slambb-picker-date.vue";
+	import pickerCity from "@/components/slambb-picker/slambb-picker-city.vue";
+
+	export default {
+		components: {
+			pickerItem,
+			pickerDateItem,
+			pickerCity
+		},
+		props: {
+			//对象
+			pickerObj: Object,
+			pickerTitle: {
+				type: String,
+				default: ""
+			},
+			pickerType: {
+				type: String,
+				default: ""
+			},
+			pickerLeftList: Array,
+			pickerRightList: Array,
+			pickerUnit: {
+				type: String,
+				default: ""
+			},
+		},
+		data() {
+			return {
+				confirmValue: 0,
+				valueIndex: 0,
+				currentPicker: this.pickerObj,
+				//是否正在滚动
+				bRolling: false
+			}
+		},
+		watch: {
+			pickerObj(val) {
+				// 重新赋值
+				console.log('watch pickerObj:', val);
+				this.currentPicker = val;
+				this.confirmValue = 0;
+				this.valueIndex = 0;
+			}
+		},
+
+		methods: {
+			onStart() {
+				console.log('onStart')
+				this.bRolling = true;
+			},
+			bindChange(value, index) {
+				this.bRolling = false;
+				// console.log('bindChange=', value, index);
+				this.confirmValue = value;
+				this.valueIndex = index;
+			},
+			onConfirm() {
+				if (this.bRolling) {
+					uni.showToast({
+						title: '请等待滚动完成',
+						icon: "none"
+					})
+					return;
+				}
+
+				this.$emit("confirmEvent", {
+					type: this.currentPicker.pickerType,
+					value: this.confirmValue,
+					index: this.valueIndex
+				})
+			},
+			onCancel() {
+				this.$emit("cancelEvent")
+			},
+			onKeyInput(event) {
+				// !(/(^[1-9]\d*$)/).test(event.target.value)
+				if (isNaN(event.target.value)) {
+					//如果不是数字...
+					// uni.showToast({
+					// 	title: '输入正整数',
+					// 	icon:'none',
+					// 	mask:true
+					// })
+					this.confirmValue = 1;
+				} else {
+					this.confirmValue = Math.abs(event.target.value);
+				}
+
+				console.log("this.confirmValue:", this.confirmValue);
+				// this.$set(this.currentPicker, 'defaultValue', this.confirmValue);
+			}
+		}
+	}
+</script>
+
+<style>
+	.cu-dialog {
+		width: 100%;
+		border-top-left-radius: 20upx;
+		border-top-right-radius: 20upx;
+	}
+
+	.left-button,
+	.right-button {
+		margin-bottom: 20upx;
+		padding: 15upx 60upx;
+		background-color: #FFFFFF;
+	}
+
+	.bDisable {
+		/* background-color: ;
+		 */
+		opacity: 0.5;
+	}
+
+	.left-button {
+		border-top-left-radius: 20px;
+		border-bottom-left-radius: 20px;
+		border-right: 1upx solid #E6E6E6;
+		/* color:rgba(245, 245, 245, 1); */
+	}
+
+	.right-button {
+		border-top-right-radius: 20px;
+		border-bottom-right-radius: 20px;
+	}
+
+	.picker-input {
+		margin-left: 20rpx;
+		margin-right: 20rpx;
+		border: 1rpx solid #AAAAAA;
+		background-color: #FFFFFF;
+		width: 330rpx;
+		border-radius: 5px;
+	}
+</style>

+ 165 - 0
components/u-charts/component.vue

@@ -0,0 +1,165 @@
+<template>
+	<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
+	 @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
+	</canvas>
+</template>
+
+<script>
+	import uCharts from './u-charts.js';
+	var canvases = {};
+	
+	export default {
+		props: {
+			chartType: {
+				required: true,
+				type: String,
+				default: 'column'
+			},
+			opts: {
+				required: true,
+				type: Object,
+				default () {
+					return null;
+				},
+			},
+			canvasId: {
+				type: String,
+				default: 'u-canvas',
+			},
+			cWidth: {
+				default: 375,
+			},
+			cHeight: {
+				default: 250,
+			},
+			pixelRatio: {
+				type: Number,
+				default: 1,
+			},
+		},
+		mounted() {
+			this.init();
+		},
+		methods: {
+			init() {
+				switch (this.chartType) {
+					case 'column':
+						this.initColumnChart();
+						break;
+					case 'line':
+						this.initLineChart();
+						break;
+					default:
+						break;
+				}
+			},
+			initColumnChart() {
+				canvases[this.canvasId] = new uCharts({
+					$this: this,
+					canvasId: this.canvasId,
+					type: 'column',
+					legend: true,
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: this.pixelRatio,
+					animation: true,
+					categories: this.opts.categories,
+					series: this.opts.series,
+					enableScroll: true,
+					xAxis: {
+						disableGrid: true,
+						itemCount: 4,
+						scrollShow: true
+					},
+					yAxis: {
+						//disabled:true
+					},
+					dataLabel: true,
+					width: this.cWidth * this.pixelRatio,
+					height: this.cHeight * this.pixelRatio,
+					extra: {
+						column: {
+							type: 'group',
+						}
+					}
+				});
+			},
+			initLineChart() {
+				canvases[this.canvasId] = new uCharts({
+					$this: this,
+					canvasId: this.canvasId,
+					type: 'line',
+					fontSize: 11,
+					legend: true,
+					dataLabel: false,
+					dataPointShape: true,
+					background: '#FFFFFF',
+					pixelRatio: this.pixelRatio,
+					categories: this.opts.categories,
+					series: this.opts.series,
+					animation: true,
+					enableScroll: true,
+					xAxis: {
+						type: 'grid',
+						gridColor: '#CCCCCC',
+						gridType: 'dash',
+						dashLength: 8,
+						itemCount: 4,
+						scrollShow: true
+					},
+					yAxis: {
+						gridType: 'dash',
+						gridColor: '#CCCCCC',
+						dashLength: 8,
+						splitNumber: 5,
+						min: 10,
+						max: 180,
+						format: (val) => {
+							return val.toFixed(0) + '元'
+						}
+					},
+					width: this.cWidth * this.pixelRatio,
+					height: this.cHeight * this.pixelRatio,
+					extra: {
+						line: {
+							type: 'straight'
+						}
+					}
+				});
+			},
+			// 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
+			changeData(cid,newdata) {
+				canvases[cid].updateData({
+					series: newdata.series,
+					categories: newdata.categories
+				});
+			},
+			touchStart(e) {
+				canvases[this.canvasId].showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+				canvases[this.canvasId].scrollStart(e);
+			},
+			touchMove(e) {
+				canvases[this.canvasId].scroll(e);
+			},
+			touchEnd(e) {
+				canvases[this.canvasId].scrollEnd(e);
+			},
+			error(e) {
+				console.log(e)
+			}
+		},
+	};
+</script>
+
+<style scoped>
+	.charts {
+		width: 100%;
+		height: 100%;
+		flex: 1;
+		background-color: #FFFFFF;
+	}
+</style>

+ 6023 - 0
components/u-charts/u-charts.js

@@ -0,0 +1,6023 @@
+/*
+ * uCharts v1.9.3.20190922
+ * uni-app平台高性能跨全端图表,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)
+ * Copyright (c) 2019 QIUN秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 
+ * uCharts官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ */
+
+'use strict';
+
+var config = {
+	yAxisWidth: 15,
+	yAxisSplit: 5,
+	xAxisHeight: 15,
+	xAxisLineHeight: 15,
+	legendHeight: 15,
+	yAxisTitleWidth: 15,
+	padding: [10, 10, 10, 10],
+	pixelRatio: 1,
+	rotate: false,
+	columePadding: 3,
+	fontSize: 13,
+	//dataPointShape: ['diamond', 'circle', 'triangle', 'rect'],
+	dataPointShape: ['circle', 'circle', 'circle', 'circle'],
+	colors: ['#1890ff', '#2fc25b', '#facc14', '#f04864', '#8543e0', '#90ed7d'],
+	pieChartLinePadding: 15,
+	pieChartTextPadding: 5,
+	xAxisTextPadding: 3,
+	titleColor: '#333333',
+	titleFontSize: 20,
+	subtitleColor: '#999999',
+	subtitleFontSize: 15,
+	unitFontSize: 11,
+	toolTipPadding: 3,
+	toolTipBackground: '#000000',
+	toolTipOpacity: 0.7,
+	toolTipLineHeight: 20,
+	radarLabelTextMargin: 15,
+	gaugeLabelTextMargin: 15,
+
+	// slam todo
+	arcbarDate: '',
+	molecularUnit: 'ka',
+	denominatorUnit: '0',
+	enableBottomSolid: false,
+};
+
+let assign = function(target, ...varArgs) {
+	if (target == null) {
+		throw new TypeError('Cannot convert undefined or null to object');
+	}
+	if (!varArgs || varArgs.length <= 0) {
+		return target;
+	}
+	// 深度合并对象
+	function deepAssign(obj1, obj2) {
+		for (let key in obj2) {
+			obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
+				deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key];
+		}
+		return obj1;
+	}
+
+	varArgs.forEach(val => {
+		target = deepAssign(target, val);
+	});
+	return target;
+};
+
+var util = {
+	toFixed: function toFixed(num, limit) {
+		limit = limit || 2;
+		if (this.isFloat(num)) {
+			num = num.toFixed(limit);
+		}
+		return num;
+	},
+	isFloat: function isFloat(num) {
+		return num % 1 !== 0;
+	},
+	approximatelyEqual: function approximatelyEqual(num1, num2) {
+		return Math.abs(num1 - num2) < 1e-10;
+	},
+	isSameSign: function isSameSign(num1, num2) {
+		return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
+	},
+	isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
+		return this.isSameSign(p1.x, p2.x);
+	},
+	isCollision: function isCollision(obj1, obj2) {
+		obj1.end = {};
+		obj1.end.x = obj1.start.x + obj1.width;
+		obj1.end.y = obj1.start.y - obj1.height;
+		obj2.end = {};
+		obj2.end.x = obj2.start.x + obj2.width;
+		obj2.end.y = obj2.start.y - obj2.height;
+		var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y <
+			obj1.end.y;
+		return !flag;
+	}
+};
+
+//兼容H5点击事件
+function getH5Offset(e) {
+	e.mp = {
+		changedTouches: []
+	};
+	e.mp.changedTouches.push({
+		x: e.offsetX,
+		y: e.offsetY
+	});
+	return e;
+}
+
+// hex 转 rgba
+function hexToRgb(hexValue, opc) {
+	var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+	var hex = hexValue.replace(rgx, function(m, r, g, b) {
+		return r + r + g + g + b + b;
+	});
+	var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+	var r = parseInt(rgb[1], 16);
+	var g = parseInt(rgb[2], 16);
+	var b = parseInt(rgb[3], 16);
+	return 'rgba(' + r + ',' + g + ',' + b + ',' + opc + ')';
+}
+
+function findRange(num, type, limit) {
+	if (isNaN(num)) {
+		throw new Error('[uCharts] unvalid series data!');
+	}
+	limit = limit || 10;
+	type = type ? type : 'upper';
+	var multiple = 1;
+	while (limit < 1) {
+		limit *= 10;
+		multiple *= 10;
+	}
+	if (type === 'upper') {
+		num = Math.ceil(num * multiple);
+	} else {
+		num = Math.floor(num * multiple);
+	}
+	while (num % limit !== 0) {
+		if (type === 'upper') {
+			num++;
+		} else {
+			num--;
+		}
+	}
+	return num / multiple;
+}
+
+function calCandleMA(dayArr, nameArr, colorArr, kdata) {
+	let seriesTemp = [];
+	for (let k = 0; k < dayArr.length; k++) {
+		let seriesItem = {
+			data: [],
+			name: nameArr[k],
+			color: colorArr[k]
+		};
+		for (let i = 0, len = kdata.length; i < len; i++) {
+			if (i < dayArr[k]) {
+				seriesItem.data.push(null);
+				continue;
+			}
+			let sum = 0;
+			for (let j = 0; j < dayArr[k]; j++) {
+				sum += kdata[i - j][1];
+			}
+			seriesItem.data.push(+(sum / dayArr[k]).toFixed(3));
+		}
+		seriesTemp.push(seriesItem);
+	}
+	return seriesTemp;
+}
+
+function calValidDistance(self, distance, chartData, config, opts) {
+	var dataChartAreaWidth = opts.width - opts.area[1] - opts.area[3];
+	var dataChartWidth = chartData.eachSpacing * (opts.chartData.xAxisData.xAxisPoints.length - 1);
+	var validDistance = distance;
+	if (distance >= 0) {
+		validDistance = 0;
+		self.event.trigger('scrollLeft');
+	} else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
+		validDistance = dataChartAreaWidth - dataChartWidth;
+		self.event.trigger('scrollRight');
+	}
+	return validDistance;
+}
+
+function isInAngleRange(angle, startAngle, endAngle) {
+	function adjust(angle) {
+		while (angle < 0) {
+			angle += 2 * Math.PI;
+		}
+		while (angle > 2 * Math.PI) {
+			angle -= 2 * Math.PI;
+		}
+		return angle;
+	}
+	angle = adjust(angle);
+	startAngle = adjust(startAngle);
+	endAngle = adjust(endAngle);
+	if (startAngle > endAngle) {
+		endAngle += 2 * Math.PI;
+		if (angle < startAngle) {
+			angle += 2 * Math.PI;
+		}
+	}
+	return angle >= startAngle && angle <= endAngle;
+}
+
+function calRotateTranslate(x, y, h) {
+	var xv = x;
+	var yv = h - y;
+	var transX = xv + (h - yv - xv) / Math.sqrt(2);
+	transX *= -1;
+	var transY = (h - yv) * (Math.sqrt(2) - 1) - (h - yv - xv) / Math.sqrt(2);
+	return {
+		transX: transX,
+		transY: transY
+	};
+}
+
+function createCurveControlPoints(points, i) {
+
+	function isNotMiddlePoint(points, i) {
+		if (points[i - 1] && points[i + 1]) {
+			return points[i].y >= Math.max(points[i - 1].y, points[i + 1].y) || points[i].y <= Math.min(points[i - 1].y,
+				points[
+					i + 1].y);
+		} else {
+			return false;
+		}
+	}
+	var a = 0.2;
+	var b = 0.2;
+	var pAx = null;
+	var pAy = null;
+	var pBx = null;
+	var pBy = null;
+	if (i < 1) {
+		pAx = points[0].x + (points[1].x - points[0].x) * a;
+		pAy = points[0].y + (points[1].y - points[0].y) * a;
+	} else {
+		pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
+		pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
+	}
+
+	if (i > points.length - 3) {
+		var last = points.length - 1;
+		pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
+		pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
+	} else {
+		pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
+		pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
+	}
+	if (isNotMiddlePoint(points, i + 1)) {
+		pBy = points[i + 1].y;
+	}
+	if (isNotMiddlePoint(points, i)) {
+		pAy = points[i].y;
+	}
+	if (pAy >= Math.max(points[i].y, points[i + 1].y) || pAy <= Math.min(points[i].y, points[i + 1].y)) {
+		pAy = points[i].y;
+	}
+	if (pBy >= Math.max(points[i].y, points[i + 1].y) || pBy <= Math.min(points[i].y, points[i + 1].y)) {
+		pBy = points[i + 1].y;
+	}
+	return {
+		ctrA: {
+			x: pAx,
+			y: pAy
+		},
+		ctrB: {
+			x: pBx,
+			y: pBy
+		}
+	};
+}
+
+function convertCoordinateOrigin(x, y, center) {
+	return {
+		x: center.x + x,
+		y: center.y - y
+	};
+}
+
+function avoidCollision(obj, target) {
+	if (target) {
+		// is collision test
+		while (util.isCollision(obj, target)) {
+			if (obj.start.x > 0) {
+				obj.start.y--;
+			} else if (obj.start.x < 0) {
+				obj.start.y++;
+			} else {
+				if (obj.start.y > 0) {
+					obj.start.y++;
+				} else {
+					obj.start.y--;
+				}
+			}
+		}
+	}
+	return obj;
+}
+
+function fillSeries(series, opts, config) {
+	var index = 0;
+	return series.map(function(item) {
+		if (!item.color) {
+			item.color = config.colors[index];
+			index = (index + 1) % config.colors.length;
+		}
+		if (!item.index) {
+			item.index = 0;
+		}
+		if (!item.type) {
+			item.type = opts.type;
+		}
+		if (typeof item.show == "undefined") {
+			item.show = true;
+		}
+		if (!item.type) {
+			item.type = opts.type;
+		}
+		if (!item.pointShape) {
+			item.pointShape = "circle";
+		}
+		if (!item.legendShape) {
+			switch (item.type) {
+				case 'line':
+					item.legendShape = "line";
+					break;
+				case 'column':
+					item.legendShape = "rect";
+					break;
+				case 'area':
+					item.legendShape = "triangle";
+					break;
+				default:
+					item.legendShape = "circle";
+			}
+		}
+		return item;
+	});
+}
+
+function getDataRange(minData, maxData) {
+	var limit = 0;
+	var range = maxData - minData;
+	if (range >= 10000) {
+		limit = 1000;
+	} else if (range >= 1000) {
+		limit = 100;
+	} else if (range >= 100) {
+		limit = 10;
+	} else if (range >= 10) {
+		limit = 5;
+	} else if (range >= 1) {
+		limit = 1;
+	} else if (range >= 0.1) {
+		limit = 0.1;
+	} else if (range >= 0.01) {
+		limit = 0.01;
+	} else if (range >= 0.001) {
+		limit = 0.001;
+	} else if (range >= 0.0001) {
+		limit = 0.0001;
+	} else if (range >= 0.00001) {
+		limit = 0.00001;
+	} else {
+		limit = 0.000001;
+	}
+	return {
+		minRange: findRange(minData, 'lower', limit),
+		maxRange: findRange(maxData, 'upper', limit)
+	};
+}
+
+function measureText(text) {
+	var fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : config.fontSize;
+	text = String(text);
+	var text = text.split('');
+	var width = 0;
+	for (let i = 0; i < text.length; i++) {
+		let item = text[i];
+		if (/[a-zA-Z]/.test(item)) {
+			width += 7;
+		} else if (/[0-9]/.test(item)) {
+			width += 5.5;
+		} else if (/\./.test(item)) {
+			width += 2.7;
+		} else if (/-/.test(item)) {
+			width += 3.25;
+		} else if (/[\u4e00-\u9fa5]/.test(item)) {
+			width += 10;
+		} else if (/\(|\)/.test(item)) {
+			width += 3.73;
+		} else if (/\s/.test(item)) {
+			width += 2.5;
+		} else if (/%/.test(item)) {
+			width += 8;
+		} else {
+			width += 10;
+		}
+	}
+	return width * fontSize / 10;
+}
+
+function dataCombine(series) {
+	return series.reduce(function(a, b) {
+		return (a.data ? a.data : a).concat(b.data);
+	}, []);
+}
+
+function dataCombineStack(series, len) {
+	var sum = new Array(len);
+	for (var j = 0; j < sum.length; j++) {
+		sum[j] = 0;
+	}
+	for (var i = 0; i < series.length; i++) {
+		for (var j = 0; j < sum.length; j++) {
+			sum[j] += series[i].data[j];
+		}
+	}
+	return series.reduce(function(a, b) {
+		return (a.data ? a.data : a).concat(b.data).concat(sum);
+	}, []);
+}
+
+function getTouches(touches, opts, e) {
+	let x, y;
+	if (touches.clientX) {
+		if (opts.rotate) {
+			y = opts.height - touches.clientX * opts.pixelRatio;
+			x = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pixelRatio / 2) * (opts.pixelRatio - 1)) *
+				opts.pixelRatio;
+		} else {
+			x = touches.clientX * opts.pixelRatio;
+			y = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pixelRatio / 2) * (opts.pixelRatio - 1)) *
+				opts.pixelRatio;
+		}
+	} else {
+		if (opts.rotate) {
+			y = opts.height - touches.x * opts.pixelRatio;
+			x = touches.y * opts.pixelRatio;
+		} else {
+			x = touches.x * opts.pixelRatio;
+			y = touches.y * opts.pixelRatio;
+		}
+	}
+	return {
+		x: x,
+		y: y
+	}
+}
+
+function getSeriesDataItem(series, index) {
+	var data = [];
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		if (item.data[index] !== null && typeof item.data[index] !== 'undefined' && item.show) {
+			let seriesItem = {};
+			seriesItem.color = item.color;
+			seriesItem.type = item.type;
+			seriesItem.style = item.style;
+			seriesItem.pointShape = item.pointShape;
+			seriesItem.disableLegend = item.disableLegend;
+			seriesItem.name = item.name;
+			seriesItem.show = item.show;
+			seriesItem.data = item.format ? item.format(item.data[index]) : item.data[index];
+			data.push(seriesItem);
+		}
+	}
+	return data;
+}
+
+function getMaxTextListLength(list) {
+	var lengthList = list.map(function(item) {
+		return measureText(item);
+	});
+	return Math.max.apply(null, lengthList);
+}
+
+function getRadarCoordinateSeries(length) {
+	var eachAngle = 2 * Math.PI / length;
+	var CoordinateSeries = [];
+	for (var i = 0; i < length; i++) {
+		CoordinateSeries.push(eachAngle * i);
+	}
+
+	return CoordinateSeries.map(function(item) {
+		return -1 * item + Math.PI / 2;
+	});
+}
+
+function getToolTipData(seriesData, calPoints, index, categories) {
+	var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+
+	var textList = seriesData.map(function(item) {
+		let titleText = [];
+		if (categories) {
+			titleText = categories;
+		} else {
+			titleText = item.data;
+		}
+		return {
+			text: option.format ? option.format(item, titleText[index]) : item.name + ': ' + item.data,
+			color: item.color
+		};
+	});
+	var validCalPoints = [];
+	var offset = {
+		x: 0,
+		y: 0
+	};
+	for (let i = 0; i < calPoints.length; i++) {
+		let points = calPoints[i];
+		if (typeof points[index] !== 'undefined' && points[index] !== null) {
+			validCalPoints.push(points[index]);
+		}
+	}
+	for (let i = 0; i < validCalPoints.length; i++) {
+		let item = validCalPoints[i];
+		offset.x = Math.round(item.x);
+		offset.y += item.y;
+	}
+	offset.y /= validCalPoints.length;
+	return {
+		textList: textList,
+		offset: offset
+	};
+}
+
+function getMixToolTipData(seriesData, calPoints, index, categories) {
+	var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+	var textList = seriesData.map(function(item) {
+		return {
+			text: option.format ? option.format(item, categories[index]) : item.name + ': ' + item.data,
+			color: item.color,
+			disableLegend: item.disableLegend ? true : false
+		};
+	});
+	textList = textList.filter(function(item) {
+		if (item.disableLegend !== true) {
+			return item;
+		}
+	});
+	var validCalPoints = [];
+	var offset = {
+		x: 0,
+		y: 0
+	};
+	for (let i = 0; i < calPoints.length; i++) {
+		let points = calPoints[i];
+		if (typeof points[index] !== 'undefined' && points[index] !== null) {
+			validCalPoints.push(points[index]);
+		}
+	}
+	for (let i = 0; i < validCalPoints.length; i++) {
+		let item = validCalPoints[i];
+		offset.x = Math.round(item.x);
+		offset.y += item.y;
+	}
+	offset.y /= validCalPoints.length;
+	return {
+		textList: textList,
+		offset: offset
+	};
+}
+
+function getCandleToolTipData(series, seriesData, calPoints, index, categories, extra) {
+	var option = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
+	let upColor = extra.color.upFill;
+	let downColor = extra.color.downFill;
+	//颜色顺序为开盘,收盘,最低,最高
+	let color = [upColor, upColor, downColor, upColor];
+	var textList = [];
+	let text0 = {
+		text: categories[index],
+		color: null
+	};
+	textList.push(text0);
+	seriesData.map(function(item) {
+		if (index == 0 && item.data[1] - item.data[0] < 0) {
+			color[1] = downColor;
+		} else {
+			if (item.data[0] < series[index - 1][1]) {
+				color[0] = downColor;
+			}
+			if (item.data[1] < item.data[0]) {
+				color[1] = downColor;
+			}
+			if (item.data[2] > series[index - 1][1]) {
+				color[2] = upColor;
+			}
+			if (item.data[3] < series[index - 1][1]) {
+				color[3] = downColor;
+			}
+		}
+		let text1 = {
+			text: '开盘:' + item.data[0],
+			color: color[0]
+		};
+		let text2 = {
+			text: '收盘:' + item.data[1],
+			color: color[1]
+		};
+		let text3 = {
+			text: '最低:' + item.data[2],
+			color: color[2]
+		};
+		let text4 = {
+			text: '最高:' + item.data[3],
+			color: color[3]
+		};
+		textList.push(text1, text2, text3, text4);
+	});
+	var validCalPoints = [];
+	var offset = {
+		x: 0,
+		y: 0
+	};
+	for (let i = 0; i < calPoints.length; i++) {
+		let points = calPoints[i];
+		if (typeof points[index] !== 'undefined' && points[index] !== null) {
+			validCalPoints.push(points[index]);
+		}
+	}
+	offset.x = Math.round(validCalPoints[0][0].x);
+	return {
+		textList: textList,
+		offset: offset
+	};
+}
+
+function filterSeries(series) {
+	let tempSeries = [];
+	for (let i = 0; i < series.length; i++) {
+		if (series[i].show == true) {
+			tempSeries.push(series[i])
+		}
+	}
+	return tempSeries;
+}
+
+function findCurrentIndex(currentPoints, calPoints, opts, config) {
+	var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
+	var currentIndex = -1;
+	var spacing = 0;
+	let xAxisPoints = [];
+	for (let i = 0; i < calPoints[0].length; i++) {
+		xAxisPoints.push(calPoints[0][i].x)
+	}
+	// slam todo
+	if ((opts.type == 'line' || opts.type == 'area') && opts.xAxis.boundaryGap == 'justify') {
+		spacing = opts.chartData.eachSpacing / 2;
+	}
+	if (!opts.categories) {
+		spacing = 0
+	}
+	if (isInExactChartArea(currentPoints, opts, config)) {
+		xAxisPoints.forEach(function(item, index) {
+			if (currentPoints.x + offset + spacing > item) {
+				currentIndex = index;
+			}
+		});
+	}
+	return currentIndex;
+}
+
+function findLegendIndex(currentPoints, legendData, opts) {
+	let currentIndex = -1;
+	if (isInExactLegendArea(currentPoints, legendData.area)) {
+		let points = legendData.points;
+		let index = -1;
+		for (let i = 0, len = points.length; i < len; i++) {
+			let item = points[i];
+			for (let j = 0; j < item.length; j++) {
+				index += 1;
+				let area = item[j]['area'];
+				if (currentPoints.x > area[0] && currentPoints.x < area[2] && currentPoints.y > area[1] && currentPoints.y < area[3]) {
+					currentIndex = index;
+					break;
+				}
+			}
+		}
+		return currentIndex;
+	}
+	return currentIndex;
+}
+
+function isInExactLegendArea(currentPoints, area) {
+	return currentPoints.x > area.start.x && currentPoints.x < area.end.x && currentPoints.y > area.start.y &&
+		currentPoints.y < area.end.y;
+}
+
+function isInExactChartArea(currentPoints, opts, config) {
+	return currentPoints.x <= opts.width - opts.area[1] + 10 && currentPoints.x >= opts.area[3] - 10 && currentPoints.y >=
+		opts.area[0] && currentPoints.y <= opts.height - opts.area[2];
+}
+
+function findRadarChartCurrentIndex(currentPoints, radarData, count) {
+	var eachAngleArea = 2 * Math.PI / count;
+	var currentIndex = -1;
+	if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) {
+		var fixAngle = function fixAngle(angle) {
+			if (angle < 0) {
+				angle += 2 * Math.PI;
+			}
+			if (angle > 2 * Math.PI) {
+				angle -= 2 * Math.PI;
+			}
+			return angle;
+		};
+
+		var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x);
+		angle = -1 * angle;
+		if (angle < 0) {
+			angle += 2 * Math.PI;
+		}
+
+		var angleList = radarData.angleList.map(function(item) {
+			item = fixAngle(-1 * item);
+
+			return item;
+		});
+
+		angleList.forEach(function(item, index) {
+			var rangeStart = fixAngle(item - eachAngleArea / 2);
+			var rangeEnd = fixAngle(item + eachAngleArea / 2);
+			if (rangeEnd < rangeStart) {
+				rangeEnd += 2 * Math.PI;
+			}
+			if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <=
+				rangeEnd) {
+				currentIndex = index;
+			}
+		});
+	}
+
+	return currentIndex;
+}
+
+function findFunnelChartCurrentIndex(currentPoints, funnelData) {
+	var currentIndex = -1;
+	for (var i = 0, len = funnelData.series.length; i < len; i++) {
+		var item = funnelData.series[i];
+		if (currentPoints.x > item.funnelArea[0] && currentPoints.x < item.funnelArea[2] && currentPoints.y > item.funnelArea[
+				1] && currentPoints.y < item.funnelArea[3]) {
+			currentIndex = i;
+			break;
+		}
+	}
+	return currentIndex;
+}
+
+function findWordChartCurrentIndex(currentPoints, wordData) {
+	var currentIndex = -1;
+	for (var i = 0, len = wordData.length; i < len; i++) {
+		var item = wordData[i];
+		if (currentPoints.x > item.area[0] && currentPoints.x < item.area[2] && currentPoints.y > item.area[1] &&
+			currentPoints.y < item.area[3]) {
+			currentIndex = i;
+			break;
+		}
+	}
+	return currentIndex;
+}
+
+function findMapChartCurrentIndex(currentPoints, opts) {
+	var currentIndex = -1;
+	var cData = opts.chartData.mapData;
+	var data = opts.series;
+	var tmp = pointToCoordinate(currentPoints.y, currentPoints.x, cData.bounds, cData.scale, cData.xoffset, cData.yoffset);
+	var poi = [tmp.x, tmp.y];
+	for (var i = 0, len = data.length; i < len; i++) {
+		var item = data[i].geometry.coordinates;
+		if (isPoiWithinPoly(poi, item)) {
+			currentIndex = i;
+			break;
+		}
+	}
+	return currentIndex;
+}
+
+function findPieChartCurrentIndex(currentPoints, pieData) {
+	var currentIndex = -1;
+	if (isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
+		var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
+		angle = -angle;
+		for (var i = 0, len = pieData.series.length; i < len; i++) {
+			var item = pieData.series[i];
+			if (isInAngleRange(angle, item._start_, item._start_ + item._proportion_ * 2 * Math.PI)) {
+				currentIndex = i;
+				break;
+			}
+		}
+	}
+
+	return currentIndex;
+}
+
+function isInExactPieChartArea(currentPoints, center, radius) {
+	return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2);
+}
+
+function splitPoints(points) {
+	var newPoints = [];
+	var items = [];
+	points.forEach(function(item, index) {
+		if (item !== null) {
+			items.push(item);
+		} else {
+			if (items.length) {
+				newPoints.push(items);
+			}
+			items = [];
+		}
+	});
+	if (items.length) {
+		newPoints.push(items);
+	}
+
+	return newPoints;
+}
+
+function calLegendData(series, opts, config, chartData) {
+	let legendData = {
+		area: {
+			start: {
+				x: 0,
+				y: 0
+			},
+			end: {
+				x: 0,
+				y: 0
+			},
+			width: 0,
+			height: 0,
+			wholeWidth: 0,
+			wholeHeight: 0
+		},
+		points: [],
+		widthArr: [],
+		heightArr: []
+	};
+	if (opts.legend.show === false) {
+		chartData.legendData = legendData;
+		return legendData;
+	}
+
+	let padding = opts.legend.padding;
+	let margin = opts.legend.margin;
+	let fontSize = opts.legend.fontSize;
+	let shapeWidth = 15 * opts.pixelRatio;
+	let shapeRight = 5 * opts.pixelRatio;
+	let lineHeight = Math.max(opts.legend.lineHeight * opts.pixelRatio, fontSize);
+	if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+		let legendList = [];
+		let widthCount = 0;
+		let widthCountArr = [];
+		let currentRow = [];
+		for (let i = 0; i < series.length; i++) {
+			let item = series[i];
+			let itemWidth = shapeWidth + shapeRight + measureText(item.name || 'undefined', fontSize) + opts.legend.itemGap;
+			if (widthCount + itemWidth > opts.width - opts.padding[1] - opts.padding[3]) {
+				legendList.push(currentRow);
+				widthCountArr.push(widthCount - opts.legend.itemGap);
+				widthCount = itemWidth;
+				currentRow = [item];
+			} else {
+				widthCount += itemWidth;
+				currentRow.push(item);
+			}
+		}
+		if (currentRow.length) {
+			legendList.push(currentRow);
+			widthCountArr.push(widthCount - opts.legend.itemGap);
+			legendData.widthArr = widthCountArr;
+			let legendWidth = Math.max.apply(null, widthCountArr);
+			switch (opts.legend.float) {
+				case 'left':
+					legendData.area.start.x = opts.padding[3];
+					legendData.area.end.x = opts.padding[3] + 2 * padding;
+					break;
+				case 'right':
+					legendData.area.start.x = opts.width - opts.padding[1] - legendWidth - 2 * padding;
+					legendData.area.end.x = opts.width - opts.padding[1];
+					break;
+				default:
+					legendData.area.start.x = (opts.width - legendWidth) / 2 - padding;
+					legendData.area.end.x = (opts.width + legendWidth) / 2 + padding;
+			}
+			legendData.area.width = legendWidth + 2 * padding;
+			legendData.area.wholeWidth = legendWidth + 2 * padding;
+			legendData.area.height = legendList.length * lineHeight + 2 * padding;
+			legendData.area.wholeHeight = legendList.length * lineHeight + 2 * padding + 2 * margin;
+			legendData.points = legendList;
+		}
+	} else {
+		let len = series.length;
+		let maxHeight = opts.height - opts.padding[0] - opts.padding[2] - 2 * margin - 2 * padding;
+		let maxLength = Math.min(Math.floor(maxHeight / lineHeight), len);
+		legendData.area.height = maxLength * lineHeight + padding * 2;
+		legendData.area.wholeHeight = maxLength * lineHeight + padding * 2;
+		switch (opts.legend.float) {
+			case 'top':
+				legendData.area.start.y = opts.padding[0] + margin;
+				legendData.area.end.y = opts.padding[0] + margin + legendData.area.height;
+				break;
+			case 'bottom':
+				legendData.area.start.y = opts.height - opts.padding[2] - margin - legendData.area.height;
+				legendData.area.end.y = opts.height - opts.padding[2] - margin;
+				break;
+			default:
+				legendData.area.start.y = (opts.height - legendData.area.height) / 2;
+				legendData.area.end.y = (opts.height + legendData.area.height) / 2;
+		}
+		let lineNum = len % maxLength === 0 ? len / maxLength : Math.floor((len / maxLength) + 1);
+		let currentRow = [];
+		for (let i = 0; i < lineNum; i++) {
+			let temp = series.slice(i * maxLength, i * maxLength + maxLength);
+			currentRow.push(temp);
+		}
+
+		legendData.points = currentRow;
+
+		if (currentRow.length) {
+			for (let i = 0; i < currentRow.length; i++) {
+				let item = currentRow[i];
+				let maxWidth = 0;
+				for (let j = 0; j < item.length; j++) {
+					let itemWidth = shapeWidth + shapeRight + measureText(item[j].name || 'undefined', fontSize) + opts.legend.itemGap;
+					if (itemWidth > maxWidth) {
+						maxWidth = itemWidth;
+					}
+				}
+				legendData.widthArr.push(maxWidth);
+				legendData.heightArr.push(item.length * lineHeight + padding * 2);
+			}
+			let legendWidth = 0
+			for (let i = 0; i < legendData.widthArr.length; i++) {
+				legendWidth += legendData.widthArr[i];
+			}
+			legendData.area.width = legendWidth - opts.legend.itemGap + 2 * padding;
+			legendData.area.wholeWidth = legendData.area.width + padding;
+		}
+	}
+
+	switch (opts.legend.position) {
+		case 'top':
+			legendData.area.start.y = opts.padding[0] + margin;
+			legendData.area.end.y = opts.padding[0] + margin + legendData.area.height;
+			break;
+		case 'bottom':
+			legendData.area.start.y = opts.height - opts.padding[2] - legendData.area.height - margin;
+			legendData.area.end.y = opts.height - opts.padding[2] - margin;
+			break;
+		case 'left':
+			legendData.area.start.x = opts.padding[3];
+			legendData.area.end.x = opts.padding[3] + legendData.area.width;
+			break;
+		case 'right':
+			legendData.area.start.x = opts.width - opts.padding[1] - legendData.area.width;
+			legendData.area.end.x = opts.width - opts.padding[1];
+			break;
+	}
+	chartData.legendData = legendData;
+	return legendData;
+}
+
+function calCategoriesData(categories, opts, config, eachSpacing) {
+	var result = {
+		angle: 0,
+		xAxisHeight: config.xAxisHeight
+	};
+	var categoriesTextLenth = categories.map(function(item) {
+		return measureText(item, opts.xAxis.fontSize || config.fontSize);
+	});
+	var maxTextLength = Math.max.apply(this, categoriesTextLenth);
+
+	if (opts.xAxis.rotateLabel == true && maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) {
+		result.angle = 45 * Math.PI / 180;
+		result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle);
+	}
+	return result;
+}
+
+function getXAxisTextList(series, opts, config) {
+	var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;
+	var data = dataCombine(series);
+	var sorted = [];
+	// remove null from data
+	data = data.filter(function(item) {
+		//return item !== null;
+		if (typeof item === 'object' && item !== null) {
+			if (item.constructor == Array) {
+				return item !== null;
+			} else {
+				return item.value !== null;
+			}
+		} else {
+			return item !== null;
+		}
+	});
+	data.map(function(item) {
+		if (typeof item === 'object') {
+			if (item.constructor == Array) {
+				if (opts.type == 'candle') {
+					item.map(function(subitem) {
+						sorted.push(subitem);
+					})
+				} else {
+					sorted.push(item[0]);
+				}
+			} else {
+				sorted.push(item.value);
+			}
+		} else {
+			sorted.push(item);
+		}
+	})
+
+	var minData = 0;
+	var maxData = 0;
+	if (sorted.length > 0) {
+		minData = Math.min.apply(this, sorted);
+		maxData = Math.max.apply(this, sorted);
+	}
+	//为了兼容v1.9.0之前的项目
+	if (index > -1) {
+		if (typeof opts.xAxis.data[index].min === 'number') {
+			minData = Math.min(opts.xAxis.data[index].min, minData);
+		}
+		if (typeof opts.xAxis.data[index].max === 'number') {
+			maxData = Math.max(opts.xAxis.data[index].max, maxData);
+		}
+	} else {
+		if (typeof opts.xAxis.min === 'number') {
+			minData = Math.min(opts.xAxis.min, minData);
+		}
+		if (typeof opts.xAxis.max === 'number') {
+			maxData = Math.max(opts.xAxis.max, maxData);
+		}
+	}
+
+
+	if (minData === maxData) {
+		var rangeSpan = maxData || 10;
+		maxData += rangeSpan;
+	}
+
+	var dataRange = getDataRange(minData, maxData);
+	var minRange = dataRange.minRange;
+	var maxRange = dataRange.maxRange;
+
+	var range = [];
+	var eachRange = (maxRange - minRange) / opts.xAxis.splitNumber;
+
+	for (var i = 0; i <= opts.xAxis.splitNumber; i++) {
+		range.push(minRange + eachRange * i);
+	}
+	return range;
+}
+
+function calXAxisData(series, opts, config) {
+	var result = {
+		angle: 0,
+		xAxisHeight: config.xAxisHeight
+	};
+
+	result.ranges = getXAxisTextList(series, opts, config);
+	result.rangesFormat = result.ranges.map(function(item) {
+		item = opts.xAxis.format ? opts.xAxis.format(item) : util.toFixed(item, 2);
+		return item;
+	});
+	var xAxisScaleValues = result.ranges.map(function(item) {
+		// 如果刻度值是浮点数,则保留两位小数
+		item = util.toFixed(item, 2);
+		// 若有自定义格式则调用自定义的格式化函数
+		item = opts.xAxis.format ? opts.xAxis.format(Number(item)) : item;
+		return item;
+	});
+
+	result = Object.assign(result, getXAxisPoints(xAxisScaleValues, opts, config));
+	// 计算X轴刻度的属性譬如每个刻度的间隔,刻度的起始点\结束点以及总长
+	var eachSpacing = result.eachSpacing;
+
+	var textLength = xAxisScaleValues.map(function(item) {
+		return measureText(item);
+	});
+
+	// get max length of categories text
+	var maxTextLength = Math.max.apply(this, textLength);
+
+	// 如果刻度值文本内容过长,则将其逆时针旋转45°
+	if (maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) {
+		result.angle = 45 * Math.PI / 180;
+		result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle);
+	}
+
+	if (opts.xAxis.disabled === true) {
+		result.xAxisHeight = 0;
+	}
+
+	return result;
+}
+
+function getRadarDataPoints(angleList, center, radius, series, opts) {
+	var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+
+	var radarOption = opts.extra.radar || {};
+	radarOption.max = radarOption.max || 0;
+	var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));
+
+	var data = [];
+	for (let i = 0; i < series.length; i++) {
+		let each = series[i];
+		let listItem = {};
+		listItem.color = each.color;
+		listItem.legendShape = each.legendShape;
+		listItem.pointShape = each.pointShape;
+		listItem.data = [];
+		each.data.forEach(function(item, index) {
+			let tmp = {};
+			tmp.angle = angleList[index];
+
+			tmp.proportion = item / maxData;
+			tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion *
+				process * Math.sin(tmp.angle), center);
+			listItem.data.push(tmp);
+		});
+
+		data.push(listItem);
+	}
+
+	return data;
+}
+
+function getPieDataPoints(series, radius) {
+	var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+
+	var count = 0;
+	var _start_ = 0;
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item.data = item.data === null ? 0 : item.data;
+		count += item.data;
+	}
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item.data = item.data === null ? 0 : item.data;
+		if (count === 0) {
+			item._proportion_ = 1 / series.length * process;
+		} else {
+			item._proportion_ = item.data / count * process;
+		}
+		item._radius_ = radius;
+	}
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item._start_ = _start_;
+		_start_ += 2 * item._proportion_ * Math.PI;
+	}
+
+	return series;
+}
+
+function getFunnelDataPoints(series, radius) {
+	var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+	series = series.sort(function(a, b) {
+		return parseInt(b.data) - parseInt(a.data);
+	});
+	for (let i = 0; i < series.length; i++) {
+		series[i].radius = series[i].data / series[0].data * radius * process;
+		series[i]._proportion_ = series[i].data / series[0].data;
+	}
+	return series.reverse();
+}
+
+function getRoseDataPoints(series, type, minRadius, radius) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var count = 0;
+	var _start_ = 0;
+
+	var dataArr = [];
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item.data = item.data === null ? 0 : item.data;
+		count += item.data;
+		dataArr.push(item.data);
+	}
+
+	var minData = Math.min.apply(null, dataArr);
+	var maxData = Math.max.apply(null, dataArr);
+	var radiusLength = radius - minRadius;
+
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item.data = item.data === null ? 0 : item.data;
+		if (count === 0 || type == 'area') {
+			item._proportion_ = item.data / count * process;
+			item._rose_proportion_ = 1 / series.length * process;
+		} else {
+			item._proportion_ = item.data / count * process;
+			item._rose_proportion_ = item.data / count * process;
+		}
+		item._radius_ = minRadius + radiusLength * ((item.data - minData) / (maxData - minData));
+	}
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item._start_ = _start_;
+		_start_ += 2 * item._rose_proportion_ * Math.PI;
+	}
+
+	return series;
+}
+
+function getArcbarDataPoints(series, arcbarOption) {
+	var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+	if (process == 1) {
+		process = 0.999999;
+	}
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item.data = item.data === null ? 0 : item.data;
+		let totalAngle;
+		if (arcbarOption.type == 'circle') {
+			totalAngle = 2;
+		} else {
+			if (arcbarOption.endAngle < arcbarOption.startAngle) {
+				totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle;
+			} else {
+				totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+			}
+		}
+		item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
+		if (item._proportion_ >= 2) {
+			item._proportion_ = item._proportion_ % 2;
+		}
+	}
+	return series;
+}
+
+function getGaugeAxisPoints(categories, startAngle, endAngle) {
+	let totalAngle = startAngle - endAngle + 1;
+	let tempStartAngle = startAngle;
+	for (let i = 0; i < categories.length; i++) {
+		categories[i].value = categories[i].value === null ? 0 : categories[i].value;
+		categories[i]._startAngle_ = tempStartAngle;
+		categories[i]._endAngle_ = totalAngle * categories[i].value + startAngle;
+		if (categories[i]._endAngle_ >= 2) {
+			categories[i]._endAngle_ = categories[i]._endAngle_ % 2;
+		}
+		tempStartAngle = categories[i]._endAngle_;
+	}
+	return categories;
+}
+
+function getGaugeDataPoints(series, categories, gaugeOption) {
+	let process = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		item.data = item.data === null ? 0 : item.data;
+		if (gaugeOption.pointer.color == 'auto') {
+			for (let i = 0; i < categories.length; i++) {
+				if (item.data <= categories[i].value) {
+					item.color = categories[i].color;
+					break;
+				}
+			}
+		} else {
+			item.color = gaugeOption.pointer.color;
+		}
+		let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
+		item._endAngle_ = totalAngle * item.data + gaugeOption.startAngle;
+		item._oldAngle_ = gaugeOption.oldAngle;
+		if (gaugeOption.oldAngle < gaugeOption.endAngle) {
+			item._oldAngle_ += 2;
+		}
+		if (item.data >= gaugeOption.oldData) {
+			item._proportion_ = (item._endAngle_ - item._oldAngle_) * process + gaugeOption.oldAngle;
+		} else {
+			item._proportion_ = item._oldAngle_ - (item._oldAngle_ - item._endAngle_) * process;
+		}
+		if (item._proportion_ >= 2) {
+			item._proportion_ = item._proportion_ % 2;
+		}
+	}
+	return series;
+}
+
+function getPieTextMaxLength(series) {
+	series = getPieDataPoints(series);
+	let maxLength = 0;
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		let text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
+		maxLength = Math.max(maxLength, measureText(text));
+	}
+
+	return maxLength;
+}
+
+function fixColumeData(points, eachSpacing, columnLen, index, config, opts) {
+	return points.map(function(item) {
+		if (item === null) {
+			return null;
+		}
+		item.width = Math.ceil((eachSpacing - 2 * config.columePadding) / columnLen);
+
+		if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+			item.width = Math.min(item.width, +opts.extra.column.width);
+		}
+		if (item.width <= 0) {
+			item.width = 1;
+		}
+		item.x += (index + 0.5 - columnLen / 2) * item.width;
+		return item;
+	});
+}
+
+function fixColumeMeterData(points, eachSpacing, columnLen, index, config, opts, border) {
+	return points.map(function(item) {
+		if (item === null) {
+			return null;
+		}
+		item.width = Math.ceil((eachSpacing - 2 * config.columePadding) / 2);
+
+		if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+			item.width = Math.min(item.width, +opts.extra.column.width);
+		}
+
+		if (index > 0) {
+			item.width -= 2 * border;
+		}
+		return item;
+	});
+}
+
+function fixColumeStackData(points, eachSpacing, columnLen, index, config, opts, series) {
+
+	return points.map(function(item, indexn) {
+
+		if (item === null) {
+			return null;
+		}
+		item.width = Math.ceil((eachSpacing - 2 * config.columePadding) / 2);
+
+		if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+			item.width = Math.min(item.width, +opts.extra.column.width);
+		}
+		return item;
+	});
+}
+
+function getXAxisPoints(categories, opts, config) {
+	var spacingValid = opts.width - opts.area[1] - opts.area[3];
+	var dataCount = opts.enableScroll ? Math.min(opts.xAxis.itemCount, categories.length) : categories.length;
+	if ((opts.type == 'line' || opts.type == 'area') && dataCount > 1 && opts.xAxis.boundaryGap == 'justify') {
+		dataCount -= 1;
+	}
+	var eachSpacing = spacingValid / dataCount;
+
+	var xAxisPoints = [];
+	var startX = opts.area[3];
+	var endX = opts.width - opts.area[1];
+	categories.forEach(function(item, index) {
+		xAxisPoints.push(startX + index * eachSpacing);
+	});
+	if (opts.xAxis.boundaryGap !== 'justify') {
+		if (opts.enableScroll === true) {
+			xAxisPoints.push(startX + categories.length * eachSpacing);
+		} else {
+			xAxisPoints.push(endX);
+		}
+	}
+	return {
+		xAxisPoints: xAxisPoints,
+		startX: startX,
+		endX: endX,
+		eachSpacing: eachSpacing
+	};
+}
+
+function getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
+	var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+	var points = [];
+	var validHeight = opts.height - opts.area[0] - opts.area[2];
+	data.forEach(function(item, index) {
+		if (item === null) {
+			points.push(null);
+		} else {
+			var cPoints = [];
+			item.forEach(function(items, indexs) {
+				var point = {};
+				point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
+				var value = items.value || items;
+				var height = validHeight * (value - minRange) / (maxRange - minRange);
+				height *= process;
+				point.y = opts.height - Math.round(height) - opts.area[2];
+				cPoints.push(point);
+			});
+			points.push(cPoints);
+		}
+	});
+
+	return points;
+}
+
+function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
+	var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+	var boundaryGap = 'center';
+	if (opts.type == 'line' || opts.type == 'area') {
+		boundaryGap = opts.xAxis.boundaryGap;
+	}
+	var points = [];
+	var validHeight = opts.height - opts.area[0] - opts.area[2];
+	var validWidth = opts.width - opts.area[1] - opts.area[3];
+	data.forEach(function(item, index) {
+		if (item === null) {
+			points.push(null);
+		} else {
+			var point = {};
+			point.color = item.color;
+			point.x = xAxisPoints[index];
+			var value = item;
+			if (typeof item === 'object' && item !== null) {
+				if (item.constructor == Array) {
+					let xranges, xminRange, xmaxRange;
+					xranges = [].concat(opts.chartData.xAxisData.ranges);
+
+					xminRange = xranges.shift();
+					xmaxRange = xranges.pop();
+					value = item[1];
+					point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+				} else {
+					value = item.value;
+				}
+			}
+			if (boundaryGap == 'center') {
+				point.x += Math.round(eachSpacing / 2);
+			}
+			var height = validHeight * (value - minRange) / (maxRange - minRange);
+			height *= process;
+			point.y = opts.height - Math.round(height) - opts.area[2];
+			points.push(point);
+		}
+	});
+
+	return points;
+}
+
+function getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) {
+	var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1;
+	var points = [];
+	var validHeight = opts.height - opts.area[0] - opts.area[2];
+
+	data.forEach(function(item, index) {
+		if (item === null) {
+			points.push(null);
+		} else {
+			var point = {};
+			point.color = item.color;
+			point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
+
+			if (seriesIndex > 0) {
+				var value = 0;
+				for (let i = 0; i <= seriesIndex; i++) {
+					value += stackSeries[i].data[index];
+				}
+				var value0 = value - item;
+				var height = validHeight * (value - minRange) / (maxRange - minRange);
+				var height0 = validHeight * (value0 - minRange) / (maxRange - minRange);
+			} else {
+				var value = item;
+				var height = validHeight * (value - minRange) / (maxRange - minRange);
+				var height0 = 0;
+			}
+			var heightc = height0;
+			height *= process;
+			heightc *= process;
+			point.y = opts.height - Math.round(height) - opts.area[2];
+			point.y0 = opts.height - Math.round(heightc) - opts.area[2];
+			points.push(point);
+		}
+	});
+
+	return points;
+}
+
+function getYAxisTextList(series, opts, config, stack) {
+	var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;
+	var data;
+	if (stack == 'stack') {
+		data = dataCombineStack(series, opts.categories.length);
+	} else {
+		data = dataCombine(series);
+	}
+	var sorted = [];
+	// remove null from data
+	data = data.filter(function(item) {
+		//return item !== null;
+		if (typeof item === 'object' && item !== null) {
+			if (item.constructor == Array) {
+				return item !== null;
+			} else {
+				return item.value !== null;
+			}
+		} else {
+			return item !== null;
+		}
+	});
+	data.map(function(item) {
+		if (typeof item === 'object') {
+			if (item.constructor == Array) {
+				if (opts.type == 'candle') {
+					item.map(function(subitem) {
+						sorted.push(subitem);
+					})
+				} else {
+					sorted.push(item[1]);
+				}
+			} else {
+				sorted.push(item.value);
+			}
+		} else {
+			sorted.push(item);
+		}
+	})
+
+	var minData = 0;
+	var maxData = 0;
+	if (sorted.length > 0) {
+		minData = Math.min.apply(this, sorted);
+		maxData = Math.max.apply(this, sorted);
+	}
+	//为了兼容v1.9.0之前的项目
+	if (index > -1) {
+		if (typeof opts.yAxis.data[index].min === 'number') {
+			minData = Math.min(opts.yAxis.data[index].min, minData);
+		}
+		if (typeof opts.yAxis.data[index].max === 'number') {
+			maxData = Math.max(opts.yAxis.data[index].max, maxData);
+		}
+	} else {
+		if (typeof opts.yAxis.min === 'number') {
+			minData = Math.min(opts.yAxis.min, minData);
+		}
+		if (typeof opts.yAxis.max === 'number') {
+			maxData = Math.max(opts.yAxis.max, maxData);
+		}
+	}
+
+
+	if (minData === maxData) {
+		var rangeSpan = maxData || 10;
+		maxData += rangeSpan;
+	}
+
+	var dataRange = getDataRange(minData, maxData);
+	var minRange = dataRange.minRange;
+	var maxRange = dataRange.maxRange;
+
+	var range = [];
+	var eachRange = (maxRange - minRange) / opts.yAxis.splitNumber;
+
+	for (var i = 0; i <= opts.yAxis.splitNumber; i++) {
+		range.push(minRange + eachRange * i);
+	}
+	return range.reverse();
+}
+
+function calYAxisData(series, opts, config) {
+	//堆叠图重算Y轴
+	var columnstyle = assign({}, {
+		type: ""
+	}, opts.extra.column);
+	//如果是多Y轴,重新计算
+	var YLength = opts.yAxis.data.length;
+	var newSeries = new Array(YLength);
+	if (YLength > 0) {
+		for (let i = 0; i < YLength; i++) {
+			newSeries[i] = [];
+			for (let j = 0; j < series.length; j++) {
+				if (series[j].index == i) {
+					newSeries[i].push(series[j]);
+				}
+			}
+		}
+		var rangesArr = new Array(YLength);
+		var rangesFormatArr = new Array(YLength);
+		var yAxisWidthArr = new Array(YLength);
+
+		for (let i = 0; i < YLength; i++) {
+			let yData = opts.yAxis.data[i];
+			//如果总开关不显示,强制每个Y轴为不显示
+			if (opts.yAxis.disabled == true) {
+				yData.disabled = true;
+			}
+			rangesArr[i] = getYAxisTextList(newSeries[i], opts, config, columnstyle.type, i);
+			let yAxisFontSizes = yData.fontSize || config.fontSize;
+			yAxisWidthArr[i] = {
+				position: yData.position ? yData.position : 'left',
+				width: 0
+			};
+			rangesFormatArr[i] = rangesArr[i].map(function(items) {
+				items = util.toFixed(items, 6);
+				items = yData.format ? yData.format(Number(items)) : items;
+				yAxisWidthArr[i].width = Math.max(yAxisWidthArr[i].width, measureText(items, yAxisFontSizes) + 5);
+				return items;
+			});
+			let calibration = yData.calibration ? 4 * opts.pixelRatio : 0;
+			yAxisWidthArr[i].width += calibration + 3 * opts.pixelRatio;
+			if (yData.disabled === true) {
+				yAxisWidthArr[i].width = 0;
+			}
+		}
+
+	} else {
+		var rangesArr = new Array(1);
+		var rangesFormatArr = new Array(1);
+		var yAxisWidthArr = new Array(1);
+		rangesArr[0] = getYAxisTextList(series, opts, config, columnstyle.type);
+		yAxisWidthArr[0] = {
+			position: 'left',
+			width: 0
+		};
+		var yAxisFontSize = opts.yAxis.fontSize || config.fontSize;
+		rangesFormatArr[0] = rangesArr[0].map(function(item) {
+			item = util.toFixed(item, 6);
+			item = opts.yAxis.format ? opts.yAxis.format(Number(item)) : item;
+			yAxisWidthArr[0].width = Math.max(yAxisWidthArr[0].width, measureText(item, yAxisFontSize) + 5);
+			return item;
+		});
+		yAxisWidthArr[0].width += 3 * opts.pixelRatio;
+		if (opts.yAxis.disabled === true) {
+			yAxisWidthArr[0] = {
+				position: 'left',
+				width: 0
+			};
+			opts.yAxis.data[0] = {
+				disabled: true
+			};
+		} else {
+			opts.yAxis.data[0] = {
+				disabled: false,
+				position: 'left',
+				max: opts.yAxis.max,
+				min: opts.yAxis.min,
+				format: opts.yAxis.format
+			};
+		}
+
+	}
+
+	return {
+		rangesFormat: rangesFormatArr,
+		ranges: rangesArr,
+		yAxisWidth: yAxisWidthArr
+	};
+
+}
+
+function calTooltipYAxisData(point, series, opts, config, eachSpacing) {
+	let ranges = [].concat(opts.chartData.yAxisData.ranges);
+	let spacingValid = opts.height - opts.area[0] - opts.area[2];
+	let minAxis = opts.area[0];
+	let items = [];
+	for (let i = 0; i < ranges.length; i++) {
+		let maxVal = ranges[i].shift();
+		let minVal = ranges[i].pop();
+		let item = maxVal - (maxVal - minVal) * (point - minAxis) / spacingValid;
+		item = opts.yAxis.data[i].format ? opts.yAxis.data[i].format(Number(item)) : item.toFixed(0);
+		items.push(String(item))
+	}
+	return items;
+}
+
+function calMarkLineData(points, opts) {
+	let minRange, maxRange;
+	let spacingValid = opts.height - opts.area[0] - opts.area[2];
+	for (let i = 0; i < points.length; i++) {
+		points[i].yAxisIndex = points[i].yAxisIndex ? points[i].yAxisIndex : 0;
+		let range = [].concat(opts.chartData.yAxisData.ranges[points[i].yAxisIndex]);
+		minRange = range.pop();
+		maxRange = range.shift();
+		let height = spacingValid * (points[i].value - minRange) / (maxRange - minRange);
+		points[i].y = opts.height - Math.round(height) - opts.area[2];
+	}
+	return points;
+}
+
+function contextRotate(context, opts) {
+	if (opts.rotateLock !== true) {
+		context.translate(opts.height, 0);
+		context.rotate(90 * Math.PI / 180);
+	} else if (opts._rotate_ !== true) {
+		context.translate(opts.height, 0);
+		context.rotate(90 * Math.PI / 180);
+		opts._rotate_ = true;
+	}
+}
+
+function drawPointShape(points, color, shape, context, opts) {
+	context.beginPath();
+	if (opts.dataPointShapeType == 'hollow') {
+		context.setStrokeStyle(color);
+		context.setFillStyle(opts.background);
+		context.setLineWidth(2 * opts.pixelRatio);
+	} else {
+		context.setStrokeStyle("#ffffff");
+		context.setFillStyle(color);
+		context.setLineWidth(1 * opts.pixelRatio);
+	}
+	if (shape === 'diamond') {
+		points.forEach(function(item, index) {
+			if (item !== null) {
+				context.moveTo(item.x, item.y - 4.5);
+				context.lineTo(item.x - 4.5, item.y);
+				context.lineTo(item.x, item.y + 4.5);
+				context.lineTo(item.x + 4.5, item.y);
+				context.lineTo(item.x, item.y - 4.5);
+			}
+		});
+	} else if (shape === 'circle') {
+		points.forEach(function(item, index) {
+			if (item !== null) {
+				context.moveTo(item.x + 2.5 * opts.pixelRatio, item.y);
+				context.arc(item.x, item.y, 3 * opts.pixelRatio, 0, 2 * Math.PI, false);
+			}
+		});
+	} else if (shape === 'rect') {
+		points.forEach(function(item, index) {
+			if (item !== null) {
+				context.moveTo(item.x - 3.5, item.y - 3.5);
+				context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+			}
+		});
+	} else if (shape === 'triangle') {
+		points.forEach(function(item, index) {
+			if (item !== null) {
+				context.moveTo(item.x, item.y - 4.5);
+				context.lineTo(item.x - 4.5, item.y + 4.5);
+				context.lineTo(item.x + 4.5, item.y + 4.5);
+				context.lineTo(item.x, item.y - 4.5);
+			}
+		});
+	}
+	context.closePath();
+	context.fill();
+	context.stroke();
+}
+
+function drawMyRingTitle(opts, config, context, center) {
+	var titlefontSize = opts.title.fontSize || config.titleFontSize;
+	var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize;
+	var unitFontSize = opts.title.unitFontSize || config.unitFontSize;
+	var title = opts.title.name || '0';
+	var subtitle = opts.subtitle.name || '';
+	var titleFontColor = opts.title.color || config.titleColor;
+	var subtitleFontColor = opts.subtitle.color || config.subtitleColor;
+	var titleHeight = title ? titlefontSize : 0;
+	var subtitleHeight = subtitle ? subtitlefontSize : 0;
+	var margin = 5;
+	//slam todo
+	var arcbarDate = opts.title.arcbarDate || config.arcbarDate;
+	// console.log("arcbarDate=",arcbarDate);
+	var molecularUnit = opts.title.molecularUnit || config.molecularUnit;
+	var denominatorUnit = opts.title.denominatorUnit || config.denominatorUnit;
+
+	if (subtitle) {
+		var textWidth = measureText(subtitle, subtitlefontSize);
+		var startX = center.x - textWidth / 2 + (opts.subtitle.offsetX || 0);
+		var startY = center.y + subtitlefontSize / 2 + (opts.subtitle.offsetY || 0);
+		if (title) {
+			startY += (titleHeight + margin) / 2;
+		}
+		context.beginPath();
+		context.setFontSize(subtitlefontSize);
+		context.setFillStyle(subtitleFontColor);
+		context.fillText(subtitle, startX, startY);
+
+		context.closePath();
+		context.stroke();
+	}
+	//为零时候显示零
+	if (title) {
+		var _textWidth = measureText(title, titlefontSize);
+
+		var _startX = center.x - _textWidth / 2 + (opts.title.offsetX || 0);
+		var _startY = center.y + titlefontSize / 2 + (opts.title.offsetY || 0);
+		if (subtitle) {
+			_startY -= (subtitleHeight + margin) / 2;
+		}
+		var _moleWidth = measureText(molecularUnit, titlefontSize * 0.39);
+		var _moleStartX = _startX + _textWidth;
+
+		var _denomiStartX = _moleStartX + _moleWidth;
+
+		// 日期的位置
+		var _textDateWidth = measureText(arcbarDate, unitFontSize);
+		var _dateStartX = center.x - _textDateWidth / 2 + 5;
+		var _dateY = 30;
+		context.beginPath();
+		context.setFontSize(titlefontSize);
+		context.setFillStyle(titleFontColor);
+		context.fillText(title, _startX, _startY - _dateY);
+		context.closePath();
+		context.stroke();
+
+		context.beginPath();
+		context.setFontSize(unitFontSize);
+		context.setFillStyle(titleFontColor);
+		// context.fillText(arcbarDate, _dateStartX, _startY-40);
+		//+"/"+denominatorUnit
+		context.fillText(molecularUnit+"/"+denominatorUnit, _moleStartX + 5, _startY - _dateY);
+		// context.fillText("/", _denomiStartX + 5, _startY - _dateY);
+		// context.fillText(denominatorUnit, _denomiStartX + 10, _startY - _dateY);
+		context.closePath();
+		context.stroke();
+
+
+	}
+	// console.log("molecularUnit", molecularUnit);
+}
+
+function drawRingTitle(opts, config, context, center) {
+	var titlefontSize = opts.title.fontSize || config.titleFontSize;
+	var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize;
+	var title = opts.title.name || '';
+	var subtitle = opts.subtitle.name || '';
+	var titleFontColor = opts.title.color || config.titleColor;
+	var subtitleFontColor = opts.subtitle.color || config.subtitleColor;
+	var titleHeight = title ? titlefontSize : 0;
+	var subtitleHeight = subtitle ? subtitlefontSize : 0;
+	var margin = 5;
+
+	if (subtitle) {
+		var textWidth = measureText(subtitle, subtitlefontSize);
+		var startX = center.x - textWidth / 2 + (opts.subtitle.offsetX || 0);
+		var startY = center.y + subtitlefontSize / 2 + (opts.subtitle.offsetY || 0);
+		if (title) {
+			startY += (titleHeight + margin) / 2;
+		}
+		context.beginPath();
+		context.setFontSize(subtitlefontSize);
+		context.setFillStyle(subtitleFontColor);
+		context.fillText(subtitle, startX, startY);
+		context.closePath();
+		context.stroke();
+	}
+	if (title) {
+		var _textWidth = measureText(title, titlefontSize);
+		var _startX = center.x - _textWidth / 2 + (opts.title.offsetX || 0);
+		var _startY = center.y + titlefontSize / 2 + (opts.title.offsetY || 0);
+		if (subtitle) {
+			_startY -= (subtitleHeight + margin) / 2;
+		}
+		context.beginPath();
+		context.setFontSize(titlefontSize);
+		context.setFillStyle(titleFontColor);
+		context.fillText(title, _startX, _startY);
+		context.closePath();
+		context.stroke();
+	}
+}
+
+function drawPointText(points, series, config, context) {
+	// 绘制数据文案
+	var data = series.data;
+	points.forEach(function(item, index) {
+		if (item !== null) {
+			//var formatVal = series.format ? series.format(data[index]) : data[index];
+			context.beginPath();
+			context.setFontSize(series.textSize || config.fontSize);
+			context.setFillStyle(series.textColor || '#666666');
+			var value = data[index]
+			if (typeof data[index] === 'object' && data[index] !== null) {
+				if (data[index].constructor == Array) {
+					value = data[index][1];
+				} else {
+					value = data[index].value
+				}
+			}
+			var formatVal = series.format ? series.format(value) : value;
+			context.fillText(String(formatVal), item.x - measureText(formatVal, series.textSize || config.fontSize) / 2, item.y -
+				4);
+			context.closePath();
+			context.stroke();
+		}
+	});
+
+}
+
+function drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context) {
+	radius -= gaugeOption.width / 2 + config.gaugeLabelTextMargin;
+
+	let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
+	let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+	let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber;
+	let splitNumber = totalNumber / gaugeOption.splitLine.splitNumber;
+	let nowAngle = gaugeOption.startAngle;
+	let nowNumber = gaugeOption.startNumber;
+	for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
+		var pos = {
+			x: radius * Math.cos(nowAngle * Math.PI),
+			y: radius * Math.sin(nowAngle * Math.PI)
+		};
+		var labelText = gaugeOption.labelFormat ? gaugeOption.labelFormat(nowNumber) : nowNumber;
+		pos.x += centerPosition.x - measureText(labelText) / 2;
+		pos.y += centerPosition.y;
+		var startX = pos.x;
+		var startY = pos.y;
+		context.beginPath();
+		context.setFontSize(config.fontSize);
+		context.setFillStyle(gaugeOption.labelColor || '#666666');
+		context.fillText(labelText, startX, startY + config.fontSize / 2);
+		context.closePath();
+		context.stroke();
+
+		nowAngle += splitAngle;
+		if (nowAngle >= 2) {
+			nowAngle = nowAngle % 2;
+		}
+		nowNumber += splitNumber;
+	}
+
+}
+
+function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) {
+	var radarOption = opts.extra.radar || {};
+	radius += config.radarLabelTextMargin;
+
+	angleList.forEach(function(angle, index) {
+		var pos = {
+			x: radius * Math.cos(angle),
+			y: radius * Math.sin(angle)
+		};
+		var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition);
+		var startX = posRelativeCanvas.x;
+		var startY = posRelativeCanvas.y;
+		if (util.approximatelyEqual(pos.x, 0)) {
+			startX -= measureText(opts.categories[index] || '') / 2;
+		} else if (pos.x < 0) {
+			startX -= measureText(opts.categories[index] || '');
+		}
+		context.beginPath();
+		context.setFontSize(config.fontSize);
+		context.setFillStyle(radarOption.labelColor || '#666666');
+		context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2);
+		context.closePath();
+		context.stroke();
+	});
+
+}
+
+function drawPieText(series, opts, config, context, radius, center) {
+	var lineRadius = config.pieChartLinePadding;
+	var textObjectCollection = [];
+	var lastTextObject = null;
+
+	var seriesConvert = series.map(function(item) {
+		var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_.toFixed(4) *
+			100) + '%';
+		if (item._rose_proportion_) item._proportion_ = item._rose_proportion_;
+		var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2);
+		var color = item.color;
+		var radius = item._radius_;
+		return {
+			arc: arc,
+			text: text,
+			color: color,
+			radius: radius,
+			textColor: item.textColor,
+			textSize: item.textSize,
+		};
+	});
+	for (let i = 0; i < seriesConvert.length; i++) {
+		let item = seriesConvert[i];
+		// line end
+		let orginX1 = Math.cos(item.arc) * (item.radius + lineRadius);
+		let orginY1 = Math.sin(item.arc) * (item.radius + lineRadius);
+
+		// line start
+		let orginX2 = Math.cos(item.arc) * item.radius;
+		let orginY2 = Math.sin(item.arc) * item.radius;
+
+		// text start
+		let orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding;
+		let orginY3 = orginY1;
+		let textWidth = measureText(item.text, item.textSize || config.fontSize);
+		let startY = orginY3;
+
+		if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, {
+				x: orginX3
+			})) {
+			if (orginX3 > 0) {
+				startY = Math.min(orginY3, lastTextObject.start.y);
+			} else if (orginX1 < 0) {
+				startY = Math.max(orginY3, lastTextObject.start.y);
+			} else {
+				if (orginY3 > 0) {
+					startY = Math.max(orginY3, lastTextObject.start.y);
+				} else {
+					startY = Math.min(orginY3, lastTextObject.start.y);
+				}
+			}
+		}
+		if (orginX3 < 0) {
+			orginX3 -= textWidth;
+		}
+
+		let textObject = {
+			lineStart: {
+				x: orginX2,
+				y: orginY2
+			},
+			lineEnd: {
+				x: orginX1,
+				y: orginY1
+			},
+			start: {
+				x: orginX3,
+				y: startY
+			},
+			width: textWidth,
+			height: config.fontSize,
+			text: item.text,
+			color: item.color,
+			textColor: item.textColor,
+			textSize: item.textSize
+		};
+		lastTextObject = avoidCollision(textObject, lastTextObject);
+		textObjectCollection.push(lastTextObject);
+	}
+
+	for (let i = 0; i < textObjectCollection.length; i++) {
+		let item = textObjectCollection[i];
+		let lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center);
+		let lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center);
+		let textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center);
+		context.setLineWidth(1 * opts.pixelRatio);
+		context.setFontSize(config.fontSize);
+		context.beginPath();
+		context.setStrokeStyle(item.color);
+		context.setFillStyle(item.color);
+		context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
+		let curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x;
+		let textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5;
+		context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y);
+		context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
+		context.stroke();
+		context.closePath();
+		context.beginPath();
+		context.moveTo(textPosition.x + item.width, textPosition.y);
+		context.arc(curveStartX, textPosition.y, 2, 0, 2 * Math.PI);
+		context.closePath();
+		context.fill();
+		context.beginPath();
+		context.setFontSize(item.textSize || config.fontSize);
+		context.setFillStyle(item.textColor || '#666666');
+		context.fillText(item.text, textStartX, textPosition.y + 3);
+		context.closePath();
+		context.stroke();
+		context.closePath();
+	}
+}
+
+function drawToolTipSplitLine(offsetX, opts, config, context) {
+	var toolTipOption = opts.extra.tooltip || {};
+	toolTipOption.gridType = toolTipOption.gridType == undefined ? 'solid' : toolTipOption.gridType;
+	toolTipOption.dashLength = toolTipOption.dashLength == undefined ? 4 : toolTipOption.dashLength;
+	var startY = opts.area[0];
+	var endY = opts.height - opts.area[2];
+
+	if (toolTipOption.gridType == 'dash') {
+		context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
+	}
+	context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
+	context.setLineWidth(1 * opts.pixelRatio);
+	context.beginPath();
+	context.moveTo(offsetX, startY);
+	context.lineTo(offsetX, endY);
+	context.stroke();
+	context.setLineDash([]);
+
+	if (toolTipOption.xAxisLabel) {
+		let labelText = opts.categories[opts.tooltip.index];
+		context.setFontSize(config.fontSize);
+		let textWidth = measureText(labelText, config.fontSize);
+
+		let textX = offsetX - 0.5 * textWidth;
+		let textY = endY;
+		context.beginPath();
+		context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity ||
+			config.toolTipOpacity));
+		context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
+		context.setLineWidth(1 * opts.pixelRatio);
+		context.rect(textX - config.toolTipPadding, textY, textWidth + 2 * config.toolTipPadding, config.fontSize + 2 *
+			config.toolTipPadding);
+		context.closePath();
+		context.stroke();
+		context.fill();
+
+		context.beginPath();
+		context.setFontSize(config.fontSize);
+		context.setFillStyle(toolTipOption.labelFontColor || config.fontColor);
+		context.fillText(String(labelText), textX, textY + config.toolTipPadding + config.fontSize);
+		context.closePath();
+		context.stroke();
+	}
+}
+
+function drawMarkLine(opts, config, context) {
+	let markLineOption = assign({}, {
+		type: 'solid',
+		dashLength: 4,
+		data: []
+	}, opts.extra.markLine);
+	let startX = opts.area[3];
+	let endX = opts.width - opts.area[1];
+	let points = calMarkLineData(markLineOption.data, opts);
+
+	for (let i = 0; i < points.length; i++) {
+		let item = assign({}, {
+			lineColor: '#DE4A42',
+			showLabel: false,
+			labelFontColor: '#666666',
+			labelBgColor: '#DFE8FF',
+			labelBgOpacity: 0.8,
+			yAxisIndex: 0
+		}, points[i]);
+
+		if (markLineOption.type == 'dash') {
+			context.setLineDash([markLineOption.dashLength, markLineOption.dashLength]);
+		}
+		context.setStrokeStyle(item.lineColor);
+		context.setLineWidth(1 * opts.pixelRatio);
+		context.beginPath();
+		context.moveTo(startX, item.y);
+		context.lineTo(endX, item.y);
+		context.stroke();
+		context.setLineDash([]);
+		if (item.showLabel) {
+			let labelText = opts.yAxis.format ? opts.yAxis.format(Number(item.value)) : item.value;
+			context.setFontSize(config.fontSize);
+			let textWidth = measureText(labelText, config.fontSize);
+			let bgStartX = opts.padding[3] + config.yAxisTitleWidth - config.toolTipPadding;
+			let bgEndX = Math.max(opts.area[3], textWidth + config.toolTipPadding * 2);
+			let bgWidth = bgEndX - bgStartX;
+
+			let textX = bgStartX + (bgWidth - textWidth) / 2;
+			let textY = item.y;
+			context.setFillStyle(hexToRgb(item.labelBgColor, item.labelBgOpacity));
+			context.setStrokeStyle(item.labelBgColor);
+			context.setLineWidth(1 * opts.pixelRatio);
+			context.beginPath();
+			context.rect(bgStartX, textY - 0.5 * config.fontSize - config.toolTipPadding, bgWidth, config.fontSize + 2 * config.toolTipPadding);
+			context.closePath();
+			context.stroke();
+			context.fill();
+
+			context.beginPath();
+			context.setFontSize(config.fontSize);
+			context.setFillStyle(item.labelFontColor);
+			context.fillText(String(labelText), textX, textY + 0.5 * config.fontSize);
+			context.stroke();
+		}
+	}
+}
+
+function drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) {
+	var toolTipOption = assign({}, {
+		gridType: 'solid',
+		dashLength: 4
+	}, opts.extra.tooltip);
+
+	var startX = opts.area[3];
+	var endX = opts.width - opts.area[1];
+
+	if (toolTipOption.gridType == 'dash') {
+		context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
+	}
+	context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
+	context.setLineWidth(1 * opts.pixelRatio);
+	context.beginPath();
+	context.moveTo(startX, opts.tooltip.offset.y);
+	context.lineTo(endX, opts.tooltip.offset.y);
+	context.stroke();
+	context.setLineDash([]);
+
+	if (toolTipOption.yAxisLabel) {
+		let labelText = calTooltipYAxisData(opts.tooltip.offset.y, opts.series, opts, config, eachSpacing);
+		let widthArr = opts.chartData.yAxisData.yAxisWidth;
+		let tStartLeft = opts.area[3];
+		let tStartRight = opts.width - opts.area[1];
+		for (let i = 0; i < labelText.length; i++) {
+			context.setFontSize(config.fontSize);
+			let textWidth = measureText(labelText[i], config.fontSize);
+			let bgStartX, bgEndX, bgWidth;
+			if (widthArr[i].position == 'left') {
+				bgStartX = tStartLeft - widthArr[i].width;
+				bgEndX = Math.max(bgStartX, bgStartX + textWidth + config.toolTipPadding * 2);
+			} else {
+				bgStartX = tStartRight;
+				bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + config.toolTipPadding * 2);
+			}
+			bgWidth = bgEndX - bgStartX;
+
+			let textX = bgStartX + (bgWidth - textWidth) / 2;
+			let textY = opts.tooltip.offset.y;
+			context.beginPath();
+			context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity ||
+				config.toolTipOpacity));
+			context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
+			context.setLineWidth(1 * opts.pixelRatio);
+			context.rect(bgStartX, textY - 0.5 * config.fontSize - config.toolTipPadding, bgWidth, config.fontSize + 2 * config.toolTipPadding);
+			context.closePath();
+			context.stroke();
+			context.fill();
+
+			context.beginPath();
+			context.setFontSize(config.fontSize);
+			context.setFillStyle(toolTipOption.labelFontColor || config.fontColor);
+			context.fillText(labelText[i], textX, textY + 0.5 * config.fontSize);
+			context.closePath();
+			context.stroke();
+			if (widthArr[i].position == 'left') {
+				tStartLeft -= (widthArr[i].width + opts.yAxis.padding);
+			} else {
+				tStartRight += widthArr[i].width + opts.yAxis.padding;
+			}
+		}
+	}
+}
+
+function drawToolTipSplitArea(offsetX, opts, config, context, eachSpacing) {
+	var toolTipOption = assign({}, {
+		activeBgColor: '#000000',
+		activeBgOpacity: 0.08
+	}, opts.extra.tooltip);
+	var startY = opts.area[0];
+	var endY = opts.height - opts.area[2];
+	context.beginPath();
+	context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity));
+	context.rect(offsetX - eachSpacing / 2, startY, eachSpacing, endY - startY);
+	context.closePath();
+	context.fill();
+}
+
+function drawToolTip(textList, offset, opts, config, context, eachSpacing, xAxisPoints) {
+	var toolTipOption = assign({}, {
+		showBox: true,
+		bgColor: '#000000',
+		bgOpacity: 0.7,
+		fontColor: '#FFFFFF'
+	}, opts.extra.tooltip);
+	var legendWidth = 4 * opts.pixelRatio;
+	var legendMarginRight = 5 * opts.pixelRatio;
+	var arrowWidth = 8 * opts.pixelRatio;
+	var isOverRightBorder = false;
+	if (opts.type == 'line' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') {
+		drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
+	}
+
+	offset = assign({
+		x: 0,
+		y: 0
+	}, offset);
+	offset.y -= 8 * opts.pixelRatio;
+	var textWidth = textList.map(function(item) {
+		return measureText(item.text, config.fontSize);
+	});
+	var toolTipWidth = legendWidth + legendMarginRight + 4 * config.toolTipPadding + Math.max.apply(null, textWidth);
+	var toolTipHeight = 2 * config.toolTipPadding + textList.length * config.toolTipLineHeight;
+
+	if (toolTipOption.showBox == false) {
+		return
+	}
+	// if beyond the right border
+	if (offset.x - Math.abs(opts._scrollDistance_) + arrowWidth + toolTipWidth > opts.width) {
+		isOverRightBorder = true;
+	}
+	if (toolTipHeight + offset.y > opts.height) {
+		offset.y = opts.height - toolTipHeight;
+	}
+	// draw background rect
+	context.beginPath();
+	context.setFillStyle(hexToRgb(toolTipOption.bgColor || config.toolTipBackground, toolTipOption.bgOpacity || config.toolTipOpacity));
+	if (isOverRightBorder) {
+		context.moveTo(offset.x, offset.y + 10 * opts.pixelRatio);
+		context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pixelRatio - 5 * opts.pixelRatio);
+		context.lineTo(offset.x - arrowWidth, offset.y);
+		context.lineTo(offset.x - arrowWidth - Math.round(toolTipWidth), offset.y);
+		context.lineTo(offset.x - arrowWidth - Math.round(toolTipWidth), offset.y + toolTipHeight);
+		context.lineTo(offset.x - arrowWidth, offset.y + toolTipHeight);
+		context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pixelRatio + 5 * opts.pixelRatio);
+		context.lineTo(offset.x, offset.y + 10 * opts.pixelRatio);
+	} else {
+		context.moveTo(offset.x, offset.y + 10 * opts.pixelRatio);
+		context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pixelRatio - 5 * opts.pixelRatio);
+		context.lineTo(offset.x + arrowWidth, offset.y);
+		context.lineTo(offset.x + arrowWidth + Math.round(toolTipWidth), offset.y);
+		context.lineTo(offset.x + arrowWidth + Math.round(toolTipWidth), offset.y + toolTipHeight);
+		context.lineTo(offset.x + arrowWidth, offset.y + toolTipHeight);
+		context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pixelRatio + 5 * opts.pixelRatio);
+		context.lineTo(offset.x, offset.y + 10 * opts.pixelRatio);
+	}
+
+	context.closePath();
+	context.fill();
+
+	// draw legend
+	textList.forEach(function(item, index) {
+		if (item.color !== null) {
+			context.beginPath();
+			context.setFillStyle(item.color);
+			var startX = offset.x + arrowWidth + 2 * config.toolTipPadding;
+			var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index +
+				config.toolTipPadding + 1;
+			if (isOverRightBorder) {
+				startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding;
+			}
+			context.fillRect(startX, startY, legendWidth, config.fontSize);
+			context.closePath();
+		}
+	});
+
+	// draw text list
+
+	textList.forEach(function(item, index) {
+		var startX = offset.x + arrowWidth + 2 * config.toolTipPadding + legendWidth + legendMarginRight;
+		if (isOverRightBorder) {
+			startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding + +legendWidth + legendMarginRight;
+		}
+		var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index +
+			config.toolTipPadding;
+		context.beginPath();
+		context.setFontSize(config.fontSize);
+		context.setFillStyle(toolTipOption.fontColor);
+		context.fillText(item.text, startX, startY + config.fontSize);
+		context.closePath();
+		context.stroke();
+	});
+}
+
+function drawYAxisTitle(title, opts, config, context) {
+	var startX = config.xAxisHeight + (opts.height - config.xAxisHeight - measureText(title)) / 2;
+	context.save();
+	context.beginPath();
+	context.setFontSize(config.fontSize);
+	context.setFillStyle(opts.yAxis.titleFontColor || '#333333');
+	context.translate(0, opts.height);
+	context.rotate(-90 * Math.PI / 180);
+	context.fillText(title, startX, opts.padding[3] + 0.5 * config.fontSize);
+	context.closePath();
+	context.stroke();
+	context.restore();
+}
+
+function drawColumnDataPoints(series, opts, config, context) {
+	let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	let xAxisData = opts.chartData.xAxisData,
+		xAxisPoints = xAxisData.xAxisPoints,
+		eachSpacing = xAxisData.eachSpacing;
+	let columnOption = assign({}, {
+		type: 'group',
+		width: eachSpacing / 2,
+		meter: {
+			border: 4,
+			fillColor: '#FFFFFF'
+		}
+	}, opts.extra.column);
+
+	let calPoints = [];
+	context.save();
+
+	let leftNum = -2;
+	let rightNum = xAxisPoints.length + 2;
+
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+		context.translate(opts._scrollDistance_, 0);
+		leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+		rightNum = leftNum + opts.xAxis.itemCount + 4;
+	}
+	if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+		drawToolTipSplitArea(opts.tooltip.offset.x, opts, config, context, eachSpacing);
+	}
+
+	series.forEach(function(eachSeries, seriesIndex) {
+		let ranges, minRange, maxRange;
+		ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+		minRange = ranges.pop();
+		maxRange = ranges.shift();
+
+		var data = eachSeries.data;
+		switch (columnOption.type) {
+			case 'group':
+				var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+				var tooltipPoints = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config,
+					seriesIndex, series, process);
+				calPoints.push(tooltipPoints);
+				points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
+				for (let i = 0; i < points.length; i++) {
+					let item = points[i];
+					if (item !== null && i > leftNum && i < rightNum) {
+						context.beginPath();
+						context.setStrokeStyle(item.color || eachSeries.color);
+						context.setLineWidth(1)
+						context.setFillStyle(item.color || eachSeries.color);
+						var startX = item.x - item.width / 2;
+						var height = opts.height - item.y - opts.area[2];
+						context.moveTo(startX - 1, item.y);
+						context.lineTo(startX + item.width - 2, item.y);
+						context.lineTo(startX + item.width - 2, opts.height - opts.area[2]);
+						context.lineTo(startX, opts.height - opts.area[2]);
+						context.lineTo(startX, item.y);
+						context.closePath();
+						context.stroke();
+						context.fill();
+					}
+				};
+				break;
+			case 'stack':
+				// 绘制堆叠数据图
+				var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex,
+					series, process);
+				calPoints.push(points);
+				points = fixColumeStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series);
+
+				for (let i = 0; i < points.length; i++) {
+					let item = points[i];
+					if (item !== null && i > leftNum && i < rightNum) {
+						context.beginPath();
+						context.setFillStyle(item.color || eachSeries.color);
+						var startX = item.x - item.width / 2 + 1;
+						var height = opts.height - item.y - opts.area[2];
+						var height0 = opts.height - item.y0 - opts.area[2];
+						if (seriesIndex > 0) {
+							height -= height0;
+						}
+						context.moveTo(startX, item.y);
+						context.fillRect(startX, item.y, item.width - 2, height);
+						context.closePath();
+						context.fill();
+					}
+				};
+				break;
+			case 'meter':
+				// 绘制温度计数据图
+				var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+				calPoints.push(points);
+				points = fixColumeMeterData(points, eachSpacing, series.length, seriesIndex, config, opts, columnOption.meter.border);
+				if (seriesIndex == 0) {
+					for (let i = 0; i < points.length; i++) {
+						let item = points[i];
+						if (item !== null && i > leftNum && i < rightNum) {
+							//画背景颜色
+							context.beginPath();
+							context.setFillStyle(columnOption.meter.fillColor);
+							var startX = item.x - item.width / 2;
+							var height = opts.height - item.y - opts.area[2];
+							context.moveTo(startX, item.y);
+							context.fillRect(startX, item.y, item.width, height);
+							context.closePath();
+							context.fill();
+							//画边框线
+							if (columnOption.meter.border > 0) {
+								context.beginPath();
+								context.setStrokeStyle(eachSeries.color);
+								context.setLineWidth(columnOption.meter.border * opts.pixelRatio);
+								context.moveTo(startX + columnOption.meter.border * 0.5, item.y + height);
+								context.lineTo(startX + columnOption.meter.border * 0.5, item.y + columnOption.meter.border * 0.5);
+								context.lineTo(startX + item.width - columnOption.meter.border * 0.5, item.y + columnOption.meter.border *
+									0.5);
+								context.lineTo(startX + item.width - columnOption.meter.border * 0.5, item.y + height);
+								context.stroke();
+							}
+						}
+					};
+				} else {
+					for (let i = 0; i < points.length; i++) {
+						let item = points[i];
+						if (item !== null && i > leftNum && i < rightNum) {
+							context.beginPath();
+							context.setFillStyle(item.color || eachSeries.color);
+							var startX = item.x - item.width / 2;
+							var height = opts.height - item.y - opts.area[2];
+							context.moveTo(startX, item.y);
+							context.fillRect(startX, item.y, item.width, height);
+							context.closePath();
+							context.fill();
+						}
+					};
+				}
+				break;
+		}
+	});
+
+	if (opts.dataLabel !== false && process === 1) {
+		series.forEach(function(eachSeries, seriesIndex) {
+			let ranges, minRange, maxRange;
+			ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+			minRange = ranges.pop();
+			maxRange = ranges.shift();
+			var data = eachSeries.data;
+			switch (columnOption.type) {
+				case 'group':
+					var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+					points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
+					drawPointText(points, eachSeries, config, context);
+					break;
+				case 'stack':
+					var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex,
+						series, process);
+					drawPointText(points, eachSeries, config, context);
+					break;
+				case 'meter':
+					var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+					drawPointText(points, eachSeries, config, context);
+					break;
+			}
+		});
+	}
+
+	context.restore();
+
+	return {
+		xAxisPoints: xAxisPoints,
+		calPoints: calPoints,
+		eachSpacing: eachSpacing
+	};
+}
+
+function drawCandleDataPoints(series, seriesMA, opts, config, context) {
+	var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+	var candleOption = assign({}, {
+		color: {},
+		average: {}
+	}, opts.extra.candle);
+	candleOption.color = assign({}, {
+		upLine: '#f04864',
+		upFill: '#f04864',
+		downLine: '#2fc25b',
+		downFill: '#2fc25b'
+	}, candleOption.color);
+	candleOption.average = assign({}, {
+		show: false,
+		name: [],
+		day: [],
+		color: config.colors
+	}, candleOption.average);
+	opts.extra.candle = candleOption;
+
+	let xAxisData = opts.chartData.xAxisData,
+		xAxisPoints = xAxisData.xAxisPoints,
+		eachSpacing = xAxisData.eachSpacing;
+
+	let calPoints = [];
+
+	context.save();
+
+	let leftNum = -2;
+	let rightNum = xAxisPoints.length + 2;
+	let leftSpace = 0;
+	let rightSpace = opts.width + eachSpacing;
+
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+		context.translate(opts._scrollDistance_, 0);
+		leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+		rightNum = leftNum + opts.xAxis.itemCount + 4;
+		leftSpace = -opts._scrollDistance_ - eachSpacing + opts.area[3];
+		rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+	}
+
+	//画均线
+	if (candleOption.average.show) {
+		seriesMA.forEach(function(eachSeries, seriesIndex) {
+			let ranges, minRange, maxRange;
+			ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+			minRange = ranges.pop();
+			maxRange = ranges.shift();
+
+			var data = eachSeries.data;
+			var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+			var splitPointList = splitPoints(points);
+
+			for (let i = 0; i < splitPointList.length; i++) {
+				let points = splitPointList[i];
+				context.beginPath();
+				context.setStrokeStyle(eachSeries.color);
+				context.setLineWidth(1);
+				if (points.length === 1) {
+					context.moveTo(points[0].x, points[0].y);
+					context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+				} else {
+					context.moveTo(points[0].x, points[0].y);
+					let startPoint = 0;
+					for (let j = 0; j < points.length; j++) {
+						let item = points[j];
+						if (startPoint == 0 && item.x > leftSpace) {
+							context.moveTo(item.x, item.y);
+							startPoint = 1;
+						}
+						if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+							var ctrlPoint = createCurveControlPoints(points, j - 1);
+							context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+						}
+					}
+					context.moveTo(points[0].x, points[0].y);
+				}
+				context.closePath();
+				context.stroke();
+			}
+		});
+	}
+	//画K线
+	series.forEach(function(eachSeries, seriesIndex) {
+		let ranges, minRange, maxRange;
+		ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+		minRange = ranges.pop();
+		maxRange = ranges.shift();
+		var data = eachSeries.data;
+		var points = getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+		calPoints.push(points);
+		var splitPointList = splitPoints(points);
+
+		for (let i = 0; i < splitPointList[0].length; i++) {
+			if (i > leftNum && i < rightNum) {
+				let item = splitPointList[0][i];
+				context.beginPath();
+				//如果上涨
+				if (data[i][1] - data[i][0] > 0) {
+					context.setStrokeStyle(candleOption.color.upLine);
+					context.setFillStyle(candleOption.color.upFill);
+					context.setLineWidth(1 * opts.pixelRatio);
+					context.moveTo(item[3].x, item[3].y); //顶点
+					context.lineTo(item[1].x, item[1].y); //收盘中间点
+					context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点
+					context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点
+					context.lineTo(item[0].x, item[0].y); //开盘中间点
+					context.lineTo(item[2].x, item[2].y); //底点
+					context.lineTo(item[0].x, item[0].y); //开盘中间点
+					context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点
+					context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点
+					context.lineTo(item[1].x, item[1].y); //收盘中间点
+					context.moveTo(item[3].x, item[3].y); //顶点
+				} else {
+					context.setStrokeStyle(candleOption.color.downLine);
+					context.setFillStyle(candleOption.color.downFill);
+					context.setLineWidth(1 * opts.pixelRatio);
+					context.moveTo(item[3].x, item[3].y); //顶点
+					context.lineTo(item[0].x, item[0].y); //开盘中间点
+					context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点
+					context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点
+					context.lineTo(item[1].x, item[1].y); //收盘中间点
+					context.lineTo(item[2].x, item[2].y); //底点
+					context.lineTo(item[1].x, item[1].y); //收盘中间点
+					context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点
+					context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点
+					context.lineTo(item[0].x, item[0].y); //开盘中间点
+					context.moveTo(item[3].x, item[3].y); //顶点
+				}
+				context.closePath();
+				context.fill();
+				context.stroke();
+			}
+		}
+	});
+
+	context.restore();
+
+	return {
+		xAxisPoints: xAxisPoints,
+		calPoints: calPoints,
+		eachSpacing: eachSpacing
+	};
+}
+
+function drawAreaDataPoints(series, opts, config, context) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var areaOption = assign({}, {
+		type: 'straight',
+		opacity: 0.2,
+		addLine: false,
+		width: 2,
+		gradient: false
+	}, opts.extra.area);
+
+	let xAxisData = opts.chartData.xAxisData,
+		xAxisPoints = xAxisData.xAxisPoints,
+		eachSpacing = xAxisData.eachSpacing;
+
+	let endY = opts.height - opts.area[2];
+	let calPoints = [];
+	// endY -=20;
+
+	context.save();
+	let leftSpace = 0;
+	let rightSpace = opts.width + eachSpacing;
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+		context.translate(opts._scrollDistance_, 0);
+		leftSpace = -opts._scrollDistance_ - eachSpacing + opts.area[3];
+		rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+	}
+	series.forEach(function(eachSeries, seriesIndex) {
+		let ranges, minRange, maxRange;
+		ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+		minRange = ranges.pop();
+		maxRange = ranges.shift();
+		let data = eachSeries.data;
+		let points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+		calPoints.push(points);
+
+		let splitPointList = splitPoints(points);
+		for (let i = 0; i < splitPointList.length; i++) {
+			let points = splitPointList[i];
+			// 绘制区域数
+			context.beginPath();
+			context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+			if (areaOption.gradient) {
+				let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]);
+				gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity));
+				gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+				context.setFillStyle(gradient);
+			} else {
+				context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+			}
+			context.setLineWidth(areaOption.width * opts.pixelRatio);
+			if (points.length > 1) {
+				let firstPoint = points[0];
+				let lastPoint = points[points.length - 1];
+				context.moveTo(firstPoint.x, firstPoint.y);
+				let startPoint = 0;
+				if (areaOption.type === 'curve') {
+					for (let j = 0; j < points.length; j++) {
+						let item = points[j];
+						if (startPoint == 0 && item.x > leftSpace) {
+							context.moveTo(item.x, item.y);
+							startPoint = 1;
+						}
+						if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+							let ctrlPoint = createCurveControlPoints(points, j - 1);
+							context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+						}
+					};
+				} else {
+					for (let j = 0; j < points.length; j++) {
+						let item = points[j];
+						if (startPoint == 0 && item.x > leftSpace) {
+							context.moveTo(item.x, item.y);
+							startPoint = 1;
+						}
+						if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+							context.lineTo(item.x, item.y);
+						}
+					};
+				}
+
+				context.lineTo(lastPoint.x, endY);
+				context.lineTo(firstPoint.x, endY);
+				context.lineTo(firstPoint.x, firstPoint.y);
+			} else {
+				let item = points[0];
+				context.moveTo(item.x - eachSpacing / 2, item.y);
+				context.lineTo(item.x + eachSpacing / 2, item.y);
+				context.lineTo(item.x + eachSpacing / 2, endY);
+				context.lineTo(item.x - eachSpacing / 2, endY);
+				context.moveTo(item.x - eachSpacing / 2, item.y);
+				
+				//slam todo 
+				//加个左右射线
+				context.lineWidth = 0.3;
+				context.beginPath();
+				context.moveTo(item.x,item.y)
+				context.lineTo(item.x + opts.width/2-30,item.y);
+				context.stroke();
+				context.beginPath();
+				context.moveTo(item.x,item.y)
+				context.lineTo(item.x - opts.width/2+30,item.y);
+				context.stroke();
+			}
+			context.closePath();
+			//slam todo 只有一个点时候,不渲染渐变颜色
+			if (points.length > 1) {
+				context.fill();
+			}
+
+
+			//画连线
+			if (areaOption.addLine) {
+				if (eachSeries.lineType == 'dash') {
+					let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+					dashLength *= opts.pixelRatio;
+					context.setLineDash([dashLength, dashLength]);
+				}
+				context.beginPath();
+				context.setStrokeStyle(eachSeries.color);
+				context.setLineWidth(areaOption.width * opts.pixelRatio);
+				if (points.length === 1) {
+					context.moveTo(points[0].x, points[0].y);
+					context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+				} else {
+					context.moveTo(points[0].x, points[0].y);
+					let startPoint = 0;
+					if (areaOption.type === 'curve') {
+						for (let j = 0; j < points.length; j++) {
+							let item = points[j];
+							if (startPoint == 0 && item.x > leftSpace) {
+								context.moveTo(item.x, item.y);
+								startPoint = 1;
+							}
+							if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+								let ctrlPoint = createCurveControlPoints(points, j - 1);
+								context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+							}
+						};
+					} else {
+						for (let j = 0; j < points.length; j++) {
+							let item = points[j];
+							if (startPoint == 0 && item.x > leftSpace) {
+								context.moveTo(item.x, item.y);
+								startPoint = 1;
+							}
+							if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+								context.lineTo(item.x, item.y);
+							}
+						};
+					}
+					context.moveTo(points[0].x, points[0].y);
+				}
+				context.stroke();
+				context.setLineDash([]);
+			}
+		}
+		if (opts.enableBottomSolid || config.enableBottomSolid) {
+			// slam todo 绘制底部线条
+			//下边框
+			context.beginPath();
+			context.moveTo(10, endY);
+			context.lineTo(opts.width / 2 - 7, endY);
+			context.lineTo(opts.width / 2, endY - 14);
+			context.lineTo(opts.width / 2 + 7, endY);
+			context.lineTo(opts.width - 10, endY);
+			// context.closePath(); //闭合路径
+			context.lineWidth = 0.3; //线的边框为10像素
+			context.strokeStyle = 'grey';
+			context.stroke(); //绘制定义的图形	
+		}
+
+
+		//画点
+		if (opts.dataPointShape !== false) {
+			drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+		}
+
+	});
+
+	if (opts.dataLabel !== false && process === 1) {
+		series.forEach(function(eachSeries, seriesIndex) {
+			let ranges, minRange, maxRange;
+			ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+			minRange = ranges.pop();
+			maxRange = ranges.shift();
+			var data = eachSeries.data;
+			var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+			drawPointText(points, eachSeries, config, context);
+		});
+	}
+
+	context.restore();
+
+	return {
+		xAxisPoints: xAxisPoints,
+		calPoints: calPoints,
+		eachSpacing: eachSpacing
+	};
+}
+
+function drawLineDataPoints(series, opts, config, context) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var lineOption = assign({}, {
+		type: 'straight',
+		width: 2
+	}, opts.extra.line);
+	lineOption.width *= opts.pixelRatio;
+
+	let xAxisData = opts.chartData.xAxisData,
+		xAxisPoints = xAxisData.xAxisPoints,
+		eachSpacing = xAxisData.eachSpacing;
+	var calPoints = [];
+
+	context.save();
+	let leftSpace = 0;
+	let rightSpace = opts.width + eachSpacing;
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+		context.translate(opts._scrollDistance_, 0);
+		leftSpace = -opts._scrollDistance_ - eachSpacing + opts.area[3];
+		rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+	}
+
+	series.forEach(function(eachSeries, seriesIndex) {
+		let ranges, minRange, maxRange;
+		ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+		minRange = ranges.pop();
+		maxRange = ranges.shift();
+		var data = eachSeries.data;
+		var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+		calPoints.push(points);
+		var splitPointList = splitPoints(points);
+
+		if (eachSeries.lineType == 'dash') {
+			let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+			dashLength *= opts.pixelRatio;
+			context.setLineDash([dashLength, dashLength]);
+		}
+		context.beginPath();
+		context.setStrokeStyle(eachSeries.color);
+		context.setLineWidth(lineOption.width);
+
+		splitPointList.forEach(function(points, index) {
+
+			if (points.length === 1) {
+				context.moveTo(points[0].x, points[0].y);
+				context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+			} else {
+				context.moveTo(points[0].x, points[0].y);
+				let startPoint = 0;
+				if (lineOption.type === 'curve') {
+					for (let j = 0; j < points.length; j++) {
+						let item = points[j];
+						if (startPoint == 0 && item.x > leftSpace) {
+							context.moveTo(item.x, item.y);
+							startPoint = 1;
+						}
+						if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+							var ctrlPoint = createCurveControlPoints(points, j - 1);
+							context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+						}
+					};
+				} else {
+					for (let j = 0; j < points.length; j++) {
+						let item = points[j];
+						if (startPoint == 0 && item.x > leftSpace) {
+							context.moveTo(item.x, item.y);
+							startPoint = 1;
+						}
+						if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+							context.lineTo(item.x, item.y);
+						}
+					};
+				}
+				context.moveTo(points[0].x, points[0].y);
+			}
+
+		});
+
+		context.stroke();
+		context.setLineDash([]);
+
+		if (opts.dataPointShape !== false) {
+			drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+		}
+	});
+
+	if (opts.dataLabel !== false && process === 1) {
+		series.forEach(function(eachSeries, seriesIndex) {
+			let ranges, minRange, maxRange;
+			ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+			minRange = ranges.pop();
+			maxRange = ranges.shift();
+			var data = eachSeries.data;
+			var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+			drawPointText(points, eachSeries, config, context);
+		});
+	}
+
+	context.restore();
+
+	return {
+		xAxisPoints: xAxisPoints,
+		calPoints: calPoints,
+		eachSpacing: eachSpacing
+	};
+}
+
+function drawMixDataPoints(series, opts, config, context) {
+	let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+
+	let xAxisData = opts.chartData.xAxisData,
+		xAxisPoints = xAxisData.xAxisPoints,
+		eachSpacing = xAxisData.eachSpacing;
+
+	let endY = opts.height - opts.area[2];
+	let calPoints = [];
+
+	var columnIndex = 0;
+	var columnLength = 0;
+	series.forEach(function(eachSeries, seriesIndex) {
+		if (eachSeries.type == 'column') {
+			columnLength += 1;
+		}
+	});
+	context.save();
+	let leftNum = -2;
+	let rightNum = xAxisPoints.length + 2;
+	let leftSpace = 0;
+	let rightSpace = opts.width + eachSpacing;
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+		context.translate(opts._scrollDistance_, 0);
+		leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+		rightNum = leftNum + opts.xAxis.itemCount + 4;
+		leftSpace = -opts._scrollDistance_ - eachSpacing + opts.area[3];
+		rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+	}
+
+	series.forEach(function(eachSeries, seriesIndex) {
+		let ranges, minRange, maxRange;
+
+		ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+		minRange = ranges.pop();
+		maxRange = ranges.shift();
+
+		var data = eachSeries.data;
+		var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+		calPoints.push(points);
+
+		// 绘制柱状数据图
+		if (eachSeries.type == 'column') {
+			points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
+			for (let i = 0; i < points.length; i++) {
+				let item = points[i];
+				if (item !== null && i > leftNum && i < rightNum) {
+					context.beginPath();
+					context.setStrokeStyle(item.color || eachSeries.color);
+					context.setLineWidth(1)
+					context.setFillStyle(item.color || eachSeries.color);
+					var startX = item.x - item.width / 2;
+					var height = opts.height - item.y - opts.area[2];
+					context.moveTo(startX, item.y);
+					context.moveTo(startX - 1, item.y);
+					context.lineTo(startX + item.width - 2, item.y);
+					context.lineTo(startX + item.width - 2, opts.height - opts.area[2]);
+					context.lineTo(startX, opts.height - opts.area[2]);
+					context.lineTo(startX, item.y);
+					context.closePath();
+					context.stroke();
+					context.fill();
+					context.closePath();
+					context.fill();
+				}
+			}
+			columnIndex += 1;
+		}
+
+		//绘制区域图数据
+
+		if (eachSeries.type == 'area') {
+			let splitPointList = splitPoints(points);
+			for (let i = 0; i < splitPointList.length; i++) {
+				let points = splitPointList[i];
+				// 绘制区域数据
+				context.beginPath();
+				context.setStrokeStyle(eachSeries.color);
+				context.setFillStyle(hexToRgb(eachSeries.color, 0.2));
+				context.setLineWidth(2 * opts.pixelRatio);
+				if (points.length > 1) {
+					var firstPoint = points[0];
+					let lastPoint = points[points.length - 1];
+					context.moveTo(firstPoint.x, firstPoint.y);
+					let startPoint = 0;
+					if (eachSeries.style === 'curve') {
+						for (let j = 0; j < points.length; j++) {
+							let item = points[j];
+							if (startPoint == 0 && item.x > leftSpace) {
+								context.moveTo(item.x, item.y);
+								startPoint = 1;
+							}
+							if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+								var ctrlPoint = createCurveControlPoints(points, j - 1);
+								context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+							}
+						};
+					} else {
+						for (let j = 0; j < points.length; j++) {
+							let item = points[j];
+							if (startPoint == 0 && item.x > leftSpace) {
+								context.moveTo(item.x, item.y);
+								startPoint = 1;
+							}
+							if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+								context.lineTo(item.x, item.y);
+							}
+						};
+					}
+					context.lineTo(lastPoint.x, endY);
+					context.lineTo(firstPoint.x, endY);
+					context.lineTo(firstPoint.x, firstPoint.y);
+				} else {
+					let item = points[0];
+					context.moveTo(item.x - eachSpacing / 2, item.y);
+					context.lineTo(item.x + eachSpacing / 2, item.y);
+					context.lineTo(item.x + eachSpacing / 2, endY);
+					context.lineTo(item.x - eachSpacing / 2, endY);
+					context.moveTo(item.x - eachSpacing / 2, item.y);
+				}
+				context.closePath();
+				context.fill();
+			}
+		}
+
+		// 绘制折线数据图
+		if (eachSeries.type == 'line') {
+			var splitPointList = splitPoints(points);
+			splitPointList.forEach(function(points, index) {
+				if (eachSeries.lineType == 'dash') {
+					let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+					dashLength *= opts.pixelRatio;
+					context.setLineDash([dashLength, dashLength]);
+				}
+				context.beginPath();
+				context.setStrokeStyle(eachSeries.color);
+				context.setLineWidth(2 * opts.pixelRatio);
+				if (points.length === 1) {
+					context.moveTo(points[0].x, points[0].y);
+					context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+				} else {
+					context.moveTo(points[0].x, points[0].y);
+					let startPoint = 0;
+					if (eachSeries.style == 'curve') {
+						for (let j = 0; j < points.length; j++) {
+							let item = points[j];
+							if (startPoint == 0 && item.x > leftSpace) {
+								context.moveTo(item.x, item.y);
+								startPoint = 1;
+							}
+							if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+								var ctrlPoint = createCurveControlPoints(points, j - 1);
+								context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+							}
+						}
+					} else {
+						for (let j = 0; j < points.length; j++) {
+							let item = points[j];
+							if (startPoint == 0 && item.x > leftSpace) {
+								context.moveTo(item.x, item.y);
+								startPoint = 1;
+							}
+							if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+								context.lineTo(item.x, item.y);
+							}
+						}
+					}
+					context.moveTo(points[0].x, points[0].y);
+				}
+				context.stroke();
+				context.setLineDash([]);
+			});
+		}
+
+		// 绘制点数据图
+		if (eachSeries.type == 'point') {
+			eachSeries.addPoint = true;
+		}
+
+		if (eachSeries.addPoint == true && eachSeries.type !== 'column') {
+			drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+		}
+	});
+	if (opts.dataLabel !== false && process === 1) {
+		var columnIndex = 0;
+		series.forEach(function(eachSeries, seriesIndex) {
+			let ranges, minRange, maxRange;
+
+			ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+			minRange = ranges.pop();
+			maxRange = ranges.shift();
+
+			var data = eachSeries.data;
+			var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+			if (eachSeries.type !== 'column') {
+				drawPointText(points, eachSeries, config, context);
+			} else {
+				points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
+				drawPointText(points, eachSeries, config, context);
+				columnIndex += 1;
+			}
+
+		});
+	}
+
+	context.restore();
+
+	return {
+		xAxisPoints: xAxisPoints,
+		calPoints: calPoints,
+		eachSpacing: eachSpacing,
+	}
+}
+
+function drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints) {
+	var toolTipOption = opts.extra.tooltip || {};
+	if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' ||
+			opts.type == 'column' || opts.type == 'candle' || opts.type == 'mix')) {
+		drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints)
+	}
+	context.save();
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+		context.translate(opts._scrollDistance_, 0);
+	}
+	if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+		drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context, eachSpacing, xAxisPoints);
+	}
+	context.restore();
+
+}
+
+function drawXAxis(categories, opts, config, context) {
+
+	let xAxisData = opts.chartData.xAxisData,
+		xAxisPoints = xAxisData.xAxisPoints,
+		startX = xAxisData.startX,
+		endX = xAxisData.endX,
+		eachSpacing = xAxisData.eachSpacing;
+	var boundaryGap = 'center';
+	if (opts.type == 'line' || opts.type == 'area') {
+		boundaryGap = opts.xAxis.boundaryGap;
+	}
+	var startY = opts.height - opts.area[2];
+	var endY = opts.area[0];
+
+	// if(opts.type == 'area'){
+	// console.log("===",startY,endY);
+	// startY -=10 ;
+	// endY += 10 ;
+	// }
+
+	//绘制滚动条
+	if (opts.enableScroll && opts.xAxis.scrollShow) {
+		var scrollY = opts.height - opts.area[2] + config.xAxisHeight;
+		var scrollScreenWidth = endX - startX;
+		var scrollTotalWidth = eachSpacing * (xAxisPoints.length - 1);
+		var scrollWidth = scrollScreenWidth * scrollScreenWidth / scrollTotalWidth;
+		var scrollLeft = 0;
+		if (opts._scrollDistance_) {
+			scrollLeft = -opts._scrollDistance_ * (scrollScreenWidth) / scrollTotalWidth;
+		}
+		context.beginPath();
+		context.setLineCap('round');
+		context.setLineWidth(6 * opts.pixelRatio);
+		context.setStrokeStyle(opts.xAxis.scrollBackgroundColor || "#EFEBEF");
+		context.moveTo(startX, scrollY);
+		context.lineTo(endX, scrollY);
+		context.stroke();
+		context.closePath();
+		context.beginPath();
+		context.setLineCap('round');
+		context.setLineWidth(6 * opts.pixelRatio);
+		context.setStrokeStyle(opts.xAxis.scrollColor || "#A6A6A6");
+		context.moveTo(startX + scrollLeft, scrollY);
+		context.lineTo(startX + scrollLeft + scrollWidth, scrollY);
+		context.stroke();
+		context.closePath();
+		context.setLineCap('butt');
+	}
+
+	context.save();
+
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
+		context.translate(opts._scrollDistance_, 0);
+	}
+
+	//绘制X轴刻度线
+	if (opts.xAxis.calibration === true) {
+		context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
+		context.setLineCap('butt');
+		context.setLineWidth(1 * opts.pixelRatio);
+		xAxisPoints.forEach(function(item, index) {
+			if (index > 0) {
+				context.beginPath();
+				//eachSpacing/2
+				context.moveTo(item - eachSpacing / 2, startY);
+				//eachSpacing/2
+				context.lineTo(item - eachSpacing / 2, startY - 3 * opts.pixelRatio);
+				context.closePath();
+				context.stroke();
+			}
+		});
+	}
+	//绘制X轴网格
+	if (opts.xAxis.disableGrid !== true) {
+		context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
+		context.setLineCap('butt');
+		context.setLineWidth(1 * opts.pixelRatio);
+		if (opts.xAxis.gridType == 'dash') {
+			context.setLineDash([opts.xAxis.dashLength, opts.xAxis.dashLength]);
+		}
+		opts.xAxis.gridEval = opts.xAxis.gridEval || 1;
+		xAxisPoints.forEach(function(item, index) {
+			if (index % opts.xAxis.gridEval == 0) {
+				context.beginPath();
+				context.moveTo(item, startY);
+				context.lineTo(item, endY);
+				context.stroke();
+			}
+		});
+		context.setLineDash([]);
+	}
+
+
+	//绘制X轴文案
+	if (opts.xAxis.disabled !== true) {
+		// 对X轴列表做抽稀处理
+		//默认全部显示X轴标签
+		let maxXAxisListLength = categories.length;
+		//如果设置了X轴单屏数量
+		if (opts.xAxis.labelCount) {
+			//如果设置X轴密度
+			if (opts.xAxis.itemCount) {
+				maxXAxisListLength = Math.ceil(categories.length / opts.xAxis.itemCount * opts.xAxis.labelCount);
+			} else {
+				maxXAxisListLength = opts.xAxis.labelCount;
+			}
+			maxXAxisListLength -= 1;
+		}
+
+		let ratio = Math.ceil(categories.length / maxXAxisListLength);
+
+		let newCategories = [];
+		let cgLength = categories.length;
+		for (let i = 0; i < cgLength; i++) {
+			if (i % ratio !== 0) {
+				newCategories.push("");
+			} else {
+				newCategories.push(categories[i]);
+			}
+		}
+		newCategories[cgLength - 1] = categories[cgLength - 1];
+
+		var xAxisFontSize = opts.xAxis.fontSize || config.fontSize;
+		if (config._xAxisTextAngle_ === 0) {
+			newCategories.forEach(function(item, index) {
+				var offset = -measureText(String(item), xAxisFontSize) / 2;
+				if (boundaryGap == 'center') {
+					offset += eachSpacing / 2;
+				}
+				var scrollHeight = 0;
+				if (opts.xAxis.scrollShow) {
+					scrollHeight = 6 * opts.pixelRatio;
+				}
+				context.beginPath();
+				context.setFontSize(xAxisFontSize);
+				context.setFillStyle(opts.xAxis.fontColor || '#666666');
+				context.fillText(String(item), xAxisPoints[index] + offset, startY + xAxisFontSize + (config.xAxisHeight -
+					scrollHeight - xAxisFontSize) / 2);
+				context.closePath();
+				context.stroke();
+			});
+
+		} else {
+			newCategories.forEach(function(item, index) {
+				context.save();
+				context.beginPath();
+				context.setFontSize(xAxisFontSize);
+				context.setFillStyle(opts.xAxis.fontColor || '#666666');
+				var textWidth = measureText(String(item), xAxisFontSize);
+				var offset = -textWidth;
+				if (boundaryGap == 'center') {
+					offset += eachSpacing / 2;
+				}
+				var _calRotateTranslate = calRotateTranslate(xAxisPoints[index] + eachSpacing / 2, startY + xAxisFontSize / 2 + 5,
+						opts.height),
+					transX = _calRotateTranslate.transX,
+					transY = _calRotateTranslate.transY;
+
+				context.rotate(-1 * config._xAxisTextAngle_);
+				context.translate(transX, transY);
+				context.fillText(String(item), xAxisPoints[index] + offset, startY + xAxisFontSize + 5);
+				context.closePath();
+				context.stroke();
+				context.restore();
+			});
+		}
+	}
+	context.restore();
+
+	//绘制X轴轴线
+	if (opts.xAxis.axisLine) {
+		context.beginPath();
+		context.setStrokeStyle(opts.xAxis.axisLineColor);
+		context.setLineWidth(1 * opts.pixelRatio);
+		context.moveTo(startX, opts.height - opts.area[2]);
+		context.lineTo(endX, opts.height - opts.area[2]);
+		context.stroke();
+	}
+}
+
+function drawYAxisGrid(categories, opts, config, context) {
+	if (opts.yAxis.disableGrid === true) {
+		return;
+	}
+	let spacingValid = opts.height - opts.area[0] - opts.area[2];
+	let eachSpacing = spacingValid / opts.yAxis.splitNumber;
+	let startX = opts.area[3];
+	let xAxisPoints = opts.chartData.xAxisData.xAxisPoints,
+		xAxiseachSpacing = opts.chartData.xAxisData.eachSpacing;
+	let TotalWidth = xAxiseachSpacing * (xAxisPoints.length - 1);
+	let endX = startX + TotalWidth;
+
+	let points = [];
+	for (let i = 0; i < opts.yAxis.splitNumber + 1; i++) {
+		points.push(opts.height - opts.area[2] - eachSpacing * i);
+	}
+
+	context.save();
+	if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
+		context.translate(opts._scrollDistance_, 0);
+	}
+
+	if (opts.yAxis.gridType == 'dash') {
+		context.setLineDash([opts.yAxis.dashLength, opts.yAxis.dashLength]);
+	}
+	context.setStrokeStyle(opts.yAxis.gridColor);
+	context.setLineWidth(1 * opts.pixelRatio);
+	points.forEach(function(item, index) {
+		context.beginPath();
+		context.moveTo(startX, item);
+		context.lineTo(endX, item);
+		context.stroke();
+	});
+	context.setLineDash([]);
+
+	context.restore();
+}
+
+function drawYAxis(series, opts, config, context) {
+	if (opts.yAxis.disabled === true) {
+		return;
+	}
+	var spacingValid = opts.height - opts.area[0] - opts.area[2];
+	var eachSpacing = spacingValid / opts.yAxis.splitNumber;
+	var startX = opts.area[3];
+	var endX = opts.width - opts.area[1];
+	var endY = opts.height - opts.area[2];
+	var fillEndY = endY + config.xAxisHeight;
+	if (opts.xAxis.scrollShow) {
+		fillEndY -= 3 * opts.pixelRatio;
+	}
+	if (opts.xAxis.rotateLabel) {
+		fillEndY = opts.height - opts.area[2] + 3;
+	}
+	// set YAxis background
+	context.beginPath();
+	context.setFillStyle(opts.background || '#ffffff');
+	if (opts._scrollDistance_ < 0) {
+		context.fillRect(0, 0, startX, fillEndY);
+	}
+	if (opts.enableScroll == true) {
+		context.fillRect(endX, 0, opts.width, fillEndY);
+	}
+	context.closePath();
+	context.stroke();
+
+	var points = [];
+	for (let i = 0; i <= opts.yAxis.splitNumber; i++) {
+		points.push(opts.area[0] + eachSpacing * i);
+	}
+
+	let tStartLeft = opts.area[3];
+	let tStartRight = opts.width - opts.area[1];
+
+	for (let i = 0; i < opts.yAxis.data.length; i++) {
+		let yData = opts.yAxis.data[i];
+		if (yData.disabled !== true) {
+			let rangesFormat = opts.chartData.yAxisData.rangesFormat[i];
+			let yAxisFontSize = yData.fontSize || config.fontSize;
+			let yAxisWidth = opts.chartData.yAxisData.yAxisWidth[i];
+			//画Y轴刻度及文案
+			rangesFormat.forEach(function(item, index) {
+				var pos = points[index] ? points[index] : endY;
+				context.beginPath();
+				context.setFontSize(yAxisFontSize);
+				context.setLineWidth(1 * opts.pixelRatio);
+				context.setStrokeStyle(yData.axisLineColor || '#cccccc');
+				context.setFillStyle(yData.fontColor || '#666666');
+				if (yAxisWidth.position == 'left') {
+					context.fillText(String(item), tStartLeft - yAxisWidth.width, pos + yAxisFontSize / 2);
+					//画刻度线
+					if (yData.calibration == true) {
+						context.moveTo(tStartLeft, pos);
+						context.lineTo(tStartLeft - 3 * opts.pixelRatio, pos);
+					}
+				} else {
+					context.fillText(String(item), tStartRight + 4 * opts.pixelRatio, pos + yAxisFontSize / 2);
+					//画刻度线
+					if (yData.calibration == true) {
+						context.moveTo(tStartRight, pos);
+						context.lineTo(tStartRight + 3 * opts.pixelRatio, pos);
+					}
+				}
+				context.closePath();
+				context.stroke();
+			});
+			//画Y轴轴线
+			if (yData.axisLine !== false && !opts.yAxis.disableLine) {
+				context.beginPath();
+				context.setStrokeStyle(yData.axisLineColor || '#cccccc');
+				context.setLineWidth(1 * opts.pixelRatio);
+				if (yAxisWidth.position == 'left') {
+					context.moveTo(tStartLeft, opts.height - opts.area[2]);
+					context.lineTo(tStartLeft, opts.area[0]);
+				} else {
+					context.moveTo(tStartRight, opts.height - opts.area[2]);
+					context.lineTo(tStartRight, opts.area[0]);
+				}
+				context.stroke();
+			}
+
+			//画Y轴标题
+			if (opts.yAxis.showTitle) {
+
+				let titleFontSize = yData.titleFontSize || config.fontSize;
+				let title = yData.title;
+				context.beginPath();
+				context.setFontSize(titleFontSize);
+				context.setFillStyle(yData.titleFontColor || '#666666');
+				if (yAxisWidth.position == 'left') {
+					context.fillText(title, tStartLeft - measureText(title, titleFontSize) / 2, opts.area[0] - 10 * opts.pixelRatio);
+				} else {
+					context.fillText(title, tStartRight - measureText(title, titleFontSize) / 2, opts.area[0] - 10 * opts.pixelRatio);
+				}
+				context.closePath();
+				context.stroke();
+			}
+			if (yAxisWidth.position == 'left') {
+				tStartLeft -= (yAxisWidth.width + opts.yAxis.padding);
+			} else {
+				tStartRight += yAxisWidth.width + opts.yAxis.padding;
+			}
+		}
+	}
+}
+
+function drawLegend(series, opts, config, context, chartData) {
+	if (opts.legend.show === false) {
+		return;
+	}
+	let legendData = chartData.legendData;
+	let legendList = legendData.points;
+	let legendArea = legendData.area;
+	let padding = opts.legend.padding;
+	let fontSize = opts.legend.fontSize;
+	let shapeWidth = 15 * opts.pixelRatio;
+	let shapeRight = 5 * opts.pixelRatio;
+	let itemGap = opts.legend.itemGap;
+	let lineHeight = Math.max(opts.legend.lineHeight * opts.pixelRatio, fontSize);
+
+	//画背景及边框
+	context.beginPath();
+	context.setLineWidth(opts.legend.borderWidth);
+	context.setStrokeStyle(opts.legend.borderColor);
+	context.setFillStyle(opts.legend.backgroundColor);
+	context.moveTo(legendArea.start.x, legendArea.start.y);
+	context.rect(legendArea.start.x, legendArea.start.y, legendArea.width, legendArea.height);
+	context.closePath();
+	context.fill();
+	context.stroke();
+
+	legendList.forEach(function(itemList, listIndex) {
+		let width = 0;
+		let height = 0;
+		width = legendData.widthArr[listIndex];
+		height = legendData.heightArr[listIndex];
+		let startX = 0;
+		let startY = 0;
+		if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+			startX = legendArea.start.x + (legendArea.width - width) / 2;
+			startY = legendArea.start.y + padding + listIndex * lineHeight;
+		} else {
+			if (listIndex == 0) {
+				width = 0;
+			} else {
+				width = legendData.widthArr[listIndex - 1];
+			}
+			startX = legendArea.start.x + padding + width;
+			startY = legendArea.start.y + padding + (legendArea.height - height) / 2;
+		}
+
+		context.setFontSize(config.fontSize);
+		for (let i = 0; i < itemList.length; i++) {
+			let item = itemList[i];
+			item.area = [0, 0, 0, 0];
+			item.area[0] = startX;
+			item.area[1] = startY;
+			item.area[3] = startY + lineHeight;
+			context.beginPath();
+			context.setLineWidth(1 * opts.pixelRatio);
+			context.setStrokeStyle(item.show ? item.color : opts.legend.hiddenColor);
+			context.setFillStyle(item.show ? item.color : opts.legend.hiddenColor);
+			switch (item.legendShape) {
+				case 'line':
+					context.moveTo(startX, startY + 0.5 * lineHeight - 2 * opts.pixelRatio);
+					context.fillRect(startX, startY + 0.5 * lineHeight - 2 * opts.pixelRatio, 15 * opts.pixelRatio, 4 * opts.pixelRatio);
+					break;
+				case 'triangle':
+					context.moveTo(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight - 5 * opts.pixelRatio);
+					context.lineTo(startX + 2.5 * opts.pixelRatio, startY + 0.5 * lineHeight + 5 * opts.pixelRatio);
+					context.lineTo(startX + 12.5 * opts.pixelRatio, startY + 0.5 * lineHeight + 5 * opts.pixelRatio);
+					context.lineTo(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight - 5 * opts.pixelRatio);
+					break;
+				case 'diamond':
+					context.moveTo(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight - 5 * opts.pixelRatio);
+					context.lineTo(startX + 2.5 * opts.pixelRatio, startY + 0.5 * lineHeight);
+					context.lineTo(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight + 5 * opts.pixelRatio);
+					context.lineTo(startX + 12.5 * opts.pixelRatio, startY + 0.5 * lineHeight);
+					context.lineTo(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight - 5 * opts.pixelRatio);
+					break;
+				case 'circle':
+					context.moveTo(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight);
+					context.arc(startX + 7.5 * opts.pixelRatio, startY + 0.5 * lineHeight, 5 * opts.pixelRatio, 0, 2 * Math.PI);
+					break;
+				case 'rect':
+					context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pixelRatio);
+					context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pixelRatio, 15 * opts.pixelRatio, 10 * opts.pixelRatio);
+					break;
+				default:
+					context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pixelRatio);
+					context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pixelRatio, 15 * opts.pixelRatio, 10 * opts.pixelRatio);
+			}
+			context.closePath();
+			context.fill();
+			context.stroke();
+
+			startX += shapeWidth + shapeRight;
+			let fontTrans = 0.5 * lineHeight + 0.5 * fontSize - 2;
+			context.beginPath();
+			context.setFontSize(fontSize);
+			context.setFillStyle(item.show ? opts.legend.fontColor : opts.legend.hiddenColor);
+			context.fillText(item.name, startX, startY + fontTrans);
+			context.closePath();
+			context.stroke();
+			if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+				startX += measureText(item.name, fontSize) + itemGap;
+				item.area[2] = startX;
+			} else {
+				item.area[2] = startX + measureText(item.name, fontSize) + itemGap;;
+				startX -= shapeWidth + shapeRight;
+				startY += lineHeight;
+			}
+		}
+	});
+}
+
+function drawPieDataPoints(series, opts, config, context) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var pieOption = assign({}, {
+		activeOpacity: 0.5,
+		activeRadius: 10 * opts.pixelRatio,
+		offsetAngle: 0,
+		labelWidth: 15 * opts.pixelRatio,
+		ringWidth: 0,
+		border: false,
+		borderWidth: 2,
+		borderColor: '#FFFFFF'
+	}, opts.extra.pie);
+	var centerPosition = {
+		x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+		y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+	};
+	if (config.pieChartLinePadding == 0) {
+		config.pieChartLinePadding = pieOption.activeRadius;
+	}
+
+	var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding -
+		config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding
+	);
+
+	series = getPieDataPoints(series, radius, process);
+
+	var activeRadius = pieOption.activeRadius;
+
+	series = series.map(function(eachSeries) {
+		eachSeries._start_ += (pieOption.offsetAngle) * Math.PI / 180;
+		return eachSeries;
+	});
+	series.forEach(function(eachSeries, seriesIndex) {
+		if (opts.tooltip) {
+			if (opts.tooltip.index == seriesIndex) {
+				context.beginPath();
+				context.setFillStyle(hexToRgb(eachSeries.color, opts.extra.pie.activeOpacity || 0.5));
+				context.moveTo(centerPosition.x, centerPosition.y);
+				context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_ + activeRadius, eachSeries._start_,
+					eachSeries._start_ + 2 *
+					eachSeries._proportion_ * Math.PI);
+				context.closePath();
+				context.fill();
+			}
+		}
+		context.beginPath();
+		context.setLineWidth(pieOption.borderWidth * opts.pixelRatio);
+		context.lineJoin = "round";
+		context.setStrokeStyle(pieOption.borderColor);
+		context.setFillStyle(eachSeries.color);
+		context.moveTo(centerPosition.x, centerPosition.y);
+		context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 *
+			eachSeries._proportion_ * Math.PI);
+		context.closePath();
+		context.fill();
+		if (pieOption.border == true) {
+			context.stroke();
+		}
+	});
+
+	if (opts.type === 'ring') {
+		var innerPieWidth = radius * 0.6;
+		if (typeof opts.extra.pie.ringWidth === 'number' && opts.extra.pie.ringWidth > 0) {
+			innerPieWidth = Math.max(0, radius - opts.extra.pie.ringWidth);
+		}
+		context.beginPath();
+		context.setFillStyle(opts.background || '#ffffff');
+		context.moveTo(centerPosition.x, centerPosition.y);
+		context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI);
+		context.closePath();
+		context.fill();
+	}
+
+	if (opts.dataLabel !== false && process === 1) {
+		var valid = false;
+		for (var i = 0, len = series.length; i < len; i++) {
+			if (series[i].data > 0) {
+				valid = true;
+				break;
+			}
+		}
+
+		if (valid) {
+			drawPieText(series, opts, config, context, radius, centerPosition);
+		}
+	}
+
+	if (process === 1 && opts.type === 'ring') {
+		drawRingTitle(opts, config, context, centerPosition);
+	}
+
+	return {
+		center: centerPosition,
+		radius: radius,
+		series: series
+	};
+}
+
+function drawRoseDataPoints(series, opts, config, context) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var roseOption = assign({}, {
+		type: 'area',
+		activeOpacity: 0.5,
+		activeRadius: 10 * opts.pixelRatio,
+		offsetAngle: 0,
+		labelWidth: 15 * opts.pixelRatio,
+		border: false,
+		borderWidth: 2,
+		borderColor: '#FFFFFF'
+	}, opts.extra.rose);
+	if (config.pieChartLinePadding == 0) {
+		config.pieChartLinePadding = roseOption.activeRadius;
+	}
+	var centerPosition = {
+		x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+		y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+	};
+	var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding -
+		config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding
+	);
+	var minRadius = roseOption.minRadius || radius * 0.5;
+
+	series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process);
+
+	var activeRadius = roseOption.activeRadius;
+
+	series = series.map(function(eachSeries) {
+		eachSeries._start_ += (roseOption.offsetAngle || 0) * Math.PI / 180;
+		return eachSeries;
+	});
+
+	series.forEach(function(eachSeries, seriesIndex) {
+		if (opts.tooltip) {
+			if (opts.tooltip.index == seriesIndex) {
+				context.beginPath();
+				context.setFillStyle(hexToRgb(eachSeries.color, roseOption.activeOpacity || 0.5));
+				context.moveTo(centerPosition.x, centerPosition.y);
+				context.arc(centerPosition.x, centerPosition.y, activeRadius + eachSeries._radius_, eachSeries._start_,
+					eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI);
+				context.closePath();
+				context.fill();
+			}
+		}
+		context.beginPath();
+		context.setLineWidth(roseOption.borderWidth * opts.pixelRatio);
+		context.lineJoin = "round";
+		context.setStrokeStyle(roseOption.borderColor);
+		context.setFillStyle(eachSeries.color);
+		context.moveTo(centerPosition.x, centerPosition.y);
+		context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 *
+			eachSeries._rose_proportion_ * Math.PI);
+		context.closePath();
+		context.fill();
+		if (roseOption.border == true) {
+			context.stroke();
+		}
+	});
+
+	if (opts.dataLabel !== false && process === 1) {
+		var valid = false;
+		for (var i = 0, len = series.length; i < len; i++) {
+			if (series[i].data > 0) {
+				valid = true;
+				break;
+			}
+		}
+
+		if (valid) {
+			drawPieText(series, opts, config, context, radius, centerPosition);
+		}
+	}
+
+	return {
+		center: centerPosition,
+		radius: radius,
+		series: series
+	};
+}
+
+function drawMyArcbarDataPoints(series, opts, config, context) {
+	var title = opts.title.name || '';
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var arcbarOption = assign({}, {
+		startAngle: 0.75,
+		endAngle: 0.25,
+		type: 'default',
+		width: 12 * opts.pixelRatio,
+		gap: 2 * opts.pixelRatio
+	}, opts.extra.arcbar);
+
+	series = getArcbarDataPoints(series, arcbarOption, process);
+
+	var centerPosition;
+	if (arcbarOption.center) {
+		centerPosition = arcbarOption.center;
+	} else {
+		centerPosition = {
+			x: opts.width / 2,
+			y: opts.height / 2
+		};
+	}
+
+	var radius;
+	if (arcbarOption.radius) {
+		radius = arcbarOption.radius;
+	} else {
+		radius = Math.min(centerPosition.x, centerPosition.y);
+		radius -= 5 * opts.pixelRatio;
+		radius -= arcbarOption.width / 2;
+	}
+	//偏移
+	centerPosition.x += 20;
+	centerPosition.y += 10;
+	//中心圆形背景
+	var innerRadius = radius - arcbarOption.width;
+	var pieRadius = radius - arcbarOption.width * 2;
+	context.beginPath();
+	// let gradient = context.createLinearGradient(
+	// 	centerPosition.x,
+	// 	centerPosition.y - pieRadius,
+	// 	centerPosition.x,
+	// 	centerPosition.y + pieRadius);
+
+	// //配置渐变填充(起点:中心点向上减半径;结束点中心点向下加半径)
+	// gradient.addColorStop('0', hexToRgb(series[0].color, 0.3));
+	// gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+	context.setFillStyle(arcbarOption.backgroundMiddle);
+	context.arc(centerPosition.x, centerPosition.y, pieRadius, 0, 2 * Math.PI, false);
+	context.fill();
+	//画进度条背景
+	// context.setLineWidth(arcbarOption.width);
+	// context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+	// context.setLineCap('round');
+	// context.beginPath();
+	// context.arc(centerPosition.x, centerPosition.y, innerRadius, arcbarOption.startAngle * Math.PI,
+	//  arcbarOption.endAngle *
+	// 	Math.PI, false);
+	// context.stroke();
+
+	for (let i = 0; i < series.length; i++) {
+		let eachSeries = series[i];
+		//背景颜色
+		// 创建线性渐变
+		var grd = context.createLinearGradient(0, 0, 0, opts.height);
+		grd.addColorStop(0, arcbarOption.backgroundColor);
+		grd.addColorStop(0.5, arcbarOption.backgroundColor);
+		grd.addColorStop(0.8, arcbarOption.backgroundEndColor);
+		// 填充渐变
+		context.setLineWidth(arcbarOption.width * 0.3);
+		context.setStrokeStyle(grd || '#E9E9E9');
+		context.setLineCap('round');
+		context.beginPath();
+		let _radius = radius - (arcbarOption.width + arcbarOption.gap) * i;
+		if (arcbarOption.type == 'default') {
+			context.arc(centerPosition.x, centerPosition.y, _radius, arcbarOption.startAngle *
+				Math.PI, arcbarOption.endAngle * Math.PI, false);
+		} else {
+			context.arc(centerPosition.x, centerPosition.y, _radius, 0, 2 * Math.PI,
+				false);
+		}
+		context.stroke();
+		//进度条
+		var grd2 = context.createLinearGradient(0, 0, 0, opts.height);
+		grd2.addColorStop(0, arcbarOption.lineColor);
+		grd2.addColorStop(0.75, arcbarOption.lineColor);
+		grd2.addColorStop(0.8, arcbarOption.lineEndColor);
+
+		context.setLineWidth(arcbarOption.width);
+		context.setStrokeStyle(grd2 || '#E9E9E9');
+		context.setLineCap('round');
+		context.beginPath();
+		context.arc(centerPosition.x, centerPosition.y, _radius, arcbarOption.startAngle *
+			Math.PI, eachSeries._proportion_ * Math.PI, false);
+
+		context.stroke();
+
+		//绘制顶点圆
+		if (title) {
+			context.setLineWidth(arcbarOption.width * 0.3);
+			context.setStrokeStyle('rgba(142, 142, 251, 255)');
+			context.setLineCap('round');
+			context.beginPath();
+
+			let _endPointX = Math.cos(eachSeries._proportion_ * Math.PI) * _radius + centerPosition.x;
+			let _endPointY = Math.sin(eachSeries._proportion_ * Math.PI) * _radius + centerPosition.y;
+			context.arc(_endPointX, _endPointY, 1, 0, 2 * Math.PI, false);
+			context.fillStyle = 'rgba(142, 142, 251, 255)';
+			context.fill();
+			context.stroke();
+		}
+
+	}
+
+	//绘制提示点
+	context.setLineWidth(6);
+	context.setStrokeStyle('#E9E9E9');
+	context.setLineCap('round');
+	let _radius = radius + (arcbarOption.width + arcbarOption.gap) * 2;
+	let _tipPointX = 0;
+	let _tipPointY = 0;
+	for (let i = 0, j = -1.2; i < 5; i++, j += 0.35) {
+		// 左边第一个点
+		context.beginPath();
+		_tipPointX = Math.cos(j * Math.PI) * (_radius - 5) + centerPosition.x;
+		_tipPointY = Math.sin(j * Math.PI) * (_radius - 5) + centerPosition.y;
+		context.arc(_tipPointX, _tipPointY, 1, 0, 2 * Math.PI, false);
+		// context.fill();
+		context.stroke();
+	}
+
+	//提示点圆环
+	context.setLineWidth(1);
+	context.setStrokeStyle(hexToRgb('#E9E9E9', 0.2));
+	context.setLineCap('round');
+	context.beginPath();
+	context.arc(centerPosition.x, centerPosition.y, _radius - 5,
+		arcbarOption.startAngle * Math.PI,
+		arcbarOption.endAngle * Math.PI, false);
+	context.stroke();
+
+	drawMyRingTitle(opts, config, context, centerPosition);
+	return {
+		center: centerPosition,
+		radius: radius,
+		series: series
+	};
+}
+
+function drawArcbarDataPoints(series, opts, config, context) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var arcbarOption = assign({}, {
+		startAngle: 0.75,
+		endAngle: 0.25,
+		type: 'default',
+		width: 12 * opts.pixelRatio,
+		gap: 2 * opts.pixelRatio
+	}, opts.extra.arcbar);
+
+	series = getArcbarDataPoints(series, arcbarOption, process);
+
+	var centerPosition;
+	if (arcbarOption.center) {
+		centerPosition = arcbarOption.center;
+	} else {
+		centerPosition = {
+			x: opts.width / 2,
+			y: opts.height / 2
+		};
+	}
+
+	var radius;
+	if (arcbarOption.radius) {
+		radius = arcbarOption.radius;
+	} else {
+		radius = Math.min(centerPosition.x, centerPosition.y);
+		radius -= 5 * opts.pixelRatio;
+		radius -= arcbarOption.width / 2;
+	}
+
+	for (let i = 0; i < series.length; i++) {
+		let eachSeries = series[i];
+		//背景颜色
+		context.setLineWidth(arcbarOption.width);
+		context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9');
+		context.setLineCap('round');
+		context.beginPath();
+		if (arcbarOption.type == 'default') {
+			context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap) * i, arcbarOption.startAngle *
+				Math.PI, arcbarOption.endAngle * Math.PI, false);
+		} else {
+			context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap) * i, 0, 2 * Math.PI,
+				false);
+		}
+		context.stroke();
+		//进度条
+		context.setLineWidth(arcbarOption.width);
+		context.setStrokeStyle(eachSeries.color);
+		context.setLineCap('round');
+		context.beginPath();
+		context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width + arcbarOption.gap) * i, arcbarOption.startAngle *
+			Math.PI, eachSeries._proportion_ * Math.PI, false);
+		context.stroke();
+	}
+
+	drawRingTitle(opts, config, context, centerPosition);
+
+	return {
+		center: centerPosition,
+		radius: radius,
+		series: series
+	};
+}
+
+function drawGaugeDataPoints(categories, series, opts, config, context) {
+	var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+	var gaugeOption = assign({}, {
+		type: 'default',
+		startAngle: 0.75,
+		endAngle: 0.25,
+		width: 15,
+		splitLine: {
+			fixRadius: 0,
+			splitNumber: 10,
+			width: 15,
+			color: '#FFFFFF',
+			childNumber: 5,
+			childWidth: 5
+		},
+		pointer: {
+			width: 15,
+			color: 'auto'
+		}
+	}, opts.extra.gauge);
+
+	if (gaugeOption.oldAngle == undefined) {
+		gaugeOption.oldAngle = gaugeOption.startAngle;
+	}
+	if (gaugeOption.oldData == undefined) {
+		gaugeOption.oldData = 0;
+	}
+	categories = getGaugeAxisPoints(categories, gaugeOption.startAngle, gaugeOption.endAngle);
+
+	var centerPosition = {
+		x: opts.width / 2,
+		y: opts.height / 2
+	};
+	var radius = Math.min(centerPosition.x, centerPosition.y);
+	radius -= 5 * opts.pixelRatio;
+	radius -= gaugeOption.width / 2;
+	var innerRadius = radius - gaugeOption.width;
+	var totalAngle = 0;
+
+	//判断仪表盘的样式:default百度样式,progress新样式
+	if (gaugeOption.type == 'progress') {
+
+		//## 第一步画中心圆形背景和进度条背景
+		//中心圆形背景
+		var pieRadius = radius - gaugeOption.width * 3;
+		context.beginPath();
+		let gradient = context.createLinearGradient(centerPosition.x, centerPosition.y - pieRadius, centerPosition.x,
+			centerPosition.y + pieRadius);
+		//配置渐变填充(起点:中心点向上减半径;结束点中心点向下加半径)
+		gradient.addColorStop('0', hexToRgb(series[0].color, 0.3));
+		gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+		context.setFillStyle(gradient);
+		context.arc(centerPosition.x, centerPosition.y, pieRadius, 0, 2 * Math.PI, false);
+		context.fill();
+		//画进度条背景
+		context.setLineWidth(gaugeOption.width);
+		context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+		context.setLineCap('round');
+		context.beginPath();
+		context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, gaugeOption.endAngle *
+			Math.PI, false);
+		context.stroke();
+
+		//## 第二步画刻度线
+		totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
+		let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+		let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
+		let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
+		let endX = -radius - gaugeOption.width - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
+		context.save();
+		context.translate(centerPosition.x, centerPosition.y);
+		context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+		let len = gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1;
+		let proc = series[0].data * process;
+		for (let i = 0; i < len; i++) {
+			context.beginPath();
+			//刻度线随进度变色
+			if (proc > (i / len)) {
+				context.setStrokeStyle(hexToRgb(series[0].color, 1));
+			} else {
+				context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+			}
+			context.setLineWidth(3 * opts.pixelRatio);
+			context.moveTo(startX, 0);
+			context.lineTo(endX, 0);
+			context.stroke();
+			context.rotate(childAngle * Math.PI);
+		}
+		context.restore();
+
+		//## 第三步画进度条
+		series = getArcbarDataPoints(series, gaugeOption, process);
+		context.setLineWidth(gaugeOption.width);
+		context.setStrokeStyle(series[0].color);
+		context.setLineCap('round');
+		context.beginPath();
+		context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, series[0]._proportion_ *
+			Math.PI, false);
+		context.stroke();
+
+		//## 第四步画指针
+		let pointerRadius = radius - gaugeOption.width * 2.5;
+		context.save();
+		context.translate(centerPosition.x, centerPosition.y);
+		context.rotate((series[0]._proportion_ - 1) * Math.PI);
+		context.beginPath();
+		context.setLineWidth(gaugeOption.width / 3);
+		let gradient3 = context.createLinearGradient(0, -pointerRadius * 0.6, 0, pointerRadius * 0.6);
+		gradient3.addColorStop('0', hexToRgb('#FFFFFF', 0));
+		gradient3.addColorStop('0.5', hexToRgb(series[0].color, 1));
+		gradient3.addColorStop('1.0', hexToRgb('#FFFFFF', 0));
+		context.setStrokeStyle(gradient3);
+		context.arc(0, 0, pointerRadius, 0.85 * Math.PI, 1.15 * Math.PI, false);
+		context.stroke();
+		context.beginPath();
+		context.setLineWidth(1);
+		context.setStrokeStyle(series[0].color);
+		context.setFillStyle(series[0].color);
+		context.moveTo(-pointerRadius - gaugeOption.width / 3 / 2, -4);
+		context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2 - 4, 0);
+		context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, 4);
+		context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, -4);
+		context.stroke();
+		context.fill();
+		context.restore();
+
+		//default百度样式
+	} else {
+		//画背景
+		context.setLineWidth(gaugeOption.width);
+		context.setLineCap('butt');
+		for (let i = 0; i < categories.length; i++) {
+			let eachCategories = categories[i];
+			context.beginPath();
+			context.setStrokeStyle(eachCategories.color);
+			context.arc(centerPosition.x, centerPosition.y, radius, eachCategories._startAngle_ * Math.PI, eachCategories._endAngle_ *
+				Math.PI, false);
+			context.stroke();
+		}
+		context.save();
+
+		//画刻度线
+		totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
+		let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+		let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
+		let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
+		let endX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
+		let childendX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.childWidth;
+
+		context.translate(centerPosition.x, centerPosition.y);
+		context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+
+		for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
+			context.beginPath();
+			context.setStrokeStyle(gaugeOption.splitLine.color);
+			context.setLineWidth(2 * opts.pixelRatio);
+			context.moveTo(startX, 0);
+			context.lineTo(endX, 0);
+			context.stroke();
+			context.rotate(splitAngle * Math.PI);
+		}
+		context.restore();
+
+		context.save();
+		context.translate(centerPosition.x, centerPosition.y);
+		context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+
+		for (let i = 0; i < gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1; i++) {
+			context.beginPath();
+			context.setStrokeStyle(gaugeOption.splitLine.color);
+			context.setLineWidth(1 * opts.pixelRatio);
+			context.moveTo(startX, 0);
+			context.lineTo(childendX, 0);
+			context.stroke();
+			context.rotate(childAngle * Math.PI);
+		}
+		context.restore();
+
+		//画指针
+		series = getGaugeDataPoints(series, categories, gaugeOption, process);
+
+		for (let i = 0; i < series.length; i++) {
+			let eachSeries = series[i];
+			context.save();
+			context.translate(centerPosition.x, centerPosition.y);
+			context.rotate((eachSeries._proportion_ - 1) * Math.PI);
+			context.beginPath();
+			context.setFillStyle(eachSeries.color);
+			context.moveTo(gaugeOption.pointer.width, 0);
+			context.lineTo(0, -gaugeOption.pointer.width / 2);
+			context.lineTo(-innerRadius, 0);
+			context.lineTo(0, gaugeOption.pointer.width / 2);
+			context.lineTo(gaugeOption.pointer.width, 0);
+			context.closePath();
+			context.fill();
+			context.beginPath();
+			context.setFillStyle('#FFFFFF');
+			context.arc(0, 0, gaugeOption.pointer.width / 6, 0, 2 * Math.PI, false);
+			context.fill();
+			context.restore();
+		}
+
+		if (opts.dataLabel !== false) {
+			drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context);
+		}
+	}
+
+	//画仪表盘标题,副标题
+	drawRingTitle(opts, config, context, centerPosition);
+
+	if (process === 1 && opts.type === 'gauge') {
+		opts.extra.gauge.oldAngle = series[0]._proportion_;
+		opts.extra.gauge.oldData = series[0].data;
+	}
+	return {
+		center: centerPosition,
+		radius: radius,
+		innerRadius: innerRadius,
+		categories: categories,
+		totalAngle: totalAngle
+	};
+}
+
+function drawRadarDataPoints(series, opts, config, context) {
+	var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	var radarOption = assign({}, {
+		gridColor: '#cccccc',
+		labelColor: '#666666',
+		opacity: 0.2,
+		gridCount: 3
+	}, opts.extra.radar);
+
+	var coordinateAngle = getRadarCoordinateSeries(opts.categories.length);
+
+	var centerPosition = {
+		x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+		y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+	};
+
+	var radius = Math.min(centerPosition.x - (getMaxTextListLength(opts.categories) + config.radarLabelTextMargin),
+		centerPosition.y - config.radarLabelTextMargin);
+	//TODO逻辑不对
+	radius -= opts.padding[1];
+
+	// draw grid
+	context.beginPath();
+	context.setLineWidth(1 * opts.pixelRatio);
+	context.setStrokeStyle(radarOption.gridColor);
+	coordinateAngle.forEach(function(angle) {
+		var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition);
+		context.moveTo(centerPosition.x, centerPosition.y);
+		context.lineTo(pos.x, pos.y);
+	});
+	context.stroke();
+	context.closePath();
+	// draw split line grid
+
+	var _loop = function _loop(i) {
+		var startPos = {};
+		context.beginPath();
+		context.setLineWidth(1 * opts.pixelRatio);
+		context.setStrokeStyle(radarOption.gridColor);
+		coordinateAngle.forEach(function(angle, index) {
+			var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(angle), radius / radarOption.gridCount *
+				i * Math.sin(angle), centerPosition);
+			if (index === 0) {
+				startPos = pos;
+				context.moveTo(pos.x, pos.y);
+			} else {
+				context.lineTo(pos.x, pos.y);
+			}
+		});
+		context.lineTo(startPos.x, startPos.y);
+		context.stroke();
+		context.closePath();
+	};
+
+	for (var i = 1; i <= radarOption.gridCount; i++) {
+		_loop(i);
+	}
+
+	var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process);
+
+	radarDataPoints.forEach(function(eachSeries, seriesIndex) {
+		// 绘制区域数据
+		context.beginPath();
+		context.setFillStyle(hexToRgb(eachSeries.color, radarOption.opacity));
+		eachSeries.data.forEach(function(item, index) {
+			if (index === 0) {
+				context.moveTo(item.position.x, item.position.y);
+			} else {
+				context.lineTo(item.position.x, item.position.y);
+			}
+		});
+		context.closePath();
+		context.fill();
+
+		if (opts.dataPointShape !== false) {
+			var points = eachSeries.data.map(function(item) {
+				return item.position;
+			});
+			drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+		}
+	});
+	// draw label text
+	drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context);
+
+	return {
+		center: centerPosition,
+		radius: radius,
+		angleList: coordinateAngle
+	};
+}
+
+function normalInt(min, max, iter) {
+	iter = iter == 0 ? 1 : iter;
+	var arr = [];
+	for (var i = 0; i < iter; i++) {
+		arr[i] = Math.random();
+	};
+	return Math.floor(arr.reduce(function(i, j) {
+		return i + j
+	}) / iter * (max - min)) + min;
+};
+
+function collisionNew(area, points, width, height) {
+	var isIn = false;
+	for (let i = 0; i < points.length; i++) {
+		if (points[i].area) {
+			if (area[3] < points[i].area[1] || area[0] > points[i].area[2] || area[1] > points[i].area[3] || area[2] < points[i]
+				.area[0]) {
+				if (area[0] < 0 || area[1] < 0 || area[2] > width || area[3] > height) {
+					isIn = true;
+					break;
+				} else {
+					isIn = false;
+				}
+			} else {
+				isIn = true;
+				break;
+			}
+		}
+	}
+	return isIn;
+};
+
+function getBoundingBox(data) {
+	var bounds = {},
+		coords;
+	bounds.xMin = 180;
+	bounds.xMax = 0;
+	bounds.yMin = 90;
+	bounds.yMax = 0
+	for (var i = 0; i < data.length; i++) {
+		var coorda = data[i].geometry.coordinates
+		for (var k = 0; k < coorda.length; k++) {
+			coords = coorda[k];
+			if (coords.length == 1) {
+				coords = coords[0]
+			}
+			for (var j = 0; j < coords.length; j++) {
+				var longitude = coords[j][0];
+				var latitude = coords[j][1];
+				var point = {
+					x: longitude,
+					y: latitude
+				}
+				bounds.xMin = bounds.xMin < point.x ? bounds.xMin : point.x;
+				bounds.xMax = bounds.xMax > point.x ? bounds.xMax : point.x;
+				bounds.yMin = bounds.yMin < point.y ? bounds.yMin : point.y;
+				bounds.yMax = bounds.yMax > point.y ? bounds.yMax : point.y;
+			}
+		}
+	}
+	return bounds;
+}
+
+function coordinateToPoint(latitude, longitude, bounds, scale, xoffset, yoffset) {
+	return {
+		x: (longitude - bounds.xMin) * scale + xoffset,
+		y: (bounds.yMax - latitude) * scale + yoffset
+	};
+}
+
+function pointToCoordinate(pointY, pointX, bounds, scale, xoffset, yoffset) {
+	return {
+		x: (pointX - xoffset) / scale + bounds.xMin,
+		y: bounds.yMax - (pointY - yoffset) / scale
+	};
+}
+
+function isRayIntersectsSegment(poi, s_poi, e_poi) {
+	if (s_poi[1] == e_poi[1]) {
+		return false;
+	}
+	if (s_poi[1] > poi[1] && e_poi[1] > poi[1]) {
+		return false;
+	}
+	if (s_poi[1] < poi[1] && e_poi[1] < poi[1]) {
+		return false;
+	}
+	if (s_poi[1] == poi[1] && e_poi[1] > poi[1]) {
+		return false;
+	}
+	if (e_poi[1] == poi[1] && s_poi[1] > poi[1]) {
+		return false;
+	}
+	if (s_poi[0] < poi[0] && e_poi[1] < poi[1]) {
+		return false;
+	}
+	let xseg = e_poi[0] - (e_poi[0] - s_poi[0]) * (e_poi[1] - poi[1]) / (e_poi[1] - s_poi[1]);
+	if (xseg < poi[0]) {
+		return false;
+	} else {
+		return true;
+	}
+}
+
+function isPoiWithinPoly(poi, poly) {
+	let sinsc = 0;
+	for (let i = 0; i < poly.length; i++) {
+		let epoly = poly[i][0];
+		if (poly.length == 1) {
+			epoly = poly[i][0]
+		}
+		for (let j = 0; j < epoly.length - 1; j++) {
+			let s_poi = epoly[j];
+			let e_poi = epoly[j + 1];
+			if (isRayIntersectsSegment(poi, s_poi, e_poi)) {
+				sinsc += 1;
+			}
+		}
+	}
+
+	if (sinsc % 2 == 1) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+
+function drawMapDataPoints(series, opts, config, context) {
+	var mapOption = assign({}, {
+		border: true,
+		borderWidth: 1,
+		borderColor: '#666666',
+		fillOpacity: 0.6,
+		activeBorderColor: '#f04864',
+		activeFillColor: '#facc14',
+		activeFillOpacity: 1
+	}, opts.extra.map);
+	var coords, point;
+	var data = series;
+	var bounds = getBoundingBox(data);
+	var xScale = opts.width / Math.abs(bounds.xMax - bounds.xMin);
+	var yScale = opts.height / Math.abs(bounds.yMax - bounds.yMin);
+	var scale = xScale < yScale ? xScale : yScale;
+	var xoffset = opts.width / 2 - Math.abs(bounds.xMax - bounds.xMin) / 2 * scale;
+	var yoffset = opts.height / 2 - Math.abs(bounds.yMax - bounds.yMin) / 2 * scale;
+	context.beginPath();
+	context.clearRect(0, 0, opts.width, opts.height);
+	context.setFillStyle(opts.background || '#FFFFFF');
+	context.rect(0, 0, opts.width, opts.height);
+	context.fill();
+	for (var i = 0; i < data.length; i++) {
+		context.beginPath();
+		context.setLineWidth(mapOption.borderWidth * opts.pixelRatio);
+		context.setStrokeStyle(mapOption.borderColor);
+		context.setFillStyle(hexToRgb(series[i].color, mapOption.fillOpacity));
+		if (opts.tooltip) {
+			if (opts.tooltip.index == i) {
+				context.setStrokeStyle(mapOption.activeBorderColor);
+				context.setFillStyle(hexToRgb(mapOption.activeFillColor, mapOption.activeFillOpacity));
+			}
+		}
+		var coorda = data[i].geometry.coordinates
+		for (var k = 0; k < coorda.length; k++) {
+			coords = coorda[k];
+			if (coords.length == 1) {
+				coords = coords[0]
+			}
+			for (var j = 0; j < coords.length; j++) {
+				point = coordinateToPoint(coords[j][1], coords[j][0], bounds, scale, xoffset, yoffset)
+				if (j === 0) {
+					context.beginPath();
+					context.moveTo(point.x, point.y);
+				} else {
+					context.lineTo(point.x, point.y);
+				}
+			}
+			context.fill();
+			if (mapOption.border == true) {
+				context.stroke();
+			}
+		}
+		if (opts.dataLabel == true) {
+			var centerPoint = data[i].properties.centroid;
+			if (centerPoint) {
+				point = coordinateToPoint(centerPoint[1], centerPoint[0], bounds, scale, xoffset, yoffset);
+				let fontSize = data[i].textSize || config.fontSize;
+				let text = data[i].properties.name;
+				context.beginPath();
+				context.setFontSize(fontSize)
+				context.setFillStyle(data[i].textColor || '#666666')
+				context.fillText(text, point.x - measureText(text, fontSize) / 2, point.y + fontSize / 2);
+				context.closePath();
+				context.stroke();
+			}
+		}
+	}
+	opts.chartData.mapData = {
+		bounds: bounds,
+		scale: scale,
+		xoffset: xoffset,
+		yoffset: yoffset
+	}
+	drawToolTipBridge(opts, config, context, 1);
+	context.draw();
+}
+
+function getWordCloudPoint(opts, type) {
+	let points = opts.series.sort(function(a, b) {
+		return parseInt(b.textSize) - parseInt(a.textSize);
+	});
+	switch (type) {
+		case 'normal':
+			for (let i = 0; i < points.length; i++) {
+				let text = points[i].name;
+				let tHeight = points[i].textSize;
+				let tWidth = measureText(text, tHeight);
+				let x, y;
+				let area;
+				let breaknum = 0;
+				while (true) {
+					breaknum++;
+					x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+					y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+					area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 + opts.height /
+						2
+					];
+					let isCollision = collisionNew(area, points, opts.width, opts.height);
+					if (!isCollision) break;
+					if (breaknum == 1000) {
+						area = [-100, -100, -100, -100];
+						break;
+					}
+				};
+				points[i].area = area;
+			}
+			break;
+		case 'vertical':
+			function Spin() {
+				//获取均匀随机值,是否旋转,旋转的概率为(1-0.5)
+				if (Math.random() > 0.7) {
+					return true;
+				} else {
+					return false
+				};
+			};
+			for (let i = 0; i < points.length; i++) {
+				let text = points[i].name;
+				let tHeight = points[i].textSize;
+				let tWidth = measureText(text, tHeight);
+				let isSpin = Spin();
+				let x, y, area, areav;
+				let breaknum = 0;
+				while (true) {
+					breaknum++;
+					let isCollision;
+					if (isSpin) {
+						x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+						y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+						area = [y - 5 - tWidth + opts.width / 2, (-x - 5 + opts.height / 2), y + 5 + opts.width / 2, (-x + tHeight + 5 +
+							opts.height / 2)];
+						areav = [opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) - 5, (opts.height /
+								2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) - 5, opts.width - (opts.width / 2 - opts.height / 2) -
+							(-x + tHeight + 5 + opts.height / 2) + tHeight, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width /
+								2) + tWidth + 5
+						];
+						isCollision = collisionNew(areav, points, opts.height, opts.width);
+					} else {
+						x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+						y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+						area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 + opts.height /
+							2
+						];
+						isCollision = collisionNew(area, points, opts.width, opts.height);
+					}
+					if (!isCollision) break;
+					if (breaknum == 1000) {
+						area = [-1000, -1000, -1000, -1000];
+						break;
+					}
+				};
+				if (isSpin) {
+					points[i].area = areav;
+					points[i].areav = area;
+				} else {
+					points[i].area = area;
+				}
+				points[i].rotate = isSpin;
+			};
+			break;
+	}
+	return points;
+}
+
+
+function drawWordCloudDataPoints(series, opts, config, context) {
+	let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	let wordOption = assign({}, {
+		type: 'normal',
+		autoColors: true
+	}, opts.extra.word);
+
+	context.beginPath();
+	context.setFillStyle(opts.background || '#FFFFFF');
+	context.rect(0, 0, opts.width, opts.height);
+	context.fill();
+	context.save();
+	let points = opts.chartData.wordCloudData;
+	context.translate(opts.width / 2, opts.height / 2);
+
+	for (let i = 0; i < points.length; i++) {
+		context.save();
+		if (points[i].rotate) {
+			context.rotate(90 * Math.PI / 180);
+		}
+		let text = points[i].name;
+		let tHeight = points[i].textSize;
+		let tWidth = measureText(text, tHeight);
+		context.beginPath();
+		context.setStrokeStyle(points[i].color);
+		context.setFillStyle(points[i].color);
+		context.setFontSize(tHeight);
+		if (points[i].rotate) {
+			if (points[i].areav[0] > 0) {
+				if (opts.tooltip) {
+					if (opts.tooltip.index == i) {
+						context.strokeText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (
+							points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+					} else {
+						context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[
+							i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+					}
+				} else {
+					context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i]
+						.areav[1] + 5 + tHeight - opts.height / 2) * process);
+				}
+			}
+		} else {
+			if (points[i].area[0] > 0) {
+				if (opts.tooltip) {
+					if (opts.tooltip.index == i) {
+						context.strokeText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[
+							i].area[1] + 5 + tHeight - opts.height / 2) * process);
+					} else {
+						context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i]
+							.area[1] + 5 + tHeight - opts.height / 2) * process);
+					}
+				} else {
+					context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i]
+						.area[1] + 5 + tHeight - opts.height / 2) * process);
+				}
+
+			}
+		}
+
+		context.stroke();
+		context.restore();
+	}
+	context.restore();
+}
+
+function drawFunnelDataPoints(series, opts, config, context) {
+	let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+	let funnelOption = assign({}, {
+		activeWidth: 10,
+		activeOpacity: 0.3,
+		border: false,
+		borderWidth: 2,
+		borderColor: '#FFFFFF',
+		fillOpacity: 1,
+		labelAlign: 'right'
+	}, opts.extra.funnel);
+	let eachSpacing = (opts.height - opts.area[0] - opts.area[2]) / series.length;
+	let centerPosition = {
+		x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+		y: opts.height - opts.area[2]
+	};
+	let activeWidth = funnelOption.activeWidth;
+	let radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - activeWidth, (opts.height - opts.area[0] - opts
+		.area[2]) / 2 - activeWidth);
+	series = getFunnelDataPoints(series, radius, process);
+	context.save();
+	context.translate(centerPosition.x, centerPosition.y);
+	for (let i = 0; i < series.length; i++) {
+		if (i == 0) {
+			if (opts.tooltip) {
+				if (opts.tooltip.index == i) {
+					context.beginPath();
+					context.setFillStyle(hexToRgb(series[i].color, funnelOption.activeOpacity));
+					context.moveTo(-activeWidth, 0);
+					context.lineTo(-series[i].radius - activeWidth, -eachSpacing);
+					context.lineTo(series[i].radius + activeWidth, -eachSpacing);
+					context.lineTo(activeWidth, 0);
+					context.lineTo(-activeWidth, 0);
+					context.closePath();
+					context.fill();
+				}
+			}
+			series[i].funnelArea = [centerPosition.x - series[i].radius, centerPosition.y - eachSpacing, centerPosition.x +
+				series[i].radius, centerPosition.y
+			];
+			context.beginPath();
+			context.setLineWidth(funnelOption.borderWidth * opts.pixelRatio);
+			context.setStrokeStyle(funnelOption.borderColor);
+			context.setFillStyle(hexToRgb(series[i].color, funnelOption.fillOpacity));
+			context.moveTo(0, 0);
+			context.lineTo(-series[i].radius, -eachSpacing);
+			context.lineTo(series[i].radius, -eachSpacing);
+			context.lineTo(0, 0);
+			context.closePath();
+			context.fill();
+			if (funnelOption.border == true) {
+				context.stroke();
+			}
+		} else {
+			if (opts.tooltip) {
+				if (opts.tooltip.index == i) {
+					context.beginPath();
+					context.setFillStyle(hexToRgb(series[i].color, funnelOption.activeOpacity));
+					context.moveTo(0, 0);
+					context.lineTo(-series[i - 1].radius - activeWidth, 0);
+					context.lineTo(-series[i].radius - activeWidth, -eachSpacing);
+					context.lineTo(series[i].radius + activeWidth, -eachSpacing);
+					context.lineTo(series[i - 1].radius + activeWidth, 0);
+					context.lineTo(0, 0);
+					context.closePath();
+					context.fill();
+				}
+			}
+			series[i].funnelArea = [centerPosition.x - series[i].radius, centerPosition.y - eachSpacing * (i + 1),
+				centerPosition.x + series[i].radius, centerPosition.y - eachSpacing * i
+			];
+			context.beginPath();
+			context.setLineWidth(funnelOption.borderWidth * opts.pixelRatio);
+			context.setStrokeStyle(funnelOption.borderColor);
+			context.setFillStyle(hexToRgb(series[i].color, funnelOption.fillOpacity));
+			context.moveTo(0, 0);
+			context.lineTo(-series[i - 1].radius, 0);
+			context.lineTo(-series[i].radius, -eachSpacing);
+			context.lineTo(series[i].radius, -eachSpacing);
+			context.lineTo(series[i - 1].radius, 0);
+			context.lineTo(0, 0);
+			context.closePath();
+			context.fill();
+			if (funnelOption.border == true) {
+				context.stroke();
+			}
+		}
+		context.translate(0, -eachSpacing)
+	}
+	context.restore();
+
+	if (opts.dataLabel !== false && process === 1) {
+		drawFunnelText(series, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition);
+	}
+
+	return {
+		center: centerPosition,
+		radius: radius,
+		series: series
+	};
+}
+
+function drawFunnelText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) {
+	for (let i = 0; i < series.length; i++) {
+		let item = series[i];
+		let startX, endX, startY, fontSize;
+		let text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
+		if (labelAlign == 'right') {
+			if (i == 0) {
+				startX = (item.funnelArea[2] + centerPosition.x) / 2;
+			} else {
+				startX = (item.funnelArea[2] + series[i - 1].funnelArea[2]) / 2;
+			}
+			endX = startX + activeWidth * 2;
+			startY = item.funnelArea[1] + eachSpacing / 2;
+			fontSize = item.textSize || opts.fontSize;
+			context.setLineWidth(1 * opts.pixelRatio);
+			context.setStrokeStyle(item.color);
+			context.setFillStyle(item.color);
+			context.beginPath();
+			context.moveTo(startX, startY);
+			context.lineTo(endX, startY);
+			context.stroke();
+			context.closePath();
+			context.beginPath();
+			context.moveTo(endX, startY);
+			context.arc(endX, startY, 2, 0, 2 * Math.PI);
+			context.closePath();
+			context.fill();
+			context.beginPath();
+			context.setFontSize(fontSize);
+			context.setFillStyle(item.textColor || '#666666');
+			context.fillText(text, endX + 5, startY + fontSize / 2 - 2);
+			context.closePath();
+			context.stroke();
+			context.closePath();
+		} else {
+			if (i == 0) {
+				startX = (item.funnelArea[0] + centerPosition.x) / 2;
+			} else {
+				startX = (item.funnelArea[0] + series[i - 1].funnelArea[0]) / 2;
+			}
+			endX = startX - activeWidth * 2;
+			startY = item.funnelArea[1] + eachSpacing / 2;
+			fontSize = item.textSize || opts.fontSize;
+			context.setLineWidth(1 * opts.pixelRatio);
+			context.setStrokeStyle(item.color);
+			context.setFillStyle(item.color);
+			context.beginPath();
+			context.moveTo(startX, startY);
+			context.lineTo(endX, startY);
+			context.stroke();
+			context.closePath();
+			context.beginPath();
+			context.moveTo(endX, startY);
+			context.arc(endX, startY, 2, 0, 2 * Math.PI);
+			context.closePath();
+			context.fill();
+			context.beginPath();
+			context.setFontSize(fontSize);
+			context.setFillStyle(item.textColor || '#666666');
+			context.fillText(text, endX - 5 - measureText(text), startY + fontSize / 2 - 2);
+			context.closePath();
+			context.stroke();
+			context.closePath();
+		}
+
+	}
+}
+
+
+function drawCanvas(opts, context) {
+	context.draw();
+}
+
+var Timing = {
+	easeIn: function easeIn(pos) {
+		return Math.pow(pos, 3);
+	},
+	easeOut: function easeOut(pos) {
+		return Math.pow(pos - 1, 3) + 1;
+	},
+	easeInOut: function easeInOut(pos) {
+		if ((pos /= 0.5) < 1) {
+			return 0.5 * Math.pow(pos, 3);
+		} else {
+			return 0.5 * (Math.pow(pos - 2, 3) + 2);
+		}
+	},
+	linear: function linear(pos) {
+		return pos;
+	}
+};
+
+function Animation(opts) {
+	this.isStop = false;
+	opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
+	opts.timing = opts.timing || 'linear';
+	var delay = 17;
+
+	function createAnimationFrame() {
+		if (typeof setTimeout !== 'undefined') {
+			return function(step, delay) {
+				setTimeout(function() {
+					var timeStamp = +new Date();
+					step(timeStamp);
+				}, delay);
+			};
+		} else if (typeof requestAnimationFrame !== 'undefined') {
+			return requestAnimationFrame;
+		} else {
+			return function(step) {
+				step(null);
+			};
+		}
+	};
+	var animationFrame = createAnimationFrame();
+	var startTimeStamp = null;
+	var _step = function step(timestamp) {
+		if (timestamp === null || this.isStop === true) {
+			opts.onProcess && opts.onProcess(1);
+			opts.onAnimationFinish && opts.onAnimationFinish();
+			return;
+		}
+		if (startTimeStamp === null) {
+			startTimeStamp = timestamp;
+		}
+		if (timestamp - startTimeStamp < opts.duration) {
+			var process = (timestamp - startTimeStamp) / opts.duration;
+			var timingFunction = Timing[opts.timing];
+			process = timingFunction(process);
+
+			opts.onProcess && opts.onProcess(process);
+			animationFrame(_step, delay);
+		} else {
+			opts.onProcess && opts.onProcess(1);
+			opts.onAnimationFinish && opts.onAnimationFinish();
+		}
+	};
+	_step = _step.bind(this);
+	animationFrame(_step, delay);
+}
+
+// stop animation immediately
+// and tigger onAnimationFinish
+Animation.prototype.stop = function() {
+	this.isStop = true;
+};
+
+function drawCharts(type, opts, config, context) {
+	var _this = this;
+	var series = opts.series;
+	var categories = opts.categories;
+	series = fillSeries(series, opts, config);
+	var duration = opts.animation ? opts.duration : 0;
+	_this.animationInstance && _this.animationInstance.stop();
+	var seriesMA = null;
+	if (type == 'candle') {
+		let average = assign({}, opts.extra.candle.average);
+		if (average.show) {
+			seriesMA = calCandleMA(average.day, average.name, average.color, series[0].data);
+			seriesMA = fillSeries(seriesMA, opts, config);
+			opts.seriesMA = seriesMA;
+		} else if (opts.seriesMA) {
+			seriesMA = opts.seriesMA = fillSeries(opts.seriesMA, opts, config);
+		} else {
+			seriesMA = series;
+		}
+	} else {
+		seriesMA = series;
+	}
+
+	/* 过滤掉show=false的series */
+	opts._series_ = series = filterSeries(series);
+
+	//重新计算图表区域
+
+	opts.area = new Array(4);
+	//复位绘图区域
+	for (let j = 0; j < 4; j++) {
+		opts.area[j] = opts.padding[j];
+	}
+
+	//通过计算三大区域:图例、X轴、Y轴的大小,确定绘图区域
+	var _calLegendData = calLegendData(seriesMA, opts, config, opts.chartData),
+		legendHeight = _calLegendData.area.wholeHeight,
+		legendWidth = _calLegendData.area.wholeWidth;
+
+	switch (opts.legend.position) {
+		case 'top':
+			opts.area[0] += legendHeight;
+			break;
+		case 'bottom':
+			opts.area[2] += legendHeight;
+			break;
+		case 'left':
+			opts.area[3] += legendWidth;
+			break;
+		case 'right':
+			opts.area[1] += legendWidth;
+			break;
+	}
+
+	let _calYAxisData = {},
+		yAxisWidth = 0;
+	if (opts.type === 'line' || opts.type === 'column' || opts.type === 'area' || opts.type === 'mix' || opts.type ===
+		'candle') {
+		_calYAxisData = calYAxisData(series, opts, config);
+		yAxisWidth = _calYAxisData.yAxisWidth;
+		//如果显示Y轴标题
+		if (opts.yAxis.showTitle) {
+			let maxTitleHeight = 0;
+			for (let i = 0; i < opts.yAxis.data.length; i++) {
+				maxTitleHeight = Math.max(maxTitleHeight, opts.yAxis.data[i].titleFontSize ? opts.yAxis.data[i].titleFontSize :
+					config.fontSize)
+			}
+			opts.area[0] += (maxTitleHeight + 6) * opts.pixelRatio;
+		}
+		let rightIndex = 0,
+			leftIndex = 0;
+		//计算主绘图区域左右位置
+		for (let i = 0; i < yAxisWidth.length; i++) {
+			if (yAxisWidth[i].position == 'left') {
+				if (leftIndex > 0) {
+					opts.area[3] += yAxisWidth[i].width + opts.yAxis.padding;
+				} else {
+					opts.area[3] += yAxisWidth[i].width;
+				}
+				leftIndex += 1;
+			} else {
+				if (rightIndex > 0) {
+					opts.area[1] += yAxisWidth[i].width + opts.yAxis.padding;
+				} else {
+					opts.area[1] += yAxisWidth[i].width;
+				}
+				rightIndex += 1;
+			}
+		}
+	} else {
+		config.yAxisWidth = yAxisWidth;
+	}
+	opts.chartData.yAxisData = _calYAxisData;
+
+	if (opts.categories && opts.categories.length) {
+		opts.chartData.xAxisData = getXAxisPoints(opts.categories, opts, config);
+		let _calCategoriesData = calCategoriesData(opts.categories, opts, config, opts.chartData.xAxisData.eachSpacing),
+			xAxisHeight = _calCategoriesData.xAxisHeight,
+			angle = _calCategoriesData.angle;
+		config.xAxisHeight = xAxisHeight;
+		config._xAxisTextAngle_ = angle;
+		opts.area[2] += xAxisHeight;
+		opts.chartData.categoriesData = _calCategoriesData;
+	} else {
+		if (opts.type === 'line' || opts.type === 'area' || opts.type === 'points') {
+			opts.chartData.xAxisData = calXAxisData(series, opts, config);
+			categories = opts.chartData.xAxisData.rangesFormat;
+			let _calCategoriesData = calCategoriesData(categories, opts, config, opts.chartData.xAxisData.eachSpacing),
+				xAxisHeight = _calCategoriesData.xAxisHeight,
+				angle = _calCategoriesData.angle;
+			config.xAxisHeight = xAxisHeight;
+			config._xAxisTextAngle_ = angle;
+			opts.area[2] += xAxisHeight;
+			opts.chartData.categoriesData = _calCategoriesData;
+		} else {
+			opts.chartData.xAxisData = {
+				xAxisPoints: []
+			};
+		}
+	}
+	//计算右对齐偏移距离
+	if (opts.enableScroll && opts.xAxis.scrollAlign == 'right' && opts._scrollDistance_ === undefined) {
+		let offsetLeft = 0,
+			xAxisPoints = opts.chartData.xAxisData.xAxisPoints,
+			startX = opts.chartData.xAxisData.startX,
+			endX = opts.chartData.xAxisData.endX,
+			eachSpacing = opts.chartData.xAxisData.eachSpacing;
+		let totalWidth = eachSpacing * (xAxisPoints.length - 1);
+		let screenWidth = endX - startX;
+		offsetLeft = screenWidth - totalWidth;
+		_this.scrollOption = {
+			currentOffset: offsetLeft,
+			startTouchX: offsetLeft,
+			distance: 0,
+			lastMoveTime: 0
+		};
+		opts._scrollDistance_ = offsetLeft;
+	}
+
+	if (type === 'pie' || type === 'ring' || type === 'rose') {
+		config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(seriesMA);
+	}
+
+	switch (type) {
+		case 'word':
+			let wordOption = assign({}, {
+				type: 'normal',
+				autoColors: true
+			}, opts.extra.word);
+			if (opts.updateData == true || opts.updateData == undefined) {
+				opts.chartData.wordCloudData = getWordCloudPoint(opts, wordOption.type);
+			}
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					drawWordCloudDataPoints(series, opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'map':
+			context.clearRect(0, 0, opts.width, opts.height);
+			drawMapDataPoints(series, opts, config, context);
+			break;
+		case 'funnel':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.funnelData = drawFunnelDataPoints(series, opts, config, context, process);
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'line':
+			this.animationInstance = new Animation({
+				timing: 'easeIn',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					drawYAxisGrid(categories, opts, config, context);
+					drawXAxis(categories, opts, config, context);
+					var _drawLineDataPoints = drawLineDataPoints(series, opts, config, context, process),
+						xAxisPoints = _drawLineDataPoints.xAxisPoints,
+						calPoints = _drawLineDataPoints.calPoints,
+						eachSpacing = _drawLineDataPoints.eachSpacing;
+					opts.chartData.xAxisPoints = xAxisPoints;
+					opts.chartData.calPoints = calPoints;
+					opts.chartData.eachSpacing = eachSpacing;
+					drawYAxis(series, opts, config, context);
+					if (opts.enableMarkLine !== false && process === 1) {
+						drawMarkLine(opts, config, context);
+					}
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+					drawCanvas(opts, context);
+
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'mix':
+			this.animationInstance = new Animation({
+				timing: 'easeIn',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					drawYAxisGrid(categories, opts, config, context);
+					drawXAxis(categories, opts, config, context);
+					var _drawMixDataPoints = drawMixDataPoints(series, opts, config, context, process),
+						xAxisPoints = _drawMixDataPoints.xAxisPoints,
+						calPoints = _drawMixDataPoints.calPoints,
+						eachSpacing = _drawMixDataPoints.eachSpacing;
+					opts.chartData.xAxisPoints = xAxisPoints;
+					opts.chartData.calPoints = calPoints;
+					opts.chartData.eachSpacing = eachSpacing;
+					drawYAxis(series, opts, config, context);
+					if (opts.enableMarkLine !== false && process === 1) {
+						drawMarkLine(opts, config, context);
+					}
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'column':
+			this.animationInstance = new Animation({
+				timing: 'easeIn',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					drawYAxisGrid(categories, opts, config, context);
+					drawXAxis(categories, opts, config, context);
+					var _drawColumnDataPoints = drawColumnDataPoints(series, opts, config, context, process),
+						xAxisPoints = _drawColumnDataPoints.xAxisPoints,
+						calPoints = _drawColumnDataPoints.calPoints,
+						eachSpacing = _drawColumnDataPoints.eachSpacing;
+					opts.chartData.xAxisPoints = xAxisPoints;
+					opts.chartData.calPoints = calPoints;
+					opts.chartData.eachSpacing = eachSpacing;
+					drawYAxis(series, opts, config, context);
+					if (opts.enableMarkLine !== false && process === 1) {
+						drawMarkLine(opts, config, context);
+					}
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+			// slam TODO myArea
+		case 'area':
+			this.animationInstance = new Animation({
+				timing: 'easeIn',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					drawYAxisGrid(categories, opts, config, context);
+					drawXAxis(categories, opts, config, context);
+					var _drawAreaDataPoints = drawAreaDataPoints(series, opts, config, context, process),
+						xAxisPoints = _drawAreaDataPoints.xAxisPoints,
+						calPoints = _drawAreaDataPoints.calPoints,
+						eachSpacing = _drawAreaDataPoints.eachSpacing;
+					opts.chartData.xAxisPoints = xAxisPoints;
+					opts.chartData.calPoints = calPoints;
+					opts.chartData.eachSpacing = eachSpacing;
+					drawYAxis(series, opts, config, context);
+					if (opts.enableMarkLine !== false && process === 1) {
+						drawMarkLine(opts, config, context);
+					}
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'ring':
+		case 'pie':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'rose':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.pieData = drawRoseDataPoints(series, opts, config, context, process);
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'radar':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process);
+					drawLegend(opts.series, opts, config, context, opts.chartData);
+					drawToolTipBridge(opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'arcbar':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.arcbarData = drawArcbarDataPoints(series, opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+			/**
+			 * 自定义arcbar
+			 * slamb todo 
+			 * */
+		case 'myArcbar':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.arcbarData = drawMyArcbarDataPoints(series, opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'gauge':
+			this.animationInstance = new Animation({
+				timing: 'easeInOut',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					opts.chartData.gaugeData = drawGaugeDataPoints(categories, series, opts, config, context, process);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+		case 'candle':
+			this.animationInstance = new Animation({
+				timing: 'easeIn',
+				duration: duration,
+				onProcess: function onProcess(process) {
+					context.clearRect(0, 0, opts.width, opts.height);
+					if (opts.rotate) {
+						contextRotate(context, opts);
+					}
+					drawYAxisGrid(categories, opts, config, context);
+					drawXAxis(categories, opts, config, context);
+					var _drawCandleDataPoints = drawCandleDataPoints(series, seriesMA, opts, config, context, process),
+						xAxisPoints = _drawCandleDataPoints.xAxisPoints,
+						calPoints = _drawCandleDataPoints.calPoints,
+						eachSpacing = _drawCandleDataPoints.eachSpacing;
+					opts.chartData.xAxisPoints = xAxisPoints;
+					opts.chartData.calPoints = calPoints;
+					opts.chartData.eachSpacing = eachSpacing;
+					drawYAxis(series, opts, config, context);
+					if (opts.enableMarkLine !== false && process === 1) {
+						drawMarkLine(opts, config, context);
+					}
+					if (seriesMA) {
+						drawLegend(seriesMA, opts, config, context, opts.chartData);
+					} else {
+						drawLegend(opts.series, opts, config, context, opts.chartData);
+					}
+					drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+					drawCanvas(opts, context);
+				},
+				onAnimationFinish: function onAnimationFinish() {
+					_this.event.trigger('renderComplete');
+				}
+			});
+			break;
+	}
+}
+
+// simple event implement
+
+function Event() {
+	this.events = {};
+}
+
+Event.prototype.addEventListener = function(type, listener) {
+	this.events[type] = this.events[type] || [];
+	this.events[type].push(listener);
+};
+
+Event.prototype.trigger = function() {
+	for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+		args[_key] = arguments[_key];
+	}
+
+	var type = args[0];
+	var params = args.slice(1);
+	if (!!this.events[type]) {
+		this.events[type].forEach(function(listener) {
+			try {
+				listener.apply(null, params);
+			} catch (e) {
+				console.error(e);
+			}
+		});
+	}
+};
+
+var Charts = function Charts(opts) {
+	opts.pixelRatio = opts.pixelRatio ? opts.pixelRatio : 1;
+	opts.fontSize = opts.fontSize ? opts.fontSize * opts.pixelRatio : 13 * opts.pixelRatio;
+	opts.title = assign({}, opts.title);
+	opts.subtitle = assign({}, opts.subtitle);
+	opts.duration = opts.duration ? opts.duration : 1000;
+	opts.yAxis = assign({}, {
+		data: [],
+		showTitle: false,
+		disabled: false,
+		disableGrid: false,
+		splitNumber: 5,
+		gridType: 'solid',
+		dashLength: 4 * opts.pixelRatio,
+		gridColor: '#cccccc',
+		padding: 10,
+		fontColor: '#666666'
+	}, opts.yAxis);
+	opts.yAxis.dashLength *= opts.pixelRatio;
+	opts.yAxis.padding *= opts.pixelRatio;
+	opts.xAxis = assign({}, {
+		rotateLabel: false,
+		type: 'calibration',
+		gridType: 'solid',
+		dashLength: 4,
+		scrollAlign: 'left',
+		boundaryGap: 'center',
+		axisLine: true,
+		axisLineColor: '#cccccc'
+	}, opts.xAxis);
+	opts.xAxis.dashLength *= opts.pixelRatio;
+	opts.legend = assign({}, {
+		show: true,
+		position: 'bottom',
+		float: 'center',
+		backgroundColor: 'rgba(0,0,0,0)',
+		borderColor: 'rgba(0,0,0,0)',
+		borderWidth: 0,
+		padding: 5,
+		margin: 5,
+		itemGap: 10,
+		fontSize: opts.fontSize,
+		lineHeight: opts.fontSize,
+		fontColor: '#333333',
+		format: {},
+		hiddenColor: '#CECECE'
+	}, opts.legend);
+	opts.legend.borderWidth = opts.legend.borderWidth * opts.pixelRatio;
+	opts.legend.itemGap = opts.legend.itemGap * opts.pixelRatio;
+	opts.legend.padding = opts.legend.padding * opts.pixelRatio;
+	opts.legend.margin = opts.legend.margin * opts.pixelRatio;
+	opts.extra = assign({}, opts.extra);
+	opts.rotate = opts.rotate ? true : false;
+	opts.animation = opts.animation ? true : false;
+	opts.rotate = opts.rotate ? true : false;
+
+	let config$$1 = JSON.parse(JSON.stringify(config));
+	config$$1.colors = opts.colors ? opts.colors : config$$1.colors;
+	config$$1.yAxisTitleWidth = opts.yAxis.disabled !== true && opts.yAxis.title ? config$$1.yAxisTitleWidth : 0;
+	if (opts.type == 'pie' || opts.type == 'ring') {
+		config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth * opts.pixelRatio ||
+			config$$1.pieChartLinePadding * opts.pixelRatio;
+	}
+	if (opts.type == 'rose') {
+		config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth * opts.pixelRatio ||
+			config$$1.pieChartLinePadding * opts.pixelRatio;
+	}
+	config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding * opts.pixelRatio;
+	config$$1.yAxisSplit = opts.yAxis.splitNumber ? opts.yAxis.splitNumber : config.yAxisSplit;
+
+	//屏幕旋转
+	config$$1.rotate = opts.rotate;
+	if (opts.rotate) {
+		let tempWidth = opts.width;
+		let tempHeight = opts.height;
+		opts.width = tempHeight;
+		opts.height = tempWidth;
+	}
+
+	//适配高分屏
+	opts.padding = opts.padding ? opts.padding : config$$1.padding;
+	for (let i = 0; i < 4; i++) {
+		opts.padding[i] *= opts.pixelRatio;
+	}
+	config$$1.yAxisWidth = config.yAxisWidth * opts.pixelRatio;
+	config$$1.xAxisHeight = config.xAxisHeight * opts.pixelRatio;
+	if (opts.enableScroll && opts.xAxis.scrollShow) {
+		config$$1.xAxisHeight += 6 * opts.pixelRatio;
+	}
+	config$$1.xAxisLineHeight = config.xAxisLineHeight * opts.pixelRatio;
+	config$$1.fontSize = opts.fontSize;
+	config$$1.titleFontSize = config.titleFontSize * opts.pixelRatio;
+	config$$1.subtitleFontSize = config.subtitleFontSize * opts.pixelRatio;
+	config$$1.toolTipPadding = config.toolTipPadding * opts.pixelRatio;
+	config$$1.toolTipLineHeight = config.toolTipLineHeight * opts.pixelRatio;
+	config$$1.columePadding = config.columePadding * opts.pixelRatio;
+	opts.$this = opts.$this ? opts.$this : this;
+
+	this.context = uni.createCanvasContext(opts.canvasId, opts.$this);
+	/* 兼容原生H5
+	this.context = document.getElementById(opts.canvasId).getContext("2d");
+	this.context.setStrokeStyle = function(e){ return this.strokeStyle=e; }
+	this.context.setLineWidth = function(e){ return this.lineWidth=e; }
+	this.context.setLineCap = function(e){ return this.lineCap=e; }
+	this.context.setFontSize = function(e){ return this.font=e+"px sans-serif"; }
+	this.context.setFillStyle = function(e){ return this.fillStyle=e; }
+	this.context.draw = function(){ }
+	*/
+
+	opts.chartData = {};
+	this.event = new Event();
+	this.scrollOption = {
+		currentOffset: 0,
+		startTouchX: 0,
+		distance: 0,
+		lastMoveTime: 0
+	};
+
+	this.opts = opts;
+	this.config = config$$1;
+
+	drawCharts.call(this, opts.type, opts, config$$1, this.context);
+};
+
+Charts.prototype.updateData = function() {
+	let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+	this.opts = assign({}, this.opts, data);
+	this.opts.updateData = true;
+	let scrollPosition = data.scrollPosition || 'current';
+	switch (scrollPosition) {
+		case 'current':
+			this.opts._scrollDistance_ = this.scrollOption.currentOffset;
+			break;
+		case 'left':
+			this.opts._scrollDistance_ = 0;
+			this.scrollOption = {
+				currentOffset: 0,
+				startTouchX: 0,
+				distance: 0,
+				lastMoveTime: 0
+			};
+			break;
+		case 'right':
+			let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config),
+				yAxisWidth = _calYAxisData.yAxisWidth;
+			this.config.yAxisWidth = yAxisWidth;
+			let offsetLeft = 0;
+			let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
+				xAxisPoints = _getXAxisPoints0.xAxisPoints,
+				startX = _getXAxisPoints0.startX,
+				endX = _getXAxisPoints0.endX,
+				eachSpacing = _getXAxisPoints0.eachSpacing;
+			let totalWidth = eachSpacing * (xAxisPoints.length - 1);
+			let screenWidth = endX - startX;
+			offsetLeft = screenWidth - totalWidth;
+			this.scrollOption = {
+				currentOffset: offsetLeft,
+				startTouchX: offsetLeft,
+				distance: 0,
+				lastMoveTime: 0
+			};
+			this.opts._scrollDistance_ = offsetLeft;
+			break;
+	}
+	drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+};
+
+Charts.prototype.zoom = function() {
+	var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.opts.xAxis.itemCount;
+	if (this.opts.enableScroll !== true) {
+		console.log('请启用滚动条后使用!')
+		return;
+	}
+	//当前屏幕中间点
+	let centerPoint = Math.round(Math.abs(this.scrollOption.currentOffset) / this.opts.chartData.eachSpacing) + Math.round(
+		this.opts.xAxis.itemCount / 2);
+	this.opts.animation = false;
+	this.opts.xAxis.itemCount = val.itemCount;
+	//重新计算x轴偏移距离
+	let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config),
+		yAxisWidth = _calYAxisData.yAxisWidth;
+	this.config.yAxisWidth = yAxisWidth;
+	let offsetLeft = 0;
+	let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
+		xAxisPoints = _getXAxisPoints0.xAxisPoints,
+		startX = _getXAxisPoints0.startX,
+		endX = _getXAxisPoints0.endX,
+		eachSpacing = _getXAxisPoints0.eachSpacing;
+	let centerLeft = eachSpacing * centerPoint;
+	let screenWidth = endX - startX;
+	let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
+	offsetLeft = screenWidth / 2 - centerLeft;
+	if (offsetLeft > 0) {
+		offsetLeft = 0;
+	}
+	if (offsetLeft < MaxLeft) {
+		offsetLeft = MaxLeft;
+	}
+	this.scrollOption = {
+		currentOffset: offsetLeft,
+		startTouchX: offsetLeft,
+		distance: 0,
+		lastMoveTime: 0
+	};
+	this.opts._scrollDistance_ = offsetLeft;
+	drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+};
+
+Charts.prototype.stopAnimation = function() {
+	this.animationInstance && this.animationInstance.stop();
+};
+
+Charts.prototype.addEventListener = function(type, listener) {
+	this.event.addEventListener(type, listener);
+};
+
+Charts.prototype.getCurrentDataIndex = function(e) {
+	var touches = null;
+	if (e.changedTouches) {
+		touches = e.changedTouches[0];
+	} else {
+		touches = e.mp.changedTouches[0];
+	}
+	if (touches) {
+		let _touches$ = getTouches(touches, this.opts, e);
+		if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose') {
+			return findPieChartCurrentIndex({
+				x: _touches$.x,
+				y: _touches$.y
+			}, this.opts.chartData.pieData);
+		} else if (this.opts.type === 'radar') {
+			return findRadarChartCurrentIndex({
+				x: _touches$.x,
+				y: _touches$.y
+			}, this.opts.chartData.radarData, this.opts.categories.length);
+		} else if (this.opts.type === 'funnel') {
+			return findFunnelChartCurrentIndex({
+				x: _touches$.x,
+				y: _touches$.y
+			}, this.opts.chartData.funnelData);
+		} else if (this.opts.type === 'map') {
+			return findMapChartCurrentIndex({
+				x: _touches$.x,
+				y: _touches$.y
+			}, this.opts);
+		} else if (this.opts.type === 'word') {
+			return findWordChartCurrentIndex({
+				x: _touches$.x,
+				y: _touches$.y
+			}, this.opts.chartData.wordCloudData);
+		} else {
+			return findCurrentIndex({
+				x: _touches$.x,
+				y: _touches$.y
+			}, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
+		}
+	}
+	return -1;
+};
+
+Charts.prototype.getLegendDataIndex = function(e) {
+	var touches = null;
+	if (e.changedTouches) {
+		touches = e.changedTouches[0];
+	} else {
+		touches = e.mp.changedTouches[0];
+	}
+	if (touches) {
+		let _touches$ = getTouches(touches, this.opts, e);
+		return findLegendIndex({
+			x: _touches$.x,
+			y: _touches$.y
+		}, this.opts.chartData.legendData);
+	}
+	return -1;
+};
+
+Charts.prototype.touchLegend = function(e) {
+	var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+	var touches = null;
+	if (e.changedTouches) {
+		touches = e.changedTouches[0];
+	} else {
+		touches = e.mp.changedTouches[0];
+	}
+	if (touches) {
+		var _touches$ = getTouches(touches, this.opts, e);
+		var index = this.getLegendDataIndex(e);
+		if (index >= 0) {
+			this.opts.series[index].show = !this.opts.series[index].show;
+			this.opts.animation = option.animation ? true : false;
+			this.opts._scrollDistance_ = this.scrollOption.currentOffset;
+			drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+		}
+	}
+
+};
+
+Charts.prototype.showToolTip = function(e) {
+	var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+	var touches = null;
+	if (e.changedTouches) {
+		touches = e.changedTouches[0];
+	} else {
+		touches = e.mp.changedTouches[0];
+	}
+	if (!touches) {
+		console.log("touchError");
+	}
+	var _touches$ = getTouches(touches, this.opts, e);
+	var currentOffset = this.scrollOption.currentOffset;
+	var opts = assign({}, this.opts, {
+		_scrollDistance_: currentOffset,
+		animation: false
+	});
+	if (this.opts.type === 'line' || this.opts.type === 'area' || this.opts.type === 'column') {
+		var index = this.getCurrentDataIndex(e);
+		if (index > -1) {
+			var seriesData = getSeriesDataItem(this.opts.series, index);
+			if (seriesData.length !== 0) {
+				var _getToolTipData = getToolTipData(seriesData, this.opts.chartData.calPoints, index, this.opts.categories,
+						option),
+					textList = _getToolTipData.textList,
+					offset = _getToolTipData.offset;
+				offset.y = _touches$.y;
+				opts.tooltip = {
+					textList: textList,
+					offset: offset,
+					option: option,
+					index: index
+				};
+			}
+		}
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+	}
+	if (this.opts.type === 'mix') {
+		var index = this.getCurrentDataIndex(e);
+		if (index > -1) {
+			var currentOffset = this.scrollOption.currentOffset;
+			var opts = assign({}, this.opts, {
+				_scrollDistance_: currentOffset,
+				animation: false
+			});
+			var seriesData = getSeriesDataItem(this.opts.series, index);
+			if (seriesData.length !== 0) {
+				var _getMixToolTipData = getMixToolTipData(seriesData, this.opts.chartData.calPoints, index, this.opts.categories,
+						option),
+					textList = _getMixToolTipData.textList,
+					offset = _getMixToolTipData.offset;
+				offset.y = _touches$.y;
+				opts.tooltip = {
+					textList: textList,
+					offset: offset,
+					option: option,
+					index: index
+				};
+			}
+		}
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+	}
+	if (this.opts.type === 'candle') {
+		var index = this.getCurrentDataIndex(e);
+		if (index > -1) {
+			var currentOffset = this.scrollOption.currentOffset;
+			var opts = assign({}, this.opts, {
+				_scrollDistance_: currentOffset,
+				animation: false
+			});
+			var seriesData = getSeriesDataItem(this.opts.series, index);
+			if (seriesData.length !== 0) {
+				var _getToolTipData = getCandleToolTipData(this.opts.series[0].data, seriesData, this.opts.chartData.calPoints,
+						index, this.opts.categories, this.opts.extra.candle, option),
+					textList = _getToolTipData.textList,
+					offset = _getToolTipData.offset;
+				offset.y = _touches$.y;
+				opts.tooltip = {
+					textList: textList,
+					offset: offset,
+					option: option,
+					index: index
+				};
+			}
+		}
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+	}
+	if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose' || this.opts.type === 'funnel') {
+		var index = this.getCurrentDataIndex(e);
+		if (index > -1) {
+			var currentOffset = this.scrollOption.currentOffset;
+			var opts = assign({}, this.opts, {
+				_scrollDistance_: currentOffset,
+				animation: false
+			});
+			var seriesData = this.opts._series_[index];
+			var textList = [{
+				text: option.format ? option.format(seriesData) : seriesData.name + ': ' + seriesData.data,
+				color: seriesData.color
+			}];
+			var offset = {
+				x: _touches$.x,
+				y: _touches$.y
+			};
+			opts.tooltip = {
+				textList: textList,
+				offset: offset,
+				option: option,
+				index: index
+			};
+		}
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+	}
+	if (this.opts.type === 'map' || this.opts.type === 'word') {
+		var index = this.getCurrentDataIndex(e);
+		if (index > -1) {
+			var currentOffset = this.scrollOption.currentOffset;
+			var opts = assign({}, this.opts, {
+				_scrollDistance_: currentOffset,
+				animation: false
+			});
+			var seriesData = this.opts._series_[index];
+			var textList = [{
+				text: option.format ? option.format(seriesData) : seriesData.properties.name,
+				color: seriesData.color
+			}];
+			var offset = {
+				x: _touches$.x,
+				y: _touches$.y
+			};
+			opts.tooltip = {
+				textList: textList,
+				offset: offset,
+				option: option,
+				index: index
+			};
+		}
+		opts.updateData = false;
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+	}
+	if (this.opts.type === 'radar') {
+		var index = this.getCurrentDataIndex(e);
+		if (index > -1) {
+			var currentOffset = this.scrollOption.currentOffset;
+			var opts = assign({}, this.opts, {
+				_scrollDistance_: currentOffset,
+				animation: false
+			});
+			var seriesData = getSeriesDataItem(this.opts.series, index);
+			if (seriesData.length !== 0) {
+				var textList = seriesData.map(function(item) {
+					return {
+						text: option.format ? option.format(item) : item.name + ': ' + item.data,
+						color: item.color
+					};
+				});
+				var offset = {
+					x: _touches$.x,
+					y: _touches$.y
+				};
+				opts.tooltip = {
+					textList: textList,
+					offset: offset,
+					option: option,
+					index: index
+				};
+			}
+		}
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+	}
+};
+
+Charts.prototype.translate = function(distance) {
+	this.scrollOption = {
+		currentOffset: distance,
+		startTouchX: distance,
+		distance: 0,
+		lastMoveTime: 0
+	};
+	let opts = assign({}, this.opts, {
+		_scrollDistance_: distance,
+		animation: false
+	});
+	drawCharts.call(this, this.opts.type, opts, this.config, this.context);
+};
+
+Charts.prototype.scrollStart = function(e) {
+	var touches = null;
+	if (e.changedTouches) {
+		touches = e.changedTouches[0];
+	} else {
+		touches = e.mp.changedTouches[0];
+	}
+	var _touches$ = getTouches(touches, this.opts, e);
+	if (touches && this.opts.enableScroll === true) {
+		this.scrollOption.startTouchX = _touches$.x;
+	}
+};
+
+Charts.prototype.scroll = function(e) {
+	if (this.scrollOption.lastMoveTime === 0) {
+		this.scrollOption.lastMoveTime = Date.now();
+	}
+	let Limit = this.opts.extra.touchMoveLimit || 20;
+	let currMoveTime = Date.now();
+	let duration = currMoveTime - this.scrollOption.lastMoveTime;
+	if (duration < Math.floor(1000 / Limit)) return;
+	this.scrollOption.lastMoveTime = currMoveTime;
+	var touches = null;
+	if (e.changedTouches) {
+		touches = e.changedTouches[0];
+	} else {
+		touches = e.mp.changedTouches[0];
+	}
+	if (touches && this.opts.enableScroll === true) {
+		var _touches$ = getTouches(touches, this.opts, e);
+		var _distance;
+		_distance = _touches$.x - this.scrollOption.startTouchX;
+		var currentOffset = this.scrollOption.currentOffset;
+		var validDistance = calValidDistance(this, currentOffset + _distance, this.opts.chartData, this.config, this.opts);
+		this.scrollOption.distance = _distance = validDistance - currentOffset;
+		var opts = assign({}, this.opts, {
+			_scrollDistance_: currentOffset + _distance,
+			animation: false
+		});
+		drawCharts.call(this, opts.type, opts, this.config, this.context);
+		return currentOffset + _distance;
+	}
+};
+
+Charts.prototype.scrollEnd = function(e) {
+	if (this.opts.enableScroll === true) {
+		var _scrollOption = this.scrollOption,
+			currentOffset = _scrollOption.currentOffset,
+			distance = _scrollOption.distance;
+		this.scrollOption.currentOffset = currentOffset + distance;
+		this.scrollOption.distance = 0;
+	}
+};
+if (typeof module === "object" && typeof module.exports === "object") {
+	module.exports = Charts;
+	//export default Charts;//建议使用nodejs的module导出方式,如报错请使用export方式导出
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
components/u-charts/u-charts.min.js


+ 206 - 0
components/uni-count-down/uni-count-down.vue

@@ -0,0 +1,206 @@
+<template>
+	<view class="uni-countdown">
+		<text v-if="showDay" :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" 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 }" class="uni-countdown__number">{{ h }}</text>
+		<text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? ':' : '时' }}</text>
+		<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" class="uni-countdown__number">{{ i }}</text>
+		<text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? ':' : '分' }}</text>
+		<text :style="{ borderColor: borderColor, color: color, backgroundColor: backgroundColor }" 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
+			}
+		},
+		data() {
+			return {
+				timer: null,
+				syncFlag: false,
+				d: '00',
+				h: '00',
+				i: '00',
+				s: '00',
+				leftTime: 0,
+				seconds: 0,
+				startSeconds: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);
+			this.timer = null;
+		},
+		methods: {
+			toSeconds(day, hours, minutes, seconds) {
+				return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
+			},
+			//开始计时
+			timePlay(data){
+				console.log(data);
+				if (this.seconds <= 0) {
+					this.seconds = this.startSeconds;
+				}
+				this.timer = setInterval(() => {
+					this.seconds--
+					if (this.seconds < 0) {
+						this.timeUp()
+						return
+					}
+					this.countDown()
+				}, 1000)
+			},
+			//暂停时间
+			timePause(data){
+				console.log(data);
+				clearInterval(this.timer);
+				this.timer = null;
+			},
+			timeUp() {
+				clearInterval(this.timer);
+				this.timer = null;
+				this.$emit('timeup');
+			},
+			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.startSeconds = this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
+				if (this.seconds <= 0) {
+					return
+				}
+				this.countDown();
+			},
+			changeFlag() {
+				this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
+				// this.startData();
+				this.countDown();
+			}
+		}
+	}
+</script>
+<style scoped>
+	
+	@font-face {
+		font-family: 'UnidreamLED';
+		src: url('~@/static/font/UnidreamLED.ttf');
+	}
+	
+	.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: 48rpx;
+		padding: 5rpx;
+		font-size: 24rpx;
+	}
+
+	.uni-countdown__number {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		width: 56rpx;
+		height: 56rpx;
+		line-height: 56rpx;
+		margin: 5rpx;
+		text-align: center;
+		font-size: 23px;
+		font-family: UnidreamLED;
+		border-radius: 3px;
+	}
+</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'
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 10 - 0
components/uni-icons/uni-icons.vue


+ 225 - 0
components/uni-nav-bar/uni-nav-bar.vue

@@ -0,0 +1,225 @@
+<template>
+	<view class="uni-navbar">
+		<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
+		 class="uni-navbar__content">
+			<uni-status-bar v-if="statusBar" />
+			<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
+				<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
+					<view class="uni-navbar__content_view" v-if="leftIcon.length">
+						<uni-icons :color="color" :type="leftIcon" size="24" />
+					</view>
+					<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view"
+					 v-if="leftText.length">
+						<text :style="{ color: color, fontSize: '14px' }">{{ leftText }}</text>
+					</view>
+					<slot name="left" />
+				</view>
+				<view class="uni-navbar__header-container uni-navbar__content_view">
+					<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
+						<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
+					</view>
+					<!-- 标题插槽 -->
+					<slot name="middle" />
+				</view>
+				<view :class="title.length ? 'uni-navbar__header-btns-right' : ''" @tap="onClickRight" class="uni-navbar__header-btns uni-navbar__content_view">
+					<view class="uni-navbar__content_view" v-if="rightIcon.length">
+						<uni-icons :color="color" :type="rightIcon" size="24" />
+					</view>
+					<!-- 优先显示图标 -->
+					<view class="uni-navbar-btn-text uni-navbar__content_view" v-if="rightText.length && !rightIcon.length">
+						<text class="uni-nav-bar-right-text">{{ rightText }}</text>
+					</view>
+					<slot name="right" />
+				</view>
+			</view>
+		</view>
+		<view class="uni-navbar__placeholder" v-if="fixed">
+			<uni-status-bar v-if="statusBar" />
+			<view class="uni-navbar__placeholder-view" />
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
+	import uniIcons from "../uni-icons/uni-icons.vue";
+
+	export default {
+		name: "UniNavBar",
+		components: {
+			uniStatusBar,
+			uniIcons
+		},
+		props: {
+			title: {
+				type: String,
+				default: ""
+			},
+			leftText: {
+				type: String,
+				default: ""
+			},
+			rightText: {
+				type: String,
+				default: ""
+			},
+			leftIcon: {
+				type: String,
+				default: ""
+			},
+			rightIcon: {
+				type: String,
+				default: ""
+			},
+			fixed: {
+				type: [Boolean, String],
+				default: false
+			},
+			color: {
+				type: String,
+				default: "#000000"
+			},
+			backgroundColor: {
+				type: String,
+				default: "#FFFFFF"
+			},
+			statusBar: {
+				type: [Boolean, String],
+				default: false
+			},
+			shadow: {
+				type: [String, Boolean],
+				default: false
+			},
+			border: {
+				type: [String, Boolean],
+				default: true
+			}
+		},
+        mounted() {
+          if(uni.report && this.title !== '') {
+              uni.report('title', this.title)
+          }
+        },
+		methods: {
+			onClickLeft() {
+				this.$emit("clickLeft");
+			},
+			onClickRight() {
+				this.$emit("clickRight");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	// default 44px;
+	$nav-height: 46px;
+	.uni-nav-bar-text {
+		/* #ifdef APP-PLUS */
+		font-size: 34rpx;
+		/* #endif */
+		/* #ifndef APP-PLUS */
+		font-size: $uni-font-size-lg;
+		/* #endif */
+	}
+	.uni-nav-bar-right-text {
+		font-size: $uni-font-size-base;
+	}
+
+	.uni-navbar {
+		width: 750rpx;
+	}
+
+	.uni-navbar__content {
+		position: relative;
+		width: 750rpx;
+		background-color: $uni-bg-color;
+		overflow: hidden;
+	}
+
+	.uni-navbar__content_view {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		flex-direction: row;
+		// background-color: #FFFFFF;
+	}
+
+	.uni-navbar__header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		width: 750rpx;
+		height: $nav-height;
+		line-height: $nav-height;
+		font-size: 16px;
+		// background-color: #ffffff;
+	}
+
+	.uni-navbar__header-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-wrap: nowrap;
+		width: 120rpx;
+		padding: 0 6px;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-navbar__header-btns-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 150rpx;
+		justify-content: flex-start;
+	}
+
+	.uni-navbar__header-btns-right {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 150rpx;
+		padding-right: 30rpx;
+		justify-content: flex-end;
+	}
+
+	.uni-navbar__header-container {
+		flex: 1;
+	}
+
+	.uni-navbar__header-container-inner {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		font-size: $uni-font-size-base;
+	}
+
+
+	.uni-navbar__placeholder-view {
+		height: $nav-height;
+	}
+
+	.uni-navbar--fixed {
+		position: fixed;
+		z-index: 998;
+	}
+
+	.uni-navbar--shadow {
+		/* #ifndef APP-NVUE */
+		box-shadow: 0 1px 6px #ccc;
+		/* #endif */
+	}
+
+	.uni-navbar--border {
+		border-bottom-width: 1rpx;
+		border-bottom-style: solid;
+		border-bottom-color: $uni-border-color;
+	}
+</style>

+ 193 - 0
components/uni-popup/uni-popup.vue

@@ -0,0 +1,193 @@
+<template>
+	<view v-if="showPopup" class="uni-popup" @touchmove.stop.prevent="clear">
+		<view class="uni-popup__mask" :class="[ani+'-mask', animation ? 'mask-ani' : '']" @click="close(true)" />
+		<view class="uni-popup__wrapper" :class="[type,ani+'-content', animation ? 'content-ani' : '']" @click="close(true)">
+			<view class="uni-popup__wrapper-box" @click.stop="clear">
+				<uni-status-bar />
+				<slot />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
+	
+	export default {
+		name: 'UniPopup',
+		components: {
+			uniStatusBar
+		},
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			maskClick: {
+				type: Boolean,
+				default: true
+			},
+			show: {
+				type: Boolean,
+				default: true
+			}
+		},
+		data() {
+			return {
+				ani: '',
+				showPopup: false
+			}
+		},
+		watch: {
+			show(newValue) {
+				if (newValue) {
+					this.open()
+				} else {
+					this.close()
+				}
+			}
+		},
+		created() {
+			// this.open()
+		},
+		methods: {
+			clear() {},
+			open() {
+				this.$emit('change', {
+					show: true
+				})
+				this.showPopup = true
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.ani = 'uni-' + this.type
+					}, 100)
+				})
+			},
+			close(type) {
+				if (!this.maskClick && type) return
+				this.$emit('change', {
+					show: false
+				})
+				this.ani = ''
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.showPopup = false
+					}, 300)
+				})
+			}
+		}
+	}
+</script>
+<style scoped>
+	.uni-popup {
+		position: fixed;
+		/* #ifdef H5 */
+		top: var(--window-top);
+		/* #endif */
+		/* #ifndef H5 */
+		top: 0;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		overflow: hidden;
+	}
+
+	.uni-popup__mask {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: rgba(0, 0, 0, 0.4);
+		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 {
+		top: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(-500px);
+	}
+
+	.bottom {
+		bottom: 0;
+		left: 0;
+		right: 0;
+		transform: translateY(500px);
+	}
+
+	.center {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-direction: column;
+		/* #endif */
+		bottom: 0;
+		left: 0;
+		right: 0;
+		top: 0;
+		justify-content: center;
+		align-items: center;
+		transform: scale(1.2);
+		opacity: 0;
+	}
+
+	.uni-popup__wrapper-box {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		position: relative;
+	}
+
+	.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>

+ 25 - 0
components/uni-status-bar/uni-status-bar.vue

@@ -0,0 +1,25 @@
+<template>
+	<view :style="{ height: statusBarHeight }" class="uni-status-bar">
+		<slot />
+	</view>
+</template>
+
+<script>
+	var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
+	export default {
+		name: 'UniStatusBar',
+		data() {
+			return {
+				statusBarHeight: statusBarHeight
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-status-bar {
+		width: 750rpx;
+		height: 20px;
+		// height: var(--status-bar-height);
+	}
+</style>

+ 223 - 0
components/uni-swipe-action/bindingx.js

@@ -0,0 +1,223 @@
+const BindingX = weex.requireModule('bindingx');
+const dom = weex.requireModule('dom');
+const animation = weex.requireModule('animation');
+
+export default {
+	data() {
+		return {
+			right: 0,
+			button: [],
+			preventGesture: false
+		}
+	},
+	mounted() {
+		this.boxSelector = this.getEl(this.$refs['selector-box-hock']);
+		this.selector = this.getEl(this.$refs['selector-content-hock']);
+		this.buttonSelector = this.getEl(this.$refs['selector-button-hock']);
+		this.position = {}
+		this.x = 0
+		setTimeout(() => {
+			this.getSelectorQuery()
+		}, 200)
+	},
+	beforeDestoy() {
+		BindingX.unbind({
+			token: this.timing.token,
+			eventType: 'timing'
+		})
+		BindingX.unbind({
+			token: this.pan.token,
+			eventType: 'pan'
+		})
+	},
+	watch: {
+		show(newVal) {
+			if (!this.position || JSON.stringify(this.position) === '{}') return;
+			if (this.autoClose) return
+			if (this.isInAnimation) return
+			if (newVal) {
+				this.open()
+			} else {
+				this.close()
+			}
+		},
+	},
+	methods: {
+		onClick(index, item) {
+			this.$emit('click', {
+				content: item,
+				index
+			})
+		},
+		touchstart(e) {
+			if (this.isInAnimation) return
+			if (this.stop) return
+			this.stop = true
+			let endWidth = this.right
+			let boxStep = `(x+${this.x})`
+			let pageX = `${boxStep}> ${-endWidth} && ${boxStep} < 0?${boxStep}:(x+${this.x} < 0? ${-endWidth}:0)`
+
+			let props = [{
+				element: this.selector,
+				property: 'transform.translateX',
+				expression: pageX
+			}]
+
+			let left = 0
+			for (let i = 0; i < this.options.length; i++) {
+				let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
+				if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
+				let moveMix = endWidth - left
+				left += this.button[i].width
+				let step = `(${this.x}+x)/${endWidth}`
+				let moveX = `(${step}) * ${moveMix}`
+				let pageButtonX = `${moveX}&& (x+${this.x} > ${-endWidth})?${moveX}:${-moveMix}`
+				props.push({
+					element: buttonSelectors,
+					property: 'transform.translateX',
+					expression: pageButtonX
+				})
+			}
+
+			this.eventpan = this._bind(this.boxSelector, props, 'pan', (e) => {
+				if (e.state === 'end') {
+					this.x = e.deltaX + this.x;
+					if (this.x < -endWidth) {
+						this.x = -endWidth
+					}
+					if (this.x > 0) {
+						this.x = 0
+					}
+					this.stop = false
+					this.bindTiming();
+				}
+			})
+		},
+		touchend(e) {
+			this.$nextTick(() => {
+				if (this.isopen && !this.isDrag && !this.isInAnimation) {
+					this.close()
+				}
+			})
+		},
+		bindTiming() {
+			if (this.isopen) {
+				this.move(this.x, -this.right)
+			} else {
+				this.move(this.x, -40)
+			}
+		},
+		move(left, value) {
+			if (left >= value) {
+				this.close()
+			} else {
+				this.open()
+			}
+		},
+		/**
+		 * 开启swipe
+		 */
+		open() {
+			this.animation(true)
+		},
+		/**
+		 * 关闭swipe
+		 */
+		close() {
+			this.animation(false)
+		},
+		/**
+		 * 开启关闭动画
+		 * @param {Object} type
+		 */
+		animation(type) {
+			this.isDrag = true
+			let endWidth = this.right
+			let time = 200
+			this.isInAnimation = true;
+
+			let exit = `t>${time}`;
+			let translate_x_expression = `easeOutExpo(t,${this.x},${type?(-endWidth-this.x):(-this.x)},${time})`
+			let props = [{
+				element: this.selector,
+				property: 'transform.translateX',
+				expression: translate_x_expression
+			}]
+
+			let left = 0
+			for (let i = 0; i < this.options.length; i++) {
+				let buttonSelectors = this.getEl(this.$refs['button-hock'][i]);
+				if (this.button.length === 0 || !this.button[i] || !this.button[i].width) return
+				let moveMix = endWidth - left
+				left += this.button[i].width
+				let step = `${this.x}/${endWidth}`
+				let moveX = `(${step}) * ${moveMix}`
+				let pageButtonX = `easeOutExpo(t,${moveX},${type ? -moveMix + '-' + moveX: 0 + '-' + moveX},${time})`
+				props.push({
+					element: buttonSelectors,
+					property: 'transform.translateX',
+					expression: pageButtonX
+				})
+			}
+
+			this.timing = BindingX.bind({
+				eventType: 'timing',
+				exitExpression: exit,
+				props: props
+			}, (e) => {
+				if (e.state === 'end' || e.state === 'exit') {
+					this.x = type ? -endWidth : 0
+					this.isInAnimation = false;
+					this.isopen = type
+					this.isDrag = false
+					this.$emit('change', type)
+				}
+			});
+		},
+		/**
+		 * 绑定  BindingX
+		 * @param {Object} anchor
+		 * @param {Object} props
+		 * @param {Object} fn
+		 */
+		_bind(anchor, props, eventType, fn) {
+			return BindingX.bind({
+				anchor,
+				eventType,
+				props
+			}, (e) => {
+				typeof(fn) === 'function' && fn(e)
+			});
+		},
+		/**
+		 * 获取ref
+		 * @param {Object} el
+		 */
+		getEl(el) {
+			return el.ref
+		},
+		/**
+		 * 获取节点信息
+		 */
+		getSelectorQuery() {
+			dom.getComponentRect(this.$refs['selector-content-hock'], (data) => {
+				if (this.position.content) return
+				this.position.content = data.size
+			})
+			for (let i = 0; i < this.options.length; i++) {
+				dom.getComponentRect(this.$refs['button-hock'][i], (data) => {
+					if (!this.button) {
+						this.button = []
+					}
+					if (this.options.length === this.button.length) return
+					this.button.push(data.size)
+					this.right += data.size.width
+					if (this.autoClose) return
+					if (this.show) {
+						this.open()
+					}
+				})
+			}
+		}
+	}
+}

+ 186 - 0
components/uni-swipe-action/index.wxs

@@ -0,0 +1,186 @@
+/**
+ * 监听页面内值的变化,主要用于动态开关swipe-action
+ * @param {Object} newValue
+ * @param {Object} oldValue
+ * @param {Object} ownerInstance
+ * @param {Object} instance
+ */
+function sizeReady(newValue, oldValue, ownerInstance, instance) {
+	var state = instance.getState()
+	state.position = JSON.parse(newValue)
+	if (!state.position || state.position.length === 0) return
+	var show = state.position[0].show
+	// console.log("sizeReady:",state);
+	state.left = state.left || state.position[0].left;
+	// 通过用户变量,开启或关闭
+	if (show) {
+		openState(true, instance, ownerInstance)
+	} else {
+		openState(false, instance, ownerInstance)
+	}
+}
+
+/**
+ * 开始触摸操作
+ * @param {Object} e
+ * @param {Object} ins
+ */
+function touchstart(e, ins) {
+	var instance = e.instance;
+	var state = instance.getState();
+	var pageX = e.touches[0].pageX;
+	// 开始触摸时移除动画类
+	instance.removeClass('ani');
+	var owner = ins.selectAllComponents('.button-hock')
+	for (var i = 0; i < owner.length; i++) {
+		owner[i].removeClass('ani');
+	}
+	console.log(state);
+	// state.position = JSON.parse(instance.getDataset().position);
+	state.left = state.left || state.position[0].left;
+	// 获取最终按钮组的宽度
+	state.width = pageX - state.left;
+	ins.callMethod('openSwipe')
+}
+
+/**
+ * 开始滑动操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchmove(e, ownerInstance) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState()
+	console.log(state);
+	if (disabled) return
+	var pageX = e.touches[0].pageX;
+	move(pageX - state.width, instance, ownerInstance)
+}
+
+/**
+ * 结束触摸操作
+ * @param {Object} e
+ * @param {Object} ownerInstance
+ */
+function touchend(e, ownerInstance) {
+	var instance = e.instance;
+	var disabled = instance.getDataset().disabled
+	var state = instance.getState()
+	if (disabled) return
+	// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
+	moveDirection(state.left, -40, instance, ownerInstance)
+}
+
+/**
+ * 设置移动距离
+ * @param {Object} value
+ * @param {Object} instance
+ * @param {Object} ownerInstance
+ */
+function move(value, instance, ownerInstance) {
+	var state = instance.getState()
+	// 获取可滑动范围
+	var x = Math.max(-state.position[1].width, Math.min((value), 0));
+	state.left = x;
+	instance.setStyle({
+		transform: 'translateX(' + x + 'px)',
+		'-webkit-transform': 'translateX(' + x + 'px)'
+	})
+	// 折叠按钮动画
+	buttonFold(x, instance, ownerInstance)
+}
+
+/**
+ * 移动方向判断
+ * @param {Object} left
+ * @param {Object} value
+ * @param {Object} ownerInstance
+ * @param {Object} ins
+ */
+function moveDirection(left, value, ins, ownerInstance) {
+	var state = ins.getState()
+	var position = state.position
+	var isopen = state.isopen
+	if (!position[1].width) {
+		openState(false, ins, ownerInstance)
+		return
+	}
+	// 如果已经是打开状态,进行判断是否关闭,还是保留打开状态
+	if (isopen) {
+		if (-left <= position[1].width) {
+			openState(false, ins, ownerInstance)
+		} else {
+			openState(true, ins, ownerInstance)
+		}
+		return
+	}
+	// 如果是关闭状态,进行判断是否打开,还是保留关闭状态
+	if (left <= value) {
+		openState(true, ins, ownerInstance)
+	} else {
+		openState(false, ins, ownerInstance)
+	}
+}
+
+/**
+ * 设置按钮移动距离
+ * @param {Object} value
+ * @param {Object} instance
+ * @param {Object} ownerInstance
+ */
+function buttonFold(value, instance, ownerInstance) {
+	var ins = ownerInstance.selectAllComponents('.button-hock');
+	var state = instance.getState();
+	var position = state.position;
+	var arr = [];
+	var w = 0;
+	for (var i = 0; i < ins.length; i++) {
+		if (!ins[i].getDataset().button) return
+		var btnData = JSON.parse(ins[i].getDataset().button)
+		var button = btnData[i] && btnData[i].width || 0
+		w += button
+		arr.push(-w)
+		// 动态计算按钮组每个按钮的折叠动画移动距离
+		var distance = arr[i - 1] + value * (arr[i - 1] / position[1].width)
+		if (i != 0) {
+			ins[i].setStyle({
+				transform: 'translateX(' + distance + 'px)',
+			})
+		}
+	}
+}
+
+/**
+ * 开启状态
+ * @param {Boolean} type
+ * @param {Object} ins
+ * @param {Object} ownerInstance
+ */
+function openState(type, ins, ownerInstance) {
+	var state = ins.getState()
+	var position = state.position
+	// 设置打开和移动状态
+	state.isopen = type
+
+	// 通知页面,已经打开
+	ownerInstance.callMethod('change', {
+		open: type
+	})
+	// 添加动画类
+	ins.addClass('ani');
+	var owner = ownerInstance.selectAllComponents('.button-hock')
+	for (var i = 0; i < owner.length; i++) {
+		owner[i].addClass('ani');
+	}
+	// 设置最终移动位置
+	move(type ? -position[1].width : 0, ins, ownerInstance)
+
+}
+
+module.exports = {
+	sizeReady: sizeReady,
+	touchstart: touchstart,
+	touchmove: touchmove,
+	touchend: touchend
+}

+ 83 - 0
components/uni-swipe-action/mp.js

@@ -0,0 +1,83 @@
+export default {
+	data() {
+		return {
+			position: [],
+			button: []
+		}
+	},
+	computed: {
+		pos() {
+			return JSON.stringify(this.position)
+		},
+		btn() {
+			return JSON.stringify(this.button)
+		}
+	},
+	watch: {
+		show(newVal) {
+			if (this.autoClose) return
+			let valueObj = this.position[0]
+			if (!valueObj) return
+			valueObj.show = newVal
+			this.$set(this.position, 0, valueObj)
+		}
+	},
+	mounted() {
+		this.init()
+		setTimeout(()=>{
+			this.getSize()
+			this.getButtonSize()
+		},50)
+	
+	},
+	methods: {
+		init() {
+			uni.$on('__uni__swipe__event', (res) => {
+				if (res !== this && this.autoClose) {
+					let valueObj = this.position[0]
+					valueObj.show = false
+					this.$set(this.position, 0, valueObj)
+				}
+			})
+		},
+		openSwipe() {
+			uni.$emit('__uni__swipe__event', this)
+		},
+		change(e) {
+			this.$emit('change', e.open)
+			let valueObj = this.position[0]
+			valueObj.show = e.open
+			this.$set(this.position, 0, valueObj)
+			// console.log('改变', e);
+		},
+		onClick(index, item) {
+			this.$emit('click', {
+				content: item,
+				index
+			})
+		},
+		getSize() {
+			const views = uni.createSelectorQuery().in(this)
+			views
+				.selectAll('.selector-query-hock')
+				.boundingClientRect(data => {
+					if (this.autoClose) {
+						data[0].show = false
+					} else {
+						data[0].show = this.show
+					}
+					this.position = data
+				})
+				.exec()
+		},
+		getButtonSize() {
+			const views = uni.createSelectorQuery().in(this)
+			views
+				.selectAll('.button-hock')
+				.boundingClientRect(data => {
+					this.button = data
+				})
+				.exec()
+		}
+	}
+}

+ 160 - 0
components/uni-swipe-action/mpother.js

@@ -0,0 +1,160 @@
+// #ifdef APP-NVUE
+const dom = weex.requireModule('dom');
+// #endif
+export default {
+	data() {
+		return {
+			uniShow: false,
+			left: 0
+		}
+	},
+	computed: {
+		moveLeft() {
+			return `translateX(${this.left}px)`
+		}
+	},
+	watch: {
+		show(newVal) {
+			if (!this.position || JSON.stringify(this.position) === '{}') return;
+			if (this.autoClose) return
+			if (newVal) {
+				this.$emit('change', true)
+				this.open()
+			} else {
+				this.$emit('change', false)
+				this.close()
+			}
+			uni.$emit('__uni__swipe__event', this)
+		}
+	},
+	mounted() {
+		this.position = {}
+		this.init()
+
+		setTimeout(()=>{
+			this.getSelectorQuery()
+		},100)
+	},
+	beforeDestoy() {
+		uni.$off('__uni__swipe__event')
+	},
+	methods: {
+		init() {
+			uni.$on('__uni__swipe__event', (res) => {
+				if (res !== this && this.autoClose) {
+					if (this.left !== 0) {
+						this.close()
+					}
+				}
+			})
+		},
+		onClick(index, item) {
+			this.$emit('click', {
+				content: item,
+				index
+			})
+		},
+		touchstart(e) {
+			const {
+				pageX
+			} = e.touches[0]
+			if (this.disabled) return
+			const left = this.position.content.left
+			uni.$emit('__uni__swipe__event', this)
+			this.width = pageX - left
+			if (this.isopen) return
+			if (this.uniShow) {
+				this.uniShow = false
+				this.isopen = true
+				this.openleft = this.left + this.position.button.width
+			}
+		},
+		touchmove(e, index) {
+			if (this.disabled) return
+			const {
+				pageX
+			} = e.touches[0]
+			this.setPosition(pageX)
+		},
+		touchend() {
+			if (this.disabled) return
+			if (this.isopen) {
+				this.move(this.openleft, 0)
+				return
+			}
+			this.move(this.left, -40)
+		},
+		setPosition(x, y) {
+			if (!this.position.button.width) {
+				return
+			}
+			// this.left = x - this.width
+			this.setValue(x - this.width)
+		},
+		setValue(value) {
+			// 设置最大最小值
+			this.left = Math.max(-this.position.button.width, Math.min(parseInt(value), 0))
+			this.position.content.left = this.left
+			if (this.isopen) {
+				this.openleft = this.left + this.position.button.width
+			}
+		},
+		move(left, value) {
+			if (left >= value) {
+				this.$emit('change', false)
+				this.close()
+			} else {
+				this.$emit('change', true)
+				this.open()
+			}
+		},
+		open() {
+			this.uniShow = true
+			this.left = -this.position.button.width
+			this.setValue(-this.position.button.width)
+		},
+		close() {
+			this.uniShow = true
+			this.setValue(0)
+			setTimeout(() => {
+				this.uniShow = false
+				this.isopen = false
+			}, 300)
+		},
+		getSelectorQuery() {
+			// #ifndef APP-NVUE
+			const views = uni.createSelectorQuery()
+				.in(this)
+			views
+				.selectAll('.selector-query-hock')
+				.boundingClientRect(data => {
+					this.position.content = data[1]
+					this.position.button = data[0]
+					if (this.autoClose) return
+					if (this.show) {
+						this.open()
+					} else {
+						this.close()
+					}
+				})
+				.exec()
+			// #endif
+			// #ifdef APP-NVUE
+			dom.getComponentRect(this.$refs['selector-content-hock'], (data) => {
+				if (this.position.content) return
+				this.position.content = data.size
+			})
+			dom.getComponentRect(this.$refs['selector-button-hock'], (data) => {
+				if (this.position.button) return
+				this.position.button = data.size
+				if (this.autoClose) return
+				if (this.show) {
+					this.open()
+				} else {
+					this.close()
+				}
+			})
+			// #endif
+		}
+	}
+}

+ 214 - 0
components/uni-swipe-action/uni-swipe-action.vue

@@ -0,0 +1,214 @@
+<template>
+	<view class="uni-swipe">
+		<!-- #ifndef APP-PLUS || MP-WEIXIN || H5 -->
+		<view class="uni-swipe_content">
+			<view ref="selector-button-hock" class="uni-swipe_button-group selector-query-hock move-hock">
+				<view v-for="(item,index) in options" :data-button="btn" :key="index" :style="{
+		    backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+		    fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+		  }" class="uni-swipe_button button-hock" @click.stop="onClick(index,item)">
+		  <!-- <text class="uni-swipe_button-text" :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text> -->
+		  <block v-if="item.bShowDeleteIcon">
+		  	<view style="width: 100rpx;">
+		  		<view class="cuIcon-delete text-white text-center"></view>
+		  	</view>
+		  </block>
+		  <block v-else>
+		  	<text class="uni-swipe_button-text" :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
+		  </block>
+		  </view>
+			</view>
+			<view ref='selector-content-hock' class="selector-query-hock" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
+				<view class="uni-swipe_move-box" :class="{'ani':uniShow}" :style="{transform:moveLeft}">
+					<view class="uni-swipe_box">
+						<slot />
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- #endif -->
+		<!-- #ifdef APP-VUE|| MP-WEIXIN||H5 -->
+		<view class="uni-swipe_content">
+			<view :data-disabled="disabled" :data-position="pos" :change:prop="swipe.sizeReady" :prop="pos" class="uni-swipe_move-box selector-query-hock move-hock" @touchstart="swipe.touchstart" @touchmove="swipe.touchmove" @touchend="swipe.touchend" @change="change">
+				<view class="uni-swipe_box">
+					<slot />
+				</view>
+				<view ref="selector-button-hock" class="uni-swipe_button-group selector-query-hock move-hock">
+					<view v-for="(item,index) in options" :data-button="btn" :key="index" :style="{
+		          backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+		          fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
+		        }" class="uni-swipe_button button-hock" @click.stop="onClick(index,item)">
+				
+					<block v-if="item.bShowDeleteIcon">
+						<view style="width: 100rpx;">
+							<view class="cuIcon-delete text-white text-center"></view>
+						</view>
+					</block>
+					<block v-else>
+						<text class="uni-swipe_button-text" :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
+					</block>
+
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- #endif -->
+		<!-- #ifdef APP-NVUE -->
+		<view ref="selector-box-hock" class="uni-swipe_content" @horizontalpan="touchstart" @touchend="touchend">
+			<view ref="selector-button-hock" class="uni-swipe_button-group selector-query-hock move-hock" :style="{width:right+'px'}">
+				<view ref="button-hock" v-for="(item,index) in options" :key="index" :style="{
+		  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
+		  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px',left: right+'px'
+		}" class="uni-swipe_button " @click.stop="onClick(index,item)">
+		<!-- <text class="uni-swipe_button-text" :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text> -->
+		<block v-if="item.bShowDeleteIcon">
+			<view style="width: 100rpx;">
+				<view class="cuIcon-delete text-white text-center"></view>
+			</view>
+		</block>
+		<block v-else>
+			<text class="uni-swipe_button-text" :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
+		</block>
+		</view>
+			</view>
+			<view ref='selector-content-hock' class="uni-swipe_move-box selector-query-hock">
+				<view class="uni-swipe_box">
+					<slot />
+				</view>
+			</view>
+
+		</view>
+		<!-- #endif -->
+
+	</view>
+</template>
+<script src="./index.wxs" module="swipe" lang="wxs"></script>
+<script>
+	// #ifndef APP-PLUS|| MP-WEIXIN || H5
+	import mixins from './mpother'
+	// #endif
+	// #ifdef APP-VUE|| MP-WEIXIN||H5
+	import mp from './mp'
+	// #endif
+	// #ifdef APP-NVUE
+	import bindingx from './bindingx.js'
+	// #endif
+	export default {
+		// #ifdef APP-VUE|| MP-WEIXIN||H5
+		mixins: [mp],
+		// #endif
+		// #ifdef APP-NVUE
+		mixins: [bindingx],
+		// #endif
+		// #ifndef APP-PLUS|| MP-WEIXIN || H5
+		mixins: [mixins],
+		// #endif
+
+		props: {
+			/**
+			 * 按钮内容
+			 */
+			options: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			/**
+			 * 禁用
+			 */
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			/**
+			 * 变量控制开关
+			 */
+			show: {
+				type: Boolean,
+				default: false
+			},
+			/**
+			 * 是否自动关闭
+			 */
+			autoClose: {
+				type: Boolean,
+				default: true
+			}
+		}
+	}
+</script>
+<style scoped>
+	.uni-swipe {
+		overflow: hidden;
+	}
+
+	.uni-swipe_content {
+		flex: 1;
+		position: relative;
+	}
+
+	.uni-swipe_move-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		position: relative;
+		flex-direction: row;
+	}
+
+	.uni-swipe_box {
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		flex-shrink: 0;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		flex: 1;
+		/* #endif */
+		font-size: 14px;
+		/* background-color: #fff; */
+	}
+
+	.uni-swipe_button-group {
+		/* #ifndef APP-VUE|| MP-WEIXIN||H5 */
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 0;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex-shrink: 0;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-swipe_button {
+		/* #ifdef APP-NVUE */
+		position: absolute;
+		left: 0;
+		top: 0;
+		bottom: 0;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		padding: 0 20px;
+	}
+
+	.uni-swipe_button-text {
+		/* #ifndef APP-NVUE */
+		flex-shrink: 0;
+		/* #endif */
+		font-size: 14px;
+	}
+
+	.ani {
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
+	}
+</style>

+ 18 - 0
main.js

@@ -0,0 +1,18 @@
+import Vue from 'vue'
+import App from './App'
+
+import store from './util/util-js/store.js'
+
+
+Vue.config.productionTip = false
+
+Vue.prototype.$store = store
+
+
+App.mpType = 'app'
+
+const app = new Vue({
+	store,
+    ...App
+})
+app.$mount()

+ 114 - 0
manifest.json

@@ -0,0 +1,114 @@
+{
+    "name" : "哔蹦",
+    "appid" : "__UNI__2635DF5",
+    "description" : "",
+    "versionName" : "2.3.14",
+    "versionCode" : 21042302,
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "popGesture" : "none",
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : false,
+            "waiting" : false,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {
+            "OAuth" : {},
+            "Bluetooth" : {}
+        },
+        /* 应用发布信息 */
+        "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_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>",
+                    "<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_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<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\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",
+                    "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {
+                "privacyDescription" : {
+                    "NSPhotoLibraryUsageDescription" : "用户修改头像时,从相册中选择图片作为用户的头像",
+                    "NSBluetoothAlwaysUsageDescription" : "连接app外设产品时,需要开启蓝牙交互数据",
+                    "NSCameraUsageDescription" : "扫描二维码时,开启摄像头扫描二维码图片"
+                }
+            },
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "oauth" : {
+                    "weixin" : {
+                        "appid" : "wxa8b47e75812d2805",
+                        "appsecret" : "33611bfc5a1f13f39a862a1599d67f3d",
+                        "UniversalLinks" : ""
+                    },
+                    "apple" : {}
+                },
+                "ad" : {}
+            },
+            "splashscreen" : {
+                "androidStyle" : "default",
+                "android" : {
+                    "xxhdpi" : "",
+                    "xhdpi" : "D:/BaiduYunDownload/uniapp资源/splash.png"
+                }
+            },
+            "icons" : {
+                "android" : {
+                    "xhdpi" : "D:/BaiduYunDownload/uniapp资源/icon.png"
+                }
+            }
+        },
+        "nativePlugins" : {}
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "wxd6dfd60729d33d17",
+        "setting" : {
+            "urlCheck" : false,
+            "es6" : true,
+            "minified" : true
+        },
+        "usingComponents" : true,
+        "permission" : {},
+        "navigateToMiniProgramAppIdList" : [ "wx6898b48e0760935c" ]
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    }
+}

+ 245 - 0
pages.json

@@ -0,0 +1,245 @@
+{
+	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+		// {
+		//     "path" : "pages/fc-page/fc/fc",
+		//     "style" : {}
+		// },
+		// {
+		//     "path" : "pages/fc-page/fc-list/fc-list",
+		//     "style" : {}
+		// },
+		// {
+		//     "path" : "pages/personal-page/devices-update/devices-update",
+		//     "style" :                                                                                    
+		//     {
+		//         "navigationBarTitleText": "",
+		//         "enablePullDownRefresh": false
+		//     }
+		    
+		// },
+		// #ifdef APP-PLUS || H5
+		{
+			"path": "pages/Loading-page/Loading/Loading",
+			"style": {}
+		},
+		//app 相关注册页面
+		{
+			"path": "pages/login-page/login/login",
+			"style": {
+				"navigationBarTitleText": "登录"
+			}
+		},
+		{
+			"path": "pages/login-page/reg/reg",
+			"style": {
+				"navigationBarTitleText": "注册"
+			}
+		},
+		{
+			"path": "pages/login-page/main/main",
+			"style": {
+				"navigationBarTitleText": "我的"
+			}
+		},
+		{
+			"path": "pages/login-page/pwd/pwd",
+			"style": {
+				"navigationBarTitleText": "找回密码"
+			}
+		},
+		{
+			"path": "pages/login-page/user/user",
+			"style": {
+				"navigationBarTitleText": "我的"
+			}
+		},
+		// #endif
+		{
+			"path": "pages/personal-page/personal/personal",
+			"style": {
+				"navigationBarTitleText": "个人中心",
+				"app-plus": {
+					"bounce": "none"
+				},
+				"disableScroll": true
+			}
+		},
+		{
+			"path": "pages/game-page/game/game",
+			"style": {
+				"navigationBarTitleText": "游戏" 
+			}
+		},
+
+		{
+			"path": "pages/my-page/homepage/homepage",
+			"style": {
+				"navigationBarTitleText": "我的"
+			}
+		},
+		{
+			"path": "pages/my-page/userInfo/userInfo",
+			"style": {
+				"navigationBarTitleText": "完善资料"
+			}
+		},
+
+		{
+			"path": "pages/personal-page/plan/plan",
+			"style": {
+				"navigationBarTitleText": "健身计划"
+			}
+		},
+
+		{
+			"path": "pages/personal-page/devices/devices",
+			"style": {
+				"navigationBarTitleText": "选中设备型号",
+				"enablePullDownRefresh": true
+			}
+		},
+		{
+			"path": "pages/conversion-page/conversion/conversion",
+			"style": {}
+		},
+		{
+			"path": "pages/personal-page/list/list",
+			"style": {}
+		}, {
+			"path": "pages/game-page/game-comment/game-comment",
+			"style": {
+				"navigationBarTitleText": "游戏评论"
+			}
+		}, {
+			"path": "pages/game-page/game-search/game-search",
+			"style": {
+				"navigationBarTitleText": "搜索"
+			}
+		},
+		{
+			"path": "pages/game-page/game-detail/game-detail",
+			"style": {
+				"navigationBarTitleText": "游戏详情"
+			}
+		},
+		// #ifdef H5
+		{
+			"path": "pages/game-page/game-play/game-play-web",
+			"style": {}
+		},
+		// #endif
+		// #ifdef APP-PLUS
+		{
+			"path": "pages/game-page/game-play-sub/game-play-sub",
+			"style": {
+				"app-plus": {
+					"titleNView": false,
+					"subNVues": [{
+						"id": "game",
+						"path": "pages/game-page/game-play-sub/subGame/subGame",
+						"type": "popup",
+						"style": {
+							"width": "100%",
+							"position":"absolute"
+						}
+					}]
+				}
+				
+			}
+		},
+		// #endif
+		{
+			"path": "pages/personal-page/favorites/favorites",
+			"style": {
+				"navigationBarTitleText": "我的关注"
+			}
+		}, {
+			"path": "pages/personal-page/more/more",
+			"style": {
+				"navigationBarTitleText": "我的设备"
+			}
+		}, {
+			"path": "pages/game-page/game-ranking/game-ranking",
+			"style": {}
+		}, {
+			"path": "pages/login-page/bindPhone/bindPhone",
+			"style": {}
+		}, {
+			"path": "pages/my-page/perfectInfo/perfectInfo",
+			"style": {}
+		}
+
+	    ,{
+            "path" : "pages/login-page/userAgreement/userAgreement",
+            "style" : {}
+        }
+        ,{
+            "path" : "pages/personal-page/devices-category/devices-category",
+            "style" : {}
+        }
+        ,{
+            "path" : "pages/personal-page/devices-hardware/devices-hardware",
+            "style" : {}
+        }
+        ,{
+            "path" : "pages/fc-page/fc/fc",
+            "style" : {}
+        }
+        ,{
+            "path" : "pages/fc-page/fc-list/fc-list",
+            "style" : {}
+        }
+        ,{
+            "path" : "pages/personal-page/devices-update/devices-update",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/info-page/app-info/app-info",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/my-page/firstPlan/firstPlan",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/login-page/feedback/feedback",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+    ],
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "uni-app",
+		"navigationBarBackgroundColor": "#FFFFFF",
+		"backgroundColor": "#F8F8F8",
+		"navigationStyle": "custom"
+	},
+	"condition": { //模式配置,仅开发期间生效
+		"current": 0, //当前激活的模式(list 的索引项)
+		"list": [{
+			"name": "", //模式名称
+			"path": "", //启动页面,必选
+			"query": "" //启动参数,在页面的onLoad函数里面得到
+		}]
+	}
+
+}

+ 103 - 0
pages/Loading-page/Loading/Loading.vue

@@ -0,0 +1,103 @@
+<!-- 初始化判断页面 -->
+<template>
+	<view>
+		<view class="loading-container-bg">
+			<!-- <image mode="aspectFill" src="../../../static/loading.jpg"></image> -->
+		</view>
+	</view>
+</template>
+
+<script>
+	import config from '../../../common/config.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+	export default {
+		data() {
+			return {}
+		},
+		computed: mapState(['bNewUser']),
+		onLoad() {},
+		onShow() {
+			let bCanLoading = false;
+			//验证登录存储
+			//如果登录过,直接跳转登录页面
+			const value = uni.getStorageSync('token');
+			var _self = this;
+			if (value) {
+				console.log("验证登录Token值:",value,config.URL.VERIFICATION);
+				reqUtil.requestData(config.URL.VERIFICATION, {
+					token: value
+				}).then(res => {
+						console.log('requestData VERIFICATION =====', res);
+
+						if (res.code == 0) {
+							// TODO token时效性问题
+							_self.$store.state.token = value;
+							_self.$store.state.bNewUser = res.data.newUser;
+							_self.accountLogin(function() {
+								// console.log("======");
+								if (_self.bNewUser) {
+									_self.onNavTo("userInfo");
+								} else {
+									_self.onNavTo("personal");
+								}
+
+							});
+							
+
+						} else {
+							//如果token 不合法,不存在,跳转登录页面
+							_self.onNavTo("login");
+						}
+					},
+					e => {
+						console.log(e)
+					});
+			} else {
+				//如果没有token,进入登录界面
+				_self.onNavTo("login");
+			}
+			
+		},
+		methods: {
+			...mapMutations(['accountLogin']),
+			onNavTo(navType) {
+				// uni.hideToast();
+				if (navType == "userInfo") {
+					uni.redirectTo({
+						url: "../../my-page/userInfo/userInfo"
+					})
+				} else if (navType == "personal") {
+					uni.redirectTo({
+						url: "../../personal-page/personal/personal"
+					})
+				} else {
+					uni.redirectTo({
+						url: "../../login-page/login/login"
+					})
+				}
+
+			}
+		}
+	}
+</script>
+
+<style>
+	.loading-container-bg {
+		position: absolute;
+		left: 0;
+		top: 0;
+		bottom: 0;
+		right: 0;
+		width: 750rpx;
+		height: 100%;
+	}
+
+	.loading-container-bg image {
+		width: 100%;
+		height: 100%;
+	}
+</style>

+ 250 - 0
pages/conversion-page/conversion/conversion.vue

@@ -0,0 +1,250 @@
+<template>
+	<view class="">
+		<view class="conversion-bg">
+			<image src="/static/conversion-bg.png"></image>
+		</view>
+		<!-- #ifndef MP-ALIPAY -->
+		<view class="tower-swiper" :style="{'height':scrollHeight+'px'}" @touchmove="TowerMove" @touchstart="TowerStart"
+		 @touchend="TowerEnd">
+			<view class="tower-item" v-for="(item,index) in swiperList" :key="index" :style="[{'--index': item.zIndex,'--bottom':item.mLeft}]"
+			 :data-direction="direction">
+				<view class="swiper-item" @tap="onNavConver(item.page_type,$event)">
+					<image :src="item.url" mode="aspectFit" v-if="item.type=='image'"></image>
+				</view>
+			</view>
+		</view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	import {
+		mapState
+	} from 'vuex'
+	export default {
+		computed: mapState(['oldSwiperList']),
+		data() {
+
+			let tempList = [{
+				id: 0,
+				type: 'image',
+				url: '/static/conversion/personal.png',
+				name: "个人中心",
+				page_type: "personal",
+				zIndex: 2,
+				mLeft: 0
+			}, {
+				id: 1,
+				type: 'image',
+				url: '/static/conversion/game.png',
+				name: '游戏',
+				page_type: "game",
+				zIndex: 1,
+				mLeft: 1
+			}]
+			return {
+				cardCur: 0,
+				swiperList: tempList,
+				dotStyle: false,
+				towerStart: 0,
+				towerStartY: 0,
+				direction: '',
+				scrollHeight: 100,
+				bTouchMove: false,
+			}
+		},
+		onLoad() {
+			let _this = this
+			uni.getSystemInfo({
+				success(res) {
+					_this.scrollHeight = res.windowHeight;
+					console.log("res==", res)
+				}
+			})
+			
+			if (this.oldSwiperList.length != 0)
+				this.swiperList = this.oldSwiperList;
+
+		},
+		methods: {
+			// 初始化towerSwiper
+			TowerSwiper(name) {
+				let list = this[name];
+				for (let i = 0; i < list.length; i++) {
+					list[i].zIndex = list.length - i; // parseInt(list.length / 2) + 1 - Math.abs(i - parseInt(list.length / 2))
+					list[i].mLeft = i; //i - parseInt(list.length/2)
+					console.log(list[i].zIndex, list[i].mLeft, 0.5 + list[i].zIndex / 20);
+				}
+				this.swiperList = list
+			},
+			// towerSwiper触摸开始
+			TowerStart(e) {
+				this.towerStart = e.touches[0].pageX;
+				this.towerStartY = e.touches[0].pageY;
+			},
+
+			// towerSwiper计算方向
+			TowerMove(e) {
+				// 简化,点击及操作
+				this.direction = 'left'; // e.touches[0].pageX - this.towerStart > 0 ? 'right' : 'left'
+				let moveX = e.touches[0].pageX - this.towerStart > 0 ? true : false;
+
+				let moveY = e.touches[0].pageY - this.towerStartY > 0 ? true : false;
+
+				this.bTouchMove = moveX || moveY;
+			},
+			// towerSwiper计算滚动
+			TowerEnd(e) {
+
+				if (!this.bTouchMove) return;
+
+				let direction = this.direction;
+				let list = this.swiperList;
+				if (direction == 'right') {
+					let mLeft = list[0].mLeft;
+					let zIndex = list[0].zIndex;
+					for (let i = 1; i < this.swiperList.length; i++) {
+						this.swiperList[i - 1].mLeft = this.swiperList[i].mLeft
+						this.swiperList[i - 1].zIndex = this.swiperList[i].zIndex
+					}
+					this.swiperList[list.length - 1].mLeft = mLeft;
+					this.swiperList[list.length - 1].zIndex = zIndex;
+				} else {
+					let mLeft = list[list.length - 1].mLeft;
+					let zIndex = list[list.length - 1].zIndex;
+					for (let i = this.swiperList.length - 1; i > 0; i--) {
+						this.swiperList[i].mLeft = this.swiperList[i - 1].mLeft
+						this.swiperList[i].zIndex = this.swiperList[i - 1].zIndex
+					}
+					this.swiperList[0].mLeft = mLeft;
+					this.swiperList[0].zIndex = zIndex;
+					this.$store.state.oldSwiperList = this.swiperList;
+
+					console.log("this.$store.state.oldSwiperList=", this.$store.state.oldSwiperList);
+				}
+				this.direction = ""
+				this.swiperList = this.swiperList
+				this.bTouchMove = false;
+			},
+
+			// 跳转对应页面
+			onNavConver(type, event) {
+				console.log("===", type, event);
+				let url = '';
+				switch (type) {
+					case "personal":
+						//个人中心页面
+						url = '../../personal-page/personal/personal';
+						break;
+					case "game":
+						url = '../../game-page/game/game';
+						break;
+					default:
+						url = '../../personal-page/personal/personal';
+						break;
+				}
+				uni.reLaunch({
+					url: url,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	.conversion-container {
+		position: relative;
+	}
+
+	.conversion-bg {
+		position: absolute;
+		left: 0;
+		top: 0;
+		bottom: 0;
+		right: 0;
+		width: 750rpx;
+		height: 100%;
+	}
+
+	.conversion-bg image {
+		width: 100%;
+		height: 100%;
+	}
+
+	.tower-swiper .tower-item {
+		transform: scale(calc(0.6 + var(--index)/10));
+		margin-bottom: calc(var(--bottom) * 70px - 100px);
+		z-index: var(--index);
+	}
+
+
+	.swiper-item image,
+	.swiper-item video {
+		width: 100%;
+		display: block;
+		height: 100%;
+		margin: 0;
+		pointer-events: none;
+	}
+
+
+
+	swiper-item {
+		width: 610upx !important;
+		left: 70upx;
+		box-sizing: border-box;
+		padding: 40upx 0upx 70upx;
+		overflow: initial;
+	}
+
+	swiper-item .swiper-item {
+		width: 100%;
+		display: block;
+		height: 100%;
+		border-radius: 10upx;
+		transform: scale(0.9);
+		transition: all 0.2s ease-in 0s;
+		overflow: hidden;
+	}
+
+	swiper-item.cur .swiper-item {
+		transform: none;
+		transition: all 0.2s ease-in 0s;
+	}
+
+
+	.tower-swiper {
+		height: 1334upx;
+		position: relative;
+		max-width: 750upx;
+		overflow: hidden;
+
+		/* background-color: #007AFF; */
+	}
+
+	/* 	.tower-swiper .tower-item {
+		position: absolute;
+		width: 750upx;
+		height: 100%;
+		top: 0;
+		bottom: 10%;
+		left: 0;
+		margin: auto;
+		transition: all 0.2s ease-in 0s;
+		opacity: 1;
+	} */
+
+	.tower-swiper .tower-item.none {
+		/* opacity: 0; */
+	}
+
+	.tower-swiper .tower-item .swiper-item {
+		width: 100%;
+		height: 100%;
+		border-radius: 45upx;
+		overflow: hidden;
+	}
+</style>

+ 311 - 0
pages/fc-page/fc-list/fc-list.vue

@@ -0,0 +1,311 @@
+<template>
+	<view>
+
+		<uni-nav-bar id="nav-bar" status-bar="true" backgroundColor="rgba(255, 255,255, 255)" @clickLeft="onBack()"
+		 @clickRight="onDownLoad()" fixed="true">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+			<view slot="middle" class="uni-navbar__header-container">
+				<view class="uni-navbar__header-container-inner">
+					<view>
+						<text>我的游戏</text>
+					</view>
+					<view class="flex align-center text-13px margin-left-sm" @click="togglePopup('top', 'popup')">
+						<image class="b-down-arrow" src="../../../static/down-arrow@2x.png"></image>
+					</view>
+				</view>
+
+			</view>
+			<view slot="right">
+				<view class="flex align-center text-13px" style="margin-right: 20rpx;">
+					<image class="png-more" style="width: 50rpx;height: 40rpx;" src="../../../static/download@2x.png"></image>
+				</view>
+			</view>
+		</uni-nav-bar>
+
+		<view style="position: relative;" v-for="(item, index) in FCList" :key="index" :data-id="index">
+			<view class="fc-list-container">
+				<view class="fc-list-body">
+					<view class="flex">
+						<image class="data-png-64" :src="item.gamePicture"></image>
+						<view style="display: flex;flex-direction: column;">
+							<text class="cont">{{item.gameName}}</text>
+							<view style="padding-left: 5px;">
+								<text class="cont-blue">{{item.suffix}}</text>
+								<text class="cont-blue">{{item.type}}</text>
+							</view>
+						</view>
+					</view>
+					<view class="fc-list-start-button">
+						启动
+					</view>
+				</view>
+			</view>
+			<uni-swipe-action :options="options1" style="border: 1rpx solid #000000; z-index: 10000;">
+				<view style="height: 200rpx;"></view>
+			</uni-swipe-action>
+
+		</view>
+		<uni-popup :show="showpopup" type="top" @change="changePopup">
+			<view style="display: flex;justify-content: center;" @click="changePopup({
+				show: false
+			})">
+				<view class="popup-content" @click.stop="clear">
+					<view class="popup-item " v-for="(item, index) in popupList" :key="index" :data-id="index" :class="index == popupList.length-1?'':'solid-bottom'">
+						<view style="padding: 10px; " :class="index == 0?'make-text-bPurple':''">{{item.name}}</view>
+					</view>
+					<view class="triangle"></view>
+				</view>
+
+			</view>
+
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	import uniSwipeAction from '@/components/uni-swipe-action/uni-swipe-action.vue';
+	import uniNavBar from '@/components/uni-nav-bar/uni-nav-bar.vue';
+	import uniPopup from '@/components/uni-popup/uni-popup.vue'
+
+	export default {
+		components: {
+			uniSwipeAction,
+			uniNavBar,
+			uniPopup
+		},
+		data() {
+			return {
+				isOpened: false,
+				options1: [{
+					text: '删除',
+					bShowDeleteIcon: true,
+					style: {
+						backgroundColor: 'rgb(255,58,49)'
+					}
+				}],
+				showpopup: false,
+				showtip: false,
+				showimage: false,
+				showshare: false,
+				type: '',
+				list: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
+				popupList: [{
+					id: 0,
+					name: "全部游戏",
+					type: 0,
+				}, {
+					id: 0,
+					name: "FC",
+					type: 0,
+				}, {
+					id: 0,
+					name: "MD",
+					type: 0,
+				}, {
+					id: 0,
+					name: "GBA",
+					type: 0,
+				}, {
+					id: 0,
+					name: "PS",
+					type: 0,
+				}, {
+					id: 0,
+					name: "GBC",
+					type: 0,
+				}, {
+					id: 0,
+					name: "MAME",
+					type: 0,
+				}, {
+					id: 0,
+					name: "NDS",
+					type: 0,
+				}],
+				content: '顶部弹 popup',
+				//我的fc游戏列表
+				FCList: []
+			}
+		},
+		onReady() {
+			this.$nextTick(() => {
+				this.isOpened = true
+			})
+
+			this.onGetStoreFCList();
+		},
+		methods: {
+			clear() {},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			onDownLoad() {
+
+			},
+
+			bindClick(e) {
+				console.log(e)
+				uni.showToast({
+					title: `点击了${e.content.text}按钮`,
+					icon: 'none'
+				})
+			},
+			setOpened() {
+				this.isOpened = !this.isOpened
+			},
+			change(e) {
+				this.isOpened = e
+			},
+			togglePopup(type, open) {
+				this['show' + open] = true
+			},
+			cancelPopup(type) {
+				this['show' + type] = false
+			},
+			changePopup(e) {
+				console.log('是否打开:' + e.show)
+				if (!e.show) {
+					this.showpopup = false
+					this.showtip = false
+					this.showimage = false
+					this.showshare = false
+				}
+			},
+			onGetStoreFCList() {
+				//todo 下载完成,设置记录数据到本地,
+
+				//#ifdef H5
+				this.FCList = uni.getStorageSync("FCList");
+				//#endif
+
+				//#ifdef APP-PLUS
+				this.FCList = plus.storage.getItem("FCList");
+				//#endif
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-navbar__header-container {
+		flex: 1;
+	}
+
+	.uni-navbar__header-container-inner {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		font-size: 15px;
+	}
+
+	.fc-list-container {
+		position: absolute;
+		width: 100%;
+		background-color: #FFFFFF;
+	}
+
+	.fc-list-body {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		height: 200rpx;
+		margin: 0 20px;
+		border-bottom: 1rpx solid #eee;
+	}
+
+	.fc-list-start-button {
+		width: 60px;
+		height: 36px;
+		font-size: 16px;
+		line-height: 36px;
+		background-color: #F5E003;
+		text-align: center;
+		border-radius: 12rpx;
+	}
+
+
+	/* #ifndef APP-NVUE */
+	page {
+		display: flex;
+		flex-direction: column;
+		box-sizing: border-box;
+		background-color: #efeff4;
+		min-height: 100%;
+		height: auto;
+	}
+
+	view {
+		font-size: 28rpx;
+		line-height: inherit;
+	}
+
+	/* #endif */
+
+
+	.cont {
+		height: 45px;
+		line-height: 45px;
+		padding: 0 15px;
+		position: relative;
+		background-color: #fff;
+		font-size: 15px;
+		/* border-bottom-color: #F5F5F5; */
+		/* border-bottom-width: 1px; */
+		/* border-bottom-style: solid; */
+	}
+
+	.cont-blue {
+		height: 20px;
+		line-height: 20px;
+		padding: 0 10px;
+		position: relative;
+		color: #2B95FF;
+		font-size: 15px;
+		/* border-bottom-color: #F5F5F5; */
+		/* border-bottom-width: 1px; */
+		/* border-bottom-style: solid; */
+	}
+
+
+	.popup-content {
+		background-color: #fff;
+		padding: 5px;
+		font-size: 14px;
+		width: 250rpx;
+		/* border: 1rpx solid #007AFF; */
+		margin-top: 70px;
+		position: relative;
+		border-radius: 12rpx;
+	}
+
+	/* clip-path属性可以创建一个只有元素的部分区域可以显示的剪切区域 */
+	.triangle {
+		display: block;
+		height: 20px;
+		width: 20px;
+		background-color: inherit;
+		border: inherit;
+		position: absolute;
+		top: -5px;
+		left: calc(50% - 10px);
+		// ---关键代码 start---
+		clip-path: polygon(0% 0%, 100% 100%, 0% 100%);
+		transform: rotate(135deg);
+		// ---end---
+		border-radius: 0 0 0 2px;
+	}
+
+	.popup-item {
+		align-items: center;
+		text-align: center;
+	}
+</style>

+ 702 - 0
pages/fc-page/fc/fc.vue

@@ -0,0 +1,702 @@
+<template>
+	<view>
+		<!--  rgba(116, 172, 240, 1)-->
+		<uni-nav-bar id="nav-bar" :status-bar="true" :border="false" @clickLeft="onBack()" @clickRight="onNavConver" title="全部游戏"
+		 :fixed="true">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+			<view slot="right">
+				<view class="align-center text-13px" style="width: 130rpx;">
+					我的游戏
+				</view>
+			</view>
+		</uni-nav-bar>
+		<view class="cu-bar search bg-white">
+			<view class="search-form ">
+				<text class="cuIcon-search"></text>
+				<!-- @focus="InputFocus" @blur="InputBlur" -->
+				<input :adjust-position="false" type="text" placeholder="搜索游戏" confirm-type="search"></input>
+			</view>
+
+		</view>
+		<view class="scrollX">
+			<scroll-view scroll-x class="bg-white nav scrollX-padding" scroll-with-animation :scroll-left="scrollLeft">
+				<view class="cu-item text-15px" :class="index == TabCur ? 'text-bold black text-22px' : 'cu-color'" v-for="(item, index) in tabList"
+				 :key="index" @tap="tabSelect" :data-id="index" :data-category_id="item.categoryType" >
+					{{ item.categoryName }}
+				</view>
+			</scroll-view>
+		</view>
+		<button @click="getFile">getFile</button>
+		<button @click="navGame">game</button>
+		<scroll-view scroll-y="true" :style="{ height: scrollviewHigh + 'px' }" @scrolltolower="lower">
+
+			<view class="fc-list">
+				<view class="fc-li" v-for="(item, index) in gameList" :key="index" :data-id="index" @tap="onNavToWebviewGame(item)">
+					<image mode="aspectFill" class="game-item-image" :src="item.gamePicture"></image>
+
+					<view class="fc-bottom-container">
+						<view class="text-center text-white text-bold">{{item.gameName}}</view>
+						<view class="text-center text-white">{{item.gamePlayNum}}人在玩</view>
+					</view>
+
+					<view v-if="item.bDownload" class="play-bg-download">
+						<view class="text-center text-white text-bold">下载中...</view>
+						<view class="text-center text-white text-bold margin-sm">{{item.progressVal}}%</view>
+					</view>
+				</view>
+			</view>
+
+			<view v-if="gameList.length == 0" class="text-16px text-gray text-center margin">没有更多数据</view>
+			<view style="height: 17px;"></view>
+		</scroll-view>
+		<!-- https://www.yuyekeji.cn/Cocos/TestDownload -->
+		<!-- <view class="web-view">
+			<web-view class="web-view-child" src = 'https://www.yuyekeji.cn/Cocos/TestEmulatrix15'></web-view>
+		</view> -->
+
+	</view>
+</template>
+
+<script>
+	import uniNavBar from '@/components/uni-nav-bar/uni-nav-bar.vue';
+	import sideBar from '@/components/side-bar/side-bar.vue';
+	import config from '../../../common/config.js';
+	import reqUtil from '../../../util/util-js/requstUtil.js';
+	import roundMenu from "@/components/round-menu/round-menu.vue";
+
+	import {
+		mapState
+	} from 'vuex';
+
+	export default {
+		components: {
+			uniNavBar,
+			sideBar,
+			roundMenu
+		},
+		computed: mapState(['ConnectBindingDevice', 'BLEConnectDevice', 'cIndex']),
+		data() {
+			return {
+				// tabList: [{
+				// 	categoryType: 1,
+				// 	categoryName: "全部"
+				// }, {
+				// 	categoryType: 1,
+				// 	categoryName: "热门"
+				// }, {
+				// 	categoryType: 1,
+				// 	categoryName: "对战"
+				// }, {
+				// 	categoryType: 1,
+				// 	categoryName: "最新"
+				// }, {
+				// 	categoryType: 1,
+				// 	categoryName: "益智"
+				// }, {
+				// 	categoryType: 1,
+				// 	categoryName: "单机"
+				// }],
+				tabList: [],
+				TabCur: 0,
+				Category: 0,
+				scrollLeft: 0,
+				scrollviewHigh: '',
+
+
+				bDontUpdate: false,
+
+				//游戏列表
+				gameList: [{
+					gameIcon: "/static/avatar/1.png",
+					gamePicture: "/static/conversion/game.png",
+					gameName: "giabbit.nes",
+					gamePlayNum: 100,
+					gameDownloadUrl: "https://www.yuyekeji.cn/Cocos/FCEmulator/roms/giabbit/giabbit.nes",
+					gameFileName: "giabbit",
+					suffix: "nes",
+					type: "NES",
+					task: null,
+					progressVal: 0,
+					bFileExists: false,
+					bDownload: false,
+				}, {
+					gameIcon: "/static/avatar/1.png",
+					gamePicture: "/static/conversion/game.png",
+					gameName: "giabbit.nes",
+					gamePlayNum: 100,
+					gameDownloadUrl: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4",
+					gameFileName: "big_buck_bunny",
+					suffix: "mp4",
+					type: "mp4",
+					task: null,
+					progressVal: 0,
+					bFileExists: false,
+					bDownload: false,
+				}],
+				gamePage: 1,
+				gameSize: 10,
+
+				//编码的item
+				encodeItem: ''
+			};
+		},
+		onLoad(option) {
+			let _this = this;
+			// 	console.log("option========:", option);
+			// 	let _index = 1;
+			// 	if (option && option.type) {
+			// 		if (option.type == "game") {
+			// 			_index = 1;
+			// 		} else if (option.type == "video") {
+			// 			_index = 2;
+			// 		}
+			// 	}
+
+			//获得游戏类目
+			reqUtil.requestData(config.URL.FCCATEGORYBYTYPE,{categoryType:1}).then(
+				res => {
+					// console.log('FCCATEGORYBYTYPE =====', res);
+					if (res.code == 0) {
+						this.tabList = res.data;
+						this.TabCur = 0;
+						this.categoryType = this.tabList[0].categoryType;
+						this.getGameList(this.categoryType);
+					}
+				},
+				e => {
+					console.log(e);
+				}
+			);
+
+		},
+		onReady() {
+			let _this = this;
+			uni.getSystemInfo({
+				success(res) {
+					// 计算组件的高度
+					let view = uni.createSelectorQuery().select('#nav-bar');
+					view.boundingClientRect(data => {
+						let navHeight = data.height;
+						let scrollXHight = uni.upx2px(90);
+						_this.scrollviewHigh = res.windowHeight - navHeight - scrollXHight;
+					}).exec();
+				}
+			});
+		},
+		methods: {
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			// 跳转转换页面
+			onNavConver() {
+				uni.navigateTo({
+					url: '../fc-list/fc-list',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+			tabSelect(e) {
+				if (this.TabCur != e.currentTarget.dataset.id) {
+					//重新设置参数
+					this.bDontUpdate = false;
+					this.gameList = [];
+					this.gamePage = 1;
+					this.gameSize = 10;
+					this.TabCur = e.currentTarget.dataset.id;
+					this.categoryType = e.currentTarget.dataset.category_id;
+					this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60;
+					this.getGameList(this.categoryType);
+				}
+
+			},
+			showClickEvent() {
+				this.$refs.sideBar.showModal();
+			},
+			onNavSearch() {
+
+				uni.showToast({
+					title: '功能尚未开放',
+					icon: 'none'
+				})
+				return;
+
+				uni.navigateTo({
+					url: '../game-search/game-search',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			//收藏
+			onFavoriteAdd(item) {
+				//添加收藏
+				let favoritesTemp = {
+					'fObjectId': item.gameId,
+					'favoritesType': 0,
+				}
+
+				reqUtil.requestData(config.URL.FAVORITESMODIFY, favoritesTemp).then(res => {
+						console.log('FAVORITESMODIFY =====', res);
+						if (res.code == 0) {
+							if (!res.data.bHas) {
+								item.gameFavorite = false;
+								uni.showToast({
+									title: "取消收藏",
+									icon: "none"
+								})
+							} else {
+								uni.showToast({
+									title: "收藏成功",
+									icon: "none"
+								})
+								item.gameFavorite = true;
+							}
+						}
+
+					},
+					e => {
+						console.log(e)
+					});
+			},
+			onNavComment() {
+				uni.showToast({
+					title: '功能尚未开放',
+					icon: 'none'
+				})
+				return;
+				uni.navigateTo({
+					url: '../game-comment/game-comment',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onNavDetail(item) {
+				// console.log(item);
+				let temItem = encodeURIComponent(JSON.stringify(item));
+				// return;
+				uni.navigateTo({
+					url: '../game-detail/game-detail?item=' + temItem,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onNavToWebviewGame(item) {
+				//#ifdef H5 
+				console.log("h5");
+				let _FCList = uni.getStorageSync("FCList");
+				if (_FCList) {
+					item.task = null;
+					_FCList.push(item);
+					uni.setStorageSync("FCList", _FCList);
+				} else {
+					uni.setStorageSync("FCList", [item]);
+				}
+				//#endif
+
+				//#ifdef APP-PLUS
+				console.log("====item == ", item);
+				let downloadUrl = item.gameDownloadUrl;
+				let name = item.gameFileName;
+				item.task = plus.downloader.createDownload(downloadUrl, {
+					filename: '_doc/' + name
+				});
+				item.task.addEventListener("statechanged", (download, status) => {
+					// console.log("status", status);
+					//连接服务器后
+					// no default
+					switch (download.state) {
+						case 1:
+							console.log('开始下载');
+							// item.bDownload = true;
+							break;
+						case 2:
+							console.log('链接到服务器...');
+							item.bDownload = true;
+							break;
+						case 3:
+							if (status !== 200) {
+								uni.showToast({
+									title: 'status=' + status
+								})
+								return;
+							}
+							item.progressVal = Math.ceil(download.downloadedSize / download.totalSize * 100);
+							// _this.precent = progressVal;
+							console.log(item.progressVal);
+							break;
+						case 4:
+							// 下载完成
+							console.log("监听下载 success: " + download.getFileName());
+							setTimeout(() => {
+								item.bDownload = false;
+							}, 500)
+							//todo 下载完成,设置记录数据到本地,
+							let _FCList = plus.storage.getItem("FCList");
+							console.log("_FCList:", _FCList);
+							if (_FCList) {
+								item.task = null;
+								_FCList.push(item);
+								plus.storage.setItem("FCList", _FCList);
+								console.log("_FCList1:", _FCList);
+							} else {
+								plus.storage.setItem("FCList", [item])
+								console.log("_FCList2:", [item]);
+							}
+							break;
+					}
+				}, false);
+				item.task.start();
+
+				//#endif
+				return;
+
+				if (!this.BLEConnectDevice || this.cIndex == -1) {
+					uni.showToast({
+						title: "没有连接绑带,请连接后重试!",
+						icon: "none"
+					})
+					return;
+				}
+
+
+				reqUtil.requestData(config.URL.GAMEDETAIL, item).then(res => {
+						console.log('GAMEDETAIL =====', res);
+						if (res.code == 0) {
+							this.encodeItem = encodeURIComponent(JSON.stringify(res.data.gameInfo));
+
+							// #ifdef APP-PLUS
+							uni.navigateTo({
+								url: '../game-play-sub/game-play-sub?item=' + this.encodeItem,
+								success: res => {},
+								fail: () => {},
+								complete: () => {}
+							});
+							// #endif 
+							// #ifdef H5
+							uni.navigateTo({
+								url: '../game-play/game-play-web?item=' + this.encodeItem,
+								success: res => {},
+								fail: () => {},
+								complete: () => {}
+							});
+							// #endif
+						}
+
+					},
+					e => {
+						console.log(e)
+					});
+
+			},
+
+			getGameList(categoryType) {
+				uni.showToast({
+					icon: "loading",
+					title: "",
+					mask: true,
+					duration: 10000
+				})
+				//获得游戏列表
+				reqUtil.requestData(
+					config.URL.FCListByCategory, {
+						categoryNumber: categoryType,//类目编号
+						//endTime 可以不设置,服务器默认设置一个值
+						// endTime: config.endTime,
+						page: this.gamePage,
+						size: this.gameSize
+					}
+				).then(res => {
+						console.log('GAMELIST_FROM_CATEGORY =====', res);
+						if (res.code == 0) {
+							uni.hideToast();
+
+							if (res.data.length < this.gameSize) {
+								this.bDontUpdate = true;
+							}
+
+							if (res.data.length != 0) {
+								uni.showToast({
+									icon: "none",
+									title: "更新成功",
+								})
+							} else {
+								uni.showToast({
+									icon: "none",
+									title: "没数据啦",
+								})
+							}
+							this.gameList = this.gameList.concat(res.data);
+						}
+					},
+					e => {
+						console.log(e);
+						uni.showToast({
+							icon: "none",
+							title: "更新出错",
+						})
+					}
+				);
+			},
+
+			onRoundTrigger(data) {
+				console.log("onRoundTrigger==", data);
+				// return;
+				let url = '';
+				switch (data.item.type) {
+					case "personal":
+						//个人中心页面
+						url = '../../personal-page/personal/personal';
+						break;
+					case "game":
+						url = '../../game-page/game/game';
+						break;
+					default:
+						url = '../../personal-page/personal/personal';
+						break;
+				}
+				uni.reLaunch({
+					url: url,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			lower(e) {
+				return;
+				if (this.bDontUpdate) return;
+				console.log(e);
+				this.gamePage++;
+				this.getGameList(this.categoryType);
+			},
+			getFile() {
+				let url = "_doc/uniapp_save/1603173965127.nes";
+
+				uni.getSavedFileList({
+					success: function(res) {
+						console.log(res.fileList);
+						for (var i = 0, len = res.fileList.length; i < len; i++) {
+							var path = plus.io.convertLocalFileSystemURL(res.fileList[i].filePath);
+							console.log(path);
+						}
+					}
+				});
+			},
+			navGame() {
+				plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
+					// 可通过fs操作PRIVATE_DOC文件系统 
+					var directoryReader = fs.root.createReader();
+					directoryReader.readEntries(function(entries) {
+						var i;
+						for (i = 0; i < entries.length; i++) {
+							console.log(entries[i].name);
+						}
+					}, function(e) {
+						console.log("Read entries failed: " + e.message);
+					});
+				}, function(e) {
+					console.log("Request file system failed: ", e.message);
+				});
+			}
+		}
+	};
+</script>
+
+<style>
+	.page {
+		height: 100vh;
+	}
+
+	page {
+		background-color: #fff;
+	}
+
+	.float-png {
+		position: absolute;
+		right: 15px;
+		bottom: 200px;
+		width: 56px;
+		height: 56px;
+	}
+
+	.png-search {
+		width: 50rpx;
+		height: 100%;
+		position: absolute;
+		right: 20px;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.scrollX {
+		position: relative;
+		width: 100%;
+		height: 90rpx;
+		margin-bottom: 10px;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.scrollX-padding {
+		padding: 0 20px;
+	}
+
+	.game-item {
+		/* display: flex; */
+		/* justify-content: space-between; */
+		/* flex-direction: row; */
+		/* background-color: white; */
+
+		flex: 0 0 33.3%;
+		max-width: 33.3%;
+		width: 226rpx;
+		height: 270rpx;
+		margin: 17px 10px 0 10px;
+		border: 1rpx solid #000000;
+		border-radius: 10rpx;
+		position: relative;
+		/* border-bottom: 1rpx solid rgba(240, 240, 240, 1); */
+	}
+
+	.game-item-image {
+		width: 100%;
+		height: 100%;
+		border-radius: 10rpx;
+		z-index: 99;
+	}
+
+	.head-image {
+		position: absolute;
+		bottom: -20px;
+		left: 0;
+		margin-left: 17px;
+		width: 80rpx;
+		height: 80rpx;
+		border: 2px solid white;
+		border-radius: 100px;
+		z-index: 100;
+	}
+
+	.play-bg-download {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		top: 0;
+		right: 0;
+		margin: auto;
+		background: rgba(0, 0, 0, 0.3);
+		z-index: 100;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		text-align: center;
+		border-radius: 12rpx;
+	}
+
+	.play-image {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		top: 0;
+		right: 0;
+		width: 44rpx;
+		height: 54rpx;
+		margin: auto;
+		z-index: 100;
+	}
+
+	.game-image-container {
+		position: relative;
+	}
+
+	.game-index {
+		z-index: 300;
+	}
+
+	.cu-color {
+		color: rgba(191, 191, 193, 1);
+	}
+
+	.right-png {
+		width: 36rpx;
+		height: 32rpx;
+	}
+
+	.fc-bottom-container {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		/* top: 0; */
+		right: 0;
+		width: 100%;
+		height: 80rpx;
+		border-radius: 0 0 10rpx 10rpx;
+		margin: auto;
+		z-index: 100;
+		background: linear-gradient(left, rgb(66, 202, 96), rgb(23, 193, 14));
+	}
+
+	.fc-list {
+		display: flex;
+		flex-wrap: wrap;
+		padding: 10px 10rpx 0px;
+		justify-content: flex-start;
+	}
+
+	.fc-li {
+		border-radius: 12rpx;
+		width: 32%;
+		height: 270rpx;
+		margin: 0 0 20rpx 8rpx;
+		position: relative;
+		z-index: 1;
+	}
+
+	.fc-li::after {
+		content: "";
+		position: absolute;
+		z-index: -1;
+		background-color: inherit;
+		width: 100%;
+		height: 100%;
+		left: 0;
+		bottom: -10%;
+		border-radius: 10upx;
+		opacity: 0.2;
+		transform: scale(0.9, 0.9);
+	}
+
+	.fc.cur {
+		color: #fff;
+		background: rgb(94, 185, 94);
+		box-shadow: 4upx 4upx 6upx rgba(94, 185, 94, 0.4);
+	}
+
+	.web-view {
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		border-style: solid;
+		border-width: 1rpx;
+		border: 1rpx solid #007AFF;
+	}
+
+	.web-view-child {
+		width: 650rpx;
+		height: 1280rpx;
+		/* flex: 1; */
+	}
+</style>

+ 135 - 0
pages/game-page/game-comment/game-comment.vue

@@ -0,0 +1,135 @@
+<template>
+	<view>
+		<!-- 自定义导航栏 -->
+		<uni-nav-bar id="nav-bar" status-bar="true"  @clickLeft="showClickEvent('DrawerModalL')"
+		 title="游戏" color="#FFFFFF" fixed="true">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="png-more" src="../../../static/more.png"></image>
+				</view>
+			</view>
+		
+			<view slot="right">
+		
+			</view>
+		</uni-nav-bar>
+		<view class="cu-bar bg-white">
+			<view class="action " @tap="onBack">
+				<text class="cuIcon-back text-gray"></text> 返回
+			</view>
+			<view class="content text-bold">
+				评论详情
+			</view>
+		</view>
+		<view class="cu-card dynamic no-card" >
+			<view class="cu-item shadow">
+				<view class="cu-list menu-avatar">
+					<view class="cu-item">
+						<view class="cu-avatar round lg" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big10006.jpg);"></view>
+						<view class="content flex-sub">
+							<view>凯尔</view>
+							<view class="text-gray text-sm flex justify-between">
+								2019年12月3日
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="text-content">
+					折磨生出苦难,苦难又会加剧折磨,凡间这无穷的循环,将有我来终结!
+				</view>
+				<view class="grid flex-sub padding-lr col-3 grid-square">
+					<view class="bg-img"  style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big10006.jpg);"
+					 v-for="(item,index) in 3" :key="index">
+					</view>
+				</view>
+				<view class="text-gray text-sm text-left padding">
+					<text class="cuIcon-attentionfill margin-lr-xs"></text> 10
+					<text class="cuIcon-appreciatefill margin-lr-xs"></text> 20
+					<text class="cuIcon-messagefill margin-lr-xs"></text> 30
+				</view>
+		
+				<view class="cu-list menu-avatar comment solids-top">
+					<view class="cu-item">
+						<view class="cu-avatar round" style="background-image:url(https://ossweb-img.qq.com/images/lol/img/champion/Morgana.png);"></view>
+						<view class="content">
+							<view class="text-grey">莫甘娜</view>
+							<view class="text-gray text-content text-df">
+								凯尔,你被自己的光芒变的盲目。
+							</view>
+							<view class="bg-grey padding-sm radius margin-top-sm  text-sm">
+								<view class="flex">
+									<view>凯尔:</view>
+									<view class="flex-sub">妹妹,你在帮他们给黑暗找借口吗?</view>
+								</view>
+							</view>
+							<view class="margin-top-sm flex justify-between">
+								<view class="text-gray text-df">2018年12月4日</view>
+								<view>
+									<text class="cuIcon-appreciatefill text-red"></text>
+									<text class="cuIcon-messagefill text-gray margin-left-sm"></text>
+								</view>
+							</view>
+						</view>
+					</view>
+		
+					<view class="cu-item">
+						<view class="cu-avatar round" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big10006.jpg);"></view>
+						<view class="content">
+							<view class="text-grey">凯尔</view>
+							<view class="text-gray text-content text-df">
+								妹妹,如果不是为了飞翔,我们要这翅膀有什么用?
+							</view>
+							<view class="bg-grey padding-sm radius margin-top-sm  text-sm">
+								<view class="flex">
+									<view>莫甘娜:</view>
+									<view class="flex-sub">如果不能立足于大地,要这双脚又有何用?</view>
+								</view>
+							</view>
+							<view class="margin-top-sm flex justify-between">
+								<view class="text-gray text-df">2018年12月4日</view>
+								<view>
+									<text class="cuIcon-appreciate text-gray"></text>
+									<text class="cuIcon-messagefill text-gray margin-left-sm"></text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<sideBar ref="sideBar">
+			
+		</sideBar>
+	</view>
+</template>
+
+<script>
+	import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue";
+	import sideBar from "@/components/side-bar/side-bar.vue";
+	
+	export default {
+		components: {
+			uniNavBar,
+			sideBar
+		},
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			showClickEvent(){
+				this.$refs.sideBar.showModal();
+			},
+			onBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 358 - 0
pages/game-page/game-detail/game-detail.vue

@@ -0,0 +1,358 @@
+<template>
+	<view class="game-content">
+		<!-- 自定义导航栏 -->
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickRight="onNavHome" @clickLeft="showClickEvent('DrawerModalL')" title="视频"
+		 color="#FFFFFF" fixed="true" backgroundColor="rgba(153, 150, 252, 255)">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="png-more" src="/static/more.png"></image>
+				</view>
+			</view>
+
+			<!-- <view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<image class="png-more" src="/static/mConver.png"></image>
+				</view>
+			</view> -->
+			<view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<view class="cuIcon-home text-20px-before"></view>
+				</view>
+			</view>
+		</uni-nav-bar>
+
+		<scroll-view v-if="decodeItem" class="scroll-class" scroll-y="true" :style="{'height':scrollviewHigh+'px'}">
+			<view class="cu-bar back-class">
+				<view class="action round" style="background-color: rgba(0,0,0,0.35);" @tap="onBack">
+					<text class="cuIcon-back text-white" style="padding: 10rpx 0 10rpx 20rpx;"></text>
+				</view>
+				<!-- <view class="content text-bold">
+					操作条
+				</view> -->
+			</view>
+			<swiper class="screen-swiper" style="height: 456px;" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true"
+			 :circular="true" :autoplay="true" interval="5000" duration="500">
+				<swiper-item v-for="(item,index) in swiperList" :key="index">
+					<image :src="item" mode="aspectFill"></image>
+				</swiper-item>
+			</swiper>
+			<view class="game-child-content">
+				<view class="text-gray text-df">{{decodeItem.createTime}}</view>
+				<view class="margin-top-sm text-bold text-xl">{{decodeItem.gameName}}</view>
+				<view class="margin-top-sm text-content text-df">
+					{{decodeItem.gameDescription}}
+				</view>
+				<view class='flex flex-wrap ' style="margin: 10rpx 0;">
+					<view style="padding-right:5rpx;" v-for="(item,index) in gameTags" :key="index">
+						<view class='cu-tag line-purple radius'>{{item.tagName}}</view>
+					</view>
+				</view>
+
+				<view class="flex padding justify-around plan-Tip-child">
+					<view>
+						<image class="margin-lr-xs right-png" :src="gameFavorite?'/static/favorite_r.png':'/static/favorite_g.png'" mode="aspectFill"
+						 @tap="onFavoriteAdd"></image>
+					</view>
+					<view>
+						<!-- <image class="margin-lr-xs right-png" src="/static/info_g.png" mode="aspectFill" @tap="onNavComment"></image> -->
+
+					</view>
+				</view>
+			</view>
+
+		</scroll-view>
+		<view class="bottom-container">
+			<view class="cu-bar tabbar" style="height: 100%;">
+				<button class="cu-btn make-bg-bPurple text-white lg margin-lg" style="width: 100%;" @tap="onNavToWebviewGame">马上去玩</button>
+			</view>
+		</view>
+
+		<sideBarD ref="sideBarDetail">
+
+		</sideBarD>
+
+		<!-- <button @tap="onNavToMiniGame">跳转小游戏</button> -->
+		<!-- <button @tap="onNavToWebviewGame">跳转webview游戏</button> -->
+	</view>
+</template>
+
+<script>
+	import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue";
+	import sideBarD from "@/components/side-bar/side-bar.vue";
+	import reqUtil from "@/util/util-js/requstUtil.js"
+	import config from "@/common/config.js"
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	export default {
+		components: {
+			uniNavBar,
+			sideBarD
+		},
+		computed: mapState(['ConnectBindingDevice', 'BLEConnectDevice', 'cIndex']),
+		data() {
+			return {
+				//解编码item
+				decodeItem: '',
+				//编码的item
+				encodeItem: '',
+
+				cardCur: 0,
+				swiperList: [],
+				gameTags: [],
+				dotStyle: false,
+				towerStart: 0,
+				direction: '',
+				scrollviewHigh: 500,
+
+				gameFavorite: false,
+			}
+		},
+		onLoad(option) {
+
+			if (option.item) {
+				console.log('option:', option);
+				// this.encodeItem = option.item;
+				// this.decodeItem = JSON.parse(decodeURIComponent(option.item));
+
+				let item = JSON.parse(decodeURIComponent(option.item));
+				// console.log("==",item);
+				this.gameFavorite = item.gameFavorite;
+				reqUtil.requestData(config.URL.GAMEDETAIL, item).then(res => {
+						console.log('GAMEDETAIL =====', res);
+						if (res.code == 0) {
+							this.encodeItem = encodeURIComponent(JSON.stringify(res.data.gameInfo));
+							this.decodeItem = res.data.gameInfo;
+							this.swiperList = res.data.gamePicturesList;
+							this.gameTags = res.data.gameTags;
+						}
+
+					},
+					e => {
+						console.log(e)
+					});
+			}
+
+
+		},
+		onReady() {
+			let _this = this;
+			uni.getSystemInfo({
+				success(res) {
+					// 计算组件的高度
+					// console.log("组件高度:", res);
+					let view = uni.createSelectorQuery().select("#nav-bar")
+					view.boundingClientRect(data => {
+						// console.log("data:", data);
+						let navHeight = data.height;
+						_this.scrollviewHigh = res.windowHeight - 58 - navHeight;
+					}).exec()
+					// 	_this.scrollviewHigh = res.windowHeight- uni.getSystemInfoSync().screenWidth / 750 * (300); //像素
+				}
+			})
+		},
+		methods: {
+			...mapMutations(['glimitPlayGame']),
+			// 跳转转换页面
+			onNavConver() {
+				uni.navigateTo({
+					url: '../../conversion-page/conversion/conversion',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			//跳转回主页
+			onNavHome() {
+				uni.reLaunch({
+					url: '../../personal-page/personal/personal',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			showClickEvent() {
+				this.$refs.sideBarDetail.showModal();
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			onNavToMiniGame() {
+				uni.navigateToMiniProgram({
+					appId: 'wx6898b48e0760935c',
+					path: '',
+					extraData: {
+						'data1': 'test'
+					},
+					success(res) {
+						// 打开成功
+						console.log(res);
+					},
+					fail(fail) {
+						console.error(fail);
+					}
+				})
+			},
+			onNavToWebviewGame() {
+				//1.先判断模式
+				//如果都不存在,返回
+				this.glimitPlayGame({
+					gameTags: this.gameTags,
+					callback: () => {
+						// #ifdef APP-PLUS
+						uni.navigateTo({
+							url: '../game-play-sub/game-play-sub?item=' + this.encodeItem,
+							success: res => {},
+							fail: () => {},
+							complete: () => {}
+						});
+						// #endif 
+						// #ifdef H5
+						uni.navigateTo({
+							url: '../game-play/game-play-web?item=' + this.encodeItem,
+							success: res => {},
+							fail: () => {},
+							complete: () => {}
+						});
+						// #endif
+					}
+				})
+
+
+			},
+			onNavComment() {
+				uni.showToast({
+					title: '功能尚未开放',
+					icon: 'none'
+				})
+				return;
+
+				uni.navigateTo({
+					url: '../game-comment/game-comment',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			//收藏
+			onFavoriteAdd() {
+				//添加收藏
+				let favoritesTemp = {
+					'fObjectId': this.decodeItem.gameId,
+					'favoritesType': 0,
+				}
+
+				reqUtil.requestData(config.URL.FAVORITESMODIFY, favoritesTemp).then(res => {
+						console.log('FAVORITESMODIFY =====', res);
+						if (res.code == 0) {
+							if (!res.data.bHas) {
+								this.gameFavorite = false;
+								uni.showToast({
+									title: "取消收藏",
+									icon: "none"
+								})
+							} else {
+								this.gameFavorite = true;
+								uni.showToast({
+									title: "收藏成功",
+									icon: "none"
+								})
+							}
+						}
+
+					},
+					e => {
+						console.log(e)
+					});
+			},
+		}
+	}
+</script>
+
+<style>
+	.game-content {
+		position: fixed;
+		height: 100%;
+		width: 100%;
+		background: #FFFFFF;
+		/* display: flex; */
+		/* flex-direction: column; */
+		/* align-items: center; */
+		/*垂直居中*/
+		/* justify-content: center; */
+		/*水平居中*/
+
+		/* border: 1rpx solid #39B54A; */
+	}
+
+	.game-child-content {
+		margin: 20px;
+	}
+
+	.bottom-container {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		height: 58px;
+		/* border: 1rpx solid #39B54A; */
+	}
+
+	.scroll-class {
+		/* background-color: #007AFF; */
+		/* border: 1rpx solid #007AFF; */
+		position: relative;
+	}
+
+	.back-class {
+		position: absolute;
+		left: 0;
+		top: 0;
+		z-index: 10;
+	}
+
+	.plan-Tip {
+		height: 90rpx;
+		margin: 60rpx 0;
+	}
+
+	.plan-Tip-child {
+		background-color: #F8F8F8;
+		border-radius: 30px;
+		width: 100%;
+		height: 90rpx;
+		margin: 50rpx 0;
+
+	}
+
+	.plan-litle-img {
+		width: 32rpx;
+		height: 32rpx;
+		margin-right: 32rpx;
+	}
+
+	.plan-m-img {
+		width: 1rpx;
+		height: 110rpx;
+		border: 1rpx dashed rgba(151, 151, 255, 1);
+
+	}
+
+	/* 图标大小 */
+	.data-png {
+		width: 16px;
+		height: 16px;
+		margin: 5rpx;
+	}
+
+
+	.right-png {
+		width: 32rpx;
+		height: 28rpx;
+	}
+</style>

+ 116 - 0
pages/game-page/game-play-sub/game-play-sub.vue

@@ -0,0 +1,116 @@
+<template>
+	<view class="content">
+	</view>
+</template>
+
+<script>
+	import AccAndOri from "@/util/util-js/AccAndOri.js"
+
+	export default {
+		data() {
+			return {
+				bUnload: false
+			};
+		},
+		onLoad(option) {
+			// console.log("game-play-sub ==",option)
+			if (!option) {
+				console.error("游戏没有option参数");
+				return;
+			}
+			/**
+			 * $on 之后要调用 $off,不然会重复绑定
+			 */
+
+			uni.$on("game-load", () => {
+				uni.$emit("setOnceGameOption", option);
+			});
+
+			uni.$on("game-unload", (data) => {
+				let {
+					globalAcc = null,
+					globalOri = null,
+					bGameOpenListen
+				} = data;
+				if(bGameOpenListen){
+					//如果开启加速计,取消加速计监听
+					console.log(globalAcc,globalOri);
+					if(globalAcc){
+						AccAndOri.unBindAcc(globalAcc);
+						this.$store.state.globalAcc = null;
+					}
+					//如果开启陀螺仪,取消陀螺仪监听
+					if(globalOri){
+						AccAndOri.unBindOri(globalOri);
+						this.$store.state.globalOri = null;
+					}
+				}
+				// console.log("this.bUnload",this.bUnload);
+				if (!this.bUnload) {
+					this.bUnload = true;
+					uni.navigateBack({
+						delta: 1
+					})
+				}
+
+			});
+			/**
+			 * 操作加速计
+			 */
+			uni.$on("bindAcc", (data) => {
+				let {
+					callback
+				} = data;
+
+				AccAndOri.bindAcc((accId) => {
+					callback(accId);
+				});
+			})
+			uni.$on("unBindAcc", (id) => {
+				AccAndOri.unBindAcc(id);
+			})
+
+			/**
+			 * 操作陀螺仪
+			 */
+			uni.$on("bindOri", (data) => {
+				let {
+					callback
+				} = data;
+
+				AccAndOri.bindOri((oriId) => {
+					callback(oriId);
+				});
+			})
+			uni.$on("unBindOri", (id) => {
+				AccAndOri.unBindOri(id);
+			})
+		},
+		onUnload() {
+			uni.$off("game-load");
+
+			uni.$off("game-unload");
+
+			/**
+			 * 操作加速计
+			 */
+			uni.$off("bindAcc");
+			uni.$off("unBindAcc");
+
+			/**
+			 * 操作陀螺仪
+			 */
+			uni.$off("bindOri");
+			uni.$off("unBindOri");
+		},
+		methods: {}
+	}
+</script>
+
+<style>
+	.content {
+		align-content: center;
+		height: 750rpx;
+		background-color: #F4F5F6;
+	}
+</style>

+ 1049 - 0
pages/game-page/game-play-sub/subGame/subGame.nvue

@@ -0,0 +1,1049 @@
+<template>
+	<view class="web-view">
+		<!-- :src="url" src = 'http://192.168.0.112:7456/build/index.html' :src="LocationGameUrl" -->
+		<!-- @receivedtitle="onReceivedTitle"   @pagefinish="onPageFinish"-->
+		<web-view class="web-view-child" src = 'http://192.168.0.112:7456/build/index.html' ref="webview" @pagestart="onPageStart" @onPostMessage="handlePostMessage"
+		 @error="onError"></web-view>
+		<view class="web-back" @click="navBack">
+			<image style="width: 40rpx;height: 40rpx;" src="/static/gameCloseW.png"></image>
+		</view>
+	</view>
+
+
+
+</template>
+
+<script>
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import config from "@/common/config.js";
+	import fruit from "@/components/fruitMachine/fruit.js"
+
+
+	// import AccAndOri from "@/util/util-js/AccAndOri.js"
+	import puchConfig from "@/util/util-js/puchConfig.js"
+
+	import EquipmentAction from "@/util/util-js/EquipmentAction.js"
+
+
+	var currentWebview;
+	var orientId = null,
+		accId = null;
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	export default {
+		computed: mapState([
+			'avatarUrl', 'gender', 'userName', 'city', 'BLEConnectDevice', 'instructionState', 'currentInstruction',
+			'cIndex', 'globalAcc', 'globalOri', 'LocationGameUrl',
+			'ConnectBindingDevice',
+			'currentModeIndex'
+		]),
+		data() {
+			return {
+				url: '',
+				pagefinish: '',
+				error: '',
+				PageStart: false, // 记录网页请求的加载状态,true 加载成功 false 加载失败
+				gameQuitListener: false, //游戏是否初始化退出监听
+
+				xA: 0,
+				yA: 0,
+				zA: 0,
+				oldxA: 0,
+				oldzA: 0,
+				bUpdateOnce: false,
+				bDelayOnce: false,
+				mass: puchConfig.BOXING_MASS,
+
+				//X轴的变化数组值
+				xAccArray: [],
+				xMax: 0,
+				maxTimeoutId: null,
+				bMaxPause: false,
+				xMin: 0,
+				minTimeoutId: null,
+				bMinPause: false,
+				bCalculation: false,
+				calTimeout: null,
+
+				//角度比 z/x
+				angleRatio: 1, //
+
+				//当前选择的item
+				decodeItem: null,
+
+				//拳击数据判断对象
+				EquipmentActionObj: null,
+
+				BLENum: 0,
+				BLEACX: 0,
+				BLEACYL: 0,
+
+				//是否是游戏里面开启的监听,如果是的话,退出游戏界面时候需要关闭相应的监听,如加速计和陀螺仪
+				bGameOpenListen: false,
+				//手机陀螺仪和加速计android模块
+				bMyAttitudeListen:false,
+			}
+		},
+		onLoad() {
+			let _self = this;
+
+			var pages = getCurrentPages();
+			var page = pages[pages.length - 1];
+			currentWebview = page.$getAppWebview();
+
+			//监听一次调用setOnceGameOption
+
+			console.log("子组件初始化");
+			uni.$once("setOnceGameOption", (option) => {
+				console.log("setOnceGameOption=", option);
+				if (option && option.item) {
+					this.decodeItem = JSON.parse(decodeURIComponent(option.item));
+					this.url = this.decodeItem.gameWebUrl;
+					let temp = {
+						fObjectId: this.decodeItem.gameId,
+						recentlyType: 0
+					}
+					// console.log("game temp:", config.URL.RECENTLYPLAYINGADD);
+					//添加最近在玩的游戏
+					reqUtil.requestData(config.URL.RECENTLYPLAYINGADD, temp).then(res => {
+							console.log('RECENTLYPLAYINGADD =====', res);
+							if (res.code == 0) {}
+
+						},
+						e => {
+							console.log(e)
+						});
+
+				}
+			});
+			//子窗体onload 后获取父窗体的onload数据
+			uni.$emit("game-load");
+
+			uni.getCurrentSubNVue().addEventListener("hide", function() {
+				console.log("subNVue子窗体已隐藏!");
+				//通知游戏,页面退出
+				_self.sendMessage("onSubHide", {
+					msg: '退出页面'
+				});
+				uni.$off('updateBLEDeviceData', _self.BLECallback);
+				//json
+				uni.$off('updateBLEDeviceJson', _self.BLEJsonCallback);
+				
+				//去掉监听
+				if(_self.bMyAttitudeListen){
+					_self.gStopSimulateBLEUpdate();
+				}
+				
+				// console.log(_self.BLEConnectDevice);
+				//如果连接了蓝牙设备是手柄
+				if (_self.BLEConnectDevice && _self.BLEConnectDevice.deviceType == "BLEHandle") {
+					//开启设备回调 3/4关闭
+					_self.onWriteBLEConnectionValue({
+						value: "4"
+					});
+					//关闭json 回调
+					_self.onWriteBLEConnectionValue({
+						value: "6"
+					});
+				
+					uni.$off('updateBLEDeviceData', _self.gWatchBLEUpdate);
+				}//关闭跳绳模式指令
+				else if (_self.BLEConnectDevice && _self.BLEConnectDevice.deviceType == "BLERope") {
+					console.warn("还没设置关闭跳绳模式")
+					_self.B_CloseRopeSkipping();
+					uni.$off('updateBLEDeviceData', _self.gWatchBLEUpdate);
+				}
+				uni.$emit("game-unload", {
+					globalAcc: _self.globalAcc,
+					globalOri: _self.globalOri,
+					bGameOpenListen: _self.bGameOpenListen
+				});
+				
+				
+			});
+			//*****注释蓝牙操作******
+			// 监听事件    
+			// uni.$on('callbackCloseBLE', this.callbackCloseBLE);
+			// uni.$on('callbackBLEState', this.callbackBLEState);
+			// uni.$on('updateBLEDeviceData', this.BLECallback);
+
+			//监听物理返回按钮
+			plus.key.addEventListener('backbutton', () => {
+				this.navBack();
+			}, false);
+			
+			//设置store状态
+			_self.$store.state.bGamePlaying = true;
+		},
+		onUnload() {
+			this.$store.state.bGamePlaying = false;
+			console.log("subNVue子窗体 onUnload!");
+			//*****注释蓝牙操作******
+			// uni.$off('callbackCloseBLE', this.callbackCloseBLE);
+			// uni.$off('callbackBLEState', this.callbackBLEState);
+			//取消相应的绑定事件
+			uni.$off('watchAcceleration', this.gWatchAcceleration);
+			uni.$off("watchAcceleration", this.gWatchBoxingAcc);
+			uni.$off("watchAcceleration", this.gWatchHitBoxingAcc);
+			uni.$off('watchOrientation', this.gWatchOrientation);
+
+			uni.$emit("game-unload");
+		},
+		methods: {
+			...mapMutations(['addlocalCalorie', 'syncRequestEvent', 'onWriteBLEConnectionValue',
+				'gCreateFilterObj', 'gUpdateFilter' ,'B_OpenRopeSkipping','B_CloseRopeSkipping',
+				'gStopSimulateBLEUpdate','gStartSimulateBLEUpdate','gUpdateSandbagAlgorithm','gCreateSandbagAlgorithm'
+			]),
+			navBack() {
+
+
+				this.sendMessage("onQuit", {
+					type: "right-button",
+					msg: '点击右上角按钮退出游戏'
+				});
+
+				uni.showModal({
+					title: '提示',
+					content: '是否退出游戏?',
+					success: (res) => {
+						//如果游戏需要监听退出,则需要走完游戏端流程,才能退出,否则直接退出
+						if (this.gameQuitListener) {
+							this.sendMessage("onQuitModal", {
+								data: res,
+								msg: '退出提示'
+							});
+						} else {
+							if (res.confirm) {
+								uni.getCurrentSubNVue().hide('auto');
+							}
+						}
+					}
+				})
+
+			},
+			//蓝牙断开连接时候
+			callbackCloseBLE() {
+				this.sendMessage("onDeviceClose", {
+					msg: '设备断开连接。'
+				});
+			},
+			//蓝牙状态回调
+			callbackBLEState(res) {
+				// console.log("game callbackBLEState==", res);
+				// 暂时只返回数据连接错误信息
+				// uni.$emit("callbackBLEState", {
+				// 	state: -1,
+				// 	msg: "设备数据错误"
+				// });
+				this.sendMessage("onDeviceState", res)
+			},
+			BLECallback(data) {
+				let dataType = 'Box';
+				// if (data.hasOwnProperty("ax")) {
+				// 	dataType = "Accelerometer"
+				// }else if(data.hasOwnProperty("gx")){
+				// 	dataType = "Gyroscope"
+				// }
+				// 设备回调后面用这个接口
+				let BLEState = {
+					device: this.BLEConnectDevice, //连接的蓝牙设备
+					instructionState: this.instructionState, //开启的指令状态
+					currentInstruction: this.currentInstruction, //当前发送的指令记录
+					dataType: dataType, //回调的数据类型
+					data: data //蓝牙回调的数据
+				}
+				this.sendMessage("onDeviceUpdateData", BLEState);
+			},
+			BLEJsonCallback(data) {
+				let dataType = 'Json';
+				// 设备回调后面用这个接口
+				let BLEState = {
+					device: this.BLEConnectDevice, //连接的蓝牙设备
+					instructionState: this.instructionState, //开启的指令状态
+					currentInstruction: this.currentInstruction, //当前发送的指令记录
+					dataType: dataType, //回调的数据类型
+					data: data //蓝牙回调的数据
+				}
+				this.sendMessage("onDeviceUpdateJson", BLEState);
+			},
+			/**
+			 * 图片转化base64
+			 * @param {Object} url
+			 * @param {Object} callback
+			 */
+			urlToBase64(url, callback) {
+				let toBase64Url;
+				uni.request({
+					url: url,
+					method: 'GET',
+					responseType: 'arraybuffer',
+					success: async res => {
+						let base64 = uni.arrayBufferToBase64(res.data);
+						toBase64Url = 'data:image/jpeg;base64,' + base64;
+						if (callback)
+							callback(toBase64Url, res.data);
+					}
+				})
+			},
+			/**
+			 * 初始化发送数据给游戏
+			 */
+			sendGameInit() {
+
+				this.urlToBase64(this.avatarUrl, (toBase64Url) => {
+					let device = null;
+					/**
+					 * 卡路里消耗参数
+					 */
+					let calorieParams = null;
+
+					if (this.BLEConnectDevice) {
+						// device = {
+						// 	cname: this.BLEConnectDevice.cname,
+						// 	ename: this.BLEConnectDevice.ename,
+						// 	name: this.BLEConnectDevice.name
+						// };
+						// calorieParams = {
+						// 	runUnit: 0.55, // 比跳的稍微大一点
+						// 	jumpUnit: 0.5 // 跳的次数 * 0.5
+						// };
+						device = {
+							cname: this.BLEConnectDevice.cname,
+							ename: this.BLEConnectDevice.ename,
+							name: this.BLEConnectDevice.name
+						};
+
+						calorieParams = {
+							hitUnit: puchConfig.getBoxingCalorie(1)
+						};
+
+					} else if (this.ConnectBindingDevice) {
+						device = {
+							cname: this.ConnectBindingDevice.cname,
+							ename: this.ConnectBindingDevice.ename,
+							name: this.ConnectBindingDevice.name
+						};
+
+						calorieParams = {
+							hitUnit: puchConfig.getBoxingCalorie(1)
+						};
+					}
+					//到时候可能要区分是什么类型
+					let item = {
+						id: this.decodeItem.gameId,
+						name: this.decodeItem.gameName
+					};
+
+					// console.log(this.BLEConnectDevice, device);
+					let gameData = {
+						avatarUrl: this.avatarUrl,
+						avatarBase64Url: toBase64Url,
+						userName: this.userName,
+						gender: this.gender,
+						caloriUnit: 10,
+						calorieParams: calorieParams,
+						//蓝牙连接的设备
+						device: device,
+						item: item
+					}
+
+					this.sendMessage("onGameInit", gameData);
+					// console.log("onGameInit =", gameData);
+				})
+
+
+			},
+			/**
+			 * 统一发送信息
+			 * @param {Object} gameData
+			 */
+			sendMessage(functionName, gameData) {
+				let data = {
+					"funName": functionName,
+					"gameData": gameData
+				}
+				if (!this.PageStart) {
+					console.warn("页面未初始化不能传消息", data);
+					return;
+				}
+				let initStr = JSON.stringify(data);
+				this.$refs.webview.evalJs("onWebViewMessage(" + initStr + ")");
+			},
+			sendMessageToWebview() {
+				if (!this.PageStart) {
+					uni.showModal({
+						title: "暴躁的提示",
+						content: "只有网页加载成功了才可以传参过去,不然无效哦。。"
+					})
+					return false;
+				}
+				/**
+				 * 下面的 jsfunction 代码你要自己在你的网页里面写一个方法 大致如下
+				 *  下面就是你基本的html知识了,我就不想说什么了,自己学。
+					window.jsfunction = function(data){
+						console.log('data', data);
+					}
+				 */
+				this.sendMessage("onDeviceUpdateData", {
+					H: 1
+				});
+
+			},
+			handlePostMessage: function(postData) {
+				console.log("handlePostMessage得到参数", postData.detail);
+				let temp = postData.detail.data[0];
+				let gameData = temp.gameData;
+				if (temp.funName == "uploadInfo") {
+
+					//TODO:写入排行榜分数,后面需要在游戏完结里面调用
+					//TODO: 后面游戏时间,卡路里的需要写入数据库,目前只是处理了分数
+					// let num = Math.round(Math.random() * 10000);
+					//1. gameScore 处理上传的分数
+					// let _temp = {
+					// 	gameId: '1595755153789139696',
+					// 	score: 1230,
+					// 	cityCode: '110101',
+					// };
+
+					//2. calorieBurned 处理卡路里
+					// 记录卡路里到本地
+					this.addlocalCalorie(gameData.calorieBurned);
+					console.log("gameData.calorieBurned", gameData.calorieBurned);
+					//然后更新上服务器
+					this.syncRequestEvent({
+						success: () => {
+							// uni.$emit('updateArcbarData', '');
+
+							let _temp = {
+								//假如排行id 为空,排行榜就是游戏自己的id
+								gameId: this.decodeItem.gameRankingId == null ? this.decodeItem.gameId : this.decodeItem.gameRankingId,
+								score: gameData.gameScore,
+								cityCode: this.city.cityCode,
+								bMaxLimit: true
+							}
+							console.log('_temp =====', _temp);
+							reqUtil.requestData(config.URL.UPLOADRANKING, _temp, "POST").then(res => {
+									console.log('UPLOADRANKING =====', res);
+									if (res.code == 0) {
+										//TODO 后续游戏数据处理
+										this.sendMessage("onUploadInfo", {
+											code: 0,
+											msg: '上传成功'
+										});
+									} else {
+										//TODO 后续游戏数据处理
+										this.sendMessage("onUploadInfo", {
+											code: 400,
+											msg: '上传失败'
+										});
+									}
+
+								},
+								e => {
+									console.log(e)
+								});
+						},
+						fail: () => {
+							this.sendMessage("onUploadInfo", {
+								code: 400,
+								msg: '上传失败'
+							});
+						}
+					});
+
+					//3. gameTime 游戏时间 
+					//TODO 后面处理游戏时长
+
+
+				} else if (temp.funName == "gameInit") {
+					// 获取游戏信息
+					this.sendGameInit();
+				} else if (temp.funName == "aiRandomInfo") {
+					// 获取aiRandomInfo
+					reqUtil.requestData(config.URL.AIRANDOMINFO, {}).then(res => {
+							console.log('AIRANDOMINFO =====', res);
+							if (res.code == 0) {
+								let data = res.data;
+								this.urlToBase64(data.aiAvatar, (toBase64Url) => {
+									let sendData = {
+										aiId: data.aiId,
+										aiName: data.aiName,
+										aiGender: data.aiGender,
+										aiType: data.aiType,
+										aiAvatarBase64Url: toBase64Url
+									}
+									this.sendMessage("onAiRandomInfo", sendData);
+								})
+							}
+
+						},
+						e => {
+							console.log(e)
+						});
+				} else if (temp.funName == "fruitInfo") {
+					let fruitIndexArray = [0, 0, 0];
+					if (gameData.hasOwnProperty("calorie")) {
+						fruitIndexArray = fruit.getFruitIndex(gameData.calorie);
+					}
+
+					this.urlToBase64("https://bbeng-bucket.oss-cn-beijing.aliyuncs.com/cocos/fruitMachine.png", (toBase64Url) => {
+						this.sendMessage("onFruitInfo", {
+							// 水果雪碧图
+							fruitBase64Url: toBase64Url,
+							// 雪碧图 单张图片宽高
+							unitWidth: 100,
+							unitHeight: 100,
+							unit: "px",
+							imageStartPosY: 0,
+							imageEndPosY: -1200,
+							fruitIndexArray: fruitIndexArray
+						});
+					})
+
+
+
+				} else if (temp.funName == "urlToBase64") {
+					if (gameData.url) {
+						this.urlToBase64(gameData.url, (toBase64Url) => {
+							this.sendMessage("onUrlToBase64", {
+								base64: toBase64Url,
+							});
+						})
+					} else {
+						this.sendMessage("onUrlToBase64", {
+							base64: {},
+						});
+					}
+
+				} else if (temp.funName == "openAccelerometer") {
+					//打开加速计s
+					// if (this.globalGameAcc) {
+					// 	uni.$on('watchAcceleration', this.gWatchAcceleration);
+					// } else {
+					// 	AccAndOri.bindAcc((accId) => {
+					// 		this.$store.state.globalGameAcc = accId;
+					// 		console.log("开启的:globalGameAcc=",this.globalGameAcc);
+					// 		uni.$on('watchAcceleration', this.gWatchAcceleration);
+					// 	});
+					// }
+					if (this.globalAcc) {
+						uni.$on('watchAcceleration', this.gWatchAcceleration);
+					} else {
+						uni.$emit("bindAcc", {
+							callback: (accId) => {
+								console.log("开启的:globalAcc=", accId);
+								this.bGameOpenListen = true;
+								this.$store.state.globalAcc = accId;
+								uni.$on('watchAcceleration', this.gWatchAcceleration);
+							}
+						});
+					}
+
+
+				} else if (temp.funName == "closeAccelerometer") {
+					uni.$off('watchAcceleration', this.gWatchAcceleration);
+					uni.$emit("unBindAcc", this.globalAcc);
+					this.$store.state.globalAcc = null;
+
+				} else if (temp.funName == "openOrientation") {
+					//打开陀螺仪
+					if (this.globalOri) {
+						uni.$on('watchOrientation', this.gWatchOrientation);
+					} else {
+						// AccAndOri.bindOri((oriId) => {
+						// 	this.$store.state.globalOri = oriId;
+						// 	uni.$on('watchOrientation', this.gWatchOrientation);
+						// });
+						uni.$emit("bindOri", {
+							callback: (oriId) => {
+								console.log("开启的:globalOri=", oriId);
+								this.bGameOpenListen = true;
+								this.$store.state.globalOri = oriId;
+								uni.$on('watchOrientation', this.gWatchOrientation);
+							}
+						});
+					}
+				} else if (temp.funName == "closeOrientation") {
+
+					// uni.$off('watchOrientation', this.gWatchOrientation);
+					uni.$off('watchOrientation', this.gWatchOrientation);
+					uni.$emit("unBindOri", this.globalOri);
+					this.$store.state.globalOri = null;
+
+				} else if (temp.funName == "bindBoxingPost") {
+					if (this.globalAcc) {
+						uni.$on('watchAcceleration', this.gWatchBoxingAcc);
+					} else {
+						uni.$emit("bindAcc", {
+							callback: (accId) => {
+								console.log("bindBoxingPost开启的:globalAcc=", accId);
+								this.bGameOpenListen = true;
+								this.$store.state.globalAcc = accId;
+								uni.$on('watchAcceleration', this.gWatchBoxingAcc);
+							}
+						});
+					}
+				} else if (temp.funName == "unbindBoxingPost") {
+
+					uni.$off('watchAcceleration', this.gWatchBoxingAcc);
+					uni.$emit("unBindAcc", this.globalAcc);
+					this.$store.state.globalAcc = null;
+
+				} else if (temp.funName == "setAngleRatio") {
+					if (gameData) {
+						this.angleRatio = Number(gameData.angleRatio);
+						console.log("this.angleRatio:", this.angleRatio);
+						this.sendMessage("onSetAngleRatio", {
+							angleRatio: this.angleRatio
+						});
+					}
+				} else if (temp.funName == "bindHitBoxingPost") {
+					console.log("bindHitBoxingPost");
+					
+					if(this.ConnectBindingDevice){
+						uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
+						//hotman 沙袋情景
+						this.gCreateSandbagAlgorithm();
+						this.gStartSimulateBLEUpdate();
+						return;
+					}
+					
+					if(!this.BLEConnectDevice)return;
+					//用设备来区分,开启什么加速计;
+					if (this.BLEConnectDevice.deviceType == "BLEHandle") {
+						//处理蓝牙设备情况下
+						//开启设备回调 3/4关闭
+						this.onWriteBLEConnectionValue({
+							value: "3"
+						});
+						setTimeout(()=>{
+							//设置加速计b:20ms a:10ms
+							this.onWriteBLEConnectionValue({
+								value: config.refreshRate
+							});
+							
+						},2000)
+						
+						uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
+
+						if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode == "general") {
+							//手机情景或者自由模式
+							this._createEquipmentBasedOnBoxingPostHit();
+						} else if (this.BLEConnectDevice.usageMode == "hotman") {
+							//hotman 沙袋情景  
+							this.gCreateFilterObj();
+						}
+					} else if (this.BLEConnectDevice.deviceType == "mySelf") {
+						//处理手机本身情况下
+						if (this.globalAcc) {
+							uni.$on('watchAcceleration', this.gWatchHitBoxingAcc);
+						} else {
+							//开启手机加速计
+							uni.$emit("bindAcc", {
+								callback: (accId) => {
+									console.log("bindHitBoxingPost开启的:globalAcc=", accId);
+									this.bGameOpenListen = true;
+									this.$store.state.globalAcc = accId;
+									uni.$on('watchAcceleration', this.gWatchHitBoxingAcc);
+									if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode == "general") {
+										//手机情景或者自由模式
+										this._createEquipmentBasedOnBoxingPostHit();
+									} else if (this.BLEConnectDevice.usageMode == "hotman") {
+										//hotman 沙袋情景 todo
+										console.warn("没有处理手机加速计的 gCreateFilterObj");
+										// this.gCreateFilterObj();
+									}
+								}
+							});
+						}
+					} else if(this.BLEConnectDevice.deviceType == "BLERope"){
+						//todo 开启跳绳模式
+						this.B_OpenRopeSkipping();
+						//监听蓝牙回调
+						uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
+					}
+
+
+				} else if (temp.funName == "unbindHitBoxingPost") {
+					
+					if(this.ConnectBindingDevice){
+						uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
+						this.gStopSimulateBLEUpdate();
+						return;
+					}
+					
+					if (this.BLEConnectDevice&&this.BLEConnectDevice.deviceType == "BLEHandle") {
+						//开启设备回调 3/4关闭
+						this.onWriteBLEConnectionValue({
+							value: "4"
+						});
+						uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
+					}else if (this.BLEConnectDevice && this.BLEConnectDevice.deviceType == "BLERope") {
+					 	console.warn("unbindHitBoxingPost 还没设置关闭跳绳模式")
+						this.B_CloseRopeSkipping();
+						uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
+					} else {
+						uni.$off('watchAcceleration', this.gWatchHitBoxingAcc);
+						uni.$emit("unBindAcc", this.globalAcc);
+						this.$store.state.globalAcc = null;
+					}
+				} else if (temp.funName == "closeGame") {
+					uni.getCurrentSubNVue().hide('auto');
+				} else if (temp.funName == "addQuitModal") {
+					this.gameQuitListener = true;
+					this.sendMessage("onQuitModalListener", {
+						bListener: this.gameQuitListener
+					});
+				} else if (temp.funName == "removeQuitModal") {
+					this.gameQuitListener = false;
+					this.sendMessage("onQuitModalListener", {
+						bListener: this.gameQuitListener
+					});
+				} else if (temp.funName == "writeBLEConnectionValue") {
+					if (!gameData.value || gameData.value == "") return;
+					
+					if(!this.BLEConnectDevice)return;
+					//蓝牙写入数据
+					this.onWriteBLEConnectionValue(gameData);
+				} else if (temp.funName == "log") {
+					console.log(gameData);
+				} else if (temp.funName == "addDeviceUpdateListener") {
+					uni.$on('updateBLEDeviceData', this.BLECallback);
+				} else if (temp.funName == "closeDeviceUpdateListener") {
+					uni.$off('updateBLEDeviceData', this.BLECallback);
+				} else if (temp.funName == "addDeviceJsonUpdateListener") {
+					uni.$on('updateBLEDeviceJson', this.BLEJsonCallback);
+				} else if (temp.funName == "closeDeviceJsonUpdateListener") {
+					uni.$off('updateBLEDeviceJson', this.BLEJsonCallback);
+				}
+				//获取手机原始陀螺仪和加速计数据
+				else if(temp.funName == "onStartAccAndGyro"){
+					this.bMyAttitudeListen = true;
+					this.gStartSimulateBLEUpdate();
+					//监听蓝牙回调
+					uni.$on('updateBLEDeviceData', this.gWatchBLEUpdate);
+				}
+				else if(temp.funName == "onStopAccAndGyro"){
+					this.bMyAttitudeListen = false;
+					this.gStopSimulateBLEUpdate();
+					//监听蓝牙回调
+					uni.$off('updateBLEDeviceData', this.gWatchBLEUpdate);
+				}
+			},
+			onPageStart: function(e) {
+				// 监听页面加载成功
+				this.PageStart = true;
+				console.log("onPageStart==", e);
+				setTimeout(()=>{
+					//加载成功后,显示
+					uni.getCurrentSubNVue().show('fade-in', 250, () => {});
+				},100)
+				
+
+			},
+			onPageFinish: function(e) {
+				console.log("onPageFinish==", e);
+			},
+			onError: function(e) {
+				// 监听页面加载错误
+				// this.error = this.url;
+				console.error(e);
+			},
+			gWatchAcceleration: function(a) {
+				this.sendMessage("onWatchAccelerometer", a);
+				return;
+				if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
+					this.sendMessage("onWatchAccelerometer", a);
+				} else if (this.BLEConnectDevice && this.cIndex != -1) {
+					this.sendMessage("onWatchAccelerometer", a);
+				}
+			},
+			gWatchOrientation: function(o) {
+				this.sendMessage("onWatchOrientation", o);
+				return;
+				if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
+					this.sendMessage("onWatchOrientation", o);
+				} else if (this.BLEConnectDevice && this.cIndex != -1) {
+					this.sendMessage("onWatchOrientation", o);
+				}
+			},
+			//监听返回计算好的puch
+			gWatchBoxingAcc: function(a) {
+				if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
+					//计算返回 puch  leftPunch  rightPunch
+					this.updateHitData(a);
+				} else if (this.BLEConnectDevice && this.cIndex != -1) {
+					this.updateHitData(a);
+				}
+			},
+			//只返回一个hit状态
+			gWatchHitBoxingAcc: function(a) {
+				if (this.ConnectBindingDevice && this.ConnectBindingDevice.deviceType == 1) {
+					//计算返回 puch  leftPunch  rightPunch
+					this.EquipmentActionObj.updateAcc({
+						xA: a.xAxis,
+						zA: a.yAxis,
+						yA: a.zAxis
+					})
+				} else if (this.cIndex != -1 && this.BLEConnectDevice != null) {
+					if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode == "general") {
+						this.EquipmentActionObj.updateAcc({
+							xA: a.xAxis,
+							zA: a.yAxis,
+							yA: a.zAxis,
+							bLimitRebound: false
+						})
+					} else if (this.BLEConnectDevice.usageMode == "hotman") {
+						//hotman 沙袋情景 todo
+						//后面处理手机加速计的数据
+					}
+
+				}
+			},
+			gWatchBLEUpdate: function(data) {
+				
+				//如果是模块外面触发,需要离线打包
+				if(this.bMyAttitudeListen){
+					this.sendMessage("updateAccAndGyro", data);
+					return;
+				}
+				
+				if(this.ConnectBindingDevice){
+					//hotman 沙袋情景 todo
+					this.gUpdateSandbagAlgorithm({
+						data: data,
+						callback: (res) => {
+							// console.log(res);
+							if (res.type == 'hit') {
+								// console.log('gUpdateFilter callback:',res)
+					
+								let temp = {
+									direction: res.direction,
+									angle:res.angle,
+									name: res.name,
+									ename: res.ename,
+									value: res.hit,
+									mass: 10, //质量
+									hitPower: res.hit //计算的力
+								}
+								this.sendMessage("onBoxingPostHit", temp);
+							}
+						}
+					});
+					return;
+				}
+				
+				if (this.BLEConnectDevice.usageMode == "phone" || this.BLEConnectDevice.usageMode == "general") {
+					//手机情景或者自由模式
+					let {
+						ax,
+						ay,
+						az
+					} = data.acc;
+					//this.BLEConnectDevice.limitType == "rebound"
+					//这里是监听 _createEquipmentBasedOnBoxingPostHit 回调
+					this.EquipmentActionObj.updateTriaxialAcc({
+						xA: ax * 9.80665,
+						zA: ay * 9.80665,
+						yA: az * 9.80665,
+						bLimitRebound: false
+					})
+				} else if (this.BLEConnectDevice.usageMode == "hotman") {
+					//hotman 沙袋情景 todo
+					this.gUpdateFilter({
+						data: data,
+						callback: (res) => {
+							// console.log(res);
+							if (res.type == 'hit') {
+								// console.log('gUpdateFilter callback:',res)
+
+								let temp = {
+									direction: res.direction,
+									angle:res.angle,
+									name: res.name,
+									ename: res.ename,
+									value: res.hit,
+									mass: 10, //质量
+									hitPower: res.hit //计算的力
+								}
+								this.sendMessage("onBoxingPostHit", temp);
+							}
+						}
+					});
+				} else if(this.BLEConnectDevice.usageMode == "ropeSkipping"){
+					//跳绳模式场景,简单更新触发
+					//看看是否反馈一个角度,180 ,360
+					let temp = {
+						direction: "all",
+						angle: 0,
+						name: "击中",// this.BLEConnectDevice.name,
+						ename: "hit",//this.BLEConnectDevice.ename,
+						value: 10,
+						mass: 10, //质量
+						hitPower: 10 //计算的力
+					}
+					this.sendMessage("onBoxingPostHit", temp);
+				}
+			},
+
+			updateHitData(a) {
+				this.xA = a.xAxis;
+				this.yA = a.yAxis;
+				this.zA = a.zAxis;
+
+				if (Math.abs(this.xA) > 8 && this.oldxA != this.xA && !this.bCalculation) {
+					this.xAccArray.push(this.xA);
+					this.oldxA = this.xA;
+
+					if (this.calTimeout == null) {
+						this.calTimeout = setTimeout(() => {
+							this.bCalculation = true;
+							for (let i = 0; i < this.xAccArray.length; i++) {
+								if (this.xAccArray[i] < 0 && this.xAccArray[i] < this.xAccArray[this.xMin]) {
+									this.xMin = i;
+								} else if (this.xAccArray[i] > 0 && this.xAccArray[i] > this.xAccArray[this.xMax]) {
+									this.xMax = i;
+								}
+							}
+							console.log(this.xAccArray, "==", this.xMin, "==", this.xMax);
+							if (this.xAccArray[this.xMin] < 0 && this.xAccArray[this.xMax] > 0) {
+								if (this.xMin > this.xMax)
+									this.onHit("xRCount", "左勾拳", "leftPunch", this.xAccArray[this.xMin], Math.ceil(Math.abs(this.xAccArray[this.xMin]) *
+										puchConfig.BOXING_MASS));
+								else if (this.xMin < this.xMax)
+									this.onHit("xLCount", "右勾拳", "rightPunch", this.xAccArray[this.xMax], Math.ceil(Math.abs(this.xAccArray[this
+										.xMax]) * puchConfig.BOXING_MASS));
+							} else if (this.xAccArray[this.xMin] < 0) {
+								this.onHit("xLCount", "右勾拳", "rightPunch", this.xAccArray[this.xMin], Math.ceil(Math.abs(this.xAccArray[this.xMin]) *
+									puchConfig.BOXING_MASS));
+							} else if (this.xAccArray[this.xMax] > 0) {
+								this.onHit("xRCount", "左勾拳", "leftPunch", this.xAccArray[this.xMax], Math.ceil(Math.abs(this.xAccArray[this.xMax]) *
+									puchConfig.BOXING_MASS));
+							}
+							setTimeout(() => {
+								this.onResetCal();
+							}, 100);
+							this.calTimeout = null;
+						}, 200);
+					}
+				} else if (this.zA < -10 && this.oldzA != this.zA && this.xAccArray.length == 0) {
+					console.log("this.zA:", this.zA);
+					this.oldzA = this.zA;
+					setTimeout(() => {
+						this.onResetCal();
+					}, 200);
+					this.onHit("zLCount", "直拳", "punch", this.zA, Math.ceil(Math.abs(this.zA) * puchConfig.BOXING_MASS));
+				}
+			},
+			onHit(direction, name, ename, direValue, power) {
+				// console.log(direction, direValue, power);
+				let temp = {
+					direction: direction,
+					angle: 0,
+					name: name,
+					ename: ename,
+					value: direValue,
+					mass: this.mass, //质量
+					hitPower: power //计算的力
+				}
+
+				this.sendMessage("onBoxingPostHit", temp);
+			},
+			onResetCal() {
+				this.xAccArray = [];
+				this.xMax = 0;
+				this.xMin = 0;
+				this.bCalculation = false;
+				this.oldxA = 0;
+				this.oldzA = 0;
+				this.calTimeout = null;
+			},
+			//创建一个 打击对象
+			_createEquipmentBasedOnBoxingPostHit() {
+				this.EquipmentActionObj = new EquipmentAction();
+				this.EquipmentActionObj.addEventListener("resultantHit", (e) => {
+					console.log(e);
+					let temp = {
+						direction: "allCount",
+						angle: 0,
+						name: "击中",
+						ename: "hit",
+						value: e.acc,
+						mass: e.mass, //质量
+						hitPower: e.power //计算的力
+					}
+					this.sendMessage("onBoxingPostHit", temp);
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	/* #ifdef APP-PLUS */
+	.web-view {
+		flex: 1;
+		flex-direction: column;
+		/* background-color: #007AFF; */
+	}
+
+	.web-view-child {
+		width: 750rpx;
+		height: 100%;
+		flex: 1;
+	}
+
+	/* #endif */
+	/* #ifdef H5 */
+
+	.web-view {
+		display: flex;
+		flex-direction: column;
+		position: absolute;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+	}
+
+	.web-view-child {
+		position: relative;
+		width: 100%;
+		height: 100%;
+	}
+
+	/* #endif */
+
+
+	.sendMessage {
+		width: 300rpx;
+		position: fixed;
+		bottom: 100rpx;
+		left: 50rpx;
+	}
+
+	.web-back {
+		position: fixed;
+		top: 40px;
+		right: 20px;
+		width: 160rpx;
+		height: 80rpx;
+		border-radius: 45px;
+		/* border: 1px solid #FFFFFF; */
+		/* box-shadow: 0px 0px 1px #FFFFFF; */
+		background-color: rgba(0, 0, 0, 1);
+		opacity: 0.5;
+
+		/* #ifndef APP-PLUS-NVUE */
+		z-Index: 10;
+		display: flex;
+		/* #endif */
+
+		justify-content: center;
+		align-items: center;
+	}
+</style>

+ 415 - 0
pages/game-page/game-play/game-play-web.nvue

@@ -0,0 +1,415 @@
+<template>
+	<view class="web-view">
+		<!-- :src="url" src = 'http://192.168.0.108:7456/build/index.html' -->
+		<!-- @receivedtitle="onReceivedTitle"   @pagefinish="onPageFinish"-->
+		<web-view class="web-view-child" :src="url" ref="webview" @pagestart="onPageStart"
+		 @onPostMessage="handlePostMessage" @error="onError"></web-view>
+		<view class="web-back" @click="navBack">
+			<image style="width: 40rpx;height: 40rpx;" src="/static/gameCloseW.png"></image>
+		</view>
+	</view>
+
+
+
+</template>
+
+<script>
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import config from "@/common/config.js";
+	import fruit from "@/components/fruitMachine/fruit.js"
+
+	var currentWebview;
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	export default {
+		computed: mapState(['avatarUrl', 'gender', 'userName', 'city', 'BLEConnectDevice']),
+		data() {
+			return {
+				url: '',
+				pagefinish: '',
+				error: '',
+				canGoBack: false,
+				canGoForward: false,
+				PageStart: false, // 记录网页请求的加载状态,true 加载成功 false 加载失败
+			}
+		},
+		onLoad(option) {
+			if (option && option.item) {
+				this.decodeItem = JSON.parse(decodeURIComponent(option.item));
+				this.url = this.decodeItem.gameWebUrl;
+				let temp = {
+					fObjectId: this.decodeItem.gameId,
+					recentlyType: 0
+				}
+				// console.log("game temp:", config.URL.RECENTLYPLAYINGADD);
+				//添加最近在玩的游戏
+				reqUtil.requestData(config.URL.RECENTLYPLAYINGADD, temp).then(res => {
+						console.log('RECENTLYPLAYINGADD =====', res);
+						if (res.code == 0) {}
+
+					},
+					e => {
+						console.log(e)
+					});
+
+			}
+
+			// #ifdef APP-PLUS
+			var pages = getCurrentPages();
+			var page = pages[pages.length - 1];
+			currentWebview = page.$getAppWebview();
+			// #endif
+
+			// 监听事件    
+			uni.$on('callbackCloseBLE', this.callbackCloseBLE);
+			uni.$on('callbackBLEState', this.callbackBLEState);
+			uni.$on('updateBLEDeviceData', this.callback);
+			
+		},
+		onUnload() {
+			uni.$off('callbackCloseBLE', this.callbackCloseBLE);
+			uni.$off('callbackBLEState', this.callbackBLEState);
+			uni.$off('updateBLEDeviceData', this.callback);
+		},
+		methods: {
+			...mapMutations([ 'addlocalCalorie']),
+			navBack() {
+				uni.navigateBack();
+			},
+			//蓝牙断开连接时候
+			callbackCloseBLE() {
+				this.sendMessage("onDeviceClose", {
+					msg: '设备断开连接。'
+				});
+			},
+			//蓝牙状态回调
+			callbackBLEState(res) {
+				// console.log("game callbackBLEState==", res);
+				// 暂时只返回数据连接错误信息
+				// uni.$emit("callbackBLEState", {
+				// 	state: -1,
+				// 	msg: "设备数据错误"
+				// });
+				this.sendMessage("onDeviceState", res)
+			},
+			callback(data) {
+				// 设备回调后面用这个接口
+				this.sendMessage("onDeviceUpdateData", data);
+			},
+			/**
+			 * 图片转化base64
+			 * @param {Object} url
+			 * @param {Object} callback
+			 */
+			urlToBase64(url, callback) {
+				let toBase64Url;
+				uni.request({
+					url: url,
+					method: 'GET',
+					responseType: 'arraybuffer',
+					success: async res => {
+						let base64 = uni.arrayBufferToBase64(res.data);
+						toBase64Url = 'data:image/jpeg;base64,' + base64;
+						if (callback)
+							callback(toBase64Url,res.data);
+					}
+				})
+			},
+			/**
+			 * 初始化发送数据给游戏
+			 */
+			sendGameInit() {
+				if (!this.PageStart) {
+					uni.showModal({
+						title: "暴躁的提示",
+						content: "只有网页加载成功了才可以传参过去,不然无效哦。。"
+					})
+					return false;
+				}
+
+				this.urlToBase64(this.avatarUrl, (toBase64Url) => {
+					let device = null;
+					if (this.BLEConnectDevice) {
+						device = {
+							cname: this.BLEConnectDevice.cname,
+							ename: this.BLEConnectDevice.ename,
+							name: this.BLEConnectDevice.name
+						}
+
+					}
+					/**
+					 * 卡路里消耗参数
+					 */
+					
+					let calorieParams ={
+						runUnit:10,
+						jumpUnit:20
+					};
+					
+					// console.log(this.BLEConnectDevice, device);
+					let gameData = {
+						avatarUrl: this.avatarUrl,
+						avatarBase64Url: toBase64Url,
+						userName: this.userName,
+						gender: this.gender,
+						caloriUnit: 10,
+						calorieParams:calorieParams,
+						//蓝牙连接的设备
+						device: device
+					}
+					this.sendMessage("onGameInit", gameData);
+				})
+
+
+			},
+			/**
+			 * 统一发送信息
+			 * @param {Object} gameData
+			 */
+			sendMessage(functionName, gameData) {
+				let data = {
+					"funName": functionName,
+					"gameData": gameData
+				}
+				let initStr = JSON.stringify(data);
+				this.$refs.webview.evalJs("onWebViewMessage(" + initStr + ")");
+			},
+			sendMessageToWebview() {
+				if (!this.PageStart) {
+					uni.showModal({
+						title: "暴躁的提示",
+						content: "只有网页加载成功了才可以传参过去,不然无效哦。。"
+					})
+					return false;
+				}
+				/**
+				 * 下面的 jsfunction 代码你要自己在你的网页里面写一个方法 大致如下
+				 *  下面就是你基本的html知识了,我就不想说什么了,自己学。
+					window.jsfunction = function(data){
+						console.log('data', data);
+					}
+				 */
+				this.sendMessage("onDeviceUpdateData", {
+					H: 1
+				});
+
+			},
+			handlePostMessage: function(postData) {
+				console.log("handlePostMessage得到参数", postData.detail);
+				let temp = postData.detail.data[0];
+				if (temp.funName == "uploadInfo") {
+					//TODO 后续游戏数据处理
+					this.sendMessage("onUploadInfo", {});
+
+					let gameData = temp.gameData;
+					//TODO:写入排行榜分数,后面需要在游戏完结里面调用
+					//TODO: 后面游戏时间,卡路里的需要写入数据库,目前只是处理了分数
+					// let num = Math.round(Math.random() * 10000);
+					//1. gameScore 处理上传的分数
+					reqUtil.requestData(config.URL.UPLOADRANKING, {
+						gameId: this.decodeItem.gameId,
+						score: gameData.gameScore,
+						cityCode: this.city.cityCode,
+					}, "POST").then(res => {
+							console.log('UPLOADRANKING =====', res);
+							if (res.code == 0) {}
+
+						},
+						e => {
+							console.log(e)
+						});
+					//2. calorieBurned 处理卡路里
+					// 记录卡路里到本地
+					this.addlocalCalorie(gameData.calorieBurned);
+					
+					//3. gameTime 游戏时间 
+					//TODO 后面处理游戏时长
+					
+
+				} else if (temp.funName == "gameInit") {
+					// 获取游戏信息
+					this.sendGameInit();
+				} else if (temp.funName == "aiRandomInfo") {
+					// 获取aiRandomInfo
+					reqUtil.requestData(config.URL.AIRANDOMINFO, {}).then(res => {
+							console.log('AIRANDOMINFO =====', res);
+							if (res.code == 0) {
+								let data = res.data;
+								this.urlToBase64(data.aiAvatar, (toBase64Url) => {
+									let sendData = {
+										aiId: data.aiId,
+										aiName: data.aiName,
+										aiGender: data.aiGender,
+										aiType: data.aiType,
+										aiAvatarBase64Url: toBase64Url
+									}
+									this.sendMessage("onAiRandomInfo", sendData);
+								})
+							}
+
+						},
+						e => {
+							console.log(e)
+						});
+				} else if (temp.funName == "fruitInfo") {
+
+					let gameData = temp.gameData;
+					let fruitIndexArray = [0, 0, 0];
+					if (temp.gameData.hasOwnProperty("calorie")) {
+						fruitIndexArray = fruit.getFruitIndex(gameData.calorie);
+					}
+
+					this.urlToBase64("https://bbeng-bucket.oss-cn-beijing.aliyuncs.com/cocos/fruitMachine.png", (toBase64Url) => {
+						this.sendMessage("onFruitInfo", {
+							// 水果雪碧图
+							fruitBase64Url: toBase64Url,
+							// 雪碧图 单张图片宽高
+							unitWidth: 100,
+							unitHeight: 100,
+							unit: "px",
+							imageStartPosY: 0,
+							imageEndPosY: -1200,
+							fruitIndexArray: fruitIndexArray
+						});
+					})
+
+
+
+				}else if(temp.funName == "urlToBase64"){
+					let gameData = temp.gameData;
+					if(gameData.url){
+						this.urlToBase64(gameData.url, (toBase64Url) => {
+							this.sendMessage("onUrlToBase64", {
+								base64: toBase64Url,
+							});
+						})
+					}else{
+						this.sendMessage("onUrlToBase64", {
+							base64: {},
+						});
+					}
+					
+				}
+			},
+			goBack: function() {
+				// 返回
+				var webview = weex.requireModule('webview');
+				webview.goBack(this.$refs.webview);
+			},
+			goForward: function() {
+				//前进
+				var webview = weex.requireModule('webview');
+				webview.goForward(this.$refs.webview);
+			},
+
+			onPageStart: function(e) {
+				// 监听页面加载成功
+				this.PageStart = true;
+				console.log("onPageStart==", e);
+			},
+			onPageFinish: function(e) {
+				//clearHistory
+				// currentWebview.clear();
+				console.log("onPageFinish==", e);
+				// if (e.url)
+				// 	this.pagefinish = e.url;
+				// if (e.canGoBack)
+				// 	this.canGoBack = e.canGoBack;
+				// if (e.canGoForward)
+				// 	this.canGoForward = e.canGoForward;
+				// var tn = currentWebview.getStyle().titleNView;
+				// tn.titleText = e.detail.title || '郁野科技游戏';
+				// currentWebview.setStyle({
+				// 	titleNView: tn
+				// });
+
+			},
+			onError: function(e) {
+				// 监听页面加载错误
+				// this.error = this.url;
+				console.error(e);
+			},
+			onReceivedTitle: function(e) {
+				// if (e.title) {
+				// 	var tn = currentWebview.getStyle().titleNView;
+				// 	tn.titleText = e.detail.title || '郁野科技游戏';
+				// 	currentWebview.setStyle({
+				// 		titleNView: tn
+				// 	});
+				// }
+			},
+			reloadWebviewUrl() {
+				// 刷新网页
+				var webview = weex.requireModule('webview');
+				webview.reload(this.$refs.webview);
+			}
+		}
+	}
+</script>
+
+<style>
+	/* #ifdef APP-PLUS */
+	.web-view {
+		flex: 1;
+		flex-direction: column;
+		border-style:solid;
+		border-width: 1rpx;
+	}
+
+	.web-view-child {
+		width: 750rpx;
+		flex: 1;
+	}
+
+	/* #endif */
+	/* #ifdef H5 */
+
+	.web-view {
+		display: flex;
+		flex-direction: column;
+		position: absolute;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+	}
+
+	.web-view-child {
+		position: relative;
+		width: 100%;
+		height: 100%;
+	}
+
+	/* #endif */
+
+
+	.sendMessage {
+		width: 300rpx;
+		position: fixed;
+		bottom: 100rpx;
+		left: 50rpx;
+	}
+
+	.web-back {
+		position: fixed;
+		top: 20px;
+		right: 20px;
+		width: 140rpx;
+		height: 60rpx;
+		border-radius: 45px;
+		/* border: 0.5rpx solid #FFFFFF; */
+		box-shadow: 0px 0px 1px #FFFFFF;
+		background-color: rgba(0, 0, 0, 0.3);
+
+		/* #ifndef APP-PLUS-NVUE */
+		z-Index: 10;
+		display: flex;
+		/* #endif */
+
+		justify-content: center;
+		align-items: center;
+	}
+</style>

+ 558 - 0
pages/game-page/game-ranking/game-ranking.vue

@@ -0,0 +1,558 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack" :title="pageTitle" backgroundColor="rgba(151, 151, 255, 1)"
+		 color="#FFFFFF" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="w-left-arrow" src="../../../static/m-icon/leftBack.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		
+		
+		<view class="make-bg-bPurple rankingTop">
+			<view style="position:absolute;left:0; right:0; top:-100px; bottom:0;margin:auto;" class="flex justify-center align-center">
+				<image style="width: 337px;height: 337px;" src="/static/ranking-light.png"></image>
+			</view>
+			<!-- 底部领奖台 -->
+			<view class="flex justify-center rankingImageContainer">
+				<image style="height: 94px; width: 100%; margin: 0 37rpx;" src="/static/ranking-plat.png"></image>
+			</view>
+			<view class="rankingImageContainer">
+				<view class="text-white text-bold text-15px text-center" style="margin-top: 66px;width: 160rpx;">{{rankInfo?rankInfo.rankScoreList[1]:''}}</view>
+				<view class="text-white text-bold text-15px text-center" style="margin: 38px 75rpx 0; width: 160rpx;">{{rankInfo?rankInfo.rankScoreList[0]:''}}</view>
+				<view class="text-white text-bold text-15px text-center" style="margin-top: 66px;width: 160rpx;">{{rankInfo?rankInfo.rankScoreList[2]:''}}</view>
+
+			</view>
+
+
+			<!-- 头像部分 -->
+			<view class="rankingHeadContainer">
+
+				<view class="flex justify-around  margin-left margin-right" style="margin-top: 40px; width: 100%;">
+					<!-- 排名2 -->
+					<view class="text-white flex justify-center flex-direction align-center" style="margin-top: 25px;width: 160rpx;height: 100%;">
+						<view v-if="rankUserInfo[1].bShow" class="rankHeadMin" style="border: 3px solid #dee2e5; ">
+							<image class="rankHead" mode="aspectFill" :src="rankUserInfo[1].avatarUrl"></image>
+							<view class="flex justify-center rankingNum">
+								<view style="background-color: #dee2e5;" class="flex justify-center align-center rankingNumChild">
+									2
+								</view>
+							</view>
+						</view>
+						{{rankUserInfo[1].username}}
+					</view>
+					<!-- 排名1 -->
+					<view class="text-white flex justify-center flex-direction align-center" style="height: 100%;width: 160rpx;">
+						<view v-if="rankUserInfo[0].bShow" class="rankHeadBig">
+
+							<image class="rankHead" mode="aspectFill" :src="rankUserInfo[0].avatarUrl"></image>
+							<view style="position: absolute;top:-14px;left: 0;  width: 100%;height: 16px; " class="flex justify-center">
+								<image style=" width: 22px;height: 16px;" src="../../../static/ranking-crown.png"></image>
+
+							</view>
+
+							<view class="flex justify-center rankingNumOne">
+
+								<view style=" background-color: #fed642;" class="flex justify-center align-center rankingNumOneChild">
+									1
+								</view>
+							</view>
+						</view>
+						{{rankUserInfo[0].username}}
+					</view>
+					<!-- 排名3 -->
+					<view class="text-white flex justify-center flex-direction align-center" style="margin-top: 25px;width: 160rpx;height: 100%;">
+						<view v-if="rankUserInfo[2].bShow" class="rankHeadMin" style="border: 3px solid #fdaf41;">
+							<image class="rankHead" mode="aspectFill" :src="rankUserInfo[2].avatarUrl"></image>
+							<view class="flex justify-center rankingNum">
+								<view style=" background-color: #fdaf41;" class="flex justify-center align-center rankingNumChild">
+									3
+								</view>
+							</view>
+						</view>
+						{{rankUserInfo[2].username}}
+					</view>
+
+				</view>
+
+			</view>
+
+
+		</view>
+
+		<!-- 切换游戏信息和分类部分 -->
+		<view style="background-color: #FFFFFF; box-shadow: 0px 0px 3px 2px rgba(113, 113, 219, 0.23);">
+
+			<view class="flex justify-between padding">
+				<view class="flex justify-center align-center ">
+					<image style="width:50px;height: 50px; background-color: #eeeeee; border-radius: 8px;" :src="rankSelectedGame?rankSelectedGame.gameIcon:''"></image>
+					<view style="margin-left: 22rpx;">{{rankSelectedGame?rankSelectedGame.gameName:''}}</view>
+				</view>
+
+				<view class="button-fav" @tap="showModal" data-target="bottomModal">切换</view>
+
+			</view>
+			<view class="nav flex  justify-around align-center ">
+				<view style="width: 200rpx; margin: 0 40rpx;" class="cu-item text-bold text-18px text-center" :class="0==TabCur?'make-text-bPurple cur':''"
+				 data-id="0" @tap="tabSelect">
+					全国
+				</view>
+				<view style="height: 30px; border-right: 1rpx solid #AAAAAA;"></view>
+				<view style="width: 200rpx; margin: 0 40rpx;" class="cu-item text-bold text-18px text-center text-cut" :class="1==TabCur?'make-text-bPurple cur':''"
+				 data-id="1" @tap="tabSelect">
+					{{cityName}}
+				</view>
+			</view>
+		</view>
+		<!-- 滚动部分 style="height: 300px; margin-bottom: 87px;"-->
+		<view >
+			<scroll-view style="max-height:300px; width: 100%; padding: 22rpx; box-sizing: border-box;" scroll-y="true">
+				<view class="flex justify-between align-center bg-white" style="height: 73px; width: 100%; border-radius: 8px; margin-bottom:14rpx ; "
+				 v-for="(item,index) in otherUserInfoList" v-bind:key="index">
+					<view class="flex justify-center align-center  " style="margin-left: 68rpx;">
+						<view class="text-13px margin-right flex justify-center align-center text-bold" style="background-color: #f6f3f7; width: 27px;height: 27px; border-radius: 45px;">{{index+1}}</view>
+						<image class="head-image-50" :src="item.avatarUrl"></image>
+						<view class="text-16px text-bold margin-left">{{item.username}}</view>
+					</view>
+
+					<view class="text-bold text-16px" style="margin-right: 68rpx;">{{otherScoreList[index]}}</view>
+				</view>
+				
+				<view v-if="otherUserInfoList.length == 0 " class="text-center text-gray">没有其他排名数据~</view>
+				<view style="height: 73px; "></view>
+			</scroll-view>
+		</view>
+
+		<view class="flex justify-between align-center bg-white" style="position: fixed;bottom: 0;height: 73px; width: 100%;">
+			<view class="flex justify-center align-center " style="margin-left: 68rpx;">
+				<view class="text-13px margin-right text-gray">{{rankInfo&&rankInfo.userRank>3?'名落孙山':'金榜题名'}}</view>
+				<image class="head-image-50" :src="rankInfo?rankInfo.userInfo.avatarUrl:''"></image>
+				<view class="text-16px text-bold margin-left">{{rankInfo?rankInfo.userInfo.username:''}}</view>
+			</view>
+
+			<view class="text-bold text-16px" style="margin-right: 68rpx;">{{rankInfo&&rankInfo.userScore?rankInfo.userScore:0}}</view>
+		</view>
+		
+		
+
+		<view class="cu-modal bottom-modal" :class="modalName=='bottomModal'?'show':''" @tap="hideModal">
+			<view class="cu-dialog bg-white" style=" border-radius: 15px;" @tap.stop="">
+				<view class="flex justify-center align-center" style="width: 100%; height: 60rpx;" @tap="hideModal">
+					<view class="text-blue" style="width: 80rpx; height: 2px; background-color: #AAAAAA;"></view>
+				</view>
+				<view class="article" style="position: relative; ">
+					<view class="title">
+						最近在玩
+					</view>
+					<view class="cu-item">
+						<view class="cu-form-group margin-top">
+							<view v-if="playRankingGames.length!=0" class="grid col-4 homepage-grid-square flex-sub ">
+								<view v-for="(item,index) in playRankingGames" :key="index" v-if="index<4" @tap="onChangeGame(item)">
+									<block v-if="platform == gamePlatform[item.platform] || item.platform == 2">
+										<image class="item-img" :src="item.gameIcon" mode="aspectFill"></image>
+										<view class="border text-center text-cut">{{item.gameName}}</view>
+									</block>
+									
+								</view>
+							</view>
+							<view v-else class="text-center text-gray" :style="{width:'100%'}">去玩游戏吧~</view>
+						</view>
+					</view>
+				</view>
+
+				<view class="article" style="position: relative; ">
+					<view class="title">
+						总榜
+					</view>
+					<scroll-view scroll-y="true"  class="cu-item">
+						<view class="cu-form-group ">
+							<view class="grid col-4 homepage-grid-square flex-sub ">
+								<view v-if="calorieGame" @tap="onChangeGame(calorieGame)">
+									<image class="item-img" :src="calorieGame.gameIcon" mode="aspectFill"></image>
+									<view class="border text-center margin-bottom text-cut">{{calorieGame.gameName}}</view>
+								</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+
+				<view class="article" style="height: 270px; position: relative; bottom: 10px;">
+					<view class="title">
+						全部游戏
+					</view>
+					<scroll-view scroll-y="true" style="height: 250px;" class="cu-item">
+						<view class="cu-form-group ">
+							<view v-if="versionCodeState&&versionCodeState.showGame&&allGames.length!=0" class="grid col-4 homepage-grid-square flex-sub ">
+								<view v-if="platform == gamePlatform[item.platform] || item.platform == 2"  v-for="(item,index) in allGames" :key="index" @tap="onChangeGame(item)">
+									<image class="item-img" :src="item.gameIcon" mode="aspectFill"></image>
+									<view class="border text-center margin-bottom text-cut">{{item.gameName}}</view>
+								</view>
+							</view>
+							<view v-else class="text-center text-gray" :style="{width:'100%'}">去玩游戏吧~</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import config from '../../../common/config.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+
+	export default {
+		computed: mapState(['rankSelectedGame', 'rankInfo', 'cityName', 'city', 'playRankingGames', 'playGames', 'hasLogin', 'allGames','platform','gamePlatform','versionCodeState']),
+		data() {
+			return {
+				pageTitle: '排行榜',
+				TabCur: 0,
+				rankUserInfo: [{
+						bShow: false,
+						avatarUrl: '',
+						username: '',
+					},
+					{
+						bShow: false,
+						avatarUrl: '',
+						username: '',
+					},
+					{
+						bShow: false,
+						avatarUrl: '',
+						username: '',
+					}
+				],
+				//除去前三名的数据
+				otherUserInfoList: [],
+				otherScoreList: [],
+
+				modalName: null,
+
+				scrollviewHight: 0,
+
+				//卡路里游戏
+				calorieGame: null,
+			}
+		},
+		onLoad() {
+			let that = this;
+			//获得全部游戏列表
+			that.getAllGame(() => {
+				reqUtil.requestData(config.URL.GETRANKGAME).then(res => {
+						console.warn('GETRANKGAME =====', res);
+						// 如果玩家有记录显示的游戏,
+						if (res.data !== null) {
+							that.$store.state.rankSelectedGame = res.data;
+							that.onGetRank();
+							reqUtil.requestData(config.URL.GAMEDETAIL, {
+								gameId: '1'
+							}).then(res => {
+									that.calorieGame = res.data.gameInfo;
+								},
+								e => {
+									console.log(e)
+								});
+						} else {
+							// //如果没有记录到用户的选择数据,给一个游戏显示
+							// if (that.allGames.length == 0) {
+							// 	console.warn("allGames 没有任何游戏!");
+							// 	return;
+							// }
+							// //设置第一个游戏给显示
+							// that.$store.state.rankSelectedGame = that.allGames[0];
+							// console.log("this.getAllGame rankSelectedGame", that.rankSelectedGame);
+							// that.onGetRank();
+							
+							reqUtil.requestData(config.URL.GAMEDETAIL, {
+								gameId: '1'
+							}).then(res => {
+									console.log("*************", res);
+									that.calorieGame = res.data.gameInfo;
+									that.$store.state.rankSelectedGame = that.calorieGame;
+									that.onGetRank();
+								},
+								e => {
+									console.log(e)
+								});
+						}
+					},
+					e => {
+						console.log(e)
+					});
+			});
+
+
+			
+
+			//获取最近玩的游戏列表
+			reqUtil.requestData(config.URL.RECENTLYPLAYINGGETBYPLATFORM).then(res => {
+					console.log('RECENTLYPLAYINGGETBYPLATFORM =====', res);
+					if (res.code == 0 && res.data.gameList) {
+						// that.$store.state.playRankingGames = res.data.gameList;
+						let _arry = [];
+						for(let i=0;i<res.data.gameList.length;i++){
+							if(res.data.gameList[i].gameRankingShow){
+								_arry.push(res.data.gameList[i]);
+							}
+						}
+						that.$store.state.playRankingGames = _arry;
+						that.onGetRank();
+					}
+				},
+				e => {
+					console.log(e)
+				});
+
+
+
+		},
+		onReady() {
+			let that = this;
+			uni.getSystemInfo({
+				success(res) {
+					// 计算组件的高度
+					let view = uni.createSelectorQuery().select('#nav-bar');
+					view.boundingClientRect(data => {
+						let navHeight = data.height;
+						let scrollXHight = uni.upx2px(90);
+						that.scrollviewHight = res.windowHeight - navHeight - 265-125-73;
+					}).exec();
+				}
+			});
+		},
+		methods: {
+			...mapMutations(['getRankGame', 'getAllGame']),
+			tabSelect(e) {
+				this.TabCur = e.currentTarget.dataset.id;
+
+				if (this.TabCur == 1 && this.city.cityCode == "") {
+					console.warn("选择城市时候,cityCode 不能为空");
+					return;
+				}
+
+
+				this.onGetRank();
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showModal(e) {
+				this.modalName = e.currentTarget.dataset.target
+			},
+			hideModal(e) {
+				this.modalName = null
+			},
+			onChangeGame(item) {
+				uni.showToast({
+					title: '',
+					icon: "loading",
+					duration: 10000
+				})
+				// console.log(item);
+				//这里切换游戏
+				let that = this;
+				//切换游戏,修改一次用户记录的数据
+				reqUtil.requestData(config.URL.MOTIFYRANKGAME, {
+					gameId: item.gameId,
+					score: 111
+				}, "POST").then(res => {
+						console.log('MOTIFYRANKGAME =====', res, item);
+						//设置当前显示的游戏数据
+						that.$store.state.rankSelectedGame = item;
+						that.hideModal();
+						that.onGetRank();
+					},
+					e => {
+						console.log(e)
+					});
+			},
+
+			onGetRank() {
+				uni.showToast({
+					title: '',
+					icon: "loading",
+					duration: 10000
+				})
+				// console.log( this.rankSelectedGame);
+				if(!this.rankSelectedGame)return;
+				this.getRankGame({
+					param: {
+						type: this.TabCur == 0 ? "china" : "city",
+						cityCode: this.city.cityCode,
+						gameId: this.rankSelectedGame.gameId
+					},
+					callback: (res) => {
+						uni.hideToast();
+						if (res.data == null) return;
+						for (let i = 0; i < 3; i++) {
+							if (this.rankInfo.rankingList[i]) {
+								this.rankUserInfo[i] = Object.assign({
+									bShow: true
+								}, this.rankInfo.rankingList[i])
+
+								// console.log("=====", this.rankUserInfo[i]);
+							} else {
+								this.rankUserInfo[i] = Object.assign({
+									bShow: false,
+									avatarUrl: '',
+									username: '',
+								})
+
+
+							}
+						}
+						//.slice(3)
+						this.otherUserInfoList = this.rankInfo.rankingList;
+						this.otherScoreList = this.rankInfo.rankScoreList;
+
+					}
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	.rankingTop {
+		position: relative;
+		width: 100%;
+		height: 265px;
+	}
+
+	.rankingImageContainer {
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		height: 94px;
+		width: 100%;
+		display: flex;
+		justify-content: center;
+	}
+
+	.rankingNum {
+		position: absolute;
+		bottom: -10px;
+		left: 0;
+		width: 100%;
+		height: 20px;
+	}
+
+	.rankingNumChild {
+		width: 20px;
+		height: 20px;
+		border-radius: 45px;
+	}
+
+
+	.rankingNumOne {
+		position: absolute;
+		bottom: -12px;
+		left: 0;
+		width: 100%;
+		height: 24px;
+	}
+
+	.rankingNumOneChild {
+		width: 24px;
+		height: 24px;
+		border-radius: 45px;
+	}
+
+	.rankingHeadContainer {
+		position: absolute;
+		top: 0;
+		left: 0;
+		height: 172px;
+		width: 100%;
+		display: flex;
+		justify-content: center;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.button-fav {
+		background-color: rgba(153, 150, 252, 255);
+		color: #FFFFFF;
+		border-radius: 10px;
+		width: 184rpx;
+		height: 90rpx;
+		display: flex;
+		justify-content: center;
+		text-align: center;
+		align-items: center;
+	}
+
+	.head-image-50 {
+		width: 50px;
+		height: 50px;
+		background-color: #eeeeee;
+		border-radius: 45px;
+	}
+
+	.title {
+		text-align: justify;
+		/* padding: 40rpx 30rpx; */
+		font-size: 15px;
+		position: relative;
+		height: 30px;
+		line-height: 60upx;
+		margin: 20rpx 40rpx;
+		font-weight: 400;
+		color: rgba(26, 26, 26, 1);
+	}
+
+	.homepage-grid-square {
+		width: 250rpx;
+		/* height: 250rpx; */
+		align-items: start;
+
+	}
+
+	.homepage-grid-square image {
+		width: 144rpx;
+		height: 144rpx;
+	}
+
+	.item-img {
+		border-radius: 20rpx;
+		box-shadow: 0px 1px 2px 0px rgba(113, 113, 219, 0.23);
+	}
+
+	.rankHead {
+		width: 100%;
+		height: 100%;
+		border-radius: 45px;
+		flex-shrink: 0;
+	}
+
+	.rankHeadMin {
+		display: flex;
+		position: relative;
+		width: 55px;
+		height: 55px;
+
+		border-radius: 45px;
+		box-sizing: border-box;
+		margin-bottom: 21px;
+	}
+
+	.rankHeadBig {
+		display: flex;
+		position: relative;
+		width: 73px;
+		height: 73px;
+		border: 3px solid #fed642;
+		border-radius: 45px;
+		box-sizing: border-box;
+		margin-bottom: 21px;
+	}
+</style>

+ 62 - 0
pages/game-page/game-search/game-search.vue

@@ -0,0 +1,62 @@
+<template>
+	<view>
+		<!-- 自定义导航栏 -->
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickRight="onNavConver" @clickLeft="showClickEvent('DrawerModalL')"
+		 title="游戏" color="#FFFFFF" fixed="true">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="png-more" src="../../../static/more.png"></image>
+				</view>
+			</view>
+		
+			<view slot="right">
+		<view class=" flex align-center " style="margin-right: 10rpx;">
+			<image class="png-more" src="../../../static/mConver.png"></image>
+		</view>
+			</view>
+		</uni-nav-bar>
+		<view class="cu-bar search bg-white">
+			<view class="search-form round">
+				<text class="cuIcon-search"></text>
+				<input @focus="InputFocus" @blur="InputBlur" :adjust-position="false" type="text" placeholder="搜索图片、文章、视频" confirm-type="search"></input>
+			</view>
+			<view class="action">
+				<button class="cu-btn bg-green shadow-blur round" @tap="onBack">取消</button>
+			</view>
+		</view>
+		<sideBar ref="sideBar">
+			
+		</sideBar>
+	</view>
+</template>
+
+<script>
+	import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue";
+	import sideBar from "@/components/side-bar/side-bar.vue";
+	
+	export default {
+		components: {
+			uniNavBar,
+			sideBar
+		},
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			showClickEvent(){
+				this.$refs.sideBar.showModal();
+			},
+			onBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 521 - 0
pages/game-page/game/game.vue

@@ -0,0 +1,521 @@
+<template>
+	<view>
+		<!--  rgba(116, 172, 240, 1)-->
+		<uni-nav-bar id="nav-bar" status-bar="true" backgroundColor="rgba(153, 150, 252, 255)" @clickLeft="showClickEvent('DrawerModalL')"
+		 @clickRight="onNavHome" title="娱乐" color="#FFFFFF" fixed="true">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="png-more" src="../../../static/more.png"></image>
+				</view>
+			</view>
+			<view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<view class="cuIcon-home text-20px-before"></view>
+				</view>
+			</view>
+		</uni-nav-bar>
+
+		<view class="scrollX">
+			<scroll-view scroll-x class="bg-white nav solid-bottom scrollX-padding" scroll-with-animation :scroll-left="scrollLeft">
+				<view class="cu-item text-18px" :class="index == TabCur ? 'make-text-bPurple cur' : 'cu-color'" v-for="(item, index) in tabList"
+				 :key="index" @tap="tabSelect" :data-id="index" :data-category_id="item.categoryType" v-if="item.categoryType !== 0">
+					{{ item.categoryName }}
+				</view>
+			</scroll-view>
+			<view class="png-search">
+				<!-- <image style="width: 50rpx; height: 50rpx;" src="/static/search.png" @tap="onNavSearch"></image> -->
+			</view>
+		</view>
+
+		<scroll-view scroll-y="true" :style="{ height: scrollviewHigh + 'px' }" @scrolltolower="lower">
+			<view v-if="(cIndex != -1 && gameShow)||ConnectBindingDevice" class="game-item card-view" v-for="(item, index) in gameList" :key="index" :data-id="index">
+				<view @tap="onNavToWebviewGame(item)">
+					<view class="game-image-container">
+						<image mode="aspectFill" class="game-item-image" :src="item.gamePicture"></image>
+						<image class="head-image" :src="item.gameIcon"></image>
+
+						<view class="play-bg-image">
+							<image class="play-image" src="/static/play.png"></image>
+						</view>
+					</view>
+					<view class="cu-list menu-avatar">
+						<view class="cu-item">
+							<view class="content flex-sub">
+								<view>{{ item.gameName }}</view>
+								<view class='flex flex-wrap ' style="margin: 10rpx 0;">
+									<view style="padding-right:5rpx;" v-for="(item,index) in item.gameTags" :key="index">
+										<view class='cu-tag line-purple radius'>{{item.tagName}}</view>
+									</view>
+								</view>
+								<!-- <view class="text-sm flex justify-between" style="color:rgba(201, 201, 201, 1);">{{item.createTime}}</view> -->
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="text-gray text-sm text-center padding flex flex-direction" style="width: 100%;">
+					<view @tap="onFavoriteAdd(item)">
+						<image class="margin-lr-xs right-png" style="margin: 25px 0;" :src="item.gameFavorite?'/static/favorite_r.png':'/static/favorite_g.png'"
+						 mode="aspectFill"></image>
+					</view>
+					<view style="margin-top: 30px;" @tap="onNavComment">
+						<!-- <image class="margin-lr-xs right-png" style="margin: 20px 0;" src="/static/info_g.png" mode="aspectFill"></image> -->
+					</view>
+					<view style="margin-top: 60px;" @tap="onNavDetail(item)">
+						<view class="cuIcon-moreandroid margin-lr-xs" style="font-size: 20px; margin: 10px 0;  color: #d6d6d6;"></view>
+					</view>
+				</view>
+			</view>
+			<view v-if="(cIndex == -1 && !gameShow) || gameList.length == 0 || ConnectBindingDevice == null" class="text-16px text-gray text-center margin">没有更多数据</view>
+			<view style="height: 17px;"></view>
+		</scroll-view>
+
+		<!-- <view class="float-png">
+			<image src="/static/conversion@2x.png" mode="aspectFit" @tap="onNavConver"></image>
+		</view> -->
+		<round-menu @trigger="onRoundTrigger"></round-menu>
+		<sideBar ref="sideBar"></sideBar>
+	</view>
+</template>
+
+<script>
+	import uniNavBar from '@/components/uni-nav-bar/uni-nav-bar.vue';
+	import sideBar from '@/components/side-bar/side-bar.vue';
+	import config from '../../../common/config.js';
+	import reqUtil from '../../../util/util-js/requstUtil.js';
+	import roundMenu from "@/components/round-menu/round-menu.vue";
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	export default {
+		components: {
+			uniNavBar,
+			sideBar,
+			roundMenu
+		},
+		computed: mapState(['ConnectBindingDevice', 'BLEConnectDevice', 'cIndex','versionCodeState','platform','gamePlatform']),
+		data() {
+			return {
+				tabList: [],
+				TabCur: 0,
+				Category: 0,
+				scrollLeft: 0,
+				scrollviewHigh: '',
+
+
+				bDontUpdate: false,
+
+				//游戏列表
+				gameList: [],
+				gamePage: 1,
+				gameSize: 10,
+				
+				//默认显示
+				gameShow: true,
+				//编码的item
+				encodeItem: '',
+
+			};
+		},
+		onLoad(option) {
+			let _this = this;
+
+			console.log("option========:", option);
+			let _index = 1;
+			if (option && option.type) {
+				if (option.type == "game") {
+					_index = 1;
+				} else if (option.type == "video") {
+					_index = 2;
+				}
+			}
+			//获得游戏类目
+			reqUtil.requestData(config.URL.GAMECATEGORY).then(
+				res => {
+					console.log('GAMECATEGORY =====', res);
+					if (res.code == 0) {
+						this.tabList = res.data;
+						this.TabCur = _index;
+						this.categoryType = this.tabList[_index].categoryType;
+						this.getGameList(this.categoryType);
+					}
+				},
+				e => {
+					console.log(e);
+				}
+			);
+
+		},
+		onReady() {
+			let _this = this;
+			uni.getSystemInfo({
+				success(res) {
+					// 计算组件的高度
+					let view = uni.createSelectorQuery().select('#nav-bar');
+					view.boundingClientRect(data => {
+						let navHeight = data.height;
+						let scrollXHight = uni.upx2px(90);
+						_this.scrollviewHigh = res.windowHeight - navHeight - scrollXHight;
+					}).exec();
+				}
+			});
+		},
+		methods: {
+			...mapMutations(['glimitPlayGame']),
+			// 跳转转换页面
+			onNavConver() {
+				uni.reLaunch({
+					url: '../../conversion-page/conversion/conversion',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			//跳转回主页
+			onNavHome() {
+				uni.reLaunch({
+					url: '../../personal-page/personal/personal',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			tabSelect(e) {
+				if (this.TabCur != e.currentTarget.dataset.id) {
+					//重新设置参数
+					this.bDontUpdate = false;
+					this.gameList = [];
+					this.gamePage = 1;
+					this.gameSize = 10;
+					this.TabCur = e.currentTarget.dataset.id;
+					this.categoryType = e.currentTarget.dataset.category_id;
+					this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60;
+					this.getGameList(this.categoryType);
+				}
+
+			},
+			showClickEvent() {
+				this.$refs.sideBar.showModal();
+			},
+			onNavSearch() {
+
+				uni.showToast({
+					title: '功能尚未开放',
+					icon: 'none'
+				})
+				return;
+
+				uni.navigateTo({
+					url: '../game-search/game-search',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			//收藏
+			onFavoriteAdd(item) {
+				//添加收藏
+				let favoritesTemp = {
+					'fObjectId': item.gameId,
+					'favoritesType': 0,
+				}
+
+				reqUtil.requestData(config.URL.FAVORITESMODIFY, favoritesTemp).then(res => {
+						console.log('FAVORITESMODIFY =====', res);
+						if (res.code == 0) {
+							if (!res.data.bHas) {
+								item.gameFavorite = false;
+								uni.showToast({
+									title: "取消收藏",
+									icon: "none"
+								})
+							} else {
+								uni.showToast({
+									title: "收藏成功",
+									icon: "none"
+								})
+								item.gameFavorite = true;
+							}
+						}
+
+					},
+					e => {
+						console.log(e)
+					});
+			},
+			onNavComment() {
+				uni.showToast({
+					title: '功能尚未开放',
+					icon: 'none'
+				})
+				return;
+				uni.navigateTo({
+					url: '../game-comment/game-comment',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onNavDetail(item) {
+				// console.log(item);
+				let temItem = encodeURIComponent(JSON.stringify(item));
+				// return;
+				uni.navigateTo({
+					url: '../game-detail/game-detail?item=' + temItem,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onNavToWebviewGame(item) {
+				// console.log("====item == ",item);
+				// if (!this.BLEConnectDevice || this.cIndex == -1) {
+				// 	uni.showToast({
+				// 		title: "没有连接绑带,请连接后重试!",
+				// 		icon: "none"
+				// 	})
+				// 	return;
+				// }
+				//1.先判断模式
+				//如果都不存在,返回
+				this.glimitPlayGame({
+					gameTags: item.gameTags,
+					callback: () => {
+						reqUtil.requestData(config.URL.GAMEDETAIL, item).then(res => {
+								console.log('GAMEDETAIL =====', res);
+								if (res.code == 0) {
+									this.encodeItem = encodeURIComponent(JSON.stringify(res.data.gameInfo));
+
+									// #ifdef APP-PLUS
+									uni.navigateTo({
+										url: '../game-play-sub/game-play-sub?item=' + this.encodeItem,
+										success: res => {},
+										fail: () => {},
+										complete: () => {}
+									});
+									// #endif 
+									// #ifdef H5
+									uni.navigateTo({
+										url: '../game-play/game-play-web?item=' + this.encodeItem,
+										success: res => {},
+										fail: () => {},
+										complete: () => {}
+									});
+									// #endif
+								}
+
+							},
+							e => {
+								console.log(e)
+							});
+					}
+				});
+
+
+
+			},
+
+			getGameList(categoryType) {
+				uni.showToast({
+					icon: "loading",
+					title: "",
+					mask: true,
+					duration: 10000
+				})
+				//获得游戏列表
+				reqUtil.requestData(
+					config.URL.GAMELIST_FROM_CATEGORY_PLATFORM, {
+						categoryType: categoryType,
+						//endTime 可以不设置,服务器默认设置一个值
+						endTime: config.endTime,
+						page: this.gamePage,
+						size: this.gameSize
+					}
+				).then(res => {
+						console.log('GAMELIST_FROM_CATEGORY_PLATFORM =====', res);
+						if (res.code == 0) {
+							uni.hideToast();
+
+							if (res.data.length < this.gameSize) {
+								this.bDontUpdate = true;
+							}
+
+							if (res.data.length != 0) {
+								uni.showToast({
+									icon: "none",
+									title: "更新成功",
+								})
+							} else {
+								uni.showToast({
+									icon: "none",
+									title: "没数据啦",
+								})
+							}
+							this.gameList = this.gameList.concat(res.data);
+							
+							if (categoryType == 1) {
+								//game
+								this.gameShow = this.versionCodeState.showGame;
+								
+							} else if (categoryType == 2) {
+								//game
+								this.gameShow = this.versionCodeState.showVideo;
+							}
+						}
+					},
+					e => {
+						console.log(e);
+						uni.showToast({
+							icon: "none",
+							title: "更新出错",
+						})
+					}
+				);
+			},
+
+			onRoundTrigger(data) {
+				console.log("onRoundTrigger==", data);
+				// return;
+				let url = '';
+				switch (data.item.type) {
+					case "personal":
+						//个人中心页面
+						url = '../../personal-page/personal/personal';
+						break;
+					case "game":
+						url = '../../game-page/game/game';
+						break;
+					default:
+						url = '../../personal-page/personal/personal';
+						break;
+				}
+				uni.reLaunch({
+					url: url,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			lower(e) {
+				if (this.bDontUpdate) return;
+				console.log(e);
+				this.gamePage++;
+				this.getGameList(this.categoryType);
+			}
+		}
+	};
+</script>
+
+<style>
+	page {
+		background-color: #fff;
+	}
+
+	.float-png {
+		position: absolute;
+		right: 15px;
+		bottom: 200px;
+		width: 56px;
+		height: 56px;
+	}
+
+	.png-search {
+		width: 50rpx;
+		height: 100%;
+		position: absolute;
+		right: 20px;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.scrollX {
+		position: relative;
+		width: 100%;
+		height: 90upx;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.scrollX-padding {
+		padding: 0 74px 0 20px;
+	}
+
+	.game-item {
+		display: flex;
+		justify-content: flex-start;
+		flex-direction: row;
+		background-color: white;
+
+		margin: 17px 14px 0 17px;
+		/* border-bottom: 1rpx solid rgba(240, 240, 240, 1); */
+	}
+
+	.game-item-image {
+		width: 542rpx;
+		height: 542rpx;
+		z-index: 99;
+	}
+
+	.head-image {
+		position: absolute;
+		bottom: -20px;
+		left: 0;
+		margin-left: 17px;
+		width: 80rpx;
+		height: 80rpx;
+		border: 2px solid white;
+		border-radius: 100px;
+		z-index: 100;
+	}
+
+	.play-bg-image {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		top: 0;
+		right: 0;
+		width: 112rpx;
+		height: 112rpx;
+
+		margin: auto;
+		background: rgba(0, 0, 0, 0.25);
+		/* opacity: 0.25; */
+		border-radius: 100px;
+		z-index: 100;
+	}
+
+	.play-image {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+		top: 0;
+		right: 0;
+		width: 44rpx;
+		height: 54rpx;
+		margin: auto;
+		z-index: 100;
+	}
+
+	.game-image-container {
+		position: relative;
+	}
+
+	.game-index {
+		z-index: 300;
+	}
+
+	.cu-color {
+		color: rgba(191, 191, 193, 1);
+	}
+
+	.right-png {
+		width: 36rpx;
+		height: 32rpx;
+	}
+</style>

+ 57 - 0
pages/info-page/app-info/app-info.vue

@@ -0,0 +1,57 @@
+<template>
+	<view >
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()"  title="" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+			<!-- <view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<image style="width: 60rpx;height: 50rpx;" src="../../../static/devicesIconSimple/upgrade.png"></image>
+				</view>
+			</view> -->
+		</uni-nav-bar>
+		<view class="flex flex-direction justify-center align-center" style="height: 350px;">
+			<view>
+				<image style="width: 180px;height: 180px ;" src="../../../static/logo/logo.png"></image>
+			</view>
+			<view >哔蹦</view>
+			<view v-if="version !=''" class="margin-sm">Version:{{version}}</view>
+			<view v-if="version !=''" class="text-11px text-grey">{{showEndTime}}</view>
+			<view  class="margin-sm"></view>
+			<button class="make-bg-bPurple text-white text-14px" @click="checkAppUpdata">检测更新</button>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+	
+	export default {
+		computed: mapState(['version','showEndTime']),
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			...mapMutations(['checkAppUpdata']),
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+	page{
+		background-color: white;
+	}
+</style>

+ 290 - 0
pages/login-page/bindPhone/bindPhone.vue

@@ -0,0 +1,290 @@
+<template>
+	<view class="container">
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack" :title="pageTitle" color="#000000" fixed="true"
+		 :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		<view style="height:6px ;width: 100%; background-color: #f2eff2;"></view>
+
+		<!-- 手机端登录,获取验证码 -->
+		<view class="input-container" style="margin: 32px 102rpx 0 68rpx;">
+			<view class="make-text-bPurple text-bold margin-bottom" style="font-size: 20px;">绑定手机</view>
+			<view class="input-row padding" style="width: 318px;">
+				<m-input type="number" maxlength="11" clearable  v-model="account" placeholder="请填写11位手机号码"></m-input>
+			</view>
+		</view>
+		<view class="flex justify-between" style="margin: 32px  96rpx 0 68rpx; ">
+			<view class="text-22px make-text-bPurple">输入验证码</view>
+			<view v-if="bCodeDisabled" class="btn-code" style="background-color: rgb(0,0,0);opacity: 0.5;">重新获取({{count}})</view>
+			<view v-else class="btn-code" @tap="onGetCode">获取验证码</view>
+		</view>
+
+		<!-- 手机端登录 -->
+		<view class="text-16px text-gray" style="margin: 20px 0 0 96rpx;">已发送4位验证码...</view>
+
+		<view class="code-input-main">
+			<view class="inputLine">
+				<view class="input-item">{{inputCode[0]}}</view>
+				<view class="input-item">{{inputCode[1]}}</view>
+				<view class="input-item">{{inputCode[2]}}</view>
+				<view class="input-item">{{inputCode[3]}}</view>
+			</view>
+
+			<input class="code-input-input" v-model="inputCode" maxlength="4" type="number" />
+		</view>
+
+		<view class="btn-row">
+			<view class="btn-confirm" :disabled="inputCode.length<4" @tap="onConfirm">确认绑定</view>
+		</view>
+
+		<input class='ipt' type="number" :maxlength="Length" :focus="bFocus"></input>
+
+	</view>
+</template>
+
+<script>
+	import mInput from '@/components/m-input.vue'
+	import config from '@/common/config.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import verify from '@/util/util-js/verify.js'
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+
+	export default {
+		components: {
+			mInput
+		},
+		data() {
+			return {
+				//获取验证码页面
+				bGetCode: true,
+				bMobileLogin: true,
+				providerList: [],
+				hasProvider: true,
+				account: '',
+				password: '',
+				positionTop: 0,
+				//输入框参数
+				Length: 4, //输入框个数
+				bFocus: false, //聚焦
+				Value: "", //输入的内容
+				inputCode: '',
+
+				pageTitle: "绑定手机",
+				bConfirm: false,
+			}
+		},
+		computed: mapState(['bNewUser', 'forcedLogin', 'phoneNumber', 'bCodeDisabled', 'count']),
+		methods: {
+			...mapMutations(['countDown','resetCountDown']),
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			onGetCode() {
+				if (!verify.checkPhone(this.account)) {
+					uni.showToast({
+						icon: 'none',
+						title: '输入手机号错误'
+					});
+					return;
+				}
+				// this.$store.state.phoneNumber = this.account;
+				//置灰状态
+				if (this.bCodeDisabled) return;
+				//调用store 倒计时
+				this.countDown(this.account);
+
+			},
+			inputEvent(res) {
+				console.log("input 1 input inputCode  components : ", res.detail.value);
+			},
+			//验证码操作
+			//注册
+			onConfirm() {
+				var _self = this;
+				if (!verify.checkPhone(_self.account)) {
+					uni.showToast({
+						icon: 'none',
+						title: '输入手机号错误'
+					});
+					return;
+				}
+				if (_self.bConfirm) return;
+				
+				uni.showToast({
+					title:"",
+					icon:"loading",
+					mask:true,
+					duration:10000
+				})
+				_self.bConfirm = true;
+			
+				reqUtil.requestData(config.URL.BINDPHONE, {
+					"phoneNumber": _self.account,
+					"code": _self.inputCode
+				}).then(res => {
+						console.log('requestData BINDPHONE =====', res);
+						uni.hideToast();
+						_self.bConfirm = false;
+						if (res.code == 0) {
+							uni.showToast({
+								title: "绑定手机号成功",
+								mask: true,
+								duration: 1000
+							})
+							_self.$store.state.phoneNumber = _self.account;
+							
+							_self.resetCountDown();
+							// 绑定电话成功后,回退页面
+							uni.navigateBack({
+								delta: 1
+							})
+
+						} else if (res.code == 213) {
+							uni.showToast({
+								title: "手机号已使用过,请换个号码",
+								mask: true,
+								icon: 'none',
+								duration: 3000
+							})
+						} else {
+							uni.showToast({
+								title: "绑定失败",
+								mask: true,
+								icon: 'none',
+								duration: 1000
+							})
+						}
+						
+					
+					},
+					e => {
+						console.log(e);
+						uni.hideToast();
+						_self.bConfirm = false;
+					});
+			}
+		}
+	}
+</script>
+
+<style>
+	.input-row {
+		display: flex;
+		flex-direction: row;
+		position: relative;
+	}
+
+	.btn-row {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+
+	}
+
+	.container {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #FFFFFF;
+	}
+
+
+
+	.input-container {
+		border-bottom: 1rpx solid #e7e9eb;
+	}
+
+	.btn-code {
+		width: 235rpx;
+		height: 63rpx;
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 10px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 15px;
+		color: #FFFFFF;
+	}
+
+	.btn-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 10px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 17px;
+		color: #FFFFFF;
+	}
+
+
+
+
+	.code-input-main {
+		display: flex;
+		flex-direction: column;
+		width: 100%;
+		/* border: 1rpx solid #000000; */
+		height: 150px;
+		position: relative;
+	}
+
+	.input-item {
+		width: 106rpx;
+		height: 118rpx;
+		font-size: 20px;
+		line-height: 118rpx;
+		background-color: rgba(244, 241, 244, 255);
+		/* border: 1rpx solid #ddd; */
+		text-align: center;
+		border-radius: 8px;
+		margin-left: 44rpx;
+		/* margin-right: 40upx; */
+		color: rgba(86, 86, 86, 1);
+		font-weight: bold;
+
+	}
+
+	.inputLine {
+		display: flex;
+		justify-content: flex-start;
+		width: 100%;
+		top: 80rpx;
+		left: 52rpx;
+		position: absolute;
+		z-index: 1;
+	}
+
+	.code-input-input {
+		height: 150px;
+		position: absolute;
+		width: 100%;
+		outline: none;
+		color: transparent;
+		text-shadow: 0 0 0 transparent;
+		width: 300%;
+		left: -100%;
+		top: 0;
+		/* background: #000000; */
+		/* border: 1rpx solid #007AFF; */
+		z-index: 10;
+	}
+
+	.ipt {
+		width: 0;
+		height: 0;
+	}
+</style>

+ 205 - 0
pages/login-page/feedback/feedback.vue

@@ -0,0 +1,205 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack" :title="pageTitle" color="#000000" fixed="true"
+		 :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		<form @submit="onUploadFeedback" class="padding flex flex-direction">
+
+			<textarea name="problemDescription" :maxlength='500' class="feedback-textarea" placeholder="请输入你要反馈的问题"
+			 placeholder-class="feedback-placeholder"></textarea>
+			<view style="height: 20px;"></view>
+			<view class="feedback-upload-image">
+				<view class="cu-bar" style="color: #BEBEBE; font-size: 14px;">
+					<view class="action">
+						请提供问题的截图或照片
+					</view>
+					<view class="action">
+						{{imgList.length}}/4
+					</view>
+				</view>
+				<view style="height: 1px; background-color: #dadada; margin: 0px 15px 15px;"></view>
+				<view class="cu-form-group" style="background-color: #F6F6F6;">
+					<view class="grid col-4 grid-square flex-sub">
+						<view class="bg-img" v-for="(item,index) in imgList" :key="index" @tap="ViewImage" :data-url="imgList[index]">
+							<image :src="imgList[index]" mode="aspectFill"></image>
+							<view class="cu-tag bg-red" @tap.stop="DelImg" :data-index="index">
+								<text class='cuIcon-close'></text>
+							</view>
+						</view>
+						<view class="solids" style="background-color: #EEEEEE; border-radius: 15rpx;" @tap="ChooseImage" v-if="imgList.length<4">
+							<text class='cuIcon-cameraadd'></text>
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<view class="cu-form-group margin-top radius" style="background-color: #F6F6F6;">
+				<view class="feedback-title">用户名</view>
+				<input name="userName" style=" text-align: right;" placeholder="请输入用户名" placeholder-class="feedback-placeholder"
+				 :value="userName"></input>
+			</view>
+			<view class="cu-form-group margin-top radius" style="background-color: #F6F6F6;">
+				<view class="feedback-title">联系方式</view>
+				<input name="phoneNumber" type="number" style="text-align: right;" placeholder="请输入手机号" placeholder-class="feedback-placeholder"
+				 :value="phoneNumber"></input>
+			</view>
+			<view class="flex flex-direction margin-top">
+				<button form-type="submit" class="cu-btn make-bg-bPurple margin-tb-sm lg text-white">提交</button>
+			</view>
+
+			<input v-show="false" name="versionName" :value="version"></input>
+			<input v-show="false" name="versionCode" :value="versionCode"></input>
+
+		</form>
+	</view>
+</template>
+
+<script>
+	import reqUtil from '@/util/util-js/requstUtil.js';
+	import config from '@/common/config.js';
+
+	import {
+		mapState
+	} from 'vuex';
+
+	export default {
+		computed: mapState(['userName', 'phoneNumber', 'version', 'versionCode']),
+		data() {
+			return {
+				pageTitle: '意见反馈',
+				imgList: []
+			}
+		},
+		methods: {
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			ChooseImage() {
+				uni.chooseImage({
+					count: 4, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					success: (res) => {
+						if (this.imgList.length != 0) {
+							this.imgList = this.imgList.concat(res.tempFilePaths)
+						} else {
+							this.imgList = res.tempFilePaths
+						}
+					}
+				});
+			},
+			ViewImage(e) {
+				uni.previewImage({
+					urls: this.imgList,
+					current: e.currentTarget.dataset.url
+				});
+			},
+			DelImg(e) {
+				uni.showModal({
+					title: '删除照片',
+					content: '确定要删除这张照片吗?',
+					cancelText: '不是',
+					confirmColor: '#ff0004',
+					confirmText: '是',
+					success: res => {
+						if (res.confirm) {
+							this.imgList.splice(e.currentTarget.dataset.index, 1)
+						}
+					}
+				})
+			},
+
+			onUploadFeedback(e) {
+				console.log(e.detail.value, this.imgList);
+				if(e.detail.value.problemDescription.length <= 10){
+					uni.showModal({
+						title:'提示',
+						content: "请填写不少于10个字的问题内容!",
+						showCancel: false
+					});
+					return;
+				}
+				if(this.imgList.length == 0){
+					uni.showModal({
+						title:'提示',
+						content: "至少选择一张反馈问题的截图照片!",
+						showCancel: false
+					});
+					return;
+				}
+				uni.showLoading({
+					title: '上传中...',
+					mask: true
+				});
+				
+				let files = this.imgList.map((value, index) => {
+					return {
+						name: 'images' + index,
+						uri: value
+					};
+				});
+				console.log("files:",files);
+				reqUtil.reqUploadFiles(config.URL.UPLOADFEEDBACK, e.detail.value, files)
+					.then(res => {
+						uni.hideLoading();
+						this.imgList = [];
+						console.log(res)
+						if(res.code ==0){
+							uni.showModal({
+								content: '成功',
+								showCancel: false
+							});
+						}else{
+							uni.showModal({
+								title:'上传失败',
+								content: res.msg,
+								showCancel: false
+							});
+						}
+					}, e => {
+						console.log(e);
+						uni.hideLoading();
+					});
+			}
+		}
+	}
+</script>
+
+<style>
+	page {
+		background-color: #FFFFFF;
+	}
+
+	.feedback-textarea {
+		/* border: solid 1px red; */
+		background-color: #F6F6F6;
+		width: 100%;
+		border-radius: 20rpx;
+		padding: 50rpx;
+	}
+
+	.feedback-placeholder {
+		color: #BEBEBE;
+		font-size: 14px;
+	}
+
+	.feedback-upload-image {
+		background-color: #F6F6F6;
+		width: 100%;
+		border-radius: 20rpx;
+		padding: 20rpx;
+	}
+
+	.feedback-title {
+		font-size: 14px;
+		color: #7B7B7B;
+	}
+</style>

+ 1000 - 0
pages/login-page/login/login.vue

@@ -0,0 +1,1000 @@
+<template>
+	<view class="container">
+
+		<image class="bg-image" src="../../../static/loginBg.png" mode="aspectFill"></image>
+		<view class="up">
+			<!-- 258px  -->
+			<view id="HeadArea" style="height: 25%;"></view>
+			<view id="MidArea">
+				<view class="action-row align-center " style="background-color: rgba(0, 0, 0, 0.2); padding: 29px 104rpx 29px 104rpx;">
+					<!-- <view class="text-white text-22px  text-center" style="width: 100%;" @tap="onSwitchLogin(true)">手机登录</view> -->
+					<view class=" text-white " :class="bMobileLogin?'text-22px':'text-16px'" @tap="onSwitchLogin(true)">手机登录</view>
+					<view class="text-bold text-white">|</view>
+					<view class=" text-white " :class="!bMobileLogin?'text-22px':'text-16px'" @tap="onSwitchLogin(false)">账号登录</view>
+				</view>
+				<view v-if="bMobileLogin">
+					<!-- 手机端登录,获取验证码 -->
+					<view v-if="bGetCode">
+						<view class="input-container" style="margin: 32px 102rpx 0 68rpx;">
+							<view class="input-row padding" style="width: 318px;">
+								<m-input type="number" maxlength="11" clearable v-model="account" placeholder="请填写11位手机号码"></m-input>
+							</view>
+						</view>
+						<view class="btn-row" style="margin: 32px 0 0 0;">
+							<view class="btn-confirm" @tap="onNavToReg">获取验证码</view>
+						</view>
+						<!-- <view v-if="appleOauth" class="btn-row" style="margin: 5px 0 0 0;">
+							<view class="btn-apple-confirm" @tap="onAppleReg">
+								<image style="width: 48rpx;height: 48rpx;margin-right: 5px;" src="../../../static/img/apple.png"></image>
+								<view>通过Apple注册</view>
+							</view>
+						</view> -->
+					</view>
+					<view v-else>
+						<!-- 手机端登录 -->
+						<view class="text-22px make-text-bPurple" style="margin: 34px 0 0 96rpx;">输入验证码</view>
+						<view class="text-16px text-gray" style="margin: 20px 0 0 96rpx;">已发送4位验证码至 +86 {{phoneNumber}}</view>
+
+						<view class="code-input-main">
+							<view class="inputLine">
+								<!-- <view class="input-item" maxlength="1" :value="inputCode[0]">{{inputCode[0]}}</input> -->
+								<view class="input-item">{{inputCode[0]}}</view>
+								<view class="input-item">{{inputCode[1]}}</view>
+								<view class="input-item">{{inputCode[2]}}</view>
+								<view class="input-item">{{inputCode[3]}}</view>
+							</view>
+							<!-- @input="inputEvent" -->
+							<input class="code-input-input" v-model="inputCode" maxlength="4" type="number" />
+						</view>
+
+						<view class="btn-row">
+							<!--  :disabled="inputCode.length<4" -->
+							<view class="btn-confirm " :class="inputCode.length<4?'disabledBtn':''" @tap="onConfirm">确认</view>
+						</view>
+
+
+						<view v-if="bCodeDisabled" class="action-row-text">
+							<view class="action-child text-gray">重新获取({{count}})</view>
+							<!-- <text style="color: #FFFFFF;">|</text>
+						<navigator url="../pwd/pwd">忘记密码</navigator> -->
+						</view>
+						<view v-else class="action-row-text">
+							<view class="action-child text-gray" @tap="onGetCode">重新发送验证码</view>
+							<!-- <text style="color: #FFFFFF;">|</text>
+						<navigator url="../pwd/pwd">忘记密码</navigator> -->
+						</view>
+
+
+						<input class='ipt' type="number" :maxlength="Length" :focus="bFocus" @input="onInputFocus" @focus="onFocus"></input>
+
+
+					</view>
+
+
+				</view>
+				<view v-else>
+					<!-- 密码登录 -->
+					<!-- <view class="text-26px text-white" style="margin: 116px 0 0 58rpx;">密码登录</view>
+					<view class="text-16px text-white" style="margin: 32px 0 0 58rpx;">记录你的运动轨迹,呵护你的身体健康</view> -->
+					<view class="input-container" style="margin: 10px 102rpx 0 68rpx;">
+						<view class="input-row padding" style="width: 318px;">
+							<m-input type="number" clearable v-model="account" placeholder="输入手机号码"></m-input>
+						</view>
+
+					</view>
+					<view class="input-container" style="margin: 8px 102rpx 0 68rpx;">
+						<view class="input-row padding" style="width: 318px;">
+							<m-input type="password" maxlength="14" displayable v-model="password" placeholder="请输入密码"></m-input>
+						</view>
+
+					</view>
+
+					<!-- border: 1rpx solid #007AFF; -->
+					<view class="btn-row" style="margin: 20px 0 0 0;">
+						<view class="btn-confirm" @tap="bindLogin">登录</view>
+					</view>
+					<!-- 	<view class="action-row " style="margin: 29px 58rpx 0 58rpx;">
+						<view class="text-14px text-gray">
+							<text class="cuIcon-roundcheck "></text>
+							我已阅读并同意使用<span style="color: rgba(151, 151, 255, 1);">服务协议</span></view>
+						<view class="text-14px" style="color: rgba(151, 151, 255, 1);">忘记密码?</view>
+					</view> -->
+
+
+				</view>
+
+			</view>
+
+			<!-- v-if="hasProvider" style="border: 1rpx solid #000000;"-->
+			<view class="oauth-row" v-if="bGetCode" v-bind:style="{top: positionTop + 'px'}" >
+				<view v-if="hasProvider&&providerList.length>0">
+					<view v-if="(bInstallWechat&&!bHideWeixin)||appleOauth" class="text-14px text-gray">其他登录方式</view>
+					<!-- <view v-else style="height: 50px;"></view> -->
+					<view class="flex justify-center align-center margin-top-sm flex-direction">
+						<!-- 	<view class="oauth-image" v-for="provider in providerList" :key="provider.value">
+							<image :src="provider.image" @tap="oauth(provider.value)"></image>
+						</view> -->
+						<view v-if="bInstallWechat&&!bHideWeixin" v-for="provider in providerList" :key="provider.value">
+							<view class="btn-apple-confirm" @tap="oauth(provider.value)">
+								<image style="width: 48rpx;height: 48rpx;margin-right: 5px;" :src="provider.image"></image>
+								<view>通过微信注册</view>
+							</view>
+						</view>
+						<view v-if="appleOauth" class="btn-apple-confirm" @tap="onAppleReg">
+							<image style="width: 48rpx;height: 48rpx;margin-right: 5px;" src="../../../static/img/apple.png"></image>
+							<view>通过Apple注册</view>
+						</view>
+					</view>
+				</view>
+
+				<view class="action-row-text">
+					<view class=" ">登录即代表同意哔蹦</view>
+					<view class="text-bold text-decoration" @tap="onSwitchAgree('agreement')">用户协议</view>
+					<view class=" ">和</view>
+					<view class="text-bold text-decoration" @tap="onSwitchAgree('privacy')">隐私政策</view>
+				</view>
+			</view>
+
+		</view>
+
+
+	</view>
+</template>
+
+<script>
+	import config from '../../../common/config.js';
+	import service from '../../../util/util-js/service.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import verify from '../../../util/util-js/verify.js'
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+	import mInput from '../../../components/m-input.vue'
+
+	export default {
+		components: {
+			mInput
+		},
+		data() {
+			return {
+				//获取验证码页面
+				bGetCode: true,
+				bMobileLogin: true,
+				providerList: [],
+				hasProvider: true,
+				account: '',
+				password: '',
+				positionTop: 0,
+				//输入框参数
+				Length: 4, //输入框个数
+				bFocus: false, //聚焦
+				Value: "", //输入的内容
+				inputCode: '',
+
+				//苹果服务
+				appleOauth: null,
+			}
+		},
+		computed: mapState(['bNewUser', 'forcedLogin', 'phoneNumber', 'bCodeDisabled', 'count', 'bInstallWechat',
+			'bHideWeixin','clientName'
+		]),
+		methods: {
+			...mapMutations(['login', 'addUserAvatarAndLogin', 'appleUserInfoLogin', 'accountLogin', 'countDown',
+				'resetCountDown'
+			]),
+			initProvider() {
+				// const filters = ['weixin', 'qq', 'sinaweibo'];
+				const filters = ['weixin'];
+				uni.getProvider({
+					service: 'oauth',
+					success: (res) => {
+						if (res.provider && res.provider.length) {
+							for (let i = 0; i < res.provider.length; i++) {
+								if (~filters.indexOf(res.provider[i])) {
+									this.providerList.push({
+										value: res.provider[i],
+										image: '../../../static/img/' + res.provider[i] + '.png'
+									});
+								}
+							}
+							this.hasProvider = true;
+						}
+					},
+					fail: (err) => {
+						console.error('获取服务供应商失败:' + JSON.stringify(err));
+					}
+				});
+			},
+			initPosition() {
+				let _self = this;
+
+				let headView = uni.createSelectorQuery().in(this).select('#HeadArea');
+				headView.fields({
+					size: true,
+				}, data => {
+					// console.log("得到节点信息1" + JSON.stringify(data));
+					let headHeight = data.height;
+					if(_self.clientName.indexOf('iPad')>-1){
+						_self.positionTop = headHeight + 390;
+					}else{
+						_self.positionTop = headHeight + 280;
+					}
+					// let midView = uni.createSelectorQuery().in(this).select('#MidArea');
+					// midView.fields({
+					// 	size: true,
+					// }, data => {
+					// 	console.log("得到节点信息2" + JSON.stringify(data));
+					// 	let midHeight = data.height;
+					// 	/**
+					// 	 * 使用 absolute 定位,并且设置 bottom 值进行定位。软键盘弹出时,底部会因为窗口变化而被顶上来。
+					// 	 * 反向使用 top 进行定位,可以避免此问题。
+					// 	 * uni.getSystemInfoSync().windowHeight - 220
+					// 	 */
+					// 	_self.positionTop = headHeight + midHeight;
+					// }).exec();
+				}).exec();
+
+
+				if (plus.runtime.isApplicationExist({
+						pname: 'com.tencent.mm',
+						action: 'weixin://'
+					})) {
+					//安装了微信
+					// console.log("安装了微信");
+					_self.$store.state.bInstallWechat = true;
+				} else {
+					//未安装微信
+					// console.log("未安装微信");
+					_self.$store.state.bInstallWechat = false;
+				}
+
+			},
+
+			bindLogin() {
+				let _self = this;
+				/**
+				 * 客户端对账号信息进行一些必要的校验。
+				 * 这里先简单处理
+				 */
+				if (this.account.length < 11) {
+					uni.showToast({
+						icon: 'none',
+						title: '账号最短为 11 个字符'
+					});
+					return;
+				}
+				if (this.password.length < 6) {
+					uni.showToast({
+						icon: 'none',
+						title: '密码最短为 6 个字符'
+					});
+					return;
+				}
+
+				reqUtil.requestData(config.URL.PASSWORDlOGIN, {
+					"phoneNumber": this.account,
+					"password": this.password
+				}).then(res => {
+						console.log('requestData PASSWORDlOGIN =====', res);
+						if (res.code == 0) {
+							uni.showToast({
+								title: "成功",
+								mask: true,
+								duration: 1000
+							})
+							//密码登录成功
+							uni.setStorageSync('token', res.data.token);
+							_self.$store.state.bNewUser = res.data.newUser;
+							_self.accountLogin(function() {
+								console.log("_self.bNewUser=", _self.bNewUser);
+								if (_self.bNewUser) {
+									uni.reLaunch({
+										url: "../../my-page/userInfo/userInfo"
+									})
+								} else {
+									uni.reLaunch({
+										url: "../../personal-page/personal/personal"
+									})
+								}
+
+							});
+
+						} else {
+							uni.showToast({
+								title: "用户密码错误",
+								icon: 'none',
+								mask: true,
+								duration: 1000
+							})
+						}
+
+
+					},
+					e => {
+						console.log(e)
+					});
+			},
+			oauth(value) {
+				let _self = this;
+				uni.showToast({
+					title: "",
+					icon: "loading",
+					duration: 10000
+				})
+
+				uni.login({
+					provider: value,
+					success: (res) => {
+						// console.log('code11:', res);
+						// #ifdef APP-PLUS
+						// android 端微信登录
+						uni.request({
+							url: config.URL.ANDROIDLOGINURL,
+							data: {
+								openid: res.authResult.openid,
+								unionid: res.authResult.unionid,
+							},
+							success: (res) => {
+								// console.log('ANDROIDLOGINURL请求返回:', res);
+								let resData = res.data;
+								uni.hideToast();
+								if (resData.code == 0) {
+									uni.showToast({
+										title: "登录中..",
+										icon: "loading",
+										mask: true,
+										duration: 10000
+									})
+									//登录成功
+									uni.setStorage({
+										key: 'token',
+										data: resData.data.token,
+										success: function() {
+											_self.$store.state.bNewUser = resData.data.newUser;
+											console.log("wx token = ", resData.data.token);
+											//如果是新用户,则获取用户信息
+											if (_self.bNewUser) {
+												uni.getUserInfo({
+													provider: value,
+													success: (infoRes) => {
+														//获取了用户信息后
+														let userInfo = {
+															username: infoRes.userInfo.nickName,
+															gender: 0 //默认是男性
+														}
+														//服务器0是男,1是女
+														//微信的2 对应的女
+														if (infoRes.userInfo.gender == 2) {
+															//服务器记录的是1
+															userInfo.gender = 1;
+														}
+														console.log("微信数据:", infoRes, userInfo);
+
+														uni.downloadFile({
+															url: infoRes.userInfo.avatarUrl,
+															success: (res) => {
+																// if (res.statusCode === 200) {
+																// 	console.log('下载成功');
+																// }
+																// console.log(res.tempFilePath);
+																_self.addUserAvatarAndLogin({
+																	params: userInfo,
+																	filePath: res.tempFilePath,
+																	callback: () => {
+																		_self.$store.state.openid = infoRes.userInfo.openId || '';
+																		uni.hideToast();
+
+																		uni.reLaunch({
+																			url: "../../my-page/perfectInfo/perfectInfo"
+																		})
+																	}
+																});
+															}
+														});
+													},
+													fail: (failRes) => {
+														uni.hideToast();
+														console.log('getUserInfo failRes:', failRes);
+													}
+												})
+											} else {
+												//如果不是新用户,直接获取用户信息
+												_self.accountLogin(function() {
+													uni.hideToast();
+													uni.reLaunch({
+														url: "../../personal-page/personal/personal"
+													})
+												});
+											}
+
+										}
+									});
+								} else {
+									uni.showToast({
+										title: "验证码错误",
+										mask: true,
+										icon: 'none',
+										duration: 1000
+									})
+								}
+							}
+						})
+						// #endif
+						// #ifdef MP-WEIXIN
+						uni.request({
+							url: config.URL.USERlOGINURL,
+							data: {
+								appid: 'wxd6dfd60729d33d17',
+								code: res.code,
+								source: 1,
+							},
+							success: (res) => {
+								// console.log('请求返回:', res, res.cookies[0]);
+
+								// return;
+								uni.getUserInfo({
+									provider: value,
+									success: (infoRes) => {
+										/**
+										 * 实际开发中,获取用户信息后,需要将信息上报至服务端。
+										 * 服务端可以用 userInfo.openId 作为用户的唯一标识新增或绑定用户信息。
+										 */
+										// this.toMain(infoRes.userInfo.nickName);
+										console.log('getUserInfo infoRes:', infoRes)
+
+										uni.request({
+											url: config.URL.WXGETUSERINFO,
+											data: {
+												appid: 'wxd6dfd60729d33d17',
+												encryptedData: infoRes.encryptedData,
+												iv: infoRes.iv,
+												signature: infoRes.signature,
+												rawData: infoRes.rawData
+											},
+											success: (wxInfoRes) => {
+												console.log('WXGETUSERINFO 请求返回:', wxInfoRes);
+											}
+
+										})
+									},
+									fail: (failRes) => {
+										console.log('getUserInfo failRes:', failRes)
+									}
+								});
+							}
+						})
+						// #endif
+
+
+					},
+					fail: (err) => {
+						console.error('授权登录失败:' + JSON.stringify(err));
+					}
+				});
+			},
+			callbackUserInfo(userinfo) {
+				console.log('callbackUserInfo:', userinfo);
+			},
+			onSwitchLogin(bMobileLogin) {
+				// console.log(bMobileLogin);
+				this.bMobileLogin = bMobileLogin;
+				//如果是已获取的验证码页面,返回获取验证码界面
+				if (this.bGetCode == false)
+					this.bGetCode = true;
+				// this.bMobileLogin = !this.bMobileLogin;
+			},
+			onNavToReg() {
+				if (!verify.checkPhone(this.account)) {
+					uni.showToast({
+						icon: 'none',
+						title: '输入手机号错误'
+					});
+					return;
+				}
+				// console.log("手机号正确:",this.account);
+				// return;
+				this.$store.state.phoneNumber = this.account;
+				this.bGetCode = false;
+				this.onGetCode();
+			},
+
+			//验证码操作
+			//注册
+			onConfirm() {
+				var _self = this;
+
+				if (_self.inputCode.length < 4) {
+					uni.showToast({
+						title: "请输入4位验证码",
+						icon: "none",
+						duration: 2000,
+						mask: true
+					})
+					return;
+				}
+
+				uni.showToast({
+					title: "",
+					icon: "loading",
+					duration: 10000,
+					mask: true
+				})
+				reqUtil.requestData(config.URL.SMSLOGIN, {
+					"phoneNumber": _self.phoneNumber,
+					"code": _self.inputCode
+				}).then(res => {
+						console.log('requestData GETCODE =====', res);
+						uni.hideToast();
+						if (res.code == 0) {
+							uni.showToast({
+								title: "登录中..",
+								icon: "loading",
+								mask: true,
+								duration: 3000
+							})
+							//登录成功
+							uni.setStorage({
+								key: 'token',
+								data: res.data.token,
+								success: function() {
+									_self.$store.state.bNewUser = res.data.newUser;
+
+									_self.resetCountDown();
+
+									_self.accountLogin(function() {
+										uni.hideToast();
+										if (_self.bNewUser) {
+											uni.reLaunch({
+												url: "../../my-page/userInfo/userInfo"
+											})
+										} else {
+											uni.reLaunch({
+												url: "../../personal-page/personal/personal"
+											})
+										}
+
+									});
+								}
+							});
+
+						} else {
+							uni.showToast({
+								title: "验证码错误",
+								mask: true,
+								icon: 'none',
+								duration: 1000
+							})
+						}
+					},
+					e => {
+						console.log(e);
+						uni.hideToast();
+					});
+			},
+			onGetCode() {
+				//置灰状态
+				if (this.bCodeDisabled) return;
+
+
+				//调用store 倒计时
+				this.countDown(this.phoneNumber);
+
+			},
+			onTap() {
+				this.bFocus = true;
+				console.log(this.bFocus);
+			},
+			onFocus(e) {
+
+				console.log(e);
+				setTimeout(() => {
+					// this.bFocus = false;
+				}, 1000)
+			},
+			onInputFocus(e) {
+				console.log(e.detail.value);
+				this.Value = e.detail.value;
+
+			},
+			inputEvent(res) {
+				console.log("input 1 input code  components : " + res.detail.value);
+				/* this.$emit('vueMsg',res.detail.value); */
+				this.inputCode = res.detail.value;
+
+			},
+			onSwitchAgree(data) {
+				console.log("=== ", data);
+
+				uni.navigateTo({
+					url: "../../login-page/userAgreement/userAgreement?type=" + data
+				})
+			},
+			onAppleReg() {
+				this.onAppleLogout(() => {
+					this.onAppleRegEvent();
+				})
+			},
+			onAppleRegEvent() {
+				let _self = this;
+				uni.login({
+					provider: 'apple',
+					success: (loginRes) => {
+						// console.log('apple login:', loginRes);
+						uni.getUserInfo({
+							provider: 'apple',
+							success(resUser) {
+								//用户信息
+								console.log("resUser:", resUser);
+								uni.showToast({
+									title: '',
+									icon: 'loading',
+									mask: true,
+									duration: 10000,
+								})
+
+								reqUtil.requestData(config.URL.APPLElOGINURL, {
+									"identityToken": resUser.userInfo.identityToken
+								}).then(res => {
+										console.log('requestData apple login =====', res);
+										uni.hideToast();
+										if (res.code == 0) {
+											//登录成功
+											uni.setStorage({
+												key: 'token',
+												data: res.data.token,
+												success: function() {
+													_self.$store.state.bNewUser = res.data.newUser;
+													// console.log("apple token = ", res.data.token);
+													//如果是新用户,则获取用户信息
+													if (_self.bNewUser) {
+														//获取了用户信息后
+														let tempName = "匿名";
+														if (resUser.userInfo.fullName.hasOwnProperty("familyName") &&
+															resUser.userInfo.fullName.hasOwnProperty("givenName")) {
+															tempName = resUser.userInfo.fullName.familyName + resUser.userInfo.fullName.givenName;
+														}
+														let userInfo = {
+															username: tempName,
+															gender: 0 //默认是男性
+														}
+														// console.log("苹果数据11:", resUser.userInfo);
+														// console.log("userInfo:", userInfo);
+														_self.appleUserInfoLogin({
+															params: userInfo,
+															callback: () => {
+																//这里是记录appleid,不是微信
+																_self.$store.state.appleid = resUser.userInfo.openId || '';
+																uni.hideToast();
+
+																uni.reLaunch({
+																	url: "../../my-page/perfectInfo/perfectInfo"
+																})
+															}
+														});
+
+													} else {
+														//如果不是新用户,直接获取用户信息
+														_self.accountLogin(function() {
+															uni.hideToast();
+															uni.reLaunch({
+																url: "../../personal-page/personal/personal"
+															})
+														});
+													}
+
+												}
+											});
+
+										} else {
+											uni.showToast({
+												title: "apple登陆失败",
+												mask: true,
+												icon: 'none',
+												duration: 1000
+											})
+										}
+									},
+									e => {
+										console.log(e);
+										uni.hideToast();
+									});
+							}
+						})
+					},
+					fail: (err) => {
+						//登陆失败
+						console.log('登陆失败:', err)
+						uni.showToast({
+							title: '登陆失败',
+							icon: 'none'
+						})
+					}
+				})
+			},
+			onAppleLogout(callback) {
+				this.appleOauth.logout(function(e) {
+					// plus.nativeUI.alert("注销登录认证成功!");
+					callback(e);
+					console.log("注销登录认证成功!");
+				}, function(e) {
+					// plus.nativeUI.alert("注销登录认证失败: " + JSON.stringify(e));
+					console.log("注销登录认证失败: " + JSON.stringify(e));
+				});
+			},
+			onGetAppleService() {
+				// console.log("onGetAppleService");
+				let _self = this;
+				plus.oauth.getServices(function(services) {
+					for (var i in services) {
+						var service = services[i];
+						// 获取苹果授权登录对象,苹果授权登录id 为 'apple' iOS13以下系统,不会返回苹果登录对应的 service    
+						if (service.id == 'apple') {
+							_self.appleOauth = service;
+							// console.log("this.appleOla:", _self.appleOauth);
+							break;
+						}
+						// console.log("service:", service);
+					}
+				}, function(err) {
+					// 获取 services 失败  
+				})
+			}
+
+		},
+		onReady() {
+			this.initPosition();
+			this.initProvider();
+
+			//获取apple相关服务
+			this.onGetAppleService();
+		}
+
+	}
+</script>
+
+<style>
+	.action-row {
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		height: 67px;
+	}
+
+	.action-row navigator {
+		color: #FFFFFF;
+		font-size: 16px;
+		/* padding: 0 20upx; */
+	}
+
+	.action-row-text {
+		margin-top: 25px;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+	}
+
+	.action-child {
+		/* color: #FFFFFF; */
+		padding: 0 20upx;
+	}
+
+	.oauth-row {
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-content: center;
+		text-align: center;
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		right: 0;
+		z-index: -1;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.oauth-image {
+		width: 76rpx;
+		height: 76rpx;
+		/* border: 1upx solid #dddddd; */
+		/* border-radius: 100upx; */
+		margin: 0 40upx;
+		/* background-color: #ffffff; */
+	}
+
+	.oauth-image image {
+		width: 76rpx;
+		height: 76rpx;
+		/* margin: 20upx; */
+	}
+
+
+	.input-group {
+		background-color: #ffffff;
+		margin-top: 40upx;
+		position: relative;
+	}
+
+	.input-group::before {
+		position: absolute;
+		right: 0;
+		top: 0;
+		left: 0;
+		height: 1upx;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc;
+	}
+
+	.input-group::after {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 1upx;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc;
+	}
+
+	.input-row {
+		display: flex;
+		flex-direction: row;
+		position: relative;
+	}
+
+	.main-title {
+		width: 20%;
+		height: 50upx;
+		min-height: 50upx;
+		padding: 15upx 0;
+		padding-left: 30upx;
+		line-height: 50upx;
+	}
+
+	.main-info {
+		width: 20%;
+		height: 50upx;
+		min-height: 50upx;
+		padding: 15upx 0;
+		padding-left: 30upx;
+		line-height: 50upx;
+	}
+
+	.btn-row {
+		/* margin-top: 50upx; */
+		/* padding: 20upx; */
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.container {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #FFFFFF;
+	}
+
+	.bg-image {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: calc(25% + 67px);
+		opacity: 1;
+	}
+
+	.up {
+		position: absolute;
+		z-index: 1;
+		width: 100%;
+		height: 100%;
+	}
+
+	.input-container {
+		border-bottom: 1rpx solid #e7e9eb;
+	}
+
+	.btn-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 10px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 17px;
+		color: #FFFFFF;
+	}
+
+	.btn-apple-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		/* background-color: rgba(151, 151, 255, 1); */
+		border: 1px solid #000000;
+		border-radius: 10px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 17px;
+		color: #000000;
+		margin-top: 7px;
+	}
+
+
+	.disabledBtn {
+		background-color: rgba(221, 221, 221, 1.0);
+	}
+
+
+
+
+	.code-input-main {
+		display: flex;
+		flex-direction: column;
+		width: 100%;
+		/* border: 1rpx solid #000000; */
+		height: 150px;
+		position: relative;
+	}
+
+	.input-item {
+		width: 106rpx;
+		height: 118rpx;
+		font-size: 20px;
+		line-height: 118rpx;
+		background-color: rgba(244, 241, 244, 255);
+		/* border: 1rpx solid #ddd; */
+		text-align: center;
+
+		border-radius: 8px;
+		margin-left: 44rpx;
+		/* margin-right: 40upx; */
+		color: rgba(86, 86, 86, 1);
+		font-weight: bold;
+
+	}
+
+	.inputLine {
+		display: flex;
+		justify-content: flex-start;
+		width: 100%;
+		top: 80rpx;
+		left: 52rpx;
+		position: absolute;
+		z-index: 1;
+	}
+
+	.code-input-input {
+		height: 150px;
+		position: absolute;
+		width: 100%;
+		outline: none;
+		color: transparent;
+		text-shadow: 0 0 0 transparent;
+		width: 300%;
+		left: -100%;
+		top: 0;
+		/* background: #000000; */
+		/* border: 1rpx solid #007AFF; */
+		z-index: 10;
+	}
+
+	.ipt {
+		width: 0;
+		height: 0;
+	}
+
+	.text-decoration {
+		margin: 0 1rpx;
+		border-bottom: 1rpx solid rgba(0, 0, 0, 0.3);
+		padding-bottom: 1rpx;
+	}
+</style>

+ 150 - 0
pages/login-page/main/main.vue

@@ -0,0 +1,150 @@
+<template>
+    <view class="content">
+		<view class="cu-bar bg-white solid-bottom">
+			<view class="action">
+				<!-- <text class="cuIcon-title text-blue"></text>按钮形状 -->
+			</view>
+			<view class="action">
+				<navigator class="action" url="design" hover-class="none">
+					<text class="text-df text-purple" @tap="onNavUser">编辑</text>
+				</navigator>
+			</view>
+		</view>
+		<view class="cu-card">
+			<view class="cu-item shadow">
+				<view class="content">
+					<view class="solids-bottom padding-xs flex align-center">
+						<view class="flex-sub text-center">
+							<view class="cu-avatar xl round margin-left" style="background-image:url(https://ossweb-img.qq.com/images/lol/web201310/skin/big99008.jpg);"></view>
+							
+							<view class="solid-bottom text-lg padding">
+								
+								<text class="text-black">ColorUI组件库</text>
+							</view>
+							<view class="padding">页面小标题,首要层级显示内容</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="cu-card article">
+			<view class="cu-item shadow">
+				<view class="title"><view class="text-cut">最近在玩</view></view>
+				<view class="content">
+					<image src="https://ossweb-img.qq.com/images/lol/web201310/skin/big10006.jpg"
+					 mode="aspectFill"></image>
+					<view class="desc">
+						<view class="text-content"> 折磨生出苦难,苦难又会加剧折磨,凡间这无穷的循环,将有我来终结!真正的恩典因不完整而美丽,因情感而真诚,因脆弱而自由!</view>
+						<view>
+							<view class="cu-tag bg-red light sm round">正义天使</view>
+							<view class="cu-tag bg-green light sm round">史诗</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="cu-card article">
+			<view class="cu-item shadow">
+				<view class="title"><view class="text-cut">关注游戏</view></view>
+				<view class="content">
+					<image src="https://ossweb-img.qq.com/images/lol/web201310/skin/big10006.jpg"
+					 mode="aspectFill"></image>
+					<view class="desc">
+						<view class="text-content"> 折磨生出苦难,苦难又会加剧折磨,凡间这无穷的循环,将有我来终结!真正的恩典因不完整而美丽,因情感而真诚,因脆弱而自由!</view>
+						<view>
+							<view class="cu-tag bg-red light sm round">正义天使</view>
+							<view class="cu-tag bg-green light sm round">史诗</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+        <view v-if="hasLogin" class="hello">
+            <view class="title">
+                您好 {{userName}},您已成功登录。
+            </view>
+            <view class="ul">
+                <view>这是 uni-app 带登录模板的示例App首页。</view>
+                <view>在 “我的” 中点击 “退出” 可以 “注销当前账户”</view>
+            </view>
+        </view>
+        <view v-if="!hasLogin" class="hello">
+            <view class="title">
+                您好 游客。
+            </view>
+            <view class="ul">
+                <view>这是 uni-app 带登录模板的示例App首页。</view>
+                <view>在 “我的” 中点击 “登录” 可以 “登录您的账户”</view>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+    import {
+        mapState
+    } from 'vuex'
+
+    export default {
+        computed: mapState(['forcedLogin', 'hasLogin', 'userName']),
+        onLoad() {
+            if (!this.hasLogin) {
+                uni.showModal({
+                    title: '未登录',
+                    content: '您未登录,需要登录后才能继续',
+                    /**
+                     * 如果需要强制登录,不显示取消按钮
+                     */
+                    showCancel: !this.forcedLogin,
+                    success: (res) => {
+                        if (res.confirm) {
+							/**
+							 * 如果需要强制登录,使用reLaunch方式
+							 */
+                            if (this.forcedLogin) {
+                                uni.reLaunch({
+                                    url: '../login/login'
+                                });
+                            } else {
+                                uni.navigateTo({
+                                    url: '../login/login'
+                                });
+                            }
+                        }
+                    }
+                });
+            }
+        },
+		methods:{
+			onNavUser(){
+				uni.navigateTo({
+				    url: '../user/user'
+				});
+			}
+		}
+    }
+</script>
+
+<style>
+    .hello {
+        display: flex;
+        flex: 1;
+        flex-direction: column;
+    }
+
+    .title {
+        color: #8f8f94;
+        margin-top: 50upx;
+    }
+
+    .ul {
+        font-size: 30upx;
+        color: #8f8f94;
+        margin-top: 50upx;
+    }
+
+    .ul>view {
+        line-height: 50upx;
+    }
+</style>

+ 53 - 0
pages/login-page/pwd/pwd.vue

@@ -0,0 +1,53 @@
+<template>
+    <view class="content">
+        <view class="input-group">
+            <view class="input-row">
+                <text class="title">邮箱:</text>
+                <m-input type="text" focus clearable v-model="email" placeholder="请输入邮箱"></m-input>
+            </view>
+        </view>
+
+        <view class="btn-row">
+            <button type="primary" class="primary" @tap="findPassword">提交</button>
+        </view>
+    </view>
+</template>
+
+<script>
+    import service from '../../../util/util-js/service.js';
+    import mInput from '../../../components/m-input.vue';
+
+    export default {
+        components: {
+            mInput
+        },
+        data() {
+            return {
+                email: ''
+            }
+        },
+        methods: {
+            findPassword() {
+                /**
+                 * 仅做示例
+                 */
+                if (this.email.length < 3 || !~this.email.indexOf('@')) {
+                    uni.showToast({
+                        icon: 'none',
+                        title: '邮箱地址不合法',
+                    });
+                    return;
+                }
+                uni.showToast({
+                    icon: 'none',
+                    title: '已发送重置邮件至注册邮箱,请注意查收。',
+                    duration: 3000
+                });
+            }
+        }
+    }
+</script>
+
+<style>
+
+</style>

+ 288 - 0
pages/login-page/reg/reg.vue

@@ -0,0 +1,288 @@
+<template>
+	<view class="container">
+		<image class="bg-image" src="../../../static/loginBg.png"></image>
+		<view class="up">
+			<!-- 自定义导航栏 -->
+			<uni-nav-bar id="nav-bar" status-bar='true' :border='false' backgroundColor="rgba(164, 136, 220, 0)" @clickLeft="showClickEvent()"
+			 :title="title" color="#FFFFFF" fixed="true">
+				<view slot="left">
+					<view class=" flex align-center margin-left" @tap="onBack">
+						<image class="png-more" src="../../../static/m-icon/leftBack.png"></image>
+					</view>
+				</view>
+
+				<view slot="right">
+
+				</view>
+			</uni-nav-bar>
+			<!-- 手机端登录 -->
+			<view class="text-26px text-white" style="margin: 105px 0 0 56rpx;">输入验证码</view>
+			<view class="text-16px text-white" style="margin: 40px 0 0 56rpx;">已发送4位验证码至 +86 {{phoneNumber}}</view>
+			<!-- <view class="flex" style="margin: 71px 0 0 46rpx;">
+				<view class="grid col-4 grid-square flex-sub ">
+					<view v-for="(item,index) in 4" :key="index">
+						<input class='iptbox' type="number" disabled :value="Value.length>=index+1?Value[index]:''" :password="false"
+						 @tap="onTap"></input>
+					</view>
+				</view>
+			</view> -->
+			<view class="code-input-main">
+				<view class="inputLine">
+					<input class="input-item" maxlength="1" :value="code[0]"></input>
+					<input class="input-item" maxlength="1" :value="code[1]"></input>
+					<input class="input-item" maxlength="1" :value="code[2]"></input>
+					<input class="input-item" maxlength="1" :value="code[3]"></input>
+				</view>
+				<!-- <view class="inputLine">
+
+					<input class="input-item" maxlength="1" :value="code[3]"></input>
+					<input class="input-item" maxlength="1" :value="code[4]"></input>
+					<input class="input-item" maxlength="1" :value="code[5]"></input>
+				</view> -->
+				<input @input="inputEvent" class="code-input-input" v-model="code" maxlength="4" type="number" />
+			</view>
+
+			<view class="btn-row" style="margin-top: 46px;">
+				<button type="primary" class="primary btn-confirm" :disabled="code.length<4" @tap="onConfirm">确认</button>
+			</view>
+
+
+			<view v-if="bCodeDisabled" class="action-row">
+				<view class="action-child text-gray">重新获取({{count}})</view>
+				<!-- <text style="color: #FFFFFF;">|</text>
+				<navigator url="../pwd/pwd">忘记密码</navigator> -->
+			</view>
+			<view v-else class="action-row">
+				<view class="action-child" @tap="onGetCode">重新发送验证码</view>
+				<!-- <text style="color: #FFFFFF;">|</text>
+				<navigator url="../pwd/pwd">忘记密码</navigator> -->
+			</view>
+
+
+			<input class='ipt' type="number" :maxlength="Length" :focus="bFocus" @input="onInputFocus" @focus="onFocus"></input>
+
+
+		</view>
+
+	</view>
+</template>
+
+<script>
+	import service from '../../../util/util-js/service.js';
+	import mInput from '../../../components/m-input.vue';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import config from '../../../common/config.js';
+	import verify from '../../../util/util-js/verify.js';
+	import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue";
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+	export default {
+		components: {
+			mInput,
+			uniNavBar
+		},
+		data() {
+			return {
+				//输入框参数
+				Length: 4, //输入框个数
+				bFocus: false, //聚焦
+				Value: "", //输入的内容
+				code: '',
+			}
+		},
+		computed: mapState(['phoneNumber', 'bCodeDisabled', 'count']),
+		onLoad() {
+			// console.log("初始化onLoad");
+			this.onGetCode();
+		},
+		methods: {
+			...mapMutations(['countDown', 'accountLogin']),
+			//注册
+			onConfirm() {
+
+				reqUtil.requestData(config.URL.SMSLOGIN, {
+					"phoneNumber": this.phoneNumber,
+					"code": this.code
+				}).then(res => {
+						console.log('requestData GETCODE =====', res);
+						if (res.code == 0) {
+							uni.showToast({
+								title: "注册成功",
+								mask: true,
+								duration: 1000
+							})
+							//登录成功
+							uni.setStorageSync('token', res.data.token);
+							// this.$store.state.hasLogin = true;
+							this.accountLogin();
+							uni.navigateTo({
+								url: "../../personal-page/personal/personal"
+							})
+						} else {
+							uni.showToast({
+								title: "验证码错误",
+								mask: true,
+								icon: 'none',
+								duration: 1000
+							})
+						}
+
+
+					},
+					e => {
+						console.log(e)
+					});
+			},
+			onGetCode() {
+				//置灰状态
+				if (this.bCodeDisabled) return;
+
+
+				//调用store 倒计时
+				this.countDown();
+
+			},
+			onTap() {
+				this.bFocus = true;
+				console.log(this.bFocus);
+			},
+			onFocus(e) {
+
+				console.log(e);
+				setTimeout(() => {
+					// this.bFocus = false;
+				}, 1000)
+			},
+			onInputFocus(e) {
+				console.log(e.detail.value);
+				this.Value = e.detail.value;
+
+			},
+			onBack() {
+				uni.navigateBack();
+			},
+			inputEvent(res) {
+				console.log("input 1 input code  components : ", res.detail.value);
+				/* this.$emit('vueMsg',res.detail.value); */
+
+			}
+		}
+	}
+</script>
+
+<style>
+	.action-row {
+		margin-top: 25px;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+	}
+
+	.action-child {
+		color: #FFFFFF;
+		padding: 0 20upx;
+	}
+
+	.iptbox {
+		width: 102rpx;
+		height: 102rpx;
+		border: 1rpx solid #ddd;
+		border-radius: 8rpx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		text-align: center;
+		background-color: rgba(255, 255, 255, 0.2);
+		color: #FFFFFF;
+		font-size: 20px;
+	}
+
+	.ipt {
+		width: 0;
+		height: 0;
+	}
+
+	.btn-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		background-color: rgba(75, 208, 200, 1);
+		border-radius: 25px;
+		opacity: 0.84;
+	}
+
+	.container {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #000000;
+	}
+
+	.bg-image {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		opacity: 0.55;
+	}
+
+	.up {
+		position: absolute;
+		z-index: 1;
+		width: 100%;
+		/* display: flex; */
+		/* align-items: flex-start; */
+		/* flex-direction: column; */
+	}
+
+	.png-more {
+		width: 10px;
+		height: 19px;
+	}
+
+	.code-input-input {
+		height: 150px;
+		position: absolute;
+		width: 100%;
+		outline: none;
+		color: transparent;
+		text-shadow: 0 0 0 transparent;
+		width: 300%;
+		margin-left: -100%;
+		background: #00000000;
+		/* border: 1rpx solid #007AFF; */
+	}
+
+	.code-input-main {
+		display: flex;
+		flex-direction: column;
+		width: 100%;
+		margin-bottom: 46px;
+		/* border: 1rpx solid #000000; */
+		height: 150px;
+	}
+
+	.input-item {
+		width: 102rpx;
+		height: 102rpx;
+		font-size: 20px;
+		background-color: rgba(255, 255, 255, 0.2);
+		border: 1rpx solid #ddd;
+		text-align: center;
+		border-radius: 8px;
+		margin-left: 40upx;
+		margin-right: 40upx;
+		color: #FFFFFF;
+	}
+
+	.inputLine {
+		display: flex;
+		justify-content: center;
+		width: 100%;
+		margin-top: 80upx;
+	}
+</style>

+ 44 - 0
pages/login-page/user/user.vue

@@ -0,0 +1,44 @@
+<template>
+    <view class="content">
+        <view class="btn-row">
+            <button v-if="!hasLogin" type="primary" class="primary" @tap="bindLogin">登录</button>
+            <button v-if="hasLogin" type="default" @tap="bindLogout">退出登录</button>
+        </view>
+    </view>
+</template>
+
+<script>
+    import {
+        mapState,
+        mapMutations
+    } from 'vuex'
+
+    export default {
+        computed: {
+            ...mapState(['hasLogin', 'forcedLogin'])
+        },
+        methods: {
+            ...mapMutations(['logout']),
+            bindLogin() {
+                uni.navigateTo({
+                    url: '../login/login',
+                });
+            },
+            bindLogout() {
+                this.logout();
+                /**
+                 * 如果需要强制登录跳转回登录页面
+                 */
+                if (this.forcedLogin) {
+                    uni.reLaunch({
+                        url: '../login/login',
+                    });
+                }
+            }
+        }
+    }
+</script>
+
+<style>
+
+</style>

+ 353 - 0
pages/login-page/userAgreement/userAgreement.vue

@@ -0,0 +1,353 @@
+<template>
+    <view class="content">
+      <uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" :title="title" color="#000000" fixed="true" :border="false">
+      	<view slot="left">
+      		<view class=" flex align-center margin-left">
+      			<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+      		</view>
+      	</view>
+      
+      </uni-nav-bar>
+	  
+	  <view style="margin:10px;">
+		  <text v-if="bAgreement">
+		  	  (以下简称“本公司”)按照下列条款与条件提供信息和产品,您在本协议中亦可被称为“用户”,以下所述条款和条件将构成您与本公司,就您使用提供的内容所达成的全部协议(以下称“本协议”)。
+		  	  
+		  	  说明
+		  	  
+		  	  本公司向您提供包括但不限于游戏下载、使用、充值、客户服务、游戏资讯、论坛交流等服务(以下称“本服务”)。本公司针对本服务所制定的相关规定,包括但不限于本公司在游戏平台下运营的任何一款游戏所包含的游戏规则、用户处罚条例,客服条例等,以及本公司就账号使用及管理、游戏充值等服务制定的相关服务协议、规则。本公司在此提示用户,请您在使用本服务前详细阅读本协议的所有内容,尤其是免除、限制本公司责任或者限制用户权利的条款(特别是粗体下划线标注的内容),如您对本协议有任何疑问,请向本公司(020-3755991)进行咨询。一旦您使用本服务,即表示您已阅读并完全同意接受本协议项下所述条款和条件的约束。如果您不同意本协议的任何条款,请您不要使用本服务。未成年人应经其监护人陪同阅读本服务协议并表示同意,方可接受本服务协议。监护人应加强对未成年人的监督和保护,因其未谨慎履行监护责任而损害未成年人利益或者本公司利益的,应由监护人承担责任。
+		  	  
+		  	  权利声明
+		  	  
+		  	  1、本公司及其关联公司(关联企业指与本公司存在直接或间接,股权或以协议安排等其他形式的控制与被控制关系,以及对公司运营具有重大影响关系的公司法人)享有并保留以下各项内容完整的、不可分割的所有权及/或知识产权:
+		  	  
+		  	  (1)游戏平台相关的软件、技术、程序、代码、用户界面等;
+		  	  
+		  	  (2)本服务相关的商标、图形标记。
+		  	  
+		  	  2、本公司提供的服务内容中所涉及的游戏,文字、软件、声音、图片、动画、录像、图表等,均受相关知识产权法以及其他相关法律的保护。未经本公司或者其他相关权利人授权,用户不得复制、使用、修改、摘编、翻译、发行,第三方未经本公司及/或其相关权利人的书面许可,不得以任何方式擅自进行使用。
+		  	  
+		  	  责任限制
+		  	  
+		  	  1、本公司向用户提供的服务均是在依"现状"提供,本公司在此明确声明对本服务不作任何明示或暗示的保证,包括但不限于对服务的可适用性、准确性、及时性、可持续性等。
+		  	  
+		  	  2、用户理解并同意自行承担使用本服务的风险,且用户在使用本服务时,应遵循中国法律的相关规定,由于用户行为所造成的任何损害和后果,本公司均不承担除法律有明确规定外的责任。
+		  	  
+		  	  3、不论在何种情况下,本公司均不对由于网络连接故障、通讯线路、第三方网站、电脑硬件等任何原因给用户造成的任何损失承担除法律有明确规定外的责任。
+		  	  
+		  	  用户行为规范
+		  	  
+		  	  1、用户在本网站注册时,不得使用虚假身份信息。用户应当妥善保存其账户信息和密码,由于用户泄密所导致的损失需由用户自行承担。如用户发现他人冒用或盗用其账户或密码,或其账户存在其他未经合法授权使用之情形,应立即以有效方式通知本公司。用户理解并同意本公司有权根据用户的通知、请求或依据判断,采取相应的行动或措施,包括但不限于冻结账户、限制账户功能等,本公司对采取上述行动所导致的损失不承担除法律有明确规定外的责任。
+		  	  
+		  	  2、用户在使用本服务时须遵守法律法规,不得利用本服务从事违法违规行为,包括但不限于:
+		  	  
+		  	  (1)发布、传送、传播、储存危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
+		  	  
+		  	  (2)发布、传送、传播、储存侵害他人知识产权、商业秘密等合法权利的内容;
+		  	  
+		  	  (3)恶意虚构事实、隐瞒真相以误导、欺骗他人;
+		  	  
+		  	  (4)发布、传送、传播广告信息及垃圾信息;
+		  	  
+		  	  (5)其他法律法规禁止的行为。
+		  	  
+		  	  3、用户不得利用本服务进行任何有损本公司及其关联企业之权利、利益及商誉,或其他用户合法权利之行为。
+		  	  
+		  	  4、用户不得基于本服务从事制作、使用、传播“私服”、“外挂”等侵害本公司合法权益的行为。如有违反,本公司将依据中国现行法律法规及本公司的相关规定予以处理。
+		  	  
+		  	  5、虚拟财产转移服务外,用户不得通过任何方式直接或变相进行游戏账号、游戏币、游戏道具等虚拟财产的转移。
+		  	  
+		  	  6、用户不得从事作弊等损害游戏公平性的行为。用户承诺接受本公司对其游戏数据进行分析,当本公司发现其数据异常时,本公司可根据自己的独立判断认定其为作弊。
+		  	  
+		  	  7、用户不得从事任何利用本公司平台系统漏洞进行有损其他用户、本公司或互联网安全的行为。
+		  	  
+		  	  8、用户知悉并确认,本公司通过公告、邮件、短信、账户通知以及用户在账户中登记的即时通讯工具等方式,向用户发出关于本服务的通知、规则、提示等信息,均为有效通知。该等信息一经公布或发布,即视为已送达至用户。
+		  	  
+		  	  广告信息和促销
+		  	  
+		  	  1、用户同意接受本公司通过公告、邮件、短信、账户通知以及用户在账户中登记的即时通讯工具等方式发送的有关本服务,或本公司、本公司之关联企业或与本公司有合作关系的第三方相关的商品、服务促销或其他商业信息。
+		  	  
+		  	  2、本公司在本服务中可能提供与其他互联网之网站站点或资源的链接,本公司对存在或源于此类网站站点或资源的任何内容、广告、产品或其他资料不予保证或负责;如该链接所载的内容或搜索引擎所提供之链接的内容侵犯用户权利,本公司声明与上述内容无关,且不承担除法律有明确规定外的责任。
+		  	  
+		    </text>
+		  <text v-else>
+				(以下简称“本公司”)按照下列条款与条件提供信息和产品,您在本协议中亦可被称为“用户”,以下所述条款和条件将构成您与本公司,就您使用提供的内容所达成的全部协议(以下称“本协议”)。
+				
+				注册成功的用户后期因游戏问题发生任何纠纷应协商解决,解决不成功的任何一方有权向被告所在地法院提起民事诉讼
+				
+				说明
+				
+				本公司向您提供包括但不限于游戏下载、使用、充值、客户服务、游戏资讯、论坛交流等服务(以下称“本服务”)。本公司针对本服务所制定的相关规定,包括但不限于本公司在游戏平台下运营的任何一款游戏所包含的游戏规则、用户处罚条例,客服条例等,以及本公司就账号使用及管理、游戏充值等服务制定的相关服务协议、规则。本公司在此提示用户,请您在使用本服务前详细阅读本协议的所有内容,尤其是免除、限制本公司责任或者限制用户权利的条款(特别是粗体下划线标注的内容),如您对本协议有任何疑问,请向本公司(020-3755991)进行咨询。一旦您使用本服务,即表示您已阅读并完全同意接受本协议项下所述条款和条件的约束。如果您不同意本协议的任何条款,请您不要使用本服务。未成年人应经其监护人陪同阅读本服务协议并表示同意,方可接受本服务协议。监护人应加强对未成年人的监督和保护,因其未谨慎履行监护责任而损害未成年人利益或者本公司利益的,应由监护人承担责任。
+				
+				权利声明
+				
+				1、本公司及其关联公司(关联企业指与本公司存在直接或间接,股权或以协议安排等其他形式的控制与被控制关系,以及对公司运营具有重大影响关系的公司法人)享有并保留以下各项内容完整的、不可分割的所有权及/或知识产权:
+				
+				(1)游戏平台相关的软件、技术、程序、代码、用户界面等;
+				
+				(2)本服务相关的商标、图形标记。
+				
+				2、本公司提供的服务内容中所涉及的游戏,文字、软件、声音、图片、动画、录像、图表等,均受相关知识产权法以及其他相关法律的保护。未经本公司或者其他相关权利人授权,用户不得复制、使用、修改、摘编、翻译、发行,第三方未经本公司及/或其相关权利人的书面许可,不得以任何方式擅自进行使用。
+				
+				责任限制
+				
+				1、本公司向用户提供的服务均是在依"现状"提供,本公司在此明确声明对本服务不作任何明示或暗示的保证,包括但不限于对服务的可适用性、准确性、及时性、可持续性等。
+				
+				2、用户理解并同意自行承担使用本服务的风险,且用户在使用本服务时,应遵循中国法律的相关规定,由于用户行为所造成的任何损害和后果,本公司均不承担除法律有明确规定外的责任。
+				
+				3、不论在何种情况下,本公司均不对由于网络连接故障、通讯线路、第三方网站、电脑硬件等任何原因给用户造成的任何损失承担除法律有明确规定外的责任。
+				
+				用户行为规范
+				
+				1、用户在本网站注册时,不得使用虚假身份信息。用户应当妥善保存其账户信息和密码,由于用户泄密所导致的损失需由用户自行承担。如用户发现他人冒用或盗用其账户或密码,或其账户存在其他未经合法授权使用之情形,应立即以有效方式通知本公司。用户理解并同意本公司有权根据用户的通知、请求或依据判断,采取相应的行动或措施,包括但不限于冻结账户、限制账户功能等,本公司对采取上述行动所导致的损失不承担除法律有明确规定外的责任。
+				
+				2、用户在使用本服务时须遵守法律法规,不得利用本服务从事违法违规行为,包括但不限于:
+				
+				(1)发布、传送、传播、储存危害国家安全统一、破坏社会稳定、违反公序良俗、侮辱、诽谤、淫秽、暴力以及任何违反国家法律法规的内容;
+				
+				(2)发布、传送、传播、储存侵害他人知识产权、商业秘密等合法权利的内容;
+				
+				(3)恶意虚构事实、隐瞒真相以误导、欺骗他人;
+				
+				(4)发布、传送、传播广告信息及垃圾信息;
+				
+				(5)其他法律法规禁止的行为。
+				
+				3、用户不得利用本服务进行任何有损本公司及其关联企业之权利、利益及商誉,或其他用户合法权利之行为。
+				
+				4、用户不得基于本服务从事制作、使用、传播“私服”、“外挂”等侵害本公司合法权益的行为。如有违反,本公司将依据中国现行法律法规及本公司的相关规定予以处理。
+				
+				5、虚拟财产转移服务外,用户不得通过任何方式直接或变相进行游戏账号、游戏币、游戏道具等虚拟财产的转移。
+				
+				6、用户不得从事作弊等损害游戏公平性的行为。用户承诺接受本公司对其游戏数据进行分析,当本公司发现其数据异常时,本公司可根据自己的独立判断认定其为作弊。
+				
+				7、用户不得从事任何利用本公司平台系统漏洞进行有损其他用户、本公司或互联网安全的行为。
+				
+				8、用户知悉并确认,本公司通过公告、邮件、短信、账户通知以及用户在账户中登记的即时通讯工具等方式,向用户发出关于本服务的通知、规则、提示等信息,均为有效通知。该等信息一经公布或发布,即视为已送达至用户。
+				
+				广告信息和促销
+				
+				1、用户同意接受本公司通过公告、邮件、短信、账户通知以及用户在账户中登记的即时通讯工具等方式发送的有关本服务,或本公司、本公司之关联企业或与本公司有合作关系的第三方相关的商品、服务促销或其他商业信息。
+				
+				2、本公司在本服务中可能提供与其他互联网之网站站点或资源的链接,本公司对存在或源于此类网站站点或资源的任何内容、广告、产品或其他资料不予保证或负责;如该链接所载的内容或搜索引擎所提供之链接的内容侵犯用户权利,本公司声明与上述内容无关,且不承担除法律有明确规定外的责任。
+				
+				隐私政策 
+				
+				引言
+				
+				我们重视用户的隐私。您在使用我们的服务时,我们可能会收集和使用您的相关信息。我们希望通过本《隐私政策》向您说明,在使用我们的服务时,我们如何收集、使用、储存和分享这些信息,以及我们为您提供的访问、更新、控制和保护这些信息的方式。本《隐私政策》与您所使用的服务息息相关,希望您仔细阅读,在需要时,按照本《隐私政策》的指引,作出您认为适当的选择。本《隐私政策》中涉及的相关技术词汇,我们尽量以简明扼要的表述,并提供进一步说明的链接,以便您的理解。
+				
+				您使用或继续使用我们的服务,即意味着同意我们按照本《隐私政策》收集、使用、储存和分享您的相关信息。
+				
+				如对本《隐私政策》或相关事宜有任何问题,请通过yeyuanshen@128xy.com与我们联系。
+				
+				我们可能收集的信息
+				
+				我们提供服务时,可能会收集、储存和使用下列与您有关的信息。如果您不提供相关信息,可能无法享受我们提供的某些服务,或者无法达到相关服务拟达到的效果。
+				
+				您提供的信息
+				
+				您在使用我们的服务时,向我们提供的相关个人信息,例如电话号码、电子邮件或银行卡号等;
+				
+				您通过我们的服务向其他方提供的共享信息,以及您使用我们的服务时所储存的信息。
+				
+				其他方分享的您的信息
+				
+				其他方使用我们的服务时所提供有关您的共享信息。
+				
+				我们获取的您的信息
+				
+				您使用服务时我们可能收集如下信息:
+				
+				日志信息,指您使用我们的服务时,系统可能通过cookies、web beacon或其他方式自动采集的技术信息,包括:
+				
+				设备或软件信息,例如您的移动设备、网页浏览器或用于接入我们服务的其他程序所提供的配置信息、您的IP地址和移动设备所用的版本和设备识别码;
+				
+				在使用我们服务时搜索或浏览的信息,例如您使用的网页搜索词语、访问的社交媒体页面url地址,以及您在使用我们服务时浏览或要求提供的其他信息和内容详情;
+				
+				有关您曾使用的移动应用(APP)和其他软件的信息,以及您曾经使用该等移动应用和软件的信息;
+				
+				位置信息,指您开启设备定位功能并使用我们基于位置提供的相关服务时,收集的有关您位置的信息,包括:
+				
+				您通过具有定位功能的移动设备使用我们的服务时,通过GPS或WiFi等方式收集的您的地理位置信息;
+				
+				您或其他用户提供的包含您所处地理位置的实时信息,例如您提供的账户信息中包含的您所在地区信息,您或其他人上传的显示您当前或曾经所处地理位置的共享信息;
+				
+				您可以通过关闭定位功能,停止对您的地理位置信息的收集。
+				
+				我们可能如何使用信息
+				
+				我们可能将在向您提供服务的过程之中所收集的信息用作下列用途:
+				
+				向您提供服务;
+				
+				在我们提供服务时,用于身份验证、客户服务、安全防范、诈骗监测、存档和备份用途,确保我们向您提供的产品和服务的安全性;
+				
+				帮助我们设计新服务,改善我们现有服务;
+				
+				使我们更加了解您如何接入和使用我们的服务,从而针对性地回应您的个性化需求,例如语言设定、位置设定、个性化的帮助服务和指示,或对您和其他用户作出其他方面的回应;
+				
+				向您提供与您更加相关的广告以替代普遍投放的广告;
+				
+				评估我们服务中的广告和其他促销及推广活动的效果,并加以改善;
+				
+				软件认证或管理软件升级;
+				
+				让您参与有关我们产品和服务的调查。
+				
+				为了让您有更好的体验、改善我们的服务或您同意的其他用途,在符合相关法律法规的前提下,我们可能将通过某一项服务所收集的信息,以汇集信息或者个性化的方式,用于我们的其他服务。例如,在您使用我们的一项服务时所收集的信息,可能在另一服务中用于向您提供特定内容,或向您展示与您相关的、非普遍推送的信息。如果我们在相关服务中提供了相应选项,您也可以授权我们将该服务所提供和储存的信息用于我们的其他服务。
+				
+				您如何访问和控制自己的个人信息
+				
+				我们将尽一切可能采取适当的技术手段,保证您可以访问、更新和更正自己的注册信息或使用我们的服务时提供的其他个人信息。在访问、更新、更正和删除前述信息时,我们可能会要求您进行身份验证,以保障账户安全。
+				
+				我们可能分享的信息
+				
+				除以下情形外,未经您同意,我们不会与任何第三方分享您的个人信息:
+				
+				我们可能将您的个人信息与第三方服务供应商、承包商及代理(例如代表我们发出电子邮件或推送通知的通讯服务提供商、为我们提供位置数据的地图服务供应商)分享(他们可能并非位于您所在的法域),用作下列用途:
+				
+				向您提供我们的服务;
+				
+				实现“我们可能如何使用信息”部分所述目的;
+				
+				履行我们在本《隐私政策》中的义务和行使我们的权利;
+				
+				理解、维护和改善我们的服务。
+				
+				如我们与任何上述第三方分享您的个人信息,我们将努力确保该等第三方在使用您的个人信息时遵守本《隐私政策》及我们要求其遵守的其他适当的保密和安全措施。
+				
+				随着我们业务的持续发展,我们有可能进行合并、收购、资产转让或类似的交易,您的个人信息有可能作为此类交易的一部分而被转移。我们将在转移前通知您。
+				
+				我们还可能为以下需要而保留、保存或披露您的个人信息:
+				
+				遵守适用的法律法规;
+				
+				遵守法院命令或其他法律程序的规定;
+				
+				遵守相关政府机关的要求;
+				
+				为遵守适用的法律法规、维护社会公共利益,或保护我们的客户、我们、其他用户的人身和财产安全或合法权益所合理必需的用途。
+				
+				信息安全
+				
+				我们仅在本《隐私政策》所述目的所必需的期间和法律法规要求的时限内保留您的个人信息。 我们使用各种安全技术和程序,以防信息的丢失、不当使用、未经授权阅览或披露。例如,在某些服务中,我们将利用加密技术(例如SSL)来保护您提供的个人信息。但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全。您需要了解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。
+				
+				您分享的信息
+				
+				我们的多项服务,可让您不仅与自己的社交网络,也与使用该服务的所有用户公开分享您的相关信息,例如,您在我们的服务中所上传或发布的信息(包括您公开的个人信息、您建立的名单)、您对其他人上传或发布的信息作出的回应,以及包括与这些信息有关的位置数据和日志信息。使用我们服务的其他用户也有可能分享与您有关的信息(包括位置数据和日志信息)。特别是,我们的社交媒体服务,是专为使您与世界各地的用户共享信息而设计,您可以使共享信息实时、广泛地传递。只要您不删除共享信息,有关信息会一直留存在公共领域;即使您删除共享信息,有关信息仍可能由其他用户或不受我们控制的非关联第三方独立地缓存、复制或储存,或由其他用户或该等第三方在公共领域保存。
+				
+				因此,请您谨慎考虑通过我们的服务上传、发布和交流的信息内容。在一些情况下,您可通过我们某些服务的隐私设定来控制有权浏览您共享信息的用户范围。如要求从我们的服务中删除您的相关信息,请通过该等特别服务条款提供的方式操作。
+				
+				您分享的敏感个人信息
+				
+				某些个人信息因其特殊性可能被认为是敏感个人信息,例如您的种族、宗教、个人健康和医疗信息等。相比其他个人信息,敏感个人信息受到更加严格的保护。
+				
+				请注意,您在使用我们的服务时所提供、上传或发布的内容和信息(例如有关您社交活动的照片等信息),可能会泄露您的敏感个人信息。您需要谨慎地考虑,是否在使用我们的服务时披露相关敏感个人信息。
+				
+				您同意按本《隐私政策》所述的目的和方式来处理您的敏感个人信息。
+				
+				我们可能如何收集信息
+				
+				我们或我们的第三方合作伙伴,可能通过cookies和web beacon收集和使用您的信息,并将该等信息储存为日志信息。
+				
+				我们使用自己的cookies和web beacon,目的是为您提供更个性化的用户体验和服务,并用于以下用途:
+				
+				记住您的身份。例如:cookies和web beacon有助于我们辨认您作为我们的注册用户的身份,或保存您向我们提供的有关您的喜好或其他信息;
+				
+				分析您使用我们服务的情况。例如,我们可利用cookies和web beacon来了解您使用我们的服务进行什么活动,或哪些网页或服务最受您的欢迎;
+				
+				广告优化。Cookies和web beacon有助于我们根据您的信息,向您提供与您相关的广告而非进行普遍的广告投放。
+				
+				我们为上述目的使用cookies和web beacon的同时,可能将通过cookies和web beacon收集的非个人身份信息,经统计加工后提供给广告商或其他合作伙伴,用于分析用户如何使用我们的服务,并用于广告服务。
+				
+				我们的产品和服务上可能会有广告商或其他合作方放置的cookies和web beacon。这些cookies和web beacon可能会收集与您相关的非个人身份信息,以用于分析用户如何使用该等服务、向您发送您可能感兴趣的广告,或用于评估广告服务的效果。这些第三方cookies和web beacon收集和使用该等信息,不受本《隐私政策》约束,而是受相关使用者的隐私政策约束,我们不对第三方的cookies或web beacon承担责任。
+				
+				您可以通过浏览器设置拒绝或管理cookies或web beacon。但请注意,如果停用cookies或web beacon,您有可能无法享受最佳的服务体验,某些服务也可能无法正常使用。同时,您还会收到同样数量的广告,但这些广告与您的相关性会降低。
+				
+				广告服务
+				
+				我们可能使用您的相关信息,向您提供与您更加相关的广告。
+				
+				我们也可能使用您的信息,通过我们的服务、电子邮件或其他方式向您发送营销信息,提供或推广我们或第三方的如下商品和服务:
+				
+				我们的服务,我们的关联公司和合作伙伴的商品或服务,包括即时通讯服务、网上媒体服务、互动娱乐服务、社交网络服务、付款服务、互联网搜索服务、位置和地图服务、应用软件和服务、数据管理软件和服务、网上广告服务、互联网金融,以及其他社交媒体、娱乐、电子商务、资讯和通讯软件或服务(统称“互联网服务”);
+				
+				第三方互联网服务供应商,以及与下列有关的第三方商品或服务:食物和餐饮、体育、音乐、电影、电视、现场表演及其他艺术和娱乐、书册、杂志和其他刊物、服装和配饰、珠宝、化妆品、个人健康和卫生、电子、收藏品、家用器皿、电器、家居装饰和摆设、宠物、汽车、酒店、交通和旅游、银行、保险及其他金融服务、会员积分和奖励计划,以及我们认为可能与您相关的其他商品或服务。
+				
+				如您不希望我们将您的个人信息用作前述广告用途,您可以通过我们在广告中提供的相关提示,或在特定服务中提供的指引,要求我们停止为上述用途使用您的个人信息。
+				
+				我们可能向您发送的邮件和信息
+				
+				邮件和信息推送
+				
+				您在使用我们的服务时,我们可能使用您的信息向您的设备发送电子邮件、新闻或推送通知。如您不希望收到这些信息,可以按照我们的相关提示,在设备上选择取消订阅。
+				
+				与服务有关的公告
+				
+				我们可能在必要时(例如因系统维护而暂停某一项服务时)向您发出与服务有关的公告。您可能无法取消这些与服务有关、性质不属于推广的公告。
+				
+				隐私政策的适用例外
+				
+				我们的服务可能包括或链接至第三方提供的社交媒体或其他服务(包括网站)。例如:
+				
+				您利用 “分享”键将某些内容分享到我们的服务,或您利用第三方连线服务登录我们的服务。这些功能可能会收集您的相关信息(包括您的日志信息),并可能在您的电脑装置cookies,从而正常运行上述功能;
+				
+				我们通过广告或我们服务的其他方式向您提供链接,使您可以接入第三方的服务或网站。
+				
+				该等第三方社交媒体或其他服务可能由相关的第三方或我们运营。您使用该等第三方的社交媒体服务或其他服务(包括您向该等第三方提供的任何个人信息),须受该第三方的服务条款及隐私政策(而非《通用服务条款》或本《隐私政策》)约束,您需要仔细阅读其条款。本《隐私政策》仅适用于我们所收集的信息,并不适用于任何第三方提供的服务或第三方的信息使用规则,我们对任何第三方使用由您提供的信息不承担任何责任。
+				
+				未成年人使用我们的服务
+				
+				我们鼓励父母或监护人指导未满十八岁的未成年人使用我们的服务。我们建议未成年人鼓励他们的父母或监护人阅读本《隐私政策》,并建议未成年人在提交的个人信息之前寻求父母或监护人的同意和指导。
+				
+				隐私政策的适用范围
+				
+				除某些特定服务外,我们所有的服务均适用本《隐私政策》。这些特定服务将适用特定的隐私政策。针对某些特定服务的特定隐私政策,将更具体地说明我们在该等服务中如何使用您的信息。该特定服务的隐私政策构成本《隐私政策》的一部分。如相关特定服务的隐私政策与本《隐私政策》有不一致之处,适用该特定服务的隐私政策。
+				
+				请您注意,本《隐私政策》不适用于以下情况:
+				
+				通过我们的服务而接入的第三方服务(包括任何第三方网站)收集的信息;
+				
+				通过在我们服务中进行广告服务的其他公司或机构所收集的信息。
+				
+				变更
+				
+				我们可能适时修订本《隐私政策》的条款,该等修订构成本《隐私政策》的一部分。如该等修订造成您在本《隐私政策》下权利的实质减少,我们将在修订生效前通过在主页上显著位置提示或向您发送电子邮件或以其他方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的本《隐私政策》的约束。
+			</text>
+		  
+	  </view>
+	</view>
+</template>
+
+<script>
+	import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue";
+	
+ 
+    export default {
+		data() {
+			return {
+				title:"用户协议",
+				bAgreement:true
+			};
+		},
+        methods: {
+			onLoad: function(option) {
+				console.log(option.type);
+				if(option.type != "agreement"){
+					this.title ="用户隐私" ;
+					this.bAgreement = false ;
+				}
+			},
+           onBack() {
+           	uni.navigateBack({
+           		delta: 1
+           	})
+           }
+        }
+    }
+</script>
+
+<style>
+
+</style>

+ 435 - 0
pages/my-page/firstPlan/firstPlan.vue

@@ -0,0 +1,435 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true"  title="设置计划" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<!-- <view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view> -->
+			</view>
+			<view slot="right">
+				<text class="text-df text-purple margin-right-sm" @tap="onSkip">跳过</text>
+			</view>
+		</uni-nav-bar>
+
+		<view class="card-view flex-sub text-center bg-white margin-top">
+			<view class="plan-tagert flex justify-center align-center">
+				<view class="plan-tagert-child make-text-bPurple flex justify-start align-center">
+					<image class="avatar-img" :src="avatarUrl"></image>
+					<view class="flex flex-direction justify-between">
+						<view class="text-black text-bold padding-left-lg margin-xs" style="text-align: start;">每天目标</view>
+						<view class="flex text-gray border">
+							<view class="padding-left-lg margin-xs flex" style="position: relative; flex-shrink: 0; " @tap="showModal"
+							 data-target="showPickerModal" data-type="target_calorie">
+								<view class="make-text-bPurple text-xl margin-right-sm ">{{ currentPlanData.calorie}}</view>
+								<view>大卡</view>
+								<view class="only-arrow"></view>
+							</view>
+							<view class="padding-left-lg margin-xs flex" style="position: relative;flex-shrink: 0;" @tap="showModal"
+							 data-target="showPickerModal" data-type="target_minute">
+								<view class="make-text-bPurple text-xl margin-right-sm">{{ currentPlanData.sportTime }}</view>
+								<view>分钟</view>
+								<view class="only-arrow"></view>
+							</view>
+
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<view class="cu-bar bg-white">
+				<view class="action">
+					<image style="width: 42rpx;height: 42rpx; margin-right: 26rpx;" src="../../../static/plan_w.png"></image>
+					<span style="font-weight: bold;">终极目标</span>
+				</view>
+				<view class="action resetBtn" style="margin-right: 60rpx;" @tap="onReset"><text class="text-13px text-white" style="letter-spacing: 1px;">自动生成计划</text></view>
+			</view>
+			<view class="cu-form-group" @tap="showModal" data-target="showPickerModal" data-type="startTime">
+				<view class="flex justify-center align-center">
+					<image class="plan-litle-img" src="../../../static/plan_t.png"></image>
+					<view class="title make-text-bPurple">开始时间</view>
+				</view>
+
+				<view class="picker flex" style="position: relative;">
+					<view>{{ startTime }}</view>
+					<view class="only-arrow"></view>
+				</view>
+			</view>
+			<view class="cu-form-group" style="border-top:none" data-target="showPickerModal" data-type="endTime">
+				<view class="flex justify-center align-center">
+					<image class="plan-m-img" src="../../../static/plan_m.png"></image>
+					<view class="title text-gray" style="font-size: 12px;">计划总天数 {{ currentDays }} 天,加油!</view>
+				</view>
+			</view>
+			<view class="cu-form-group" style="border-top:none" @tap="showModal" data-target="showPickerModal" data-type="endTime">
+				<view class="flex justify-center align-center">
+					<image class="plan-litle-img" src="../../../static/plan_e.png"></image>
+					<view class="title make-text-bPurple">截止时间</view>
+				</view>
+				<view class="picker flex" style="position: relative;">
+					<view>{{ endTime }}</view>
+					<view class="only-arrow"></view>
+				</view>
+			</view>
+		</view>
+		<view class="flex flex-direction" style="padding: 23px 42rpx 46px"><button class="cu-btn make-bg-bPurple text-white lg"
+			 @tap="onUpdatePlanInfo">确定</button></view>
+		<view class="cu-modal bottom-modal" :class="modalName == 'showPickerModal' ? 'show' : ''" @touchmove.stop.prevent="moveHandle">
+			<view class="cu-dialog" style="border-top-right-radius: 20rpx; border-top-left-radius: 20rpx;">
+				<myPicker v-if="modalName == 'showPickerModal' ? true:false" :pickerObj="pickerObj" @confirmEvent="onConfirm"
+				 @cancelEvent="onCancel"></myPicker>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import config from '../../../common/config.js';
+	import date from '../../../util/util-js/date.js';
+	import reqUtil from '../../../util/util-js/requstUtil.js';
+
+	import myPicker from '@/components/slambb-picker/slambb-picker.vue';
+	import pickerData from '@/components/slambb-picker/picker.js';
+
+	import utilData from '@/util/util-js/util-data.js';
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+	export default {
+		computed: mapState(['planData', 'avatarUrl', 'days', "defaultPlanData", "remainingDays"]),
+		components: {
+			myPicker
+		},
+		data() {
+			return {
+				startTime: '',
+				endTime: '',
+				pickerObj: {
+					pickerType: 'dateItem',
+					pickerTitle: '记时间'
+				},
+				modalName: null,
+				pikerType: '',
+				oldPlanData: null,
+				// 当前plan页面的数据
+				currentPlanData: null,
+				// 当前天数
+				currentDays: 0,
+				//如果需要更新
+				hasUpdate: false,
+				//显示的重量
+				currenWeight: 0
+			};
+		},
+		onLoad: function(option) {
+			this.oldPlanData = JSON.parse(JSON.stringify(this.planData));
+			this.currentPlanData = JSON.parse(JSON.stringify(this.planData));
+			this.startTime = this.currentPlanData.startTime;
+			this.endTime = this.currentPlanData.endTime;
+			this.currentDays = this.days;
+
+			// 用累计的卡路里来计算当前累计的重量
+			// let weight = this.currentPlanData.cumulativeCalorie *2 / 7000;
+			let weight = utilData.calorieConversionKg(this.currentPlanData.cumulativeCalorie);
+
+			this.currenWeight = weight.toFixed(2);
+			
+			//新手进入此第一次设置一次默认值
+			this.onReset();
+		},
+		methods: {
+			...mapMutations(['addlocalCalorie']),
+			DateChange(e) {
+				this.planData.startTime = e.detail.value;
+			},
+			onConfirm(args) {
+				this.hasUpdate = true;
+				console.log('onConfirm', args);
+				// detail.__args__[0]
+				// let args = data;
+				//月0~11
+				if (this.pikerType == 'startTime') {
+					let nDate = new Date();
+					nDate.setFullYear(args.value[0], args.value[1] - 1, args.value[2]);
+					// 判断日期
+					// console.log(date.formatDate(nDate),"==",date.formatDate(nDate).replace(/-/g, '/'))
+					var sDate1 = Date.parse(date.formatDate(nDate));
+					var sDate2 = Date.parse(this.endTime);
+					var dateSpan = sDate2 - sDate1;
+					if (dateSpan > 0) {
+						this.startTime = date.formatDate(nDate);
+						this.currentPlanData.startTime = date.formatTime(nDate);
+						// this.currentDays = date.datedifference(this.startTime, this.endTime);
+						this.currentDays = Math.floor(Math.abs(dateSpan) / (24 * 3600 * 1000));
+					} else {
+						uni.showToast({
+							title: "开始日期超过截止日期!",
+							icon: "none"
+						})
+					}
+
+
+				} else if (this.pikerType == 'endTime') {
+					let nDate = new Date();
+					nDate.setFullYear(args.value[0], args.value[1] - 1, args.value[2]);
+
+					// 判断日期
+					var sDate1 = Date.parse(this.startTime.replace(/-/g, '/'));
+					var sDate2 = Date.parse(date.formatDate(nDate).replace(/-/g, '/'));
+					var dateSpan = sDate2 - sDate1;
+					// console.log(dateSpan);
+					if (dateSpan > 0) {
+						this.endTime = date.formatDate(nDate);
+						this.currentPlanData.endTime = date.formatTime(nDate);
+						// this.currentDays = date.datedifference(this.startTime, this.endTime);
+						this.currentDays = Math.floor(Math.abs(dateSpan) / (24 * 3600 * 1000));
+					} else {
+						uni.showToast({
+							title: "开始日期不能超过或等于截止日期!",
+							icon: "none"
+						})
+					}
+
+
+
+				} else if (this.pikerType == 'target_weight') {
+					console.log('target_weight:');
+					this.currentPlanData.targetWeight = args.value;
+				} else if (this.pikerType == 'target_calorie') {
+					console.log('target_calorie:');
+					this.currentPlanData.calorie = parseInt(args.value);
+				} else if (this.pikerType == 'target_minute') {
+					console.log('target_minute:');
+					this.currentPlanData.sportTime = parseInt(args.value);
+				}
+
+				this.hideModal();
+			},
+			onCancel(value) {
+				console.log('onCancel', value);
+				this.modalName = null;
+			},
+			showModal(e) {
+				// console.log(e.currentTarget.type);
+				this.modalName = e.currentTarget.dataset.target;
+				this.pikerType = e.currentTarget.dataset.type;
+				switch (this.pikerType) {
+					case 'target_weight':
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getWeightList().leftList);
+						this.$set(this.pickerObj, 'pickerRightList', pickerData.getWeightList().rightList);
+						this.$set(this.pickerObj, 'pickerType', 'doubleItem');
+						this.$set(this.pickerObj, 'pickerUnit', '斤');
+						this.$set(this.pickerObj, 'pickerTitle', '记体重');
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case 'startTime':
+					case 'endTime':
+						this.$set(this.pickerObj, 'pickerType', 'dateItem');
+						this.$set(this.pickerObj, 'pickerTitle', '记时间');
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+					case 'target_calorie':
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getCalorieList().calorieList);
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerUnit', '大卡');
+						this.$set(this.pickerObj, 'pickerType', 'singleItem');
+						this.$set(this.pickerObj, 'pickerTitle', '卡路里');
+						this.$set(this.pickerObj, 'defaultValue', this.currentPlanData.calorie);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case 'target_minute':
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getMinuteList().minuteList);
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerUnit', '分钟');
+						this.$set(this.pickerObj, 'pickerType', 'singleItem');
+						this.$set(this.pickerObj, 'pickerTitle', '预计时间');
+						this.$set(this.pickerObj, 'defaultValue', this.currentPlanData.sportTime);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+				}
+			},
+			hideModal(e) {
+				this.modalName = null;
+				this.pikerType = '';
+			},
+			moveHandle() {
+				return;
+			},
+			onUpdatePlanInfo() {
+				let that = this;
+				console.warn(that.currentPlanData);
+				if (!that.hasUpdate) {
+					uni.showToast({
+						title: '没有数据更新',
+						icon: 'none'
+					});
+					return;
+				}
+
+				if (that.currentPlanData.startTime > that.currentPlanData.endTime||
+				date.datedifference(that.currentPlanData.startTime, that.currentPlanData.endTime) == 0) {
+					uni.showToast({
+						title: '截止时间不能早于或等于开始时间',
+						icon: 'none'
+					});
+					return;
+				}
+				// console.warn(that.currentPlanData);
+				// return;
+				reqUtil.requestData(config.URL.FITNESSPROGRAM, that.currentPlanData, 'POST').then(
+					res => {
+						console.log('更新信息成功', res);
+						if (res.code == 0) {
+							uni.showToast({
+								title: '更新成功',
+								mask: true,
+								duration: 1000
+							});
+							that.oldPlanData = res.data;
+							that.hasUpdate = false;
+							that.$store.state.planData = Object.assign(that.$store.state.planData, res.data, {
+								sportTime: Number(that.currentPlanData.sportTime) 
+							});
+							// console.log("========",that.planData);
+							that.$store.state.days = date.datedifference(res.data.startTime, res.data.endTime) + 1;
+							let nDate = new Date();
+							let tempTime = date.formatDate(nDate);
+							that.$store.state.remainingDays = date.datedifference(tempTime, res.data.endTime) + 1;
+							// console.log("remainingDays==", that.remainingDays);
+							setTimeout(function() {
+								// console.log("updateArcbarData==setTimeout");
+								that.addlocalCalorie(0);
+								
+								uni.redirectTo({
+									url: "../../personal-page/personal/personal"
+								})
+							}, 500);
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+			},
+			//重置默认信息
+			onReset() {
+				uni.showToast({
+					title: '生成计划成功!',
+					icon: 'none',
+				})
+				this.hasUpdate = true;
+				// 拷贝
+				this.currentPlanData = JSON.parse(JSON.stringify(this.defaultPlanData));
+				this.startTime = this.currentPlanData.startTime;
+				this.endTime = this.currentPlanData.endTime;
+				this.currentDays = date.datedifference(this.startTime, this.endTime);
+				// console.log("this.defaultPlanData=",this.defaultPlanData);
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			
+			onSkip(){
+				uni.redirectTo({
+					url: "../../personal-page/personal/personal"
+				})
+			}
+		}
+	};
+</script>
+
+<style>
+	.plan-w {
+		position: relative;
+		/* width: 464rpx; */
+		height: 464rpx;
+	}
+
+	.plan-w-bg-img {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		width: 464rpx;
+		height: 464rpx;
+	}
+
+	.plan-w-child {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		width: 464rpx;
+		height: 464rpx;
+
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.plan-w-img {
+		width: 46rpx;
+		height: 46rpx;
+	}
+
+	.plan-Tip {
+		height: 90rpx;
+		margin: 60rpx 0;
+	}
+
+	.plan-Tip-child {
+		background-color: #f5f5ff;
+		border-radius: 20px;
+		width: 614rpx;
+		height: 90rpx;
+		margin: 60rpx 0;
+	}
+
+	.plan-litle-img {
+		width: 32rpx;
+		height: 32rpx;
+		margin-right: 32rpx;
+	}
+
+	.plan-m-img {
+		width: 1rpx;
+		height: 110rpx;
+		margin: 0 41rpx 0 14rpx;
+		border: 1rpx dashed rgba(151, 151, 255, 1);
+	}
+
+	.resetBtn {
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 3px;
+		padding: 10rpx 32rpx;
+	}
+
+	.plan-tagert {
+		margin: 20px 0;
+		height: 208rpx;
+	}
+
+	.plan-tagert-child {
+		background-color: #f5f5ff;
+		border-radius: 20px;
+		width: 614rpx;
+		height: 208rpx;
+		padding-left: 40rpx;
+	}
+
+	.avatar-img {
+		width: 96rpx;
+		height: 96rpx;
+		border: 4rpx solid rgba(151, 151, 255, 1);
+		border-radius: 45px;
+		flex-shrink: 0;
+	}
+</style>

+ 316 - 0
pages/my-page/homepage/homepage.vue

@@ -0,0 +1,316 @@
+<template>
+	<view class="full-container">
+		<uni-nav-bar id="nav-bar" status-bar="true"  @clickLeft="onBack()"
+		 title="我的" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+		
+		</uni-nav-bar>
+		<!-- <view class="cu-bar ">
+			<view class="action">
+			</view>
+			<view class="action">
+				<text class="text-df text-purple" @tap="onNavUser">编辑</text>
+			</view>
+		</view> -->
+		<image class="bg-image" src="../../../static/loginBg.png" mode="aspectFill"></image>
+		<view class="card-view flex align-center " style="position: relative; margin-top: 113px;">
+			<view class="avatar-size">
+				<image class="avatar-img round" :src="avatarUrl"></image>
+			</view>
+			<view class="avatar-group text-upload">
+				<view class="text-lg flex justify-between align-center justify-center">
+					<text class="text-black text-bold">{{userName}}</text>
+					<text class="text-black">达标{{days}}天</text>
+				</view>
+				<!-- <view class="text-xs padding-top">
+					<text class="text-black">{{days}}</text>
+				</view> -->
+				<view class="text-gray padding-top">{{signature}}</view>
+			</view>
+
+			<view class="only-arrow" @tap="onNavUser"></view>
+
+		</view>
+
+
+
+
+
+		<view class="card-view article ">
+			<view class="title">
+				最近在玩
+			</view>
+			<view class="cu-item shadow">
+				<view class="cu-form-group margin-top">
+					<view v-if="playGames.length!=0" class="grid col-3 homepage-grid-square flex-sub ">
+						<view v-for="(item,index) in playGames" :key="index" v-if="index<6" @tap="onViewImage(item)">
+							<image class="item-img" :src="item.gameIcon" mode="aspectFill"></image>
+							<view class="border text-center text-cut">{{item.gameName}}</view>
+						</view>
+					</view>
+					<view v-else class="text-center text-gray" :style="{width:'100%'}">去玩吧~</view>
+					<view v-if="playGames.length!=0" class="homepage-arrow" @tap="onNavList('recently')"></view>
+				</view>
+			</view>
+		</view>
+		<view v-if="favoriteGames.length==0" class="card-view flex align-center">
+			<view class="content flex flex-direction align-start margin-top">
+				<view class="title">关注</view>
+				<view class="text-grey" style="margin: 0rpx 40rpx 40rpx;">有好多好玩的视频等着你关注哦</view>
+			</view>
+			<view class=" margin-sm button-fav " @tap="onGoToFollow">
+				<image style="width: 21px;height: 21px; margin-right: 12rpx;" src="../../../static/add_w.png"></image>
+				去关注
+			</view>
+		</view>
+		<view v-else class="card-view article">
+			<view class="title">
+				已关注的
+			</view>
+			<view class="cu-item shadow">
+				<view class="cu-form-group margin-top">
+					<view v-if="favoriteGames.length!=0" class="grid col-3 homepage-grid-square flex-sub ">
+						<view  class="text-center "  v-for="(item,index) in favoriteGames" :key="index" v-if="index<6" @tap="onViewImage(item)">
+							<image class="item-img" :src="item.gameIcon" mode="aspectFill"></image>
+							<view class="border text-cut">{{item.gameName}}</view>
+						</view>
+					</view>
+					<view v-else class="text-center text-gray" :style="{width:'100%'}">去关注更多的游戏吧~</view>
+					<view v-if="favoriteGames.length!=0" class="homepage-arrow" @tap="onNavList('watchGame')"></view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="homepage-action-row">
+			<view class=" ">哔蹦</view>
+			<view class="text-bold text-decoration" style="
+		color: #007AFF; border-bottom: solid 1rpx #007AFF;" @tap="onSwitchAgree('agreement')">用户协议</view>
+			<view class=" ">和</view>
+			<view class="text-bold text-decoration" style="
+		color: #007AFF; border-bottom: solid 1rpx #007AFF;" @tap="onSwitchAgree('privacy')">隐私政策</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import config from '../../../common/config.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import {
+		mapState
+	} from 'vuex'
+
+	export default {
+		computed: mapState(['forcedLogin', 'hasLogin', 'userName', 'avatarUrl', 'playGames', 'favoriteGames', 'days',
+			'signature','platform','gamePlatform'
+		]),
+		onLoad() {
+			let that = this;
+			reqUtil.requestData(config.URL.RECENTLYPLAYINGGETBYPLATFORM).then(res => {
+					console.log('RECENTLYPLAYINGGETBYPLATFORM =====', res);
+					if (res.code == 0) {
+						that.$store.state.playGames = res.data.gameList;
+					}
+
+				},
+				e => {
+					console.log(e)
+				});
+
+			reqUtil.requestData(config.URL.FAVORITESGETBYPLATFORM).then(res => {
+					console.log('FAVORITESGETBYPLATFORM =====', res);
+					if (res.code == 0) {
+						that.$store.state.favoriteGames = res.data.gameList;
+					}
+
+				},
+				e => {
+					console.log(e)
+				});
+		},
+		methods: {
+			onViewImage(item) {
+				let temItem = encodeURIComponent(JSON.stringify(item));
+				uni.navigateTo({
+					url: "../../game-page/game-detail/game-detail?item=" + temItem
+				})
+			},
+			onNavUser() {
+				uni.navigateTo({
+					url: '../userInfo/userInfo'
+				});
+			},
+			onNavList(type) {
+				if (type == "recently" && this.playGames.length == 0) {
+					uni.showModal({
+						title: "提示",
+						content: "没有最近在玩的游戏数据"
+					})
+					return;
+				} else if (type == "watchGame" && this.favoriteGames.length == 0) {
+					uni.showModal({
+						title: "提示",
+						content: "没有关注的游戏数据"
+					})
+					return;
+				}
+
+
+				uni.navigateTo({
+					url: '../../personal-page/list/list?type='+type
+				});
+			},
+			onGoToFollow() {
+				// uni.showModal({
+				// 	title: "提示",
+				// 	content: "功能尚未开放"
+				// })
+				uni.navigateTo({
+					url: '../../game-page/game/game'
+				});
+			},
+			onBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			onSwitchAgree(data) {
+				uni.navigateTo({
+					url: "../../login-page/userAgreement/userAgreement?type=" + data
+				})
+			},
+		}
+	}
+</script>
+
+<style>
+	.avatar-group {
+		display: flex;
+		flex-direction: column;
+		/* justify-content: center; */
+		/* align-items: center; */
+		text-align: start;
+		background-color: #FFFFFF;
+		display: block;
+		border-radius: 10rpx;
+		margin: 0 54rpx 0 30rpx;
+		width: 100%;
+	}
+
+
+	.avatar-size {
+		position: relative;
+		margin-left: 47rpx;
+		width: 140rpx;
+		height: 140rpx;
+		flex-shrink: 0;
+	}
+
+	.avatar-img {
+		position: absolute;
+		top: 0px;
+		left: 0;
+		width: 140rpx;
+		height: 140rpx;
+	}
+
+	.text-upload {
+		font-size: 13px;
+		color: rgba(166, 166, 166, 1);
+		padding: 40px 35rpx 40px 0;
+	}
+
+	.homepage-grid-square {
+		width: 250rpx;
+		/* height: 250rpx; */
+		align-items: start;
+
+	}
+
+	.homepage-grid-square image {
+		width: 176rpx;
+		height: 176rpx;
+	}
+
+	.homepage-arrow {
+		position: relative;
+		width: 35rpx;
+	}
+
+	.homepage-arrow::before {
+		position: absolute;
+		top: 0;
+		right: 0upx;
+		bottom: 0;
+		display: block;
+		margin: auto;
+		width: 30upx;
+		height: 30upx;
+		color: #8799a3;
+		content: "\e6a3";
+		text-align: center;
+		font-size: 34upx;
+		font-family: cuIcon;
+		line-height: 30upx
+	}
+
+	.button-fav {
+		background-color: rgba(153, 150, 252, 255);
+		color: #FFFFFF;
+		border-radius: 10px;
+		width: 184rpx;
+		height: 90rpx;
+		display: flex;
+		justify-content: center;
+		text-align: center;
+		align-items: center;
+	}
+
+	.title {
+		text-align: justify;
+		/* padding: 40rpx 30rpx; */
+		font-size: 15px;
+		position: relative;
+		height: 30px;
+		line-height: 60upx;
+		margin: 20rpx 40rpx;
+		font-weight: 400;
+		color: rgba(26, 26, 26, 1);
+	}
+
+	.bg-image {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 159px;
+		opacity: 1;
+	}
+	
+	.border{
+		width: 176rpx;
+		font-size: 30rpx;
+		color:rgba(175, 175, 175, 1);
+		font-weight: 400;
+		text-align: center;
+		margin-top: 22rpx;
+		margin-bottom: 40rpx;
+	}
+	
+	.item-img{
+		border-radius: 20rpx;
+		/* border: 1rpx solid #EEEEEE; */
+		box-shadow: 0px 1px 2px 0px rgba(113, 113, 219, 0.23);
+	}
+	
+	.homepage-action-row{
+		margin-top: 25px;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		padding: 20px;
+	}
+</style>

+ 448 - 0
pages/my-page/perfectInfo/perfectInfo.vue

@@ -0,0 +1,448 @@
+<template>
+	<view class="container">
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack" :title="pageTitle" color="#000000" fixed="true"
+		 :border="false">
+			<!-- <view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view> -->
+			<view slot="right">
+				<text class="text-df text-purple margin-right-sm" @tap="onSkip">跳过</text>
+			</view>
+		</uni-nav-bar>
+		<view style="height:6px ;width: 100%; background-color: #f2eff2;"></view>
+
+		<!-- 手机端登录,获取验证码 -->
+		<view class="input-container" style="margin: 32px 102rpx 0 68rpx;">
+			<view class="make-text-bPurple text-bold margin-bottom" style="font-size: 20px;">完善资料</view>
+			<view class="text-16px text-gray">请完善您的个人资料,以便于更好的统计数据……</view>
+		</view>
+
+		<view class="input-container" style="margin: 32px 102rpx 0 68rpx;">
+			<view class="text-bold margin-bottom text-16px">你的性别</view>
+			<view class="flex justify-start">
+				<view class="flex justify-between align-center" style="height: 38px;" @tap="onGender(0)">
+					<image style="width: 38rpx;height: 38rpx;" :src="gender==0?'/static/radio-on.png':'/static/radio-off.png'"></image>
+					<view class="text-16px margin-left">男</view>
+				</view>
+
+				<view class="flex justify-between align-center" style="height: 38px;margin-left: 143rpx;" @tap="onGender(1)">
+					<image style="width: 38rpx;height: 38rpx;" :src="gender==1?'/static/radio-on.png':'/static/radio-off.png'"></image>
+					<view class="text-16px margin-left">女</view>
+				</view>
+			</view>
+		</view>
+		<view class="input-container" style="margin: 32px 102rpx 0 68rpx;">
+			<view class="text-bold margin-bottom text-16px">您所在的省份/城市</view>
+			<view class="flex justify-start align-center" style="margin: 68rpx 0;">
+				<image style="width: 38rpx;height: 38rpx;" src="../../../static/locationIcon.png"></image>
+				<view class="text-16px margin-left">{{city.label}}</view>
+				<view style="margin-left: 10rpx;" @tap="showModal" data-target="showPickerModal" data-type="city">
+					<image style="width: 38rpx;height: 38rpx;" src="../../../static/locationMore.png"></image>
+				</view>
+			</view>
+		</view>
+
+		<view class="flex justify-between perf-bottom-container">
+			<view class="flex justify-center align-center">
+				<!-- <image style="width: 10px;height: 10px; margin-left: 38rpx;" src="/static/asterisk.png"></image> -->
+				<view class="text-grey padding-sm margin-name text-width flex">生日</view>
+				<view class="text-bold">{{sBirthday}} </view>
+			</view>
+			<view class="right-container" @tap="showModal" data-target="showPickerModal" data-type="birthday">
+				<text class="text-grey text-sm" style="margin: 0 24rpx;">请选择</text>
+				<view class="only-arrow"></view>
+			</view>
+		</view>
+
+		<view class="flex justify-between perf-bottom-container">
+			<view class="flex justify-center align-center">
+				<!-- <image style="width: 10px;height: 10px; margin-left: 38rpx;" src="/static/asterisk.png"></image> -->
+				<view class="text-grey padding-sm margin-name text-width flex">身高</view>
+				<view class="text-bold">{{height}}cm </view>
+			</view>
+			<view class="right-container" @tap="showModal" data-target="showPickerModal" data-type="height">
+				<text class="text-grey text-sm" style="margin: 0 24rpx;">请选择</text>
+				<view class="only-arrow"></view>
+			</view>
+		</view>
+		<view class="flex justify-between perf-bottom-container">
+			<view class="flex justify-center align-center">
+				<!-- <image style="width: 10px;height: 10px; margin-left: 38rpx;" src="/static/asterisk.png"></image> -->
+				<view class="text-grey padding-sm margin-name text-width flex">体重</view>
+				<view class="text-bold">{{weight}}kg </view>
+			</view>
+			<view class="right-container" @tap="showModal" data-target="showPickerModal" data-type="weight">
+				<text class="text-grey text-sm" style="margin: 0 24rpx;">请选择</text>
+				<view class="only-arrow"></view>
+			</view>
+		</view>
+
+
+		<view class="btn-row">
+			<view class="btn-confirm" @tap="onPerfectConfirm">确认绑定</view>
+		</view>
+
+		<view class="cu-modal bottom-modal" :class="modalName=='showPickerModal'?'show':''" @touchmove.stop.prevent="moveHandle">
+			<view class="cu-dialog" style="border-top-right-radius: 20rpx; border-top-left-radius: 20rpx;">
+				<myPicker v-if="modalName == 'showPickerModal' ? true:false" :pickerObj="pickerObj" @confirmEvent="onPickerConfirm"
+				 @cancelEvent="hideModal">
+				</myPicker>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import myPicker from '@/components/slambb-picker/slambb-picker.vue';
+	import pickerData from '@/components/slambb-picker/picker.js';
+	import config from '@/common/config.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import date from "@/util/util-js/date.js";
+	import {
+		mapState
+	} from 'vuex'
+
+	export default {
+		components: {
+			myPicker
+		},
+		data() {
+			return {
+				account: '',
+				pageTitle: "完善资料",
+				sBirthday: '',
+				modalName: null,
+				//选择器对象
+				pickerObj: {
+					pickerLeftList: pickerData.getWeightList().leftList,
+					pickerRightList: pickerData.getWeightList().rightList,
+					pickerType: "doubleItem",
+					pickerUnit: "斤",
+					pickerTitle: "记体重",
+					defaultValue: 0
+				},
+				bLoading: false,
+				//是否可以更新
+				bCanUpdate: false,
+			}
+		},
+		computed: mapState(['bNewUser','height', 'weight', 'birthday', 'city', 'gender', 'userName']),
+		onLoad() {
+			let s = this.birthday.replace(/-/g, "/");
+			var dateTemp = new Date(s);
+			this.sBirthday = date.formatDate(dateTemp);
+			
+			if (this.bNewUser) {
+				this.$store.state.bNewGuide = true;
+			}
+		},
+		methods: {
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			
+			showModal(e) {
+				this.pikerType = e.currentTarget.dataset.type
+				switch (this.pikerType) {
+					case "weight":
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getWeightList().leftList);
+						this.$set(this.pickerObj, 'pickerRightList', pickerData.getWeightList().rightList);
+						this.$set(this.pickerObj, 'pickerType', "doubleItem");
+						this.$set(this.pickerObj, 'pickerUnit', "公斤");
+						this.$set(this.pickerObj, 'pickerTitle', "记体重");
+						this.$set(this.pickerObj, 'defaultValue', this.weight);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case "height":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getHeightList().leftList);
+						// pickerData.getHeightList().rightList
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerType', "singleItem");
+						this.$set(this.pickerObj, 'pickerUnit', "厘米");
+						this.$set(this.pickerObj, 'pickerTitle', "记身高");
+						this.$set(this.pickerObj, 'defaultValue', this.height);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case "birthday":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerType', "dateItem");
+						this.$set(this.pickerObj, 'pickerTitle', "记生日");
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+					case "gender":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getGenderList().genderList);
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerType', "singleItem");
+						this.$set(this.pickerObj, 'pickerTitle', "性别");
+						this.$set(this.pickerObj, 'defaultValue', "男");
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+					case "city":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerType', "city");
+						this.$set(this.pickerObj, 'pickerTitle', "省市区");
+						this.$set(this.pickerObj, 'defaultValue', this.city.value);
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+
+				}
+				this.modalName = e.currentTarget.dataset.target
+			},
+			hideModal(e) {
+				this.modalName = null
+			},
+			moveHandle() {
+				return;
+			},
+			onPickerConfirm(data) {
+				console.log(data);
+				switch (this.pikerType) {
+					case "weight":
+						if (data.value != this.weight) {
+							this.bCanUpdate = true;
+							this.$store.state.weight = data.value;
+						}
+						break;
+					case "height":
+						if (data.value != this.height) {
+							this.bCanUpdate = true;
+							this.$store.state.height = data.value;
+						}
+						break;
+					case "birthday":
+						this.bCanUpdate = true;
+						let nDate = new Date();
+						nDate.setFullYear(data.value[0], data.value[1] - 1, data.value[2]);
+						this.sBirthday = date.formatDate(nDate);
+						this.$store.state.birthday = date.formatTime(nDate);
+						break;
+					case "gender":
+						if (data.value != this.gender) {
+							this.bCanUpdate = true;
+							this.$store.state.gender = data.value;
+						}
+						break;
+					case "city":
+						if (data.value.cityCode != this.cityCode) {
+							this.bCanUpdate = true;
+							this.$store.state.city = data.value;
+						}
+						break;
+				}
+
+				this.hideModal();
+			},
+			onGender(value) {
+				// console.log(value);
+				this.$store.state.gender = value;
+			},
+			/**
+			 * 由于性别和生日是有默认值,所以不用检测
+			 */
+			onCheck() {
+				if (this.height == 0) {
+					uni.showToast({
+						title: "请选择身高",
+						icon: "none"
+					})
+					return false;
+				} else
+				if (this.weight == 0) {
+					uni.showToast({
+						title: "请选择体重",
+						icon: "none"
+					})
+					return false;
+				}
+				return true;
+			},
+			onPerfectConfirm() {
+				let that = this;
+
+				if (!that.onCheck()) {
+					console.log("onCheck false")
+					return;
+				}
+				uni.showToast({
+					title: "",
+					icon: "loading",
+					mask: true,
+					duration: 10000
+				})
+				if (that.bLoading) return;
+				that.bLoading = true;
+				
+				let data = {
+					"username": this.userName,
+					"birthday": this.birthday,
+					"gender": this.gender,
+					"cityCode": this.city.cityCode,
+					"weight": this.weight,
+					"height": this.height,
+					//微信注册时候,更新一次到fitness
+					"bAddWeightInfo":true
+				}
+				
+				reqUtil.requestData(config.URL.USERINFOADD, data, "POST").then(res => {
+						console.log('requestData USERINFOADD =====', res);
+						uni.hideToast();
+						that.bLoading = false;
+						if (res.code == 0) {
+							uni.showToast({
+								title: "更新成功",
+								mask: true,
+								duration: 1000
+							})
+							// that.bCanUpdate = false;
+							setTimeout(() => {
+								that.$store.state.bNewUser = false;
+								// uni.redirectTo({
+								// 	url: "../../personal-page/personal/personal"
+								// })
+								uni.redirectTo({
+									url:'../firstPlan/firstPlan'
+								})
+							}, 1000);
+						}
+					},
+					e => {
+						console.log(e);
+						that.bLoading = false;
+						uni.showModal({
+							title: '错误',
+							content: '更新数据失败,是否重新更新?',
+							confirmText: '是的',
+							success: (res) => {
+								if (res.confirm) {
+									that.onPerfectConfirm();
+								}
+							}
+						})
+					});
+			},
+			//跳过
+			onSkip(){
+				
+				let that = this;
+				
+				uni.showToast({
+					title: "",
+					icon: "loading",
+					mask: true,
+					duration: 10000
+				})
+				if (that.bLoading) return;
+				that.bLoading = true;
+				
+				let data = {
+					"username": this.userName,
+					"birthday": this.birthday,
+					"gender": this.gender,
+					"cityCode": this.city.cityCode,
+					"weight": this.weight,
+					"height": this.height,
+					//微信注册时候,更新一次到fitness
+					"bAddWeightInfo":true
+				}
+				
+				reqUtil.requestData(config.URL.USERINFOADD, data, "POST").then(res => {
+						console.log('requestData USERINFOADD =====', res);
+						uni.hideToast();
+						that.bLoading = false;
+						if (res.code == 0) {
+							uni.showToast({
+								title: "",
+								icon:"loading",
+								mask: true,
+								duration: 1000
+							})
+							// that.bCanUpdate = false;
+							setTimeout(() => {
+								that.$store.state.bNewUser = false;
+								// uni.redirectTo({
+								// 	url: "../../personal-page/personal/personal"
+								// })
+								uni.redirectTo({
+									url:'../firstPlan/firstPlan'
+								})
+				
+							}, 1000);
+						}
+					},
+					e => {
+						console.log(e);
+						that.bLoading = false;
+						uni.showModal({
+							title: '错误',
+							content: '更新数据失败,是否重新更新?',
+							confirmText: '是的',
+							success: (res) => {
+								if (res.confirm) {
+									that.onPerfectConfirm();
+								}
+							}
+						})
+					});
+			}
+		}
+	}
+</script>
+
+<style>
+	.btn-row {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		margin: 102rpx 0;
+	}
+
+	.container {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #FFFFFF;
+	}
+
+
+
+	.input-container {
+		/* border-bottom: 1rpx solid #e7e9eb; */
+	}
+
+
+
+	.btn-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 10px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 17px;
+		color: #FFFFFF;
+	}
+
+	.right-container {
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		position: relative;
+	}
+
+	.perf-bottom-container {
+		border: 1rpx solid #EEEEEE;
+		border-radius: 10px;
+		height: 50px;
+		margin: 19rpx 41rpx 0 41rpx;
+	}
+</style>

+ 801 - 0
pages/my-page/userInfo/userInfo.vue

@@ -0,0 +1,801 @@
+<template>
+	<view>
+
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" :title="pageTitle" color="#000000" fixed="true"
+		 :border="false">
+			<view slot="left">
+				<view v-if="!bNewUser" class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+			<view v-if="bNewUser" slot="right">
+				<text class="text-df text-purple margin-right-sm" @tap="onNavUser">下一步</text>
+			</view>
+		</uni-nav-bar>
+
+		<view class="card-view">
+			<view class="avatar-group" @tap="ChooseImage">
+				<view class="avatar-size ">
+					<!-- 保持纵横比缩放图片 -->
+					<image class="avatar-img round bg-black" mode="aspectFit" :src="changeData.avatarUrl"></image>
+					<image class="avatar-tag " src="/static/camera.png"></image>
+				</view>
+				<view class="text-upload">
+					<text>请上传头像</text>
+				</view>
+			</view>
+			<view class="item-group flex align-center">
+				<view class="text-grey padding-sm margin-name text-width ">
+					昵称
+				</view>
+
+				<input maxlength="8" placeholder="输入名字" :value="changeData.userName" @input="onInput('name',$event)"></input>
+
+
+			</view>
+			<view class="item-group flex align-center" @tap="showModal" data-target="showPickerModal" data-type="gender">
+				<view class="text-grey padding-sm margin-name text-width flex">性别
+					<view v-if="bNewUser" style="position: relative; width: 4px;">
+						<!-- <view class="cu-tag badge"></view> -->
+					</view>
+				</view>
+				<view class="text-bold">{{changeData.gender==0?'男':'女'}}</view>
+			</view>
+			<view class="item-group flex align-center" @tap="showModal" data-target="showPickerModal" data-type="birthday">
+				<view class="text-grey padding-sm margin-name text-width flex">生日
+					<view v-if="bNewUser" style="position: relative; width: 4px;">
+						<!-- <view class="cu-tag badge"></view> -->
+					</view>
+				</view>
+				<view class="text-bold">{{changeData.sBirthday}}</view>
+			</view>
+
+			<view class="item-group flex align-center" @tap="showModal" data-target="showPickerModal" data-type="city">
+				<view class="text-grey padding-sm margin-name text-width flex">城市
+					<view v-if="bNewUser" style="position: relative; width: 4px;">
+						<!-- <view class="cu-tag badge"></view> -->
+					</view>
+				</view>
+				<view class="text-bold">{{changeData.city.label}}</view>
+			</view>
+
+			<view class="flex justify-start  ">
+				<view class="text-grey padding-sm margin-name text-width flex-shrink">个性签名</view>
+				<textarea class="sign-text text-bold" maxlength="50" placeholder="在这里留下你的签名吧!" :value="changeData.signature!=='null'?changeData.signature:''"
+				 @input="onInput('signature',$event)"></textarea>
+			</view>
+		</view>
+		<view class="card-view margin-top ">
+			<view class="cu-item shadow padding-top padding-bottom">
+				<view class="content">
+					<view class="item-group" @tap="showModal" data-target="showPickerModal" data-type="height">
+						<view class="text-grey padding-sm margin-name text-width flex">身高
+							<view v-if="bNewUser" style="position: relative; width: 4px;">
+								<!-- <view class="cu-tag badge"></view> -->
+							</view>
+						</view>
+						<view class="text-bold">{{changeData.height}} cm</view>
+					</view>
+					<view class="item-group" @tap="showModal" data-target="showPickerModal" data-type="weight">
+						<view class="text-grey padding-sm margin-name text-width flex">体重
+							<view v-if="bNewUser" style="position: relative; width: 4px;">
+								<!-- <view class="cu-tag badge"></view> -->
+							</view>
+						</view>
+						<view class="text-bold">{{changeData.weight}} 公斤</view>
+					</view>
+				</view>
+			</view>
+
+		</view>
+
+		<view class="card-view margin-top">
+			<view class="cu-item shadow padding-top-sm padding-bottom-sm flex justify-between">
+				<view class="content">
+					<view class="item-group">
+						<view class="text-grey padding-sm margin-name text-width flex">手机
+						</view>
+						<view class="text-bold">{{phoneNumber!==''?phoneNumber:'未绑定' }}</view>
+					</view>
+
+				</view>
+				<view class="right-container" @tap="onBindPhone">
+					<image style="width: 48rpx;height: 48rpx;" src="/static/bindPhone.png"></image>
+					<text class="text-grey text-sm" style="margin: 0 24rpx;">{{phoneNumber!==''?'已绑定':'去绑定'}}</text>
+					<view class="only-arrow"></view>
+				</view>
+			</view>
+
+		</view>
+
+		<view v-if="bInstallWechat&&!bHideWeixin" class="card-view margin-top ">
+			<view class="cu-item  shadow padding-top-sm padding-bottom-sm flex justify-between">
+				<view class="content">
+					<view class="item-group">
+						<view class="text-grey padding-sm margin-name text-width flex">微信
+
+						</view>
+						<view class="text-bold">{{openid!==''?'已关联微信':'未关联微信'}} </view>
+					</view>
+
+				</view>
+
+				<view class="right-container" @tap="onBindWeixin">
+					<image style="width: 48rpx;height: 48rpx;" src="/static/img/weixin_b.png"></image>
+					<text class="text-grey text-sm" style="margin: 0 24rpx;">{{openid!==''?'已绑定':'去绑定'}}</text>
+					<view class="only-arrow"></view>
+				</view>
+			</view>
+
+		</view>
+
+		<view v-if="!bNewUser" class="flex justify-center" style="margin: 32px 0 32px 0;">
+			<view class="btn-confirm" @tap="onNavUser">保存</view>
+		</view>
+
+		<view class="cu-modal bottom-modal" :class="modalName=='showPickerModal'?'show':''" @touchmove.stop.prevent="moveHandle">
+			<view class="cu-dialog" style="border-top-right-radius: 20rpx; border-top-left-radius: 20rpx;">
+				<myPicker v-if="modalName == 'showPickerModal' ? true:false" :pickerObj="pickerObj" @confirmEvent="onConfirm"
+				 @cancelEvent="hideModal">
+				</myPicker>
+			</view>
+		</view>
+
+		<view class="cu-modal" :class="modalName=='showBindModal'?'show':''" @touchmove.stop.prevent="moveHandle">
+			<view class="cu-bind-modal">
+				<view style="position: absolute; top: 0; left: 0; width: 100%; height:100%;">
+					<image style="position: absolute;top: 0;left: 0; width: 100%;height: 100%;" src="../../../static/modelBg.png"></image>
+				</view>
+				<view class="flex flex-direction justify-between " style="position: relative; height: 100%;">
+					<view class="flex justify-around justify-center align-center" style="margin: 170rpx 30rpx 0 30rpx;">
+						<view style="width: 80rpx;height: 2rpx;border-radius: 2px; background-color: #cbcdcf;"></view>
+						<view class="make-text-bPurple" style=" font-size: 20px;">{{bindModal.title}}</view>
+						<view style="width: 80rpx;height: 2rpx;border-radius: 2px;background-color: #cbcdcf;"></view>
+					</view>
+					<view class="text-16px">{{bindModal.content}}</view>
+
+					<view class="flex justify-around align-center" style=" border-top: 1rpx solid #EEEEEE; margin-bottom: 2px;">
+						<view class="flex justify-center align-center  text-16px" style="width: 100%;height: 123rpx;" @tap="hideModal">稍后再说</view>
+						<view style="height: 123rpx;width: 1px;background-color: #EEEEEE;"></view>
+						<view class="flex justify-center align-center  text-16px" style="width: 100%;height: 123rpx;" @tap="hideBindModal">确定</view>
+					</view>
+				</view>
+
+
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import myPicker from '@/components/slambb-picker/slambb-picker.vue';
+	import pickerData from '@/components/slambb-picker/picker.js';
+	import config from '@/common/config.js';
+	import reqUtil from "@/util/util-js/requstUtil.js";
+	import date from "@/util/util-js/date.js";
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex'
+	export default {
+		computed: mapState(['bNewUser', 'height', 'weight', 'userName', 'avatarUrl', 'days', 'signature', "gender",
+			'birthday', 'city', 'phoneNumber', 'openid','bInstallWechat','bHideWeixin'
+		]),
+		components: {
+			myPicker
+		},
+		data() {
+			let pickerObj = {
+				pickerLeftList: pickerData.getWeightList().leftList,
+				pickerRightList: pickerData.getWeightList().rightList,
+				pickerType: "doubleItem",
+				pickerUnit: "斤",
+				pickerTitle: "记体重",
+				defaultValue: 0
+			};
+
+			return {
+				modalName: null,
+				//选择器对象
+				pickerObj,
+				bChoose: false,
+				// oldData: null,
+				changeData:null,
+				//是否可以更新
+				bCanUpdate: false,
+
+				pageTitle: "完善资料",
+
+				bLoading: false,
+
+				bindModal: {
+					title: '解绑',
+					content: '绑定账号可以快速登录'
+				}
+			}
+		},
+		onLoad() {
+			let s = this.birthday.replace(/-/g, "/");
+			var dateTemp = new Date(s);
+			// this.oldData = {
+			// 	'height': this.height,
+			// 	'weight': this.weight,
+			// 	'userName': this.userName,
+			// 	'avatarUrl': this.avatarUrl,
+			// 	'signature': this.signature,
+			// 	"gender": this.gender,
+			// 	"cityCode": this.city.cityCode,
+			// 	'birthday': this.birthday,
+			// 	"city":this.city,
+			// 	"sBirthday": date.formatDate(dateTemp)
+			// };
+			
+			this.changeData = {
+				'height': this.height,
+				'weight': this.weight,
+				'userName': this.userName,
+				'avatarUrl': this.avatarUrl,
+				'signature': this.signature,
+				"gender": this.gender,
+				"cityCode": this.city.cityCode,
+				'birthday': this.birthday,
+				"city":this.city,
+				"sBirthday": date.formatDate(dateTemp)
+			};
+
+			if (this.bNewUser) {
+				this.pageTitle = "基础资料";
+				this.$store.state.bNewGuide = true;
+			}
+		},
+		methods: {
+			...mapMutations(['login']),
+			ChooseImage() {
+				uni.chooseImage({
+					count: 1, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择
+					success: (res) => {
+						this.bChoose = true;
+						let size = res.tempFiles[0].size;
+						console.log('res:',res);
+						if(size<=10000000){
+							this.changeData.avatarUrl = res.tempFiles[0].path;
+						}else{
+							uni.showToast({
+								title:'上传的图片不能超过10M',
+								icon:'none',
+							})
+						}
+					}
+				});
+			},
+			onInput(type, event) {
+				// console.log(type, "==", event.detail.value);
+				if (type == "name") {
+					this.changeData.userName = event.detail.value;
+					this.bCanUpdate = true;
+				} else if (type == "signature") {
+					this.changeData.signature = event.detail.value;
+					this.bCanUpdate = true;
+				}
+			},
+			/**
+			 * 由于性别和生日是有默认值,所以不用检测
+			 */
+			onCheck() {
+				if (this.height == 0) {
+					uni.showToast({
+						title: "请选择身高",
+						icon: "none"
+					})
+					return false;
+				} else
+				if (this.weight == 0) {
+					uni.showToast({
+						title: "请选择体重",
+						icon: "none"
+					})
+					return false;
+				}
+				return true;
+			},
+			//上传用户数据
+			onNavUser() {
+				let that = this;
+				
+				uni.showToast({
+					title: "",
+					icon: "loading",
+					mask: true,
+					duration: 10000
+				})
+				if (that.bLoading) return;
+				that.bLoading = true;
+				let data = {
+					"filePath": this.changeData.avatarUrl,
+					"username": this.changeData.userName,
+					"birthday": this.changeData.birthday,
+					"signature": this.changeData.signature,
+					"gender": this.changeData.gender,
+					"cityCode": this.changeData.city.cityCode,
+					"weight": this.changeData.weight,
+					"height": this.changeData.height,
+				}
+				console.log("更新时候的 data信息:",data);
+				//如果选择了图片,用图片接口更新数据
+				if (that.bChoose) {
+					reqUtil.reqUpload(config.URL.USERINFOADDAVATAR, data, that.changeData.avatarUrl).then(res => {
+							console.log('reqUpload USERINFOADDAVATAR =====', res);
+							uni.hideToast();
+							that.bLoading = false;
+							if (res.code == 0) {
+								uni.showToast({
+									title: "更新成功",
+									mask: true,
+									duration: 1000
+								})
+								that.bChoose = false;
+								// that.$store.state.avatarUrl = res.data.avatarUrl;
+								that.login(res.data);
+								// 如果是新用户,跳转首页
+
+								setTimeout(() => {
+									if (that.bNewUser) {
+										that.$store.state.bNewUser = false;
+										// uni.redirectTo({
+										// 	url: "../../personal-page/personal/personal"
+										// })
+										uni.redirectTo({
+											url:'../firstPlan/firstPlan'
+										})
+									} else {
+										uni.navigateBack({
+											delta: 1
+										})
+									}
+								}, 1000);
+
+							}
+
+						},
+						e => {
+							console.log(e);
+							that.bLoading = false;
+							uni.showModal({
+								title: '错误',
+								content: '更新头像失败,是否重新更新?',
+								confirmText: '是的',
+								success: (res) => {
+									if (res.confirm) {
+										that.onNavUser();
+									}
+								}
+							})
+						});
+				} else {
+					//如果只修改数据,走数据接口
+					if (!that.bNewUser && !that.bCanUpdate) {
+						uni.showToast({
+							title: "数据无改动",
+							icon: "none",
+							mask: true,
+							duration: 1000
+						})
+						that.bLoading = false;
+						return;
+					}
+					reqUtil.requestData(config.URL.USERINFOADD, data, "POST").then(res => {
+							console.log('requestData USERINFOADD =====', res);
+							uni.hideToast();
+							that.bLoading = false;
+							if (res.code == 0) {
+								uni.showToast({
+									title: "更新成功",
+									mask: true,
+									duration: 1000
+								})
+								that.bCanUpdate = false;
+								that.login(res.data);
+								setTimeout(() => {
+									if (that.bNewUser) {
+										that.$store.state.bNewUser = false;
+										// uni.redirectTo({
+										// 	url: "../../personal-page/personal/personal"
+										// })
+										uni.redirectTo({
+											url:'../firstPlan/firstPlan'
+										})
+									} else {
+										uni.navigateBack({
+											delta: 1
+										})
+									}
+								}, 1000);
+							}
+						},
+						e => {
+							console.log(e);
+							that.bLoading = false;
+							uni.showModal({
+								title: '错误',
+								content: '更新数据失败,是否重新更新?',
+								confirmText: '是的',
+								success: (res) => {
+									if (res.confirm) {
+										that.onNavUser();
+									}
+								}
+							})
+						});
+				}
+
+
+
+
+			},
+
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+
+			showModal(e) {
+				this.pikerType = e.currentTarget.dataset.type
+				switch (this.pikerType) {
+					case "weight":
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getWeightList().leftList);
+						this.$set(this.pickerObj, 'pickerRightList', pickerData.getWeightList().rightList);
+						this.$set(this.pickerObj, 'pickerType', "doubleItem");
+						this.$set(this.pickerObj, 'pickerUnit', "公斤");
+						this.$set(this.pickerObj, 'pickerTitle', "记体重");
+						this.$set(this.pickerObj, 'defaultValue', this.weight);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case "height":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getHeightList().leftList);
+						// pickerData.getHeightList().rightList
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerType', "singleItem");
+						this.$set(this.pickerObj, 'pickerUnit', "厘米");
+						this.$set(this.pickerObj, 'pickerTitle', "记身高");
+						this.$set(this.pickerObj, 'defaultValue', this.height);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case "birthday":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerType', "dateItem");
+						this.$set(this.pickerObj, 'pickerTitle', "记生日");
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+					case "gender":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getGenderList().genderList);
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerType', "singleItem");
+						this.$set(this.pickerObj, 'pickerTitle', "性别");
+						this.$set(this.pickerObj, 'defaultValue', "男");
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+					case "city":
+						this.pickerObj = {};
+						this.$set(this.pickerObj, 'pickerType', "city");
+						this.$set(this.pickerObj, 'pickerTitle', "省市区");
+						this.$set(this.pickerObj, 'defaultValue', this.city.value);
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+
+				}
+				this.modalName = e.currentTarget.dataset.target
+			},
+			hideModal(e) {
+				this.modalName = null
+			},
+			moveHandle() {
+				return;
+			},
+			onConfirm(data) {
+				console.log(data);
+				// let data = e.detail.__args__[0];
+				switch (this.pikerType) {
+					case "weight":
+						if (data.value != this.weight) {
+							this.bCanUpdate = true;
+							this.changeData.weight = data.value;
+						}
+						break;
+					case "height":
+						if (data.value != this.height) {
+							this.bCanUpdate = true;
+							this.changeData.height = data.value;
+						}
+						break;
+					case "birthday":
+						this.bCanUpdate = true;
+						let nDate = new Date();
+						nDate.setFullYear(data.value[0], data.value[1] - 1, data.value[2]);
+						this.changeData.sBirthday = date.formatDate(nDate);
+						this.changeData.birthday = date.formatTime(nDate);
+						break;
+					case "gender":
+						if (data.value != this.gender) {
+							this.bCanUpdate = true;
+							this.changeData.gender = data.index;
+						}
+						break;
+					case "city":
+						if (data.value.cityCode != this.cityCode) {
+							this.bCanUpdate = true;
+							this.changeData.city = data.value;
+						}
+						break;
+				}
+
+				this.hideModal();
+			},
+
+
+			onBindPhone() {
+				// //TODO 弹出解绑提示
+				// this.bindModal = {
+				// 	title: '解绑',
+				// 	content: '你确定要解绑手机吗?',
+				// 	type: "deletePhoneNumber"
+				// };
+				// this.modalName = "showBindModal";
+				if (!this.phoneNumber) {
+					uni.navigateTo({
+						url: "../../login-page/bindPhone/bindPhone"
+					})
+				} else {
+					uni.showToast({
+						title: '已绑定手机',
+						icon: 'none',
+					})
+				}
+
+			},
+			onBindWeixin() {
+				if (this.openid) {
+					uni.showToast({
+						title: '已绑定微信',
+						icon: 'none'
+					})
+				} else {
+					this.bindModal = {
+						title: '微信绑定',
+						content: '“哔蹦”想打开“微信”',
+						type: 'bindWxInfo'
+					};
+					this.modalName = "showBindModal";
+				}
+			},
+			hideBindModal() {
+				this.modalName = null;
+				console.log(this.bindModal);
+				let _self = this;
+				if (this.bindModal.type == 'bindWxInfo') {
+					// 绑定微信
+					// #ifdef APP-PLUS
+					this.oauth("weixin");
+					// #endif
+
+					// #ifndef APP-PLUS
+					uni.showToast({
+						title: "只支持app端",
+						icon: "none"
+					})
+
+					// #endif
+				} else if (this.bindModal.type == 'deletePhoneNumber') {
+					//弹框解绑手机
+					reqUtil.requestData(config.URL.DELETEPHONE, {}).then(res => {
+							console.log('DELETEPHONE请求返回:', res);
+							if (res.code == 0) {
+								uni.showToast({
+									title: "解绑手机号成功",
+									mask: true,
+									duration: 1000
+								})
+								_self.$store.state.phoneNumber = '';
+
+							} else {
+								uni.showToast({
+									title: "解绑手机号失败",
+									mask: true,
+									icon: 'none',
+									duration: 1000
+								})
+							}
+
+
+						},
+						e => {
+							console.log(e)
+						});
+				}
+			},
+			oauth(value) {
+				let _self = this;
+				uni.showToast({
+					title: "",
+					icon: "loading",
+					duration: 10000
+				})
+				uni.login({
+					provider: value,
+					success: (res) => {
+						console.log('code11:', res);
+						// android 端绑定微信信息
+						let wxInfo = {
+							openid: res.authResult.openid,
+							unionid: res.authResult.unionid
+						};
+
+						reqUtil.requestData(config.URL.BINDWXINFO, {
+							openid: res.authResult.openid,
+							unionid: res.authResult.unionid
+						}).then(res => {
+								console.log('BINDWXINFO请求返回:', res);
+								uni.hideToast();
+								if (res.code == 0) {
+									uni.showToast({
+										title: "绑定微信成功",
+										mask: true,
+										duration: 1000
+									})
+									_self.$store.state.openid = wxInfo.openid;
+								} else if (res.code == 212) {
+									uni.showToast({
+										title: "此微信已被绑定,请使用其他微信",
+										mask: true,
+										icon: 'none',
+										duration: 3000
+									})
+									// // 微信授权登录对象
+									// let aweixin = null;
+									// // 当前环境支持的所有授权登录对象
+									// let auths = {};
+									// plus.oauth.getServices(function(services) {
+									// 	for (var i in services) {
+									// 		auths[services[i].id] = services[i];
+									// 	}
+									// 	aweixin = auths['weixin'];
+									// 	aweixin.logout(function(e) {
+									// 		// plus.nativeUI.alert("注销登录认证成功!");
+									// 		console.log("注销登录认证成功");
+									// 	}, function(e) {
+									// 		// plus.nativeUI.alert("注销登录认证失败: " + JSON.stringify(e));
+									// 		console.log("注销登录认证失败: " + JSON.stringify(e));
+									// 	});
+									// }, function(e) {
+									// 	plus.nativeUI.alert("获取登录授权服务列表失败:" + JSON.stringify(e));
+									// });
+
+								} else {
+									uni.showToast({
+										title: "绑定微信失败",
+										mask: true,
+										icon: 'none',
+										duration: 1000
+									})
+								}
+
+
+							},
+							e => {
+								console.log(e);
+								uni.hideToast();
+							});
+
+					},
+					fail: (err) => {
+						console.error('授权登录失败:' + JSON.stringify(err));
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style>
+	.flex-shrink {
+		flex-shrink: 0;
+	}
+
+	.avatar-group {
+		margin-top: 30px;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.avatar-size {
+		position: relative;
+		width: 187.33rpx;
+		height: 186.67rpx;
+	}
+
+	.avatar-img {
+		width: 187.33rpx;
+		height: 186.67rpx;
+		border: 3px solid #9997fc;
+	}
+
+
+	.avatar-tag {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+
+		width: 46rpx;
+		height: 46rpx;
+	}
+
+	.text-upload {
+		font-size: 13px;
+		color: rgba(166, 166, 166, 1);
+		padding: 10px 0 45px 0;
+	}
+
+	.text-width {
+		width: 160rpx;
+		/* background: #007AFF; */
+	}
+
+	.margin-name {
+		margin: 0 0 0 66rpx;
+	}
+
+	.item-group {
+		display: flex;
+		justify-content: flex-start;
+		align-items: center;
+	}
+
+	.item-group input {
+		font-weight: bold;
+
+	}
+
+	.sign-text {
+		margin: 20rpx 30rpx 30rpx 0;
+		height: 4.6em;
+		width: 100%;
+		line-height: 1.2em;
+		flex: 1;
+		font-size: 28rpx;
+		/* padding: 1rpx; */
+		/* border: 1rpx solid #007AFF; */
+	}
+
+	/* 	.btn-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 10px;
+	} */
+
+	.btn-confirm {
+		width: 636rpx;
+		height: 102rpx;
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 10px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 17px;
+		color: #FFFFFF;
+	}
+
+	.right-container {
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+	}
+</style>

+ 81 - 0
pages/personal-page/devices-category/devices-category.vue

@@ -0,0 +1,81 @@
+<!-- 蓝牙平台限制 todo https://uniapp.dcloud.io/api/system/bluetooth?id=stopbluetoothdevicesdiscovery -->
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="选择设备类型" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		<view class="flex justify-start  align-center margin-top ">
+			<image style="margin: 0 20rpx 0 100rpx; width: 30rpx;height: 30rpx;" src="/static/devicesOther/link.png" mode="aspectFit"></image>
+			<text style="font-size: 15px; color: #999999;">请选择设备类型开始绑定</text>
+		</view>
+		<view class="card-view padding-top padding-bottom" v-for="(item,index) in devicesList" :key="index">
+			<view class="flex justify-between align-center" @tap="_onConnectDevice(item,$event)">
+				<text style="margin-left: 70rpx; font-weight: bold; font-size: 18px; color: #565656;">{{item.cname}}</text>
+				<image style="margin-right: 30rpx; width: 20rpx;height: 90rpx;" src="/static/devicesOther/deviceright.png" mode="aspectFit"></image>
+			</view>
+		</view>
+
+	</view>
+
+
+</template>
+
+<script>
+	import {
+		mapState
+	} from 'vuex';
+
+	export default {
+		computed: mapState([]),
+		data() {
+			return {
+				// 列表
+				devicesList: [{
+						cname: "手柄盒子",
+						deviceType: 'BLEHandle',
+						//type: 'boxingMode'
+					},
+					// {
+					// 	cname: "跳跃模式",
+					// 	type: 'jumpMode'
+					// },
+					// {
+					// 	cname: "跳跑模式",
+					// 	type: 'jumpRunMode'
+					// }
+				]
+			}
+		},
+		onLoad() {
+
+		},
+		onShow() {},
+		onHide() {},
+		methods: {
+
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+
+
+			// 提示点击连接设备
+			_onConnectDevice(item, event) {
+				// console.log(item, event);
+				uni.navigateTo({
+					url: '../devices-hardware/devices-hardware?deviceType='+item.deviceType
+				})
+			}
+		}
+
+	}
+</script>
+
+<style>
+</style>

+ 782 - 0
pages/personal-page/devices-hardware/devices-hardware.vue

@@ -0,0 +1,782 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" @clickRight="onNavUpdateDevice()" title="选择设备类型"
+		 color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+			<view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<image style="width: 60rpx;height: 50rpx;" src="../../../static/devicesIconSimple/upgrade.png"></image>
+				</view>
+			</view>
+		</uni-nav-bar>
+		<view class="card-view padding-top padding-bottom" v-for="(item,index) in devicesList" :key="index" :class="item.bRatio?'hardware-border':''">
+			<view class="flex justify-between align-center">
+				<view class="flex justify-start align-center">
+					<image style="margin-left: 30rpx; width: 200rpx;height: 120rpx;" :src="item.icon" mode="aspectFit"></image>
+					<view>
+						<view style="margin: 20rpx 50rpx; font-weight: bold; font-size: 18px; color: #565656;">{{item.cname}}</view>
+						<view style="margin-left: 50rpx; font-size: 12px;" class="make-text-bPurple">{{item.describe}}</view>
+					</view>
+
+				</view>
+				<image style="margin-right: 60rpx; width: 60rpx;height: 60rpx;" :src="item.bRatio?'/static/devicesOther/radio-b.png':'/static/devicesOther/radio-g.png'"
+				 mode="aspectFit" @tap="_onRadio(item,$event)"></image>
+			</view>
+		</view>
+		<!-- <button @click="onGetDevice()"> onGetDevice</button> -->
+
+	</view>
+
+
+</template>
+
+<script>
+	import config from '@/common/config.js'
+	import reqUtil from '@/util/util-js/requstUtil.js';
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	export default {
+		computed: mapState(['bOpenBluetooth', 'bOpenSuccess', 'bListenAdapterStateChange', 'bListenDeviceFound',
+			'BLEConnectDevice', 'BLEGetServices', 'cIndex', 'bConnection', 'bVerifiedConnection', 'BLEInfoList',
+			'BLEDeviceShowList', 'finallyUseDevice'
+		]),
+		data() {
+			return {
+				// 设备列表
+				devicesList: [],
+				currentItem: null,
+				//设置一个旧的连接item
+				oldItem: null,
+				searchObj: null,
+				//设置搜索超时时间
+				searchTimeOut: null,
+				option: null,
+				saveObj: null,
+				//搜索提示定时器
+				searchMac: null,
+				//
+				getServicesTimeout: null,
+				writeMacTimeout: null,
+				//限制关闭连接
+				bLimitClose: false,
+
+				//是否需要检测发起的连接蓝牙是否匹配上
+				bTestBondConnect: true,
+				//是否显示
+				bShow: true,
+				//切换连接
+				bSwitch: false
+			}
+		},
+		onLoad(op) {
+			// if (op.deviceType) {
+			// 	console.log(op);
+			// 	this.option = op;
+			// }
+			//目前是固定这个值,去掉了一级页面
+			// this.option = {
+			// 	cname: "手柄盒子",
+			// 	deviceType: 'BLEHandle'
+			// };
+			// if (this.option.deviceType == 'BLEHandle') {
+			// 	this.BLEInfoList.forEach((item, index, selfarr) => {
+			// 		if (item.deviceType == 'BLEHandle' || item.deviceType == 'BLERope') {
+			// 			let item = Object.assign({}, selfarr[index]);
+			// 			this.devicesList.push(item);
+			// 		}
+			// 	})
+			// }
+			this.BLEInfoList.forEach((item, index, selfarr) => {
+				if (item.deviceType == 'BLEHandle' || item.deviceType == 'BLERope') {
+					let item = Object.assign({}, selfarr[index]);
+					this.devicesList.push(item);
+				}
+			})
+			uni.$on('retryConnectBLESuccess', this.onRetryConnectBLESuccess);
+			uni.$on('callbackCloseBLE', this.hardCallbackCloseBLE);
+			uni.$on('listenerBLE', this.onListenerBLE);
+
+
+
+		},
+		onUnload() {
+			uni.$off('retryConnectBLESuccess', this.onRetryConnectBLESuccess);
+			uni.$off('callbackCloseBLE', this.hardCallbackCloseBLE);
+			uni.$off('listenerBLE', this.onListenerBLE);
+
+			//清除定时器
+			this.onClearTimeout();
+		},
+		onShow() {
+			this.bShow = true;
+			this.bLimitClose = false;
+			console.log(this.cIndex, this.BLEDeviceShowList, this.BLEConnectDevice, this.devicesList);
+			//this.bConnection &&
+			if (this.bVerifiedConnection && this.BLEConnectDevice) {
+				for (let i = 0; i < this.devicesList.length; i++) {
+					let eq = this.devicesList[i];
+					if (
+						(eq.ename.indexOf("mobilePhoneBandage") > -1 && this.BLEConnectDevice.id == 0) ||
+						(eq.ename.indexOf("hotman") > -1 && this.BLEConnectDevice.id == 1) ||
+						(eq.ename.indexOf("BLEHandle") > -1 && this.BLEConnectDevice.id == 2)||
+						(eq.ename.indexOf("rope") > -1 && this.BLEConnectDevice.id == 3)) {
+						eq.bRatio = true;
+						this.currentItem = eq;
+
+						// setTimeout(() => {
+						// 	this.onCheckBondDevice();
+						// }, 5000)
+
+
+					}
+				}
+			} else {
+				//如果没连接的话,设置一下显示状态
+				for (let i = 0; i < this.devicesList.length; i++) {
+					let eq = this.devicesList[i];
+					eq.bRatio = false;
+				}
+				// this.currentItem = null;
+			}
+
+
+		},
+		onHide() {
+			//如果蓝牙弹出匹配框,会触发onHide。这时候处理蓝牙连接流程检测应等onShow 时候,再检测
+			this.bShow = false;
+		},
+		methods: {
+			...mapMutations(['initAdapter', 'onCreateBLESuccess', 'onGetBLEDeviceServices', 'onOnlyCloseBLEConnection',
+				'onGetRSSITransDistance',
+				'addBLEDevice', 'onWriteBLEConnectionValue', 'deleteBLEDevice', 'B_GetBondedDevices', 'B_OpenBLESetting'
+			]),
+			//
+			onClearTimeout() {
+				// 退出后,清除计时器
+				if (this.searchMac) {
+					clearTimeout(this.searchMac);
+					this.searchMac = null;
+				}
+				//servicesTimeout
+				if (this.getServicesTimeout) {
+					clearTimeout(this.getServicesTimeout);
+					this.getServicesTimeout = null;
+				}
+				//写入指令writeMacTimeout
+				if (this.writeMacTimeout) {
+					clearTimeout(this.writeMacTimeout);
+					this.writeMacTimeout = null;
+				}
+
+				if (this.searchTimeOut) {
+					clearTimeout(this.searchTimeOut);
+					this.searchTimeOut = null;
+				}
+			},
+			//监听回调
+			onListenerBLE(res) {
+				// console.log('onListenerBLE:', res);
+				if (res.type !== 'mac') return;
+				//如果mac 回调了不用提示
+				if (this.searchMac) {
+					clearTimeout(this.searchMac);
+					this.searchMac = null;
+				}
+				let _self = this;
+				let mac = res.value;
+				console.log('mac =====', mac);
+				//用返回的mac 判断,如果非法,则断开连接
+				//就判断一下是否
+				//测试
+				// mac="BB:34:24:22:77:88";
+				// mac="较è¾";
+				//判断mac地址是否是合理的格式
+				var tempMacRegExp = /[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}/;
+				if (!tempMacRegExp.test(mac)) {
+					uni.hideToast();
+					uni.showModal({
+						title: '验证信息',
+						content: '获取Mac地址失败,请重新连接。'
+					})
+					//关闭当前连接
+					_self.onOnlyCloseBLEConnection({
+						getSuccess: () => {
+							_self.currentItem = null;
+							_self.saveObj = null;
+						}
+					});
+					return;
+				}
+
+				reqUtil.requestData(config.URL.BLEFINDHASBIND, {
+					mac: mac,
+				}).then(
+					res => {
+						console.log('BLEFINDHASBIND:', res);
+						if (res.code == 0) {
+							//code = 0 是新的地址,没绑定过
+							//绑定设备使用者
+							reqUtil.requestData(config.URL.BLEBIND, {
+								mac: mac,
+							}).then(
+								res => {
+									// console.log('BLEBIND:', res);
+									if (res.code == 0) {
+										//绑定成功,添加设备
+										if (_self.saveObj == null) return;
+										_self.addBLEDevice(_self.saveObj);
+										_self.ConnectionSuccess();
+									}
+								},
+								e => {
+									console.log(e);
+									//绑定失败, 关闭当前连接
+									_self.onOnlyCloseBLEConnection({
+										getSuccess: () => {
+											_self.currentItem.bRatio = false;
+											_self.currentItem = null;
+											_self.saveObj = null;
+										}
+									});
+								}
+							);
+
+						} else if (res.code == 721) {
+							// console.log("~~:",_self.saveObj);
+							//是自己绑定的,添加设备
+							if (_self.saveObj == null) return;
+							_self.addBLEDevice(_self.saveObj);
+							_self.ConnectionSuccess();
+
+
+						} else if (res.code == 711 || res.code == 722) {
+							//res.code = 711  蓝牙设备不是我们自己的
+							//res.code = 722  蓝牙设备别人使用过
+							uni.hideToast();
+							uni.showModal({
+								title: '连接失败',
+								content: '当前手柄已经被其它账号绑定。'
+							})
+							//关闭当前连接
+							_self.onOnlyCloseBLEConnection({
+								getSuccess: () => {
+									_self.currentItem = null;
+									_self.saveObj = null;
+								}
+							});
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+			},
+			ConnectionSuccess() {
+				// console.log(this.cIndex, this.BLEDeviceShowList, this.BLEConnectDevice);
+				// uni.showToast({
+				// 	icon: "none",
+				// 	title: "连接设备成功!",
+				// 	duration: 2000
+				// })
+				for (let i = 0; i < this.devicesList.length; i++) {
+					let eq = this.devicesList[i];
+					if (
+						(eq.ename.indexOf("mobilePhoneBandage") > -1 && this.BLEConnectDevice.id == 0) ||
+						(eq.ename.indexOf("hotman") > -1 && this.BLEConnectDevice.id == 1) ||
+						(eq.ename.indexOf("BLEHandle") > -1 && this.BLEConnectDevice.id == 2)||
+						(eq.ename.indexOf("rope") > -1 && this.BLEConnectDevice.id == 3)) {
+
+						eq.bRatio = true;
+						this.currentItem = eq;
+						/**
+						 * 已验证的连接设置true
+						 */
+						this.$store.state.bVerifiedConnection = true;
+
+						// setTimeout(() => {
+						// 	this.onCheckBondDevice();
+						// }, 5000)
+
+					}
+				}
+			},
+			onCheckBondDevice() {
+				console.log("onCheckBondDevice", this.bTestBondConnect);
+				if (this.bTestBondConnect && this.bShow) {
+					/**
+					 * 假如手机没有匹配,断开连接
+					 */
+					console.log(2, this.finallyUseDevice);
+					this.B_GetBondedDevices({
+						deviceId: this.finallyUseDevice.deviceId,
+						success: (bondedDevice) => {
+							uni.hideToast();
+							if (bondedDevice == null) {
+								// if (plus.os.name == 'Android') 
+								{
+									//此问题 华为手机容易出现
+									//android手机已配对的设备 不存在,但是app 又直接连接成功了。提示,并且断开app连接
+									//1.关闭当前连接
+									this.onOnlyCloseBLEConnection({
+										getSuccess: () => {
+											this.currentItem.bRatio = false;
+											this.currentItem = null;
+											this.saveObj = null;
+										}
+									});
+									//2.跳转蓝牙设置
+									uni.showModal({
+										title: '蓝牙配对失败',
+										content: '请跳转后点击配对BGBox_2020,成功后手动跳转回哔蹦重新连接。',
+										success: (res) => {
+											if (res.confirm) {
+												this.B_OpenBLESetting();
+											}
+										}
+									})
+								}
+
+							}
+						}
+					});
+					this.bTestBondConnect = false;
+				} else {
+					uni.hideToast();
+				}
+			},
+			onRetryConnectBLESuccess() {
+				this.ConnectionSuccess();
+			},
+			hardCallbackCloseBLE() {
+
+				if (this.BLEConnectDevice == null && this.currentItem && !this.bSwitch) {
+					this.currentItem.bRatio = false;
+					this.currentItem = null;
+					this.saveObj = null;
+				}
+				//如果限制不走重连
+				if (this.bLimitClose) return;
+
+				console.log(this.currentItem, this.oldItem);
+				if (this.oldItem && this.currentItem && this.currentItem.id == this.oldItem.id) {
+					// this.$store.state.bConnection = false;
+					if (this.currentItem.bRatio) {
+						uni.showToast({
+							title: '设备断开连接!',
+							icon: 'none',
+							duration: 2000,
+							mask: true
+						})
+						this.currentItem.bRatio = false;
+						this.oldItem = null;
+						this.currentItem = null;
+						//断开连接
+						this.$store.state.bVerifiedConnection = false;
+					}
+				} else if (this.bConnection && this.BLEConnectDevice) {
+					//假如匹配过程中断开连接
+					this.$store.state.BLEConnectDevice = null;
+					this.$store.state.bConnection = false;
+					// uni.hideToast();
+					// console.log("//假如匹配过程中断开连接");
+					uni.showToast({
+						title: '连接失败,尝试重新连接。',
+						icon: 'none',
+						mask: true,
+						duration: 2000
+					})
+					if (this.getServicesTimeout) {
+						clearTimeout(this.getServicesTimeout);
+						this.getServicesTimeout = null;
+					}
+				}
+
+			},
+			/**
+			 * 开始查找设备
+			 * */
+			startBluetoothDeviceDiscovery() {
+				//在页面显示的时候判断是都已经初始化完成蓝牙适配器若成功,则开始查找设备
+				let _self = this;
+				if (_self.bOpenBluetooth) {
+					//1.第一步还是先进行设备搜索
+					_self.onCanStart();
+				} else {
+					_self.initAdapter(() => {
+						_self.startBluetoothDeviceDiscovery();
+					});
+				}
+			},
+			/**
+			 * 通过检测手机连接的设备进行连接,null 的话进行搜索操作
+			 */
+			onBondedDeviceConnect() {
+				let _self = this;
+				//获取手机本身已连接的硬件,
+				//示例
+				// {
+				// 	"deviceId": "C5:5C:19:04:00:30",
+				// 	"name": "BGBox_202012",
+				// 	"RSSI": -74,
+				// 	"localName": "BGBox_20201",
+				// 	"advertisServiceUUIDs": ["00001812-0000-1000-8000-00805F9B34FB", "0000FFF0-0000-1000-8000-00805F9B34FB"]
+				// }
+
+				console.log("onBoded ***************:", _self.finallyUseDevice);
+
+				_self.B_GetBondedDevices({
+					deviceId: _self.finallyUseDevice == null ? null : _self.finallyUseDevice.deviceId,
+					success: (bondedDevice) => {
+						console.log("bondedDevice:", bondedDevice);
+						//获取已和蓝牙连接的设备
+						if (bondedDevice != null) {
+							//如果用户匹配了对应的设备,直接用对应的设备来连接
+							let setDevice = {
+								"deviceId": bondedDevice.address,
+								"name": bondedDevice.name,
+								"RSSI": -74,
+								"localName": "",
+								"advertisServiceUUIDs": ["00001812-0000-1000-8000-00805F9B34FB", "0000FFF0-0000-1000-8000-00805F9B34FB"]
+							}
+
+							let obj = Object.assign({}, setDevice, _self.currentItem);
+							//finallyUserDevice 就是最后一次使用搜索到的设备信息
+							_self.saveObj = Object.assign({}, setDevice, {
+								id: _self.currentItem.id
+							});
+							uni.showToast({
+								title: '设备连接中...',
+								icon: 'loading',
+								duration: 10000,
+								mask: true
+							})
+							console.log("GetBondedDevices:::===", setDevice, _self.currentItem, obj);
+							// 先直连,然后判断版本
+							_self._onConnectDevice(obj);
+
+							//getBond后发起的连接,不需要检测了
+							_self.bTestBondConnect = false;
+						} else {
+							console.log("没有获取到绑定的设备");
+							uni.showToast({
+								title: '获取匹配设备失败',
+								icon: 'none',
+								mask: true
+							})
+						}
+					}
+				});
+			},
+			//开始搜索
+			onCanStart() {
+				let _self = this;
+				uni.showToast({
+					title: '设备连接中...',
+					icon: 'loading',
+					duration: 15000,
+					mask: true
+				})
+				// 1.已经搜索到的,根据蓝牙回调的mac 地址判断合法性。
+				uni.startBluetoothDevicesDiscovery({
+					allowDuplicatesKey: true,
+					success: res => {
+						console.log("startBluetoothDevicesDiscovery:", res);
+
+						_self.bSwitch = false;
+						_self.onBluetoothDeviceFound();
+					},
+					fail: res => {
+						console.log("搜索失败!");
+						_self.initAdapter(() => {
+							_self.startBluetoothDeviceDiscovery();
+						});
+					}
+				});
+				// 2.没有搜索到的,一段时间后处理。比如手机已经连接了设备,但是app 里面搜索不到,也没记录使用过的。
+				if (_self.searchTimeOut) {
+					clearTimeout(_self.searchTimeOut);
+					_self.searchTimeOut = null;
+				}
+				_self.searchTimeOut = setTimeout(() => {
+					//1.搜索12秒钟之后,停止搜索
+					_self.stopBluetoothDevicesDiscovery();
+					//搜索失败后,再检查是否和手机配对的设备连接
+					// _self.onBondedDeviceConnect();
+
+				}, 8000)
+			},
+			/**
+			 * 停止搜索蓝牙设备
+			 */
+			stopBluetoothDevicesDiscovery() {
+				uni.stopBluetoothDevicesDiscovery({
+					success: e => {
+						console.log('停止搜索蓝牙设备:' + e.errMsg);
+					},
+					fail: e => {
+						console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
+					}
+				});
+			},
+			/**
+			 * 发现外围设备
+			 */
+			onBluetoothDeviceFound() {
+				let _self = this;
+				_self.searchObj = null;
+				uni.onBluetoothDeviceFound(res => {
+					/**
+					 * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
+					 */
+					// console.log("onBluetoothDeviceFound:", res);
+					res.devices.forEach(device => {
+						if (device.name.indexOf('PBox') > -1 || device.name.indexOf('BGBox') > -1 || device.name.indexOf('Rope') > -1) {
+							//如果搜索的设备名 不是对应当前设备类型,过滤
+							// if (device.name.indexOf(_self.currentItem.deviceName) == -1) return;
+							if (_self.currentItem.deviceName.indexOf('PBox') == -1 
+							&& _self.currentItem.deviceName.indexOf('BGBox') == -1
+							&& _self.currentItem.deviceName.indexOf('Rope') == -1
+							) return;
+							//寻找到对应设备时候,其余的返回
+							if (_self.searchObj) return;
+							_self.searchObj = device;
+							if (_self.searchTimeOut) {
+								clearTimeout(_self.searchTimeOut);
+								_self.searchTimeOut = null;
+							}
+							//currentItem 是mode 页面选中的item
+							let obj = Object.assign({}, device, _self.currentItem);
+
+							_self.saveObj = Object.assign({}, {
+								id: _self.currentItem.id
+							}, device);
+
+							console.log(device, "****", obj, _self.saveObj, _self.currentItem)
+							// 先直连,然后判断版本
+							_self._onConnectDevice(obj);
+							_self.stopBluetoothDevicesDiscovery();
+						}
+					})
+
+				})
+			},
+
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+
+			// 提示点击连接设备
+			_onConnectDevice(item) {
+				//servicesTimeout
+				if (this.getServicesTimeout) {
+					clearTimeout(this.getServicesTimeout);
+					this.getServicesTimeout = null;
+				}
+				//写入指令writeMacTimeout
+				if (this.writeMacTimeout) {
+					clearTimeout(this.writeMacTimeout);
+					this.writeMacTimeout = null;
+				}
+				//如果已经连接,加上服务不存在,直接获取服务
+				if (this.bConnection && this.BLEGetServices && this.BLEGetServices.length == 0) {
+					console.log("***直接获取服务*******");
+					this.onGetBLEDeviceServices({
+						item: item,
+						success: (res) => {
+							console.log("*****getBLEDeviceServices************");
+							//连接成功了,设置旧的item
+							this.oldItem = this.currentItem;
+							uni.showToast({
+								title: '正在验证设备信息...',
+								icon: 'loading',
+								duration: 10000,
+								mask: true
+							})
+							// 初始化服务后,获取版本,判断
+							// 停止蓝牙加速计
+							this.writeMacTimeout = setTimeout(() => {
+								//停止蓝牙加速计
+								this.onWriteBLEConnectionValue({
+									value: "4"
+								});
+								// 发送获取mac
+								this.onWriteBLEConnectionValue({
+									value: "M"
+								});
+								if (this.searchMac) {
+									clearTimeout(this.searchMac);
+									this.searchMac = null;
+								}
+								this.searchMac = setTimeout(() => {
+									uni.hideToast();
+									uni.showModal({
+										title: '提示',
+										content: '检测设备失败。\r\n1.检查手机蓝牙是否已连接上设备。\r\n2.再次尝试连接或者 重启手柄(Reset键位也可)后再尝试连接'
+									})
+									this.onOnlyCloseBLEConnection({
+										getSuccess: () => {
+											if (this.currentItem)
+												this.currentItem.bRatio = false;
+
+											this.currentItem = null;
+										}
+									});
+								}, 6000)
+							}, 3000)
+
+						}
+					});
+					return;
+				}
+				//创建一个连接,需要对应close
+				this.onCreateBLESuccess({
+					item: item,
+					getSuccess: () => {
+						console.log("****创建一个连接*******");
+						this.getServicesTimeout = setTimeout(() => {
+							this.onGetBLEDeviceServices({
+								item: item,
+								success: (res) => {
+									// console.log("******getBLEDeviceServices************", res);
+									//连接成功了,设置旧的item
+									this.oldItem = this.currentItem;
+									uni.showToast({
+										title: '正在验证设备信息...',
+										icon: 'loading',
+										duration: 10000,
+										mask: true
+									})
+									// 初始化服务后,获取版本,判断
+									// 停止蓝牙加速计
+									this.writeMacTimeout = setTimeout(() => {
+										//停止蓝牙加速计
+										this.onWriteBLEConnectionValue({
+											value: "4"
+										});
+										// 发送获取mac
+										this.onWriteBLEConnectionValue({
+											value: "M"
+										});
+										if (this.searchMac) {
+											clearTimeout(this.searchMac);
+											this.searchMac = null;
+										}
+										this.searchMac = setTimeout(() => {
+											uni.hideToast();
+											uni.showModal({
+												title: '提示',
+												content: '检测设备失败。\r\n1.检查手机蓝牙是否已连接上设备。\r\n2.再次尝试连接或者 重启手柄(Reset键位也可)后再尝试连接'
+											})
+											this.onOnlyCloseBLEConnection({
+												getSuccess: () => {
+													if (this.currentItem)
+														this.currentItem.bRatio = false;
+
+													this.currentItem = null;
+												}
+											});
+										}, 6000)
+									}, 3000)
+
+								}
+							});
+						}, 2500);
+					}
+				})
+			},
+
+			_onRadio(item, event) {
+
+				if (!item.bRatio) {
+					//设置默认值
+					this.bTestBondConnect = true;
+					if (this.BLEConnectDevice) {
+						this.onOnlyCloseBLEConnection({
+							getSuccess: () => {
+								if (this.currentItem)
+									this.currentItem.bRatio = false;
+
+								this.currentItem = null;
+								this.currentItem = item;
+								this.bSwitch = true;
+								console.log("this.currentItem1 ==:", this.currentItem, this.bOpenBluetooth, this.BLEConnectDevice);
+								this.startBluetoothDeviceDiscovery();
+							}
+						});
+						return;
+					}
+					this.currentItem = null;
+					this.currentItem = item;
+					console.log("this.currentItem ==2:", this.currentItem, this.bOpenBluetooth, this.BLEConnectDevice);
+					this.startBluetoothDeviceDiscovery();
+				}
+			},
+			//跳转进入升级页面,
+			onNavUpdateDevice() {
+				// console.log('onNavUpdateDevice');
+				// if (!this.option) {
+				// 	uni.showToast({
+				// 		title: 'option null',
+				// 		icon: 'none'
+				// 	})
+				// 	return;
+				// }
+				//需要连接设备后,才能进入升级
+				if (!this.currentItem || !this.currentItem.bRatio || !this.BLEConnectDevice) {
+					uni.showToast({
+						title: '选择一个连接后进入',
+						icon: 'none'
+					})
+					return;
+				}
+
+				// if (this.BLEConnectDevice.deviceType != this.option.deviceType) {
+				// 	uni.showToast({
+				// 		title: '设备类型不对',
+				// 		icon: 'none'
+				// 	})
+				// 	return;
+				// }
+
+				this.bLimitClose = true;
+				uni.navigateTo({
+					// url: "../devices-update/devices-update?deviceType=" + this.option.deviceType
+					url: "../devices-update/devices-update"
+				})
+			},
+			onGetDevice() {
+				uni.getBluetoothDevices({
+					success(res) {
+						console.log("getBluetoothDevices:", res)
+					}
+				})
+
+				uni.getConnectedBluetoothDevices({
+					success(res) {
+						console.log("getConnectedBluetoothDevices:", res)
+					}
+				})
+
+
+			}
+		}
+
+	}
+</script>
+
+<style>
+	.hardware-border {
+		border: 1rpx solid #9898FF;
+		box-sizing: border-box;
+	}
+</style>

+ 814 - 0
pages/personal-page/devices-update/devices-update.vue

@@ -0,0 +1,814 @@
+<!-- 蓝牙平台限制 todo https://uniapp.dcloud.io/api/system/bluetooth?id=stopbluetoothdevicesdiscovery -->
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="设备升级" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+
+		<view class="card-view padding-top padding-bottom" v-for="(item,index) in devicesList" :key="index" :class="item.bRatio?'hardware-border':''">
+			<view class="flex justify-between align-center">
+
+				<image style="margin-left: 30rpx; width: 200rpx;height: 120rpx;" :src="item.icon" mode="aspectFit"></image>
+				<view style="width: 250rpx;">
+					<view style="font-weight: bold; font-size: 18px; color: #565656; margin: 20rpx 0;">{{item.cname}}</view>
+					<view v-if="send_index<=0&&item.currentVersion !== ''">
+						<view style="margin: 20rpx 0; font-size: 12px; color: grey;">固件版本号:{{item.currentVersion}}</view>
+						<!-- <view style="margin: 20rpx; font-size: 12px;" class="make-text-bPurple">更新版本号:{{item.latestVersion}}</view> -->
+					</view>
+					<!-- <view class="flex">
+						<view style="margin: 20rpx; font-size: 12px; color: grey;">硬件rom:{{item.currentRomVersion}}</view>
+						<view style="margin: 20rpx; font-size: 12px;" class="make-text-bPurple">更新版本rom:{{item.latestRomVersion}}</view>
+					</view> -->
+					<!-- <view class="flex">
+						<view style="margin: 20rpx; font-size: 12px; color: grey;">Bytes:{{bin_offset}} 总 {{bin_byteLength}}</view>
+					</view> -->
+					<view v-if="send_index>0" class="flex justify-between align-center" style="width: 210rpx;">
+
+						<view class="cu-progress round" style="  width: 140rpx; height: 15rpx;">
+							<view class="bg-green" :style="[{ width:percentage+'%'}]"></view>
+						</view>
+						<view class="" style=" font-size: 12px; color: grey;">{{percentage}}%</view>
+
+						<!-- <view>
+							<progress :percent="percentage" stroke-width="3" />
+						</view> -->
+						<!-- ,total {{bin_total}} send:{{send_index}} -->
+						<!-- <view style=" font-size: 12px; color: grey;"> {{percentage}}% </view> -->
+					</view>
+
+				</view>
+
+				<view v-if = "!bStart" style="width: 180rpx;margin-right: 30rpx;">
+					<view v-if="send_index<=0&&item.latestVersion !== ''">
+						<view v-if="bCanUpdate&&downLoadOTA!==''" class="text-11px make-text-bPurple " style="text-decoration:underline"
+						 @click="onSendConnect"> 请更新版本{{item.latestVersion}}
+						</view>
+						<view v-else class="text-11px text-grey">最新版本{{item.latestVersion}}</view>
+						<!-- <button v-else class="text-11px make-bg-bPurple text-white" @click="onCheckDeviceFiles">检查更新</button> -->
+						<!-- <button v-if="item.currentVersion !== ''" class="text-11px margin" @click="onSendConnect">开始</button> -->
+						<!-- <button v-if="item.currentVersion !== ''" class="text-11px margin" @click="onStop">停止</button> -->
+					</view>
+					<view v-if="send_index<=0&&item.latestVersion === ''" class="text-26px text-grey text-center"><text class="cuIcon-loading2 cuIconfont-spin"></text></view>
+				</view>
+				<view v-else style="width: 180rpx;margin-right: 30rpx;">
+					<view v-if="send_index<=0&&!sending_file" class="text-11px text-grey">{{writeTip}}</view>
+					<view v-else class="text-11px text-grey">{{writeTip}}</view>
+				</view>
+
+			</view>
+			<!-- <view class="flex">
+				<view style="margin: 20rpx; font-size: 12px; color: grey;">发送和接收的次数:send:{{send_index}}</view>
+				<view style="margin: 20rpx; font-size: 12px;" class="make-text-bPurple">time:{{send_index/100}}</view>
+			</view> -->
+
+			<!-- <scroll-view class="text-box" scroll-y="true">
+				<scroll-view scroll-x="true">
+					<text selectable="true">{{text}}</text>
+				</scroll-view>
+			</scroll-view> -->
+		</view>
+
+
+
+	</view>
+
+
+</template>
+
+<script>
+	import config from '@/common/config.js'
+	import reqUtil from '@/util/util-js/requstUtil.js';
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	export default {
+		computed: mapState(['bOpenBluetooth', 'bOpenSuccess', 'bListenAdapterStateChange', 'bListenDeviceFound',
+			'BLEConnectDevice', 'cIndex'
+		]),
+		data() {
+			return {
+				/**
+				 * OTA config
+				 */
+				UUID_OTA_SERVICE: "f000ffc0-0451-4000-b000-000000000000", //OTA 服务对应的服务的 UUID
+				UUID_IDENTFY: "f000ffc1-0451-4000-b000-000000000000", //OTA 版本特征值的UUID,读取版本就是写向这个特征值写入:0x00
+				UUID_BLOCK: "f000ffc2-0451-4000-b000-000000000000", //OTA 写bin文件特征值UUID,发送bin文件就是写这个特征值
+				/*****/
+
+
+				boxingList: [{
+					cname: "蓝牙手柄",
+					ename: "BLEHandle",
+					icon: "/static/devicesIcon/handle.png",
+					mIcon: "/static/devicesIcon/handle.png",
+					bRatio: false,
+					limitType: 'noRebound', //app处理蓝牙发送的数据
+					deviceType: 'BLEHandle', //指的是外部蓝牙,目前定义为BLEHandle
+					deviceName: 'PBox', //连接的设备名称
+					limitDis: 100, //
+					primaryUUID: 'f000ffc0', //OTA升级主服务id
+					currentVersion: '', //当前固件版本
+					latestVersion: '', //服务器最新固件版本
+					currentRomVersion: '',
+					latestRomVersion: '',
+					UUID_OTA_SERVICE: "f000ffc0-0451-4000-b000-000000000000", //OTA 服务对应的服务的 UUID
+					UUID_IDENTFY: "f000ffc1-0451-4000-b000-000000000000", //OTA 版本特征值的UUID,读取版本就是写向这个特征值写入:0x00
+					UUID_BLOCK: "f000ffc2-0451-4000-b000-000000000000", //OTA 写bin文件特征值UUID,发送bin文件就是写这个特征值
+				}],
+				devicesList: [],
+
+				downLoadOTA: '',
+				//文件数据
+				bin_buffer: [],
+				bin_file_len: 0,
+				bin_byteLength: 0,
+				bin_total: 0,
+				bin_offset: 0,
+				//当前发送的下标
+				send_index: 0,
+				sending_file: false,
+				// 当前进度
+				percentage: 0,
+				//是否可以发送
+				bSend: true,
+				//是否可以更新
+				bCanUpdate: false,
+				//是否开始
+				bStart: false,
+
+				bListenValueChange: false,
+				//测试
+				text: '',
+				extraLine: [],
+
+				//timeout 对象
+				writeHeadTimeout: null,
+				backTimeout: null,
+				sendFileHeaderTimeout: null,
+				
+				writeTip:'准备写入数据..',
+				
+				bBacking:false,
+			}
+		},
+		onLoad(option) {
+			uni.$on('callbackCloseBLE', this.updateCallbackCloseBLE);
+			this.devicesList = this.boxingList;
+
+			//比如现在BLEHandle 对应的 1,
+			//获得游戏列表
+			reqUtil
+				.requestData(config.URL.GETOTA, {
+					bleType: 1, //目前只有一种设备,就是 BLEHandle,todo 后面如果设备多了需要设备多种ota
+				})
+				.then(
+					res => {
+						console.log('GETOTA =====', res);
+						if (res.code == 0) {
+							//设置对应的下载地址
+							this.downLoadOTA = res.data.otaDownload;
+
+							//读取需要更新的设备,存储在数据库
+							this.onCheckServerFiles();
+
+							this.onCheckDeviceFiles();
+							
+							uni.showToast({
+								title: '获取信息...',
+								icon: 'loading',
+								duration: 20000
+							})
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+
+
+
+		},
+		onUnload() {
+			uni.$off('callbackCloseBLE', this.updateCallbackCloseBLE);
+			//如果是获取版本指令timeout
+			if (this.writeHeadTimeout) {
+				clearTimeout(this.writeHeadTimeout);
+				this.writeHeadTimeout = null;
+			}
+
+			//回退timeout
+			if (this.backTimeout) {
+				clearTimeout(this.backTimeout);
+				this.backTimeout = null;
+			}
+
+			//发送头指令timeout
+			if (this.sendFileHeaderTimeout) {
+				clearTimeout(this.sendFileHeaderTimeout);
+				this.sendFileHeaderTimeout = null;
+			}
+			
+			this.onBack();
+		},
+		onShow() {
+			
+		},
+		onHide() {},
+		methods: {
+			...mapMutations(['initAdapter', 'onCloseBLEConnection',
+				'onGetRSSITransDistance'
+			]),
+			updateCallbackCloseBLE() {
+				this.onBack();
+			},
+			onBack() {
+				// if(this.bStart){
+
+				// }
+				if(this.bBacking)return;
+				this.bBacking = true;
+				//停止发送数据
+				this.onStop();
+				console.log('onBack:',this.BLEConnectDevice);
+				//关闭当前的蓝牙连接
+				this.onCloseBLEConnection({
+					getSuccess: () => {
+						console.log("close ble");
+						this.$store.state.bConnection = false;
+					}
+				});
+				console.log('onBack');
+				
+				this.$store.state.cIndex = -1;
+				this.$store.state.BLEConnectDevice = null;
+				this.$store.state.BLEGetServices = null;
+				this.$store.state.bOpenBluetooth = false;
+
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+
+			//获取版本
+			onCheckDeviceFiles() {
+				// console.log('onCheckDeviceFiles:', this.BLEConnectDevice);
+				//直接连接对应服务
+				this.notifyBLECharacteristicValueChange({
+					deviceId: this.BLEConnectDevice.deviceId,
+					serviceId: this.UUID_OTA_SERVICE,
+					characteristicId: this.UUID_IDENTFY
+				});
+			},
+			//开始写数据
+			onSendConnect() {
+				uni.showModal({
+					title: '更新提示',
+					content: '设备更新成功后会自动关闭,是否继续更新?',
+					success: (resValue) => {
+						if (resValue.confirm) {
+							//直接连接对应服务
+							this.notifyBLECharacteristicValueChange({
+								deviceId: this.BLEConnectDevice.deviceId,
+								serviceId: this.UUID_OTA_SERVICE,
+								characteristicId: this.UUID_BLOCK
+							});
+							uni.showToast({
+								title: '请求硬件更新数据...',
+								icon: 'none',
+								duration: 3000,
+								mask:true
+							})
+							//发送头指令timeout
+							if (this.sendFileHeaderTimeout) {
+								clearTimeout(this.sendFileHeaderTimeout);
+								this.sendFileHeaderTimeout = null;
+							}
+
+							this.sendFileHeaderTimeout = setTimeout(() => {
+								let retryCount = 3;
+								this.sendFileHeader(retryCount);
+								// this.send_index = -1;
+							}, 3000)
+
+							this.bStart = true;
+						}
+					}
+				})
+			},
+
+
+			//启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。
+			//注意:必须设备的特征值支持notify或者indicate才可以成功调用,具体参照 characteristic 的 properties 属性
+			notifyBLECharacteristicValueChange(context) {
+				var _self = this;
+				let {
+					deviceId,
+					serviceId,
+					characteristicId
+				} = context;
+				// 启用notify功能
+				uni.notifyBLECharacteristicValueChange({
+					state: true,
+					deviceId: deviceId,
+					serviceId: serviceId,
+					characteristicId: characteristicId,
+					success: function(res) {
+						if (!_self.bListenValueChange) {
+							_self.onBLECharacteristicValueChange(); //监听特征值变化
+							_self.bListenValueChange = true;
+						}
+						if (characteristicId == _self.UUID_IDENTFY) {
+							//重发3次
+							_self.onGetDeviceVersion(context,3);
+						}
+
+					},
+					fail: function(res) {
+						uni.showToast({
+							title: 'notify启动失败',
+							icon: "none",
+							mask: true
+						});
+
+					}
+				})
+			},
+			
+			onGetDeviceVersion(context,retryCount){
+				let _self = this;
+				let {
+					deviceId,
+					serviceId,
+					characteristicId
+				} = context;
+				//如果是获取版本,延迟写一个指令
+				if (_self.writeHeadTimeout) {
+					clearTimeout(_self.writeHeadTimeout);
+					_self.writeHeadTimeout = null;
+				}
+				_self.writeHeadTimeout = setTimeout(() => {
+					
+					// 向蓝牙设备发送一个0x00的16进制数据
+					let bufferDevice = new ArrayBuffer(1)
+					let dataViewDevice = new DataView(bufferDevice)
+					dataViewDevice.setUint8(0, 0)
+				
+					uni.writeBLECharacteristicValue({
+						deviceId: deviceId,
+						serviceId: serviceId,
+						characteristicId: characteristicId,
+						value: bufferDevice,
+						success:(res) => {
+							console.log('获取版本:writeBLECharacteristicValue success', res.errMsg ," == " ,retryCount)
+						},
+						fail:(fail)=>{
+							console.error('获取版本:writeBLECharacteristicValue fail', fail.errMsg ," == " ,retryCount)
+							
+							if(retryCount>0){
+								retryCount--;
+								setTimeout(()=>{
+									_self.onGetDeviceVersion(context,retryCount);
+								},300);
+								return;
+							}
+							
+							
+							uni.showModal({
+								title:'获取固件版本',
+								content:'获取不成功,是否重新获取',
+								success: (resValue) => {
+									if(resValue.confirm){
+										_self.onGetDeviceVersion(context,retryCount);
+									}
+								}
+							})
+						}
+					})
+				}, 3000)
+			},
+			//监听低功耗蓝牙设备的特征值变化。必须先启用notify接口才能接收到设备推送的notification。
+			onBLECharacteristicValueChange() {
+				var _self = this;
+				// ArrayBuffer转16进制字符串示例
+				// console.log("onBLECharacteristicValueChange");
+				uni.onBLECharacteristicValueChange(function(res) {
+
+					if (res.characteristicId.toLocaleLowerCase() === _self.UUID_IDENTFY) {
+						//如果硬件的版本获取版本
+						var resValue = ab2hext(res.value); //16进制字符串
+						// console.log("Device 版本:", resValue.substr(0, 4), "Rom 版本号:", resValue.substr(16, 4));
+						_self.devicesList[0].currentRomVersion = resValue.substr(16, 4);
+						_self.devicesList[0].currentVersion = resValue.substr(0, 4);
+
+						//读取到硬件版本,判断是否需要更新
+						if (_self.devicesList[0].currentVersion === _self.devicesList[0].latestVersion && _self.devicesList[0].currentRomVersion ===
+							_self.devicesList[0].latestRomVersion) {
+							uni.showToast({
+								title: '版本一致,无需升级',
+								icon: 'none',
+								mask: true,
+
+							})
+							_self.bCanUpdate = false;
+							return;
+						}
+						uni.showToast({
+							title: '获取信息成功',
+							icon: 'success',
+							mask: true,
+						})
+						//设置状态
+						_self.bCanUpdate = true;
+
+					} else {
+						uni.hideToast();
+						//成功发送头文件会走一个回调
+						let uint8_buf = new DataView(res.value);
+						_self.send_index = ((uint8_buf.getUint8(1) << 8) | uint8_buf.getUint8(0));
+						console.log("val===>> data:" + ab2hext(res.value) + ",rv index:" + _self.send_index + _self.sending_file)
+
+						if (_self.sending_file == false) {
+							_self.sending_file = true;
+							// console.log("SendBlePkg");
+							_self.writeTip = "正在写入设备...";
+							_self.SendBlePkg();
+						}
+					}
+				});
+			},
+			//下载后读取
+			onCheckServerFiles() {
+				this.bin_buffer = [];
+				this.bin_offset = 0;
+				this.bin_total = 0;
+				this.reset();
+
+				uni.request({
+					url: this.downLoadOTA,
+					method: "GET",
+					responseType: "arraybuffer",
+					success: (res) => {
+						//记录二进制数据
+						this.bin_buffer = res.data;
+						let binData = new Uint8Array(this.bin_buffer, 0, 16); //new Uint8Array(this.bin_buffer);
+						this.bin_file_len = (binData[7] << 8) | binData[6]
+						this.bin_total = (this.bin_file_len) / 4
+						this.bin_byteLength = this.bin_buffer.byteLength;
+
+						function uint8_to_hex_str(data) {
+							var v = data.toString(16).slice(-2) + ''
+							if (v == '0') {
+								v = '00'
+							}
+							if (v.length == 1) {
+								v = '0' + v
+							}
+							return v
+						}
+						// console.log("ver2:", uint8_to_hex_str(binData[4]) + uint8_to_hex_str(binData[5]), ",rom:", uint8_to_hex_str(
+						// 		binData[14]) +
+						// 	uint8_to_hex_str(binData[15]));
+						//显示信息
+						this.devicesList[0].latestRomVersion = uint8_to_hex_str(binData[14]) + uint8_to_hex_str(binData[15]); //str.substr(28, 2);
+						this.devicesList[0].latestVersion = uint8_to_hex_str(binData[4]) + uint8_to_hex_str(binData[5]); //str.substr(8, 2);
+
+					},
+					fail: (fail) => {
+						uni.showToast({
+							title: '下载固件失败..',
+							icon: 'none'
+						});
+					}
+				});
+			},
+
+			//发送文件头信息(配置信息)
+			sendFileHeader(retryCount) {
+				console.log('---------- sendFileHeader --------------')
+				let _self = this
+				let buffer = new ArrayBuffer(16)
+				let dataView = new DataView(buffer)
+				var b = new Uint8Array(_self.bin_buffer, 0, 16);
+				for (var i = 0; i < 16; i++) {
+					dataView.setUint8(i, b[i])
+				}
+				console.log('send header:' + ab2hext(buffer))
+				// return;
+				uni.writeBLECharacteristicValue({
+					deviceId: _self.BLEConnectDevice.deviceId,
+					serviceId: _self.UUID_OTA_SERVICE.toLocaleUpperCase(),
+					characteristicId: _self.UUID_IDENTFY.toLocaleUpperCase(),
+					value: buffer,
+					success: function(res) {
+						// _self.send_index = -1
+						// _self.sending_file = false
+						uni.showToast({
+							title: '准备更新数据...',
+							icon: 'none',
+							duration: 3000,
+							mask:true
+						})
+						console.log('开始发送文件success', _self.sending_file)
+						// _self.SendBlePkg()
+					},
+					fail: function(err) {
+						console.log('read version fail! ' + JSON.stringify(err)+retryCount)
+						
+						if(retryCount>0){
+							retryCount--;
+							setTimeout(()=>{
+								_self.sendFileHeader(retryCount);
+							},300);
+							return;
+						}
+						
+						uni.showModal({
+							title:'请求更新',
+							content:'请求更新失败,是否重新尝试继续。',
+							success: (resValue) => {
+								if(resValue.confirm){
+									_self.sendFileHeader(retryCount);
+								}else if(resValue.cancel){
+									_self.bStart = false;
+								}
+							}
+						})
+					}
+				})
+			},
+			//发送一包数据
+			SendBlePkg() {
+				var _self = this;
+				if (!_self.bSend) return;
+
+				if (_self.send_index == -1) {
+					return
+				}
+
+				if (_self.send_index >= _self.bin_total) {
+					_self.percentage = 100;
+					uni.showToast({
+						title: "更新完成",
+						duration: 2000,
+						mask: true
+					})
+					//回退timeout
+					if (this.backTimeout) {
+						clearTimeout(this.backTimeout);
+						this.backTimeout = null;
+					}
+
+					this.backTimeout = setTimeout(() => {
+						//更新成功后设备会断开,此时回退出此页面
+						uni.hideToast();
+						_self.onBack();
+					}, 1500)
+
+					return;
+				}
+				_self.percentage = parseInt(_self.send_index / _self.bin_total * 100);
+
+				//分包长度,16字节有效数据(总数据/16=次数)
+				let length = 16;
+				//发送每包数据的结构:2个字节的序号 + 16个字节的有效数据
+				//设置数据包序号
+				let lo = getLow8(_self.send_index);
+				let hi = getHeight8(_self.send_index);
+				//最要一个18字节的包
+				let send_ab = new ArrayBuffer(18);
+				let a = new Uint8Array(send_ab);
+				//2个字节的序号
+				a[0] = lo;
+				a[1] = hi;
+
+				if (_self.bin_offset + length > _self.bin_buffer.byteLength) {
+					length = _self.bin_buffer.byteLength - _self.bin_offset;
+				}
+				var b = new Uint8Array(_self.bin_buffer, _self.bin_offset, length);
+				a.set(b, 2);
+				uni.writeBLECharacteristicValue({
+					deviceId: _self.BLEConnectDevice.deviceId,
+					serviceId: _self.UUID_OTA_SERVICE, //  _deviceId,
+					characteristicId: _self.UUID_BLOCK,
+					value: send_ab,
+					fail: function(res) {
+						console.log('write BLEChar fail')
+						_self.SendBlePkg();
+					},
+					success: function(res) {
+						_self.send_index++;
+						//发送的有效字节数
+						_self.bin_offset += length;
+						// _self.sending_file = false;
+						_self.SendBlePkg();
+						// console.log('success')
+					},
+
+				})
+
+
+			},
+			reset() {
+
+				//发送字节的下标
+				this.send_index = 0;
+				//发送的有效字节数
+				this.bin_offset = 0;
+
+				this.percentage = 0;
+
+
+				this.bSend = true;
+
+			},
+			onStop() {
+				this.bSend = false;
+			},
+			onReadFile(url) {
+				//游戏列表
+				// firmwareList: [{
+				// 	name: "24_LYY_3431Q_H2_S3_bk3435_ble_app_oad.bin",
+				// 	downloadUrl: "https://www.yuyekeji.cn/Cocos/bin_version/24_LYY_3431Q_H2_S3_bk3435_ble_app_oad.bin",
+				// 	fileName: "bin_version",
+				// 	suffix: "bin",
+				// 	type: "bin",
+				// 	task: null,
+				// 	progressVal: 0,
+				// 	bFileExists: false,
+				// 	bDownload: false,
+				// }],
+				// data URIs to buffer
+				function dataURL2Buffer(dataURI) {
+					var byteStr
+					var intArray
+					var ab
+					var i
+					var mimetype
+					var parts
+
+					parts = dataURI.split(',')
+					parts[1] = parts[1].replace(/\s/g, '')
+					// console.log(parts);
+					if (~parts[0].indexOf('base64')) {
+						byteStr = atob(parts[1])
+					} else {
+						byteStr = decodeURIComponent(parts[1])
+					}
+
+					// // ab = new ArrayBuffer(byteStr.length)
+					// intArray = new Uint8Array(byteStr.length)
+
+					// for (i = 0; i < byteStr.length; i++) {
+					// 	intArray[i] = byteStr.charCodeAt(i)
+					// }
+					// console.log(intArray.length, intArray.byteLength);
+					return byteStr;
+				}
+				let item = this.firmwareList[0];
+				console.log("url:" + JSON.stringify(url));
+				plus.io.resolveLocalFileSystemURL(url, function(entry) {
+					entry.file(function(file) {
+						var fileReader = new plus.io.FileReader();
+						fileReader.readAsDataURL(file);
+						fileReader.onloadend = function(evt) {
+							// console.log("_buffer1:" + JSON.stringify(evt.target.result));
+							// let _arrayBuffer = dataURL2Buffer(evt.target.result)
+							let parts = evt.target.result.split(',')
+							let _arrayBuffer = parts[1].replace(/\s/g, '')
+							console.log("_buffer1:" + JSON.stringify(_arrayBuffer));
+							let _buffer = uni.base64ToArrayBuffer(_arrayBuffer);
+							console.log("_buffer2:", JSON.stringify(_buffer));
+							console.log("_buffer:", _buffer.length, _buffer.byteLength, _buffer.byteOffset);
+
+						}
+					});
+				}, function(e) {
+					console.log("Resolve file URL failed: " + e.message);
+				});
+
+
+			},
+			//下载固件
+			downLoadBin() {
+				let _self = this;
+				let item = this.firmwareList[0];
+				let downloadUrl = item.downloadUrl;
+				let _filename = '_doc/' + item.name; //+'/'+item.name
+				console.log(_filename, downloadUrl);
+				item.task = plus.downloader.createDownload(downloadUrl, {
+					filename: _filename
+				});
+				item.task.addEventListener("statechanged", (download, status) => {
+					// console.log("status", status);
+					//连接服务器后
+					// no default
+					switch (download.state) {
+						case 1:
+							console.log('开始下载');
+							// item.bDownload = true;
+							break;
+						case 2:
+							console.log('链接到服务器...');
+							item.bDownload = true;
+							break;
+						case 3:
+							if (status !== 200) {
+								uni.showToast({
+									title: 'status=' + status
+								})
+								return;
+							}
+							item.progressVal = Math.ceil(download.downloadedSize / download.totalSize * 100);
+							// _this.precent = progressVal;
+							console.log(item.progressVal);
+							break;
+						case 4:
+							// 下载完成
+							console.log("监听下载 success: " + download.getFileName());
+							setTimeout(() => {
+								item.bDownload = false;
+							}, 500)
+							break;
+					}
+				}, false);
+				item.task.start();
+			},
+			add: function(data) {
+				// console.log(data)
+
+				if (this.extraLine.length > 500) {
+					this.extraLine = [];
+					this.text = this.extraLine.join('\n');
+				}
+
+				this.extraLine.push(data);
+				this.text = this.extraLine.join('\n');
+
+
+			},
+			remove: function(e) {
+				if (this.extraLine.length > 0) {
+					// this.extraLine.pop();
+					this.extraLine = [];
+					this.text = this.extraLine.join('\n');
+				}
+			},
+
+		}
+
+	}
+
+	function ab2hext(buffer) {
+		var hexArr = Array.prototype.map.call(
+			new Uint8Array(buffer),
+			function(bit) {
+				return ('00' + bit.toString(16)).slice(-2)
+			}
+		)
+		return hexArr.join('');
+	}
+
+	function getHeight8(data) { //获取高8位
+		let height;
+		height = (data >> 8);
+		return height;
+	}
+
+	function getLow8(data) { //获取低8位
+		let low;
+		low = (data & 0xFF);
+		return low;
+	}
+</script>
+
+<style>
+	.hardware-border {
+		border: 1rpx solid #9898FF;
+		box-sizing: border-box;
+	}
+
+	.text-box {
+		margin: 20rpx;
+		display: flex;
+		width: 95%;
+		min-height: 300rpx;
+		max-height: 600rpx;
+		background-color: #EEEEEE;
+		justify-content: center;
+		align-items: center;
+		text-align: center;
+		font-size: 30upx;
+		color: #353535;
+		line-height: 1.8;
+		border: 1rpx solid #555555;
+		overflow-y: hidden;
+	}
+</style>

+ 295 - 0
pages/personal-page/devices/devices.vue

@@ -0,0 +1,295 @@
+<!-- 蓝牙平台限制 todo https://uniapp.dcloud.io/api/system/bluetooth?id=stopbluetoothdevicesdiscovery -->
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="选中设备型号" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		<view v-if="devicesList.length==0" class="text-xs text-center text-gray margin-top">
+			<text>下拉搜索设备 {{devicesList.length}}</text>
+		</view>
+		<view v-else class="card-view padding-top padding-bottom">
+			<view class="cu-list menu margin-left margin-right">
+				<view class="cu-item" :class="true?'arrow':''" v-for="(item,index) in devicesList" :key="index">
+					<view class="content" @tap="_onConnectDevice(item,$event)">
+						<image :src="item.icon" mode="aspectFit"></image>
+						<text class="text-grey">{{item.cname}}</text>
+					</view>
+				</view>
+			</view>
+
+
+		</view>
+
+	</view>
+
+
+</template>
+
+<script>
+	import BLE from '@/util/util-js/BLE.js'
+	import {
+		mapState
+	} from 'vuex';
+
+	export default {
+		computed: mapState(['bOpenBluetooth', 'bOpenSuccess', 'bListenAdapterStateChange', 'bListenDeviceFound']),
+		data() {
+			return {
+				// 设备列表
+				devicesList: []
+			}
+		},
+		onLoad() {
+			this.Init();
+			// #ifdef APP-PLUS
+			this.searchDevice();
+			// #endif
+
+		},
+		onShow() {
+			uni.$on('updateGetDevices', this.onGetDevices);
+		},
+		onHide() {
+			uni.$off('updateGetDevices', this.onGetDevices);
+		},
+		methods: {
+			Init() {
+				//假如没有初始化蓝牙,就来后再初始化
+				if (!this.bOpenBluetooth) {
+					/**
+					 * 蓝牙部分操作
+					 * */
+					//初始化蓝牙模块
+					BLE.openBluetoothAdapter({
+						success: (res) => {
+							this.$store.state.bOpenSuccess = true;
+							this.$store.state.bOpenBluetooth = true;
+						},
+						fail: (fail) => {
+							//fail 返回
+							//给蒙层提示,提示用户打开蓝牙,显示引导层
+							// this.$store.state.bGuidePages = true;
+							// this.guideCurrent = 2;
+							this.$store.state.bOpenSuccess = false;
+							this.$store.state.bOpenBluetooth = false;
+							uni.showToast({
+								title: '蓝牙尚未开启!',
+								icon: 'none'
+							})
+						},
+						complete: () => {
+							//初始化模块后,开始监听手机蓝牙状态
+							if (this.bListenAdapterStateChange) return;
+
+							this.$store.state.bListenAdapterStateChange = true;
+							uni.onBluetoothAdapterStateChange((res) => {
+								console.log('adapterState changed, now is', res)
+								// 手机蓝牙状态
+								this.$store.state.bOpenBluetooth = res.available;
+								if (this.bOpenBluetooth && !this.bOpenSuccess) {
+									this.Init();
+								}
+							})
+
+
+						}
+					});
+					//监听断开事件
+					BLE.onBLEConnectionStateChange();
+				}
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+
+			/**
+			 * 开始查找设备
+			 * */
+			startBluetoothDeviceDiscovery() {
+				//在页面显示的时候判断是都已经初始化完成蓝牙适配器若成功,则开始查找设备
+				let self = this;
+				setTimeout(function() {
+					if (self.bOpenBluetooth) {
+						uni.startBluetoothDevicesDiscovery({
+							//services: ['fff0'],
+							success: res => {
+								if (!self.bListenDeviceFound) {
+									self.$store.state.bListenDeviceFound = true;
+									self.onBluetoothDeviceFound();
+								}
+							},
+							fail: res => {
+								uni.showToast({
+									icon: "none",
+									title: "查找设备失败!",
+									duration: 3000
+								})
+							}
+						});
+					} else {
+						uni.showToast({
+							icon: "none",
+							title: "请打开手机蓝牙!",
+							duration: 3000
+						})
+						console.log("未初始化蓝牙是配饰器:" + self.bOpenBluetooth);
+					}
+				}, 300);
+			},
+
+			/**
+			 * 停止搜索蓝牙设备
+			 */
+			stopBluetoothDevicesDiscovery() {
+				uni.stopBluetoothDevicesDiscovery({
+					success: e => {
+						console.log('停止搜索蓝牙设备:' + e.errMsg);
+					},
+					fail: e => {
+						console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
+					}
+				});
+			},
+			/**
+			 * 发现外围设备
+			 */
+			onBluetoothDeviceFound() {
+				let _self = this;
+				console.log("发现外围设备 onBluetoothDeviceFound:");
+				uni.onBluetoothDeviceFound(devices => {
+					/**
+					 * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
+					 */
+					console.log("onBluetoothDeviceFound:", devices);
+
+					uni.$emit('updateGetDevices', devices);
+				});
+			},
+
+			onGetDevices() {
+				let _self = this;
+				uni.getBluetoothDevices({
+					success: res => {
+						let devicesList = res.devices;
+						console.log("搜索的设备对应的信息:", res);
+						//中间值
+						let _tempList = [];
+
+						//在这里查找对应名称的设备
+						for (let i = 0; i < devicesList.length; i++) {
+							let eq = devicesList[i];
+							//蹦床的设备名字
+							if (eq.name.indexOf("BBC") > -1) {
+								// eq.cname = "蹦床";
+								// eq.ename = "Trampoline";
+								// eq.icon = "/static/trampoline1.png";
+								// eq.mIcon = "/static/trampoline.png";
+								// let E = 2.718281828459045;
+								// let _dis = Math.pow(E, (Math.abs(eq.RSSI) - 66.78) / 16.56);
+								// console.log('距离:', _dis);
+								eq.cname = "绑带蓝牙";
+								eq.ename = "BT04";
+								eq.icon = "/static/trampoline1.png";
+								eq.mIcon = "/static/trampoline.png";
+
+								_tempList.push(eq);
+							} else if (eq.name.indexOf("BT04-E") > -1) {
+								eq.cname = "绑带蓝牙";
+								eq.ename = "BT04";
+								eq.icon = "/static/trampoline1.png";
+								eq.mIcon = "/static/trampoline.png";
+
+								_tempList.push(eq);
+							} else if (eq.name.indexOf("ITAG") > -1) {
+								eq.cname = "绑带蓝牙定位";
+								eq.ename = "ITAG";
+								eq.icon = "/static/trampoline1.png";
+								eq.mIcon = "/static/trampoline.png";
+
+								_tempList.push(eq);
+							} else {
+								eq.cname = eq.name;
+								eq.icon = "/static/logo.png";
+								eq.mIcon = "/static/logo.png";
+							}
+						}
+
+						if (_tempList.length != 0) {
+							uni.showToast({
+								icon: "none",
+								title: "查找设备成功!",
+								duration: 1000
+							})
+							_self.devicesList = [];
+
+							for (let i = 0, l = _tempList.length; i < l; i++) {
+								_self.devicesList.push(_tempList[i]);
+							}
+						} else {
+							uni.showToast({
+								icon: "none",
+								title: "未搜索到设备!",
+								duration: 1000
+							})
+						}
+						//停止搜索设备
+						uni.stopPullDownRefresh();
+						_self.stopBluetoothDevicesDiscovery();
+
+					},
+					fail: e => {
+						console.log('获取蓝牙设备错误,错误码:' + e.errCode);
+					}
+				});
+			},
+
+			onPullDownRefresh(e) {
+				//假如没有初始化蓝牙,就来后再初始化
+				console.warn("************BLE.bOpenBluetooth 初始化蓝牙适配器 == ", this.bOpenBluetooth);
+				this.Init();
+				this.searchDevice();
+			},
+			searchDevice() {
+				this.startBluetoothDeviceDiscovery();
+			},
+			// 提示点击连接设备
+			_onConnectDevice(item, event) {
+				// console.log(item, event);
+				if (!this.bOpenBluetooth) {
+					uni.showToast({
+						title: "蓝牙未初始化",
+						icon: "none"
+					})
+					return;
+				}
+				uni.showModal({
+					title: "连接",
+					content: "是否连接对应设备",
+					confirmText: '是的',
+					success: (res) => {
+						if (res.confirm) {
+							if (item.deviceId) {
+								//连接设备后,
+								this.$store.commit('addBLEDevice', item);
+								uni.navigateBack({
+									delta: 1
+								})
+							}
+						}
+					}
+				})
+			}
+		}
+
+	}
+</script>
+
+<style>
+</style>

+ 105 - 0
pages/personal-page/favorites/favorites.vue

@@ -0,0 +1,105 @@
+<!-- 蓝牙平台限制 todo https://uniapp.dcloud.io/api/system/bluetooth?id=stopbluetoothdevicesdiscovery -->
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="我的关注" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+
+		<view v-if="gameList.length==0" class="text-xs text-center text-gray margin-top">
+			<text>下拉刷新列表</text>
+		</view>
+		<view v-else class="cu-list menu margin-top">
+			<view class="cu-item" :class="true?'arrow':''" v-for="(item,index) in gameList" :key="index">
+				<view v-if="platform == gamePlatform[item.platform] || item.platform == 2" class="content" @tap="_onConnectDevice(item,$event)">
+					<image :src="item.icon" mode="aspectFit"></image>
+					<text class="text-grey">{{item.name}}</text>
+				</view>
+			</view>
+
+		</view>
+	</view>
+
+
+</template>
+
+<script>
+	import reqUtil from "@/util/util-js/requstUtil.js"
+	import config from "@/common/config.js"
+	import {
+		mapState
+	} from 'vuex';
+	
+	export default {
+		computed: mapState(['platform','gamePlatform']),
+		data() {
+			return {
+				gameList: []
+			}
+		},
+		onLoad() {
+			// reqUtil.requestData(config.URL.FAVORITESGET).then(res => {
+			// 		console.log('FAVORITESADD =====', res);
+			// 		if (res.code == 0) {
+
+			// 		}
+
+			// 	},
+			// 	e => {
+			// 		console.log(e)
+			// 	});
+
+			// reqUtil.requestData(config.URL.RECENTLYPLAYINGADD).then(res => {
+			// 		console.log('RECENTLYPLAYINGADD =====', res);
+			// 		if (res.code == 0) {
+
+			// 		}
+
+			// 	},
+			// 	e => {
+			// 		console.log(e)
+			// 	});
+
+			reqUtil.requestData(config.URL.RECENTLYPLAYINGGETBYPLATFORM).then(res => {
+					console.log('RECENTLYPLAYINGGETBYPLATFORM =====', res);
+					if (res.code == 0) {
+
+					}
+
+				},
+				e => {
+					console.log(e)
+				});
+
+
+		},
+		methods: {
+
+			onPullDownRefresh(e) {
+				reqUtil.requestData(config.URL.FAVORITESGETBYPLATFORM).then(res => {
+						console.log('FAVORITESGETBYPLATFORM =====', res);
+						if (res.code == 0) {
+
+						}
+
+					},
+					e => {
+						console.log(e)
+					});
+			},
+			onBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			}
+		}
+
+	}
+</script>
+
+<style>
+</style>

+ 145 - 0
pages/personal-page/list/list.vue

@@ -0,0 +1,145 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" :title="title" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		<view class="card-view game-item" v-for="(item,index) in list" :key="index">
+			<!-- <view class="only-arrow"> -->
+			<view v-if="platform == gamePlatform[item.platform] || item.platform == 2" class="content" @tap="onNavTo(item)">
+				<image :src="item.gameIcon" class="png"></image>
+				<text class="text-black text-bold ">{{item.gameName}}</text>
+				<view class="only-arrow"></view>
+			</view>
+			<!-- </view> -->
+
+		</view>
+		<view v-if="bDontUpdate" class="text-16px text-gray text-center margin">- 没有更多数据 -</view>
+	</view>
+</template>
+
+<script>
+	import reqUtil from "@/util/util-js/requstUtil.js"
+	import config from "@/common/config.js"
+	import {
+		mapState
+	} from 'vuex';
+	export default {
+		computed: mapState(['platform', 'gamePlatform']),
+		data() {
+			return {
+				list: [],
+				title: "最近在玩",
+				type: '',
+				page: 1,
+				size: 10,
+				bDontUpdate: false,
+			}
+		},
+		onLoad(option) {
+
+			let that = this;
+
+			if (option && option.type) {
+				that.type = option.type;
+				that.onGetData();
+			}
+
+		},
+		methods: {
+			onNavTo(item) {
+				let temItem = encodeURIComponent(JSON.stringify(item));
+				uni.navigateTo({
+					url: "../../game-page/game-detail/game-detail?item=" + temItem
+				})
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			onReachBottom() {
+				if (this.bDontUpdate) return;
+				this.page++;
+				this.onGetData();
+			},
+			onGetData() {
+				let that = this;
+				uni.showToast({
+					title: '',
+					icon: 'loading',
+					mask: true,
+					duration: 10000
+				})
+				if (that.type == 'recently') {
+					that.title = "最近在玩";
+					reqUtil.requestData(config.URL.RECENTLYPLAYINGGETBYPLATFORM, {
+						page: that.page,
+						size: that.size
+					}).then(res => {
+							console.log('RECENTLYPLAYINGGETBYPLATFORM =====', res);
+							if (res.code == 0) {
+								if (res.data.gameList.length < that.size) {
+									that.bDontUpdate = true;
+								}
+								that.list = that.list.concat(res.data.gameList);
+							}
+							uni.hideToast();
+
+						},
+						e => {
+							uni.hideToast();
+							console.log(e)
+						});
+				} else if (that.type == 'watchGame') {
+					that.title = "关注的游戏";
+					reqUtil.requestData(config.URL.FAVORITESGETBYPLATFORM, {
+						page: that.page,
+						size: that.size
+					}).then(res => {
+							console.log('FAVORITESGETBYPLATFORM =====', res);
+							if (res.code == 0) {
+								if (res.data.gameList.length < that.size) {
+									that.bDontUpdate = true;
+								}
+								that.list = that.list.concat(res.data.gameList);
+							}
+							uni.hideToast();
+						},
+						e => {
+							uni.hideToast();
+							console.log(e)
+						});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	.content {
+
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		height: 98px;
+	}
+
+	.content image {
+		width: 71px;
+		height: 71px;
+		margin-left: 40rpx;
+		margin-right: 40rpx;
+		border-radius: 12px;
+	}
+
+	.game-item {
+		position: relative;
+		background-color: #FFFFFF;
+		border-radius: 10px;
+	}
+</style>

+ 230 - 0
pages/personal-page/more/more.vue

@@ -0,0 +1,230 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="我的设备" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+		<view class="card-view text-center">
+			<view class="plan-w" style="margin-top: 34px;">
+				<view class="plan-w-child">
+					<image src="../../../static/moreBg.png"></image>
+				</view>
+			</view>
+			<view class="plan-Tip flex justify-center align-center">
+				<view class="plan-Tip-child make-text-bPurple flex align-center justify-between">
+					<view class="flex" style="margin-left: 80rpx;">
+						<image style="width:48rpx;height: 48rpx;" src="../../../static/wifi_on.png"></image>
+						<view class="padding-left text-16px">在线设备</view>
+					</view>
+					<view class=" text-16px" style="margin-right: 80rpx;">{{cIndex==-1?0:1}} 台</view>
+				</view>
+			</view>
+			<view class="button-fav" @tap="onNavToDevices">
+				<image style="width: 72rpx;height: 72rpx; margin-right: 12rpx;" src="../../../static/add_w.png"></image>
+				添加设备
+			</view>
+		</view>
+
+		<!-- 添加设备部分 -->
+		<view class="card-view">
+			<view class="text-left padding margin-xs">
+				<text class="text-black text-bold ">我的设备</text>
+			</view>
+			<!-- @tap="onDevice(item,$event)" -->
+			<view class="container-device">
+				<view class="width-device flex align-center " v-for="(item,index) in BLEDeviceList" :key="index" 
+				 :data-index="index">
+
+					<!-- 	<view style="position: relative; height: 100%;">
+						<image src="/static/deviceBg.png" class="data-png-64" mode="aspectFit"></image>
+						<image src="/static/trampolineS.png" class="data-png-add" mode="aspectFit"></image>
+					</view>
+
+					<view class="flex-sub text-center">
+						<image src="/static/wifi_on.png" class="data-png-32" mode="aspectFit"></image>
+						<view class="text-gray">{{item.cname}}</view>
+					</view>
+
+					<view style="position: absolute;right: 0;top: 0;" @tap.stop="onCloseDevice(item,$event)" :data-index="index">
+						<image src="/static/d_on.png" class="data-png-26" mode="aspectFit"></image>
+					</view> -->
+
+					<view style="position: relative; height: 100%;">
+						<image :src="index == cIndex ? '/static/deviceBg.png' : '/static/deviceBg_off.png'" class="data-png-64" mode="aspectFit"></image>
+						<image src="/static/trampolineS.png" class="data-png-add" mode="aspectFit"></image>
+					</view>
+
+					<view class="flex-sub text-center">
+						<image :src="index == cIndex ? '/static/wifi_on.png' : '/static/wifi_off.png'" class="data-png-32" mode="aspectFit"></image>
+						<view class="text-gray">{{ item.cname }}</view>
+					</view>
+					<!-- @tap.stop="onCloseDevice(item, $event)" :data-index="index" -->
+					<!-- <view style="position: absolute;right: 0;top: 0;" >
+						<image :src="index == cIndex ? '/static/d_on.png' : '/static/d_off.png'" class="data-png-26" mode="aspectFit"></image>
+					</view> -->
+
+				</view>
+
+			</view>
+
+
+		</view>
+
+
+	</view>
+
+</template>
+
+<script>
+	import config from '../../../common/config.js'
+	import date from '../../../util/util-js/date.js'
+	import reqUtil from '../../../util/util-js/requstUtil.js'
+
+	import picker from "@/components/slambb-picker/slambb-picker.vue";
+	import pickerData from '@/components/slambb-picker/picker.js';
+	import {
+		mapState
+	} from 'vuex'
+	export default {
+		computed: mapState(['planData', 'BLEDeviceList']),
+		components: {
+			picker,
+
+		},
+		data() {
+			return {
+				cIndex: -1
+			}
+		},
+		onShow() {
+
+
+		},
+		onLoad: function(option) { //option为object类型,会序列化上个页面传递的参数
+			console.log(option);
+			this.cIndex = option.index;
+		},
+		methods: {
+			onNavToDevices() {
+				uni.navigateTo({
+					url: '../devices/devices?newsid=' + 11,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			onCloseDevice(item, e) {
+				//如果不是连接状态,则删除
+				if (e.currentTarget.dataset.index != this.cIndex) {
+					uni.showModal({
+						title: '设备状态',
+						content: '是否删除设备',
+						ConfirmColor: '#A488DC',
+						success: res => {
+							if (res.confirm) {
+								// this.$store.state.BLEDeviceList.splice(e.currentTarget.dataset.index, 1)
+								this.$store.commit('deleteBLEDevice', e.currentTarget.dataset.index);
+							}
+						}
+					});
+					return;
+				}
+				uni.showModal({
+					title: '设备状态',
+					content: '是否关闭设备绑定',
+					/**
+					 * 如果需要强制,不显示取消按钮
+					 */
+					showCancel: true,
+					ConfirmColor: '#A488DC',
+					success: res => {
+						if (res.confirm) {
+							// this.$store.state.BLEDeviceList.splice(e.currentTarget.dataset.index, 1)
+							// this.$store.commit('deleteBLEDevice', e.currentTarget.dataset.index);
+							BLE.closeBLEConnection(item.deviceId);
+							if (this.cIndex == e.currentTarget.dataset.index) {
+								this.cIndex = -1;
+							}
+						}
+					}
+				});
+			}
+		}
+	}
+</script>
+
+<style>
+	.plan-w {
+		position: relative;
+		/* width: 464rpx; */
+		height: 464rpx;
+	}
+
+
+	.plan-w-child {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		width: 488rpx;
+		height: 372rpx;
+
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+
+
+
+	.plan-Tip {
+		height: 90rpx;
+		/* margin: 60rpx 0; */
+		margin-bottom: 60rpx;
+	}
+
+	.plan-Tip-child {
+		background-color: #f5f5ff;
+		border-radius: 20px;
+		width: 614rpx;
+		height: 90rpx;
+		/* margin-top: 60rpx; */
+
+	}
+
+	.button-fav {
+		background-color: rgba(153, 150, 252, 255);
+		color: #FFFFFF;
+		/* border-radius: 10px; */
+		/* width: 184rpx; */
+		height: 122rpx;
+		display: flex;
+		justify-content: center;
+		text-align: center;
+		align-items: center;
+		font-size: 17px;
+	}
+
+
+	.data-png-add {
+		position: absolute;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		margin: auto;
+		width: 34px;
+		height: 37px;
+	}
+</style>

+ 3005 - 0
pages/personal-page/personal/personal.vue

@@ -0,0 +1,3005 @@
+<template>
+	<view class="content bg-person " :class="bEFHitShake?' screen-jitter ':''">
+		<!-- :title="title" -->
+		<!-- 自定义导航栏 backgroundColor="rgba(164, 136, 220, 1)"  @clickRight="onSyncData" @clickRight="onTestShare"-->
+		<uni-nav-bar id="nav-bar" status-bar="true" backgroundColor="rgba(153, 150, 252, 255)" @clickLeft="showClickEvent()"
+		 @clickRight="onNavAppInfo()" title="" color="#FFFFFF" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="png-more" src="/static/more.png"></image>
+				</view>
+			</view>
+			<!-- @clickRight="onNavFcGame()" -->
+			<!-- <view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<view class="text-22px-before cuIcon-game"></view>
+				</view>
+			</view> -->
+			<view slot="right">
+				<view class=" flex align-center " style="margin-right: 10rpx;">
+					<view class="text-22px-before cuIcon-info"></view>
+				</view>
+			</view>
+		</uni-nav-bar>
+		<!-- 导航栏下面滚动区域 -->
+		<scroll-view class="scroll-class" @scroll="mainScroll" :scroll-top="scrollTop" :scroll-into-view="toView" scroll-y="true"
+		 :style="{ height: scrollviewHight + 'px' }">
+			<view class="flex align-center">
+				<view class="text-center">
+					<!-- 计划显示 区域 topScrollHight :style="{ height: + '100%' }"-->
+					<scroll-view scroll-y="true" style="height: 100%; width: 100%;">
+						<view class="plan-view">
+							<!-- 拳击模块 -->
+							<view v-if="currentMode == 'pkMode'" style="display: flex; flex-direction: row; height: 200rpx; margin-top: 140rpx; justify-content: space-around;align-items: center;">
+								<view>
+									<view class="cu-avatar-group" style="position: relative;">
+										<view class="cu-avatar round xl" :class="bAiHitShake?' screen-jitter':''" :style="[{ backgroundImage:'url('+avatarUrl+')' }]"></view>
+										<HitEffect ref="aiHitEffectRef"></HitEffect>
+									</view>
+									<view style="margin-top: 20rpx; width: 165rpx;" class="text-cut text-white">{{userName}}</view>
+								</view>
+
+								<view>
+									<image style="width: 104rpx; height: 42rpx ;margin-bottom: 60rpx;" src="/static/personal/pk@2x.png"></image>
+								</view>
+								<view>
+									<view class="cu-avatar-group" style="position: relative;">
+										<view class="cu-avatar round xl" :class="bHitShake?' screen-jitter':''" :style="[{ backgroundImage:'url('+aiObj.avatar+')' }]"></view>
+										<HitEffect ref="hitEffectRef"></HitEffect>
+									</view>
+									<view style="margin-top: 20rpx; width: 165rpx;" class="text-cut text-white">{{aiObj.name}}</view>
+								</view>
+
+								<view style="position: absolute;left: 0;right: 0;top: 0;bottom: 0; height: 200rpx; margin-top: 120rpx;">
+									<HitFistEffect ref="hitFistRef"></HitFistEffect>
+								</view>
+
+							</view>
+
+
+							<!-- 圆形进度条 -->
+							<view v-else class="qiun-charts-arcbar">
+								<!-- 进度条 -->
+								<canvas canvas-id="canvasArcbar" id="canvasArcbar" class="charts-arcbar "></canvas>
+								<!-- 水果卡路里-->
+								<view class="personal-fruit-container">
+									<fruit ref="personalFruitRef" :calorie="planData.allCalorie"></fruit>
+								</view>
+								<!-- 卡路里提示 -->
+								<view class="personal-fruit-container">
+									<prompt-box :calorie="planData.allCalorie"></prompt-box>
+								</view>
+								<!-- 计划运动时间提示 -->
+								<view class="personal-fruit-container">
+									<view style="margin-top: 130px;font-size:12px;color: #FFFFFF;">计划时间{{planData.sportTime}}分钟</view>
+								</view>
+								<!-- 计划按钮 -->
+								<!-- <view id="projectButtonView" style="position: absolute;left: 0;top: 18px;">
+									<view class="flex justify-center" style="width: 100%;">
+										<view class="charts-pring-button  make-line-bPurple " :class="bPlanExpired?'breathing-lamp':''" style="background-color: #FFFFFF;"
+										 @tap="openPlan">
+											<image src="/static/reform.png" class="p-data-png" mode="aspectFit"></image>
+											<view class="text-11px">改计划</view>
+										</view>
+									</view>
+								</view> -->
+							</view>
+
+							<!-- 计划按钮 -->
+							<view id="projectButtonView" style="position: absolute;left: 0;top: 18px;">
+								<view class="flex justify-center" style="width: 100%;">
+									<view class="charts-pring-button  make-line-bPurple " :class="bPlanExpired?'breathing-lamp':''" style="background-color: #FFFFFF;"
+									 @tap="openPlan">
+										<image src="/static/reform.png" class="p-data-png" mode="aspectFit"></image>
+										<view class="text-11px">改计划</view>
+									</view>
+								</view>
+							</view>
+
+							<!-- 用于定位 -->
+							<!-- <view id="boxingHitID" style="position: absolute;top: 180rpx; pointer-events: none;" ></view> -->
+							<view id="boxingHitID" v-if="currentModeIndex == 0" class="charts-pring-bottom">
+								<!-- 添加一个 ConnectBindingDevice 测试 -->
+								<boxing-hit ref="boxingPostRef" :bUpdate="!bHide&&(ConnectBindingDevice!=null)||(cIndex!=-1 && BLEConnectDevice!=null &&
+								 (BLEConnectDevice.deviceType == 'mySelf'||BLEConnectDevice.deviceType == 'BLEHandle' || BLEConnectDevice.deviceType == 'BLERope' ))"
+								 :showTime="localSportTime" :bRebound="BLEConnectDevice&&BLEConnectDevice.limitType == 'rebound'"
+								 @updateCalorie="boxingUpdateCalorie" @boxingPostCheck="onPersonalCheck" @shake="onScreenShake"
+								 @updateSportTime="onUpdateSportTime" @boxingGuideFinish="onBoxingGuideFinish" @boxingPostControlPlay="onBoxingPostControlPlay"
+								 @modeEvent="onModeEvent" @hitEvent="onHitEvent" @aiHitEvent="onAiHitEvent" @gameOver="onBoxingGameOver"
+								 @closeBoxingControl="onCloseBoxingHit"></boxing-hit>
+
+							</view>
+							
+							<view id='actionJumpID' v-if="true" class="charts-pring-bottom">
+								<action-jump ref = "actionJumpRef"></action-jump>
+							</view>
+							<!-- <button @tap="onTestAddLocalCalorie">11</button> -->
+						</view>
+
+					</scroll-view>
+					<!-- <view class="margin flex flex-direction">
+						<view class="title">当前游戏链接:{{LocationGameUrl}}</view>
+						<input style="border: 1rpx solid #000000;margin: 10rpx;" @input="onKeyInput" placeholder="输入同步到view中" />
+					</view> -->
+					<!-- <button  @tap="onShowBoxingHitTip">11</button> -->
+					<!--数据展示部分 -->
+					<view class="bottom-view" style="position: relative;">
+						<view style="position: absolute; z-index: 1; background-color: #FFFFFF; width: 100%; height: 217px; " class="flex justify-center">
+							<view style="border: 3px solid #9797ff; width: 35px; height: 3px; border-radius: 5px; margin-top: 9px;"></view>
+						</view>
+						<view style="height: 26px ;"></view>
+
+						<view class="card-view">
+							<view class="flex justify-between margin-top margin-left">
+								<view class="flex justify-start">
+									<image src="/static/sync.png" class=" data-png" mode="aspectFit" @tap="onSyncData"></image>
+									<view class="text-gray" style="margin-left: 10rpx;">{{ currentDate }}同步</view>
+								</view>
+								<!-- <view class="flex justify-start margin-right">
+									<view class="text-gray">标准体重:</view>
+									<view class="make-text-bPurple" style="margin-left: 10rpx;">120斤</view>
+								</view> -->
+							</view>
+							<view class="text-xl padding">
+								<view class="make-text-bPurple">
+									{{ weight }}公斤
+									<!-- <span class="text-11px text-gray "> (过重)</span> -->
+								</view>
+							</view>
+							<!-- 曲线图绘制部分 -->
+							<view class="qiun-charts-area">
+								<canvas canvas-id="canvasLineA" id="canvasLineA" class="charts-area" @touchstart.prevent="touchLineA"
+								 @touchmove.prevent="moveLineA" @touchend.prevent="touchEndLineA"></canvas>
+							</view>
+							<view class="bg-white qiun-charts-bottom-container">
+								<view class="avatar-bg-arrow"></view>
+								<view class="avatar-bg-personal">
+									<image mode="aspectFit" :src="avatarUrl" style="width: 100%;height: 100%; border-radius: 45px;background-color: #000000;"></image>
+								</view>
+								<view class="qiun-charts-bottom-right" @tap.prevent="showModal" data-target="bottomModal">
+									<image src="/static/weightEdit.png" class="png-size-34" mode="aspectFit"></image>
+								</view>
+							</view>
+						</view>
+
+						<view class="cu-modal bottom-modal" :class="modalName == 'bottomModal' ? 'show' : ''">
+							<view class="cu-dialog" style=" border-top-right-radius: 20rpx; border-top-left-radius: 20rpx;">
+								<myPicker :pickerObj="pickerObj" @confirmEvent="onConfirm" @cancelEvent="hideModal"></myPicker>
+							</view>
+						</view>
+
+						<view class="card-view">
+							<!-- 累计消耗和计划 -->
+							<view class="flex margin-top-sm margin-bottom-sm justify-center">
+								<view class=" padding-sm margin-right plan-l-tip-view flex align-center">
+									<image src="/static/middlePlant.png" class="data-png-26 margin-sm" mode="aspectFit"></image>
+									<view class="flex justify-start flex-direction">
+										<text style="text-align: start; line-height: 24px; font-weight: 400;">累计消耗</text>
+										<view class="text-11px " style="text-align: start;font-weight: 400; line-height: 28px;">{{ planData.cumulativeCalorie }}/ka</view>
+										<view class="text-gray" style="font-size: 10px;">始于{{ planData.startTime }}</view>
+									</view>
+
+								</view>
+								<view style="height: 56px; width: 1rpx;margin-top: 16px; background-color: #EEEEEE;"></view>
+								<view class="padding-sm margin-left-xs margin-right-xl plan-r-tip-view  flex align-center">
+
+									<image src="/static/middleDay.png" class="data-png-26 margin-sm" mode="aspectFit"></image>
+									<view class="flex justify-start flex-direction">
+										<text style="text-align: start; line-height: 24px;font-weight: 400;">剩余天数</text>
+										<view class="text-11px " style="text-align: start;font-weight: 400;line-height: 28px;">{{ remainingDays }}/day</view>
+										<view class="text-gray" style="font-size: 10px;">计划天数{{ days }}</view>
+									</view>
+								</view>
+							</view>
+						</view>
+
+						<!-- 添加设备部分 -->
+						<view class="card-view">
+							<view class="text-left padding margin-xs flex justify-between">
+								<text class="text-black text-15px  margin-left">我的设备</text>
+								<!-- <view @tap="onNavToMore" class="flex  text-center justify-center align-center  margin-right">
+									<text class="text-gray text-11px">查看更多</text>
+									<image style="margin-left: 6rpx; width: 24rpx;height: 22rpx;" src="/static/right-g.png"></image>
+								</view> -->
+
+							</view>
+							<!-- 绑定的设备列表 拳击柱-->
+							<!-- <view class="container-device">
+								<view class="width-device flex align-center" v-for="(item, index) in DeviceBindingList" :key="index" @tap="onBindingDevice(item, index)"
+								 :data-index="index" :id="'bing-'+item.ename">
+
+									<view style="position: relative; height: 100%;">
+										<image :src="index == cIndex ? '/static/deviceBg.png' : '/static/deviceBg_off.png'" class="data-png-64" mode="aspectFit"></image>
+										<image :src="index == cIndex ?item.icon:item.mIcon" class="data-png-add" mode="aspectFit"></image>
+									</view>
+
+									<view class="flex-sub text-center">
+										<image :src="index == cIndex ? '/static/wifi_on.png' : '/static/wifi_off.png'" class="data-png-32" mode="aspectFit"></image>
+										<view class="text-gray">{{ item.cname }}</view>
+									</view>
+								</view>
+								<view id="QRDeviceView" class="width-device flex align-center" @tap="openQRCode">
+									<view style="position: relative;height: 100%;">
+										<image src="/static/deviceBg.png" class="data-png-64" mode="aspectFit"></image>
+										<image src="/static/deviceAdd.png" class="data-png-add" mode="aspectFit"></image>
+									</view>
+
+									<view class="flex-sub text-center">
+										<view class="text-gray">扫码添加设备</view>
+									</view>
+								</view>
+							</view> -->
+							<!-- 开启手机加速计和陀螺仪数据 -->
+							<!-- <view class="container-device" id="openAccGyroView">
+								<view class="width-device flex align-center" v-for="(item, index) in DeviceBindingList" @tap="onBindingDevice(item, 0)"
+								 :key="'key-'+index" :id="'bing-'+item.ename">
+
+									<view style="position: relative; height: 100%;">
+										<image :src="ConnectBindingDevice? '/static/deviceBg.png' : '/static/deviceBg_off.png'" class="data-png-64"
+										 mode="aspectFit"></image>
+										<image :src="ConnectBindingDevice?item.icon:item.mIcon" class="data-png-add" mode="aspectFit"></image>
+									</view>
+
+									<view class="flex-sub text-center">
+										<image :src="ConnectBindingDevice? '/static/wifi_on.png' : '/static/wifi_off.png'" class="data-png-32" mode="aspectFit"></image>
+										<view class="text-gray">{{ item.cname }}</view>
+									</view>
+								</view>
+							</view> -->
+							<!-- 隐藏设备处 -->
+							<view class="container-device">
+								<view class="width-device flex align-center" v-for="(item, index) in BLEDeviceShowList" :key="index" @tap="onDevice(item, $event)"
+								 :data-index="index">
+									<view style="position: relative; height: 100%;">
+										<image :src="index == cIndex ? '/static/deviceBg.png' : '/static/deviceBg_off.png'" class="data-png-64" mode="aspectFit"></image>
+										<image :src="item.mIcon" class="data-png-add" mode="aspectFit"></image>
+									</view>
+
+									<view class="flex-sub text-center">
+										<image :src="index == cIndex ? '/static/wifi_on.png' : '/static/wifi_off.png'" class="data-png-32" mode="aspectFit"></image>
+										<view class="text-gray">{{ item.cname }}</view>
+									</view>
+
+									<view style="position: absolute;right: 0;top: 0;" @tap.stop="onCloseDevice(item, $event)" :data-index="index">
+										<image :src="index == cIndex ? '/static/d_on.png' : '/static/d_off.png'" class="data-png-26" mode="aspectFit"></image>
+									</view>
+								</view>
+								<view id="addDeviceView" class="width-device flex align-center" @tap="openDeviceList">
+									<view style="position: relative;height: 100%;">
+										<image src="/static/deviceBg.png" class="data-png-64" mode="aspectFit"></image>
+										<image src="/static/deviceAdd.png" class="data-png-add" mode="aspectFit"></image>
+									</view>
+
+									<view class="flex-sub text-center">
+										<view class="text-gray">添加设备</view>
+									</view>
+								</view>
+							</view>
+
+						</view>
+
+						<!-- 游戏推荐 -->
+						<view class="card-view" v-if="ConnectBindingDevice || (cIndex != -1 && versionCodeState&&versionCodeState.showGame && gameList.length !== 0)">
+							<view class="text-left padding margin-xs flex justify-between">
+								<text class="text-black text-15px margin-left">游戏推荐</text>
+								<view data-type="game" @tap="onNavToGameMore" class="flex text-center justify-center align-center margin-right">
+									<view class="text-gray text-11px " style=" line-height: 12px; ">查看更多</view>
+									<image style="margin-left: 6rpx; width: 24rpx;height: 22rpx; " src="/static/right-g.png"></image>
+								</view>
+							</view>
+							<view class="cu-item shadow">
+								<view class="cu-form-group margin-top">
+									<view class="grid col-3 homepage-grid-square flex-sub ">
+										<view v-for="(item, index) in gameList" :key="index" @tap="onNavDetail(item)">
+											<image class="item-img" :src="item.gamePicture" mode="aspectFill"></image>
+											<view class="border text-center">{{ item.gameName }}</view>
+										</view>
+									</view>
+								</view>
+							</view>
+
+							<!-- <view @tap="onNavToGameMore" class="flex  text-center justify-center align-center padding-lg make-text-bPurple solid-top margin text-15px text-bold">
+								查看更多
+								<image style="margin-left: 20rpx; width: 28rpx;height: 28rpx;" src="../../../static/right-d.png"></image>
+							</view> -->
+						</view>
+						<!-- <button class="margin" @click="onWriteBLEConnectionValue({value:'V'})">设备版本</button> -->
+						<!-- <button class="margin" @click="openAcc">开启手机加速计和方向传感器</button> -->
+						<!-- <button class="margin" @click="closeAcc">关闭手机加速计和方向传感器</button> -->
+						<!-- <button class="margin" @click="openGyro">开启手机加速计和方向传感器</button> -->
+						<!-- <button class="margin" @click="stopGyro">关闭手机加速计和方向传感器</button> -->
+						<!-- <button class="margin" @click="getBLEDeviceServices">getBLEDeviceServices</button> -->
+
+						<!-- <keyboard-listener @keydown="onKeyDown"></keyboard-listener> -->
+						<!-- 	<button type="primary" @click="testAsyncFunc">testAsyncFunc</button>
+						<button type="primary" @click="startSyncFunc">startSyncFunc</button>
+						<button type="primary" @click="stopSyncFunc">stopSyncFunc</button> -->
+						<!-- 视频推荐 -->
+						<view class="card-view" v-if="ConnectBindingDevice || (cIndex != -1 && versionCodeState&&versionCodeState.showVideo && videoList.length !== 0)">
+							<view class="text-left padding margin-xs flex justify-between">
+								<text class="text-black text-15px margin-left">视频推荐</text>
+								<view data-type="video" @tap="onNavToGameMore" class="flex text-center justify-center align-center margin-right">
+									<view class="text-gray text-11px " style=" line-height: 12px; ">查看更多</view>
+									<image style="margin-left: 6rpx; width: 24rpx;height: 22rpx; " src="/static/right-g.png"></image>
+								</view>
+							</view>
+							<view class="cu-item shadow">
+								<view class="cu-form-group margin-top">
+									<view class="grid col-3 homepage-grid-square flex-sub ">
+										<view v-for="(item, index) in videoList" :key="index" @tap="onNavDetail(item)">
+											<image class="item-img" :src="item.gamePicture" mode="aspectFill"></image>
+											<view class="border text-center">{{ item.gameName }}</view>
+										</view>
+									</view>
+								</view>
+							</view>
+
+						</view>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+
+		<!-- 右下角导航栏 -->
+		<round-menu @trigger="onRoundTrigger"></round-menu>
+
+		<!-- 侧边栏 -->
+		<sideBar ref="sideBar"></sideBar>
+
+		<!-- 训练卡 -->
+		<view class="cu-modal" :class="modalName == 'sportCompletion' ? 'show' : ''">
+
+			<view style="
+			position: relative; 
+			width: 586rpx;
+			height: 766rpx;
+			background-color: #FFFFFF; 
+			border-radius: 25px;
+			display: inline-block;
+			vertical-align: middle;
+			margin-left: auto;
+			margin-right: auto;
+			overflow: hidden;">
+				<view style="position: relative; width: 100%; height: 328rpx;">
+					<image style="position: absolute;top: 0;left: 0; width: 100%;height: 100%;" src="../../../static/sidebar_top_bg.png"></image>
+					<view class="flex flex-direction justify-around align-center" style="position: relative; height: 100%;">
+						<view class="text-white">已在哔嘣健身训练了</view>
+						<view class="text-white"><span style="font-size: 43px;">{{sportData.time}}</span> 分钟</view>
+						<view class="text-white">本次达标率{{sportData.percent}}%</view>
+					</view>
+				</view>
+				<view class="flex justify-around">
+					<view class="flex flex-direction justify-around align-center" style="position: relative; height: 162rpx;">
+						<view class="text-grey">消耗</view>
+						<view class="text-grey"><span style="font-size: 18px; color: #000000;">{{sportData.calorie}}</span> 卡</view>
+					</view>
+					<view class="flex flex-direction justify-around align-center" style="position: relative; height: 162rpx;">
+						<view class="text-grey">踩中</view>
+						<view class="text-grey"><span style="font-size: 18px; color: #000000;">{{sportData.hit}}</span> 次</view>
+					</view>
+					<view class="flex flex-direction justify-around align-center" style="position: relative; height: 162rpx;">
+						<view class="text-grey">失误</view>
+						<view class="text-grey"><span style="font-size: 18px; color: #000000;">{{sportData.miss}}</span> 次</view>
+					</view>
+				</view>
+				<view class="flex flex-direction justify-around align-center margin-top-sm">
+					<view style="position: relative; width: 500rpx; border:1rpx solid #EEEEEE ;"></view>
+				</view>
+				<view class="flex flex-direction justify-around align-center" style="height: 230rpx;">
+					<view class="text-black text-16px">非常优秀,继续加油!</view>
+					<view class="flex justify-center align-center text-white make-bg-bPurple round text-16px" style="width: 300rpx;height: 80rpx;"
+					 @tap="hideModal">确定</view>
+				</view>
+			</view>
+		</view>
+		<!-- :class="modalName == 'jumpAnimation' ? 'show' : ''" -->
+		<view class="cu-modal " :class="modalName == 'jumpAnimation' ? '' : ''">
+
+			<view style="
+			position: relative; 
+			width: 586rpx;
+			height: 400rpx;
+			background-color: #FFFFFF; 
+			border-radius: 4px;
+			display: inline-block;
+			vertical-align: middle;
+			margin-left: auto;
+			margin-right: auto;
+			overflow: hidden;">
+				<view style="height: 100%;display: flex;justify-content: center;align-items: center;">
+					<character></character>
+				</view>
+			</view>
+		</view>
+
+		<!-- 引导蒙层 bGuidePages guideCurrent-->
+		<code-elf-guide ref="codeElfGuide" v-if="bGuidePages" @hide="guideHide" @change="onGuideChange" :current="guideCurrent"
+		 :currentMode="currentMode"></code-elf-guide>
+
+		<!-- <view v-if="bStartBoxingPost" class="CountDownMask">
+			{{BoxingPostCountDownText}}
+		</view> -->
+
+		<view class="cu-modal " :class="modalName=='showPlanTipModal'?'show':''" @touchmove.stop.prevent="moveBoxingHandle">
+			<view class="cu-bind-modal">
+				<view style="position: absolute; top: 0; left: 0; width: 100%; height:100%;">
+					<image style="position: absolute;top: 0;left: 0; width: 100%;height: 100%;" src="/static/modelBg.png"></image>
+				</view>
+				<view class="flex flex-direction justify-between " style="position: relative; height: 100%;">
+					<view class="flex justify-around justify-center align-center" style="margin: 170rpx 30rpx 0 30rpx;">
+						<view style="width: 80rpx;height: 2rpx;border-radius: 2px; background-color: #cbcdcf;"></view>
+						<view class="make-text-bPurple" style=" font-size: 20px;">提示</view>
+						<view style="width: 80rpx;height: 2rpx;border-radius: 2px;background-color: #cbcdcf;"></view>
+					</view>
+					<view class="text-16px" style="align-self: center; max-width: 200px; word-break: break-all;">{{planTip[planTipIndex]}}</view>
+
+					<view class="flex justify-around align-center" style=" border-top: 1rpx solid #EEEEEE; margin-bottom: 2px;">
+						<view class="flex justify-center align-center  text-16px" style="width: 100%;height: 123rpx;" @tap="hidePlanTipModal">取消</view>
+						<view style="height: 123rpx;width: 1px;background-color: #EEEEEE;"></view>
+						<view class="flex justify-center align-center  text-16px" style="width: 100%;height: 123rpx;" @tap="confirmPlanTipModal">确定</view>
+					</view>
+				</view>
+
+
+			</view>
+		</view>
+
+		<ModalTip ref='modalTipRef' :class="modalName=='showModalTip'?' show':''" @hide="onModalTipHide" @confirm="onModalTipConfirm"></ModalTip>
+
+	</view>
+</template>
+
+<script>
+	import uniNavBar from '@/components/uni-nav-bar/uni-nav-bar.vue';
+	import uCharts from '@/components/u-charts/u-charts.js';
+	import myPicker from '@/components/slambb-picker/slambb-picker.vue';
+	import pickerData from '@/components/slambb-picker/picker.js';
+	import date from '@/util/util-js/date.js';
+	import sideBar from '@/components/side-bar/side-bar.vue';
+
+	import reqUtil from '@/util/util-js/requstUtil.js';
+	import config from '@/common/config.js';
+
+	import uniCountDown from '@/components/uni-count-down/uni-count-down.vue'
+
+	import elect from "@/components/electAni/electAnimation.vue"
+	import character from "@/components/electAni/character.vue"
+	import fruit from "@/components/fruitMachine/fruitMachine.vue"
+
+	import promptBox from "@/components/prompt-box/prompt-box.vue"
+
+	import roundMenu from "@/components/round-menu/round-menu.vue"
+	import codeElfGuide from '@/components/code-elf-guide/code-elf-guide.vue'
+
+	import boxingPost from "@/components/modal/boxing-post/boxing-post.vue"
+
+	import boxingHit from "@/components/modal/boxing-hit/boxing-hit.vue"
+	
+	import actionJump from "@/components/modal/action-jump/action-jump.vue"
+
+	import AccAndOri from "@/util/util-js/AccAndOri.js"
+
+	import AvatarConfig from "@/util/util-js/avatar.js"
+
+	import HitEffect from "@/components/effectHit/hitEffect.vue"
+	import HitFistEffect from "@/components/effectHit/hitFistEffect.vue"
+
+	import ModalTip from "@/components/modal-tip/modalTip.vue"
+
+	import keyboardListener from '@/components/keyboard-listener/keyboard-listener.vue'
+
+	// 获取 module 
+	// var testModule = uni.requireNativePlugin("MyAttitude")
+	// const modal = uni.requireNativePlugin('modal');
+
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+
+	var _self;
+	var canvaArcbar1;
+	var canvaLineA = null;
+	var sportSpeedInterval = null;
+	var personalAcc = null;
+
+	export default {
+		computed: mapState(['bCanvasShow', 'forcedLogin', 'hasLogin', 'userName', 'avatarUrl', 'days', 'remainingDays',
+			'signature', 'weight', 'height', 'planData', 'BLEDeviceShowList', 'BLEConnectDevice', 'bPlanExpired',
+			'bPlanFinish',
+			'bGuidePages',
+			'globalAcc', 'globalOri', 'DeviceBindingList', 'ConnectBindingDevice', 'cIndex', 'bNewGuide', 'localSportTime',
+			'currentModeIndex', 'oldArcbarProCalorie', 'oldArcbarAllCalorie', 'bOpenBluetooth', 'bOpenSuccess',
+			'bListenAdapterStateChange', 'bConnection', 'bVerifiedConnection', 'currentInstruction', 'instructionState',
+			'LocationGameUrl',
+			'bPhoneMatched',
+			'versionCodeState',
+			'platform'
+		]),
+		components: {
+			uniNavBar,
+			myPicker,
+			sideBar,
+			uniCountDown,
+			elect,
+			character,
+			fruit,
+			roundMenu,
+			codeElfGuide,
+			boxingPost,
+			boxingHit,
+			promptBox,
+			HitEffect,
+			HitFistEffect,
+			ModalTip,
+			keyboardListener,
+			
+			actionJump
+		},
+
+		data() {
+			return {
+				title: 'pk模式', //pk模式 健身模式
+				modalName: null,
+				originalDate: '', //记录new date
+				currentDate: '', //当前日期
+				cWidthArcbar: '', //圆弧进度图
+				cHeightArcbar: '', //圆弧进度图
+				arcbarWidth: '', //圆弧进度图,进度条宽度,此设置可使各端宽度一致
+				pixelRatio: 1,
+				// textarea: '',
+				// arcbarImagePath: '/static/logo.png',
+				cWidth: '',
+				cHeight: '',
+				scrollviewHight: '',
+				// 顶部区域部分
+				topScrollHight: '',
+				// 选择器
+				pickerObj: {},
+				// lineAImagePath: '/static/logo.png',
+				// visible: true,
+				// indicatorStyle: `height: ${Math.round(uni.getSystemInfoSync().screenWidth / (750 / 100))}px;`,
+				//设备列表
+				deviceList: [{
+					name: '蹦床',
+					icon: '/static/trampoline.png'
+				}],
+				cState: 1,
+				//游戏列表
+				gameList: [],
+				//视频列表,现在视频是和游戏一起管理
+				videoList: [],
+				//运动数据
+				sportData: {
+					calorie: 0,
+					hit: 0,
+					miss: 0,
+					percent: 0,
+					time: 0,
+					allData: 0
+				},
+
+				//设置滚动栏高度
+				scrollTop: 0,
+				//scroll view 跳转到对应的组件上
+				toView: '',
+				guideCurrent: 0,
+
+				bHide: false,
+
+				//屏幕抖动
+				bEFHitShake: false,
+				bStartBoxingPost: false,
+				BoxingPostCountDownText: 3,
+				b_countDown: null,
+
+				countDownUrl: [
+					"/static/personal/audio/GO.mp3",
+					"/static/personal/audio/1.mp3",
+					"/static/personal/audio/2.mp3",
+					"/static/personal/audio/3.mp3"
+				],
+				threeUrl: "/static/personal/audio/3.mp3",
+				twoUrl: "/static/personal/audio/2.mp3",
+				oneUrl: "/static/personal/audio/1.mp3",
+				goUrl: "/static/personal/audio/GO.mp3",
+
+				dangdang: "/static/personal/audio/dangdang.mp3",
+				personalAudioContext: null,
+
+				planTip: [
+					'您今天的目标已经达成,是否进行自由训练.',
+					'您今天的目标还没完成,是否结束训练.'
+				],
+				planTipIndex: 0,
+
+				//匹配的ai信息
+				aiObj: {
+					name: '匿名',
+					avatar: '/static/defaultAvatar.png'
+				},
+				aiOldObj: {
+					name: '匿名',
+					avatar: '/static/defaultAvatar.png'
+				},
+				currentMode: 'calorieMode', //pkMode calorieMode
+
+				bHitShake: false,
+
+				bAiHitShake: false,
+				//限制重连,比如去了对应硬件连接页面,限制这个页面的重连操作
+				bLimitReconnection: false,
+
+				/**
+				 * 首页这里连接了蓝牙,然后选择框回来后show会触发,触发时候检测一下是否有对应的
+				 * 匹配蓝牙
+				 */
+				bGetBondTesting: false,
+
+			};
+		},
+		onLoad() {
+			//设置self
+			_self = this;
+			// 圆形进度条样式
+			this.cWidthArcbar = uni.upx2px(480); //这里要与样式的宽高对应
+			this.cHeightArcbar = uni.upx2px(580); //这里要与样式的宽高对应
+			this.arcbarWidth = uni.upx2px(24);
+			// 体重数据样式
+			this.cWidth = uni.upx2px(750);
+			this.cHeight = uni.upx2px(300);
+			// 心电图数据样式
+			this.eWidth = uni.upx2px(464);
+			this.eHeight = uni.upx2px(140);
+			// #ifdef APP-PLUS || H5
+			//监听
+			uni.$on('personalShowLineA', this.personalShowLineA);
+			uni.$on('updateArcbarData', this.updateArcbarData);
+			// #endif
+			// #ifdef MP
+			this.personalShowLineA();
+			// #endif
+
+			//监听
+			uni.$on('callbackCloseBLE', this.callbackCloseBLE);
+			// uni.$on('callbackBLEState', this.callbackBLEState);
+
+			//获得游戏列表
+			reqUtil
+				.requestData(config.URL.GAMERECOMMENDBYPLATFORM, {
+					recommendType: 2,
+					endTime: config.endTime
+				})
+				.then(
+					res => {
+						console.log('GAMERECOMMEND =====', res);
+						if (res.code == 0) {
+							if (res.data.gameList.length > 3) {
+								this.gameList = this.gameList.concat(res.data.gameList.slice(0, 3));
+							} else {
+								this.gameList = this.gameList.concat(res.data.gameList);
+							}
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+			//获得视频列表
+			reqUtil
+				.requestData(config.URL.GAMERECOMMENDBYPLATFORM, {
+					recommendType: 1,
+					endTime: config.endTime
+				})
+				.then(
+					res => {
+						if (res.code == 0) {
+							if (res.data.gameList.length > 3) {
+								this.videoList = this.videoList.concat(res.data.gameList.slice(0, 3));
+							} else {
+								this.videoList = this.videoList.concat(res.data.gameList);
+							}
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+
+			this.personalShowLineA();
+
+			//初始化后设置一下pickerObj
+			this.pickerObj = {
+				pickerLeftList: pickerData.getWeightList().leftList,
+				pickerRightList: pickerData.getWeightList().rightList,
+				pickerType: 'doubleItem',
+				pickerUnit: '公斤',
+				pickerTitle: '记体重',
+				defaultValue: this.weight,
+				showInput: true,
+			};
+
+
+			this.getPlanData(function() {
+				// 如果个人页面直接获取数据
+				_self.showArcbar();
+
+			});
+
+			this.testList = [{
+				cname: "拳击柱",
+				ename: "boxingPost",
+				icon: "/static/modal/boxing-post/left-hook-h@2x.png",
+				mIcon: "/static/modal/boxing-post/left-hook-m@2x.png",
+			}];
+
+			this.personalAudioContext = uni.createInnerAudioContext();
+			this.personalAudioContext.autoplay = false;
+			this.personalAudioContext.src = this.dangdang;
+			this.personalAudioContext.volume = 1;
+
+			//获取本地记录的运动时间
+			uni.getStorage({
+				key: 'localSportTime',
+				success: function(res) {
+					// console.log("本地的时间:",res.data);
+					_self.$store.state.localSportTime = res.data;
+				}
+			});
+
+			//获取设备信息,上报服务器
+			this.gOnAddClientInfo();
+
+		},
+		onShow() {
+			_self.bHide = false;
+
+			if (canvaArcbar1)
+				_self.updateArcbarData();
+
+			//this.bConnection && 
+			if (this.bVerifiedConnection && this.BLEConnectDevice) {
+				this.updateBLECIndex();
+
+				// setTimeout(() => {
+				// 	/**
+				// 	 * 如果是首页连接,则检测
+				// 	 */
+				// 	if (this.bGetBondTesting) {
+				// 		this.onGetBondDevice();
+				// 		this.bGetBondTesting = false;
+				// 	}
+				// }, 5000)
+
+			}
+			//如果是测试数据
+			if (this.ConnectBindingDevice) {
+				if (this.$refs.boxingPostRef) {
+					this.$refs.boxingPostRef.onSetMode('pkMode');
+				} else {
+					setTimeout(() => {
+						this.$refs.boxingPostRef.onSetMode('pkMode');
+					}, 500)
+				}
+			}
+
+			console.log('personal show');
+
+			this.bLimitReconnection = false;
+
+			//测试环境检测,给个modal提示 active
+			// if (config.active == 'dev') {
+			// 	function thanDate(date2) {
+			// 		var oDate1 = new Date();
+			// 		console.log("检测日期", oDate1);
+			// 		var oDate2 = new Date(date2);
+			// 		if (oDate1.getTime() > oDate2.getTime()) {
+			// 			return true;
+			// 		} else {
+			// 			return false;
+			// 		}
+			// 	}
+			// 	if (thanDate('2021-05-31 13:10:36')) {
+			// 		uni.showModal({
+			// 			title: "提示",
+			// 			content: "此版本为测试版本,有需要请和开发者联系。微信 sweetdontcry"
+			// 		})
+			// 	}
+			// }
+
+		},
+		onReady() {
+			// 计算屏幕剩余高度  填补剩余高度
+			uni.getSystemInfo({
+				success(res) {
+					_self.phoneHeight = res.windowHeight;
+					// 计算组件的高度
+					let view = uni.createSelectorQuery().select('#nav-bar');
+					view.boundingClientRect(data => {
+						// console.log('data===:', data);
+						if (data != null) {
+							_self.navHeight = data.height;
+							_self.scrollviewHight = _self.phoneHeight - _self.navHeight;
+							_self.topScrollHight = _self.phoneHeight - _self.navHeight - 30;
+						}
+					}).exec();
+				}
+			});
+
+		},
+		onUnload() {
+			console.log("personal ********* onUnload *********");
+			// #ifndef APP-PLUS||H5
+			//监听
+			console.log('移除监听');
+			uni.$off('personalShowLineA', this.personalShowLineA);
+			uni.$off('updateArcbarData', this.updateArcbarData);
+			// #endif
+			//*****注释蓝牙操作******
+			uni.$off('callbackCloseBLE', this.callbackCloseBLE);
+			// uni.$off('callbackBLEState', this.callbackBLEState);
+			uni.$off('updateBLEDeviceData', this.callbackUpdateBLEData);
+
+			// // 停掉对应的interval
+
+			if (sportSpeedInterval) {
+				clearInterval(sportSpeedInterval);
+				sportSpeedInterval = null;
+			}
+			//unload 时候清除timeout
+			this.onUnloadCreateBLEConnectionTimeout();
+
+		},
+		onHide() {
+			_self.bHide = true;
+			console.log("personal ******* onHide *******");
+			//时间暂停 ,隐藏了 需要判断是否为空
+			if (_self.$refs.countDownObj)
+				_self.$refs.countDownObj.timePause('pause');
+			//心电图暂停
+			if (_self.$refs.electRef)
+				_self.$refs.electRef.pausedElect(true);
+
+		},
+		methods: {
+			...mapMutations(['accountLogin', 'getPlanData', 'addlocalCalorie', 'setLocalCalorie', 'setShowCalorie',
+				'syncLocalDataToServer', 'syncRequestEvent', 'setLocalSportTime',
+				'initAdapter', 'onCreateBLEConnection', 'onUnloadCreateBLEConnectionTimeout', 'onCloseBLEConnection',
+				'gOnAddClientInfo', 'onWriteBLEConnectionValue',
+				'gCreateFilterObj', 'gUpdateFilter', 'B_GetBondedDevices', 'B_OpenBLESetting', 'B_OpenRopeSkipping',
+				'B_CloseRopeSkipping',
+				'gCreateSandbagAlgorithm', 'gUpdateSandbagAlgorithm', 'gStartSimulateBLEUpdate', 'gStopSimulateBLEUpdate'
+			]),
+			onKeyDown(e) {
+				console.log(e);
+			},
+			//登录的回调初始化
+			personalShowLineA() {
+
+				//获得体重列表
+				reqUtil.requestData(config.URL.USERGETWEIGHT).then(
+					res => {
+						// console.log('USERGETWEIGHT =====', res);
+						// this.$store.state.weight = res.data;
+						if (res.code == 0 && res.data) {
+							let list = [];
+							for (let i = 0; i < res.data.timestamp.length; i++) {
+								//String.fromCharCode(65 + i)
+								list.push(date.getWeightDate(res.data.timestamp[i]));
+							}
+
+							let lineData = {
+								// ["2012", "2013", "2014", "2015", "2016", "2017"]
+								categories: list,
+								series: [{
+									color: '#9797FF',
+									//["100", "10", "20", "50", "60", "70"]
+									data: res.data.weightList,
+									index: 0,
+									legendShape: 'curve',
+									name: '体重变化',
+									pointShape: 'circle',
+									show: true,
+									type: 'area'
+								}]
+							};
+							_self.showLineA('canvasLineA', lineData);
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+			},
+
+			showClickEvent() {
+				this.$refs.sideBar.showModal();
+				this.$store.state.bCanvasShow = false;
+			},
+			showModal(e) {
+				this.modalName = e.currentTarget.dataset.target;
+				this.$store.state.bCanvasShow = false;
+			},
+			hideModal(e) {
+				if (this.modalName == "sportCompletion") {
+					console.log("关闭卡片");
+					this.sportData = {
+						calorie: 0,
+						hit: 0,
+						miss: 0,
+						percent: 0,
+						time: 0,
+						allData: 0,
+					}
+				}
+				this.modalName = null;
+				this.$store.state.bCanvasShow = true;
+			},
+
+			//获取体重数据
+			onConfirm(e) {
+				// detail.__args__[0]
+				console.log('当前输出的体重:', e);
+				//把体重传上服务器
+				reqUtil
+					.requestData(
+						config.URL.USERADDWEIGHT, {
+							weight: e.value
+						},
+						'POST'
+					)
+					.then(
+						res => {
+							// console.log('USERADDWEIGHT =====', res);
+							_self.$store.state.weight = res.data.currentWeight;
+							let listData = res.data.weightList;
+							let list = [];
+							for (let i = 0; i < listData.timestamp.length; i++) {
+								//String.fromCharCode(65 + i)
+								list.push(date.getWeightDate(listData.timestamp[i]));
+							}
+
+							let lineData = {
+								// ["2012", "2013", "2014", "2015", "2016", "2017"]
+								categories: list,
+								series: [{
+									color: '#9797FF',
+									data: listData.weightList,
+									index: 0,
+									legendShape: 'curve',
+									name: '体重变化',
+									pointShape: 'circle',
+									show: true,
+									type: 'area'
+								}]
+							};
+
+							canvaLineA.updateData(lineData);
+						},
+						e => {
+							console.log(e);
+						}
+					);
+				this.hideModal();
+			},
+			onTestAddLocalCalorie() {
+				let _add = (10 * 1.875) / (4 * 30);
+				console.log(_add);
+				this.onUpdateCaloriePlane(10);
+			},
+			// 进度条数据
+			arcbarData(_planData) {
+				let showCal = _planData.calorie,
+					showLCal = _planData.allCalorie,
+					LCalTip = '大卡',
+					showTip = '(未达标)';
+
+				// 如果运动的卡路里大于目标卡路里,设置为目标卡路里值,即为Max
+				if (showLCal >= showCal) {
+					showTip = '(达标)';
+				}
+
+				let series = [{
+					name: showTip,
+					data: _planData.allCalorie == 0 ? 0 : _planData.allCalorie / showCal,
+					color: '#2fc25b'
+				}];
+				return {
+					showCal,
+					showLCal,
+					LCalTip,
+					showTip,
+					series
+				}
+			},
+			// 圆形进度条
+			showArcbar() {
+				let {
+					showCal,
+					showLCal,
+					LCalTip,
+					series
+				} = this.arcbarData(_self.planData);
+				// console.log("series==", series[0]);
+				canvaArcbar1 = new uCharts({
+					$this: _self,
+					canvasId: 'canvasArcbar',
+					type: 'myArcbar',
+					fontSize: 11,
+					legend: {
+						show: false
+					},
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					series: series,
+					animation: true,
+					width: _self.cWidthArcbar,
+					height: _self.cHeightArcbar,
+					dataLabel: true,
+					//  Math.round(chartData.series[0].data * 100) + '%'
+					title: {
+						// arcbarDate: date.formatDate(_self.originalDate),
+						name: showLCal,
+						molecularUnit: LCalTip, //单位的分子部分
+						denominatorUnit: showCal, //单位的分母部分
+						unitFontSize: 11, //单位字符大小
+						color: 'rgba(255, 255, 255, 1)',
+						fontSize: 28,
+						offsetX: -30,
+						offsetY: 10
+					},
+					subtitle: {
+						name: series[0].name,
+						color: 'rgba(255, 255, 255, 1)',
+						fontSize: 13,
+						offsetY: -75
+					},
+					extra: {
+						arcbar: {
+							type: 'default',
+							backgroundColor: 'rgba(234, 234, 255, 1)',
+							backgroundEndColor: 'rgba(234, 234, 255, 1)',
+							backgroundMiddle: 'rgba(158, 158, 255, 1)',
+							width: _self.arcbarWidth, //圆弧的宽度
+							lineColor: 'rgba(255, 255, 255, 1)',
+							lineEndColor: 'rgba(233, 233, 255, 1)'
+						}
+					}
+				});
+
+				// 更新位置同步
+				this.syncLocalDataToServer((res) => {
+					this.originalDate = res.newDate;
+					this.currentDate = date.formatTime(res.newDate);
+					this.updateArcbarData();
+				});
+			},
+			updateArcbarData(data) {
+				// if (data == "plan") {
+				// 	// 加入设置的卡路里小于本地,则更新本地最小值
+				// 	_self.addlocalCalorie(0);
+				// 	console.log("**************updateArcbarData");
+				// 	// 如果是计划设置好后
+				// 	// this.$store.state.bPlanFinish = true;
+				// 	// setTimeout(() => {
+				// 	// 	this.$store.state.bPlanFinish = false;
+				// 	// }, 10000)
+				// }
+				// console.log("updateArcbarData:",this.planData);
+				let {
+					showCal,
+					showLCal,
+					LCalTip,
+					series
+				} = _self.arcbarData(_self.planData);
+
+				if (showCal == _self.oldArcbarProCalorie && showLCal == _self.oldArcbarAllCalorie) {
+					// console.log("没有改变值,不刷新表盘:", showCal, _self.oldArcbarProCalorie, showLCal, _self.oldArcbarAllCalorie);
+					return;
+				}
+				//这个是显示当前的总卡路里
+				_self.$store.state.oldArcbarAllCalorie = showLCal;
+				//这个是计划的卡路里
+				_self.$store.state.oldArcbarProCalorie = showCal;
+
+				canvaArcbar1.updateData({
+					series: series,
+					title: {
+						//这里的文案是自定义的,不写是不变的
+						name: showLCal,
+						molecularUnit: LCalTip, //单位的分子部分
+						denominatorUnit: showCal, //单位的分母部分
+					},
+					subtitle: {
+						//这里的文案是自定义的,不写是不变的
+						name: series[0].name
+					}
+				});
+			},
+			//没有限制下的更新表盘
+			updateNoLimit() {
+				let {
+					showCal,
+					showLCal,
+					LCalTip,
+					series
+				} = _self.arcbarData(_self.planData);
+
+				//这个是显示当前的总卡路里
+				_self.$store.state.oldArcbarAllCalorie = showLCal;
+				//这个是计划的卡路里
+				_self.$store.state.oldArcbarProCalorie = showCal;
+
+				canvaArcbar1.updateData({
+					series: series,
+					title: {
+						//这里的文案是自定义的,不写是不变的
+						name: showLCal,
+						molecularUnit: LCalTip, //单位的分子部分
+						denominatorUnit: showCal, //单位的分母部分
+					},
+					subtitle: {
+						//这里的文案是自定义的,不写是不变的
+						name: series[0].name
+					}
+				});
+			},
+			// 数据列表
+			showLineA(canvasId, chartData) {
+				canvaLineA = new uCharts({
+					$this: _self,
+					canvasId: canvasId,
+					type: 'area',
+					fontSize: 11,
+					padding: [15, 40, 0, 15],
+					legend: {
+						show: false,
+						padding: 0,
+						lineHeight: 10,
+						margin: 0
+					},
+					dataLabel: true,
+					dataPointShape: true,
+					dataPointShapeType: 'solid',
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					categories: chartData.categories,
+					series: chartData.series,
+					animation: true,
+					enableScroll: true, //开启图表拖拽功能
+					enableBottomSolid: false,
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 7,
+						calibration: true,
+						scrollShow: false,
+						scrollAlign: 'left',
+						gridColor: 'rgba(175, 175, 175, 1)',
+						dashLength: 8
+						// boundaryGap: 'justify' //两端不留白配置
+					},
+					yAxis: {
+						// disabled: false,
+						disableGrid: true,
+						disableLine: true,
+						splitNumber: 10,
+						min: 0,
+						// max: 50,
+						format: val => {
+							// console.log("=======",val)
+							// return val.toFixed(0) + '斤'
+							return '';
+						}
+					},
+					width: _self.cWidth,
+					height: _self.cHeight,
+					extra: {
+						area: {
+							type: 'straight', //curve
+							opacity: 1,
+							addLine: true,
+							gradient: true,
+							width: 2
+						}
+					}
+				});
+
+			},
+			touchLineA(e) {
+				// console.log("touchLineA:", e);
+				if (canvaLineA) canvaLineA.scrollStart(e);
+			},
+			moveLineA(e) {
+				if (canvaLineA) {
+					canvaLineA.scroll(e);
+				}
+			},
+			touchEndLineA(e) {
+				if (canvaLineA) {
+					canvaLineA.scrollEnd(e);
+				}
+			},
+			// 跳转计划页面
+			openPlan(e) {
+				// console.log(e);
+				uni.navigateTo({
+					url: '../plan/plan?newsid=' + 11,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+			// 跳转转换页面
+			onNavConver() {
+				uni.reLaunch({
+					url: '../../conversion-page/conversion/conversion',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			// 跳转我的页面
+			onNavMyPage() {
+				uni.navigateTo({
+					url: '../../my-page/homepage/homepage',
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+			updateBLECIndex() {
+				for (let i = 0; i < this.BLEDeviceShowList.length; i++) {
+					let eq = this.BLEDeviceShowList[i];
+					if ((eq.ename.indexOf("mobilePhoneBandage") > -1 && this.BLEConnectDevice.id == 0) ||
+						(eq.ename.indexOf("hotman") > -1 && this.BLEConnectDevice.id == 1) ||
+						(eq.ename.indexOf("BLEHandle") > -1 && this.BLEConnectDevice.id == 2) ||
+						(eq.ename.indexOf("rope") > -1 && this.BLEConnectDevice.id == 3)) {
+
+						eq.bRatio = true;
+						this.$store.state.cIndex = i;
+
+					}
+
+					if (eq.ename.indexOf("hotman") > -1 && this.BLEConnectDevice.id == 1) {
+						if (this.$refs.boxingPostRef) {
+							this.$refs.boxingPostRef.onSetMode('pkMode');
+						} else {
+							setTimeout(() => {
+								this.$refs.boxingPostRef.onSetMode('pkMode');
+							}, 500)
+						}
+
+					} else if (eq.ename.indexOf("BLEHandle") > -1 && this.BLEConnectDevice.id == 2) {
+						if (this.$refs.boxingPostRef) {
+							this.$refs.boxingPostRef.onSetMode('calorieMode');
+						} else {
+							setTimeout(() => {
+								this.$refs.boxingPostRef.onSetMode('calorieMode');
+							}, 500)
+						}
+					} else if (eq.ename.indexOf("rope") > -1 && this.BLEConnectDevice.id == 3) {
+						//todo 暂时设置兼容跑步模式
+						if (this.$refs.boxingPostRef) {
+							this.$refs.boxingPostRef.onSetMode('ropeMode');
+						} else {
+							setTimeout(() => {
+								this.$refs.boxingPostRef.onSetMode('ropeMode');
+							}, 500)
+						}
+					}
+				}
+			},
+
+			//蓝牙断开连接时候
+			callbackCloseBLE() {
+				// this.$store.state.cIndex = -1;
+				//蓝牙断开连接后,直接关闭
+				this.$refs.boxingPostRef.onCloseDevices();
+
+				// if (!this.BLEConnectDevice) {
+				// 	console.log('连接蓝牙对象为空,不进行重连!');
+				// 	return;
+				// }
+				// //如果限制不走重连
+				// if (this.bLimitReconnection) return;
+				// //连接蓝牙
+				// this.onCreateBLEConnection({
+				// 	item: this.BLEConnectDevice,
+				// 	initItem: false,
+				// 	getSuccess: () => {
+				// 		this.updateBLECIndex();
+
+				// 		if (this.bHide) {
+				// 			//弹出框时候,是隐藏状态
+				// 			this.bGetBondTesting = true;
+				// 		} else {
+				// 			//没有弹出框时候,直接检测
+				// 			setTimeout(() => {
+				// 				this.onGetBondDevice();
+				// 			}, 5000)
+				// 		}
+				// 	},
+				// 	getinitAdapter: () => {
+				// 		// this.onDevice(item, e);
+				// 		// console.log("未开启蓝牙模块?");
+				// 	}
+				// });
+			},
+			//蓝牙状态回调
+			callbackBLEState(res) {
+				console.log("callbackBLEState==", res);
+				if (this.cState != res.state) this.cState = res.state;
+			},
+			//设备回调事件
+			callbackUpdateBLEData(data) {
+				//如果在监听状态时候隐藏页面,返回
+				if (_self.bHide) return;
+				// console.log("callbackDeviceState==", data);
+
+				if (this.ConnectBindingDevice) {
+					this.gUpdateSandbagAlgorithm({
+						data: data,
+						callback: (res) => {
+							if (res.type == 'hit') {
+								this.$refs.boxingPostRef.onBLEHotmanUpdate(res);
+							}
+						}
+					});
+					return;
+				}
+
+				//连接了手柄模式
+				//没有开启指令不刷新
+				if (!this.instructionState.bOpen) return;
+
+				if (this.BLEConnectDevice.usageMode == "hotman") {
+					this.gUpdateFilter({
+						data: data,
+						callback: (res) => {
+							if (res.type == 'hit') {
+								this.$refs.boxingPostRef.onBLEHotmanUpdate(res);
+							}
+						}
+					});
+				} else if (this.BLEConnectDevice.usageMode == "general") {
+					//这个是普通打击模式
+					this.$refs.boxingPostRef.onBLEHandleUpdate(data);
+				} else if (this.BLEConnectDevice.usageMode == "ropeSkipping") {
+					//跳绳蓝牙反馈
+					let _data = {
+						jump: 1
+					}
+					this.$refs.boxingPostRef.onBLERopeUpdate(_data);
+
+				}
+
+
+			},
+			//绑定设备函数
+			onBindingDevice(item, index) {
+				if (item == null) {
+					item = this.DeviceBindingList[0];
+				}
+				if (this.BLEConnectDevice) {
+					uni.showToast({
+						icon: "none",
+						title: "已连接硬件设备",
+						duration: 1000
+					})
+					return;
+				}
+
+				if (this.ConnectBindingDevice) {
+					this.$store.state.ConnectBindingDevice = null;
+					setTimeout(() => {
+						uni.showToast({
+							icon: "none",
+							title: "断开连接",
+							duration: 1000
+						})
+					}, 300)
+				} else {
+					this.$store.state.ConnectBindingDevice = item;
+					setTimeout(() => {
+						uni.showToast({
+							icon: "none",
+							title: "已连接",
+							duration: 1000
+						})
+					}, 300)
+					//连接后保存最近连接的设备
+				}
+
+				//刷新状态
+				this.$refs.boxingPostRef.onSetMode('pkMode');
+
+			},
+			//关闭设备函数
+			onCloseBindingDevice(item, e) {
+				if (e.currentTarget.dataset.index == this.cIndex) {
+					uni.showModal({
+						title: '设备状态',
+						content: '是否断开连接',
+						ConfirmColor: '#A488DC',
+						success: res => {
+							if (res.confirm) {
+								this.$store.state.cIndex = -1;
+								this.$store.state.ConnectBindingDevice = null;
+							}
+						}
+					});
+				}
+			},
+			onNavBindingDevice() {
+				this.toView = "addDeviceView";
+			},
+			onDevice(item, e) {
+				if (this.ConnectBindingDevice) {
+					uni.showToast({
+						title: '当前已开启数据',
+						icon: 'none',
+						mask: true
+					})
+					return;
+				}
+				if (this.cIndex !== -1) {
+					uni.showToast({
+						title: '当前已连接设备',
+						icon: 'none',
+						mask: true
+					})
+					return;
+				}
+				//连接蓝牙
+				this.onCreateBLEConnection({
+					item: item,
+					index: e.currentTarget.dataset.index,
+					initItem: true,
+					getinitAdapter: () => {
+						this.onDevice(item, e);
+					},
+					getSuccess: () => {
+						if (this.bHide) {
+							//弹出框时候,是隐藏状态
+							this.bGetBondTesting = true;
+						} else {
+							//没有弹出框时候,直接检测
+							// setTimeout(() => {
+							// 	this.onGetBondDevice();
+							// }, 5000)
+						}
+
+						//刷新状态
+						if (this.cIndex != -1) {
+							let eq = this.BLEDeviceShowList[this.cIndex];
+							// console.log(eq,this.BLEConnectDevice);
+							if (eq.ename.indexOf("hotman") > -1 && this.BLEConnectDevice.id == 1) {
+								this.$refs.boxingPostRef.onSetMode('pkMode');
+							} else if (eq.ename.indexOf("BLEHandle") > -1 && this.BLEConnectDevice.id == 2) {
+								this.$refs.boxingPostRef.onSetMode('calorieMode');
+							} else if (eq.ename.indexOf("rope") > -1 && this.BLEConnectDevice.id == 3) {
+								this.$refs.boxingPostRef.onSetMode('ropeMode');
+							}
+						}
+					}
+				});
+			},
+			/**
+			 * 检测获取匹配的设备
+			 */
+			onGetBondDevice() {
+				/**
+				 * 假如手机没有匹配,断开连接
+				 */
+				console.log("****", this.BLEConnectDevice);
+				if (!this.BLEConnectDevice) return;
+
+				this.B_GetBondedDevices({
+					deviceId: this.BLEConnectDevice.deviceId,
+					success: (bondedDevice) => {
+						// console.error("===========", bondedDevice);
+						// uni.hideToast();
+						if (bondedDevice == null) {
+							// if (plus.os.name == 'Android') 
+							{
+								//此问题 华为手机容易出现
+								//android手机已配对的设备 不存在,但是app 又直接连接成功了。提示,并且断开app连接
+								//1.关闭当前连接
+								this.onCloseBLEConnection({
+									getSuccess: () => {}
+								});
+								uni.hideToast();
+								//2.跳转蓝牙设置
+								uni.showModal({
+									title: '蓝牙配对失败',
+									content: '请跳转后点击配对BGBox_2020,成功后手动跳转回哔蹦重新连接。',
+									success: (res) => {
+										if (res.confirm) {
+											this.B_OpenBLESetting();
+										}
+									}
+								})
+							}
+						}
+					}
+				});
+
+			},
+
+			openDeviceList(e) {
+
+				if (this.ConnectBindingDevice) {
+					uni.showToast({
+						title: '当前已开启数据',
+						icon: 'none',
+						mask: true
+					})
+					return;
+				}
+
+				//先判断蓝牙是否初始化
+				/**
+				 * 蓝牙部分操作,转全局变量操作
+				 * */
+				console.log("openDeviceList bOpenBluetooth", this.bOpenBluetooth);
+				// #ifdef APP-PLUS
+				if (!this.bOpenBluetooth) {
+
+					this.initAdapter(() => {
+						uni.navigateTo({
+							// url: '../devices-category/devices-category',
+							url: '../devices-hardware/devices-hardware',
+							success: res => {
+								this.bLimitReconnection = true;
+							},
+							fail: () => {},
+							complete: () => {}
+						});
+					});
+
+					return;
+				}
+				// #endif
+				uni.navigateTo({
+					url: '../devices-hardware/devices-hardware',
+					success: res => {
+						this.bLimitReconnection = true;
+					},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onNavToMore() {
+				uni.navigateTo({
+					url: '../more/more?index=' + this.cIndex,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+			onAddDevice() {
+				let deviceItem = {
+					name: '蹦床',
+					icon: '/static/trampoline.png'
+				};
+				if (this.deviceList.length != 0) {
+					this.deviceList = this.deviceList.concat(deviceItem);
+				} else {
+					this.deviceList = deviceItem;
+				}
+			},
+			onCloseDevice(item, e) {
+				//如果不是连接状态,则删除
+				if (e.currentTarget.dataset.index != this.cIndex) {
+					if (this.cIndex != -1) {
+						uni.showToast({
+							icon: 'none',
+							title: "请先断开已连接设备",
+							duration: 2000,
+							mask: true
+						})
+						return;
+					}
+					uni.showModal({
+						title: '设备状态',
+						content: '是否删除设备?',
+						ConfirmColor: '#A488DC',
+						success: res => {
+							if (res.confirm) {
+								this.$store.commit('deleteBLEDevice', e.currentTarget.dataset.index);
+							}
+						}
+					});
+					return;
+				}
+				uni.showModal({
+					title: '设备状态',
+					content: '是否断开连接?',
+					/**
+					 * 如果需要强制,不显示取消按钮
+					 */
+					showCancel: true,
+					ConfirmColor: '#A488DC',
+					success: res => {
+						if (res.confirm) {
+							this.onCloseBLEConnection({
+								getSuccess: () => {}
+							});
+
+						}
+					}
+				});
+			},
+
+			onNavDetail(item) {
+				console.log(item);
+				let temItem = encodeURIComponent(JSON.stringify(item));
+				// return;
+				uni.navigateTo({
+					url: '../../game-page/game-detail/game-detail?item=' + temItem
+				});
+			},
+			onNavToGameMore(e) {
+
+				uni.reLaunch({
+					url: '../../game-page/game/game?type=' + e.currentTarget.dataset.type
+				});
+			},
+			
+			//判断是否有其他限制
+			onStartCheck() {
+				//#ifdef H5
+				// 直接走测试,如果是h5
+				this.onBoxingGuideFinish();
+				return;
+				//#endif
+				//分类型判断
+				if (0 === this.currentModeIndex) {
+					//拳击运动类型
+					// 1.检测是否有对应设备,没有ConnectBindingDevice,再进行下一步
+					if (this.ConnectBindingDevice == null) {
+						uni.showToast({
+							title: '开启连接数据',
+							icon: 'none'
+						})
+						this.toView = "openAccGyroView";
+						return;
+
+					}
+					// TODO,目前去掉蓝牙设备
+					// //2.检测是否有设备
+					// if (this.BLEDeviceShowList.length == 0) {
+					// 	this.$store.state.bGuidePages = true;
+					// 	this.guideCurrent = 3;
+					// 	uni.showToast({
+					// 		title: '请添加蓝牙设备',
+					// 		icon: 'none'
+					// 	})
+					// 	this.toView = "addDeviceView";
+					// 	return;
+					// }
+					// //2.检测是否连接设备 || this.BLEConnectDevice.ename !== 'BT04'
+					// if (this.cIndex == -1) {
+					// 	//没有连接设备,提示去连接设备
+					// 	uni.showToast({
+					// 		title: '请连接蓝牙设备',
+					// 		icon: 'none'
+					// 	})
+					// 	this.toView = "addDeviceView";
+					// 	return;
+					// }
+
+				}
+
+
+				//3.检测一下计划日期
+				console.log(this.remainingDays);
+				if (this.planData.startTime > this.planData.endTime || this.remainingDays == 0) {
+					if (!this.$store.state.bPlanExpired) {
+						this.$store.state.bPlanExpired = true;
+						setTimeout(() => {
+							this.$store.state.bPlanExpired = false;
+						}, 3000)
+						uni.showToast({
+							title: "计划到期,请制定计划。",
+							icon: 'none'
+						})
+					}
+
+					this.$store.state.bGuidePages = true;
+					setTimeout(() => {
+						this.$refs.codeElfGuide.setCurrent(0);
+					}, 0)
+					this.toView = "projectButtonView";
+					return;
+				}
+
+				if (0 === this.currentModeIndex) {
+
+					//如果新手,调用新手教程
+					console.log("this.bNewGuide:", this.bNewGuide);
+					// this.$store.state.bNewGuide = true;
+					if (this.bNewGuide) {
+						// this.$refs.boxingPostRef.onGuideBoxingPostPlay();
+						// 拳击的新手提示
+						this.$store.state.bGuidePages = true;
+						this.guideCurrent = 5;
+						this.toView = "boxingHitID";
+						this.$store.state.bNewGuide = false;
+					} else {
+						if (this.ConnectBindingDevice) {
+							//假如有连接bingding设备
+							this.gCreateSandbagAlgorithm();
+							this.gStartSimulateBLEUpdate();
+						} else {
+							//todo 跳绳模式 发送开启指令
+							if (this.BLEConnectDevice.usageMode == "ropeSkipping") {
+								//打开跳绳模式
+								this.B_OpenRopeSkipping();
+							} else {
+								//初始化filter快速打击对象
+								if (this.BLEConnectDevice.usageMode == "hotman") {
+									this.gCreateFilterObj();
+								}
+								//打开加速计
+								this.onWriteBLEConnectionValue({
+									value: "3"
+								});
+
+								setTimeout(() => {
+									//设置加速计b:20ms a:10ms
+									this.onWriteBLEConnectionValue({
+										value: config.refreshRate
+									});
+
+								}, 1000)
+							}
+
+						}
+
+						//监听蓝牙回调
+						uni.$on('updateBLEDeviceData', this.callbackUpdateBLEData);
+
+
+						this.onBoxingGuideFinish();
+					}
+
+				}
+			},
+			onShowBoxingHitTip() {
+				this.$store.state.bGuidePages = true;
+				this.guideCurrent = 5;
+				this.toView = "boxingHitID";
+				this.$store.state.bNewGuide = false;
+			},
+			//检测是否符合要求,没有的话进行新手提示
+			onPersonalCheck() {
+				// //判断一下,是否达标,给moadal 提示 
+				// if (this.planData.allCalorie >= this.planData.calorie) {
+				// 	this.modalName = 'showPlanTipModal';
+				// 	this.planTipIndex = 0;
+				// } else {
+				// 	//如果是一开始,还没达标,就不给modal 提示
+				// 	this.onStartCheck();
+				// }
+				this.onStartCheck();
+			},
+			//
+			onBoxingGuideFinish() {
+
+				if (this.b_countDown) {
+					clearInterval(this.b_countDown);
+					this.b_countDown = null;
+				}
+
+
+				if (this.currentMode == 'calorieMode' || this.currentMode == 'ropeMode') {
+					this.personalAudioContext.stop();
+					this.personalAudioContext.play();
+
+					setTimeout(() => {
+						this.$refs.boxingPostRef.onBoxingPostPlay(true);
+					}, 600);
+				} else {
+					this.BoxingPostCountDownText = 3;
+					this.$refs.boxingPostRef.onSetRingAnimation(true);
+					uni.showToast({
+						title: '匹配中...',
+						mask: true,
+						icon: 'loading',
+						duration: 2000
+					})
+
+					setTimeout(() => {
+						//ai信息
+						this.onGetAiRandom();
+
+						// this.b_countDown = setInterval(() => {
+
+						// 	if (this.BoxingPostCountDownText <= 1) {
+						// 		if (this.b_countDown) {
+						// 			clearInterval(this.b_countDown);
+						// 			this.b_countDown = null;
+						// 		}
+						// 		setTimeout(() => {
+						// 			this.personalAudioContext.stop();
+						// 			this.personalAudioContext.play();
+						// 			this.$refs.boxingPostRef.onBoxingPostPlay(true);
+						// 			this.$refs.boxingPostRef.onSetRingAnimation(false);
+						// 			uni.hideToast();
+						// 		}, 800)
+						// 	}
+						// 	this.BoxingPostCountDownText--;
+						// }, 1000)
+						setTimeout(() => {
+							this.personalAudioContext.stop();
+							this.personalAudioContext.play();
+							this.$refs.boxingPostRef.onBoxingPostPlay(true);
+							this.$refs.boxingPostRef.onSetRingAnimation(false);
+							uni.hideToast();
+						}, 800)
+					}, 2000);
+
+				}
+
+
+			},
+			//运动时间
+			onUpdateSportTime(res) {
+				// console.log("同步的运动时间",res);
+				this.setLocalSportTime(res);
+			},
+
+			//更新运动数据
+			onUpdateCaloriePlane(data) {
+
+				// 记录卡路里到本地
+				this.addlocalCalorie(data);
+
+				this.updateArcbarData();
+			},
+
+			onRoundTrigger(data) {
+				// console.log("onRoundTrigger==", data);
+				// return;
+				let url = '';
+				switch (data.item.type) {
+					case "personal":
+						//个人中心页面
+						url = '../../personal-page/personal/personal';
+						break;
+					case "game":
+						url = '../../game-page/game/game';
+						break;
+					default:
+						url = '../../personal-page/personal/personal';
+						break;
+				}
+				uni.reLaunch({
+					url: url,
+					success: res => {},
+					fail: () => {},
+					complete: () => {}
+				});
+			},
+
+			/**
+			 * 同步本地数据到服务器
+			 */
+			onSyncData() {
+				this.syncRequestEvent({
+					success: () => {
+						this.updateArcbarData();
+					}
+				});
+				// 更新显示日期
+				this.originalDate = new Date();
+				this.currentDate = date.formatTime(this.originalDate);
+			},
+			hidePlanTipModal() {
+				this.modalName = null;
+				if (this.planTipIndex === 1) {
+					// 您今天的目标还没完成  是否结束训练
+					this.onBoxingPause(false);
+				}
+			},
+			confirmPlanTipModal() {
+				this.modalName = null;
+				if (this.planTipIndex === 0) {
+					this.onStartCheck()
+				} else if (this.planTipIndex === 1) {
+					// 您今天的目标还没完成  是否结束训练
+					this.onBoxingPause(true);
+				}
+			},
+			//断开连接时候,关闭
+			onCloseBoxingHit() {
+				console.log('关闭训练');
+				if (this.currentMode == 'pkMode') {
+					this.$refs.hitEffectRef.onStop();
+				}
+				this.onBoxingPause(true);
+			},
+			//点击暂停时候,判断一下是否完成目标
+			onBoxingPostControlPlay(bPlay) {
+				if (!bPlay) {
+
+					if (this.planData.allCalorie < this.planData.calorie) {
+						this.modalName = 'showPlanTipModal';
+						this.planTipIndex = 1;
+					} else {
+						//假如完成了目标,更新卡路里
+						this.onBoxingPause(true);
+					}
+				}
+			},
+			//点击切换模式
+			onModeEvent(data) {
+				console.log("当前模式:", data);
+				this.currentMode = data.mode;
+				this.title = data.name;
+
+				if (this.currentMode == 'calorieMode' || this.currentMode == 'ropeMode') {
+					setTimeout(() => {
+						this.updateNoLimit();
+					}, 0)
+
+				}
+			},
+			onAiHitEvent(bloodPoint) {
+
+				// this.onPlay({
+				// 	bloodPoint: num,
+				// 	createType: 'red',
+				// 	callback: (res) => {
+				// 		console.log("红色拳头击中对方:", res);
+				// 	}
+				// });
+				this.$refs.hitFistRef.onPlay({
+					bloodPoint: bloodPoint,
+					createType: 'red',
+					callback: () => {
+						if (this.bAiHitShake) return;
+						this.bAiHitShake = true;
+						this.$refs.aiHitEffectRef.onPlay();
+						this.$refs.aiHitEffectRef.onAIHit();
+						setTimeout(() => {
+							this.bAiHitShake = false;
+						}, 500)
+					}
+				});
+
+
+			},
+			//打击时候头像修改
+			onHitEvent(bloodPoint) {
+				// console.log("this.bHitShake:",this.bHitShake);
+
+				this.$refs.hitFistRef.onPlay({
+						bloodPoint: bloodPoint,
+						createType: 'blue',
+						callback: () => {
+							if (this.bHitShake) return;
+							this.bHitShake = true;
+							this.$refs.hitEffectRef.onPlay();
+							this.$refs.hitEffectRef.onMyHit();
+							setTimeout(() => {
+								this.bHitShake = false;
+							}, 500)
+						}
+					}
+
+				);
+			},
+
+			//弹出目标提示后,进行下一步
+			onBoxingPause(bFinish) {
+				if (bFinish) {
+
+					if (this.ConnectBindingDevice) {
+						this.gStopSimulateBLEUpdate();
+					} else {
+						if (this.BLEConnectDevice.usageMode == "ropeSkipping") {
+							this.B_CloseRopeSkipping();
+						} else {
+							//停止蓝牙加速计
+							this.onWriteBLEConnectionValue({
+								value: "4"
+							});
+						}
+
+					}
+
+
+
+					uni.$off('updateBLEDeviceData', this.callbackUpdateBLEData);
+
+					console.log("停止时候,上传卡路里");
+					this.$refs.boxingPostRef.onBoxingPostStop();
+
+					this.syncRequestEvent({
+						success: () => {
+							this.updateArcbarData();
+						}
+					});
+
+					//停止时候,重置ai信息
+					this.aiObj.name = this.aiOldObj.name;
+					this.aiObj.avatar = this.aiOldObj.avatar;
+
+				} else {
+					//如果不是,继续调用播放
+					this.$refs.boxingPostRef.onBoxingPostPlay(true);
+				}
+
+			},
+
+			/**
+			 * 新手任务引导
+			 */
+			onGuideChange(e) {
+				let tempCurrent = e.detail.current;
+				if (tempCurrent == 1) {
+					_self.toView = "addDeviceView";
+				} else if (tempCurrent == 0) {
+					_self.toView = "projectButtonView";
+				}
+
+			},
+
+			guideHide(e) {
+				this.$store.state.bGuidePages = false;
+				if (e.current == 0 && !e.onlyHide) {
+					//跳转计划页面
+					this.openPlan();
+				} else if (e.current == 1 && !e.onlyHide) {
+					console.log('guideHide:', e.current);
+					//跳转搜索设备页面
+					// this.openDeviceList();
+				} else if (e.current == 3 && !e.onlyHide) {
+					//新手引导跳转扫码页面,直接走绑定 再check
+					// this.openQRCode((res) => {
+					// 	setTimeout(() => {
+					// 		this.onPersonalCheck();
+					// 	}, 200);
+					// });
+					// 跳转连接蓝牙页面
+					this.openDeviceList();
+				} else if (e.current == 4 && !e.onlyHide) {
+					//连接绑定设备
+					// this.openQRCode();
+					console.log(e);
+					// this.testList[e.dataset.index] DeviceBindingList
+					let _index = Number(e.device.dataset.index);
+					this.onBindingDevice(this.DeviceBindingList[_index], _index);
+
+					//连接设备后,再
+					setTimeout(() => {
+						this.onPersonalCheck();
+					}, 200);
+				} else if (e.current == 5 && !e.onlyHide) {
+					console.log("==:", e);
+					//todo 跳绳模式 新手引导
+					if (this.BLEConnectDevice.usageMode == "ropeSkipping") {
+						this.B_OpenRopeSkipping();
+					} else {
+						//初始化filter快速打击对象
+						if (this.BLEConnectDevice.usageMode == "hotman") {
+							this.gCreateFilterObj();
+						}
+						//打开加速计
+						this.onWriteBLEConnectionValue({
+							value: "3"
+						});
+
+						setTimeout(() => {
+							//设置加速计b:20ms a:10ms
+							this.onWriteBLEConnectionValue({
+								value: config.refreshRate
+							});
+
+						}, 1000)
+					}
+
+					//监听蓝牙回调
+					uni.$on('updateBLEDeviceData', this.callbackUpdateBLEData);
+					this.onBoxingGuideFinish();
+				}
+			},
+
+			mainScroll(e) {
+				if (_self.toView == "addDeviceView") {
+					_self.toView = "";
+					if (!_self.bGuidePages) return;
+					let view = uni.createSelectorQuery().select('#addDeviceView');
+					view.boundingClientRect(data => {
+						_self.$refs.codeElfGuide.setDeviceObj(data);
+					}).exec();
+				} else if (_self.toView == "projectButtonView") {
+					_self.toView = "";
+					if (!_self.bGuidePages) return;
+					_self.onGetProjectView();
+				} else if (_self.toView == "QRDeviceView") {
+					_self.toView = "";
+					if (!_self.bGuidePages) return;
+					let view = uni.createSelectorQuery().select('#QRDeviceView');
+					view.boundingClientRect(data => {
+						_self.$refs.codeElfGuide.setDeviceObj(data);
+					}).exec();
+				} else if (_self.toView == "bing-boxingPost") {
+					_self.toView = "";
+					if (!_self.bGuidePages) return;
+					let view = uni.createSelectorQuery().select('#bing-boxingPost');
+					view.boundingClientRect(data => {
+						_self.$refs.codeElfGuide.setDeviceObj(data);
+
+						console.log(data);
+					}).exec();
+				} else if (_self.toView == "boxingHitID") {
+					_self.toView = "";
+
+					// let view = uni.createSelectorQuery().select('#boxingHitID');
+					// view.boundingClientRect(data => {
+					// 	_self.$refs.codeElfGuide.setModalObj(data);
+
+					// 	console.log(data);
+					// }).exec();
+				} else if (_self.toView == "openAccGyroView") {
+					_self.toView = "";
+				}
+			},
+
+			onGetProjectView() {
+				let view = uni.createSelectorQuery().select('#projectButtonView');
+				view.boundingClientRect(data => {
+					_self.$refs.codeElfGuide.setProjectObj(data);
+				}).exec();
+			},
+
+			//拳击模块的回调
+			boxingUpdateCalorie(calorie) {
+				if (this.currentMode != 'pkMode') {
+					//这里调用一下设置可以播放音效
+					this.$refs.personalFruitRef.onCanPlay();
+				}
+
+				this.onUpdateCaloriePlane(calorie);
+
+
+			},
+			//扫码添加设备
+			openQRCode(callback) {
+				let that = this;
+				// 允许从相机和相册扫码
+				uni.scanCode({
+					success: function(res) {
+						// console.log('条码类型:' + res.scanType);
+						// console.log('条码内容:' + res.result);
+						let obj = JSON.parse(res.result)
+						let data = {
+							type: obj.type,
+							uuid: obj.uuid,
+						}
+					}
+				});
+			},
+
+			//屏幕抖动
+			onScreenShake() {
+				this.bEFHitShake = true;
+				setTimeout(() => {
+					this.bEFHitShake = false;
+				}, 500)
+			},
+
+			onGetAiRandom() {
+				let _self = this;
+
+				let avatarlist = AvatarConfig.getAvatarList().avatarList;
+				let _length = avatarlist.length;
+				let _index = Math.floor(Math.random() * _length);
+
+				console.log(avatarlist);
+
+				_self.aiObj.name = avatarlist[_index].name;
+				_self.aiObj.avatar = avatarlist[_index].url;
+			},
+			onBoxingGameOver(res) {
+				this.$refs.hitEffectRef.onStop();
+
+				this.onBoxingPause(true);
+
+				let _title = res.myWin ? "胜利" : "失败";
+				let _context = res.myWin ? "你已经赢得PK胜利!" : "你在PK中被打败了!";
+				this.modalName = "showModalTip"
+
+				this.$refs.modalTipRef.setShowData({
+					title: _title,
+					context: _context
+				});
+			},
+			onModalTipHide() {
+				this.modalName = null;
+
+			},
+			onModalTipConfirm() {
+				this.modalName = null;
+				//再来一局
+			},
+			onTestShare() {
+				uni.share({
+					provider: "weixin",
+					scene: "WXSenceTimeline",
+					type: 2,
+					imageUrl: "https://img-cdn-qiniu.dcloud.net.cn/uniapp/images/uni@2x.png",
+					success: function(res) {
+						console.log("success:" + JSON.stringify(res));
+					},
+					fail: function(err) {
+						console.log("fail:" + JSON.stringify(err));
+					}
+				});
+			},
+			openAcc() {
+				if (!this.globalAcc) {
+					AccAndOri.bindAcc((accId) => {
+						this.$store.state.globalAcc = accId;
+						console.log("初始化:globalAcc=", this.globalAcc);
+					});
+				}
+
+				if (!this.globalOri) {
+					AccAndOri.bindOri((oriId) => {
+						this.$store.state.globalOri = oriId;
+						console.log("初始化:globalOri=", this.globalOri);
+					});
+				}
+			},
+			closeAcc() {
+				AccAndOri.unBindAcc(this.globalAcc);
+				this.$store.state.globalAcc = null;
+
+				AccAndOri.unBindOri(this.globalOri);
+				this.$store.state.globalOri = null;
+			},
+			outGyro(o) {
+				console.log("Orientation\nAlpha:" + o.alpha + "\nBeta:" + o.beta + "\nGamma:" + o.gamma);
+			},
+			openGyro() {
+				if (!this.globalOri) {
+					AccAndOri.bindOri((oriId) => {
+						this.$store.state.globalOri = oriId;
+						console.log("初始化:globalOri=", this.globalOri);
+					});
+				}
+				uni.$on('watchOrientation', this.outGyro);
+			},
+			stopGyro() {
+				uni.$off('watchOrientation', this.outGyro);
+				AccAndOri.unBindOri(this.globalOri);
+				this.$store.state.globalOri = null;
+			},
+
+			onKeyInput: function(event) {
+				this.$store.state.LocationGameUrl = event.target.value
+			},
+
+			onNavFcGame() {
+				// console.log(0);
+				uni.navigateTo({
+					url: "../../fc-page/fc/fc"
+				})
+			},
+
+			onNavAppInfo() {
+				uni.navigateTo({
+					url: '../../info-page/app-info/app-info'
+				})
+			},
+
+			getBLEDeviceServices() {
+				console.log("getBLEDeviceServices");
+
+				// uni.getBLEDeviceServices({
+				// 	deviceId: "C5:5C:19:04:00:30",
+				// 	success: res => {
+				// 		console.log("getBLEDeviceServices==", JSON.stringify(res));
+				// 	},
+				// 	fail: failRes => {
+				// 		console.log('device services:', failRes)
+
+				// 	}
+				// });
+			},
+
+			// testAsyncFunc() {
+			// 	// 调用异步方法
+			// 	testModule.testAsyncFunc({
+			// 			'name': 'unimp',
+			// 			'age': 1
+			// 		},
+			// 		(ret) => {
+			// 			modal.toast({
+			// 				message: ret,
+			// 				duration: 1.5
+			// 			});
+			// 		})
+			// },
+			// startSyncFunc() {
+			// 	// 调用同步方法
+			// 	var ret = testModule.onStartAccAndGyro({
+			// 		'name': 'unimp',
+			// 		'age': 1
+			// 	})
+			// 	modal.toast({
+			// 		message: ret,
+			// 		duration: 1.5
+			// 	});
+			// },
+
+			// stopSyncFunc() {
+			// 	// 调用同步方法
+			// 	var ret = testModule.onStopAccAndGyro({
+			// 		'name': 'unimp',
+			// 		'age': 1
+			// 	})
+			// 	modal.toast({
+			// 		message: ret,
+			// 		duration: 1.5
+			// 	});
+			// },
+
+		}
+	};
+</script>
+
+<style>
+	.bg-person {
+		background-color: #9797ff;
+	}
+
+	.plan-view {
+		overflow: hidden;
+		background-color: #9797ff;
+	}
+
+	.plan-l-tip-view {
+		border-radius: 80upx 0 0 80upx;
+		background-color: rgba(255, 255, 255, 0.05);
+	}
+
+	.plan-r-tip-view {
+		border-radius: 0 80upx 80upx 0;
+		background-color: rgba(255, 255, 255, 0.05);
+	}
+
+	.bottom-view {
+		background-color: rgba(246, 243, 249, 255);
+		padding-bottom: 20rpx;
+		border-radius: 80rpx 80rpx 0 0;
+		width: 100%;
+		overflow: hidden;
+	}
+
+	.time-view {
+		width: 100%;
+		margin-top: 53rpx;
+		/* border: 1rpx solid #DD514C; */
+	}
+
+	/*样式的width和height一定要与定义的cWidth和cHeight相对应*/
+	.qiun-charts-arcbar {
+		/* padding: 20rpx 15rpx; */
+		height: 556rpx;
+		position: relative;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.charts-arcbar {
+		position: absolute;
+		/* margin-left: 81upx;
+		 */
+		left: 0;
+		right: 0;
+		top: 0;
+		/* bottom: 0; */
+		margin: auto;
+		width: 556upx;
+		height: 556upx;
+		/* border: 1rpx solid #FFFFFF; */
+	}
+
+	.charts-arcbar-img {
+		position: absolute;
+		left: 135upx;
+		width: 480upx;
+		height: 480upx;
+	}
+
+	.charts-pring-bottom {
+		position: relative;
+		width: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+
+	}
+
+	.charts-pring-button {
+		width: 178rpx;
+		height: 64rpx;
+		display: flex;
+		flex-direction: row;
+		justify-content: start;
+		align-items: center;
+		border-radius: 0 25px 25px 0;
+	}
+
+	/* 心电图 */
+	/* .qiun-charts-elect {
+		width: 500rpx;
+		height: 136rpx;
+	} */
+
+	.charts-elect {
+		width: 464rpx;
+		height: 96rpx;
+		border: 1rpx solid #000000;
+	}
+
+	.e-button {
+		background-color: rgba(255, 255, 255, 0.25);
+		border-radius: 45px;
+		margin: 5px 12px;
+		box-shadow: 1px 1px 3px #888888;
+		display: flex;
+		justify-content: center;
+	}
+
+	/* 曲线图 */
+	.qiun-charts-area {
+		width: calc(750rpx - 40rpx);
+		height: 300upx;
+		/* background-color: #007AFF; */
+		position: relative;
+	}
+
+	.charts-area {
+		position: absolute;
+		width: 750upx;
+		height: 300upx;
+	}
+
+	.qiun-charts-bottom-container {
+		height: 63px;
+		position: relative;
+		width: 100%;
+		justify-content: center;
+		align-items: center;
+		display: flex;
+		flex-direction: row;
+	}
+
+
+	.qiun-charts-bottom-right {
+		position: absolute;
+		left: calc(50% + 50rpx);
+		top: 15px;
+		margin-left: 20rpx;
+	}
+
+	/* picker */
+	.mpvue-picker-view {
+		width: calc(50% - 5px);
+		height: 300px;
+		/* background-color: rgba(255, 255, 255, 1); */
+		border-radius: 20px;
+	}
+
+	.item {
+		text-align: center;
+		width: calc(100% - 0px);
+		background-color: rgba(255, 255, 255, 1);
+		height: 88upx;
+		line-height: 88upx;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		font-size: 40upx;
+	}
+
+	.picker-unit {
+		position: absolute;
+		right: 70px;
+		top: 43%;
+	}
+
+	.left-button,
+	.right-button {
+		margin: 20px 0;
+		padding: 10px 30px;
+		background-color: #ffffff;
+	}
+
+	.left-button {
+		border-top-left-radius: 20px;
+		border-bottom-left-radius: 20px;
+		border-right: 1px solid #e6e6e6;
+	}
+
+	.right-button {
+		border-top-right-radius: 20px;
+		border-bottom-right-radius: 20px;
+	}
+
+	.png-size-28 {
+		width: 24px;
+		height: 24px;
+		margin-bottom: 4px;
+	}
+
+	.png-size-32 {
+		width: 32px;
+		height: 32px;
+	}
+
+	.png-size-34 {
+		width: 34px;
+		height: 34px;
+	}
+
+	/* 图标大小 */
+	.data-play {
+		width: 16px;
+		height: 16px;
+		margin-top: 10rpx;
+	}
+
+	.p-data-png {
+		width: 16px;
+		height: 16px;
+		margin: 5rpx 20rpx;
+	}
+
+	.data-png {
+		width: 16px;
+		height: 16px;
+		margin: 5rpx;
+	}
+
+	.data-png-20 {
+		width: 20px;
+		height: 20px;
+		margin: 0 14rpx;
+	}
+
+	.data-png-54 {
+		width: 54px;
+		height: 54px;
+		margin: 0 14rpx;
+	}
+
+	.data-png-add {
+		position: absolute;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		margin: auto;
+		width: 34px;
+		height: 37px;
+	}
+
+	.time-container {
+		margin-top: 13px;
+		width: 100%;
+		height: 218rpx;
+		position: relative;
+		/* border: 1rpx solid #007AFF; */
+	}
+
+	.time-png {
+		width: 503rpx;
+		height: 222rpx;
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		z-index: 1;
+	}
+
+	.time-text {
+		font-size: 9px;
+		z-index: 10;
+		position: relative;
+		height: 100%;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		color: #FFFFFF;
+	}
+
+	.padding {
+		padding: 10rpx;
+	}
+
+	.logo {
+		height: 200rpx;
+		width: 200rpx;
+		margin-top: 200rpx;
+		margin-left: auto;
+		margin-right: auto;
+		margin-bottom: 50rpx;
+	}
+
+	.float-png {
+		position: absolute;
+		right: 15px;
+		bottom: 200px;
+		width: 56px;
+		height: 56px;
+	}
+
+	.moveCanvas {
+		position: fixed;
+		top: 9999rpx;
+		left: 0;
+		width: 188rpx;
+		height: 188rpx;
+	}
+
+	.scroll-class {
+		width: 100%;
+		overflow-x: hidden;
+		box-sizing: border-box;
+		/* border: 1rpx solid #000000; */
+	}
+
+	.homepage-grid-square {
+		width: 250rpx;
+		/* height: 250rpx; */
+		align-items: start;
+	}
+
+	.homepage-grid-square image {
+		width: 176rpx;
+		height: 176rpx;
+	}
+
+	.border {
+		/* width: 176rpx; */
+		font-size: 30rpx;
+		color: rgba(175, 175, 175, 1);
+		font-weight: 400;
+		text-align: center;
+		margin-top: 22rpx;
+		margin-bottom: 40rpx;
+	}
+
+	.item-img {
+		border-radius: 20rpx;
+		/* border: 1rpx solid #EEEEEE; */
+		box-shadow: 0px 1px 2px 0px rgba(113, 113, 219, 0.23);
+	}
+
+	.plan-Tip-child {
+		height: 120rpx;
+	}
+
+	.plan-mode-tip {
+		height: 90rpx;
+	}
+
+	.plan-grid-square {
+		width: 250rpx;
+		/* height: 250rpx; */
+		align-items: start;
+	}
+
+	.plan-grid-square image {
+		width: 168rpx;
+		height: 58rpx;
+	}
+
+	.plan-mode {
+		/* height: 54px; */
+		border-radius: 10px;
+		padding: 3px;
+		margin: 0 5px 10px 5px;
+		border: 1rpx solid #eeeeee;
+		/* box-shadow: 0px 1px 2px 0px rgba(113, 113, 219, 0.23); */
+		position: relative;
+	}
+
+	.plan-mode-selected {
+		/* height: 54px; */
+		padding: 3px;
+		margin: 0 5px 10px 5px;
+		background-size: contain;
+		background-clip: border-box;
+		background-repeat: no-repeat;
+		background-image: url(../../../static/plan-select-bg.png);
+		/* box-shadow: 0px 1px 2px 0px rgba(113, 113, 219, 0.23); */
+		position: relative;
+	}
+
+	.plan-mode-border {
+		/* width: 176rpx; */
+		font-size: 26rpx;
+		color: rgba(151, 151, 255, 1);
+		font-weight: 400;
+		text-align: center;
+	}
+
+	.button-fav {
+		background-color: rgba(153, 150, 252, 255);
+		color: #ffffff;
+		/* border-radius: 10px; */
+		/* width: 184rpx; */
+		height: 122rpx;
+		display: flex;
+		justify-content: center;
+		text-align: center;
+		align-items: center;
+		font-size: 14px;
+	}
+
+	.card-view-small {
+		/* border: 1rpx solid #000000; */
+		width: 80%;
+		border-radius: 20px;
+		margin-left: 50rpx;
+		overflow: hidden;
+		background-color: #ffffff;
+		box-shadow: 0px 2px 4px 0px rgba(113, 113, 219, 0.23);
+	}
+
+	.right-bg {
+		/* border: 1rpx solid #000000; */
+		border-radius: 8px;
+		background-color: #9797ff;
+		padding: 15rpx;
+		position: absolute;
+		right: 5%;
+		margin-top: 4%;
+	}
+
+	.plan-small-child {
+		background-color: #f5f5ff;
+		border-radius: 20px;
+		width: 480rpx;
+		height: 90rpx;
+		margin: 0 0 30rpx 30rpx;
+		/* margin-top: 60rpx; */
+	}
+
+	.cu-btn-plan {
+		position: relative;
+		border: 0upx;
+		display: inline-flex;
+		align-items: center;
+		justify-content: center;
+		box-sizing: border-box;
+		padding: 4upx 25upx 4upx 4upx;
+		margin-left: 5px;
+		font-size: 22upx;
+		height: 64upx;
+		line-height: 1;
+		text-align: center;
+		text-decoration: none;
+		overflow: visible;
+		margin-left: initial;
+		transform: translate(0upx, 0upx);
+		margin-right: initial;
+	}
+
+	.cu-btn-plan-child {
+		position: relative;
+		border: 0upx;
+		display: inline-flex;
+		align-items: center;
+		justify-content: center;
+		box-sizing: border-box;
+		padding: 0 4upx;
+		font-size: 22upx;
+		height: 56upx;
+		line-height: 1;
+		text-align: center;
+		text-decoration: none;
+		overflow: visible;
+		margin-left: initial;
+		transform: translate(0upx, 0upx);
+		margin-right: initial;
+	}
+
+	.cu-btn-plan-right {
+		position: relative;
+		border: 0upx;
+		display: inline-flex;
+		align-items: center;
+		justify-content: center;
+		box-sizing: border-box;
+		padding: 4upx 4upx 4upx 19upx;
+		margin-left: 5px;
+		font-size: 22upx;
+		height: 64upx;
+		line-height: 1;
+		text-align: center;
+		text-decoration: none;
+		overflow: visible;
+		margin-left: initial;
+		transform: translate(0upx, 0upx);
+		margin-right: initial;
+	}
+
+	/* 粗线条 */
+	.line-make {
+		margin-top: 11px;
+		margin-left: 8px;
+		border: 4rpx solid #FFFFFF;
+		width: 152rpx;
+		border-radius: 3px;
+	}
+
+
+	/* 头像背景处理 */
+	.avatar-bg-personal {
+		width: 34px;
+		height: 34px;
+		border-radius: 45px;
+		border: 2px solid #9997fc;
+		background-color: #9997fc;
+		box-sizing: border-box;
+	}
+
+
+	.avatar-bg-arrow {
+		position: absolute;
+		top: 12px;
+		left: calc(50% - 10px);
+		border-left: 10px solid transparent;
+		border-right: 10px solid transparent;
+		border-bottom: 10px solid #9997fc;
+	}
+
+	.elect-round-image {
+		width: 48px;
+		height: 48px;
+		z-index: 10;
+		box-shadow: 1px 1px 3px #888888;
+		border-radius: 45px;
+	}
+
+	.elect-personal {
+		/* width: 100%; */
+		height: 120rpx;
+		/* margin: 50rpx 0; */
+		margin-bottom: 50rpx;
+		border-radius: 45px;
+		padding: 10rpx;
+		border: 1rpx solid rgba(255, 255, 255, 0.11);
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		position: relative;
+	}
+
+	/* 呼吸灯 */
+	.breathing-lamp {
+		animation-duration: 1s;
+		animation-timing-function: ease-out;
+		animation-fill-mode: inherit;
+		animation-iteration-count: infinite;
+		animation-name: run-lamp;
+		animation-play-state: running;
+	}
+
+	@keyframes run-lamp {
+
+		0%,
+		100% {
+			opacity: 1;
+			transform: scale(1);
+		}
+
+		50% {
+			opacity: 0.6;
+			transform: scale(0.9);
+		}
+
+	}
+
+	.personal-fruit-container {
+		position: absolute;
+		left: 0;
+		top: 0;
+		bottom: 0;
+		right: 0;
+		margin: auto;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		/* border: 1rpx solid #F0F0F0; */
+	}
+
+
+	.screen-jitter {
+		animation-duration: 1s;
+		animation-timing-function: ease-out;
+		animation-fill-mode: inherit;
+		animation-iteration-count: infinite;
+		animation-name: personal-shake;
+		animation-play-state: running;
+	}
+
+	.screen-red {
+		border: 1rpx solid #ff0000;
+	}
+
+	@keyframes personal-shake {
+
+		0%,
+		100% {
+			transform: translateX(0)
+		}
+
+		10% {
+			transform: translateX(-9px)
+		}
+
+		20% {
+			transform: translateX(8px)
+		}
+
+		30% {
+			transform: translateX(-7px)
+		}
+
+		40% {
+			transform: translateX(6px)
+		}
+
+		50% {
+			transform: translateX(-5px)
+		}
+
+		60% {
+			transform: translateX(4px)
+		}
+
+		70% {
+			transform: translateX(-3px)
+		}
+
+		80% {
+			transform: translateX(2px)
+		}
+
+		90% {
+			transform: translateX(-1px)
+		}
+	}
+
+	.CountDownMask {
+		position: absolute;
+		top: 0;
+		bottom: 0;
+		right: 0;
+		left: 0;
+		background-color: rgba(0, 0, 0, 0.5);
+		z-index: 1000;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 100px;
+		font-weight: bold;
+		color: #FFFFFF;
+	}
+</style>

+ 443 - 0
pages/personal-page/plan/plan.vue

@@ -0,0 +1,443 @@
+<template>
+	<view>
+		<uni-nav-bar id="nav-bar" status-bar="true" @clickLeft="onBack()" title="健身计划" color="#000000" fixed="true" :border="false">
+			<view slot="left">
+				<view class=" flex align-center margin-left">
+					<image class="p-left-arrow" src="../../../static/p-left-arrow.png"></image>
+				</view>
+			</view>
+
+		</uni-nav-bar>
+
+		<view class="card-view text-center">
+			<!-- @tap="showModal" data-target="showPickerModal" data-type="target_weight" -->
+			<view class="plan-w" style="margin-top: 34px;">
+				<view class="plan-w-child">
+					<image src="../../../static/plan_w_bg.png"></image>
+				</view>
+
+				<view class="plan-w-child">
+					<image class="plan-w-img" src="../../../static/plan_w.png"></image>
+					<view class="padding-sm make-text-bPurple text-11px">
+						<span style="font-size: 29px;">{{ currenWeight }}</span>
+						公斤
+					</view>
+					<view class="text-gray text-13px">累计减重</view>
+				</view>
+			</view>
+			<view class="plan-Tip flex justify-center align-center">
+				<view class="plan-Tip-child make-text-bPurple flex justify-center align-center">每天努力一点,离成功更近一步,加油!</view>
+			</view>
+		</view>
+
+		<view class="card-view flex-sub text-center bg-white margin-top">
+			<view class="plan-tagert flex justify-center align-center">
+				<view class="plan-tagert-child make-text-bPurple flex justify-start align-center">
+					<image class="avatar-img" :src="avatarUrl"></image>
+					<view class="flex flex-direction justify-between">
+						<view class="text-black text-bold padding-left-lg margin-xs" style="text-align: start;">每天目标</view>
+						<view class="flex text-gray border">
+							<view class="padding-left-lg margin-xs flex" style="position: relative; flex-shrink: 0; " @tap="showModal"
+							 data-target="showPickerModal" data-type="target_calorie">
+								<view class="make-text-bPurple text-xl margin-right-sm ">{{ currentPlanData.calorie}}</view>
+								<view>大卡</view>
+								<view class="only-arrow"></view>
+							</view>
+							<view class="padding-left-lg margin-xs flex" style="position: relative;flex-shrink: 0;" @tap="showModal"
+							 data-target="showPickerModal" data-type="target_minute">
+								<view class="make-text-bPurple text-xl margin-right-sm">{{ currentPlanData.sportTime }}</view>
+								<view>分钟</view>
+								<view class="only-arrow"></view>
+							</view>
+
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<view class="cu-bar bg-white">
+				<view class="action">
+					<image style="width: 42rpx;height: 42rpx; margin-right: 26rpx;" src="../../../static/plan_w.png"></image>
+					<span style="font-weight: bold;">终极目标</span>
+				</view>
+				<view class="action resetBtn" style="margin-right: 60rpx;" @tap="onReset"><text class="text-13px text-white" style="letter-spacing: 1px;">自动生成计划</text></view>
+			</view>
+			<view class="cu-form-group" @tap="showModal" data-target="showPickerModal" data-type="startTime">
+				<view class="flex justify-center align-center">
+					<image class="plan-litle-img" src="../../../static/plan_t.png"></image>
+					<view class="title make-text-bPurple">开始时间</view>
+				</view>
+
+				<view class="picker flex" style="position: relative;">
+					<view>{{ startTime }}</view>
+					<view class="only-arrow"></view>
+				</view>
+			</view>
+			<view class="cu-form-group" style="border-top:none" data-target="showPickerModal" data-type="endTime">
+				<view class="flex justify-center align-center">
+					<image class="plan-m-img" src="../../../static/plan_m.png"></image>
+					<view class="title text-gray" style="font-size: 12px;">计划总天数 {{ currentDays }} 天,加油!</view>
+				</view>
+			</view>
+			<view class="cu-form-group" style="border-top:none" @tap="showModal" data-target="showPickerModal" data-type="endTime">
+				<view class="flex justify-center align-center">
+					<image class="plan-litle-img" src="../../../static/plan_e.png"></image>
+					<view class="title make-text-bPurple">截止时间</view>
+				</view>
+				<view class="picker flex" style="position: relative;">
+					<view>{{ endTime }}</view>
+					<view class="only-arrow"></view>
+				</view>
+			</view>
+		</view>
+		<view class="flex flex-direction" style="padding: 23px 42rpx 46px"><button class="cu-btn make-bg-bPurple text-white lg"
+			 @tap="onUpdatePlanInfo">确定</button></view>
+		<view class="cu-modal bottom-modal" :class="modalName == 'showPickerModal' ? 'show' : ''" @touchmove.stop.prevent="moveHandle">
+			<view class="cu-dialog" style="border-top-right-radius: 20rpx; border-top-left-radius: 20rpx;">
+				<myPicker v-if="modalName == 'showPickerModal' ? true:false" :pickerObj="pickerObj" @confirmEvent="onConfirm"
+				 @cancelEvent="onCancel"></myPicker>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import config from '../../../common/config.js';
+	import date from '../../../util/util-js/date.js';
+	import reqUtil from '../../../util/util-js/requstUtil.js';
+
+	import myPicker from '@/components/slambb-picker/slambb-picker.vue';
+	import pickerData from '@/components/slambb-picker/picker.js';
+
+	import utilData from '@/util/util-js/util-data.js';
+
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+	export default {
+		computed: mapState(['planData', 'avatarUrl', 'days', "defaultPlanData", "remainingDays"]),
+		components: {
+			myPicker
+		},
+		data() {
+			return {
+				startTime: '',
+				endTime: '',
+				pickerObj: {
+					pickerType: 'dateItem',
+					pickerTitle: '记时间'
+				},
+				modalName: null,
+				pikerType: '',
+				oldPlanData: null,
+				// 当前plan页面的数据
+				currentPlanData: null,
+				// 当前天数
+				currentDays: 0,
+				//如果需要更新
+				hasUpdate: false,
+				//显示的重量
+				currenWeight: 0
+			};
+		},
+		onLoad: function(option) {
+			this.oldPlanData = JSON.parse(JSON.stringify(this.planData));
+			this.currentPlanData = JSON.parse(JSON.stringify(this.planData));
+			this.startTime = this.currentPlanData.startTime;
+			this.endTime = this.currentPlanData.endTime;
+			this.currentDays = this.days;
+
+			// 用累计的卡路里来计算当前累计的重量
+			// let weight = this.currentPlanData.cumulativeCalorie *2 / 7000;
+			let weight = utilData.calorieConversionKg(this.currentPlanData.cumulativeCalorie);
+
+			this.currenWeight = weight.toFixed(2);
+		},
+		methods: {
+			...mapMutations(['addlocalCalorie']),
+			DateChange(e) {
+				this.planData.startTime = e.detail.value;
+			},
+			onConfirm(args) {
+				this.hasUpdate = true;
+				console.log('onConfirm', args);
+				// detail.__args__[0]
+				// let args = data;
+				//月0~11
+				if (this.pikerType == 'startTime') {
+					let nDate = new Date();
+					nDate.setFullYear(args.value[0], args.value[1] - 1, args.value[2]);
+					// 判断日期
+					// console.log(date.formatDate(nDate),"==",date.formatDate(nDate).replace(/-/g, '/'))
+					var sDate1 = Date.parse(date.formatDate(nDate));
+					var sDate2 = Date.parse(this.endTime);
+					var dateSpan = sDate2 - sDate1;
+					if (dateSpan > 0) {
+						this.startTime = date.formatDate(nDate);
+						this.currentPlanData.startTime = date.formatTime(nDate);
+						// this.currentDays = date.datedifference(this.startTime, this.endTime);
+						this.currentDays = Math.floor(Math.abs(dateSpan) / (24 * 3600 * 1000));
+					} else {
+						uni.showToast({
+							title: "开始日期超过截止日期!",
+							icon: "none"
+						})
+					}
+
+
+				} else if (this.pikerType == 'endTime') {
+					let nDate = new Date();
+					nDate.setFullYear(args.value[0], args.value[1] - 1, args.value[2]);
+
+					// 判断日期
+					var sDate1 = Date.parse(this.startTime.replace(/-/g, '/'));
+					var sDate2 = Date.parse(date.formatDate(nDate).replace(/-/g, '/'));
+					var dateSpan = sDate2 - sDate1;
+					// console.log(dateSpan);
+					if (dateSpan > 0) {
+						this.endTime = date.formatDate(nDate);
+						this.currentPlanData.endTime = date.formatTime(nDate);
+						// this.currentDays = date.datedifference(this.startTime, this.endTime);
+						this.currentDays = Math.floor(Math.abs(dateSpan) / (24 * 3600 * 1000));
+					} else {
+						uni.showToast({
+							title: "开始日期不能超过或等于截止日期!",
+							icon: "none"
+						})
+					}
+
+
+
+				} else if (this.pikerType == 'target_weight') {
+					console.log('target_weight:');
+					this.currentPlanData.targetWeight = args.value;
+				} else if (this.pikerType == 'target_calorie') {
+					console.log('target_calorie:');
+					this.currentPlanData.calorie = parseInt(args.value);
+				} else if (this.pikerType == 'target_minute') {
+					console.log('target_minute:');
+					this.currentPlanData.sportTime = parseInt(args.value);
+				}
+
+				this.hideModal();
+			},
+			onCancel(value) {
+				console.log('onCancel', value);
+				this.modalName = null;
+			},
+			showModal(e) {
+				// console.log(e.currentTarget.type);
+				this.modalName = e.currentTarget.dataset.target;
+				this.pikerType = e.currentTarget.dataset.type;
+				switch (this.pikerType) {
+					case 'target_weight':
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getWeightList().leftList);
+						this.$set(this.pickerObj, 'pickerRightList', pickerData.getWeightList().rightList);
+						this.$set(this.pickerObj, 'pickerType', 'doubleItem');
+						this.$set(this.pickerObj, 'pickerUnit', '斤');
+						this.$set(this.pickerObj, 'pickerTitle', '记体重');
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case 'startTime':
+					case 'endTime':
+						this.$set(this.pickerObj, 'pickerType', 'dateItem');
+						this.$set(this.pickerObj, 'pickerTitle', '记时间');
+						this.$set(this.pickerObj, 'showInput', false);
+						break;
+					case 'target_calorie':
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getCalorieList().calorieList);
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerUnit', '大卡');
+						this.$set(this.pickerObj, 'pickerType', 'singleItem');
+						this.$set(this.pickerObj, 'pickerTitle', '卡路里');
+						this.$set(this.pickerObj, 'defaultValue', this.currentPlanData.calorie);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+					case 'target_minute':
+						this.$set(this.pickerObj, 'pickerLeftList', pickerData.getMinuteList().minuteList);
+						this.$set(this.pickerObj, 'pickerRightList', []);
+						this.$set(this.pickerObj, 'pickerUnit', '分钟');
+						this.$set(this.pickerObj, 'pickerType', 'singleItem');
+						this.$set(this.pickerObj, 'pickerTitle', '预计时间');
+						this.$set(this.pickerObj, 'defaultValue', this.currentPlanData.sportTime);
+						this.$set(this.pickerObj, 'showInput', true);
+						break;
+				}
+			},
+			hideModal(e) {
+				this.modalName = null;
+				this.pikerType = '';
+			},
+			moveHandle() {
+				return;
+			},
+			onUpdatePlanInfo() {
+				let that = this;
+				console.warn(that.currentPlanData);
+				if (!that.hasUpdate) {
+					uni.showToast({
+						title: '没有数据更新',
+						icon: 'none'
+					});
+					return;
+				}
+
+				if (that.currentPlanData.startTime > that.currentPlanData.endTime||
+				date.datedifference(that.currentPlanData.startTime, that.currentPlanData.endTime) == 0) {
+					uni.showToast({
+						title: '截止时间不能早于或等于开始时间',
+						icon: 'none'
+					});
+					return;
+				}
+				// console.warn(that.currentPlanData);
+				// return;
+				reqUtil.requestData(config.URL.FITNESSPROGRAM, that.currentPlanData, 'POST').then(
+					res => {
+						console.log('更新信息成功', res);
+						if (res.code == 0) {
+							uni.showToast({
+								title: '更新成功',
+								mask: true,
+								duration: 1000
+							});
+							that.oldPlanData = res.data;
+							that.hasUpdate = false;
+							that.$store.state.planData = Object.assign(that.$store.state.planData, res.data, {
+								sportTime: Number(that.currentPlanData.sportTime) 
+							});
+							// console.log("========",that.planData);
+							that.$store.state.days = date.datedifference(res.data.startTime, res.data.endTime) + 1;
+							let nDate = new Date();
+							let tempTime = date.formatDate(nDate);
+							that.$store.state.remainingDays = date.datedifference(tempTime, res.data.endTime) + 1;
+							// console.log("remainingDays==", that.remainingDays);
+							setTimeout(function() {
+								// console.log("updateArcbarData==setTimeout");
+								that.addlocalCalorie(0);
+								// uni.$emit('updateArcbarData', 'plan');
+								uni.navigateBack();
+							}, 500);
+						}
+					},
+					e => {
+						console.log(e);
+					}
+				);
+			},
+			//重置默认信息
+			onReset() {
+				uni.showToast({
+					title: '生成计划成功!',
+					icon: 'none',
+				})
+				this.hasUpdate = true;
+				// 拷贝
+				this.currentPlanData = JSON.parse(JSON.stringify(this.defaultPlanData));
+				this.startTime = this.currentPlanData.startTime;
+				this.endTime = this.currentPlanData.endTime;
+				this.currentDays = date.datedifference(this.startTime, this.endTime);
+				// console.log("this.defaultPlanData=",this.defaultPlanData);
+			},
+			onBack() {
+				uni.navigateBack({
+					delta: 1
+				})
+			}
+		}
+	};
+</script>
+
+<style>
+	.plan-w {
+		position: relative;
+		/* width: 464rpx; */
+		height: 464rpx;
+	}
+
+	.plan-w-bg-img {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		width: 464rpx;
+		height: 464rpx;
+	}
+
+	.plan-w-child {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		margin: auto;
+		width: 464rpx;
+		height: 464rpx;
+
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.plan-w-img {
+		width: 46rpx;
+		height: 46rpx;
+	}
+
+	.plan-Tip {
+		height: 90rpx;
+		margin: 60rpx 0;
+	}
+
+	.plan-Tip-child {
+		background-color: #f5f5ff;
+		border-radius: 20px;
+		width: 614rpx;
+		height: 90rpx;
+		margin: 60rpx 0;
+	}
+
+	.plan-litle-img {
+		width: 32rpx;
+		height: 32rpx;
+		margin-right: 32rpx;
+	}
+
+	.plan-m-img {
+		width: 1rpx;
+		height: 110rpx;
+		margin: 0 41rpx 0 14rpx;
+		border: 1rpx dashed rgba(151, 151, 255, 1);
+	}
+
+	.resetBtn {
+		background-color: rgba(151, 151, 255, 1);
+		border-radius: 3px;
+		padding: 10rpx 32rpx;
+	}
+
+	.plan-tagert {
+		margin: 20px 0;
+		height: 208rpx;
+	}
+
+	.plan-tagert-child {
+		background-color: #f5f5ff;
+		border-radius: 20px;
+		width: 614rpx;
+		height: 208rpx;
+		padding-left: 40rpx;
+	}
+
+	.avatar-img {
+		width: 96rpx;
+		height: 96rpx;
+		border: 4rpx solid rgba(151, 151, 255, 1);
+		border-radius: 45px;
+		flex-shrink: 0;
+	}
+</style>

BIN
static/add-purple.png


BIN
static/add.png


BIN
static/add_w.png


BIN
static/asterisk.png


BIN
static/avatar/1.png


BIN
static/avatar/10.png


BIN
static/avatar/11.png


BIN
static/avatar/2.png


BIN
static/avatar/3.png


BIN
static/avatar/4.png


BIN
static/avatar/5.png


BIN
static/avatar/6.png


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff