Browse Source

水电代码合并

zhang 5 years ago
parent
commit
36059ffa0c
46 changed files with 13775 additions and 3 deletions
  1. 4 3
      pages/index/index.vue
  2. 163 0
      pages/jiaofei/jiaofei.css
  3. 385 0
      pages/jiaofei/jiaofei.vue
  4. 92 0
      pages/select/select.css
  5. 295 0
      pages/select/select.vue
  6. 138 0
      pages/show/show.css
  7. 117 0
      pages/show/show.vue
  8. BIN
      static/image/banner2x.png
  9. BIN
      static/image/building.png
  10. BIN
      static/image/elec.png
  11. BIN
      static/image/floor.png
  12. BIN
      static/image/logo.png
  13. BIN
      static/image/money.png
  14. BIN
      static/image/recharge2x.png
  15. BIN
      static/image/record.png
  16. BIN
      static/image/right.png
  17. BIN
      static/image/room.png
  18. BIN
      static/image/school.png
  19. BIN
      static/image/show.png
  20. BIN
      static/image/shower2x.png
  21. BIN
      static/image/sjx.png
  22. 79 0
      static/test.js
  23. 38 0
      static/test_xiaofei.js
  24. 169 0
      uni_modules/qiun-data-charts/changelog.md
  25. 1541 0
      uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue
  26. 46 0
      uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue
  27. 162 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue
  28. 170 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue
  29. 173 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue
  30. 222 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue
  31. 229 0
      uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue
  32. 36 0
      uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue
  33. 420 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js
  34. 633 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js
  35. 12 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md
  36. 6776 0
      uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js
  37. 201 0
      uni_modules/qiun-data-charts/license.md
  38. 80 0
      uni_modules/qiun-data-charts/package.json
  39. 451 0
      uni_modules/qiun-data-charts/readme.md
  40. 23 0
      uni_modules/qiun-data-charts/static/app-plus/echarts.min.js
  41. 23 0
      uni_modules/qiun-data-charts/static/h5/echarts.min.js
  42. 6 0
      uni_modules/uni-datetime-picker/changelog.md
  43. 45 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js
  44. 903 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
  45. 82 0
      uni_modules/uni-datetime-picker/package.json
  46. 61 0
      uni_modules/uni-datetime-picker/readme.md

+ 4 - 3
pages/index/index.vue

@@ -17,7 +17,8 @@
 				</navigator>
 			</view>
 			<view class="reset">
-				<navigator url="" open-type="redirect" @click="reauthorization()" class="menu_item">
+				<navigator :url="'/pages/jiaofei/jiaofei?item=' + encodeURIComponent(JSON.stringify(this.userinfo))"
+					open-type="redirect" class="menu_item">
 					<text class="iconfont icon-zhongzhi"></text>
 					<text>重新授权</text>
 				</navigator>
@@ -123,7 +124,7 @@
 					const {
 						wxcode = ""
 					} = detail
-					
+
 					if (wxcode.length == 0) {
 						uni.showToast({
 							title: '未获得wxcode',
@@ -166,7 +167,7 @@
 				} else {
 					this.access_token = res.data.access_token;
 					this.refresh_token = res.data.refresh_token;
-					
+
 
 					// 通过access_token换取用户信息
 					this.get_user_info();

+ 163 - 0
pages/jiaofei/jiaofei.css

@@ -0,0 +1,163 @@
+page {
+	background-color: #f5f5f5;
+}
+
+.container {
+	font-size: 29upx;
+	font-family: "MicrosoftYaHei";
+	display: flex;
+	flex-direction: column;
+}
+
+.select-item {
+	margin: 19upx 0 10upx 0;
+	display: flex;
+	flex-direction:row;
+	background-color: #ffffff;
+	height: 139upx;
+}
+
+.show-item{
+	margin: 20upx 0;
+	display: flex;
+	flex-direction:row;
+	background-color: #ffffff;
+	height: 139upx;
+}
+
+.picker-item-logol{
+	width: 88upx;
+	display: flex;
+	justify-content: flex-end;
+}
+
+.picker-item-logo-left {
+	width: 58upx;
+	height: 58upx;
+	margin: 41upx 0upx 40upx 0upx;
+}
+.picker-item-label{
+	font-size: 30upx;
+	width: 161upx;
+	/* height: 30upx; */
+	margin: 52upx 0upx 52upx 0upx;
+	display: flex;
+	justify-content: center;
+}
+.picker-item-content {
+	width: 360upx;
+	height: 26upx;
+	font-size: 26upx;
+	margin: 55upx 0upx 52upx 60upx;
+	display: flex;
+	justify-content: flex-start;
+	color: #999999;
+}
+
+.picker-item-logor{
+	width: 91upx;
+	/* justify-content: flex-end; */
+	display: flex;
+	justify-content: center;
+	margin: 57upx 0upx 51upx 0upx;
+}
+
+.picker-item-logo-right{
+	width: 20upx;
+	height: 31upx;
+	/* display: flex; */
+	/* justify-content: flex-end; */
+}
+
+.font-txt{
+	color: #333333;
+}
+
+.add-money-show{
+	/* margin: 20upx 0; */
+	display: flex;
+	flex-direction:row;
+	background-color: #ffffff;
+	height: 120upx;
+	justify-content: flex-start;
+	/* padding-top: 31upx; */
+	/* align-content: flex-start; */
+	
+}
+
+.add-money{
+	height: 365upx;
+	display: flex;
+	flex-direction: column;
+}
+
+.money-show{
+	width: 300upx;
+	justify-content: flex-start;
+	margin-left: 20upx;
+	margin-top: 48upx;
+}
+
+.money-logo{
+	/* margin-top: 31upx; */
+}
+
+.add-money-list{
+	display: flex;
+	flex-direction: row;
+	flex-wrap: wrap;
+	margin-left: 15upx;
+}
+
+.add-money-button{
+	margin: 4upx 15upx 14.5upx 15upx;
+	width: 210upx;
+	height: 90upx;
+	/* border: solid #1296DB 1upx; */
+	border-radius: 10upx;
+	/* color: red; */
+	/* background-color: #ffffff; */
+}
+
+.select-submit{
+	border: solid #1296DB 1upx; 
+	border-radius: 10upx;
+	color: #1296DB;
+	font-size: 30upx;
+	background-color: #ffffff;
+}
+
+.input-money{
+	height: 139upx;
+	font-size: 30upx;
+	color: #333333;
+	margin-left: 29upx;
+}
+
+.submit-item{
+	margin: 54upx 30upx 0upx 30upx;
+	width: 690upx;
+	height: 96upx;
+	
+}
+
+.submit{
+	font-size: 29upx;
+	color: #ffffff;
+	border: solid #1296DB 1upx;
+	border-radius: 47.5upx;
+	background-color: #1296DB; 
+	padding: 15upx 315upx;
+}
+
+.change-show{
+	width: 120upx;
+	font-size: 30upx;
+	margin: 47upx 316upx;
+	color: #1296DB;
+}
+
+.bg-color{
+	background-color: #1296DB;
+	color: #ffffff;
+}

+ 385 - 0
pages/jiaofei/jiaofei.vue

@@ -0,0 +1,385 @@
+<template>
+	<view class="content">
+		<view class="select-item" @tap="navigateToSelect">
+			<view class="picker-item-logol">
+				<image class="picker-item-logo-left" src="/static/image/room.png"></image>
+			</view>
+			<view class="picker-item-label">已选房间</view>
+			<view class="picker-item-content" :class="{'font-txt':add_class==1}">{{roomSelect}}</view>
+			<view class="picker-item-logor">
+				<image class="picker-item-logo-right" src="/static/image/right.png"></image>
+			</view>
+		</view>
+		<view class="show-item">
+			<view class="picker-item-logol">
+				<image class="picker-item-logo-left" src="/static/image/elec.png"></image>
+			</view>
+			<view class="picker-item-label">剩余电量</view>
+			<view class="picker-item-content font-txt">{{remainElec}}度</view>
+		</view>
+		<view class="show-item add-money">
+			<view class="add-money-show">
+				<view class="picker-item-logol money-logo">
+					<image class="picker-item-logo-left" src="/static/image/money.png"></image>
+				</view>
+				<view class="picker-item-label money-show">请选择金额</view>
+			</view>
+			<view class="add-money-list">
+				<view class="add-money-button">
+					<button class="select-submit" :data-item="10" @tap="add_money" :class="{'bg-color':add_class1==1}">10元</button>
+				</view>
+				<view class="add-money-button">
+					<button class="select-submit" :data-item="30" @tap="add_money">30元</button>
+				</view>
+				<view class="add-money-button">
+					<button class="select-submit" :data-item="50" @tap="add_money">50元</button>
+				</view>
+				<view class="add-money-button">
+					<button class="select-submit" :data-item="100" @tap="add_money">100元</button>
+				</view>
+				<view class="add-money-button">
+					<button class="select-submit" :data-item="200" @tap="add_money">200元</button>
+				</view>
+				<view class="add-money-button">
+					<button class="select-submit" :data-item="300" @tap="add_money">300元</button>
+				</view>
+			</view>
+		</view>
+		<view class="show-item">
+			<input class="input-money" placeholder="请输入金额(1-1000)" v-model:value="inputMoney"
+				placeholder-class="#B3B3B3" @input="onInput"/>
+		</view>
+		<view class="submit-item">
+			<button class="submit" :data-rooms='room' @tap="input_money">充值</button>
+		</view>
+		<view class="change-show" @tap="navigateToShow">
+			台账管理
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				index: 0,
+				roomSelect: '请选择房间号', //房间号
+				remainElec: 80.1, //剩余电量
+				add_class: '', //增加class属性
+				add_class1: '',
+				inputMoney: '', //手动输入增加金额
+				addMoney: 0, //选择充值金额
+				// add_class_money: '',  
+				userinfo: {}, //用户信息
+				card_number: 0, //用户卡号
+				dom: '', //房间号
+				campus: '', //校区
+				access_token: '',
+				sub_appid: '1015730314_1941301045', //商户号
+				order_id: '202107151048111111', //订单号
+				pay_info: '',
+				item: {},
+				// storage: {},
+			}
+		},
+
+		onPullDownRefresh: function() {
+			uni.navigateTo({
+				url: '../jiaofei/jiaofei',
+			});
+			// console.log('触发了下拉刷新')
+		},
+
+		onLoad: function(options) {
+
+			// console.log('item:' + item);
+			// console.log(options.item.card_number)
+
+			try {
+				// 获取存储的用户数据
+				const value = uni.getStorageSync('userinfo_storage_key');
+
+				//将字符串解密转换成对象
+				let item = JSON.parse(decodeURIComponent(options.item));
+
+				// console.log(item)
+
+				if (JSON.stringify(item) === '{}') { // 如果没有用户信息,返回首页
+					uni.redirectTo({
+						url: '../index/index'
+					});
+					return;
+				}
+
+				//判断item是否存在
+				if (JSON.stringify(item) != '') {
+
+					//判断是哪个页面传入
+					if (typeof(item.roomSelect) != 'undefined') {
+
+						// this.item = item;
+
+						this.roomSelect = item.roomSelect;
+
+						this.add_class = 1;
+
+						this.dom = item.dom;
+
+						console.log(this.roomSelect)
+
+					} else {
+						// 处理JSON字符串
+						// this.userinfo = options.item.replace(/"/g, "'");
+						this.userinfo = item;
+						// console.log(this.userinfo)
+						this.card_number = this.userinfo.card_number
+
+						this.campus = this.userinfo.campus
+
+						this.dom = this.userinfo.dorm_number
+
+						this.roomSelect = this.campus + this.dom
+
+						this.add_class = 1;
+
+						// this.sub_appid = this.userinfo.sub_appid
+
+						// this.access_token = this.userinfo.access_token
+
+						// this.storage.access_token = this.access_token
+
+						// this.storage.card_number = this.card_number
+
+						// uni.setStorageSync('storage_data', this.storage)
+
+						// console.log(this.access_token)
+
+					}
+
+				} else if (value != '') {
+					// 处理JSON字符串
+					// this.userinfo = value.replace(/"/g, "'");
+					this.userinfo = value;
+				}
+
+				// console.log(this.dom)
+				// console.log(this.campus)
+			} catch (e) {
+				console.log(e)
+			}
+
+			// 查询用户信息
+			// this.select_user_info()
+
+			// console.log('房间号' + this.dom)
+
+			//将缓存中的token码进行获取
+			this.access_token = uni.getStorageSync('userinfo_storage_key').access_token
+			
+			//将缓存中的卡号进行获取
+			this.card_number = uni.getStorageSync('userinfo_storage_key').card_number
+
+
+			// console.log(this.access_token)
+
+		},
+
+		methods: {
+			//修改房间号
+			// changeSelect1(e) {
+			// 	console.log(e);
+			// this.index = e.detail.value;
+			// this.arr1 = this.array1;
+			// },
+
+			//跳转到选择页面
+			navigateToSelect() {
+				uni.navigateTo({
+					url: '../select/select',
+				});
+			},
+
+			//跳转到显示页面
+			navigateToShow(e) {
+				uni.navigateTo({
+					url: '../show/show?card_number=' + this.card_number,
+				});
+			},
+
+			//增加固定金额
+			add_money(e) {
+				this.add_class1 = 0
+				this.addMoney = e.currentTarget.dataset.item
+				uni.showModal({
+					// title: '确定充值'+this.inputMoney+'元',
+					title: '确定充值' + this.addMoney + '元',
+					success: (res) => {
+						if (res.confirm) {
+							// console.log('用户点击确定');
+							// console.log(this.addMoney);
+							this.pay_money_start()
+							// console.log(this.access_token)
+							// console.log('卡号' + this.card_number)
+							// console.log(this.sub_appid)
+							// console.log(this.order_id)
+							// console.log(this.addMoney)
+						} else if (res.cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				});
+
+				// this.pay_money_start()
+			},
+
+			//增加可变金额
+			input_money(e) {
+
+				// console.log(e)
+				//判断输入是否为空或不是数字
+				if (this.inputMoney == '' || this.inputMoney == null) {
+					uni.showToast({
+						title: '请输入',
+						duration: 2000
+					});
+				} else if (isNaN(this.inputMoney)) {
+					uni.showToast({
+						title: '输入错误',
+						duration: 2000
+					});
+				} else if (this.inputMoney > 1000 || this.inputMoney < 0) {
+					uni.showToast({
+						title: '超出范围',
+						duration: 2000
+					});
+				} else {
+					this.addMoney = this.inputMoney
+					uni.showModal({
+						// title: '确定充值'+this.inputMoney+'元',
+						title: '确定充值' + this.addMoney + '元',
+						success: (res) => {
+							if (res.confirm) {
+								// console.log('用户点击确定');
+								// console.log(this.addMoney)
+								this.pay_money_start()
+							} else if (res.cancel) {
+								console.log('用户点击取消');
+							}
+						}
+					});
+
+				}
+
+			},
+
+			/**
+			 * 输入充值金额
+			 */
+			onInput(e) {
+				const v = e.detail.value
+				this.inputMoney = 10
+
+				const zero = /^(0{1,})|[^0-9]/g
+				let final = 0
+				if (!v) {
+					final = 0
+				} else {
+					final = v.toString().replace(zero, (v) => {
+						return 0
+					})
+
+					if (final.split('')[0] * 1 === 0) {
+						final = final.slice(1) - 0 || 0
+					}
+
+					if (final > 1000) {
+						final = 1000
+					}
+				}
+				this.$nextTick(() => {
+					this.inputMoney = final.toString() || '0'
+				})
+				// setTimeout(() => {
+				// 	this.amount = final.toString() || '0'
+				// }, 100)
+			},
+
+			//失去焦点
+			// onBlur() {
+			// 	if (this.inputMoney < 10) {
+			// 		this.inputMoney = 10
+			// 	}
+			// },
+
+			//准备支付
+			async pay_money_start() {
+				const res = await this.$myRequest({
+					// ip: 'http://open.wecard.qq.com',
+					host: 'wecard',
+					url: "/cgi-bin/pay/app/mppay",
+					method: 'POST',
+					header: {
+						'content-type': 'application/json'
+					},
+					data: {
+						'access_token': this.access_token,
+						'sub_appid': this.sub_appid,
+						'user_id': this.card_number,
+						"order_id": this.order_id,
+						"amount": this.addMoney * 100,
+					}
+				});
+				// console.log(res)
+				this.pay_info = res.data.data.pay_info
+
+				// var info = decodeURIComponent(this.pay_info).substr(5,)
+				// info = JSON.parse(info)
+				// console.log(this.pay_info)
+				// console.log(this.resToken.access_token)
+
+				this.add_money_pay()
+
+			},
+
+			//调起支付
+			add_money_pay() {
+				var OpenMidas = require("../../static/openMidas.js"); // 引入小程序目录下的SDK文件
+
+				// 设置支付配置
+				wx['OpenMidasConfig'] = {
+					apiCommonConf: {
+						version: "weixiao"
+					},
+					cgiDomain: {
+						test: "midas.weixiao.qq.com/api", // 私有化参数联系微卡客服进行获取
+					},
+					webDomain: "https://midas.weixiao.qq.com/h5", // 私有化参数联系微卡客服进行获取
+					sandboxWebDomain: "https://midas.weixiao.qq.com/h5" // 私有化参数联系微卡客服进行获取
+				}
+
+				var payInfo = this.pay_info; // 请求mppay接口返回的数据
+				// console.log(payInfo)
+				// var appMetaData = "app=test&version=1.1"; // 自定义回调数据
+
+				OpenMidas.init("test");
+				OpenMidas.pay(
+					payInfo,
+					function(resultCode, innerCode, resultMsg, appMetaData) {
+						console.log(resultCode); // 支付响应状态码
+						console.log(innerCode); // 支付响应内部错误码
+						console.log(resultMsg); // 支付响应说明
+						console.log(appMetaData); // 自定义回调数据
+
+						// todo:处理业务逻辑
+					},
+					// appMetaData
+				);
+			}
+
+		},
+	}
+</script>
+
+<style>
+	@import url("jiaofei.css");
+</style>

+ 92 - 0
pages/select/select.css

@@ -0,0 +1,92 @@
+page {
+	background-color: #f5f5f5;
+}
+
+.container {
+	font-size: 29upx;
+	font-family: "MicrosoftYaHei";
+	display: flex;
+	flex-direction: column;
+}
+
+.picker-item1{
+	margin: 19upx 0 10upx 0;
+}
+
+.picker-item2{
+	margin: 10upx 0;
+}
+
+.select-item {
+	display: flex;
+	flex-direction:row;
+	background-color: #ffffff;
+	height: 139upx;
+}
+
+.picker-item-logol{
+	width: 88upx;
+	display: flex;
+	justify-content: flex-end;
+}
+
+.picker-item-logo-left {
+	width: 58upx;
+	height: 58upx;
+	margin: 41upx 0upx 40upx 0upx;
+}
+.picker-item-label{
+	font-size: 30upx;
+	width: 99upx;
+	/* height: 30upx; */
+	margin: 52upx 0upx 52upx 0upx;
+	display: flex;
+	justify-content: center;
+}
+.picker-item-content {
+	width: 360upx;
+	height: 26upx;
+	font-size: 26upx;
+	margin: 55upx 0upx 52upx 120upx;
+	display: flex;
+	justify-content: flex-start;
+	color: #999999;
+}
+
+.picker-item-logor{
+	width: 91upx;
+	/* justify-content: flex-end; */
+	display: flex;
+	justify-content: center;
+	margin: 57upx 0upx 51upx 0upx;
+}
+
+.picker-item-logo-right{
+	width: 20upx;
+	height: 31upx;
+	
+	/* display: flex; */
+	
+	/* justify-content: flex-end; */
+	
+}
+
+.submit-item{
+	margin: 112upx 30upx;
+	width: 690upx;
+	height: 96upx;
+	border-radius: 47.5upx;
+}
+
+.submit{
+	font-size: 29upx;
+	color: #ffffff;
+	border: solid #CCCCCC 1upx;
+	border-radius: 47.5upx;
+	background-color: #1296DB; 
+	padding: 15upx 315upx;
+}
+
+.font-txt{
+	color: #333333;
+}

+ 295 - 0
pages/select/select.vue

@@ -0,0 +1,295 @@
+<template>
+	<view class="container">
+		<picker class="picker-item1" @change="changeSelect1" :range="array1" :value="index1">
+			<view class="select-item">
+				<view class="picker-item-logol">
+					<image class="picker-item-logo-left" src="/static/image/school.png"></image>
+				</view>
+				<view class="picker-item-label">校区</view>
+				<view class="picker-item-content" :class="{'font-txt':add_class1==1}">{{arr1[index1]}}</view>
+				<view class="picker-item-logor">
+					<image class="picker-item-logo-right" src="/static/image/right.png"></image>
+				</view>
+			</view>
+		</picker>
+		<picker class="picker-item2" @change="changeSelect2" :range="array2" :value="index2" :disabled="dis_num2">
+			<view class="select-item">
+				<view class="picker-item-logol">
+					<image class="picker-item-logo-left" src="/static/image/building.png"></image>
+				</view>
+				<view class="picker-item-label">楼栋</view>
+				<view class="picker-item-content" :class="{'font-txt':add_class2==1}">{{arr2[index2]}}</view>
+				<view class="picker-item-logor">
+					<image class="picker-item-logo-right" src="/static/image/right.png"></image>
+				</view>
+			</view>
+		</picker>
+		<picker class="picker-item2" @change="changeSelect3" :range="array3" :value="index3" :disabled="dis_num3">
+			<view class="select-item">
+				<view class="picker-item-logol">
+					<image class="picker-item-logo-left" src="/static/image/floor.png"></image>
+				</view>
+				<view class="picker-item-label">楼层</view>
+				<view class="picker-item-content" :class="{'font-txt':add_class3==1}">{{arr3[index3]}}</view>
+				<view class="picker-item-logor">
+					<image class="picker-item-logo-right" src="/static/image/right.png"></image>
+				</view>
+			</view>
+		</picker>
+		<picker class="picker-item2" @change="changeSelect4" :range="array4" :value="index4" :disabled="dis_num4">
+			<view class="select-item">
+				<view class="picker-item-logol">
+					<image class="picker-item-logo-left" src="/static/image/room.png"></image>
+				</view>
+				<view class="picker-item-label">房间</view>
+				<view class="picker-item-content" :class="{'font-txt':add_class4==1}">{{arr4[index4]}}</view>
+				<view class="picker-item-logor">
+					<image class="picker-item-logo-right" src="/static/image/right.png"></image>
+				</view>
+			</view>
+		</picker>
+		<view class="submit-item">
+			<button @tap="navigateToIndex" class="submit" :data-room='room' :disabled="dis_num5">完成</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	import sortdata from '../../static/test.js'
+	export default {
+		data() {
+			return {
+				index1: 0, //选择器选择
+				index2: 0,
+				index3: 0,
+				index4: 0,
+				nschool: 0, //选择器中各个值的个数
+				nbuilds: 0,
+				floors: 0,
+				rooms: 0,
+				arr1: ['请选择校区'], //初始选择
+				arr2: ['请选择楼栋'],
+				arr3: ['请选择楼层'],
+				arr4: ['请选择房间'],
+				array1: ["黄家湖校区", "墨轩湖校区"], //选择器的值
+				array2: [],
+				array3: [],
+				array4: [],
+				room: '', //存储选择器选择的所有值
+				add_class1: '', //选择器class属性
+				add_class2: '',
+				add_class3: '',
+				add_class4: '',
+				dis_num2: 1, //选择器disable属性,是否禁用
+				dis_num3: 1,
+				dis_num4: 1,
+				dis_num5: 1,
+				allData: sortdata, //所有数据
+				storage: {}, //存放选择数据
+			}
+		},
+
+		onLoad() {
+			// console.log(this.allData.data[1].builds.length)
+			this.nschool = this.allData.data.length
+		},
+
+		methods: {
+			changeSelect1(e) {
+				// console.log(e);
+				this.index1 = e.detail.value;
+
+				//清空选择器
+				if (this.array2) {
+
+					this.array2 = []
+
+				}
+
+				//获取选择器1的值
+				for (var i = 0; i < this.nschool; i++) {
+
+					// this.array1.push(this.allData.data[i].school)
+
+					// console.log(this.allData.data[i].school)
+
+					//判断是否为空,不为空则继续
+					if (!this.allData.data[i].builds) {
+
+						continue
+
+					}
+
+					//获取选择器二中的值
+					if (i == this.index1) {
+
+						//得到选择器二中值的个数
+						this.nbuilds = this.allData.data[i].builds.length
+
+						// console.log(this.nbuilds)
+
+						//将数据加入选择器二中
+						for (var j = 0; j < this.nbuilds; j++) {
+
+							this.array2.push(this.allData.data[i].builds[j].building)
+
+						}
+
+					}
+
+				}
+
+				this.arr1 = this.array1;
+
+				// this.room = this.room.concat(this.array1[this.index1]);
+
+				this.add_class1 = 1;
+
+				this.dis_num2 = 0;
+
+				// console.log(this.array2)
+				// console.log(this.room)
+			},
+			changeSelect2(e) {
+				// console.log(e);
+				this.index2 = e.detail.value;
+
+				if (this.array3) {
+
+					this.array3 = []
+
+				}
+
+				for (var i = 0; i < this.nbuilds; i++) {
+
+					// this.array1.push(this.allData.data[i].school)
+
+					// console.log(this.allData.data[i].school)
+
+					if (!this.allData.data[this.index1].builds[i].floors) {
+						continue
+					}
+
+					if (i == this.index2) {
+
+						this.floors = this.allData.data[this.index1].builds[i].floors.length
+
+						// console.log(this.floors)
+
+						for (var j = 0; j < this.floors; j++) {
+
+							this.array3.push(this.allData.data[this.index1].builds[i].floors[j].floor)
+
+						}
+
+					}
+
+				}
+
+				this.arr2 = this.array2;
+
+				// this.room = this.room.concat(this.array2[this.index2]);
+
+				this.add_class2 = 1;
+
+				this.dis_num3 = 0;
+
+				// console.log(this.room)
+			},
+			changeSelect3(e) {
+				// console.log(e);
+				this.index3 = e.detail.value;
+
+				if (this.array4) {
+
+					this.array4 = []
+
+				}
+
+				for (var i = 0; i < this.floors; i++) {
+
+					// this.array1.push(this.allData.data[i].school)
+
+					// console.log(this.allData.data[i].school)
+
+					if (!this.allData.data[this.index1].builds[this.index2].floors[i].rooms) {
+
+						continue
+
+					}
+
+					if (i == this.index3) {
+
+						this.rooms = this.allData.data[this.index1].builds[this.index2].floors[i].rooms.length
+
+						// console.log(this.rooms)
+
+						for (var j = 0; j < this.rooms; j++) {
+
+							this.array4.push(this.allData.data[this.index1].builds[this.index2].floors[i].rooms[j])
+
+						}
+
+					}
+
+				}
+
+				this.arr3 = this.array3;
+
+				// this.room = this.room.concat(this.array3[this.index3]);
+
+				this.add_class3 = 1;
+
+				this.dis_num4 = 0;
+
+				// console.log(this.room)
+			},
+			changeSelect4(e) {
+				// console.log(e);
+
+				this.index4 = e.detail.value;
+
+				this.arr4 = this.array4;
+
+				this.add_class4 = 1;
+
+				if (this.room) {
+
+					this.room = ''
+
+				}
+
+				//将选择器中的值加到变量room中,传到下一个页面
+				// this.room = this.room.concat(this.array1[this.index1], this.array2[this.index2], this.array3[this.index3],
+				// 	this.array4[this.index4]);
+				this.room = this.room.concat(this.array1[this.index1], this.array4[this.index4]);
+
+				this.dis_num5 = 0;
+
+				// console.log(this.array1[this.index1])
+				// console.log(this.array2[this.index2])
+				// console.log(this.array3[this.index3])
+				// console.log(this.array4[this.index4])
+
+				// console.log(this.room)
+			},
+
+			//跳转页面
+			navigateToIndex(e) {
+				// console.log(e)
+				var roomSelect = e.currentTarget.dataset.room;
+				this.storage.roomSelect = roomSelect;
+				this.storage.dom = this.array4[this.index4];
+				// console.log(roomSelect)
+				uni.navigateTo({
+					url: '../jiaofei/jiaofei?item=' + encodeURIComponent(JSON.stringify(this.storage)),
+				});
+			},
+
+		}
+	}
+</script>
+
+<style>
+	@import url("select.css");
+</style>

+ 138 - 0
pages/show/show.css

@@ -0,0 +1,138 @@
+page {
+	background-color: #f5f5f5;
+}
+
+.container {
+	font-size: 28upx;
+	font-family: "MicrosoftYaHei";
+	display: flex;
+	flex-direction: column;
+	color: #333333;
+}
+
+.show-item {
+	margin: 18upx 0;
+	height: 625upx;
+	background-color: #ffffff;
+}
+
+.show-elec-label {
+	display: flex;
+	flex-direction: row;
+	height: 80upx;
+}
+
+.show-item-logol {
+	width: 81upx;
+	display: flex;
+	justify-content: flex-end;
+}
+
+.show-item-logo-left {
+	width: 50upx;
+	height: 50upx;
+	margin: 30upx 0upx;
+}
+
+.show-item-label {
+	font-size: 32upx;
+	width: 163upx;
+	/* height: 30upx; */
+	margin: 34upx 0upx 0upx 17upx;
+	display: flex;
+	justify-content: center;
+}
+
+.charts-box {
+	height: 360upx;
+	margin-top: 27upx;
+	margin-left: -10upx;
+}
+
+.select-show {
+	/* padding-bottom: 40upx; */
+	height: 160upx;
+	display: flex;
+	align-items: center;
+}
+
+.first-button {
+	width: 200upx;
+	height: 80upx;
+	display: flex;
+	justify-content: center;
+	font-size: 28upx;
+	align-items: center;
+	border-radius: 10upx;
+	color: #1296DB;
+	border: solid #1296DB 1upx;
+	background-color: #FFFFFF;
+}
+
+/* .first-button:hover {
+	background-color: #e4faff;
+	color: #1296DB;
+	border-color: #1296DB;
+} */
+
+
+.show-item-date {
+	height: 1158upx;
+	margin: 2upx 0;
+	background-color: #ffffff;
+}
+
+.show-label {
+	width: 132upx;
+}
+
+.uni-input {
+	margin-left: 32upx;
+	margin-top: 40.1upx;
+
+}
+
+.uni-input-label {
+	font-size: 40upx;
+}
+
+.picker-item-logo {
+	width: 37upx;
+	height: 15upx;
+}
+
+
+.uni-list{
+	margin: 39upx 30upx 0 30upx;
+	display: flex;
+	flex-direction: column;
+}
+
+.item-list {
+	height: 97upx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	border-top: 2rpx #CCCCCC solid;
+}
+
+.item-list:last-child{
+	border-bottom: 2rpx #CCCCCC solid;
+}
+
+.item-list-left{
+	display: flex;
+	justify-content: space-between;
+	width: 425upx;
+}
+
+.item-list-txt {
+	font-size: 28upx;
+	color: #333333;
+}
+
+.show-money{
+	margin-right: 10upx;
+	color: #F76200;
+	font-size: 32upx;
+}

+ 117 - 0
pages/show/show.vue

@@ -0,0 +1,117 @@
+<template>
+	<view class="container">
+		<view class="show-item">
+			<view class="show-elec-label">
+				<view class="show-item-logol">
+					<image class="show-item-logo-left" src="/static/image/show.png"></image>
+				</view>
+				<view class="show-item-label">能耗走势图</view>
+			</view>
+			<view class="charts-box">
+				<qiun-data-charts type="demotype" :chartData="chartData" />
+			</view>
+			<view class="select-show">
+				<button class="first-button">月</button>
+			</view>
+		</view>
+		<view class="show-item-date">
+			<view class="show-elec-label">
+				<view class="show-item-logol">
+					<image class="show-item-logo-left" src="/static/image/record.png"></image>
+				</view>
+				<view class="show-item-label show-label">缴费记录</view>
+			</view>
+			<view class="select-date">
+				<picker mode="date" fields="month" :start="startDate" :end="endDate" @change="bindDateChange">
+					<view class="uni-input">
+						<text class="uni-input-label">{{date}}</text>
+						<text class="iconfont icon-sanjiaoxing"></text>
+					</view>
+				</picker>
+				<!-- <picker mode="date" fields="month" :start="startDate" :end="endDate" @change="bindDateChange">
+					<view class="uni-input">
+						<text class="uni-input-label">{{date}}</text>月
+						<text class="iconfont icon-sanjiaoxing"></text>
+					</view>
+				</picker> -->
+				<view class="uni-list">
+					<view class="item-list" v-for="(item, i) in list" :key="i">
+						<view class="item-list-left">
+							<text class="item-list-txt">{{item.name}}</text>
+							<text class="item-list-txt">{{item.tdate}} {{item.time}}</text>
+						</view>
+						<text class="item-list-txt show-money">{{item.money}}</text>
+					</view>
+				</view>
+				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import data from '../../static/test_xiaofei.js'
+	export default {
+		data() {
+			return {
+				date_time: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
+				use_elec: [5, 19, 16, 24, 38, 22, 15, 16, 14, 17, 22, 20],
+				chartData: {
+					categories: [],
+					series: [{
+						data: [],
+					}],
+				},
+				date: getDate({
+					// format: true
+				}),
+				// startDate: getDate('start_date'),
+				// endDate: getDate('end_date'),
+				all_data: data, //所有数据
+				list: [] ,//消费列表
+				card_number: 0,   //用户卡号
+			}
+		},
+		onLoad(options){
+			this.chartData.categories = this.date_time;
+			this.chartData.series[0].data = this.use_elec;
+			// console.log(this.chartData.series[0].data)
+			
+			this.list = this.all_data.data[0].xiaofei;
+			// this.name = this.all_data.data[0].xiaofei.name;
+			// console.log(this.date)
+			this.card_number = options.card_number
+			// console.log(this.card_number)
+		},
+		methods: {
+			bindDateChange: function(e) {
+				this.date = e.detail.value
+				// console.log(this.date)
+			},
+			
+		},
+		
+	}
+	function getDate(type) {
+		const date = new Date();
+	
+		let year = date.getFullYear();
+		let month = date.getMonth() + 1;
+		// let day = date.getDate();
+	
+		// if (type === 'start_date') {
+		// 	year = year - 4;
+		// } else if (type === 'end_date') {
+		// 	year = year;
+		// }
+	
+		month = month > 9 ? month : '0' + month;
+		// day = day > 9 ? day : '0' + day;
+	
+		return `${year}-${month}`;
+	}
+</script>
+
+<style>
+	@import url("show.css");
+</style>

BIN
static/image/banner2x.png


BIN
static/image/building.png


BIN
static/image/elec.png


BIN
static/image/floor.png


BIN
static/image/logo.png


BIN
static/image/money.png


BIN
static/image/recharge2x.png


BIN
static/image/record.png


BIN
static/image/right.png


BIN
static/image/room.png


BIN
static/image/school.png


BIN
static/image/show.png


BIN
static/image/shower2x.png


BIN
static/image/sjx.png


+ 79 - 0
static/test.js

@@ -0,0 +1,79 @@
+// const data = [{"黄家湖校区":[{
+// 		"1#":[{
+
+// 		}]
+// 	}]}
+// 	,
+// 	{"墨轩湖校区":[{
+// 			"1#":[{
+
+// 			}]
+// 		}]}
+// ]
+
+const data = [{
+	"school": "黄家湖校区",
+}, {
+	"school": "墨轩湖校区",
+	"builds": [{
+			"building": "1#",
+			"floors": [{
+					"floor": "1层",
+					"rooms": [1101, 1102, 1103,1104,1105]
+				},
+				{
+					"floor": "2层",
+					"rooms": [1201, 1202, 1203,1204,1205]
+				},{
+					"floor": "3层",
+					"rooms": [1301, 1302, 1303,1304,1305]
+				}
+			]
+		},
+		{
+			"building": "2#",
+			"floors": [{
+					"floor": "1层",
+					"rooms": [2101, 2102, 2103,2104,2105]
+				},
+				{
+					"floor": "2层",
+					"rooms": [2201, 2202, 2203,2204,2205]
+				},{
+					"floor": "3层",
+					"rooms": [2301, 2302, 2303,2304,2305]
+				},{
+					"floor": "4层",
+					"rooms": [2401, 2402, 2403,2404,2405]
+				}
+			]
+		},
+		{
+			"building": "3#",
+			"floors": [{
+					"floor": "1层",
+					"rooms": [3101, 3102, 3103,3104,3105]
+				},
+				{
+					"floor": "2层",
+					"rooms": [3201, 3202, 3203,3204,3205]
+				},{
+					"floor": "3层",
+					"rooms": [3301, 3302, 3303,3304,3305]
+				},{
+					"floor": "4层",
+					"rooms": [3401, 3402, 3403,3404,3405]
+				},{
+					"floor": "5层",
+					"rooms": [3501, 3502, 3503,3504,3505]
+				}
+			]
+		}
+	]
+}]
+
+
+
+module.exports = {
+	data: data,
+}

+ 38 - 0
static/test_xiaofei.js

@@ -0,0 +1,38 @@
+const data_xiaofei = [{
+	dom: '3310',
+	xiaofei: [{
+		name: "但茂华",
+		tdate: "7月1日",
+		time: "9:00",
+		money: 10.3
+	},{
+		name: "张平",
+		tdate: "7月2日",
+		time: "8:00",
+		money: 20
+	},{
+		name: "陈士柏",
+		tdate: "7月2日",
+		time: "9:00",
+		money: 30
+	},{
+		name: "张平",
+		tdate: "7月3日",
+		time: "11:00",
+		money: 15
+	},{
+		name: "程志平",
+		tdate: "7月5日",
+		time: "14:00",
+		money: 20
+	},{
+		name: "但茂华",
+		tdate: "7月8日",
+		time: "16:00",
+		money: 15
+	}]
+}]
+
+module.exports = {
+	data: data_xiaofei,
+}

+ 169 - 0
uni_modules/qiun-data-charts/changelog.md

@@ -0,0 +1,169 @@
+## 2.3.2-20210627(2021-06-27)
+- 秋云图表组件 修复tooltipCustom个别情况下传值不正确报错TypeError: Cannot read property 'name' of undefined的bug
+## 2.3.1-20210616(2021-06-16)
+- uCharts.js 修复圆角柱状图使用4角圆角时,当数值过大时不正确的bug
+## 2.3.0-20210612(2021-06-12)
+- uCharts.js 【重要】uCharts增加nvue兼容,可在nvue项目中使用gcanvas组件渲染uCharts,[详见码云uCharts-demo-nvue](https://gitee.com/uCharts/uCharts)
+- 秋云图表组件 增加tapLegend属性,是否开启图例点击交互事件
+- 秋云图表组件 getIndex事件中增加返回uCharts实例中的opts参数,以便在页面中调用参数
+- 示例项目 pages/other/other.vue增加app端自定义tooltip的方法,详见showOptsTooltip方法
+## 2.2.1-20210603(2021-06-03)
+- uCharts.js 修复饼图、圆环图、玫瑰图,当起始角度不为0时,tooltip位置不准确的bug
+- uCharts.js 增加温度计式柱状图开启顶部半圆形的配置
+## 2.2.0-20210529(2021-05-29)
+- uCharts.js 增加条状图type="bar"
+- 示例项目 pages/ucharts/ucharts.vue增加条状图的demo
+## 2.1.7-20210524(2021-05-24)
+- uCharts.js 修复大数据量模式下曲线图不平滑的bug
+## 2.1.6-20210523(2021-05-23)
+- 秋云图表组件 修复小程序端开启滚动条更新数据后滚动条位置不符合预期的bug
+## 2.1.5-2021051702(2021-05-17)
+- uCharts.js 修复自定义Y轴min和max值为0时不能正确显示的bug
+## 2.1.5-20210517(2021-05-17)
+- uCharts.js 修复Y轴自定义min和max时,未按指定的最大值最小值显示坐标轴刻度的bug
+## 2.1.4-20210516(2021-05-16)
+- 秋云图表组件 优化onWindowResize防抖方法
+- 秋云图表组件 修复APP端uCharts更新数据时,清空series显示loading图标后再显示图表,图表抖动的bug
+- uCharts.js 修复开启canvas2d后,x轴、y轴、series自定义字体大小未按比例缩放的bug
+- 示例项目 修复format-e.vue拼写错误导致app端使用uCharts渲染图表
+## 2.1.3-20210513(2021-05-13)
+- 秋云图表组件 修改uCharts变更chartData数据为updateData方法,支持带滚动条的数据动态打点
+- 秋云图表组件 增加onWindowResize防抖方法 fix by ど誓言,如尘般染指流年づ 
+- 秋云图表组件 H5或者APP变更chartData数据显示loading图表时,原数据闪现的bug
+- 秋云图表组件 props增加errorReload禁用错误点击重新加载的方法
+- uCharts.js 增加tooltip显示category(x轴对应点位)标题的功能,opts.extra.tooltip.showCategory,默认为false
+- uCharts.js 修复mix混合图只有柱状图时,tooltip的分割线显示位置不正确的bug
+- uCharts.js 修复开启滚动条,图表在拖动中动态打点,滚动条位置不正确的bug
+- uCharts.js 修复饼图类数据格式为echarts数据格式,series为空数组报错的bug
+- 示例项目 修改uCharts.js更新到v2.1.2版本后,@getIndex方法获取索引值变更为e.currentIndex.index
+- 示例项目 pages/updata/updata.vue增加滚动条拖动更新(数据动态打点)的demo
+- 示例项目 pages/other/other.vue增加errorReload禁用错误点击重新加载的demo
+## 2.1.2-20210509(2021-05-09)
+秋云图表组件 修复APP端初始化时就传入chartData或lacaldata不显示图表的bug
+## 2.1.1-20210509(2021-05-09)
+- 秋云图表组件 变更ECharts的eopts配置在renderjs内执行,支持在config-echarts.js配置文件内写function配置。
+- 秋云图表组件 修复APP端报错Prop being mutated: "onmouse"错误的bug。
+- 秋云图表组件 修复APP端报错Error: Not Found:Page[6][-1,27] at view.umd.min.js:1的bug。
+## 2.1.0-20210507(2021-05-07)
+- 秋云图表组件 修复初始化时就有数据或者数据更新的时候loading加载动画闪动的bug
+- uCharts.js 修复x轴format方法categories为字符串类型时返回NaN的bug
+- uCharts.js 修复series.textColor、legend.fontColor未执行全局默认颜色的bug
+## 2.1.0-20210506(2021-05-06)
+- 秋云图表组件 修复极个别情况下报错item.properties undefined的bug
+- 秋云图表组件 修复极个别情况下关闭加载动画reshow不起作用,无法显示图表的bug
+- 示例项目 pages/ucharts/ucharts.vue 增加时间轴折线图(type="tline")、时间轴区域图(type="tarea")、散点图(type="scatter")、气泡图demo(type="bubble")、倒三角形漏斗图(opts.extra.funnel.type="triangle")、金字塔形漏斗图(opts.extra.funnel.type="pyramid")
+- 示例项目 pages/format-u/format-u.vue 增加X轴format格式化示例
+- uCharts.js 升级至v2.1.0版本
+- uCharts.js 修复 玫瑰图面积模式点击tooltip位置不正确的bug
+- uCharts.js 修复 玫瑰图点击图例,只剩一个类别显示空白的bug
+- uCharts.js 修复 饼图类图点击图例,其他图表tooltip位置某些情况下不准的bug
+- uCharts.js 修复 x轴为矢量轴(时间轴)情况下,点击tooltip位置不正确的bug
+- uCharts.js 修复 词云图获取点击索引偶尔不准的bug
+- uCharts.js 增加 直角坐标系图表X轴format格式化方法(原生uCharts.js用法请使用formatter)
+- uCharts.js 增加 漏斗图扩展配置,倒三角形(opts.extra.funnel.type="triangle"),金字塔形(opts.extra.funnel.type="pyramid")
+- uCharts.js 增加 散点图(opts.type="scatter")、气泡图(opts.type="bubble")
+- 后期计划 完善散点图、气泡图,增加markPoints标记点,增加横向条状图。
+## 2.0.0-20210502(2021-05-02)
+- uCharts.js 修复词云图获取点击索引不正确的bug
+## 2.0.0-20210501(2021-05-01)
+- 秋云图表组件 修复QQ小程序、百度小程序在关闭动画效果情况下,v-for循环使用图表,显示不正确的bug
+## 2.0.0-20210426(2021-04-26)
+- 秋云图表组件 修复QQ小程序不支持canvas2d的bug
+- 秋云图表组件 修复钉钉小程序某些情况点击坐标计算错误的bug
+- uCharts.js 增加 extra.column.categoryGap 参数,柱状图类每个category点位(X轴点)柱子组之间的间距
+- uCharts.js 增加 yAxis.data[i].titleOffsetY 参数,标题纵向偏移距离,负数为向上偏移,正数向下偏移
+- uCharts.js 增加 yAxis.data[i].titleOffsetX 参数,标题横向偏移距离,负数为向左偏移,正数向右偏移
+- uCharts.js 增加 extra.gauge.labelOffset 参数,仪表盘标签文字径向便宜距离,默认13px
+## 2.0.0-20210422-2(2021-04-22)
+秋云图表组件 修复 formatterAssign 未判断 args[key] == null 的情况导致栈溢出的 bug
+## 2.0.0-20210422(2021-04-22)
+- 秋云图表组件 修复H5、APP、支付宝小程序、微信小程序canvas2d模式下横屏模式的bug
+## 2.0.0-20210421(2021-04-21)
+- uCharts.js 修复多行图例的情况下,图例在上方或者下方时,图例float为左侧或者右侧时,第二行及以后的图例对齐方式不正确的bug
+## 2.0.0-20210420(2021-04-20)
+- 秋云图表组件 修复微信小程序开启canvas2d模式后,windows版微信小程序不支持canvas2d模式的bug
+- 秋云图表组件 修改非uni_modules版本为v2.0版本qiun-data-charts组件
+## 2.0.0-20210419(2021-04-19)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
+## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
+## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
+## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font> 
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- uCharts.js 修复混合图中柱状图单独设置颜色不生效的bug
+- uCharts.js 修复多Y轴单独设置fontSize时,开启canvas2d后,未对应放大字体的bug
+## 2.0.0-20210418(2021-04-18)
+- 秋云图表组件 增加directory配置,修复H5端history模式下如果发布到二级目录无法正确加载echarts.min.js的bug
+## 2.0.0-20210416(2021-04-16)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
+## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
+## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
+## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font> 
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- 秋云图表组件 修复APP端某些情况下报错`Not Found Page`的bug,fix by 高级bug开发技术员
+- 示例项目 修复APP端v-for循环某些情况下报错`Not Found Page`的bug,fix by 高级bug开发技术员
+- uCharts.js 修复非直角坐标系tooltip提示窗右侧超出未变换方向显示的bug
+## 2.0.0-20210415(2021-04-15)
+- 秋云图表组件 修复H5端发布到二级目录下echarts无法加载的bug
+- 秋云图表组件 修复某些情况下echarts.off('finished')移除监听事件报错的bug
+## 2.0.0-20210414(2021-04-14)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX,如仍不好用,请重启电脑;
+## 如果是cli项目,请尝试清理node_modules,重新install,还不行就删除项目,再重新install。
+## 此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## 其他图表不显示问题详见[常见问题选项卡](https://demo.ucharts.cn)
+## <font color=#FF0000> 新手请先完整阅读帮助文档及常见问题3遍,右侧蓝色按钮示例项目请看2遍! </font> 
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在项目中的应用参见 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- 秋云图表组件 修复H5端在cli项目下ECharts引用地址错误的bug
+- 示例项目 增加ECharts的formatter用法的示例(详见示例项目format-e.vue)
+- uCharts.js 增加圆环图中心背景色的配置extra.ring.centerColor
+- uCharts.js 修复微信小程序安卓端柱状图开启透明色后显示不正确的bug
+## 2.0.0-20210413(2021-04-13)
+- 秋云图表组件 修复百度小程序多个图表真机未能正确获取根元素dom尺寸的bug
+- 秋云图表组件 修复百度小程序横屏模式方向不正确的bug
+- 秋云图表组件 修改ontouch时,@getTouchStart@getTouchMove@getTouchEnd的触发条件
+- uCharts.js 修复饼图类数据格式series属性不生效的bug
+- uCharts.js 增加时序区域图 详见示例项目中ucharts.vue
+## 2.0.0-20210412-2(2021-04-12)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册&lt;qiun-data-charts&gt;组件,请重启HBuilderX。如仍不好用,请重启电脑,此问题已于DCloud官方确认,HBuilderX下个版本会修复。
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- 秋云图表组件 修复uCharts在APP端横屏模式下不能正确渲染的bug
+- 示例项目 增加ECharts柱状图渐变色、圆角柱状图、横向柱状图(条状图)的示例
+## 2.0.0-20210412(2021-04-12)
+- 秋云图表组件 修复created中判断echarts导致APP端无法识别,改回mounted中判断echarts初始化
+- uCharts.js 修复2d模式下series.textOffset未乘像素比的bug
+## 2.0.0-20210411(2021-04-11)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧绿色【使用HBuilderX导入插件】即可使用,示例项目请点击右侧蓝色按钮【使用HBuilderX导入示例项目】。
+## 初次使用如果提示未注册<qiun-data-charts>组件,请重启HBuilderX,并清空小程序开发者工具缓存。
+## [DEMO演示及在线生成工具(v2.0文档)https://demo.ucharts.cn](https://demo.ucharts.cn)
+## [图表组件在uniCloudAdmin中的应用 UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- uCharts.js 折线图区域图增加connectNulls断点续连的功能,详见示例项目中ucharts.vue
+- 秋云图表组件 变更初始化方法为created,变更type2d默认值为true,优化2d模式下组件初始化后dom获取不到的bug
+- 秋云图表组件 修复左右布局时,右侧图表点击坐标错误的bug,修复tooltip柱状图自定义颜色显示object的bug
+## 2.0.0-20210410(2021-04-10)
+- 修复左右布局时,右侧图表点击坐标错误的bug,修复柱状图自定义颜色tooltip显示object的bug
+- 增加标记线及柱状图自定义颜色的demo
+## 2.0.0-20210409(2021-04-08)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
+## 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+- uCharts.js 修复钉钉小程序百度小程序measureText不准确的bug,修复2d模式下饼图类activeRadius为按比例放大的bug
+- 修复组件在支付宝小程序端点击位置不准确的bug
+## 2.0.0-20210408(2021-04-07)
+- 修复组件在支付宝小程序端不能显示的bug(目前支付宝小程不能点击交互,后续修复)
+- uCharts.js 修复高分屏下柱状图类,圆弧进度条 自定义宽度不能按比例放大的bug
+## 2.0.0-20210407(2021-04-06)
+## v1.0版本已停更,建议转uni_modules版本组件方式调用,点击右侧【使用HBuilderX导入插件】即可体验,DEMO演示及在线生成工具(v2.0文档)[https://demo.ucharts.cn](https://demo.ucharts.cn)
+## 增加 通过tofix和unit快速格式化y轴的demo add by `howcode`
+## 增加 图表组件在uniCloudAdmin中的应用 [UReport数据报表](https://ext.dcloud.net.cn/plugin?id=4651) 
+## 2.0.0-20210406(2021-04-05)
+# 秋云图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页
+## 2.0.0(2021-04-05)
+# 秋云图表组件+uCharts v2.0版本同步上线,使用方法详见https://demo.ucharts.cn帮助页

File diff suppressed because it is too large
+ 1541 - 0
uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue


File diff suppressed because it is too large
+ 46 - 0
uni_modules/qiun-data-charts/components/qiun-error/qiun-error.vue


+ 162 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading1.vue

@@ -0,0 +1,162 @@
+<template>
+	 <view class="container loading1">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading1',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+.container.loading1 {
+  -webkit-transform: rotate(45deg);
+          transform: rotate(45deg);
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+.loading1 .shape1 {
+  -webkit-animation: animation1shape1 0.5s ease 0s infinite alternate;
+          animation: animation1shape1 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, 16px);
+            transform: translate(16px, 16px);
+  }
+}
+
+@keyframes animation1shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, 16px);
+            transform: translate(16px, 16px);
+  }
+}
+.loading1 .shape2 {
+  -webkit-animation: animation1shape2 0.5s ease 0s infinite alternate;
+          animation: animation1shape2 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, 16px);
+            transform: translate(-16px, 16px);
+  }
+}
+
+@keyframes animation1shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, 16px);
+            transform: translate(-16px, 16px);
+  }
+}
+.loading1 .shape3 {
+  -webkit-animation: animation1shape3 0.5s ease 0s infinite alternate;
+          animation: animation1shape3 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, -16px);
+            transform: translate(16px, -16px);
+  }
+}
+
+@keyframes animation1shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(16px, -16px);
+            transform: translate(16px, -16px);
+  }
+}
+.loading1 .shape4 {
+  -webkit-animation: animation1shape4 0.5s ease 0s infinite alternate;
+          animation: animation1shape4 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation1shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, -16px);
+            transform: translate(-16px, -16px);
+  }
+}
+
+@keyframes animation1shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-16px, -16px);
+            transform: translate(-16px, -16px);
+  }
+}
+
+
+</style>

+ 170 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading2.vue

@@ -0,0 +1,170 @@
+<template>
+	 <view class="container loading2">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading2',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+.container.loading2 {
+  -webkit-transform: rotate(10deg);
+          transform: rotate(10deg);
+}
+.container.loading2 .shape {
+  border-radius: 5px;
+}
+.container.loading2{
+  -webkit-animation: rotation 1s infinite;
+          animation: rotation 1s infinite;
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+
+.loading2 .shape1 {
+  -webkit-animation: animation2shape1 0.5s ease 0s infinite alternate;
+          animation: animation2shape1 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, 20px);
+            transform: translate(20px, 20px);
+  }
+}
+
+@keyframes animation2shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, 20px);
+            transform: translate(20px, 20px);
+  }
+}
+.loading2 .shape2 {
+  -webkit-animation: animation2shape2 0.5s ease 0s infinite alternate;
+          animation: animation2shape2 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, 20px);
+            transform: translate(-20px, 20px);
+  }
+}
+
+@keyframes animation2shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, 20px);
+            transform: translate(-20px, 20px);
+  }
+}
+.loading2 .shape3 {
+  -webkit-animation: animation2shape3 0.5s ease 0s infinite alternate;
+          animation: animation2shape3 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, -20px);
+            transform: translate(20px, -20px);
+  }
+}
+
+@keyframes animation2shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(20px, -20px);
+            transform: translate(20px, -20px);
+  }
+}
+.loading2 .shape4 {
+  -webkit-animation: animation2shape4 0.5s ease 0s infinite alternate;
+          animation: animation2shape4 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation2shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, -20px);
+            transform: translate(-20px, -20px);
+  }
+}
+
+@keyframes animation2shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-20px, -20px);
+            transform: translate(-20px, -20px);
+  }
+}
+
+</style>

+ 173 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading3.vue

@@ -0,0 +1,173 @@
+<template>
+	 <view class="container loading3">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading3',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+ .container.loading3 {
+  -webkit-animation: rotation 1s infinite;
+          animation: rotation 1s infinite;
+}
+.container.loading3 .shape1 {
+  border-top-left-radius: 10px;
+}
+.container.loading3 .shape2 {
+  border-top-right-radius: 10px;
+}
+.container.loading3 .shape3 {
+  border-bottom-left-radius: 10px;
+}
+.container.loading3 .shape4 {
+  border-bottom-right-radius: 10px;
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+.loading3 .shape1 {
+  -webkit-animation: animation3shape1 0.5s ease 0s infinite alternate;
+          animation: animation3shape1 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, 5px);
+            transform: translate(5px, 5px);
+  }
+}
+
+@keyframes animation3shape1 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, 5px);
+            transform: translate(5px, 5px);
+  }
+}
+.loading3 .shape2 {
+  -webkit-animation: animation3shape2 0.5s ease 0s infinite alternate;
+          animation: animation3shape2 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, 5px);
+            transform: translate(-5px, 5px);
+  }
+}
+
+@keyframes animation3shape2 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, 5px);
+            transform: translate(-5px, 5px);
+  }
+}
+.loading3 .shape3 {
+  -webkit-animation: animation3shape3 0.5s ease 0s infinite alternate;
+          animation: animation3shape3 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, -5px);
+            transform: translate(5px, -5px);
+  }
+}
+
+@keyframes animation3shape3 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(5px, -5px);
+            transform: translate(5px, -5px);
+  }
+}
+.loading3 .shape4 {
+  -webkit-animation: animation3shape4 0.5s ease 0s infinite alternate;
+          animation: animation3shape4 0.5s ease 0s infinite alternate;
+}
+
+@-webkit-keyframes animation3shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, -5px);
+            transform: translate(-5px, -5px);
+  }
+}
+
+@keyframes animation3shape4 {
+  from {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  to {
+    -webkit-transform: translate(-5px, -5px);
+            transform: translate(-5px, -5px);
+  }
+}
+</style>

+ 222 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading4.vue

@@ -0,0 +1,222 @@
+<template>
+	 <view class="container loading5">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading5',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+.container.loading5 .shape {
+  width: 15px;
+  height: 15px;
+}
+
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+.loading5 .shape1 {
+  animation: animation5shape1 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+  50% {
+    -webkit-transform: translate(15px, 15px);
+            transform: translate(15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+}
+
+@keyframes animation5shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+  50% {
+    -webkit-transform: translate(15px, 15px);
+            transform: translate(15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+}
+.loading5 .shape2 {
+  animation: animation5shape2 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-15px, 15px);
+            transform: translate(-15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+}
+
+@keyframes animation5shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-15px, 15px);
+            transform: translate(-15px, 15px);
+  }
+  75% {
+    -webkit-transform: translate(0, 15px);
+            transform: translate(0, 15px);
+  }
+}
+.loading5 .shape3 {
+  animation: animation5shape3 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(15px, -15px);
+            transform: translate(15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+}
+
+@keyframes animation5shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(15px, 0);
+            transform: translate(15px, 0);
+  }
+  50% {
+    -webkit-transform: translate(15px, -15px);
+            transform: translate(15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+}
+.loading5 .shape4 {
+  animation: animation5shape4 2s ease 0s infinite reverse;
+}
+
+@-webkit-keyframes animation5shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+  50% {
+    -webkit-transform: translate(-15px, -15px);
+            transform: translate(-15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+}
+
+@keyframes animation5shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -15px);
+            transform: translate(0, -15px);
+  }
+  50% {
+    -webkit-transform: translate(-15px, -15px);
+            transform: translate(-15px, -15px);
+  }
+  75% {
+    -webkit-transform: translate(-15px, 0);
+            transform: translate(-15px, 0);
+  }
+}
+
+</style>

+ 229 - 0
uni_modules/qiun-data-charts/components/qiun-loading/loading5.vue

@@ -0,0 +1,229 @@
+<template>
+	 <view class="container loading6">
+		<view class="shape shape1"></view>
+		<view class="shape shape2"></view>
+		<view class="shape shape3"></view>
+		<view class="shape shape4"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'loading6',
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+<style scoped="true">
+.container {
+  width: 30px;
+  height: 30px;
+  position: relative;
+}
+
+.container.loading6 {
+  -webkit-animation: rotation 1s infinite;
+          animation: rotation 1s infinite;
+}
+.container.loading6 .shape {
+  width: 12px;
+  height: 12px;
+  border-radius: 2px;
+}
+.container .shape {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  border-radius: 1px;
+}
+.container .shape.shape1 {
+  left: 0;
+  background-color: #1890FF;
+}
+.container .shape.shape2 {
+  right: 0;
+  background-color: #91CB74;
+}
+.container .shape.shape3 {
+  bottom: 0;
+  background-color: #FAC858;
+}
+.container .shape.shape4 {
+  bottom: 0;
+  right: 0;
+  background-color: #EE6666;
+}
+
+
+.loading6 .shape1 {
+  -webkit-animation: animation6shape1 2s linear 0s infinite normal;
+          animation: animation6shape1 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+  50% {
+    -webkit-transform: translate(18px, 18px);
+            transform: translate(18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+}
+
+@keyframes animation6shape1 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+  50% {
+    -webkit-transform: translate(18px, 18px);
+            transform: translate(18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+}
+.loading6 .shape2 {
+  -webkit-animation: animation6shape2 2s linear 0s infinite normal;
+          animation: animation6shape2 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-18px, 18px);
+            transform: translate(-18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+}
+
+@keyframes animation6shape2 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(-18px, 18px);
+            transform: translate(-18px, 18px);
+  }
+  75% {
+    -webkit-transform: translate(0, 18px);
+            transform: translate(0, 18px);
+  }
+}
+.loading6 .shape3 {
+  -webkit-animation: animation6shape3 2s linear 0s infinite normal;
+          animation: animation6shape3 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(18px, -18px);
+            transform: translate(18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+}
+
+@keyframes animation6shape3 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(18px, 0);
+            transform: translate(18px, 0);
+  }
+  50% {
+    -webkit-transform: translate(18px, -18px);
+            transform: translate(18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+}
+.loading6 .shape4 {
+  -webkit-animation: animation6shape4 2s linear 0s infinite normal;
+          animation: animation6shape4 2s linear 0s infinite normal;
+}
+
+@-webkit-keyframes animation6shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+  50% {
+    -webkit-transform: translate(-18px, -18px);
+            transform: translate(-18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+}
+
+@keyframes animation6shape4 {
+  0% {
+    -webkit-transform: translate(0, 0);
+            transform: translate(0, 0);
+  }
+  25% {
+    -webkit-transform: translate(0, -18px);
+            transform: translate(0, -18px);
+  }
+  50% {
+    -webkit-transform: translate(-18px, -18px);
+            transform: translate(-18px, -18px);
+  }
+  75% {
+    -webkit-transform: translate(-18px, 0);
+            transform: translate(-18px, 0);
+  }
+}
+</style>

+ 36 - 0
uni_modules/qiun-data-charts/components/qiun-loading/qiun-loading.vue

@@ -0,0 +1,36 @@
+<template>
+	<view>
+	 <Loading1 v-if="loadingType==1"/>
+	 <Loading2 v-if="loadingType==2"/>
+	 <Loading3 v-if="loadingType==3"/>
+	 <Loading4 v-if="loadingType==4"/>
+	 <Loading5 v-if="loadingType==5"/>
+	</view>
+</template>
+
+<script>
+	import Loading1 from "./loading1.vue";
+	import Loading2 from "./loading2.vue";
+	import Loading3 from "./loading3.vue";
+	import Loading4 from "./loading4.vue";
+	import Loading5 from "./loading5.vue";
+	export default {
+		components:{Loading1,Loading2,Loading3,Loading4,Loading5},
+		name: 'qiun-loading',
+		props: {
+			loadingType: {
+				type: Number,
+				default: 2
+			},
+		},
+		data() {
+			return {
+				
+			};
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 420 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/config-echarts.js

@@ -0,0 +1,420 @@
+/*
+ * uCharts®
+ * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
+ * Copyright (c) 2021 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
+ * 
+ */
+
+// 通用配置项
+
+// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
+const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
+
+module.exports = {
+  //demotype为自定义图表类型
+	"type": ["pie", "ring", "rose", "funnel", "line", "column", "area", "radar", "gauge","candle","demotype"],
+  //增加自定义图表类型,如果需要categories,请在这里加入您的图表类型例如最后的"demotype"
+	"categories": ["line", "column", "area", "radar", "gauge", "candle","demotype"],
+  //instance为实例变量承载属性,option为eopts承载属性,不要删除
+	"instance": {},
+	"option": {},
+  //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
+  "formatter":{
+    "tooltipDemo1":function(res){
+      let result = ''
+      for (let i in res) {
+      	if (i == 0) {
+      		result += res[i].axisValueLabel + '年销售额'
+      	}
+      	let value = '--'
+      	if (res[i].data !== null) {
+      		value = res[i].data
+      	}
+      	// #ifdef H5
+      	result += '\n' + res[i].seriesName + ':' + value + ' 万元'
+      	// #endif
+      	
+      	// #ifdef APP-PLUS
+      	result += '<br/>' + res[i].marker + res[i].seriesName + ':' + value + ' 万元'
+      	// #endif
+      }
+      return result;
+    },
+    legendFormat:function(name){
+      return "自定义图例+"+name;
+    },
+    yAxisFormatDemo:function (value, index) {
+      return value + '元';
+    },
+    seriesFormatDemo:function(res){
+      return res.name + '年' + res.value + '元';
+    }
+  },
+  //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在eopts参数,会将demotype与eopts中option合并后渲染图表。
+  "demotype":{
+    "color": color,
+    //在这里填写echarts的option即可
+    
+  },
+  //下面是自定义配置,请添加项目所需的通用配置
+	"column": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'axis'
+		},
+		"grid": {
+			"top": 30,
+			"bottom": 50,
+			"right": 15,
+			"left": 40
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"toolbox": {
+			"show": false,
+		},
+		"xAxis": {
+			"type": 'category',
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+			"boundaryGap": true,
+			"data": []
+		},
+		"yAxis": {
+			"type": 'value',
+			"axisTick": {
+				"show": false,
+			},
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'bar',
+			"data": [],
+			"barwidth": 20,
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"line": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'axis'
+		},
+		"grid": {
+			"top": 30,
+			"bottom": 50,
+			"right": 15,
+			"left": 40
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"toolbox": {
+			"show": false,
+		},
+		"xAxis": {
+			"type": 'category',
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+			"boundaryGap": true,
+			"data": []
+		},
+		"yAxis": {
+			"type": 'value',
+			"axisTick": {
+				"show": false,
+			},
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'line',
+			"data": [],
+			"barwidth": 20,
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"area": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'axis'
+		},
+		"grid": {
+			"top": 30,
+			"bottom": 50,
+			"right": 15,
+			"left": 40
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"toolbox": {
+			"show": false,
+		},
+		"xAxis": {
+			"type": 'category',
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+			"boundaryGap": true,
+			"data": []
+		},
+		"yAxis": {
+			"type": 'value',
+			"axisTick": {
+				"show": false,
+			},
+			"axisLabel": {
+				"color": '#666666'
+			},
+			"axisLine": {
+				"lineStyle": {
+					"color": '#CCCCCC'
+				}
+			},
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'line',
+			"data": [],
+			"areaStyle": {},
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"pie": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item'
+		},
+		"grid": {
+			"top": 40,
+			"bottom": 30,
+			"right": 15,
+			"left": 15
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'pie',
+			"data": [],
+			"radius": '50%',
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+		},
+	},
+	"ring": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item'
+		},
+		"grid": {
+			"top": 40,
+			"bottom": 30,
+			"right": 15,
+			"left": 15
+		},
+		"legend": {
+			"bottom": 'left',
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'pie',
+			"data": [],
+			"radius": ['40%', '70%'],
+			"avoidLabelOverlap": false,
+			"label": {
+				"show": true,
+        "color": "#666666",
+				"position": 'top',
+			},
+			"labelLine": {
+				"show": true
+			},
+		},
+	},
+	"rose": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item'
+		},
+		"legend": {
+			"top": 'bottom'
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'pie',
+			"data": [],
+			"radius": "55%",
+			"center": ['50%', '50%'],
+			"rosetype": 'area',
+		},
+	},
+	"funnel": {
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"tooltip": {
+			"trigger": 'item',
+			"formatter": "{b} : {c}%"
+		},
+		"legend": {
+			"top": 'bottom'
+		},
+		"seriesTemplate": {
+			"name": '',
+			"type": 'funnel',
+			"left": '10%',
+			"top": 60,
+			"bottom": 60,
+			"width": '80%',
+			"min": 0,
+			"max": 100,
+			"minSize": '0%',
+			"maxSize": '100%',
+			"sort": 'descending',
+			"gap": 2,
+			"label": {
+				"show": true,
+				"position": 'inside'
+			},
+			"labelLine": {
+				"length": 10,
+				"lineStyle": {
+					"width": 1,
+					"type": 'solid'
+				}
+			},
+			"itemStyle": {
+				"bordercolor": '#fff',
+				"borderwidth": 1
+			},
+			"emphasis": {
+				"label": {
+					"fontSize": 20
+				}
+			},
+			"data": [],
+		},
+	},
+	"gauge": {
+		"color": color,
+		"tooltip": {
+        "formatter": '{a} <br/>{b} : {c}%'
+    },
+		"seriesTemplate": {
+			"name": '业务指标',
+      "type": 'gauge',
+      "detail": {"formatter": '{value}%'},
+      "data": [{"value": 50, "name": '完成率'}]
+		},
+	},
+	"candle": {
+		"xAxis": {
+			"data": []
+		},
+		"yAxis": {},
+		"color": color,
+		"title": {
+			"text": ''
+		},
+		"dataZoom": [{
+				"type": 'inside',
+				"xAxisIndex": [0, 1],
+				"start": 10,
+				"end": 100
+			},
+			{
+				"show": true,
+				"xAxisIndex": [0, 1],
+				"type": 'slider',
+				"bottom": 10,
+				"start": 10,
+				"end": 100
+			}
+		],
+		"seriesTemplate": {
+			"name": '',
+			"type": 'k',
+			"data": [],
+		},
+	}
+}

+ 633 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/config-ucharts.js

@@ -0,0 +1,633 @@
+/*
+ * uCharts®
+ * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360)、Vue、Taro等支持canvas的框架平台
+ * Copyright (c) 2021 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
+ * 
+ */
+
+// 主题颜色配置:如每个图表类型需要不同主题,请在对应图表类型上更改color属性
+const color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'];
+
+//事件转换函数,主要用作格式化x轴为时间轴,根据需求自行修改
+const formatDateTime = (timeStamp, returnType) => {
+	var date = new Date();
+	date.setTime(timeStamp * 1000);
+	var y = date.getFullYear();
+	var m = date.getMonth() + 1;
+	m = m < 10 ? ('0' + m) : m;
+	var d = date.getDate();
+	d = d < 10 ? ('0' + d) : d;
+	var h = date.getHours();
+	h = h < 10 ? ('0' + h) : h;
+	var minute = date.getMinutes();
+	var second = date.getSeconds();
+	minute = minute < 10 ? ('0' + minute) : minute;
+	second = second < 10 ? ('0' + second) : second;
+	if (returnType == 'full') {
+		return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
+	}
+	if (returnType == 'y-m-d') {
+		return y + '-' + m + '-' + d;
+	}
+	if (returnType == 'h:m') {
+		return h + ':' + minute;
+	}
+	if (returnType == 'h:m:s') {
+		return h + ':' + minute + ':' + second;
+	}
+	return [y, m, d, h, minute, second];
+}
+
+module.exports = {
+	//demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可
+	"type": ["pie", "ring", "rose", "word", "funnel", "map", "arcbar", "line", "column", "bar", "area", "radar",
+		"gauge", "candle", "mix", "tline", "tarea", "scatter", "bubble", "demotype"
+	],
+	"range": ["饼状图", "圆环图", "玫瑰图", "词云图", "漏斗图", "地图", "圆弧进度条", "折线图", "柱状图", "条状图", "区域图", "雷达图", "仪表盘", "K线图",
+		"混合图", "时间轴折线", "时间轴区域", "散点图", "气泡图", "自定义类型"
+	],
+	//增加自定义图表类型,如果需要categories,请在这里加入您的图表类型,例如最后的"demotype"
+	//自定义类型时需要注意"tline","tarea","scatter","bubble"等时间轴(矢量x轴)类图表,没有categories,不需要加入categories
+	"categories": ["line", "column", "bar", "area", "radar", "gauge", "candle", "mix", "demotype"],
+	//instance为实例变量承载属性,不要删除
+	"instance": {},
+	//option为opts及eopts承载属性,不要删除
+	"option": {},
+	//下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
+	"formatter": {
+		"yAxisDemo1": function(val) {
+			return val + '元'
+		},
+		"yAxisDemo2": function(val) {
+			return val.toFixed(2)
+		},
+		"xAxisDemo1": function(val) {
+			return val + '年'
+		},
+		"xAxisDemo2": function(val) {
+			return formatDateTime(val, 'h:m')
+		},
+		"seriesDemo1": function(val) {
+			return val + '元'
+		},
+		"tooltipDemo1": function(item, category, index, opts) {
+			if (index == 0) {
+				return '随便用' + item.data + '年'
+			} else {
+				return '其他我没改' + item.data + '天'
+			}
+		},
+		"pieDemo": function(val, index, series) {
+			if (index !== undefined) {
+				return series[index].name + ':' + series[index].data + '元'
+			}
+		},
+	},
+	//这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。
+	"demotype": {
+		//我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
+		"type": "line",
+		"color": ["#EF7A2D"],
+		"padding": [15, 10, 10, 15],
+		"dataLabel": false,
+		"dataPointShapeType": "hollow",
+		 "tapLegend": true,
+		 "animation": false,
+		"xAxis": {
+			"disableGrid": true,
+			"fontColor": '#666666',
+			"axisLineColor": "#CCCCCC",
+			"rotateLabel": true,
+			"fontSize": 12,
+		},
+		"yAxis": {
+			"disabled": false,
+			"gridType": "solid",
+			"dashLength": 2,
+			"gridColor": "#CCCCCC",
+			"showTitle": true,
+			"splitNumber": 4,
+			"data": [{
+				"type": "value",
+				"position": "left",
+				"disabled": false,
+				"axisLine": false,
+				"axisLineColor": "#CCCCCC",
+				"calibration": false,
+				"fontColor": "#666666",
+				"fontSize": 12,
+				"textAlign": "right",
+				"title": "度",
+				"titleFontSize": 12,
+				"titleOffsetY": -5,
+				"titleOffsetX": -10,
+				"titleFontColor": "#666666",
+				"min": 0,
+				"max": 80,
+				"tofix": null,
+				"unit": "",
+				"format": ""
+			}]
+		},
+		"legend": {
+		        "show": false,
+		        "position": "bottom",
+		        "float": "center",
+		        "padding": 10,
+		        "margin": 10,
+		        "backgroundColor": "#cccccc",
+		        "borderColor": "#1296DB",
+		        "borderWidth": 0.5,
+		        "fontSize": 14,
+		        "fontColor": "#666666",
+		        "lineHeight": 11,
+		        "hiddenColor": "#CECECE",
+		        "itemGap": 10,
+		    },
+		"extra": {
+			"line": {
+				"type": "curve",
+				"width": 2
+			},
+		}
+	},
+	//下面是自定义配置,请添加项目所需的通用配置
+	"pie": {
+		"type": "pie",
+		"color": color,
+		"padding": [5, 5, 5, 5],
+		"extra": {
+			"pie": {
+				"activeOpacity": 0.5,
+				"activeRadius": 10,
+				"offsetAngle": 0,
+				"labelWidth": 15,
+				"border": true,
+				"borderWidth": 3,
+				"borderColor": "#FFFFFF"
+			},
+		}
+	},
+	"ring": {
+		"type": "ring",
+		"color": color,
+		"padding": [5, 5, 5, 5],
+		"rotate": false,
+		"dataLabel": true,
+		"legend": {
+			"show": true,
+			"position": "right",
+			"lineHeight": 25,
+		},
+		"title": {
+			"name": "收益率",
+			"fontSize": 15,
+			"color": "#666666"
+		},
+		"subtitle": {
+			"name": "70%",
+			"fontSize": 25,
+			"color": "#7cb5ec"
+		},
+		"extra": {
+			"ring": {
+				"ringWidth": 30,
+				"activeOpacity": 0.5,
+				"activeRadius": 10,
+				"offsetAngle": 0,
+				"labelWidth": 15,
+				"border": true,
+				"borderWidth": 3,
+				"borderColor": "#FFFFFF"
+			},
+		},
+	},
+	"rose": {
+		"type": "rose",
+		"color": color,
+		"padding": [5, 5, 5, 5],
+		"legend": {
+			"show": true,
+			"position": "left",
+			"lineHeight": 25,
+		},
+		"extra": {
+			"rose": {
+				"type": "area",
+				"minRadius": 50,
+				"activeOpacity": 0.5,
+				"activeRadius": 10,
+				"offsetAngle": 0,
+				"labelWidth": 15,
+				"border": false,
+				"borderWidth": 2,
+				"borderColor": "#FFFFFF"
+			},
+		}
+	},
+	"word": {
+		"type": "word",
+		"color": color,
+		"extra": {
+			"word": {
+				"type": "normal",
+				"autoColors": false
+			}
+		}
+	},
+	"funnel": {
+		"type": "funnel",
+		"color": color,
+		"padding": [15, 15, 0, 15],
+		"extra": {
+			"funnel": {
+				"activeOpacity": 0.3,
+				"activeWidth": 10,
+				"border": true,
+				"borderWidth": 2,
+				"borderColor": "#FFFFFF",
+				"fillOpacity": 1,
+				"labelAlign": "right"
+			},
+		}
+	},
+	"map": {
+		"type": "map",
+		"color": color,
+		"padding": [0, 0, 0, 0],
+		"dataLabel": true,
+		"extra": {
+			"map": {
+				"border": true,
+				"borderWidth": 1,
+				"borderColor": "#666666",
+				"fillOpacity": 0.6,
+				"activeBorderColor": "#F04864",
+				"activeFillColor": "#FACC14",
+				"activeFillOpacity": 1
+			},
+		}
+	},
+	"arcbar": {
+		"type": "arcbar",
+		"color": color,
+		"title": {
+			"name": "百分比",
+			"fontSize": 25,
+			"color": "#00FF00"
+		},
+		"subtitle": {
+			"name": "默认标题",
+			"fontSize": 15,
+			"color": "#666666"
+		},
+		"extra": {
+			"arcbar": {
+				"type": "default",
+				"width": 12,
+				"backgroundColor": "#E9E9E9",
+				"startAngle": 0.75,
+				"endAngle": 0.25,
+				"gap": 2
+			}
+		}
+	},
+	"line": {
+		"type": "line",
+		"color": color,
+		"padding": [15, 10, 0, 15],
+		"xAxis": {
+			"disableGrid": true,
+		},
+		"yAxis": {
+			"gridType": "dash",
+			"dashLength": 2,
+		},
+		"legend": {},
+		"extra": {
+			"line": {
+				"type": "straight",
+				"width": 2
+			},
+		}
+	},
+	"tline": {
+		"type": "line",
+		"color": color,
+		"padding": [15, 10, 0, 15],
+		"xAxis": {
+			"disableGrid": false,
+			"boundaryGap": "justify",
+		},
+		"yAxis": {
+			"gridType": "dash",
+			"dashLength": 2,
+			"data": [{
+				"min": 0,
+				"max": 80
+			}]
+		},
+		"legend": {},
+		"extra": {
+			"line": {
+				"type": "curve",
+				"width": 2
+			},
+		}
+	},
+	"tarea": {
+		"type": "area",
+		"color": color,
+		"padding": [15, 10, 0, 15],
+		"xAxis": {
+			"disableGrid": true,
+			"boundaryGap": "justify",
+		},
+		"yAxis": {
+			"gridType": "dash",
+			"dashLength": 2,
+			"data": [{
+				"min": 0,
+				"max": 80
+			}]
+		},
+		"legend": {},
+		"extra": {
+			"area": {
+				"type": "curve",
+				"opacity": 0.2,
+				"addLine": true,
+				"width": 2,
+				"gradient": true
+			},
+		}
+	},
+	"column": {
+		"type": "column",
+		"color": color,
+		"padding": [15, 15, 0, 5],
+		"xAxis": {
+			"disableGrid": true,
+		},
+		"yAxis": {
+			"data": [{
+				"min": 0
+			}]
+		},
+		"legend": {},
+		"extra": {
+			"column": {
+				"type": "group",
+				"width": 30,
+				"meterBorde": 1,
+				"meterFillColor": "#FFFFFF",
+				"activeBgColor": "#000000",
+				"activeBgOpacity": 0.08
+			},
+		}
+	},
+	"bar": {
+		"type": "bar",
+		"color": color,
+		"padding": [15, 30, 0, 5],
+		"xAxis": {
+			"boundaryGap": "justify",
+			"disableGrid": false,
+			"min": 0,
+			"axisLine": false
+		},
+		"yAxis": {},
+		"legend": {},
+		"extra": {
+			"bar": {
+				"type": "group",
+				"width": 30,
+				"meterBorde": 1,
+				"meterFillColor": "#FFFFFF",
+				"activeBgColor": "#000000",
+				"activeBgOpacity": 0.08
+			},
+		}
+	},
+	"area": {
+		"type": "area",
+		"color": color,
+		"padding": [15, 15, 0, 15],
+		"xAxis": {
+			"disableGrid": true,
+		},
+		"yAxis": {
+			"gridType": "dash",
+			"dashLength": 2,
+		},
+		"legend": {},
+		"extra": {
+			"area": {
+				"type": "straight",
+				"opacity": 0.2,
+				"addLine": true,
+				"width": 2,
+				"gradient": false
+			},
+		}
+	},
+	"radar": {
+		"type": "radar",
+		"color": color,
+		"padding": [5, 5, 5, 5],
+		"legend": {
+			"show": true,
+			"position": "right",
+			"lineHeight": 25,
+		},
+		"extra": {
+			"radar": {
+				"gridType": "radar",
+				"gridColor": "#CCCCCC",
+				"gridCount": 3,
+				"opacity": 0.2,
+				"max": 200
+			},
+		}
+	},
+	"gauge": {
+		"type": "gauge",
+		"color": color,
+		"title": {
+			"name": "66Km/H",
+			"fontSize": 25,
+			"color": "#2fc25b",
+			"offsetY": 50
+		},
+		"subtitle": {
+			"name": "实时速度",
+			"fontSize": 15,
+			"color": "#1890ff",
+			"offsetY": -50
+		},
+		"extra": {
+			"gauge": {
+				"type": "default",
+				"width": 30,
+				"labelColor": "#666666",
+				"startAngle": 0.75,
+				"endAngle": 0.25,
+				"startNumber": 0,
+				"endNumber": 100,
+				"labelFormat": "",
+				"splitLine": {
+					"fixRadius": 0,
+					"splitNumber": 10,
+					"width": 30,
+					"color": "#FFFFFF",
+					"childNumber": 5,
+					"childWidth": 12
+				},
+				"pointer": {
+					"width": 24,
+					"color": "auto"
+				}
+			}
+		}
+	},
+	"candle": {
+		"type": "candle",
+		"color": color,
+		"padding": [15, 15, 0, 15],
+		"enableScroll": true,
+		"enableMarkLine": true,
+		"dataLabel": false,
+		"xAxis": {
+			"labelCount": 4,
+			"itemCount": 40,
+			"disableGrid": true,
+			"gridColor": "#CCCCCC",
+			"gridType": "solid",
+			"dashLength": 4,
+			"scrollShow": true,
+			"scrollAlign": "left",
+			"scrollColor": "#A6A6A6",
+			"scrollBackgroundColor": "#EFEBEF"
+		},
+		"yAxis": {},
+		"legend": {},
+		"extra": {
+			"candle": {
+				"color": {
+					"upLine": "#f04864",
+					"upFill": "#f04864",
+					"downLine": "#2fc25b",
+					"downFill": "#2fc25b"
+				},
+				"average": {
+					"show": true,
+					"name": ["MA5", "MA10", "MA30"],
+					"day": [5, 10, 20],
+					"color": ["#1890ff", "#2fc25b", "#facc14"]
+				}
+			},
+			"markLine": {
+				"type": "dash",
+				"dashLength": 5,
+				"data": [{
+						"value": 2150,
+						"lineColor": "#f04864",
+						"showLabel": true
+					},
+					{
+						"value": 2350,
+						"lineColor": "#f04864",
+						"showLabel": true
+					}
+				]
+			}
+		}
+	},
+	"mix": {
+		"type": "mix",
+		"color": color,
+		"padding": [15, 15, 0, 15],
+		"xAxis": {
+			"disableGrid": true,
+		},
+		"yAxis": {
+			"disabled": false,
+			"disableGrid": false,
+			"splitNumber": 5,
+			"gridType": "dash",
+			"dashLength": 4,
+			"gridColor": "#CCCCCC",
+			"padding": 10,
+			"showTitle": true,
+			"data": []
+		},
+		"legend": {},
+		"extra": {
+			"mix": {
+				"column": {
+					"width": 20
+				}
+			},
+		}
+	},
+	"scatter": {
+		"type": "scatter",
+		"color": color,
+		"padding": [15, 15, 0, 15],
+		"dataLabel": false,
+		"xAxis": {
+			"disableGrid": false,
+			"gridType": "dash",
+			"splitNumber": 5,
+			"boundaryGap": "justify",
+			"min": 0
+		},
+		"yAxis": {
+			"disableGrid": false,
+			"gridType": "dash",
+		},
+		"legend": {},
+		"extra": {
+			"scatter": {},
+		}
+	},
+	"bubble": {
+		"type": "bubble",
+		"color": color,
+		"padding": [15, 15, 0, 15],
+		"xAxis": {
+			"disableGrid": false,
+			"gridType": "dash",
+			"splitNumber": 5,
+			"boundaryGap": "justify",
+			"min": 0,
+			"max": 250
+		},
+		"yAxis": {
+			"disableGrid": false,
+			"gridType": "dash",
+			"data": [{
+				"min": 0,
+				"max": 150
+			}]
+		},
+		"legend": {},
+		"extra": {
+			"bubble": {
+				"border": 2,
+				"opacity": 0.5,
+			},
+		}
+	}
+}

+ 12 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/readme.md

@@ -0,0 +1,12 @@
+# uCharts JSSDK说明
+1、如不使用uCharts组件,可直接引用u-charts.js,打包编译后会`自动压缩`,压缩后体积约为`98kb`。
+2、如果100kb的体积仍需压缩,请手动删除u-charts.js内您不需要的图表类型,如k线图candle。
+3、config-ucharts.js为uCharts组件的用户配置文件,升级前请`自行备份config-ucharts.js`文件,以免被强制覆盖。
+3、config-echarts.js为ECharts组件的用户配置文件,升级前请`自行备份config-echarts.js`文件,以免被强制覆盖。
+
+# v1.0转v2.0注意事项
+1、opts.colors变更为opts.color
+2、ring圆环图的扩展配置由extra.pie变更为extra.ring
+3、混合图借用的扩展配置由extra.column变更为extra.mix.column
+4、全部涉及到format的格式化属性变更为formatter
+5、不需要再传canvasId及$this参数,如果通过uChats获取context,可能会导致this实例混乱,导致小程序开发者工具报错。如果不使用qiun-data-charts官方组件,需要在new uCharts()实例化之前,自行获取canvas的上下文context(ctx),并传入new中的context(opts.context)。为了能跨更多的端,给您带来的不便敬请谅解。

File diff suppressed because it is too large
+ 6776 - 0
uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts.js


+ 201 - 0
uni_modules/qiun-data-charts/license.md

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 80 - 0
uni_modules/qiun-data-charts/package.json

@@ -0,0 +1,80 @@
+{
+  "id": "qiun-data-charts",
+  "displayName": "秋云 ucharts echarts 高性能跨全端图表组件",
+  "version": "2.3.2-20210627",
+  "description": "uCharts v2.3上线,支持nvue!全新官方图表组件,支持H5及APP用ECharts渲染图表,uniapp可视化首选组件",
+  "keywords": [
+    "ucharts",
+    "echarts",
+    "f2",
+    "图表",
+    "可视化"
+],
+  "repository": "https://gitee.com/uCharts/uCharts",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "前端组件",
+        "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "474119"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        }
+      }
+    }
+  }
+}

File diff suppressed because it is too large
+ 451 - 0
uni_modules/qiun-data-charts/readme.md


File diff suppressed because it is too large
+ 23 - 0
uni_modules/qiun-data-charts/static/app-plus/echarts.min.js


File diff suppressed because it is too large
+ 23 - 0
uni_modules/qiun-data-charts/static/h5/echarts.min.js


+ 6 - 0
uni_modules/uni-datetime-picker/changelog.md

@@ -0,0 +1,6 @@
+## 1.0.6(2021-03-18)
+- 新增 hide-second 属性,时间支持仅选择时、分
+- 修复 选择跟显示的日期不一样的 bug
+- 修复 chang事件触发2次的 bug
+- 修复 分、秒 end 范围错误的 bug
+- 优化 更好的 nvue 适配

+ 45 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js

@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    this.$once('hook:beforeDestroy', () => {
+      document.removeEventListener('keyup', listener)
+    })
+  },
+	render: () => {}
+}
+// #endif

+ 903 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue

@@ -0,0 +1,903 @@
+<template>
+	<view class="uni-datetime-picker">
+		<view @click="initTimePicker">
+			<slot>
+				<view class="uni-datetime-picker-timebox-pointer"
+					:class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}">
+					<text class="uni-datetime-picker-text">{{time}}</text>
+					<view v-if="!time" class="uni-datetime-picker-time">
+						<text class="uni-datetime-picker-text">选择{{title}}</text>
+					</view>
+				</view>
+			</slot>
+		</view>
+		<view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view>
+		<view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']" :style="fixNvueBug">
+			<view class="uni-title">
+				<text class="uni-datetime-picker-text">设置{{title}}</text>
+			</view>
+			<view v-if="dateShow" class="uni-datetime-picker__container-box">
+				<picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd"
+					@change="bindDateChange">
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+				</picker-view>
+				<!-- 兼容 nvue 不支持伪类 -->
+				<text class="uni-datetime-picker-sign sign-left">-</text>
+				<text class="uni-datetime-picker-sign sign-right">-</text>
+			</view>
+			<view v-if="timeShow" class="uni-datetime-picker__container-box">
+				<picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']"
+					:indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange">
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column v-if="!hideSecond">
+						<view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+				</picker-view>
+				<!-- 兼容 nvue 不支持伪类 -->
+				<text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text>
+				<text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text>
+			</view>
+			<view class="uni-datetime-picker-btn">
+				<view @click="clearTime">
+					<text class="uni-datetime-picker-btn-text">清空</text>
+				</view>
+				<view class="uni-datetime-picker-btn-group">
+					<view class="uni-datetime-picker-cancel" @click="tiggerTimePicker">
+						<text class="uni-datetime-picker-btn-text">取消</text>
+					</view>
+					<view @click="setTime">
+						<text class="uni-datetime-picker-btn-text">确定</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- #ifdef H5 -->
+		<keypress v-if="visible" @esc="tiggerTimePicker" @enter="setTime" />
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import keypress from './keypress'
+	// #endif
+
+	/**
+	 * DatetimePicker 时间选择器
+	 * @description 可以同时选择日期和时间的选择器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
+	 * @property {String} type = [datetime | date | time] 显示模式
+	 * @property {Boolean} multiple = [true|false] 是否多选
+	 * @property {String|Number} value 默认值
+	 * @property {String|Number} start 起始日期或时间
+	 * @property {String|Number} end 起始日期或时间
+	 * @property {String} return-type = [timestamp | string]
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: 'UniDatetimePicker',
+		components: {
+			// #ifdef H5
+			keypress
+			// #endif
+		},
+		data() {
+			return {
+				indicatorStyle: `height: 50px;`,
+				visible: false,
+				fixNvueBug: {},
+				dateShow: true,
+				timeShow: true,
+				title: '日期和时间',
+				// 输入框当前时间
+				time: '',
+				// 当前的年月日时分秒
+				year: 1900,
+				month: 0,
+				day: 0,
+				hour: 0,
+				minute: 0,
+				second: 0,
+				// 起始时间
+				startYear: 1920,
+				startMonth: 1,
+				startDay: 1,
+				startHour: 0,
+				startMinute: 0,
+				startSecond: 0,
+				// 结束时间
+				endYear: 2120,
+				endMonth: 12,
+				endDay: 31,
+				endHour: 23,
+				endMinute: 59,
+				endSecond: 59,
+			}
+		},
+		props: {
+			type: {
+				type: String,
+				default: 'datetime'
+			},
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			start: {
+				type: [Number, String],
+				default: ''
+			},
+			end: {
+				type: [Number, String],
+				default: ''
+			},
+			returnType: {
+				type: String,
+				default: 'string'
+			},
+			disabled: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: [Boolean, String],
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		watch: {
+			value: {
+				handler(newVal, oldVal) {
+					if (newVal) {
+						this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式
+						this.initTime(false)
+					} else {
+						this.parseValue(Date.now())
+					}
+				},
+				immediate: true
+			},
+			type: {
+				handler(newValue) {
+					if (newValue === 'date') {
+						this.dateShow = true
+						this.timeShow = false
+						this.title = '日期'
+					} else if (newValue === 'time') {
+						this.dateShow = false
+						this.timeShow = true
+						this.title = '时间'
+					} else {
+						this.dateShow = true
+						this.timeShow = true
+						this.title = '日期和时间'
+					}
+				},
+				immediate: true
+			},
+			start: {
+				handler(newVal) {
+					this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'start') //兼容 iOS、safari 日期格式
+				},
+				immediate: true
+			},
+			end: {
+				handler(newVal) {
+					this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'end') //兼容 iOS、safari 日期格式
+				},
+				immediate: true
+			},
+
+			// 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项
+			months(newVal) {
+				this.checkValue('month', this.month, newVal)
+			},
+			days(newVal) {
+				this.checkValue('day', this.day, newVal)
+			},
+			hours(newVal) {
+				this.checkValue('hour', this.hour, newVal)
+			},
+			minutes(newVal) {
+				this.checkValue('minute', this.minute, newVal)
+			},
+			seconds(newVal) {
+				this.checkValue('second', this.second, newVal)
+			}
+		},
+		created() {
+			this.form = this.getForm('uniForms')
+			this.formItem = this.getForm('uniFormsItem')
+
+			if (this.formItem) {
+				if (this.formItem.name) {
+					this.rename = this.formItem.name
+					this.form.inputChildrens.push(this)
+				}
+			}
+		},
+		computed: {
+			// 当前年、月、日、时、分、秒选择范围
+			years() {
+				return this.getCurrentRange('year')
+			},
+
+			months() {
+				return this.getCurrentRange('month')
+			},
+
+			days() {
+				return this.getCurrentRange('day')
+			},
+
+			hours() {
+				return this.getCurrentRange('hour')
+			},
+
+			minutes() {
+				return this.getCurrentRange('minute')
+			},
+
+			seconds() {
+				return this.getCurrentRange('second')
+			},
+
+			// picker 当前值数组
+			ymd() {
+				return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay]
+			},
+			hms() {
+				return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond]
+			},
+
+			// 当前 date 是 start
+			currentDateIsStart() {
+				return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay
+			},
+
+			// 当前 date 是 end
+			currentDateIsEnd() {
+				return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay
+			},
+
+			// 当前年、月、日、时、分、秒的最小值和最大值
+			minYear() {
+				return this.startYear
+			},
+			maxYear() {
+				return this.endYear
+			},
+			minMonth() {
+				if (this.year === this.startYear) {
+					return this.startMonth
+				} else {
+					return 1
+				}
+			},
+			maxMonth() {
+				if (this.year === this.endYear) {
+					return this.endMonth
+				} else {
+					return 12
+				}
+			},
+			minDay() {
+				if (this.year === this.startYear && this.month === this.startMonth) {
+					return this.startDay
+				} else {
+					return 1
+				}
+			},
+			maxDay() {
+				if (this.year === this.endYear && this.month === this.endMonth) {
+					return this.endDay
+				} else {
+					return this.daysInMonth(this.year, this.month)
+				}
+			},
+			minHour() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart) {
+						return this.startHour
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					return this.startHour
+				}
+			},
+			maxHour() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd) {
+						return this.endHour
+					} else {
+						return 23
+					}
+				}
+				if (this.type === 'time') {
+					return this.endHour
+				}
+			},
+			minMinute() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart && this.hour === this.startHour) {
+						return this.startMinute
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.startHour) {
+						return this.startMinute
+					} else {
+						return 0
+					}
+				}
+			},
+			maxMinute() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd && this.hour === this.endHour) {
+						return this.endMinute
+					} else {
+						return 59
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.endHour) {
+						return this.endMinute
+					} else {
+						return 59
+					}
+				}
+			},
+			minSecond() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) {
+						return this.startSecond
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.startHour && this.minute === this.startMinute) {
+						return this.startSecond
+					} else {
+						return 0
+					}
+				}
+			},
+			maxSecond() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) {
+						return this.endSecond
+					} else {
+						return 59
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.endHour && this.minute === this.endMinute) {
+						return this.endSecond
+					} else {
+						return 59
+					}
+				}
+			}
+		},
+
+		mounted() {
+			// #ifdef APP-NVUE
+			const res = uni.getSystemInfoSync();
+			this.fixNvueBug = {
+				top: res.windowHeight / 2,
+				left: res.windowWidth / 2
+			}
+			// #endif
+		},
+
+		methods: {
+			/**
+			 * @param {Object} item
+			 * 小于 10 在前面加个 0
+			 */
+
+			lessThanTen(item) {
+				return item < 10 ? '0' + item : item
+			},
+
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+
+			/**
+			 * 解析时分秒字符串,例如:00:00:00
+			 * @param {String} timeString
+			 */
+			parseTimeType(timeString) {
+				if (timeString) {
+					let timeArr = timeString.split(':')
+					this.hour = Number(timeArr[0])
+					this.minute = Number(timeArr[1])
+					this.second = Number(timeArr[2])
+				}
+			},
+
+			/**
+			 * 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000
+			 * @param {String | Number} datetime
+			 */
+			initPickerValue(datetime) {
+				let defaultValue = null
+				if (datetime) {
+					defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end)
+				} else {
+					defaultValue = Date.now()
+					defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end)
+				}
+				this.parseValue(defaultValue)
+			},
+
+			/**
+			 * 初始值规则:
+			 * - 用户设置初始值 value
+			 * 	- 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start
+			 * 	- 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start
+			 * 	- 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end
+			 * 	- 无起始终止时间,则初始值为 value
+			 * - 无初始值 value,则初始值为当前本地时间 Date.now()
+			 * @param {Object} value
+			 * @param {Object} dateBase
+			 */
+			compareValueWithStartAndEnd(value, start, end) {
+				let winner = null
+				value = this.superTimeStamp(value)
+				start = this.superTimeStamp(start)
+				end = this.superTimeStamp(end)
+
+				if (start && end) {
+					if (value < start) {
+						winner = new Date(start)
+					} else if (value > end) {
+						winner = new Date(end)
+					} else {
+						winner = new Date(value)
+					}
+				} else if (start && !end) {
+					winner = start <= value ? new Date(value) : new Date(start)
+				} else if (!start && end) {
+					winner = value <= end ? new Date(value) : new Date(end)
+				} else {
+					winner = new Date(value)
+				}
+
+				return winner
+			},
+
+			/**
+			 * 转换为可比较的时间戳,接受日期、时分秒、时间戳
+			 * @param {Object} value
+			 */
+			superTimeStamp(value) {
+				let dateBase = ''
+				if (this.type === 'time' && value && typeof value === 'string') {
+					const now = new Date()
+					const year = now.getFullYear()
+					const month = now.getMonth() + 1
+					const day = now.getDate()
+					dateBase = year + '/' + month + '/' + day + ' '
+				}
+				if (Number(value) && typeof value !== NaN) {
+					value = parseInt(value)
+					dateBase = 0
+				}
+				return this.createTimeStamp(dateBase + value)
+			},
+
+			/**
+			 * 解析默认值 value,字符串、时间戳
+			 * @param {Object} defaultTime
+			 */
+			parseValue(value) {
+				if (!value) return
+				if (this.type === 'time' && typeof value === "string") {
+					this.parseTimeType(value)
+				} else {
+					let defaultDate = null
+					defaultDate = new Date(value)
+					if (this.type !== 'time') {
+						this.year = defaultDate.getFullYear()
+						this.month = defaultDate.getMonth() + 1
+						this.day = defaultDate.getDate()
+					}
+					if (this.type !== 'date') {
+						this.hour = defaultDate.getHours()
+						this.minute = defaultDate.getMinutes()
+						this.second = defaultDate.getSeconds()
+					}
+				}
+				if (this.hideSecond) {
+					this.second = 0
+				}
+			},
+
+			/**
+			 * 解析可选择时间范围 start、end,年月日字符串、时间戳
+			 * @param {Object} defaultTime
+			 */
+			parseDatetimeRange(point, pointType) {
+				if (point && this.type === 'time') {
+					const pointArr = point.split(':')
+					this[pointType + 'Hour'] = Number(pointArr[0])
+					this[pointType + 'Minute'] = Number(pointArr[1])
+					this[pointType + 'Second'] = Number(pointArr[2])
+				} else {
+					if (!point) {
+						pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60
+						return
+					}
+					if (Number(point) && Number(point) !== NaN) {
+						point = parseInt(point)
+					}
+					// datetime 的 end 没有时分秒, 则不限制
+					const hasTime = /[0-9]:[0-9]/
+					if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test(
+							point)) {
+						point = point + ' 23:59:59'
+					}
+					const pointDate = new Date(point)
+					this[pointType + 'Year'] = pointDate.getFullYear()
+					this[pointType + 'Month'] = pointDate.getMonth() + 1
+					this[pointType + 'Day'] = pointDate.getDate()
+					if (this.type === 'datetime') {
+						this[pointType + 'Hour'] = pointDate.getHours()
+						this[pointType + 'Minute'] = pointDate.getMinutes()
+						this[pointType + 'Second'] = pointDate.getSeconds()
+					}
+				}
+			},
+
+			// 获取 年、月、日、时、分、秒 当前可选范围
+			getCurrentRange(value) {
+				const range = []
+				for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) {
+					range.push(i)
+				}
+				return range
+			},
+
+			// 字符串首字母大写
+			capitalize(str) {
+				return str.charAt(0).toUpperCase() + str.slice(1)
+			},
+
+			// 检查当前值是否在范围内,不在则当前值重置为可选范围第一项
+			checkValue(name, value, values) {
+				if (values.indexOf(value) === -1) {
+					this[name] = values[0]
+				}
+			},
+
+			// 每个月的实际天数
+			daysInMonth(year, month) { // Use 1 for January, 2 for February, etc.
+				return new Date(year, month, 0).getDate();
+			},
+
+			//兼容 iOS、safari 日期格式
+			fixIosDateFormat(value) {
+				if (typeof value === 'string') {
+					value = value.replace(/-/g, '/')
+				}
+				return value
+			},
+
+			/**
+			 * 生成时间戳
+			 * @param {Object} time
+			 */
+			createTimeStamp(time) {
+				if (!time) return
+				if (typeof time === "number") {
+					return time
+				} else {
+					time = time.replace(/-/g, '/')
+					if (this.type === 'date') {
+						time = time + ' ' + '00:00:00'
+					}
+					return Date.parse(time)
+				}
+			},
+
+			/**
+			 * 生成日期或时间的字符串
+			 */
+			createDomSting() {
+				const yymmdd = this.year +
+					'-' +
+					this.lessThanTen(this.month) +
+					'-' +
+					this.lessThanTen(this.day)
+
+				let hhmmss = this.lessThanTen(this.hour) +
+					':' +
+					this.lessThanTen(this.minute)
+
+				if(!this.hideSecond) {
+					hhmmss = hhmmss + ':' + this.lessThanTen(this.second)
+				}
+
+				if (this.type === 'date') {
+					return yymmdd
+				} else if (this.type === 'time') {
+					return hhmmss
+				} else {
+					return yymmdd + ' ' + hhmmss
+				}
+			},
+
+			/**
+			 * 初始化返回值,并抛出 change 事件
+			 */
+			initTime(emit = true) {
+				this.time = this.createDomSting()
+				if (!emit) return
+				if (this.returnType === 'timestamp' && this.type !== 'time') {
+					this.formItem && this.formItem.setValue(this.createTimeStamp(this.time))
+					this.$emit('change', this.createTimeStamp(this.time))
+					this.$emit('input', this.createTimeStamp(this.time))
+				} else {
+					this.formItem && this.formItem.setValue(this.time)
+					this.$emit('change', this.time)
+					this.$emit('input', this.time)
+				}
+			},
+
+			/**
+			 * 用户选择日期或时间更新 data
+			 * @param {Object} e
+			 */
+			bindDateChange(e) {
+				const val = e.detail.value
+				this.year = this.years[val[0]]
+				this.month = this.months[val[1]]
+				this.day = this.days[val[2]]
+			},
+			bindTimeChange(e) {
+				const val = e.detail.value
+				this.hour = this.hours[val[0]]
+				this.minute = this.minutes[val[1]]
+				this.second = this.seconds[val[2]]
+			},
+
+			/**
+			 * 初始化弹出层
+			 */
+			initTimePicker() {
+				if (this.disabled) return
+				const value = this.fixIosDateFormat(this.value)
+				this.initPickerValue(value)
+				this.visible = !this.visible
+			},
+
+			/**
+			 * 触发或关闭弹框
+			 */
+			tiggerTimePicker(e) {
+				this.visible = !this.visible
+			},
+
+			/**
+			 * 用户点击“清空”按钮,清空当前值
+			 */
+			clearTime() {
+				this.time = ''
+				this.formItem && this.formItem.setValue(this.time)
+				this.$emit('change', this.time)
+				this.$emit('input', this.time)
+				this.tiggerTimePicker()
+			},
+
+			/**
+			 * 用户点击“确定”按钮
+			 */
+			setTime() {
+				this.initTime()
+				this.tiggerTimePicker()
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-datetime-picker {
+		/* #ifndef APP-NVUE */
+		width: 100%;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-view {
+		height: 130px;
+		width: 270px;
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-item {
+		height: 50px;
+		line-height: 50px;
+		text-align: center;
+		font-size: 14px;
+	}
+
+	.uni-datetime-picker-btn {
+		margin-top: 60px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		cursor: pointer;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+	}
+
+	.uni-datetime-picker-btn-text {
+		font-size: 14px;
+		color: #007AFF;
+	}
+
+	.uni-datetime-picker-btn-group {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-datetime-picker-cancel {
+		margin-right: 30px;
+	}
+
+	.uni-datetime-picker-mask {
+		position: fixed;
+		bottom: 0px;
+		top: 0px;
+		left: 0px;
+		right: 0px;
+		background-color: rgba(0, 0, 0, 0.4);
+		transition-duration: 0.3s;
+		z-index: 998;
+	}
+
+	.uni-datetime-picker-popup {
+		border-radius: 8px;
+		padding: 30px;
+		width: 270px;
+		/* #ifdef APP-NVUE */
+		height: 500px;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		width: 330px;
+		/* #endif */
+		background-color: #fff;
+		position: fixed;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%);
+		transition-duration: 0.3s;
+		z-index: 999;
+	}
+
+	.fix-nvue-height {
+		/* #ifdef APP-NVUE */
+		height: 330px;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-time {
+		color: grey;
+	}
+
+	.uni-datetime-picker-column {
+		height: 50px;
+	}
+
+	.uni-datetime-picker-timebox {
+
+		border: 1px solid #E5E5E5;
+		border-radius: 5px;
+		padding: 7px 10px;
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-timebox-pointer {
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+	}
+
+
+	.uni-datetime-picker-disabled {
+		opacity: 0.4;
+		/* #ifdef H5 */
+		cursor: not-allowed !important;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-text {
+		font-size: 14px;
+	}
+
+	.uni-datetime-picker-sign {
+		position: absolute;
+		top: 53px;
+		/* 减掉 10px 的元素高度,兼容nvue */
+		color: #999;
+		/* #ifdef APP-NVUE */
+		font-size: 16px;
+		/* #endif */
+	}
+
+	.sign-left {
+		left: 86px;
+	}
+
+	.sign-right {
+		right: 86px;
+	}
+
+	.sign-center {
+		left: 135px;
+	}
+
+	.uni-datetime-picker__container-box {
+		position: relative;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-top: 40px;
+	}
+
+	.time-hide-second {
+		width: 180px;
+	}
+</style>

+ 82 - 0
uni_modules/uni-datetime-picker/package.json

@@ -0,0 +1,82 @@
+{
+  "id": "uni-datetime-picker",
+  "displayName": "DatetimePicker 日期选择器",
+  "version": "1.0.6",
+  "description": "DatetimePicker 可以同时选择日期和时间的选择器",
+  "keywords": [
+    "DatetimePicker",
+    "uni-ui",
+    "日期时间选择器",
+    "日期时间"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}

+ 61 - 0
uni_modules/uni-datetime-picker/readme.md

@@ -0,0 +1,61 @@
+
+
+## DatetimePicker 时间选择器
+> 代码块: `uDatetimePicker`
+
+
+该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。
+
+若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。
+
+
+___点击 picker 默认值规则:___
+
+- 若设置初始值 value, 会显示在 picker 显示框中; 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中
+	- 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start
+	- 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start
+	- 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end
+	- 无起始终止时间,则初始值为 value
+
+### 安装方式
+
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
+
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
+
+### 基本用法
+
+在 ``template`` 中使用组件
+
+```html
+<uni-datetime-picker></uni-datetime-picker>
+<uni-datetime-picker v-model="vModelDatetime" start="2010-6-10 08:30:30" end="2021-6-10 08:30:30"></uni-datetime-picker>
+<uni-datetime-picker :value="timestamp" return-type="timestamp" start="1276129830000" end="1623285030000" @change="timestampChange"></uni-datetime-picker>
+<uni-datetime-picker type="date" :value="date" start="2020-6-15" end="2025-6-15" @change="dateChange"></uni-datetime-picker>
+<uni-datetime-picker type="time" :value="time" start="06:30:30" end="12:30:30" @change="timeChange"></uni-datetime-picker>
+```
+
+## API
+
+### DatetimePicker Props
+
+|属性名			|类型						|默认值		|值域									|说明																											|
+|:-:				|:-:						|:-:			|											|:-:																											|
+|type				|String					|datetime	|datetime、date、time	|选择器类型																								|
+|value			|String、Number	|-				|-										|输入框当前值																							|
+|start			|String、Number	|-				|-										|最小值,可以使用日期的字符串(String)、时间戳(Number)	|
+|end				|String、Number	|-				|-										|最大值,可以使用日期的字符串(String)、时间戳(Number)	|
+|return-type|String					|timestamp|timestamp 、string		|返回值格式																								|
+|border			|Boolean、String|true			|											|是否有边框																								|
+|hide-second|Boolean、String|false		|											|是否隐藏秒																								|
+|disabled		|Boolean、String|false		|											|是否不可选择																							|
+
+
+
+注:如 type 为 time 类型,无对应的时间戳,则返回值格式 return-type 无论为何值,都会返回 string
+
+### DatetimePicker Events
+
+|事件名称	|说明																				|返回值	|
+|:-:		|:-:																				|:-:		|
+|change	|确定日期时间时触发的事件,参数为当前选择的 value	|-			|