zouling преди 8 месеца
ревизия
21ed21ab65
променени са 100 файла, в които са добавени 30426 реда и са изтрити 0 реда
  1. 20 0
      .hbuilderx/launch.json
  2. 9 0
      1.txt
  3. 159 0
      App.vue
  4. 21 0
      LICENSE
  5. 52 0
      README.md
  6. 64 0
      api/index/index.js
  7. 79 0
      api/login.js
  8. 39 0
      api/mine/class.js
  9. 195 0
      api/mine/files.js
  10. 86 0
      api/mine/mine.js
  11. 63 0
      api/mine/news.js
  12. 42 0
      api/mine/order.js
  13. 25 0
      api/mine/payslip.js
  14. 240 0
      api/mine/register.js
  15. 89 0
      api/mine/score.js
  16. 64 0
      api/mine/trends.js
  17. 55 0
      api/system/user.js
  18. 130 0
      api/work/index.js
  19. 39 0
      api/work/menu.js
  20. 71 0
      components/footer/footer.vue
  21. 8 0
      components/home/list.vue
  22. 88 0
      components/home/luswiper.vue
  23. 82 0
      components/home/luvideo.vue
  24. 39 0
      components/nodata/nodata.vue
  25. 501 0
      components/popup/popup.vue
  26. 631 0
      components/shlist/list.vue
  27. 168 0
      components/timetable/timetable.vue
  28. 176 0
      components/toptab/phonebtn.vue
  29. 99 0
      components/toptab/tab.vue
  30. 31 0
      config.js
  31. BIN
      f8ba4038bda577d6c56968e3f4a293f4.keystore
  32. 21 0
      main.js
  33. 112 0
      manifest.json
  34. 406 0
      mine/components/ba-tree-picker/danpicker.vue
  35. 524 0
      mine/components/list/list.vue
  36. 370 0
      mine/components/login/applyparent.vue
  37. 262 0
      mine/components/login/applyregister.vue
  38. 263 0
      mine/components/login/applyteacher.vue
  39. 570 0
      mine/components/popup/popup.vue
  40. 79 0
      mine/components/popup/stepbar.vue
  41. 58 0
      mine/components/popup/watermark.vue
  42. 320 0
      mine/components/qiun-data-charts/changelog.md
  43. 1620 0
      mine/components/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue
  44. 42 0
      mine/components/qiun-data-charts/components/qiun-error/qiun-error.vue
  45. 162 0
      mine/components/qiun-data-charts/components/qiun-loading/loading1.vue
  46. 170 0
      mine/components/qiun-data-charts/components/qiun-loading/loading2.vue
  47. 173 0
      mine/components/qiun-data-charts/components/qiun-loading/loading3.vue
  48. 222 0
      mine/components/qiun-data-charts/components/qiun-loading/loading4.vue
  49. 229 0
      mine/components/qiun-data-charts/components/qiun-loading/loading5.vue
  50. 36 0
      mine/components/qiun-data-charts/components/qiun-loading/qiun-loading.vue
  51. 422 0
      mine/components/qiun-data-charts/js_sdk/u-charts/config-echarts.js
  52. 633 0
      mine/components/qiun-data-charts/js_sdk/u-charts/config-ucharts.js
  53. 5 0
      mine/components/qiun-data-charts/js_sdk/u-charts/readme.md
  54. 7706 0
      mine/components/qiun-data-charts/js_sdk/u-charts/u-charts.js
  55. 17 0
      mine/components/qiun-data-charts/js_sdk/u-charts/u-charts.min.js
  56. 201 0
      mine/components/qiun-data-charts/license.md
  57. 81 0
      mine/components/qiun-data-charts/package.json
  58. 84 0
      mine/components/qiun-data-charts/readme.md
  59. 22 0
      mine/components/qiun-data-charts/static/app-plus/echarts.min.js
  60. 22 0
      mine/components/qiun-data-charts/static/h5/echarts.min.js
  61. 92 0
      mine/components/search/search.vue
  62. 164 0
      mine/components/share/share.vue
  63. 577 0
      mine/components/shmily-drag-image/shmily-drag-image.vue
  64. 65 0
      mine/components/zb-table/all.js
  65. 180 0
      mine/components/zb-table/components/table-checkbox.vue
  66. 78 0
      mine/components/zb-table/components/table-h5-summary.vue
  67. 59 0
      mine/components/zb-table/components/table-side-summary.vue
  68. 77 0
      mine/components/zb-table/components/table-summary.vue
  69. 50 0
      mine/components/zb-table/components/zb-load-more.vue
  70. 88 0
      mine/components/zb-table/js/summary.js
  71. 51 0
      mine/components/zb-table/js/util.js
  72. 1255 0
      mine/components/zb-table/zb-table.vue
  73. 1264 0
      mine/components/zb-table/zb-tables.vue
  74. 876 0
      mine/pages/files/addstudent.vue
  75. 702 0
      mine/pages/files/addteacher.vue
  76. 347 0
      mine/pages/files/detail.vue
  77. 145 0
      mine/pages/files/height.vue
  78. 215 0
      mine/pages/files/heightlist.vue
  79. 248 0
      mine/pages/files/history.vue
  80. 284 0
      mine/pages/files/leave.vue
  81. 281 0
      mine/pages/files/leavelist.vue
  82. 582 0
      mine/pages/files/map.vue
  83. 575 0
      mine/pages/files/maps.nvue
  84. 158 0
      mine/pages/files/mind.vue
  85. 214 0
      mine/pages/files/mindlist.vue
  86. 365 0
      mine/pages/files/student.vue
  87. 197 0
      mine/pages/files/teacher.vue
  88. 280 0
      mine/pages/files/teacherdetail.vue
  89. 229 0
      mine/pages/login/query.vue
  90. 209 0
      mine/pages/login/register.vue
  91. 51 0
      mine/pages/login/word.vue
  92. 254 0
      mine/pages/mine/addclass.vue
  93. 371 0
      mine/pages/mine/applyparent.vue
  94. 313 0
      mine/pages/mine/applyregister.vue
  95. 343 0
      mine/pages/mine/applyteacher.vue
  96. 308 0
      mine/pages/mine/auth.vue
  97. 131 0
      mine/pages/mine/exit.vue
  98. 125 0
      mine/pages/mine/limit.vue
  99. 264 0
      mine/pages/mine/roles.vue
  100. 162 0
      mine/pages/mine/school.vue

+ 20 - 0
.hbuilderx/launch.json

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

+ 9 - 0
1.txt

@@ -0,0 +1,9 @@
+包名:zs.cfschool.txt
+
+
+证书别名:__uni__d7019d4
+证书私钥密码:AYBNO2qb
+
+SHA1: 5B:E0:0E:9B:8E:8E:28:E1:3B:09:5E:3F:00:77:38:A1:21:2A:C2:63
+
+

+ 159 - 0
App.vue

@@ -0,0 +1,159 @@
+<script>
+  import config from './config'
+  import store from '@/store'
+  import { getToken } from '@/utils/auth'
+import self from '@/utils/location.js';
+import {getAdrinfo} from "@/api/index/index.js"
+  export default {
+    onLaunch: function() {
+      this.initApp()
+	  // 小程序强制更新
+	  // #ifdef MP-WEIXIN
+	  const updateManager = uni.getUpdateManager()
+	    updateManager.onCheckForUpdate(function (res) {
+	      // 请求完新版本信息的回调
+			updateManager.onUpdateReady(function () {	   
+			  uni.showModal({   
+			    title: '更新提示',   
+			    content: '新版本已经准备好,是否重启应用?',   
+			    success: function (res) {   
+			      if (res.confirm) { 
+			        // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启  
+			        updateManager.applyUpdate()   
+			      }
+				   
+			    }
+				   
+			  })
+				   
+			})
+	    })
+	   
+	    updateManager.onUpdateFailed(function () {
+	      // 新的版本下载失败
+	      uni.showModal({
+	        title: '更新提示',
+	        content: '新版本下载失败',
+	        showCancel: false
+	      })
+	   
+	    })
+		// #endif
+    },
+    methods: {
+      // 初始化应用
+      initApp() {
+        // 初始化应用配置
+        this.initConfig()
+        // 检查用户登录状态
+		this.checkLogin()
+        //#ifdef H5
+        
+        //#endif
+      },
+      initConfig() {
+        this.globalData.config = config
+      },
+	  getAdrinfoFn(res){
+	  	var params={
+	  		address:res.address,
+	  		longitude:res.lng,
+	  		latitude:res.lat,
+	  	}
+	  	getAdrinfo(params).then(res=>{
+	  	})
+	  },
+      checkLogin() {
+		  var that=this;
+        if (getToken()) {
+			// #ifndef H5
+			self.getLocation(function(res){
+				if(res==-1){
+					// that.setflag=true
+				}else{
+					that.getAdrinfoFn(res)
+				}			
+			})
+			// #endif
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss">
+  @import '@/static/scss/index.scss';
+  @import "@/static/style.css";
+  /* #ifdef MP-WEIXIN */
+  .ytbox /deep/ uni-textarea{flex: 1;width: auto;text-align: right;}
+  
+  .xmmain /deep/ .uni-data-checklist .checklist-group{display: block;}
+    .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box{padding: 28rpx 0;margin: 0;}
+     
+     .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box .checklist-text{color: #343434;font-size: 34rpx;font-weight: bold;}
+    .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box .checkbox__inner{margin-right: 32rpx;}
+    .xmmain  /deep/ .uni-data-checklist .checklist-group .checklist-box.is--default.is-checked .checkbox__inner{border-color: #FF440B; background-color: #FF440B;}
+    .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box.is--default.is-checked .checklist-text{color: #343434;}
+  
+ .addbox /deep/ .uni-forms{flex: 1;}
+ .addbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 30rpx;font-weight: bold;
+ color: #161616;}
+ .addbox /deep/ .uni-forms .uni-forms-item{margin-bottom: 0;padding: 4rpx 32rpx;
+ 	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+ }
+ .addbox /deep/  .uni-easyinput{height: 70rpx;}
+ // .addbox /deep/  .uni-textarea-textarea{height: auto;}
+ .addbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+ .addbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+ .addbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+ .addbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+  .addbox /deep/ .uni-forms-item__error{margin-top:-12rpx;left: auto;right: 0;}
+  .addbox /deep/ .uni-data-checklist .checklist-group .checklist-box{margin-right: 30rpx;}
+  .addbox /deep/ .uni-forms-item__content{justify-content: flex-end;}
+   .addbox /deep/ .uni-data-checklist .checklist-group{justify-content: flex-end;}
+   
+   
+   //注册
+   .regbox /deep/ .uni-forms{flex: 1;}
+      .regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+      color: #161616;}
+      .regbox /deep/ .uni-forms .uni-forms-item{padding: 28rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+      	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+      }
+      .regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+      .regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+      .regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+      .regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+       .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+	.container  .regbox /deep/ .uni-forms .uni-forms-item{padding: 10rpx 24rpx 10rpx;border-bottom: none;}
+	.container  .regbox /deep/ .uni-forms-item__error{margin-top:-16rpx;left: auto;right: 0;}
+// 日期格式
+.mind /deep/ .uni-input-wrapper{text-align: right;font-size: 30rpx;}
+.mind /deep/ .uni-date__x-input{padding: 0;text-align: right;font-size: 30rpx;}
+.mind /deep/ .uni-date-x{padding: 0;}
+.mind /deep/ .uniui-calendar::before{display: none;}
+.mind /deep/ .uni-input-placeholder{color:#AAAAAA;font-size: 30rpx;}
+
+
+// 历史记录
+.zb-table /deep/ .zb-table-fixed{background: #F1F5FF !important;}
+.zb-table /deep/ .item-th{text-align: center !important;padding: 0 4rpx;background: #F1F5FF !important;text-align: center;border-bottom: none !important;}
+.zb-table /deep/ .item-td{text-align: center !important;padding: 0 4rpx;}
+.container /deep/ .zb-table-fixed{background: #F1F5FF !important;}
+.container /deep/ .item-th{text-align: center !important;padding: 0 4rpx;background: #F1F5FF !important;text-align: center;}
+.container /deep/ .item-td{text-align: center !important;padding: 0 4rpx;}
+// 工资条
+.pay .paybox /deep/  .zb-table-header{background-color: #F2F5FB !important;}
+.pay .paybox /deep/  .zb-table-applet .zb-table-header .zb-stick-side{background-color: #F2F5FB !important;}
+.pay .paybox /deep/  .odd{background-color: #F2F5FB !important;}
+.pay .paybox /deep/ .item-td{border-bottom: none !important;font-weight: bold !important;font-size: 26rpx ;}
+.pay .paybox /deep/ .item-th{border-bottom: none !important;background-color: #F2F5FB !important;font-weight: bold !important;font-size: 26rpx;}
+.pay .paybox /deep/ .zb-table-tbody{padding-bottom: 20rpx !important;}
+.detail /deep/  .zb-table-header{background-color: #F2F5FB !important;}
+.detail /deep/  .zb-table-applet .zb-table-header .zb-stick-side{background-color: #F2F5FB !important;}
+.detail /deep/  .odd{background-color: #F2F5FB !important;}
+.detail /deep/ .item-td{border-bottom: none !important;}
+.detail /deep/ .item-th{border-bottom: none !important;background-color: #F2F5FB !important;}
+  /* #endif */
+
+</style>

+ 21 - 0
LICENSE

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

+ 52 - 0
README.md

@@ -0,0 +1,52 @@
+<p align="center">
+	<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-43e3941654fa3054c9684bf53d1b1d356a1.png">
+</p>
+<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v1.1.0</h1>
+<h4 align="center">基于UniApp开发的轻量级移动端框架</h4>
+<p align="center">
+	<a href="https://gitee.com/y_project/RuoYi-App/stargazers"><img src="https://gitee.com/y_project/RuoYi-App/badge/star.svg?theme=dark"></a>
+	<a href="https://gitee.com/y_project/RuoYi-App"><img src="https://img.shields.io/badge/RuoYi-v1.1.0-brightgreen.svg"></a>
+	<a href="https://gitee.com/y_project/RuoYi-App/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
+</p>
+
+## 平台简介
+
+RuoYi App 移动解决方案,采用uniapp框架,一份代码多终端适配,同时支持APP、小程序、H5!实现了与[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)、[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)完美对接的移动解决方案!目前已经实现登录、我的、工作台、编辑资料、头像修改、密码修改、常见问题、关于我们等基础功能。
+
+* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 或 [RuoYi-Cloud](https://github.com/yangzongzhuan/RuoYi-Cloud) 版本。
+* 应用框架基于[uniapp](https://uniapp.dcloud.net.cn/),支持小程序、H5、Android和IOS。
+* 前端组件采用[uni-ui](https://github.com/dcloudio/uni-ui),全端兼容的高性能UI框架。
+* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
+* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
+
+
+## 技术文档
+
+- 官网网站:[http://ruoyi.vip](http://ruoyi.vip)
+- 文档地址:[http://doc.ruoyi.vip](http://doc.ruoyi.vip)
+- H5页体验:[http://h5.ruoyi.vip](http://h5.ruoyi.vip)
+- QQ交流群: ①133713780
+- 小程序体验
+
+<img src="https://oscimg.oschina.net/oscnet/up-26c76dc90b92acdbd9ac8cd5252f07c8ad9.jpg" alt="小程序演示"/>
+ 
+
+## 演示图
+
+<table>
+    <tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-3ea20e447ac621a161e395fb53ccc683d84.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-a6f23cf9a371a30165e135eff6d9ae89a9d.png"/></td>
+		<td><img src="https://oscimg.oschina.net/oscnet/up-ff5f62016bf6624c1ff27eee57499dccd44.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-b9a582fdb26ec69d407fabd044d2c8494df.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-96427ee08fca29d77934cfc8d1b1a637cef.png"/></td>
+		<td><img src="https://oscimg.oschina.net/oscnet/up-5fdadc582d24cccd7727030d397b63185a3.png"/></td>
+    </tr>
+	<tr>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-0a36797b6bcc50c36d40c3c782665b89efc.png"/></td>
+        <td><img src="https://oscimg.oschina.net/oscnet/up-d77995cc00687cedd00d5ac7d68a07ea276.png"/></td>
+		<td><img src="https://oscimg.oschina.net/oscnet/up-fa8f5ab20becf59b4b38c1b92a9989e7109.png"/></td>
+    </tr>
+</table>

+ 64 - 0
api/index/index.js

@@ -0,0 +1,64 @@
+import request from '@/utils/request'
+// 首页
+export function getApplet(data) {
+  return request({
+    'url': '/applet/index',
+    'method': 'post',
+	'data':data
+  })
+}
+// 准备放学
+export function getAppxiaKe(data) {
+  return request({
+    'url': '/applet/xiaKe',
+    'method': 'post',
+	'data':data
+  })
+}
+// 首页列表
+export function getApplist(data) {
+  return request({
+    'url': '/applet/indexList',
+    'method': 'post',
+	'data':data
+  })
+}
+//
+export function getTablenow(data) {
+  return request({
+    'url': '/course/table/now',
+    'method': 'get',
+	'data':data
+  })
+}
+// 家长放学时间
+export function getxiaKeTime(data) {
+  return request({
+    'url': '/applet/xiaKeTime',
+    'method': 'post',
+	'data':data
+  })
+}
+//定位信息orientation:info:add
+export function getAdrinfo(data) {
+  return request({
+    'url': '/orientation/info',
+    'method': 'post',
+	'data':data
+  })
+}
+// 家长 包含的学校
+export function getptenantList(data) {
+  return request({
+    'url': '/auth/parents/tenant/list',
+    'method': 'get',
+  })
+}
+// 切换学校
+export function gettenantCheck(data) {
+  return request({
+    'url': '/system/tenant/dynamic/'+data,
+    'method': 'get',
+  })
+}
+

+ 79 - 0
api/login.js

@@ -0,0 +1,79 @@
+import request from '@/utils/request'
+
+// 登录方法
+export function login(username, password, code, uuid,tenantId,clientId,grantType) {
+  const data = {
+    username,
+    password,
+    code,
+    uuid,
+	tenantId,
+	clientId,
+	grantType
+  }
+  return request({
+    'url': '/auth/login',
+    headers: {
+      isToken: false
+    },
+    'method': 'post',
+    'data': data
+  })
+}
+// 解码接口
+export function getweChatOpenid(data) {
+  return request({
+    'url': '/weChatOpenid',
+    'method': 'post',
+	'data':data
+  })
+}
+// 微信登录
+export function getweChatLogin(data) {
+  return request({
+    'url': '/auth/weChatLogin',
+    'method': 'post',
+	'data':data
+  })
+}
+// 获取用户详细信息
+export function getInfo() {
+  return request({
+    'url': '/system/user/getInfo',
+    'method': 'get'
+  })
+}
+// 获取用户详细信息
+export function gettenantList() {
+  return request({
+    'url': '/auth/tenant/list',
+    'method': 'get'
+  })
+}
+// 获取注册学校详细信息
+export function getschoolList(data) {
+  return request({
+    'url': '/auth/school/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 退出方法
+export function logout() {
+  return request({
+    'url': '/auth/logout',
+    'method': 'post'
+  })
+}
+
+// 获取验证码
+export function getCodeImg() {
+  return request({
+    'url': '/auth/code',
+    headers: {
+      isToken: false
+    },
+    method: 'get',
+    timeout: 20000
+  })
+}

+ 39 - 0
api/mine/class.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+// 获取查询老师-班级 列表 formal:class:list
+export function getclassListFn(data) {
+  return request({
+    'url': '/formal/class/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 老师-班级详情 formal:class:list
+export function getclassDetFn(data) {
+  return request({
+    'url': '/formal/class/'+data,
+    'method': 'get',
+  })
+}
+// 老师-班级新增 formal:class:add
+export function getclassAddFn(data) {
+  return request({
+    'url': '/formal/class',
+    'method': 'post',
+	'data':data
+  })
+}
+// 老师-班级修改 formal:class:edit
+export function getclassPutFn(data) {
+  return request({
+    'url': '/formal/class/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//删除老师-班级formal/class:remove
+export function getclassDelFn(data) {
+  return request({
+    'url': '/formal/class/delete/'+data,
+    'method': 'get',
+  })
+}

+ 195 - 0
api/mine/files.js

@@ -0,0 +1,195 @@
+import request from '@/utils/request'
+// 学生档案信息 student:info:list
+export function getstuCountFn(data) {
+  return request({
+    'url': '/student/info/statistics',
+    'method': 'get',
+	'data':data
+  })
+}
+
+// 学生档案信息 student:info:list
+export function getstuListFn(data) {
+  return request({
+    'url': '/student/info/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 学生档案信息详情 student:info:query
+export function getstuDetFn(data) {
+  return request({
+    'url': '/student/info/'+data,
+    'method': 'get',
+  })
+}
+// 新增学生档案信息 student:info:add
+export function getstuAddtFn(data) {
+  return request({
+    'url': '/student/info',
+    'method': 'post',
+	'data':data
+  })
+}
+//修改学生档案信息 student:info:edit
+export function getstuPutFn(data) {
+  return request({
+    'url': '/student/info/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//删除学生档案信息 student:info:remove
+export function getstuDelFn(data) {
+  return request({
+    'url': '/student/info/delete/'+data,
+    'method': 'get',
+  })
+}
+
+
+// 老师档案信息 teacher:info:list
+export function getteaListFn(data) {
+  return request({
+    'url': '/teacher/info/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 老师档案信息详情 teacher:info:query
+export function getteaDetFn(data) {
+  return request({
+    'url': '/teacher/info/'+data,
+    'method': 'get',
+  })
+}
+// 新增老师档案信息 teacher:info:add
+export function getteaAddtFn(data) {
+  return request({
+    'url': '/teacher/info',
+    'method': 'post',
+	'data':data
+  })
+}
+//修改老师档案信息 teacher:info:edit
+export function getteaPutFn(data) {
+  return request({
+    'url': '/teacher/info/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//删除老师档案信息 teacher:info:remove
+export function getteaDelFn(data) {
+  return request({
+    'url': '/teacher/info/delete/'+data,
+    'method': 'get',
+  })
+}
+
+// echarts student/old/echarts
+export function getoldechFn(data) {
+  return request({
+    'url': '/student/old/echarts',
+    'method': 'get',
+	data:data
+  })
+}
+// 历史信息
+export function getoldlistFn(data) {
+  return request({
+    'url': '/student/old/list',
+    'method': 'get',
+	data:data
+  })
+}
+
+//班级学生信息
+export function getstunoListFn(data) {
+  return request({
+    'url': '/system/student/noPage/list',
+    'method': 'get',
+	data:data
+  })
+}
+//老师信息
+export function getteanoListFn(data) {
+  return request({
+    'url': '/formal/class/noPage/list',
+    'method': 'get',
+	data:data
+  })
+}
+
+//心理健康-新增学生信息mind:old:add
+export function getmindAddFn(data) {
+  return request({
+    'url': '/mind/old',
+    'method': 'post',
+	data:data
+  })
+}
+//心理健康-历史信息mind:old:list
+export function getmindListFn(data) {
+  return request({
+    'url': '/mind/old/list',
+    'method': 'get',
+	data:data
+  })
+}
+//心理健康-删除学生信息mind:old:add
+export function getmindDelFn(data) {
+  return request({
+    'url': '/mind/old/delete/'+data,
+    'method': 'get',
+  })
+}
+
+//身高体重-新增学生信息live:old:add
+export function getliveAddFn(data) {
+  return request({
+    'url': '/live/old',
+    'method': 'post',
+	data:data
+  })
+}
+//身高体重-历史信息live:old:list
+export function getliveListFn(data) {
+  return request({
+    'url': '/live/old/list',
+    'method': 'get',
+	data:data
+  })
+}
+//身高体重-删除学生信息live:old:add
+export function getliveDelFn(data) {
+  return request({
+    'url': '/live/old/delete/'+data,
+    'method': 'get',
+  })
+}
+
+//请假-新增system:leave:add
+export function getleaveAddFn(data) {
+  return request({
+    'url': '/record/leave',
+    'method': 'post',
+	data:data
+  })
+}
+//请假-历史信息system:leave:list
+export function getleaveListFn(data) {
+  return request({
+    'url': '/record/leave/list',
+    'method': 'get',
+	data:data
+  })
+}
+
+//请假-删除学生信息system:leave:list
+export function getleaveDelFn(data) {
+  return request({
+    'url': '/system/leave/'+data,
+    'method': 'get',
+  })
+}

+ 86 - 0
api/mine/mine.js

@@ -0,0 +1,86 @@
+import request from '@/utils/request'
+// 查看默认放学 时间 course:table:list
+export function getConfigKey(data) {
+  return request({
+    'url': '/xiake/config/configKey',
+    'method': 'post',
+	'data':data
+  })
+}
+// 修改默认放学course:table:list
+export function getupdConfigKey(data) {
+  return request({
+    'url': '/xiake/config/updateConfigKey',
+    'method': 'post',
+	'data':data
+  })
+}
+//获取子部门列表system:dept:list
+export function getDeptList(data) {
+  return request({
+    'url': '/system/dept/list/'+data,
+    'method': 'get',
+  })
+}
+export function getDeptListparent(data) {
+  return request({
+    'url': '/system/dept/old/list',
+    'method': 'get',
+	'data':data
+  })
+}
+export function getDeptListmine(data) {
+  return request({
+    // 'url': '/system/dept/list',
+    'url': '/system/dept/noAuthority/list',
+    'method': 'get',
+	// 'data':data
+  })
+}
+//app查看所属自己的部门信息
+export function getselfList(data) {
+  return request({
+    'url': '/system/dept/app/self/list',
+    'method': 'get',
+	'data':data
+  })
+}
+//详情 
+export function getDeptdetFn(data) {
+  return request({
+    'url': '/system/dept/'+data,
+    'method': 'get',
+  })
+}
+//新增班级system:dept:addAll
+// export function getDeptaddFn(data) {
+//   return request({
+//     'url': '/system/dept/addAll',
+//     'method': 'post',
+// 	'data':data
+//   })
+// }
+//新增班级后台
+export function getDeptaddFn(data) {
+  return request({
+    'url': '/system/dept',
+    'method': 'post',
+	'data':data
+  })
+}
+//修改班级后台
+export function getDeptupdFn(data) {
+  return request({
+    'url': '/system/dept/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//删除班级后台
+export function getDeptdelFn(data) {
+  return request({
+    'url': '/system/dept/delete/'+data,
+    'method': 'get',
+  })
+}
+

+ 63 - 0
api/mine/news.js

@@ -0,0 +1,63 @@
+import request from '@/utils/request'
+// 校园安全 列表 xiaoYuanInfo:xiaoYuanInfo:list
+export function getsafeListFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 校园详情 xiaoYuanInfo:xiaoYuanInfo:query
+export function getsafeDetFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/'+data,
+    'method': 'get',
+  })
+}
+// 校园新增 xiaoYuanInfo:xiaoYuanInfo:add
+export function getsafeAddFn(data) {
+  return request({
+    'url': '/xiaoYuan/info',
+    'method': 'post',
+	'data':data
+  })
+}
+//删除校园xiaoYuanInfo:xiaoYuanInfo:remove
+export function getsafeDelFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/delete/'+data,
+    'method': 'get',
+  })
+}
+//校园评论新增	
+export function getplAddFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/pingLun',
+    'method': 'post',
+	'data':data
+  })
+}
+//校园评论点赞/取消点赞
+export function getdzAddFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/dianZan',
+    'method': 'post',
+	'data':data
+  })
+}
+//校园评论转发
+export function getzfAddFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/zhuanFa',
+    'method': 'post',
+	'data':data
+  })
+}
+//校园评论删除
+export function getzfDelFn(data) {
+  return request({
+    'url': '/xiaoYuan/info/delete/pingLun',
+    'method': 'post',
+	'data':data
+  })
+}

+ 42 - 0
api/mine/order.js

@@ -0,0 +1,42 @@
+import request from '@/utils/request'
+//根据教职工手机号查询可预约的时间
+export function getSubscribe(data) {
+  return request({
+    'url': '/system/reservat/subscribe',
+    'method': 'post',
+	'data':data
+  })
+}
+
+//新增预约
+export function getReservatAdd(data) {
+  return request({
+    'url': '/system/reservat',
+    'method': 'post',
+	'data':data
+  })
+}
+//预约审核列表 system:reservat:add
+export function getReservatList(data) {
+  return request({
+    'url': '/system/reservat/list',
+    'method': 'get',
+	'data':data
+  })
+}
+//删除预约 system:reservat:remove
+export function getReservatDel(data) {
+  return request({
+    'url': '/system/reservat/delete/'+data,
+    'method': 'get',
+  })
+}
+//预约审核 system:reservat:sh
+export function getReservatSh(data) {
+  return request({
+    'url': '/system/reservat/sh',
+    'method': 'post',
+	'data':data
+  })
+}
+

+ 25 - 0
api/mine/payslip.js

@@ -0,0 +1,25 @@
+import request from '@/utils/request'
+// 工资条 xiaoYuan:data:importData
+export function getpayListFn(data) {
+  return request({
+    'url': '/xiaoYuan/pay/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 导入 xiaoYuan:data:importData
+export function getpayImporttFn(data) {
+  return request({
+    'url': '/xiaoYuan/pay/importData',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除 xiaoYuan:data:remove
+export function getpayDelFn(data) {
+  return request({
+    'url': '/xiaoYuan/pay/delete/'+data,
+    'method': 'get',
+  })
+}
+

+ 240 - 0
api/mine/register.js

@@ -0,0 +1,240 @@
+import request from '@/utils/request'
+
+
+// 字典值yzdqId
+export function getDictionaryFn(data) {
+  return request({
+    url: '/system/dict/data/type/'+data,
+    method: 'get',
+	type:true
+  })
+}
+// 科目 未登录 system/dict/data/type
+export function getSystemType(data) {
+  return request({
+    'url': '/system/dict/data/type',
+    'method': 'get',
+	'data':data
+  })
+}
+// 参数设置
+export function getconfigKeyFn(data) {
+  return request({
+    url: '/system/config/scoreWatermark/'+data,
+    method: 'get',
+	type:true
+  })
+}
+// 审核audit:shyj:add
+export function getshyjFn(data) {
+  return request({
+    'url': '/audit/shyj',
+    'method': 'post',
+	'data':data
+  })
+}
+//注册查询register:school:add
+export function getqueryFn(data) {
+  return request({
+    'url': '/register/school/query',
+    'method': 'get',
+	'data':data
+  })
+}
+//学校注册register:school:add
+export function getschoolregFn(data) {
+  return request({
+    'url': '/register/school',
+    'method': 'post',
+	'data':data
+  })
+}
+//获取学校注册列表register:school:list
+export function getschoollistFn(data) {
+  return request({
+    'url': '/register/school/list',
+    'method': 'get',
+	'data':data
+  })
+}
+//获取学校注册详情register:school:query
+export function getschoolDetFn(data) {
+  return request({
+    'url': '/register/school/'+data,
+    'method': 'get',
+  })
+}
+//学校注册信息修改register:school:edit
+export function getschoolPutFn(data) {
+  return request({
+    'url': '/register/school/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//删除注册-学校register:school:remove
+export function getschoolDelFn(data) {
+  return request({
+    'url': '/register/school/delete/'+data,
+    'method': 'get',
+  })
+}
+
+
+
+//老师注册register:teacher:add
+export function getteacherregFn(data) {
+  return request({
+    'url': '/register/teacher',
+    'method': 'post',
+	'data':data
+  })
+}
+// 获取老师注册列表register:teacher:list
+export function getteacherlistFn(data) {
+  return request({
+    'url': '/register/teacher/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 获取老师注册详情register:teacher:query
+export function getteacherdetFn(data) {
+  return request({
+    'url': '/register/teacher/'+data,
+    'method': 'get',
+  })
+}
+// 修改老师注册列表register:teacher:edit
+export function getteacherputFn(data) {
+  return request({
+    'url': '/register/teacher/put',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除老师注册列表register:teacher:remove
+export function getteacherdelFn(data) {
+  return request({
+    'url': '/register/teacher/delete/'+data,
+    'method': 'get',
+  })
+}
+
+
+//家长注册register:parents:add
+export function getparentsregFn(data) {
+  return request({
+    'url': '/register/parents',
+    'method': 'post',
+	'data':data
+  })
+}
+//家长新增学生register:student:add
+export function getstudentregFn(data) {
+  return request({
+    'url': '/register/student',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除新增学生register:student:remove
+export function getstudentputdelFn(data) {
+  return request({
+    'url': '/register/student/put/delete',
+    'method': 'get',
+	'data':data
+  })
+}
+// 获取家长注册列表register:student:list
+export function getparentslistFn(data) {
+  return request({
+    'url': '/register/student/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 获取家长注册详情register:student:query
+export function getstudentdetFn(data) {
+  return request({
+    'url': '/register/student/'+data,
+    'method': 'get',
+  })
+}
+// 修改家长注册列表register:parents:edit
+export function getstudentputFn(data) {
+  return request({
+    'url': '/register/student/put',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除家长注册列表register:parents:remove
+export function getstudentdelFn(data) {
+  return request({
+    'url': '/register/parents/delete/'+data,
+    'method': 'get',
+  })
+}
+
+
+// 通用注册
+export function getRegisterFn(data) {
+  return request({
+    'url': '/register/common',
+    'method': 'post',
+	'data':data
+  })
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// // 流程发起时获取下一节点
+// export function getflowableNextRegFn(data) {
+//   return request({
+//     'url': '/flowable/task/nextFlowNodeByStart',
+//     'method': 'post',
+// 	data:data
+//   })
+// }
+// // 发起流程
+// export function getflowableRegFn(id,data) {
+//   return request({
+//     'url': '/flowable/definition/start/'+id,
+//     'method': 'post',
+// 	data:data
+//   })
+// }
+
+// //获取流程定义列表
+// export function getflowlistFn(data) {
+//   return request({
+//     'url': '/flowable/definition/list',
+//     'method': 'get',
+// 	'data':data
+//   })
+// }
+// //获取自己发起的流程
+// export function getflowMyFn(data) {
+//   return request({
+//     'url': '/flowable/task/myProcess',
+//     'method': 'get',
+// 	'data':data
+//   })
+// }

+ 89 - 0
api/mine/score.js

@@ -0,0 +1,89 @@
+import request from '@/utils/request'
+// 成绩导入 score:data:add
+export function getscoreAddimpFn(data) {
+  return request({
+    'url': '/score/data',
+    'method': 'post',
+	'data':data
+  })
+}
+export function getscoreAddFn(data) {
+  return request({
+    'url': '/score/data/add',
+    'method': 'post',
+	'data':data
+  })
+}
+// 成绩详情 score:data:query
+export function getscoreDetFn(data) {
+  return request({
+    'url': '/score/data/query',
+    'method': 'post',
+	'data':data
+  })
+}
+// 成绩列表 score:data:list
+export function getscoreListFn(data) {
+  return request({
+    'url': '/score/data/list',
+    'method': 'get',
+	'data':data
+  })
+}
+//删除成绩
+export function getscoreDelFn(data) {
+  return request({
+    'url': '/score/data/delete/'+data,
+    'method': 'get',
+  })
+}
+
+// 统计
+// 总分排名
+export function getscoregradeRank(data) {
+  return request({
+    'url': '/score/data/gradeRank',
+    'method': 'post',
+	'data':data
+  })
+}
+// 成绩学科统计
+export function getscorexuekeRank(data) {
+  return request({
+    'url': '/score/data/xuekeRank',
+    'method': 'post',
+	'data':data
+  })
+}
+// 班级总分平均分排名统计
+export function getscoreclassRank(data) {
+  return request({
+    'url': '/score/data/classRank',
+    'method': 'post',
+	'data':data
+  })
+}
+// 班级总分平均分人数统计
+export function getscoreavgRank(data) {
+  return request({
+    'url': '/score/data/avgRank',
+    'method': 'post',
+	'data':data
+  })
+}
+// 班级总分平均分人数统计折线图
+export function getscoreavgRankZheXian(data) {
+  return request({
+    'url': '/score/data/avgRankZheXian',
+    'method': 'post',
+	'data':data
+  })
+}
+// 年级分数段统计
+export function getscorebingTuRank(data) {
+  return request({
+    'url': '/score/data/bingTuRank',
+    'method': 'post',
+	'data':data
+  })
+}

+ 64 - 0
api/mine/trends.js

@@ -0,0 +1,64 @@
+import request from '@/utils/request'
+// 新闻列表 xiaoYuan:notice:list
+export function getNoticeList(data) {
+  return request({
+    'url': '/xiaoYuan/notice/list',
+    'method': 'get',
+	'data':data
+  })
+}
+//详情
+export function getNoticeDetail(data) {
+  return request({
+    'url': '/xiaoYuan/notice/'+data,
+    'method': 'get',
+  })
+}
+//新闻新增xiaoYuan:notice:add
+export function getNoticeAdd(data) {
+  return request({
+    'url': '/xiaoYuan/notice',
+    'method': 'post',
+	'data':data
+  })
+}
+
+//新闻修改xiaoYuan:notice:edit
+export function getNoticeUpt(data) {
+  return request({
+    'url': '/xiaoYuan/notice/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//新闻删除xiaoYuan:notice:list
+export function getNoticeDel(data) {
+  return request({
+    'url': '/xiaoYuan/notice/delete/'+data,
+    'method': 'get',
+  })
+}
+// 我的动态
+export function getNoticeMy(data) {
+  return request({
+    'url': '/xiaoYuan/notice/myList',
+    'method': 'get',
+	data:data,
+  })
+}
+// 我的收藏
+export function getCollecttMy(data) {
+  return request({
+    'url': '/xiaoYuan/notice/collect',
+    'method': 'get',
+	data:data,
+  })
+}
+//意见反馈 system:opinion:add
+export function getopinionAdd(data) {
+  return request({
+    'url': '/system/opinion',
+    'method': 'post',
+	'data':data
+  })
+}

+ 55 - 0
api/system/user.js

@@ -0,0 +1,55 @@
+import upload from '@/utils/upload'
+import request from '@/utils/request'
+
+// 用户密码重置
+export function updateUserPwd(oldPassword, newPassword) {
+  const data = {
+    oldPassword,
+    newPassword
+  }
+  return request({
+    url: '/system/user/profile/updatePwd',
+    method: 'put',
+    params: data
+  })
+}
+// 忘记密码发送短信
+export function getappForgetPW(data) {
+  return request({
+    url: '/applet/appForgetPW/'+data,
+    method: 'get',
+  })
+}
+// 重置密码
+export function getappCheck(data) {
+  return request({
+    url: '/applet/appCheck',
+    method: 'get',
+	'data':data
+  })
+}
+// 查询用户个人信息
+export function getUserProfile() {
+  return request({
+    url: '/system/user/profile',
+    method: 'get'
+  })
+}
+
+// 修改用户个人信息
+export function updateUserProfile(data) {
+  return request({
+    url: '/system/user/profile',
+    method: 'put',
+    data: data
+  })
+}
+
+// 用户头像上传
+export function uploadAvatar(data) {
+  return upload({
+    url: '/system/user/profile/avatar',
+    name: data.name,
+    filePath: data.filePath
+  })
+}

+ 130 - 0
api/work/index.js

@@ -0,0 +1,130 @@
+import request from '@/utils/request'
+// 课程列表 course:table:list
+export function getCourselistFn(data) {
+  return request({
+    'url': '/course/table/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 课程详情 course:table:list
+export function getCoursedetFn(data) {
+  return request({
+    'url': '/course/table/'+data,
+    'method': 'get',
+  })
+}
+// 新增课程列表 course:table:add
+export function getCourseAddFn(data) {
+  return request({
+    'url': '/course/table',
+    'method': 'post',
+	'data':data
+  })
+}
+// 修改课程列表 course:table:edit
+export function getCoursePutFn(data) {
+  return request({
+    'url': '/course/table/put',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除课程列表 course:table:remove
+export function getCourseDelFn(data) {
+  return request({
+    'url': '/course/table/delete/'+data,
+    'method': 'get',
+  })
+}
+// 课程时间 course:time:list
+export function getTimelistFn(data) {
+  return request({
+    'url': '/course/time/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 新增课程时间 course:time:add
+export function getTimeAddFn(data) {
+  return request({
+    'url': '/course/time',
+    'method': 'post',
+	'data':data
+  })
+}
+// 修改课程时间 course:time:edit
+export function getTimePutFn(data) {
+  return request({
+    'url': '/course/time/put',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除课程时间 course:time:remove
+export function getTimeDelFn(data) {
+  return request({
+    'url': '/course/time/delete/'+data,
+    'method': 'get',
+  })
+}
+
+
+// 调课列表 course:change:list
+export function getChangelistFn(data) {
+  return request({
+    'url': '/course/change/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 调课通知 course:change:list
+export function getChangetklistFn(data) {
+  return request({
+    'url': '/course/change/list/class',
+    'method': 'get',
+	'data':data
+  })
+}
+// 调课详情 course:change:query
+export function getChangeDetFn(data) {
+  return request({
+    'url': '/course/change/'+data,
+    'method': 'get',
+  })
+}
+// 新增调课 course:change:add
+export function getChangeAddFn(data) {
+  return request({
+    'url': '/course/change',
+    'method': 'post',
+	'data':data
+  })
+}
+// 修改调课 course:change:edit
+export function getChangePutFn(data) {
+  return request({
+    'url': '/course/change/put',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除调课 course:change:remove
+export function getChangeDelFn(data) {
+  return request({
+    'url': '/course/change/delete/'+data,
+    'method': 'get',
+  })
+}
+
+//回复调课 course:time:remove
+export function getChangereplyFn(data) {
+  return request({
+    'url': '/course/change/reply',
+    'method': 'get',
+	'data':data
+  })
+}
+
+
+

+ 39 - 0
api/work/menu.js

@@ -0,0 +1,39 @@
+import request from '@/utils/request'
+// 食谱信息列表 system:recipe:list
+export function getRecipelistFn(data) {
+  return request({
+    'url': '/system/recipe/list',
+    'method': 'get',
+	'data':data
+  })
+}
+// 新增食谱信息 system:recipe:add
+export function getRecipeAddFn(data) {
+  return request({
+    'url': '/system/recipe',
+    'method': 'post',
+	'data':data
+  })
+}
+// 删除食谱信息 system:recipe:remove
+export function getRecipedelFn(data) {
+  return request({
+    'url': '/system/recipe/delete/'+data,
+    'method': 'get',
+  })
+}
+// 修改食谱信息 system:recipe:edit
+export function getRecipeEditFn(data) {
+  return request({
+    'url': '/system/recipe/put',
+    'method': 'post',
+	'data':data
+  })
+}
+//食谱详情 system:recipe:query
+export function getRecipedetaFn(data) {
+  return request({
+    'url': '/system/recipe/'+data,
+    'method': 'get',
+  })
+}

+ 71 - 0
components/footer/footer.vue

@@ -0,0 +1,71 @@
+<template>
+	<view>
+		
+	
+	<view style="height: 100rpx;"></view>
+    <view class="com_footer">
+		<block v-for="(item,k) in footlist" :key="k" >
+			<view class="in_item" v-if="(item.limit&&checkPermi([item.limit]))||!item.limit" @click="gotopage(item)">
+				<image class="in_img" v-if="active == item.module" :src="item.icon_checked" mode="scaleToFill"></image>
+				<image class="in_img" v-else :src="item.icon_nochecked" mode="scaleToFill"></image>
+				<view class="in_txt" v-if="active == item.module" :style="'color: #'+color_checked">{{item.title}}</view>
+				<view class="in_txt" v-else :style="'color: #'+color_nochecked">{{item.title}}</view>
+			</view>
+		</block>
+        
+    </view>
+	</view>
+</template>
+
+<script>
+	// import api from '../../api/api.js'
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+    export default {
+		props:[
+			'footlist',
+			'footerindex',
+			'color_checked',
+			'color_nochecked',
+			'isHomeIndex'
+		],
+        data () {
+            return{
+				active :'',
+            }
+        },
+		mounted() {
+			var that = this;
+			this.active = this.footerindex;
+		},
+        methods:{
+			checkPermi,checkRole,
+            // 跳转底部导航页面
+			gotopage(e){
+				var that = this;
+				let link = e.link, module = e.module, def = e.default, title = e.title;
+				if(module == 'home'){
+					this.$tab.reLaunch('/pages/index/index')
+				}else if(module == 'mine'){
+					this.$tab.reLaunch('/pages/mine/index')
+				}else if(module == 'work'){
+					this.$tab.reLaunch('/pages/work/index')
+				}else if(module == 'trends'){
+					this.$tab.reLaunch('/pages/trends/index')
+				}else if(module == 'road'){
+					this.$tab.reLaunch('/pages/road/index')
+				}
+			},
+			
+        }
+    }
+</script>
+
+
+
+<style type="text/css">
+    .com_footer{ display: flex;position: fixed;box-sizing: border-box;z-index: 99;width: 100%;height: 100rpx;bottom: 0;left: 0;background-color: #fff;overflow: hidden;box-shadow: 0px 0px 16rpx 0px rgba(87,87,87,0.41);}
+	.com_footer .in_item{ display: block;flex: 1;padding: 12rpx 0 0 0;overflow: hidden; }
+	.com_footer .in_img{ display: block;width: 44rpx;height: 44rpx;margin: 0 auto; }
+	.com_footer .in_txt{ font-size: 26rpx;color: #999;text-align: center; font-weight: bold;}
+	.com_footer .in_txt_on{ color: #20AD20; }
+</style>

+ 8 - 0
components/home/list.vue

@@ -0,0 +1,8 @@
+<template>
+</template>
+
+<script>
+</script>
+
+<style>
+</style>

+ 88 - 0
components/home/luswiper.vue

@@ -0,0 +1,88 @@
+<template>
+  <view>
+	  <view class="hlu flexc" @click="getRoad">
+	  		<image :src="hcroad"></image>
+			<swiper class="swiper" circular :autoplay="autoplay" :interval="interval" :duration="duration" vertical='true'>
+				<swiper-item>
+					<view class="swipera over">
+						<text class="tit coeb">拥堵</text>
+						<!-- <text class="tit co5c">畅通</text> -->
+						<text class="over">黄山路与潜山路交口当前较为拥堵!</text>
+					</view>
+				</swiper-item>
+				<swiper-item >
+					<view class="swipera over">
+						<!-- <text class="tit coeb">拥堵</text> -->
+						<text class="tit co5c">畅通</text>
+						<text class="over"> 黄山路与潜山路交口当前较为拥堵!</text>
+					</view>
+				</swiper-item>
+				<swiper-item>
+					<view class="swipera over">
+						<text class="tit coeb">拥堵</text>
+						<!-- <text class="tit co5c">畅通</text> -->
+						<text class="over"> 黄山路与潜山路交口当前较为拥堵!</text>
+					</view>
+				</swiper-item>
+			</swiper>
+	  		
+	  </view>
+  </view>
+</template>
+
+<script>
+  export default {
+	  props:{
+	  	autoplay: {
+	  		type: Boolean,
+	  		default () {
+	  			return false
+	  		}
+	  	},
+	  	confdat:{}
+	  	// status:{
+	  	// 	type: String,
+	  	// 	default () {
+	  	// 		return 'add'
+	  	// 	}
+	  	// },
+	  	// iteminfo:{},
+	  	// xmjzinfo:{},
+	  },
+	data(){
+		return{
+			hcroad:require('@/static/images/hcroad.png'),
+            interval: 2000,
+            duration: 500
+		}
+	},
+	methods:{
+		 getRoad(){
+		 	console.log(1)
+		 },
+	},
+	onLoad: function() {
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.hlu{height: 90rpx;background: #FFFFFF;border-radius: 18rpx;margin: 0 34rpx;padding: 0 25rpx;font-size: 30rpx;
+	image{width: 70rpx;height: 40rpx;flex: 0 0 auto;margin-right: 26rpx;}
+	.tit{
+		font-size: 30rpx;position: relative;
+		padding:0 32rpx 0 27rpx;font-weight: bold;flex: 0 0 auto;
+		&::before{content: '';position: absolute;left: 0;width: 12rpx;height: 12rpx;border-radius: 50%;top: 12rpx;}
+		&::after{content:'';position: absolute;right: 14rpx;top: 6rpx;bottom: 6rpx;width: 4rpx;background-color: #666666;}
+		&.coeb{color: #EB5663;
+			&::before{background-color: #EB5663;}
+		}
+		&.co5c{color: #5CC37D;
+			&::before{background-color: #5CC37D;}
+		}
+	}
+	.swiper{flex: 1;height: 90rpx;
+	.swipera{height: 100%;display: flex;align-items: center;overflow: hidden;}
+	}
+}
+</style>

+ 82 - 0
components/home/luvideo.vue

@@ -0,0 +1,82 @@
+<template>
+  <view class="hvideo bgf">
+	  <view class="hvlist" v-for="(ite,idx) in videoList" :key="idx">
+			 <view class="hvlistl">
+				 <view :class="ite.txt==1?'cir1 cir':'cir2 cir'"></view>
+				 <view class="tit mb6">{{ite.tit}}</view>
+				 <view class="txt">当前路况<text :class="ite.txt==1?'co5c':'coeb'">{{ite.txt==1?'畅通':'拥堵'}}</text></view>
+			 </view>
+			 
+			 <video class="hvlistr" :id="`video${idx}`" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4" :controls='controls'   @play='videoPlay(idx)'>
+			 </video>
+			 <!-- controls -->
+			<!-- <video id="myVideo" class="hvlistr" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4"
+			                   @fullscreenchange="fullscreenchange" @play='videoPlay(idx)'  controls></video> -->
+	  </view>
+	  <!--  -->
+	 <view class="hmore">
+	 	查看更多
+	 	<image :src="moreimg"></image>
+	 </view>
+	
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+  export default {
+	data(){
+		return{
+			src: '',
+			videoList:[{tit:'黄山路与潜山路交口路况',txt:'1'},{tit:'黄山路与潜山路交口路况',txt:'2'}],
+			moreimg:require('@/static/images/hmore.png'),
+			playIdx:'',
+			controls:true,
+			videoContext:''
+		}
+	},
+	methods:{
+		videoPlay(idx) {
+            if (this.playIdx !== '') {
+                console.log(`暂停上一个下标为${this.playIdx}的视频`);
+                let videoContext  = uni.createVideoContext(`video${this.playIdx}`)
+                videoContext .pause()
+            }
+            
+            this.playIdx = idx
+        },
+			fullscreenchange (e){
+				if(!e.detail.fullScreen){
+					this.videoContext.stop()
+				}
+			}
+	},
+	
+	onLoad: function() {
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.hvideo{margin: 0rpx 36rpx;padding: 28rpx 24rpx;box-sizing: border-box;
+	.hvlist{margin-bottom: 28rpx;min-height: 146rpx;background: #F3F3FD;
+border-radius: 14rpx;padding: 11rpx;box-sizing: border-box;display: flex;align-items: center;
+	&:last-child{margin-bottom: 0;}
+}
+	.hvlistl{flex: 1;position: relative;padding-left: 40rpx;
+		.tit{font-size: 30rpx;font-weight: bold;
+color: #161616;}
+		.txt{font-size: 28rpx;color: #666666;}
+		.cir{width: 12rpx;height: 12rpx;border-radius: 50%;position: absolute;left: 12rpx;top:14rpx ;
+			&.cir1{background-color: #5CC37D;}
+			&.cir2{background-color: #EB5663;}
+		}
+	}
+	.hvlistr{width: 217rpx;height: 125rpx;border-radius: 14rpx;flex: 0 0 auto;flex: 0 0 auto;}
+
+}
+.hmore{font-size: 30rpx;font-weight: 500;text-align: center;
+color: #AAAAAA;
+		image{width: 26rpx;height: 22rpx;margin: 12rpx auto 0;}
+	}
+</style>

+ 39 - 0
components/nodata/nodata.vue

@@ -0,0 +1,39 @@
+<template>
+	<view class="nodata" :style="'padding-top:'+padtop+'rpx'">
+		<image :src="noiconpimg"></image>
+		<view>{{notxt}}</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			notxt:{
+				type: String,
+				default () {
+					return '暂无数据'
+				}
+			},
+			padtop:{
+				type: Number,
+				default () {
+					return 200
+				}
+			}
+		},
+		data(){
+			return{
+				noiconpimg:require("@/static/images/noiconp.png"),
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+// 无数据
+.nodata{
+	display: flex;flex-direction: column;align-items: center;box-sizing: border-box;
+	image{width: 456rpx;height: 178rpx;margin-bottom: 28rpx;}
+	view{font-size: 30rpx;color: #AAAAAA;font-weight: bold;}
+}	
+</style>

+ 501 - 0
components/popup/popup.vue

@@ -0,0 +1,501 @@
+<template>
+	<view>
+		<!-- 弹窗 -->
+		<view class="bgbox" @click="getClose" v-if="type"></view>
+		<!-- 确认弹窗 -->
+		<view class="confirmbox flexdc" v-if="type==1">
+			<view class="tit flex0">{{confdat.tit}}</view>
+			<view class="txt">{{confdat.txt}}</view>
+			<view class="cfbtn flex ">
+				<view class="cbtn btn1" @click="getClose">{{confdat.closetxt}}</view>
+				<view class="cbtn btn2" @click="getConfirm">{{confdat.suretxt}}</view>
+			</view>
+		</view>
+		<!-- 延迟弹窗 -->
+		<view class="chec_time yc_time" v-if="type==9">
+			<view class="f17 co16 fw">延迟放学</view>
+			<view class="time_par">
+				<view class="pr che_box flexc">
+					<picker-view  :indicator-style="indicatorStyle"  :value="value" @change="bindChange" class="picker-view flex1">
+						<picker-view-column>
+						    <view class="item" v-for="(item,index) in timelist" :key="index">
+								<view :class="[valarr[0]==index?'pickerSelected':'','u-line-1']">{{item.dictLabel}}</view>
+							</view>		
+						</picker-view-column>	
+					</picker-view>
+					<text class="f16 co16 fw flex0">分钟</text>	
+				</view>
+				<!-- <view class="txt"><text>*</text>提前延迟指 在选择的延迟放学时间上提前多久放学。</view> -->
+			</view>
+			
+			<view class="cfbtn flex ">
+				<view class="cbtn btn1" @click="getClose">取消</view>
+				<view class="cbtn btn2" @click="getyanKeyFn(2)">确认延迟</view>
+			</view>
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		<!-- 完善 -->
+		<view class="perfect" v-if="type==2">
+			<image :src="bgimg" class="bgimg"></image>
+			<view class="pbox flexdc">
+				<view class="tit mb24">温馨提示</view>
+				<view class="txt ptb10 flexc">您还未填写学校信息 请您尽快去完善</view>
+				<view class="pbtn btn1">去完善</view>
+				<view class="pbtn btn2">稍后完善</view>
+				
+			</view>
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		<!-- 调整时间 延时放学-->
+		<view class="chec_time" v-if="type==3">
+			<view class="f17 co16 fw">放学时间</view>
+			<view class="pr che_box flexc">
+				<picker-view  :indicator-style="indicatorStyle"  :value="value" @change="bindChange" class="picker-view flex1">
+					<picker-view-column>
+					    <view class="item" v-for="(item,index) in timelist" :key="index">
+							<view :class="[valarr[0]==index?'pickerSelected':'','u-line-1']">{{item.dictLabel}}</view>
+						</view>		
+					</picker-view-column>	
+				</picker-view>
+				<text class="f16 co16 fw flex0">分钟</text>
+			</view>
+			<view class="pbtn btn1" @click="getKeyFn">确定</view>
+			<view class="txt"><text>*</text>指首页准备放学按钮点击后,根据设置 的放学时间后放学,默认为5分钟。</view>
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		
+		<!-- 注册成功 -->
+		<view class="perfect" v-if="type==4">
+			<image :src="bgimg" class="bgimg"></image>
+			<view class="pbox flexdc" style="padding-bottom: 80rpx;">
+				<view class="tit mb24">{{regdat.tit}}</view>
+				<view class="txt ptb10 flexc">{{regdat.txt}}</view>
+				<view class="pbtn btn1" @click="getregfn(regdat.type)">{{regdat.btn}}</view>
+				<!-- <view class="pbtn btn2">稍后完善</view> -->
+				
+			</view>
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		<!-- 选择班级 -->
+		<view class="chec_time" v-if="type==5" style="min-height: 416rpx;margin-top: -300rpx;">
+			<view class="f17 co16 fw">选择班级</view>
+			<picker @change="bindPickerChange" range-key='dictLabel'  :value="classindex" :range="teacherClass">
+				<view class="checkpick">
+					<view class="f16 co16 fw mr10 flex0">班级</view>
+					<view :class="className?'flex1':'coa flex1'">{{className||"请选择班级"}}</view>
+					<image :src="upimg"></image>
+				</view>
+			</picker>
+			
+			
+			<view class="pbtn btn1" @click="getKeyNext">下一步</view>
+			<!-- <view class="txt"><text>*</text>指首页准备放学按钮点击后,根据设置 的放学时间后放学,默认为5分钟。</view> -->
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		<!-- 审核弹窗 -->
+		<!-- 审核意见 -->
+		<view class="chec_shyj" v-if="type==6">
+			<view class="f17 co16 fw">拒绝理由</view>
+			<view  class="boxs">
+				
+			</view>
+			<view class="shbox ">
+				<textarea  style="height: 256rpx;" v-model="shyj" placeholder="请输入反馈意见,限200 字内…" maxlength="200" class="textar"></textarea>
+			</view>
+			<view class="pbtn btn1" @click="getyjSubmit">提交</view>
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		<!-- 调课弹窗 -->
+		<view class="confirmbox flexdc" v-if="type==7" style="margin-top: -40%;">
+			<view class="tit flex0">调课信息</view>
+			<view class="tkbox">
+				<view>调课信息:{{formdata.subjectTime}}{{formdata.subject}}</view>
+				<view>被调课信息:{{formdata.beSubjectTime}}{{formdata.beSubject}}</view>
+				<view>调课内容:
+					<textarea v-model="content" placeholder="请输入调课内容,例:5月16日星期二的英语课与 5月18日周四的语文课调换…" maxlength="200" class="textarea"></textarea>
+				</view>
+			</view>
+			<view class="cfbtn flex ">
+				<view class="cbtn btn1" @click="getClose">取消</view>
+				<view class="cbtn btn2" @click="getConfirm">确认</view>
+			</view>
+		</view>
+		<!-- 预约码 -->
+		<view class="invbox" v-if="type==8">
+			<view class="tit">预约码</view>
+			<view class="img">
+				<image :src="yycode" @click="getPreview(yycode)"></image>
+			</view>
+			<view class="txt">
+				<text>*</text>此预约码为来访者预约登记码,将此码发送给来访者,即可扫码预约
+			</view>
+			<view class="btn" @click="getSaver">保存至手机</view>
+			<image :src="closeimg" class="cloimg" @click="getClose"></image>
+		</view>
+		<!-- 9已用 延迟放学 -->
+		<!-- 视频播放 -->
+		<!-- <view class="videobox" v-if="type==4">
+			<video id="myVideo" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4"
+			                   @fullscreenchange="fullscreenchange"  controls></video>
+		</view> -->
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			type: {
+				type: Number,
+				default () {
+					return 0
+				}
+			},
+			teacherClass:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			timetit:{},
+			timelist:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			yycode:{
+				type: String,
+				default () {
+					return ''
+				}
+			},
+			shyjflag:{
+				type: Boolean,
+				default () {
+					return true
+				}
+			},
+			confdat:{tit:'确认放学',txt:"是否确认准备放学?",closetxt:'我点错啦',suretxt:'确认放学'},
+			regdat:{tit:'',txt:'',btn:"",type:''},
+			formdata:{"subjectClassId": "","subjectClass": "","subject": "","isNum":"","subjectTime":"","subjectWeek":"","beSubject": "","beIsNum": "","beSubjectTime":"","week": "","content":''},
+			// status:{
+			// 	type: String,
+			// 	default () {
+			// 		return 'add'
+			// 	}
+			// },
+			// iteminfo:{},
+			// xmjzinfo:{},
+		},
+		watch:{
+			timetit(val){
+				var newArr=this.timelist;
+				var newsArr=[]
+				Object.keys(newArr).some((key) => {
+					if (newArr[key].dictLabel == ('' + val)) {
+						newsArr[0]=Number(key)
+						this.value=newsArr;
+						this.valarr=newsArr;
+						return true;
+					}
+				})
+				
+			},
+			type(val){
+				this.shyj='';
+				this.content='';
+				this.valarr=[0];
+				if((val==3||val==9)&&this.timetit){
+					var newArr=this.timelist;
+					var newsArr=[]
+					Object.keys(newArr).some((key) => {
+						if (newArr[key].dictLabel == ('' + this.timetit)) {
+							newsArr[0]=Number(key)
+							this.value=newsArr;
+							this.valarr=newsArr;
+							return true;
+						}
+					})
+				}
+				
+			}
+		},
+		data(){
+			return{
+				// type:0,
+				bgimg:require("@/static/images/popbg.png"),
+				closeimg:require("@/static/images/close.png"),
+				upimg:require("@/static/images/upicon.png"),
+				
+				// confdat:{tit:'确认放学',txt:"是否确认准备放学?",closetxt:'我点错啦',suretxt:'确认放学'},
+				videoContext:'',
+				value:[0],
+				valarr:[0],
+				visible: true,
+				indicatorStyle: `height: 90rpx;color:#4775EA;`,
+				classindex:0,
+				className:'',
+				classId:'',
+				shyj:'',
+				content:'',
+			}
+		},
+		mounted() {
+			// this.valarr=this.timetit
+			// #ifndef MP-ALIPAY
+			// this.videoContext = uni.createVideoContext('myVideo')
+			// this.videoContext.requestFullScreen();
+			// #endif
+		},
+		methods:{
+			getClose(){
+				this.$emit("getClose")
+				// console.log(1)
+				// this.type=0;
+			},
+			getPreview(url) {
+				var newArr=[];
+				newArr.push(url)
+				uni.previewImage({
+					urls: newArr,
+					current:0,
+					success: function(data) {
+						
+					},
+					fail: function(err) {
+						
+					}
+				});
+			},
+			getSaver(){
+				// #ifdef H5
+				// 将base64格式的图片转换成Blob对象
+				  var arr = this.yycode.split(","),
+				    mime = arr[0].match(/:(.*?);/)[1],
+				    bstr = atob(arr[1]),
+				    n = bstr.length,
+				    u8arr = new Uint8Array(n);
+				  while (n--) {
+				    u8arr[n] = bstr.charCodeAt(n);
+				  }
+				  // 将Blob对象转换成文件并下载到本地
+				  var blob = new Blob([u8arr], {
+				    type: mime
+				  });
+				  var a = document.createElement('a');
+				  a.download = 'qrcode';
+				  a.href = URL.createObjectURL(blob);
+				  a.click();
+				// #endif
+				// #ifndef H5
+				uni.getSetting({//获取用户的当前设置
+				    success:(res)=> {
+				        if(res.authSetting['scope.writePhotosAlbum']){//验证用户是否授权可以访问相册
+				            this.saveImageToPhotosAlbum();
+				        }else{
+				            uni.authorize({//如果没有授权,向用户发起请求
+				                scope: 'scope.writePhotosAlbum',
+				                success:()=> {
+				                    this.saveImageToPhotosAlbum();
+				                },
+				                fail:()=>{
+				                    uni.showToast({
+				                        title:"请打开保存相册权限,再点击保存相册分享",
+				                        icon:"none",
+				                        duration:3000
+				                    });
+				                    setTimeout(()=>{
+				                        uni.openSetting({//调起客户端小程序设置界面,让用户开启访问相册
+				                            success:(res2)=> {
+				                                // console.log(res2.authSetting)
+				                            }
+				                        });
+				                    },3000);
+				                }
+				            })
+				        }
+				    }
+				})
+				// #endif
+				
+			},
+			saveImageToPhotosAlbum(){
+                let base64=this.yycode.replace(/^data:image\/\w+;base64,/, "");//去掉data:image/png;base64,
+                let filePath=wx.env.USER_DATA_PATH + '/qrcode.png';
+                uni.getFileSystemManager().writeFile({
+                    filePath:filePath ,  //创建一个临时文件名
+                    data: base64,    //写入的文本或二进制数据
+                    encoding: 'base64',  //写入当前文件的字符编码
+                    success: res => {
+                        uni.saveImageToPhotosAlbum({
+                            filePath: filePath,
+                            success: function(res2) {
+                                uni.showToast({
+                                    title: '保存成功,请从相册选择再分享',
+                                    icon:"none",
+                                    duration:5000
+                                })
+                            },
+                            fail: function(err) {
+                                // console.log(err.errMsg);
+                            }
+                        })
+                    },
+                    fail: err => {
+                        //console.log(err)
+                    }
+                })
+            },
+			getyjSubmit(){
+				if(!this.shyj&&this.shyjflag){
+					this.$toast("请输入审核意见")
+					return
+				}
+				this.$emit("getyjSubmit",this.shyj)
+			},
+			getregfn(e){
+				this.$emit("getregfn",e)
+			},
+			getConfirm(){
+					this.$emit("getConfirm",this.content)
+				  // this.$tab.navigateTo(`/mine/pages/login/register`)
+				  // this.$tab.navigateTo(`/pages/logines`)
+			},
+			bindPickerChange(e){
+				var val=e.detail.value;
+				this.className=this.teacherClass[val].dictLabel
+				this.classId=this.teacherClass[val].dictValue
+			},
+			getyanKeyFn(id){
+				var value=this.valarr[0];
+				var str=this.timelist[value].dictLabel;
+				this.$emit('getyanKeyFn',str)
+			},
+			getKeyFn(){
+				var value=this.valarr[0];
+				var str=this.timelist[value].dictLabel;
+				if(str==this.timetit){
+					this.$emit('getClose')
+				}else{
+					this.$emit('getKeyFn',str)
+				}
+				
+			},
+			getKeyNext(){
+				this.$emit('getKeyNext',this.classId)
+			},
+			bindChange(e){
+				this.valarr=e.detail.value;
+				// console.log(e)
+                // const val = e.detail.value
+                // this.year = this.years[val[0]]
+                // this.month = this.months[val[1]]
+                // this.day = this.days[val[2]]
+            },
+			fullscreenchange (e){
+				if(!e.detail.fullScreen){
+					this.videoContext.stop()
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	// 公共
+		.pbtn{text-align: center;font-size: 30rpx;font-weight: 500;flex:0 0 auto;
+			&.btn1{background: #1f57e6;color: #ffffff;height: 70rpx;border-radius: 35rpx;line-height: 70rpx;width: 100%;}
+			&.btn2{color: #aaa;margin-top: 14rpx;padding:10rpx;}
+		}
+		.cloimg{width: 56rpx;height: 56rpx;position: absolute;bottom: -80rpx;left: 50%;margin-left: -28rpx;}
+	// end
+.perfect{
+	position: fixed;left: 82rpx;right: 82rpx;height: 550rpx;top: 50%;margin-top: -340rpx;border-radius: 24rpx;z-index: 10;
+	.bgimg{width: 100%;height: 100%;}
+	
+	.pbox{position: absolute;left: 0;top: 0;right: 0;bottom: 0;padding: 32rpx 68rpx;box-sizing: border-box;z-index: 5;
+		.tit{font-size: 34rpx;font-weight: bold;
+color: #FFFFFF;text-align: center;flex: 0 0 auto;}
+		.txt{font-size: 32rpx;font-weight: 500;color: #161616;flex: 1;text-align: center;}	
+	}	
+}
+.confirmbox{
+	position: fixed;left: 82rpx;right: 82rpx;min-height: 300rpx;top: 50%;margin-top: -30%;border-radius: 24rpx;z-index: 10;background-color: #ffffff;padding-top: 30rpx;box-sizing: border-box;text-align: center;
+	.tit{font-size: 34rpx;font-weight: bold;
+color: #161616;line-height: 48rpx;}
+	.txt{font-size: 32rpx;color: #161616;flex: 1;padding: 28rpx;display: flex;align-items: center;justify-content: center;line-height: 48rpx;}
+	.cfbtn{border-top: 2rpx solid #DDDDDD;flex: 0 0 auto;
+		.cbtn{width: 50%;height: 88rpx;line-height: 88rpx;
+			&.btn1{font-size: 32rpx;font-weight: 500;
+color: #AAAAAA;position: relative;
+			&::after{position: absolute;right: 1rpx;top: 0;bottom: 0;content: "";width: 2rpx;background-color: #DDDDDD;;}
+
+}
+			&.btn2{font-size: 32rpx;font-weight: 500;
+			color: #4775EA;}
+		}
+	}
+}
+// 时间选择
+.chec_time{position: fixed;left: 126rpx;right: 126rpx;min-height: 660rpx;top: 50%;margin-top: -400rpx;border-radius: 14rpx;z-index: 10;background-color: #ffffff;padding: 48rpx 46rpx 54rpx;box-sizing: border-box;text-align: center;
+// .chec_over{max-height: calc(100% - 400rpx) ;overflow: auto;}
+	.che_box{padding-left: 80rpx;
+			.picker-view {height: 300rpx;margin: 20rpx 0rpx;width: 100%;flex: 1;
+				.item {line-height: 90rpx;text-align: center;
+					.pickerSelected{font-size: 40rpx;font-weight: bold;color: #4775EA;}
+				}
+			}	
+		}
+	.txt{margin-top: 32rpx;
+		font-size: 24rpx;color: #666666;
+		text{font-size: 32rpx;color: #DF0024;margin-right: 6rpx;}
+	}
+	// 延迟提前
+	&.yc_time{
+		padding:48rpx 0 0rpx;min-height:auto;
+		.time_par{padding:0 46rpx;
+			.txt{text-align:left;margin:0 0 24rpx;}
+		}
+		.cfbtn{border-top: 2rpx solid #DDDDDD;flex: 0 0 auto;
+			.cbtn{width: 50%;height: 88rpx;line-height: 88rpx;
+				&.btn1{font-size: 32rpx;font-weight: 500;color: #AAAAAA;position: relative;
+					&::after{position: absolute;right: 1rpx;top: 0;bottom: 0;content: "";width: 2rpx;background-color: #DDDDDD;;}
+				}
+				&.btn2{font-size: 32rpx;font-weight: 500;color: #4775EA;}
+			}
+		}
+	}
+}
+
+.checkpick{display: flex;align-items: center;border-bottom: 2rpx solid #FFB132;flex-direction: row;margin: 40rpx auto 76rpx;width: 100%;padding: 32rpx 0;
+	
+	image{width: 22rpx;height: 12rpx;flex: 0 0 auto;margin-left: 16rpx;}
+}
+.chec_shyj{position: fixed;left: 82rpx;right: 82rpx;height: 560rpx;top: 50%;margin-top: -380rpx;border-radius: 14rpx;z-index: 10;background-color: #ffffff;padding: 48rpx 46rpx 54rpx;box-sizing: border-box;text-align: center;
+	.shbox{
+		.textar{width: 100%;border: 2rpx solid #FF6400;border-radius: 10rpx;padding: 26rpx 30rpx;font-size: 30rpx;color: #343434;height: 376rpx;margin: 40rpx 0;text-align: left;}
+	}
+}
+//调课
+.tkbox{flex: 1;text-align: left;display: flex;flex-direction: column;padding:20rpx;
+	view{font-size: 32rpx;color: #161616;padding: 6rpx 0;}
+}
+.textarea{width: 100%;border: 2rpx solid #FF6400;border-radius: 10rpx;padding: 26rpx 30rpx;font-size: 30rpx;color: #343434;height: 200rpx;margin: 20rpx 0;text-align: left;}
+// 预约码
+.invbox{
+	position: fixed;left: 126rpx;right: 126rpx;background: #ffffff;border-radius: 14rpx;min-height: 640rpx;padding: 44rpx 46rpx 48rpx;box-sizing: border-box;top: 50%;z-index: 10;transform: translateY(-50%);margin-top: -60rpx;
+	.tit{font-size: 34rpx;font-weight: bold;color: #161616;margin-bottom: 16rpx;text-align: center;line-height: 48rpx;}
+	.img{width: 280rpx;height: 280rpx;margin: 0 auto 16rpx;
+		image{width: 100%;height: 100%;}
+	}
+	.txt{font-size: 28rpx;color: #AAAAAA;display: flex;align-items: flex-start;line-height: 40rpx;
+		text{color: #F7082E;flex: 0 0 auto;}
+	}
+	.btn{width:100%;height: 72rpx;background: #4775EA;border-radius: 36rpx;text-align: center;line-height: 72rpx;font-size: 30rpx;font-weight: 500;margin-top:36rpx;
+color: #FFFFFF;
+}
+}
+
+// 全屏的视频播放
+.videobox /deep/ uni-video{width: 100% !important;}
+</style>

+ 631 - 0
components/shlist/list.vue

@@ -0,0 +1,631 @@
+<template>
+  <view>
+		<view v-if="datalist.length>0">
+			<block v-if="zhtype==2">
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb6">
+						<view class="f17 fw co16 flex1">{{ite.userName}}</view>
+						<view class="tsbtn co1" v-if="ite.isPass==1">待审核</view>
+						<view class="tsbtn co2" v-if="ite.isPass==2">已通过</view>
+						<view class="tsbtn co3" v-if="ite.isPass==3">已拒绝</view>
+					</view>
+					<view class="plr12">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">学校:</view>
+							<view class="f15 co6 flex1">{{ite.schoolName}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">班级:</view>
+							<view class="f15 co6 flex1">
+								<block v-for="(mite,midx) in ite.registerTeacherClassList" :key="midx">{{mite.className}};
+								</block>
+							</view>
+						</view>
+						<view class="list flexc">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">学科:</view>
+								<view class="f15 co6 flex1">
+									<block v-for="(mite,midx) in ite.registerTeacherClassList" :key="midx">{{mite.discipline}};
+									</block>
+								</view>
+							</view>
+							<block v-if="!ite.opinion">
+								<view class="btn btn1" @click="getPass(ite.id)" v-if="ite.isPass==1&&checkPermi(['audit:shyj:add'])">通过</view>
+								<view class="btn btn2" @click="getSefuse(ite.id)" v-if="ite.isPass==1&&checkPermi(['audit:shyj:add'])">拒绝</view>
+								<view class="btn btn3" @click="getDel(ite.id)" v-if="checkPermi(['register:teacher:remove'])">删除</view>
+							</block>
+							
+						</view>
+						<view class="list flexc" v-if="ite.opinion">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">审核意见:</view>
+								<view class="f15 co6 flex1">
+									{{ite.opinion}}
+								</view>
+							</view>
+							<view class="btn btn1" @click="getPass(ite.id)" v-if="ite.isPass==1&&checkPermi(['audit:shyj:add'])">通过</view>
+							<view class="btn btn2" @click="getSefuse(ite.id)" v-if="ite.isPass==1&&checkPermi(['audit:shyj:add'])">拒绝</view>
+							<view class="btn btn3" @click="getDel(ite.id)" v-if="checkPermi(['register:teacher:remove'])">删除</view>
+						</view>
+					</view>
+				</view>
+			</block>
+			<!-- 家长 -->
+			<block v-if="zhtype==3" >
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb6">
+						<view class="f17 fw co16 flex1">{{ite.parentsName}}<text class="ml6">{{ite.parentsPhone}}</text></view>
+						<view class="tsbtn co1" v-if="ite.isPass==1">待审核</view>
+						<view class="tsbtn co2" v-if="ite.isPass==2">已通过</view>
+						<view class="tsbtn co3" v-if="ite.isPass==3">已拒绝</view>
+					</view>
+					<view class="plr12">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">学校:</view>
+							<view class="f15 co6 flex1">{{ite.schoolName}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">班级:</view>
+							<view class="f15 co6 flex1">{{ite.className}}</view>
+						</view>
+						<view class="list flext ptb4" v-if="ite.studentName">
+							<view class="f15 co16 flex0 fw5">学生姓名:</view>
+							<view class="f15 co6 flex1">{{ite.studentName}}</view>
+						</view>
+						<view class="list flext ptb4" v-if="ite.studentNumber">
+							<view class="f15 co16 flex0 fw5">身份证号:</view>
+							<view class="f15 co6 flex1">{{ite.studentNumber}}</view>
+						</view>
+						<view class="list flexc">
+							<view class="ptb4 flext flex1"></view>
+							<view class="btn btn1" @click="getPass(ite.id)" v-if="ite.isPass==1&&checkPermi(['audit:shyj:add'])">通过</view>
+							<view class="btn btn2" @click="getSefuse(ite.id)" v-if="ite.isPass==1&&checkPermi(['audit:shyj:add'])">拒绝</view>
+							<view class="btn btn3" @click="getDel(ite.id)" v-if="checkPermi(['register:student:remove'])">删除</view>
+						</view>
+					</view>
+				</view>
+			</block>
+			<!-- 调课 -->
+			<block v-if="zhtype==4">
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb6">
+						<view class="f17 fw co16 flex1">{{ite.applyName}}</view>
+						<view class="tsbtn co1" v-if="ite.isPass==1">待审核</view>
+						<view class="tsbtn co2" v-if="ite.isPass==2">已通过</view>
+						<view class="tsbtn co3" v-if="ite.isPass==3">已拒绝</view>
+						<!-- <view class="tsbtn co2">已通过</view>
+						<view class="tsbtn co3">已拒绝</view> -->
+					</view>
+					<view class="plr12">
+						<!-- <view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">申请时间:</view>
+							<view class="f15 co6 flex1">{{ite.applyTime}}</view>
+						</view> -->
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">调课班级:</view>
+							<view class="f15 co6 flex1">{{ite.subjectClass}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">调课科目:</view>
+							<view class="f15 co6 flex1">{{ite.subject}}/{{ite.subjectTime}}/{{kaType(ite.subjectWeek,week)}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">被调科目:</view>
+							<view class="f15 co6 flex1">{{ite.beSubject}}/{{ite.beSubjectTime}}/{{kaType(ite.week,week)}}</view>
+						</view>
+						<!-- <view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">时间(星期):</view>
+							<view class="f15 co6 flex1">{{kaType(ite.week,week)}}</view>
+						</view> -->
+						<view class="list flext ptb4" v-if='ite.content'>
+							<view class="f15 co16 flex0 fw5">调课内容:</view>
+							<view class="f15 co6 flex1">{{ite.content}}</view>
+						</view>
+						<view class="list flexc">
+							<view class="flex1"><block v-if="ite.opinion">拒绝理由:{{ite.opinion||''}}</block></view>
+							<view class="btn btn1" @click="getPass(ite)" v-if="ite.isPass==1&&checkPermi(['course:change:reply'])">通过</view>
+							<view class="btn btn2" @click="getSefuse(ite)" v-if="ite.isPass==1&&checkPermi(['course:change:reply'])">拒绝</view>
+							<view class="btn btn3" @click="getDel(ite)" v-if="checkPermi(['course:change:remove'])&&ite.applyId==userId">删除</view>
+							<!-- <view class="btn btn1" @click="getUpdate(ite.id)" v-if="checkPermi(['course:change:edit'])&&ite.isPass!=2&&ite.applyId==userId">修改</view> -->
+						</view>
+					</view>
+				</view>
+			</block>
+			
+			<!-- 调课通知 -->
+			<block v-if="zhtype==5">
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb8">
+						<view class="f17 f5 co47 flex1">{{ite.subject}} </view>
+						<!-- <span style="margin-left: 20rpx;">{{ite.applyName}}</span> -->
+						<view class="f14 f5 co47 flex0">{{ite.subjectTime}}/{{kaType(ite.week,week)}}</view>
+					</view>
+					<view class="plr12">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">调课班级:</view>
+							<view class="f15 co6 flex1">{{ite.subjectClass}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">被调课班级:</view>
+							<view class="f15 co6 flex1">{{ite.beSubject}}/{{ite.beSubjectTime}}/{{kaType(ite.week,week)}}</view>
+						</view>
+						<view class="list flext ptb4" v-if='ite.content'>
+							<view class="f15 co16 flex0 fw5">调课内容:</view>
+							<view class="f15 co6 flex1">{{ite.content}}</view>
+						</view>
+					</view>
+				</view>
+			</block>
+			<!-- 动态 -->
+			<block v-if="zhtype==6">
+				<view class="dtlist" v-for="(ite,idx) in datalist" :key="idx" @click="getDetail(ite.noticeId)">
+					<view class="flext">
+						<image v-if='ite.avatar' :src="baseUrl+ite.avatar" class="listl"></image>
+						<image v-else :src="avatar" class="listl"></image>
+						<view class="listr">
+							<view class="top">
+								<view class="f17 co16 fw5 flex0" v-if="ite.senderName">{{ite.senderName}}</view>
+								<view class="f14 co6 flex1 ml6 txr" v-if="ite.schoolName">{{ite.schoolName}}</view>
+							</view>
+							<view>
+								<view class="f15 co16 mb8" v-if="ite.noticeContent">{{ite.noticeContent}}</view>
+								<view class="imgs" v-if="ite.photo">
+									<image :src="baseUrl+pit" :class="ite.photo.length==0?'img1':''"  v-for="(pit,pid) in ite.photo" :key="pid" @click.stop="getPreview(ite.photo,pit)"></image>
+								</view>
+							</view>
+							<view class="flexcj">
+								<view class="f13 coa">{{ite.createTime}}</view>
+								
+								<view class="trsta flexc">
+									<view class="trstal">
+										<image :src="tricong"></image>
+										<!-- <view class="cir">2</view> -->
+									</view>
+									<view class="trstal">
+										<image :src="triconb"></image>
+										<!-- <view class="cir">2</view> -->
+									</view>
+									<view class="trstal">
+										<image :src="triconc"></image>
+									</view>
+									<view class="trstal">
+										<image :src="tricond"></image>
+									</view>
+								</view>
+								<!-- 暂放end -->
+								<!-- <view class="delbox">
+									<image :src="tddelimg"></image>
+									<view>删除</view>
+								</view> -->
+							</view>
+							<!-- <view class="f14 coa"></view> -->
+						</view>
+					</view>
+					<!-- 评论 -->
+					<view class="trcom mt15" style="display: none;">
+						<view class="trcomz flext">
+							<view class="trcoml">
+								<image :src="triconc"></image>
+							</view>
+							<view class="trcomr">
+								<image :src="avatar"></image>
+							</view>
+						</view>
+						<view class="trcomp flext">
+							<view class="trcoml">
+								<image :src="triconb"></image>
+							</view>
+							<view class="flex1">
+								<view class="trcompr flext">
+									<image v-if='ite.avatar' :src="baseUrl+ite.avatar" class="listl"></image>
+									<image v-else :src="avatar" class="listl"></image>
+									<view>
+										<view class="flexcj mb5">
+											<view  class="f13 fw c37 lh20">王运营</view>
+											<view class="f13 co6">6月23日 14:15</view>
+										</view>
+										<view class="f13 co16 fw5 lh20">好的,收到!我们家长一定会督促孩子完成英语作 业,保质保量的完成!</view>
+									</view>
+								</view>
+							</view>
+							
+						</view>
+					</view>
+					
+				</view>
+			</block>
+			<!-- 查询注册结果 -->
+			<block v-if="zhtype==7">
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb6">
+						<view class="f17 fw co16 flex1">
+							<block v-if="ite.zctype=='school'">学校管理员</block>
+							<block v-if="ite.zctype=='teacher'">老师</block>
+							<block v-if="ite.zctype=='parents'">家长</block>
+						<!-- {{ite.zctype}} -->
+						
+						</view>
+						<view class="tsbtn co1" v-if="ite.isPass==1">待审核</view>
+						<view class="tsbtn co2" v-if="ite.isPass==2">已通过</view>
+						<view class="tsbtn co3" v-if="ite.isPass==3">已拒绝</view>
+					</view>
+					<!-- 学校 -->
+					<view class="plr12" v-if="ite.zctype=='school'">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">学校:</view>
+							<view class="f15 co6 flex1">{{ite.schoolName}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">负责人:</view>
+							<view class="f15 co6 flex1">{{ite.userName}}</view>
+						</view>
+						<view class="list flexc">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">联系方式:</view>
+								<view class="f15 co6 flex1">{{ite.userPhone}}</view>
+							</view>
+							<view class="btn btn3" v-if="!ite.opinion&&ite.isPass!='2'&&!ite.registerSchoolFileList" @click="getUpdate(ite)" >修改</view>
+						</view>
+						<view class="list flex" v-if="ite.registerSchoolFileList&&ite.registerSchoolFileList.length">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">资质:</view>
+								<view class="cldelistbf flexc"  v-for="(fite,fidx) in ite.registerSchoolFileList" :key='fite.id'>
+									<view class="flext f15 co16 flex1" @click="getDown(fite.url)">
+										<view class="imgl"><image :src="wimg" ></image></view>
+										<view class="tit">{{fite.name}}</view>
+									</view>
+								</view>
+							</view>
+							<view class="btn btn3 " style="margin-top: 6rpx;" v-if="!ite.opinion&&ite.isPass!='2'" @click="getUpdate(ite)" >修改</view>
+						</view>
+						<view class="list flexc" v-if="ite.opinion">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">审核意见:</view>
+								<view class="f15 co6 flex1">
+									{{ite.opinion}}
+								</view>
+							</view>
+							<view class="btn btn3" @click="getUpdate(ite)" v-if="ite.isPass!='2'">修改</view>
+						</view>
+					</view>
+					<view class="plr12" v-if="ite.zctype=='teacher'">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">学校:</view>
+							<view class="f15 co6 flex1">{{ite.schoolName}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">姓名:</view>
+							<view class="f15 co6 flex1">{{ite.userName}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">联系方式:</view>
+							<view class="f15 co6 flex1">{{ite.userPhone}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">班级:</view>
+							<view class="f15 co6 flex1">
+								<block v-for="(mite,midx) in ite.registerTeacherClassList" :key="midx">{{mite.className}};
+								</block>
+							</view>
+						</view>
+						<view class="list flexc">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">学科:</view>
+								<view class="f15 co6 flex1">
+								<block v-for="(mite,midx) in ite.registerTeacherClassList" :key="midx">{{mite.discipline}};</block>
+								</view>
+							</view>
+							<view class="btn btn3" v-if="!ite.opinion&&ite.isPass!='2'" @click="getUpdate(ite)">修改</view>
+						</view>
+						<view class="list flexc" v-if="ite.opinion">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">审核意见:</view>
+								<view class="f15 co6 flex1">
+									{{ite.opinion}}
+								</view>
+							</view>
+							<view class="btn btn3" @click="getUpdate(ite)" v-if="ite.isPass!=='2'">修改</view>
+						</view>
+					</view>
+					<block v-if="ite.zctype=='parents'">
+						<view class="plr12">
+							<view class="list flext ptb4">
+								<view class="f15 co16 flex0 fw5">学校:</view>
+								<view class="f15 co6 flex1">{{ite.schoolName}}</view>
+							</view>
+							<view class="list flext ptb4">
+								<view class="f15 co16 flex0 fw5">班级:</view>
+								<view class="f15 co6 flex1">{{ite.className}}</view>
+							</view>
+							<view class="list flexc">
+								<view class="ptb4 flext flex1">
+									<view class="f15 co16 flex0 fw5">学生姓名:</view>
+									<view class="f15 co6 flex1">{{ite.studentName}}</view>
+								</view>
+								<view class="btn btn3" v-if="!ite.opinion&&ite.isPass!=='2'" @click="getUpdate(ite)">修改</view>
+							</view>
+							<view class="list flexc" v-if="ite.opinion">
+								<view class="ptb4 flext flex1">
+									<view class="f15 co16 flex0 fw5">审核意见:</view>
+									<view class="f15 co6 flex1">
+										{{ite.opinion}}
+									</view>
+								</view>
+								<view class="btn btn3" @click="getUpdate(ite)" v-if="ite.isPass!=='2'">修改</view>
+							</view>
+						</view>
+					</block>
+					
+				</view>
+			</block>
+			<!-- 家长添加学生 -->
+			<block v-if="zhtype==8">
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb6">
+						<view class="f17 fw co16 flex1">{{ite.studentName}}</view>
+						<view class="tsbtn co1" v-if="ite.isPass==1">待审核</view>
+						<view class="tsbtn co2" v-if="ite.isPass==2">已通过</view>
+						<view class="tsbtn co3" v-if="ite.isPass==3">已拒绝</view>
+					</view>
+					<view class="plr12">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">学校:</view>
+							<view class="f15 co6 flex1">{{ite.schoolName}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">班级:</view>
+							<view class="f15 co6 flex1">{{ite.className}}</view>
+							<view class="btn btn3" v-if="!ite.opinion&&ite.isPass!=='2'" @click="getUpdate(ite)">修改</view>
+							<view class="btn btn3" @click="getDel(ite)" v-if="ite.isPass=='2'">删除</view>
+						</view>
+						<view class="list flexc" v-if="ite.opinion">
+							<view class="ptb4 flext flex1">
+								<view class="f15 co16 flex0 fw5">审核意见:</view>
+								<view class="f15 co6 flex1">
+									{{ite.opinion}}
+								</view>
+							</view>
+							<!-- checkPermi(['register:student:remove'])&& -->
+							<view class="btn btn3" @click="getUpdate(ite)" v-if="ite.isPass!=='2'">修改</view>
+							<view class="btn btn3" @click="getDel(ite)" v-if="ite.isPass=='2'">删除</view>
+						</view>
+					</view>
+				</view>
+			</block>
+			<view class="shax" v-if="wtdt">{{wtdt}}</view>
+	   </view>
+	   <block v-else>
+			<no-data ></no-data>
+	   </block>
+  </view>
+</template>
+
+<script>
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	import noData from "@/components/nodata/nodata.vue"
+	import { selectDictValue } from '@/utils/common.js';
+	import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
+  export default {
+	  props:{
+	  	datalist: {
+	  		type: Array,
+	  		default () {
+	  			return []
+	  		}
+	  	},
+		subject: {
+			type: Array,
+			default () {
+				return []
+			}
+		},
+		week: {
+			type: Array,
+			default () {
+				return []
+			}
+		},
+		zhtype:{
+			typeof:[Number,String],
+			default () {
+				return 0
+			}
+		},
+		userId:{
+			typeof:[Number,String],
+			default () {
+				return 0
+			}
+		},
+		avatar:{
+			type: String,
+			default () {
+				return ''
+			}
+		},
+	  	wtdt:{
+	  		type: String,
+	  		default () {
+	  			return ''
+	  		}
+	  	},
+	  	type:{
+	  		type: String,
+	  		default () {
+	  			return ''
+	  		}
+	  	},
+		froms:{
+			type: String,
+			default () {
+				return ''
+			}
+		}
+	  },
+	  components:{
+		noData  
+	  },
+	data(){
+		return{
+			sucimg:require("@/mine/static/mine/success.png"), 
+			delimg:require("@/static/images/tcdel.png"),
+			tddelimg:require("@/static/images/tdel.png"),
+			tricona:require("@/static/images/tricoa.png"),
+			triconb:require("@/static/images/tricob.png"),
+			triconc:require("@/static/images/tricoc.png"),
+			tricond:require("@/static/images/tricod.png"),
+			tricong:require("@/static/images/tricog.png"),
+			wimg:require('@/static/images/read.png'),
+			baseUrl:''
+		}
+	},
+	methods:{
+		checkPermi,checkRole,
+		kaType(data, list) {
+			return selectDictValue(list, data);
+		},
+		getPass(data){
+			this.$modal.confirm('确定通过审核?').then(() => {
+			  this.$emit('getPass',data)
+			})
+		},
+		getDel(data){
+			this.$modal.confirm('确定删除该条信息?').then(() => {
+			  this.$emit('getDel',data)
+			})
+		},
+		getDetail(id){
+			this.$emit('getDetail',id)
+		},
+		getSefuse(data){
+			this.$emit('getSefuse',data)
+		},
+		getUpdate(data){
+			this.$emit('getUpdate',data)
+		},
+		getDown(e){
+			uni.showLoading({
+				title: '加载中'
+			});
+			var url=this.baseUrl+e;
+			uni.downloadFile({
+				url: url,//文件的下载路径
+				success(result) {
+						uni.hideLoading()
+					var filePath = result.tempFilePath;
+					   uni.openDocument({
+					     filePath: filePath,
+					     showMenu: true,
+					     success: function (res) {
+					     }
+					   });
+				},
+				fail(res) {uni.hideLoading()}
+			})
+		},
+		// 查看照片
+		getPreview(iurl,idx) {
+			var newArr=[];
+			iurl.forEach(ite=>{
+				var ds=this.baseUrl+ite
+				newArr.push(ds)
+			})
+			uni.previewImage({
+				urls: newArr,
+				current:idx,
+				success: function(data) {
+					
+				},
+				fail: function(err) {
+					console.log(err.errMsg);
+				}
+			});
+		},
+	},
+	mounted() {
+		this.baseUrl=baseUrl
+	},
+	onLoad: function() {
+		
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.shlist{width: 100%;background: #FFFFFF;border-radius: 14rpx;padding: 0 24rpx 24rpx;margin-bottom: 24rpx;
+	.tittop{padding:20rpx 24rpx;border-bottom: 2rpx solid #E6E6E6;
+		.tsbtn{min-width: 90rpx;height: 36rpx;border-radius: 4rpx;padding: 0 12rpx;box-sizing: border-box;font-size: 24rpx;line-height: 36rpx;
+			&.co1{background: #FFEDDF;color: #E19301;}
+			&.co2{background: #D3F7E5;color: #24D725;}
+			&.co3{background: #FDE2E3;color: #EC1134;}
+		}
+	}
+	.list{
+		.btn{min-width: 106rpx;height: 46rpx;border-radius: 14rpx;display: flex;align-items: center;justify-content: center;box-sizing: border-box;font-size: 26rpx;margin-left: 20rpx;
+			&.btn1{background: #1f57e6;color: #FFFFFF;}
+			&.btn2{border: 1px solid #4775EA;color: #4775EA;}
+			&.btn3{border: 1px solid red;color: red;}
+		}
+	}
+}
+// 附件
+.cldelistbf {
+	padding: 0rpx 24rpx;flex: 1;
+		image{flex: 0 0 auto;}
+		.imgl{width: 40rpx;height: 40rpx;display: flex;align-items: center;justify-content: center;margin-right: 24rpx;
+			image{width: 40rpx;height: 34rpx;}
+		}
+		.imgr{width: 30rpx;height: 30rpx;margin-left: 24rpx;}
+		.tit{line-height: 40rpx;font-size: 32rpx;color: #161616;flex: 1;word-break: break-all;}
+	}
+.infolist_b{color: #aaaaaa;font-size: 26rpx;padding:0 24rpx;margin-top:10rpx;
+	text{word-break: break-all;margin: 0 4rpx;color: #ff0000;}
+}
+// 动态
+.dtlist{width: 100%;margin-top: 24rpx;background: #FFFFFF;border-radius: 8rpx;padding: 28rpx 30rpx;box-sizing: border-box;
+		.listl{width: 60rpx;height: 60rpx;margin-right: 20rpx;flex: 0 0 auto;border-radius:50%;}
+		.listr{flex: 1;
+			.top{min-height: 60rpx;display: flex;align-items: center;margin-bottom: 10rpx;
+			}
+			.imgs{display: flex;flex-wrap: wrap;padding-bottom: 16rpx;
+				image{width: 180rpx;height: 180rpx;margin-bottom: 24rpx;margin-right: 10rpx;
+				&:nth-of-type(3n){margin-right: 0;}
+				&.img1{width: 100%;height: 290rpx;}
+				}
+				
+			}
+			.trsta{
+				.trstal{width:40rpx ;height: 32rpx;display: flex;align-items: center;justify-content: center;position: relative;margin-left: 20rpx;
+				.cir{min-width: 20rpx;height: 24rpx;line-height: 24rpx;font-size: 20rpx;color: #FFFFFF;
+background: #DF1616;
+border: 2rpx solid #FFFFFF;
+border-radius: 6rpx;position: absolute;right: -50%;top: -50%;text-align: center;padding: 0 4rpx;box-sizing: border-box;}
+				}
+				image{width: 26rpx;height: 26rpx;}
+			}
+		}
+		.delbox{display: flex;align-items: center;font-size: 26rpx;color: #718DD4;
+			image{width: 24rpx;height: 25rpx ;margin-right: 12rpx;}
+		}
+		
+		.trcom{width: 100%;background: #ECECEC;
+			.trcomz{padding: 24rpx 8rpx 8rpx 24rpx;border-bottom: 2rpx solid #DADADA;
+				.trcomr{display: flex;align-items: center;flex-wrap: wrap;
+					image{width: 40rpx;height: 40rpx;margin: 0 16rpx 16rpx 0;border-radius: 50%;}
+					}
+			}
+			.trcomp{padding: 24rpx 0 0 24rpx;
+				.trcompr{padding: 0 24rpx 12rpx 0;border-bottom: 2rpx solid #DADADA;margin-bottom: 12rpx;
+					&:last-of-type{border-bottom: none;}
+					.listl{width: 40rpx;height: 40rpx;margin-right:12rpx;border-radius: 50%;flex: 0 0 auto;}
+					
+				}
+			}
+			.trcoml{flex: 0 0 auto;margin-right: 12rpx;width: 40rpx;height: 40rpx;display: flex;align-items: center;
+				image{width: 26rpx;height: 26rpx;}
+			}
+		}
+	}
+
+</style>

+ 168 - 0
components/timetable/timetable.vue

@@ -0,0 +1,168 @@
+<template>
+    <view class="tablebox">
+    	<table  class='table'>
+    		<thead class='thead'> 
+    			<tr class="tr_one"> 
+					<th style="width: 80rpx;flex: 0 0 auto;"></th>
+    				<th  v-for="(item,idx) in week" :key="idx">{{item.tit}}</th>
+    			</tr>
+    		</thead>
+    		
+    		<tbody class="tbody" v-if="week.length>0">
+    			<tr v-for="(item,index) in timelist" :key="index">
+    				<td  class="tbodyl">
+						<view>{{item.val}}</view>
+						<view v-if="item.time">{{item.time}}</view>
+					</td>
+					<td  v-for="(weekite,idx) in week" :key="idx">
+						<block v-for="(ite,idx) in timetables" :key="idx">
+							<block v-if="ite.week==weekite.val">
+								<view v-if="item.val==1" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(1)?'act':''"  @click="getChose(ite.oneClass,ite.week,item.val)">
+									<view class="tit">{{ite.oneClass||''}}</view>
+									<view class="txt">{{ite.oneTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==2" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(2)?'act':''" @click="getChose(ite.twoClass,ite.week,item.val)">
+									<view class="tit">{{ite.twoClass||''}}</view>
+									<view class="txt">{{ite.twoTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==3" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(3)?'act':''"  @click="getChose(ite.threeClass,ite.week,item.val)">
+									<view class="tit">{{ite.threeClass||''}}</view>
+									<view class="txt">{{ite.threeTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==4" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(4)?'act':''"  @click="getChose(ite.fourClass,ite.week,item.val)">
+									<view class="tit">{{ite.fourClass||''}}</view>
+									<view class="txt">{{ite.fourTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==5" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(5)?'act':''"  @click="getChose(ite.fiveClass,ite.week,item.val)">
+									<view class="tit">{{ite.fiveClass||''}}</view>
+									<view class="txt">{{ite.fiveTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==6" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(6)?'act':''"  @click="getChose(ite.sixClass,ite.week,item.val)">
+									<view class="tit">{{ite.sixClass||''}}</view>
+									<view class="txt">{{ite.sixTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==7" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(7)?'act':''"  @click="getChose(ite.sevenClass,ite.week,item.val)">
+									<view class="tit">{{ite.sevenClass||''}}</view>
+									<view class="txt">{{ite.sevenTeacher||''}}</view>
+								</view>
+								<view v-if="item.val==8" class="lit" :class="ite.teacherClassNum&&ite.teacherClassNum.includes(8)?'act':''"  @click="getChose(ite.eightClass,ite.week,item.val)">
+									<view class="tit">{{ite.eightClass||''}}</view>
+									<view class="txt">{{ite.eightTeacher||''}}</view>
+								</view>
+							</block>
+						</block>
+					</td>
+    			</tr>
+    		</tbody>
+    	</table>
+    </view>
+</template>
+
+<script>
+	import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
+  export default {
+    name: 'Timetable',
+    props: {
+      timelist: {
+        type: Array,
+        default: () => {
+          return [{ val: '1'},{ val: '2'}, { val: '3'},{ val: '4'},{ val: '5'},{ val: '6'},{ val: '7'},{ val: '8'}]
+        }
+      },
+      week: {
+        type: Array,
+        default: () => {
+          return [{tit:'周一',val:1}, {tit:'周二',val:2}, {tit:'周三',val:3}, {tit:'周四',val:4}, {tit:'周五',val:5}]
+        }
+      },
+      timetables: {
+        type: Array,
+        default: () => {
+          return []
+        }
+      },
+      palette: {
+        type: Array,
+        default: () => {
+          return []
+        }
+      },
+	  roles:{
+		  
+	  }
+    },
+    data () {
+      return {
+        allPalette: [...this.palette, '#f05261', '#48a8e4', '#ffd061', '#52db9a', '#70d3e6', '#52db9a', '#3f51b5', '#f3d147', '#4adbc3', '#673ab7', '#f3db49', '#76bfcd', '#b495e1', '#ff9800', '#8bc34a']
+      }
+    },
+	mounted() {
+		// console.log(this.timelist)
+	},
+    computed: {
+      todayWeekIndex () {
+        let weekIndex = new Date().getDay() - 1
+        if (weekIndex === -1) {
+          weekIndex = 6
+        }
+        return weekIndex
+      }
+    },
+    methods: {
+		checkPermi, checkRole,
+      handleCourseClick (course, weekIndex, courseIndex) {
+        const data = {
+          index: courseIndex + 1,
+          length: course.length,
+          week: this.week[weekIndex],
+          weekIndex: weekIndex,
+          name: course.name
+        }
+        console.log(`星期${data.week}; 第${data.index}节课; 课程名:${data.name}; 课节:${data.length}`)
+        console.log(data)
+        this.$emit('courseClick', data)
+      },
+	  getChose(course,zweek,val){
+		  if(checkPermi(['course:change:add'])){
+			  var newobj={
+			  		subject:course,
+			  		subjectWeek:zweek,
+			  		isNum:val,
+			  }
+			  this.$emit("getChose",newobj)
+		  }
+	  }
+    }
+  }
+</script>
+
+<style scoped lang="scss">
+.tablebox{
+	.table{border-spacing: 0;width: 100%;display: flex;flex-direction: column;overflow: hidden;
+		tr{display: flex;}
+		.thead{width: 100%;background-color:#F5F5F5;flex: 0 0 auto;border-radius: 10rpx;
+			th{padding:10rpx 8rpx;box-sizing: border-box;font-size: 24rpx;color: #838383;font-weight: 500;text-align: center;flex: 1;
+			}
+		}
+		.tbody {flex: 1;overflow: auto;
+			td{min-height: 100rpx;box-sizing: border-box;font-weight: 500;color: #343434;font-size: 28rpx;text-align: center;word-break: break-all;flex: 1;display: flex;align-items: center;justify-content: center;flex-direction: column;background-color: #ffffff;padding: 0;
+				.lit{padding: 16rpx 12rpx;box-sizing: border-box;width: 100%;height: 100%;
+				// &.act{background-color:#fbb0b0;
+				&.act{background-color:#EBEBEB;
+					.txt{color: #6f6f6f;}
+				}
+				}
+			}
+			.tbodyl{display: flex;align-items: center;justify-content: center;flex: 0 0 auto;width: 80rpx;background-color:#F5F5F5;font-size: 24rpx;color: #838383;font-weight: 500;
+			}
+			
+			.tit{font-size: 30rpx;color: #161616;}
+			.txt{font-size: 26rpx;color: #AAAAAA;}
+		}
+	}	 
+}
+table, td,th{
+	border: 1rpx solid #E6E6E6;;
+	border-collapse: collapse;
+}
+</style>

+ 176 - 0
components/toptab/phonebtn.vue

@@ -0,0 +1,176 @@
+<template>
+  <view>
+	  <view class="box_hei" @click="getClose" v-if="type">
+	  	<view @click.stop="btns"  class="hei_box">
+	  		<view class="box_top">
+	  			<view class="box_title">
+	  				<view>
+	  					智能校管家 申请使用
+	  				</view>
+	  			</view>
+	  			<view class="box_nameq">你的手机号码</view>
+	  		</view>
+	  		<!-- <view class="boxs"></view> -->
+	  		<view class="box_btns">
+	  			<view @click="getClose" class="box_btn box_btn1">拒绝</view>
+	  			<button class="box_btn box_btn2" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">允许</button>
+	  		</view>
+	  	</view>
+	  </view>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import {getweChatOpenid} from "@/api/login.js"
+  export default {
+	  props:{
+		type:{
+			type:Boolean,
+			default () {
+				return true
+			}
+		},
+	  },
+	data(){
+		return{
+			sucimg:require("@/mine/static/mine/success.png") 
+		}
+	},
+	methods:{
+		getClose(){
+			this.$emit("getClose")
+		},
+		btns(){
+			
+		},
+		async getPhoneNumber(e){
+			const {iv,encryptedData} = e.detail;
+			var that=this;
+			uni.login({
+			    provider: 'weixin',
+			    success: (res) => {
+			        // 获取用户信息
+					if(res.code) {
+						var params={
+							iv: iv,
+							encryptedData: encryptedData,
+							code : res.code,
+						}
+						// 登录还是注册
+						that.$emit("getPhoneNumber",params)
+						
+					}
+			    }
+			})			
+		}, 
+	},
+	onLoad: function() {
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+.box_hei{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,.8);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 3;
+		.hei_box{
+			background: #fff;
+			border-radius:22upx 22upx 0 0;
+			height: 440upx;
+			padding: 52upx 28upx 104upx;
+			position: absolute;
+			bottom:0;
+			width: 100%;
+			box-sizing: border-box;
+			.box_top{
+				padding: 0 18upx 62upx;
+				.box_title{
+					display: flex;
+					justify-content: space-between;
+					font-size: 30upx;
+					margin-bottom: 30upx;
+					view{
+						display: flex;
+						align-items: center;
+						color: #333333;
+					}
+					.img{
+						margin-right: 14upx;
+						width: 180upx;
+						height: 48upx;
+					}
+					.imgs{
+						width: 40upx;
+						height: 40upx;
+					}
+				}
+				.box_nameq{
+					color: #333333;
+					font-size: 44upx;
+					font-weight: bold;
+				}
+			}
+			.box_phone{
+				height: 106upx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				font-size: 28upx;
+				color: #A6A6A6;
+				border-bottom: 1upx solid #EBEBEB;
+				border-top: 1upx solid #EBEBEB;
+				view{
+					display: flex;
+					align-items: center;
+				}
+				.img{
+					width: 26upx;
+					height: 22upx;
+				}
+				span{
+					color: #333333;
+					font-size: 32upx;
+					padding-right: 18upx;
+					font-weight: bold;
+				}
+			}
+			.box_qita{
+				height: 106upx;
+				font-size: 28upx;
+				color: #7CA4FC;
+				line-height: 106upx;
+			}
+			.boxs{
+				height: 50upx;
+			}
+			.box_btns{
+				margin-top: 10upx;
+				display: flex;
+				justify-content: space-between;
+				.box_btn{
+					width: 324upx;
+					height: 82upx;
+					font-size: 32upx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+					border-radius: 4upx;
+				}
+				.box_btn1{
+					background: #F3F3F3;
+					color: #33B925;
+				}
+				.box_btn2{
+					background: #37962B;
+					color: #FFFFFF;
+				}
+			}
+		}
+	}
+</style>

+ 99 - 0
components/toptab/tab.vue

@@ -0,0 +1,99 @@
+<template>
+	<view class="listtopb flexc" >
+		<block v-for="(ite,idx) in tablist" :key='idx'>
+			<block v-if='ite.limt'>
+				<view class="tit" :style="'height:'+height+'rpx'" :class="tabidx==ite.val?'act':''" @click="getTab(ite.val)" v-if="checkPermi([ite.limt])">
+					<view class="f16 fw mb6 tits" >{{ite.tit}}</view>
+					<view class="f500 f14 txt" v-if="ite.txt||ite.txt==0">{{ite.txt}}</view>
+					<image :src="tapline" class="line"></image>
+				</view>
+			</block>
+			<block v-else>
+				<view class="tit" :style="'height:'+height+'rpx'" :class="tabidx==ite.val?'act':''" @click="getTab(ite.val)" >
+					<view class="f16 fw mb6 tits" >{{ite.tit}}</view>
+					<view class="f500 f14 txt" v-if="ite.txt||ite.txt==0">{{ite.txt}}</view>
+					<image :src="tapline" class="line"></image>
+				</view>
+				
+			</block>
+		</block>
+		<!-- 切换按钮 -->
+		<view :style="'height:'+height+'rpx'" class="chebox" @click="getroleFn" v-if="checkPermi(['register:teacher:list'])&&tabbtn">
+			<image :src="micone"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import { checkPermi, checkRole } from "@/utils/permission"; // 权限判断函数
+	export default{
+		props:{
+			tablist:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			height:{
+				type: Number,
+				default () {
+					return 100
+				}
+			},
+			tabbtn:{
+				type:Boolean,
+				default () {
+					return false
+				}
+			},
+			tabidx:{
+				type: Number,
+				default () {
+					return 0
+				}
+			}
+		},
+		data(){
+			return{
+				// :0,
+				tapline:require("@/static/images/hline.png"), 
+				micone:require("@/static/images/micone.png"),
+			}
+		},
+		mounted() {
+			// this.tabidxs=this.tabidx
+		},
+		methods:{
+			checkPermi, checkRole,
+			getTab(idx){
+				// this.tabidxs=idx;
+				this.$emit('getCheck',idx)
+			},
+			getroleFn(){
+				this.$emit('getroleFn')
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.listtopb{
+		background-color: #ffffff;
+		 .tit{flex: 1;display: flex;flex-direction: column;justify-content: center;position: relative;
+			view{text-align: center;}
+			.tits{color: #AAAAAA ;}
+			.txt{color: #aaaaaa;}
+			.line{width: 40rpx;height: 12rpx;position: absolute;left: 50%;margin-left: -20rpx;bottom: 6rpx;display: none;}
+		 &.act{
+			 // &::after{content: '';width: 100rpx;height: 6rpx;background:#FE5706 ;position: absolute;left: 50%;margin-left: -50rpx;bottom: 0;}
+			.tits{color: #161616;}
+			.txt{color: #FE5706;}
+			.line{display: block;}
+			}
+		 }
+		.chebox{width: 96rpx;background: #FFFFFF;
+box-shadow: -10rpx 0rpx 10rpx 0rpx rgba(196,191,191,0.22);display: flex;align-items: center;justify-content: center;
+			image{width: 30rpx;height: 26rpx;}
+		}
+	}
+</style>

+ 31 - 0
config.js

@@ -0,0 +1,31 @@
+// 应用全局配置
+module.exports = {
+  // baseUrl: 'https://xygl.qs163.cn/prod-api',
+  // baseUrl: 'http://192.168.101.245:8030',
+  baseUrl: 'http://192.168.101.168:8030',
+  // baseUrl: 'http://localhost:8080',
+  baseUrlimg: 'https://xygl.qs163.cn',
+  Clientid:'428a8310cd442757ae699df5d894f051',//
+  confirmflag:false,//是否有弹窗
+  // 应用信息
+  appInfo: {
+    // 应用名称
+    name: "ruoyi-app",
+    // 应用版本
+    version: "1.1.0",
+    // 应用logo
+    logo: "/static/logo.png",
+    // 官方网站
+    site_url: "http://ruoyi.vip",
+    // 政策协议
+    agreements: [{
+        title: "隐私政策",
+        url: "https://ruoyi.vip/protocol.html"
+      },
+      {
+        title: "用户服务协议",
+        url: "https://ruoyi.vip/protocol.html"
+      }
+    ]
+  }
+}

BIN
f8ba4038bda577d6c56968e3f4a293f4.keystore


+ 21 - 0
main.js

@@ -0,0 +1,21 @@
+import Vue from 'vue'
+import App from './App'
+import store from './store' // store
+import plugins from './plugins' // plugins
+import './permission' // permission
+Vue.use(plugins)
+import {toast} from "@/utils/common.js"
+
+
+
+Vue.config.productionTip = false
+Vue.prototype.$store = store
+Vue.prototype.$toast=toast;
+
+App.mpType = 'app'
+
+const app = new Vue({
+  ...App
+})
+
+app.$mount()

+ 112 - 0
manifest.json

@@ -0,0 +1,112 @@
+{
+    "name" : "智能校管家",
+    "appid" : "__UNI__D7019D4",
+    "description" : "",
+    "versionName" : "1.1.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "modules" : {
+            "Maps" : {},
+            "Geolocation" : {},
+            "Camera" : {}
+        },
+        "distribute" : {
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            "ios" : {
+                "dSYMs" : false
+            },
+            "sdkConfigs" : {
+                "oauth" : {},
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "2c4c338296d8bd870b9c4a58d6a8f258",
+                        "appkey_android" : "2c4c338296d8bd870b9c4a58d6a8f258"
+                    }
+                },
+                "ad" : {},
+                "geolocation" : {}
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "static/logo.png"
+                }
+            }
+        }
+    },
+    "quickapp" : {},
+    "mp-weixin" : {
+        "appid" : "wx4492fe7554b0cb0a",
+        "setting" : {
+            "urlCheck" : false,
+            "es6" : false,
+            "minified" : true,
+            "postcss" : true
+        },
+        "optimization" : {
+            "subPackages" : true
+        },
+        "usingComponents" : true,
+        "unipush" : {
+            "enable" : true
+        },
+        "permission" : {
+            "scope.userLocation" : {
+                "desc" : "获取当前位置"
+            }
+        }
+    },
+    "vueVersion" : "2",
+    "h5" : {
+        "template" : "static/index.html",
+        "devServer" : {
+            "port" : 9090,
+            "https" : false
+        },
+        "title" : "RuoYi-App",
+        "router" : {
+            "mode" : "history",
+            "base" : ""
+        },
+        "sdkConfigs" : {
+            "maps" : {
+                "amap" : {
+                    "key" : "fba818d626f91cf5a13cd61943a7667e",
+                    "securityJsCode" : "b06df55c66884ce2c9a3f3281c2c5ca9",
+                    "serviceHost" : ""
+                }
+            }
+        }
+    }
+}

+ 406 - 0
mine/components/ba-tree-picker/danpicker.vue

@@ -0,0 +1,406 @@
+<!-- 树形层级选择器-->
+<!-- 1、支持单选、多选 -->
+<template>
+	<view class="xmmain">
+		<view class="tree-cover" :class="{'show':showDialog}" @tap="_cancel"></view>
+		<view class="tree-dialog" :class="{'show':showDialog}">
+			<view class="tree-bar">
+				<view class="tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消
+				</view>
+				<view class="tree-bar-title" :style="{'color':titleColor}">{{title}}</view>
+				<view class="tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c" @tap="_confirm">
+					{{multiple?'确定':''}}
+				</view>
+			</view>
+			<view class="tree-view">
+				<scroll-view class="tree-list" :scroll-y="true">
+					<uni-data-checkbox selectedTextColor='#343434'  :map="map" :multiple="multiple" v-model="bgvalue" :localdata="localdata" @change="checkboxChangeadr"></uni-data-checkbox>
+				</scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		emits: ['select-change'],
+		name: "ba-tree-picker",
+		props: {
+			map:{
+				type: Object,
+				default: {},
+			},
+			mvalue:{
+				type: Array,
+				default: function() {
+					return []
+				}
+			},
+			valueKey: {
+				type: String,
+				default: 'id'
+			},
+			textKey: {
+				type: String,
+				default: 'name'
+			},
+			childrenKey: {
+				type: String,
+				default: 'children'
+			},
+			localdata: {
+				type: Array,
+				default: function() {
+					return []
+				}
+			},
+			localTreeList: { //在已经格式化好的数据
+				type: Array,
+				default: function() {
+					return []
+				}
+			},
+			selectedData: {
+				type: Array,
+				default: function() {
+					return []
+				}
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			deptType:{
+				type: String,
+				default: ''
+			},
+			multiple: { // 是否可以多选
+				type: Boolean,
+				default: true
+			},
+			selectParent: { //是否可以选父级
+				type: Boolean,
+				default: true
+			},
+			confirmColor: { // 确定按钮颜色
+				type: String,
+				default: '' // #FE5706
+			},
+			cancelColor: { // 取消按钮颜色
+				type: String,
+				default: '' // #757575
+			},
+			titleColor: { // 标题颜色
+				type: String,
+				default: '' //
+			},
+			switchColor: { // 节点切换图标颜色
+				type: String,
+				default: '' // #666
+			},
+			border: { // 是否有分割线
+				type: Boolean,
+				default: false
+			},
+		},
+		data() {
+			return {
+				showDialog: false,
+				treeList: [],
+				checkArr:[],
+				bgvalue:[1,2]
+			}
+		},
+		computed: {},
+		methods: {
+			checkboxChangeadr(e){
+				this.checkArr=e.detail.data;
+			},
+			_show() {
+				this.showDialog = true
+			},
+			_hide() {
+				this.showDialog = false
+			},
+			_cancel() {
+				this._hide()
+				this.$emit("cancel", '');
+			},
+			_confirm() { //多选
+				
+				this._hide()
+				if(this.checkArr.length>0){
+					this.$emit("select-change", this.checkArr);
+				}
+				// this.$emit("select-change", selectedList, selectedNames);	
+			},
+		},
+		watch: {
+			mvalue(data){
+				this.bgvalue=data
+			}
+		},
+		mounted() {
+			this.bgvalue=this.mvalue;
+			// this._initTree();
+		}
+	}
+</script>
+
+<style >
+
+.xmbtn{height: 100rpx;display: flex;align-items: center;justify-content: center;}
+.xmbtn.btn1{width: 200rpx;}
+.xmbtn.btn2{background-color: $uni-color-fa;}
+	.tree-cover {
+		position: fixed;
+		top: 0rpx;
+		right: 0rpx;
+		bottom: 0rpx;
+		left: 0rpx;
+		z-index: 100;
+		background-color: rgba(0, 0, 0, .4);
+		opacity: 0;
+		transition: all 0.3s ease;
+		visibility: hidden;
+	}
+
+	.tree-cover.show {
+		visibility: visible;
+		opacity: 1;
+	}
+
+	.tree-dialog {
+		position: fixed;
+		top: 0rpx;
+		right: 0rpx;
+		bottom: 0rpx;
+		left: 0rpx;
+		background-color: #fff;
+		border-top-left-radius: 10px;
+		border-top-right-radius: 10px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		z-index: 100002;
+		top: 20%;
+		transition: all 0.3s ease;
+		transform: translateY(100%);
+	}
+
+	.tree-dialog.show {
+		transform: translateY(0);
+	}
+
+	.tree-bar {
+		/* background-color: #fff; */
+		height: 90rpx;
+		padding-left: 25rpx;
+		padding-right: 25rpx;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		box-sizing: border-box;
+		border-bottom-width: 1rpx !important;
+		border-bottom-style: solid;
+		border-bottom-color: #f5f5f5;
+		font-size: 32rpx;
+		color: #757575;
+		line-height: 1;
+	}
+
+	.tree-bar-confirm {
+		color: #FE5706;
+		padding: 15rpx;
+	}
+
+	.tree-bar-title {}
+
+	.tree-bar-cancel {
+		color: #757575;
+		padding: 15rpx;
+	}
+
+	.tree-view {
+		flex: 1;
+		padding: 20rpx 36rpx;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		overflow: hidden;
+		height: 100%;
+	}
+
+	.tree-list {
+		flex: 1;
+		height: 100%;
+		overflow: hidden;
+	}
+
+	.tree-item {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		line-height: 1;
+		height: 0;
+		opacity: 0;
+		transition: 0.2s;
+		overflow: hidden;
+	}
+
+	.tree-item.show {
+		height: 90rpx;
+		opacity: 1;
+	}
+
+	.tree-item.showchild:before {
+		transform: rotate(90deg);
+	}
+
+	.tree-item.last:before {
+		opacity: 0;
+	}
+
+	.switch-on {
+		width: 0;
+		height: 0;
+		border-left: 16rpx solid transparent;
+		border-right: 16rpx solid transparent;
+		border-top: 20rpx solid #666;
+	}
+
+	.switch-off {
+		width: 0;
+		height: 0;
+		border-bottom: 16rpx solid transparent;
+		border-top: 16rpx solid transparent;
+		border-left: 20rpx solid #666;
+	}
+
+	.item-last-dot {
+		position: absolute;
+		width: 12rpx;
+		height: 12rpx;
+		border-radius: 100%;
+		background: #666;
+	}
+
+	.item-icon {
+		width: 26rpx;
+		height: 30rpx;
+		margin-right: 8rpx;
+		padding-right: 20rpx;
+		padding-left: 20rpx;
+	}
+
+	.item-label {
+		flex: 1;
+		display: flex;
+		align-items: center;
+		height: 100%;
+		line-height: 1.2;
+	}
+
+	.item-name {
+		flex: 1;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		/* width: 450rpx; */
+		font-size: 34rpx;
+		font-weight: bold;
+		line-height: 1;
+	}
+
+	.item-check {
+		width: 40px;
+		height: 40px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.item-check-yes,
+	.item-check-no {
+		width: 32rpx;
+		height: 32rpx;
+		border-top-left-radius: 20%;
+		border-top-right-radius: 20%;
+		border-bottom-right-radius: 20%;
+		border-bottom-left-radius: 20%;
+		border-top-width: 1rpx;
+		border-left-width: 1rpx;
+		border-bottom-width: 1rpx;
+		border-right-width: 1rpx;
+		border-style: solid;
+		border-color: #FE5706;
+		border-radius: 8rpx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		box-sizing: border-box;
+		 /* background-color: #FE5706; */
+	}
+	.item-check-yes{
+		border: none;
+		background-color: #FE5706;
+	}
+
+	.item-check-yes-part {
+		width: 24rpx;
+		height: 6rpx;
+		border-top-left-radius: 20%;
+		border-top-right-radius: 20%;
+		border-bottom-right-radius: 20%;
+		border-bottom-left-radius: 20%;
+		background-color: #ffffff;
+	}
+
+	.item-check-yes-all {
+		margin-bottom: 5px;
+		border: 2px solid #ffffff;
+		border-left: 0;
+		border-top: 0;
+		height: 12px;
+		width: 6px;
+		transform-origin: center;
+		/* #ifndef APP-NVUE */
+		transition: all 0.3s;
+		/* #endif */
+		transform: rotate(45deg);
+		/* border: none;
+		background-color: #FE5706; */
+	}
+
+	.item-check .radio {
+		border-top-left-radius: 50%;
+		border-top-right-radius: 50%;
+		border-bottom-right-radius: 50%;
+		border-bottom-left-radius: 50%;
+	}
+
+	.item-check .radio .item-check-yes-b {
+		border-top-left-radius: 50%;
+		border-top-right-radius: 50%;
+		border-bottom-right-radius: 50%;
+		border-bottom-left-radius: 50%;
+	}
+
+	.hover-c {
+		opacity: 0.6;
+	}
+
+	.itemBorder {
+		border-bottom: 1px solid #e5e5e5;
+	}
+.xmmain /deep/ .uni-data-checklist .checklist-group{display: block;}
+  .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box{padding: 28rpx 0;margin: 0;}
+   
+   .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box .checklist-text{color: #343434;font-size: 32rpx;font-weight: bold;}
+  .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box .checkbox__inner{margin-right: 32rpx;}
+  .xmmain  /deep/ .uni-data-checklist .checklist-group .checklist-box.is--default.is-checked .checkbox__inner{border-color: #FF440B; background-color: #FF440B;}
+  .xmmain /deep/ .uni-data-checklist .checklist-group .checklist-box.is--default.is-checked .checklist-text{color: #343434;}
+
+</style>

+ 524 - 0
mine/components/list/list.vue

@@ -0,0 +1,524 @@
+<template>
+	<view>
+		<view v-if="datalist.length>0">
+			<!-- 学生 -->
+			<block v-if="datype==1">
+				<view class="stlbox clearf">
+					<view class="stlist" :class="[ite.sex==1?'bg1':'bg2',roles=='parents'?'sthlist':'']" @click="getDetail(ite.id)"
+						v-for="(ite,idx) in datalist" :key="idx">
+						<view class="flext listt">
+							<image v-if="ite.identificationPhoto" :src="baseUrl+ite.identificationPhoto" class="headimg"
+								:class="ite.sex==1?'btn1':'btn2'"></image>
+							<image :src="head" :class="ite.sex==1?'btn1':'btn2'" class="headimg" v-else></image>	
+							 
+							<view class="flex1">
+								<view class="flextj ">
+									<view class="flex1 flext">
+										<view class="tit">{{ite.name}}</view>
+										<image :src="man" class="mximg" v-if="ite.sex==1"></image>
+										<image :src="woman" class="wmimg" v-if="ite.sex==2"></image>
+										<image :src="year" class="yeimg" v-if="ite.isNearsightedness&&ite.isNearsightedness==1"></image>
+										<image :src="health" class="heimg" v-if="ite.health&&ite.health!=1"></image>
+									</view>
+									<view class="flex0 f13 coa" v-if="roles=='parents'">更新时间:{{ite.updateTime||ite.createTime}}</view>
+								</view>
+								<view class="txt" >
+									<block v-if="ite.age">{{ite.age}}岁/</block>
+									<block v-if="ite.height">{{ite.height}}cm/</block>
+									<block v-if="ite.weight">{{ite.weight}}kg/</block>
+									<block v-if="ite.isNearsightedness==1">{{ite.degreeMyopia}}</block>
+									<block v-if="ite.isNearsightedness==2">无近视/远视</block>
+									<view class="updimg" @click.stop="getHeightFn(ite,'height')">
+										<image :src="daupdata"></image>
+									</view>
+									
+								</view>
+							</view>
+						</view>
+						<view class="listf">
+							<view class="ltxt" v-if="roles=='parents'">政治面貌:{{ite.politicalStatus}}</view>
+							<view class="ltxt">心理健康状态:{{ite.mind}}
+							<view class="updimg" @click.stop="getHeightFn(ite,'mind')">
+								<image :src="daupdata"></image>
+							</view>
+							</view>
+							<view class="ltxt">家长描述:{{ite.psychologicalDescription}}</view>
+							<!-- 请假 -->
+							<!-- <view class="ltxtq">请假中,查看详情...</view> -->
+							<!-- 家长 -->
+							<block v-if="roles=='parents'">
+								<image :src="mbg" class="mbg" v-if="ite.sex==1"></image>
+								<image :src="wmbg" class="mbg" v-if="ite.sex==2"></image>
+							</block>
+						</view>
+					</view>
+				</view>
+			</block>
+			<!-- 教职工 -->
+			<block v-if="datype==2">
+				<view class="stlbox clearf">
+					<view class="stlist "  :class="ite.sex==1?'bg1':'bg2'" @click="getDetail(ite.id)"
+						v-for="(ite,idx) in datalist" :key="idx">
+						<view class="flext listt">
+							<image v-if="ite.identificationPhoto" :src="baseUrl+ite.identificationPhoto" class="headimg"
+								:class="ite.sex==1?'btn1':'btn2'"></image>
+							<image :src="head" :class="ite.sex==1?'btn1':'btn2'" class="headimg" v-else></image>	
+							<view>
+								<view class="flext">
+									<view class="tit">{{ite.name}}</view>
+									<image :src="man" class="mximg" v-if="ite.sex==1"></image>
+									<image :src="woman" class="wmimg" v-if="ite.sex==2"></image>
+								</view>
+								<view class="txt">
+									<block v-if="ite.age">{{ite.age}}岁/</block>
+									<block v-if="ite.height">{{ite.height}}cm/</block>
+									<block v-if="ite.weight">{{ite.weight}}kg</block>
+								</view>
+							</view>
+							<!-- <image :src="year" class="yeimg"></image> -->
+						</view>
+						<view class="listf">
+							<!-- <view class="ltxt">教龄:7年</view> -->
+							<view class="ltxt">职称:{{ite.professional}}</view>
+							<view class="ltxt">联系方式:{{ite.phone}}</view>
+							<!-- <view class="ltxt">入职已经<text :class="ite.sex==1?'co47':'cfe'">2313</text>天啦</view> -->
+						</view>
+					</view>
+				</view>
+			</block>
+			<!-- 班级成绩 -->
+			<block v-if="datype==3">
+				<view class="cjlist" @click="getDetail(ite.scoreId)" v-for="(ite,idx) in datalist" :key="idx">
+					<!-- 老师 -->
+					<view class="flext mb6">
+						<view class="f16 c16 fw flex1">{{ite.scoreTitle}}</view>
+						<image :src="cjmicong" class="moimg"></image>
+					</view>
+					<!-- 家长 -->
+					<!-- <view class="flexc mb6">
+						<view class="f16 c16 fw flex1">{{ite.scoreTitle}}</view>
+						<view class="f14 fw5 flex0 ml10 co47">已查看</view>
+						<view class="f14 fw5 flex0 ml10 c6">未查看</view>
+					</view> -->
+					<view class="flexc">
+						<view class="f14 fw5 co6 flex1">考试班级:{{ite.scoreClassName}}</view>
+						<view class="f14 fw5 coa flex0">{{ite.scoreTime}}</view>
+					</view>
+					<view class='cjlook flexc' v-if="roles!='parents'">
+						<view>已查看:<text class="f15 co16">{{ite.chaKan}}</text><text class="co16">人</text></view>
+						<view>未查看:<text class="f15 co16">{{ite.weiChaKan}}</text><text class="co16">人</text></view>
+						<view>查看率:<text class="f15 co16">{{ite.percentage}}</text></view>
+					</view>
+				</view>
+			</block>
+			<!-- 心理健康 -->
+			<block v-if="datype==5">
+				<view class="time" v-for="(lite,lidx) in datalist" :key="lidx">
+					<view class="time_t"  @click="getLook(lidx)" :class="lite.check?'act':''">
+						<view>{{lite.ayear}}年<text>{{lite.amonth}}月</text></view>
+						<image :src="timeup" class="timeup"></image>
+					 </view>
+					 <view v-if="lite.check">
+						<view class="timebox" v-for="(ite,idx) in lite.children" :key="idx">
+							<view class="list">
+								<image :src="timel" class="timel"></image>
+								<view class="listr">
+									<view class="listrt">
+									{{ite.createTime}}<text v-if="ite.createType" class="type " :class="ite.createType==2?'bg2':'bg1'">
+										{{ite.createType==2?'老师':'家长'}}
+									</text>
+										<view class="flex1"></view>
+										<view class="delboxs" v-if="checkPermi(['live:old:remove'])" @click="getDel(ite.mindId)">删除</view>
+									</view>
+									<view class="listrx flext">
+										<view class="ltit">状态:</view>
+										<view class="ltxt">{{ite.mind}}</view>
+									</view>
+									<view class="listrx flext" v-if="ite.psychologicalDescription">
+										<view class="ltit">描述:</view>
+										<view class="ltxt">{{ite.psychologicalDescription}}</view>
+									</view>
+								</view>
+							</view>
+						</view> 
+					 </view>
+				</view>
+			</block>
+			<block v-if="datype==15">
+				<view class="time" v-for="(ite,idx) in datalist" :key="idx">
+					<!-- :class="actidx==1?'act':''" -->
+					<!-- <view class="time_t"  @click="getLook(1)">
+						<view>2023年<text>7月</text></view>
+						<image :src="timeup" class="timeup"></image>
+					 </view> -->
+					<view class="timebox">
+						<view class="list">
+							<image :src="timel" class="timel"></image>
+							<view class="listr">
+								<view class="listrt">
+								{{ite.createTime}}<text v-if="ite.createType" class="type " :class="ite.createType==2?'bg2':'bg1'">
+									{{ite.createType==2?'老师':'家长'}}
+								</text>
+									<view class="flex1"></view>
+									<view class="delboxs" v-if="checkPermi(['live:old:remove'])" @click="getDel(ite.mindId)">删除</view>
+								</view>
+								<view class="listrx flext">
+									<view class="ltit">状态:</view>
+									<view class="ltxt">{{ite.mind}}</view>
+								</view>
+								<view class="listrx flext" v-if="ite.psychologicalDescription">
+									<view class="ltit">描述:</view>
+									<view class="ltxt">{{ite.psychologicalDescription}}</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</block>
+			<!-- 身高体重 -->
+			<block v-if="datype==6">
+				<view class="time" v-for="(lite,lidx) in datalist" :key="lidx">
+					<view class="time_t"  @click="getLook(lidx)" :class="lite.check?'act':''">
+						<view>{{lite.ayear}}年<text>{{lite.amonth}}月</text></view>
+						<image :src="timeup" class="timeup"></image>
+					 </view>
+					<view v-if="lite.check">
+					<view class="timebox" v-for="(ite,idx) in lite.children" :key="idx">
+						<view class="list">
+							<image :src="timel" class="timel"></image>
+							<view class="listr">
+								<view class="listrt">
+								{{ite.createTime}}
+								<text v-if="ite.createType" class="type " :class="ite.createType==2?'bg2':'bg1'">
+									{{ite.createType==2?'老师':'家长'}}</text>
+									<view class="flex1"></view>
+									<view class="delboxs" v-if="checkPermi(['live:old:remove'])" @click="getDel(ite.liveId)">删除</view>
+								</view>
+								<view class="listrx flext" v-if="ite.height">
+									<view class="ltit">身高:</view>
+									<view class="ltxt">{{ite.height}}cm</view>
+								</view>
+								<view class="listrx flext" v-if="ite.weight">
+									<view class="ltit">体重:</view>
+									<view class="ltxt">{{ite.weight}}kg</view>
+								</view>
+							</view>
+						</view>
+					</view>
+					</view>
+				</view>
+			</block>
+			<!-- 请假 -->
+			<block v-if="datype==7">
+				<view class="time" v-for="(lite,lidx) in datalist" :key="lidx">
+					<view class="time_t"  @click="getLook(lidx)" :class="lite.check?'act':''">
+						<view>{{lite.ayear}}年<text>{{lite.amonth}}月</text></view>
+						<image :src="timeup" class="timeup"></image>
+					 </view>
+					<view v-if="lite.check">
+					<view class="timebox" v-for="(ite,idx) in lite.children" :key="idx">
+						<view class="list">
+							<image :src="timel" class="timel"></image>
+							<view class="listr">
+								<view class="listrt">
+								{{ite.submitTime}}
+								<!-- <text v-if="ite.createType" class="type " :class="ite.createType==2?'bg2':'bg1'">
+									{{ite.createType==2?'老师':'家长'}}</text> -->
+									<view class="flex1"></view>
+									<!-- <view class="delboxs" v-if="checkPermi(['system:leave:remove'])" @click="getDel(ite.id)">删除</view> -->
+								</view>
+								<view class="listrx flext" v-if="roles!='parents'">
+									<view class="ltit">姓名:</view>
+									<view class="ltxt">{{ite.absenteeName}}</view>
+								</view>
+								<view class="listrx flext">
+									<view class="ltit">时间:</view>
+									<view class="ltxt">{{ite.startTime}} 至 {{ite.endTime}}</view>
+								</view>
+								<view class="listrx flext">
+									<view class="ltit">类别:</view>
+									<view class="ltxt">{{kaType(ite.category,qjlxrange)}}</view>
+								</view>
+								<view class="listrx flext">
+									<view class="ltit">描述:</view>
+									<view class="ltxt">{{ite.reason}}</view>
+								</view>
+							</view>
+						</view>
+					</view>
+					</view>
+				</view>
+			</block>
+			<!-- 预约 -->
+			<block v-if="datype==8">
+				<view class="shlist" v-for="(ite,idx) in datalist" :key="idx">
+					<view class="tittop flexc mb8">
+						<view class="f17 f5 co47 flex1">{{ite.subject}} </view>
+						<!-- <span style="margin-left: 20rpx;">{{ite.applyName}}</span> -->
+						<view class="f14 f5 co47 flex0">{{ite.subjectTime}}/{{kaType(ite.week,week)}}</view>
+					</view>
+					<view class="plr12">
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">调课班级:</view>
+							<view class="f15 co6 flex1">{{ite.subjectClass}}</view>
+						</view>
+						<view class="list flext ptb4">
+							<view class="f15 co16 flex0 fw5">被调课班级:</view>
+							<view class="f15 co6 flex1">{{ite.beSubject}}/{{ite.beSubjectTime}}/{{kaType(ite.week,week)}}</view>
+						</view>
+						<view class="list flext ptb4" v-if='ite.content'>
+							<view class="f15 co16 flex0 fw5">调课内容:</view>
+							<view class="f15 co6 flex1">{{ite.content}}</view>
+						</view>
+					</view>
+				</view>
+			</block>
+			<view class="shax" v-if="wtdt">{{wtdt}}</view>
+		</view>
+		<block v-else>
+			<no-data></no-data>
+		</block>
+	</view>
+</template>
+
+<script>
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	import noData from "@/components/nodata/nodata.vue"
+	import {selectDictValue} from '@/utils/common.js';
+	import {
+		checkPermi,
+		checkRole
+	} from "@/utils/permission"; // 权限判断函数
+	export default {
+		props: {
+			datalist: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			datype: {
+				typeof: [Number, String],
+				default () {
+					return 0
+				}
+			},
+			wtdt: {
+				type: String,
+				default () {
+					return ''
+				}
+			},
+			roles:{},
+			delfalg:{
+				type: Boolean,
+				default () {
+					return false
+				}
+			},
+			qjlxrange:{
+				type: Array,
+				default () {
+					return []
+				}
+			}
+
+		},
+		components: {
+			noData
+		},
+		data() {
+			return {
+				woman:require("@/mine/static/score/woman.png"),
+				man:require("@/mine/static/score/man.png"),
+				year:require("@/mine/static/score/year.png"),
+				head:require("@/mine/static/score/head.png"),
+				health:require("@/mine/static/score/health.png"),
+				mbg:require("@/mine/static/score/mbg.png"),
+				wmbg:require("@/mine/static/score/wmbg.png"),
+				cjmicong:require("@/mine/static/score/more.png"),
+				timel:require("@/mine/static/score/timel.png"),
+				timeup:require("@/mine/static/score/timeup.png"),
+				daupdata:require("@/mine/static/score/daupdata.png"),
+				baseUrl: ''
+			}
+		},
+		methods: {
+			checkPermi,
+			checkRole,
+			kaType(data, list) {
+				return selectDictValue(list, data);
+			},
+			getDel(data) {
+				this.$modal.confirm('确定删除该条信息?').then(() => {
+					this.$emit('getDel', data)
+				})
+			},
+			getDetail(id) {
+				this.$emit('getDetail', id)
+			},
+			getHeightFn(ite,type){
+				var obj={
+					studentId:ite.studentId,
+					name:ite.name,
+					type:type
+				}
+				this.$emit('getHeightFn', obj)
+			},
+			// 查看照片
+			getPreview(iurl, idx) {
+				var newArr = [];
+				iurl.forEach(ite => {
+					var ds = this.baseUrl + ite
+					newArr.push(ds)
+				})
+				uni.previewImage({
+					urls: newArr,
+					current: idx,
+					success: function(data) {
+
+					},
+					fail: function(err) {
+						console.log(err.errMsg);
+					}
+				});
+			},
+			// 展开
+			getLook(idx){
+				this.datalist[idx].check=!this.datalist[idx].check
+			}
+		},
+		mounted() {
+			this.baseUrl = baseUrl
+		},
+		onLoad: function() {
+
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	// align-items: stretch;display: flex;flex-wrap: wrap;justify-content: space-between;
+.stlbox{padding:40rpx 20rpx 0;}
+.shlist{width: 100%;background: #FFFFFF;border-radius: 14rpx;padding: 0 24rpx 24rpx;margin-bottom: 24rpx;
+	.tittop{padding:20rpx 24rpx;border-bottom: 2rpx solid #E6E6E6;
+		.tsbtn{min-width: 90rpx;height: 36rpx;border-radius: 4rpx;padding: 0 12rpx;box-sizing: border-box;font-size: 24rpx;line-height: 36rpx;
+			&.co1{background: #FFEDDF;color: #E19301;}
+			&.co2{background: #D3F7E5;color: #24D725;}
+			&.co3{background: #FDE2E3;color: #EC1134;}
+		}
+	}
+	.list{
+		.btn{min-width: 106rpx;height: 46rpx;border-radius: 14rpx;display: flex;align-items: center;justify-content: center;box-sizing: border-box;font-size: 26rpx;margin-left: 20rpx;
+			&.btn1{background: #1f57e6;color: #FFFFFF;}
+			&.btn2{border: 1px solid #4775EA;color: #4775EA;}
+			&.btn3{border: 1px solid red;color: red;}
+		}
+	}
+}
+// min-height: 288rpx;
+.stlist{width: 328rpx;border-radius: 10rpx;padding:0 20rpx;box-sizing: border-box;margin:0 12rpx 24rpx;float: left;
+	&.bg1{background: #F5FAFE;}
+	&.bg2{background: #FFF8FA;}
+	.listt{padding: 24rpx 0;min-height: 130rpx;box-sizing: border-box;}
+	.headimg{width: 80rpx;height: 80rpx;border-radius: 50%;flex: 0 0 auto;margin: 0 !important;margin-right: 14rpx !important;box-sizing: border-box;
+		&.btn1{border: 2rpx solid #4775EA;}
+		&.btn2{border: 2rpx solid #F59FBC;}
+	}
+	.tit{font-size: 30rpx;font-weight: bold;color: #161616;margin-bottom: 10rpx;}
+	.txt{font-weight: bold;color: #161616;font-size: 24rpx;word-break: break-all;	}
+	image{flex: 0 0 auto;margin-left: 12rpx;margin-top: 10rpx;}
+	.updimg{width: 32rpx;height: 32rpx;display: inline-flex;align-items: center;justify-content: center;
+		image{width: 18rpx;height: 18rpx;}
+	}
+	.wmimg{width: 20rpx;height: 20rpx;}
+	.mximg{width: 14rpx;height: 22rpx;}
+	.yeimg{width: 32rpx;height: 20rpx;}
+	.heimg{width: 20rpx;height: 22rpx;}
+	.listf{border-top: 2rpx solid #E6E6E6;padding:20rpx 8rpx;position: relative;
+		.ltxt{font-size: 26rpx;font-weight: 500;color: #666666;margin-bottom: 8rpx;z-index: 1;
+			text{padding: 0 6rpx;}
+		}
+		.ltxtq{font-size: 26rpx;font-weight: 500;color: #FE5A0E;}
+		.mbg{width: 96rpx;height: 96rpx;position: absolute;right: 16rpx;bottom: 20rpx;}
+		
+	}
+	// 横向
+	&.sthlist{
+		min-height: 260rpx;width: 100%;
+		.headimg{width: 70rpx;height: 70rpx;}
+		.listt{padding: 24rpx 14rpx;}
+		.listf{padding: 20rpx 16rpx;display: flex;flex-wrap: wrap;
+			.ltxt{width: 50%;}
+		}
+	}
+}
+// 成绩
+.cjlist{width: 100%;background: #FFFFFF;border-radius: 14rpx;padding: 24rpx;margin-bottom: 30rpx;
+	.moimg{width: 26rpx;height: 6rpx;flex: 0 0 auto;margin-left: 20rpx;}
+	.cjlook{border-top: 2rpx solid #E5E5E5;margin-top: 20rpx;padding-top: 16rpx;
+		view{width: 33.3%;font-size: 26rpx;font-weight: bold;color: #666666;}
+	}
+}
+// 安全
+.secure{width: 100%;box-sizing: border-box;border-bottom: 2rpx solid #E5E5E5;padding: 24rpx 0 20rpx;display: flex;align-items: stretch;
+	.sec_t{flex: 1;overflow: hidden;display: flex;flex-direction: column;
+		.tit{font-size: 30rpx;font-weight: bold;color: #161616;width: 100%;margin-bottom: 12rpx;}
+		.txt{font-size: 28rpx;color: #161616;width: 100%;margin-bottom: 20rpx;
+		}
+		.sec_x{font-size: 28rpx;color: #161616;
+			.xxicona{width: 28rpx;height: 32rpx;margin-right: 18rpx;}
+			.xxiconb{width: 30rpx;height: 28rpx;margin-right: 18rpx;}
+			.xxiconc{width: 30rpx;height: 30rpx;margin-right: 18rpx;}
+			.xxicond{width: 32rpx;height: 24rpx;margin-right: 18rpx;}
+			.xxicondel{width: 32rpx;height: 33rpx;margin-right: 18rpx;}
+		}
+	}
+	.sec_i{flex: 0 0 auto;margin-left: 28rpx;
+		image{width: 220rpx;height: 160rpx;}
+	}
+}
+//心理
+.mind{
+	padding: 0 24rpx;width: 100%;box-sizing: border-box;background-color: #FFFFFF;border-radius: 14rpx;margin-bottom: 24rpx;
+	.mind_top{border-bottom: 2rpx solid #E5E5E5;min-height: 72rpx;padding:16rpx 0;
+		image{width: 26rpx;height: 6rpx;flex: 0 0 auto;margin-left: 20rpx;}
+	}
+	.mind_c{padding: 20rpx 0;
+		.tit{font-size: 30rpx;color: #AAAAAA;flex: 0 0 auto;}
+		.txt{font-size: 30rpx;color: #161616;}
+	}
+}
+// 时间轴
+.time{
+	.time_t{padding: 24rpx 0;display: flex;align-items: center;
+		view{font-weight: bold;color: #4775EA;font-size: 32rpx;}
+		text{margin-left:12rpx;}
+		.timeup{width: 26rpx;height: 24rpx;margin-left: 30rpx;transition: all 0.3s; }
+		&.act .timeup{transform: rotate(-180deg);}
+	}
+	// .timebox{display: none;}
+	.list{display: flex;align-items: flex-start;padding-left: 10rpx;padding-bottom: 36rpx;position: relative;
+	
+		&::before{width: 2rpx;content: "";position: absolute;top: 44rpx;bottom: 14rpx;left: 26rpx;
+background: #DADADA;}
+		.timel{width: 32rpx;height: 32rpx;margin-right: 20rpx;position: relative;flex: 0 0 auto;}
+		.listr{flex:1;
+			.listrt{line-height: 32rpx;font-size: 30rpx;font-weight: bold;color: #161616;margin-bottom: 16rpx;display: flex;align-items: center;
+				.type{height: 30rpx;border-radius: 10rpx;margin-left: 20rpx;font-size: 24rpx;color: #FFFFFF;padding:2rpx 8rpx;
+					&.bg1{background: #AABCE9;}
+					&.bg2{background: #8CD5B3;}
+				}
+			}
+			.listrx{padding: 6rpx 0;
+				.ltit{flex:0 0 auto;font-size: 30rpx;color: #AAAAAA;}
+				.ltxt{font-weight: 500;color: #161616;flex:1;font-size: 30rpx;}
+			}
+		}
+	}
+	&.act .timebox{display: block;}
+	
+	// &.quse_txt:last-child ul:before{display: none;}
+}
+</style>

+ 370 - 0
mine/components/login/applyparent.vue

@@ -0,0 +1,370 @@
+<template>
+	<view class="regbox flexdc">
+		
+			<block v-if="type=='add'">
+				<uni-forms ref="form" :rules="rulebs" :modelValue="datainfob">
+				<uni-forms-item label="姓名" required name="userName">
+					<uni-easyinput :inputBorder="false" v-model="datainfob.userName" placeholder="请输入您的姓名">
+					</uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+				<uni-forms-item label="联系方式" required name="userPhone">
+					<uni-easyinput :inputBorder="false" v-model="datainfob.userPhone" placeholder="请输入您的联系方式">
+					</uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+
+				<!-- 单选 -->
+				<view v-for="(ite,idx) in classlist" class="pr" :key="idx" @click="getShow(idx)">
+					<view @click="getDel(idx)" class="delbox" v-if="idx!=0">
+						<image :src="tcdel"></image>
+					</view>
+					<uni-forms-item label="学生姓名" required name="studentName">
+						<uni-easyinput :inputBorder="false" v-model="ite.studentName" placeholder="请输入学生姓名">
+						</uni-easyinput>
+						<view class="rimg"></view>
+					</uni-forms-item>
+					<uni-forms-item label="学生身份证号" required name="studentNumber">
+						<uni-easyinput :inputBorder="false" type="number" v-model="ite.studentNumber"
+							placeholder="请输入学生身份证号"></uni-easyinput>
+						<view class="rimg"></view>
+					</uni-forms-item>
+					<picker range-key='dictLabel'  :value="xxindex" :range="schoolval"
+						@change='bindDateChangea'>
+						<uni-forms-item label="学校" required name="schoolName">
+							<view class="f16  flex1 txr" :class="ite.schoolName?'co16':'coa'">
+								{{ite.schoolName||"请选择学校"}}</view>
+							<view class="rimg">
+								<image :src="rimg" class="rimgs"></image>
+							</view>
+						</uni-forms-item>
+					</picker>
+					<picker range-key='dictLabel'  :value="xkindex" :range="classval" @change='bindDateChangeb'>
+						<uni-forms-item label="班级" required name="className">
+							<view class="f16  flex1 txr" :class="ite.className?'co16':'coa'">{{ite.className||"请选择班级"}}
+							</view>
+							<view class="rimg">
+								<image :src="rimg" class="rimgs"></image>
+							</view>
+						</uni-forms-item>
+					</picker>
+					<view class="line"></view>
+				</view>
+				<view class="addbox f17 co47 flexcc mt26" @click="getAddFn">
+					<image :src="addimg"></image>
+					新增学校信息
+				</view>
+				</uni-forms>
+			</block>
+			<!-- 家长的修改 -->
+			<block v-else>
+				<uni-forms ref="form" :rules="rulesup" :modelValue="datainfob">
+				<uni-forms-item label="姓名" required name="parentsName">
+					<uni-easyinput :inputBorder="false" v-model="datainfob.parentsName" placeholder="请输入您的姓名">
+					</uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+				<uni-forms-item label="联系方式" required name="parentsPhone">
+					<uni-easyinput :inputBorder="false" v-model="datainfob.parentsPhone" placeholder="请输入您的联系方式">
+					</uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+
+				<!-- 单选 -->
+				<uni-forms-item label="学生姓名" required name="studentName">
+					<uni-easyinput :inputBorder="false" v-model="datainfob.studentName" placeholder="请输入学生姓名">
+					</uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+				<uni-forms-item label="学生身份证号" required name="studentNumber">
+					<uni-easyinput :inputBorder="false" type="number" v-model="datainfob.studentNumber"
+						placeholder="请输入学生身份证号"></uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+				<picker range-key='dictLabel'  :value="xxindex" :range="schoolval" @change='bindDateChangea'>
+					<uni-forms-item label="学校" required name="schoolName">
+						<view class="f16  flex1 txr" :class="datainfob.schoolName?'co16':'coa'">
+							{{datainfob.schoolName||"请选择学校"}}</view>
+						<view class="rimg">
+							<image :src="rimg" class="rimgs"></image>
+						</view>
+					</uni-forms-item>
+				</picker>
+				<picker range-key='dictLabel'  :value="xkindex" :range="classval" @change='bindDateChangeb'>
+					<uni-forms-item label="班级" required name="className">
+						<view class="f16  flex1 txr" :class="datainfob.className?'co16':'coa'">
+							{{datainfob.className||"请选择班级"}}
+						</view>
+						<view class="rimg">
+							<image :src="rimg" class="rimgs"></image>
+						</view>
+					</uni-forms-item>
+				</picker>
+				<view class="line"></view>
+				</uni-forms>
+			</block>
+		<view class="mt26">
+			<view class="rbtn" @click="getSubmit">保存</view>
+			<view class="apllytxt f15" @click="gethome">稍后完善</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getDeptList,getDeptListminea} from "@/api/mine/mine.js"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	import {getToken} from '@/utils/auth'
+	import {getparentsregFn,getstudentdetFn,getstudentputFn} from "@/api/mine/register.js"
+	export default {
+		props:{
+			schoolval:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			classvals:{
+				type: Array,
+				default () {
+					return []
+				}
+			}
+		},
+		watch:{
+			classvals(val){
+				this.classval=val
+			}
+		},
+		data() {
+			return {
+				rimg: require("@/static/images/rimg.png"),
+				wimg: require('@/static/images/read.png'),
+				delimg: require('@/static/images/del.png'),
+				addimg: require('@/static/images/add.png'),
+				tcdel: require('@/static/images/tcdel.png'),
+				cyvalue: '',
+				xxindex: 0,
+				bjindex: 0,
+				xkindex: 0,
+				rulebs: {
+					userName: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入姓名',
+						}]
+					},
+					userPhone: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入联系方式',
+						},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]
+					},
+					registerParentsStudentList: {
+						rules: [{
+							required: true,
+							errorMessage: '请填写学生信息',
+						}]
+					}
+				},
+				rulesup: {
+					parentsName: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入姓名',
+						}]
+					},
+					parentsPhone: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入联系方式',
+						},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]
+					},
+					studentName: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入学生姓名',
+						}]
+					},
+					schoolName: {
+						rules: [{
+							required: true,
+							errorMessage: '请选择学校',
+						}]
+					},
+					className: {
+						rules: [{
+							required: true,
+							errorMessage: '请选择班级',
+						}]
+					},
+				},
+				datainfob: {
+					"userName": "",
+					"userPhone": "",
+					"registerParentsStudentList": [{
+						"schoolId": "",
+						"schoolName": "",
+						"classId": "",
+						"className": "",
+						"studentName": "",
+						"studentNumber": ""
+					}]
+				},
+				classlist: [{
+					"schoolId": "",
+					"schoolName": "",
+					"classId": "",
+					"className": "",
+					"studentName": "",
+					"studentNumber": ""
+				}],
+				classval: [],
+				checkidx: -1,
+				id: '',
+				type: 'add', //页面类型
+			}
+		},
+		methods: {
+			// 班级
+			
+			getAddFn() {
+				var obj = {
+					"schoolId": "",
+					"schoolName": "",
+					"classId": "",
+					"className": "",
+					"studentName": "",
+					"studentNumber": ""
+				}
+				this.classlist.push(obj);
+			},
+			getDel(idx) {
+				var that = this;
+				uni.showModal({
+					title: '确认删除',
+					content: "是否确认删除",
+					cancelText: '取消删除',
+					confirmText: '确认删除',
+					success: function(res) {
+						if (res.confirm) {
+							that.classlist.splice(idx, 1)
+						} else if (res.cancel) {
+							// console.log('用户点击取消');
+						}
+					}
+				});
+			},
+			getShow(idx) {
+				this.checkidx = idx;
+			},
+			// 选择学校
+			bindDateChangea(e) {
+				var val = e.detail.value;
+				var v = this.schoolval[val];
+				var id = v.dictValue;
+				var idx = this.checkidx;
+				if (this.classlist[idx].schoolId != id) {
+					this.classlist[idx].schoolName = v.dictLabel
+					this.classlist[idx].tenantId = v.tenantId
+					this.classlist[idx].schoolId = id
+					this.classlist[idx].className = '';
+					this.classlist[idx].classId = '';
+					this.$emit('getclassListFn',id)
+				}
+
+			},
+			// 班级
+			bindDateChangeb(e) {
+				var val = e.detail.value;
+				var idx = this.checkidx;
+				this.classlist[idx].className = this.classval[val].dictLabel
+				this.classlist[idx].classId = this.classval[val].dictValue
+
+			},
+			getSubmit() {
+				var that = this;
+				this.$refs.form.validate().then(res => {
+					var params = JSON.parse(JSON.stringify(this.datainfob))
+					var list=this.classlist;
+					var newArr = []
+					var a=0;
+					Object.keys(list).some((key) => {
+						if(!list[key].studentName){
+							a=1;
+							this.$toast("请输入学生姓名" )
+							return
+						}else if(!list[key].studentNumber){
+							a=1;
+							this.$toast("请输入学生身份证号" )
+							return	
+						}else if (list[key].schoolName && list[key].className) {
+							let _IDRe18 =
+								/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+							let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+							// 校验身份证:
+							if (_IDRe18.test(list[key].studentNumber) || _IDre15.test(list[key].studentNumber)) {
+								newArr.push(list[key])
+							}else{
+								a=1;
+								this.$toast('请输入学生'+ list[key].studentName + "正确身份证号")
+								return
+							}
+						} else if (list[key].schoolName && !list[key].className) {
+							a=1;
+							this.$toast("请选择" + list[key].schoolName + "的班级")
+							return
+						} else if(!list[key].schoolName){
+							a=1;
+							this.$toast("请选择学校")
+							return
+						}
+					})
+					if(a==1){
+						return
+					}
+					params.registerParentsStudentList = JSON.parse(JSON.stringify(newArr))
+					this.$emit('getparentsregFn',params)
+					
+
+
+					// this.$tab.navigateTo(`/mine/pages/mine/success`)
+				})
+
+			},
+			gethome() {
+				this.$tab.reLaunch(`/pages/index/index`)
+			},
+		},
+
+	}
+</script>
+
+<style lang="scss" scoped>
+.regbox{padding: 20rpx 36rpx 80rpx;box-sizing: border-box;min-height: auto;overflow: auto;
+	.apllytxt{font-size:30rpx ;}
+	.line{width: 40rpx;height: 6rpx;background: #FFB132;margin: 60rpx auto 0;}
+	
+	.addbox{font-weight: 500;
+		image{width: 44rpx;height: 44rpx;margin-right: 24rpx;flex: 0 0 auto;}
+	}
+	
+	.delbox{width: 40rpx;height: 40rpx;position: absolute;right: 0;top: -40rpx;
+		image{
+			width: 36rpx;height: 36rpx;
+		}
+	}
+}
+.regbox /deep/ .uni-forms{flex: 1;}
+.regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.regbox /deep/ .uni-forms .uni-forms-item{padding: 28rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+}
+.regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+
+</style>

+ 262 - 0
mine/components/login/applyregister.vue

@@ -0,0 +1,262 @@
+<template>
+  <view class="regbox flexdc">
+	  <uni-forms  ref="form" :rules="rules" :modelValue="variables">
+	  	<!-- <uni-forms-item label="学校" required name="schoolName">
+	  		<uni-easyinput :inputBorder="false" v-model="variables.schoolName" placeholder="请输入学校名称"></uni-easyinput>
+			<view class="rimg">	</view>
+	  	</uni-forms-item> -->
+		<view @click="getSchoolFn">
+			<uni-forms-item label="学校" name="schoolName">
+				<view  class="f16  flex1 txr" :class="variables.schoolName?'co16':'coa'">{{variables.schoolName||'请选择学校'}}</view>
+				<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			</uni-forms-item>
+		</view>
+		<!-- <picker  range-key='dictLabel' :value="xxindex" :range="schoolval" @change='bindDateChangea'>
+			<uni-forms-item label="学校" name="schoolName">
+					<view  class="f16  flex1 txr" :class="variables.schoolName?'co16':'coa'">{{variables.schoolName||'请选择学校'}}</view>
+			<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			</uni-forms-item>
+		</picker> -->
+		<uni-forms-item name="userName" required label="负责人姓名">
+			<uni-easyinput :inputBorder="false" v-model="variables.userName" placeholder="请输入负责人姓名"></uni-easyinput>
+			<view class="rimg">	</view>
+		</uni-forms-item>
+	  	<uni-forms-item name="userPhone" required label="联系方式">
+	  		<uni-easyinput :inputBorder="false" type="number" v-model="variables.userPhone" placeholder="请输入您的联系方式"></uni-easyinput>
+			<view class="rimg">	</view>
+	  	</uni-forms-item>
+		<view class="noborder">
+			<uni-forms-item name="registerSchoolFileList"  style='margin-bottom: 0;'>
+				<view class="flexc" style="width: 100%;">
+					<view class="f16 fw co16 flex0 ">上传资质</view>
+					<view class="infolist_a co47" ><lsj-upload
+						    ref="lsjUpload"
+						    childId="upload1"
+						    :width="width"
+						    :height="height"
+						    :option="option"
+						    :size="size"
+							:count="count"
+						    :formats="formats"
+						    :debug="debug"
+						    :instantly="instantly"
+						    @progress=""
+							@uploadEnd="onuploadEnd" >
+						        <view class="btn" :style="{width: width,height: height}">去上传</view>
+						</lsj-upload></view>
+					</view>
+			</uni-forms-item>
+			
+		</view>
+		
+		<view>
+			<view class="cldelistbf flexc"  v-for="(ite,idx) in filelist" :key='idx'>
+				<view class="flext f15 co16 flex1" @click="getDown(ite.url)">
+					<view class="imgl"><image :src="wimg" ></image></view>
+					<view class="tit">{{ite.name}}</view>
+				</view>
+				<!-- 删除 -->
+				<view class="delimg flex0" @click.stop="getDelFj(idx)">
+					<image :src="delimg" class="imgr"></image>
+				</view>
+			</view>
+		</view>
+		<view class="infolist_tit">注:须上传学校法人营业执照,或后期补传</view>
+		<view class="infolist_b"><text>*</text>请上传大小不超过<text>100MB</text>格式为<text>pdf</text>的文件</view>
+	  </uni-forms>
+	  <view class="mt26">
+	  	<view class="rbtn" @click="getSubmit">提交</view>
+	  	 <view class="apllytxt"><text>*</text>请确认您提交的信息真实有效</view>
+	  </view>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import config from '@/config'
+	 const baseUrl = config.baseUrl
+	 const Clientid = config.Clientid
+	 import { getToken } from '@/utils/auth'
+	 import {getschoolregFn,getschoolDetFn,getschoolPutFn} from "@/api/mine/register.js"
+	 import {getDeptList} from "@/api/mine/mine.js"
+  export default {
+	  props:{
+	  	schoolval:{
+	  		type: Array,
+	  		default () {
+	  			return []
+	  		}
+	  	},
+		schoolobj:{
+			type: Object,
+			default () {
+				return {}
+			}
+		}
+	  },
+	watch:{
+		schoolobj(val){
+			this.schooltit=val
+			this.variables.schoolName=val.schoolName
+		}
+	},
+	mounted() {
+		
+	},
+	data(){
+		return{
+			//附件
+			  option: {
+			        // 上传服务器地址,需要替换为你的接口地址
+			        // url: baseUrl+'/common/upload', // 该地址非真实路径,需替换为你项目自己的接口地址
+			        url: baseUrl+'/common/upload', // 该地址非真实路径,需替换为你项目自己的接口地址
+			        // 上传附件的key
+			        name: 'file',
+			        // 根据你接口需求自定义请求头,默认不要写content-type,让浏览器自适配
+			        header: {
+			            // 示例参数可删除
+			            'Authorization':  'Bearer ' + getToken(),
+			            'Clientid':  Clientid,
+			        },
+			        // 根据你接口需求自定义body参数
+			        formData: {
+						
+			        }
+			    },
+			// 选择文件后是否立即自动上传,true=选择后立即上传
+			instantly: true,
+			// 必传宽高且宽高应与slot宽高保持一致
+			width: '',
+			height: '44rpx',
+			// 限制允许上传的格式,空串=不限制,默认为空
+			formats: 'pdf',
+			// 文件上传大小限制
+			size: 100,
+			// 文件数量限制 默认10
+			count: 5,
+			// 文件回显列表
+			files: new Map(),
+			// 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道
+			wxFiles: [],
+			// 是否打印日志
+			debug: false,
+			filelist:[], 
+			rimg:require("@/static/images/rimg.png"),
+			wimg:require('@/static/images/read.png'),
+			delimg:require('@/static/images/del.png'),
+			cyvalue:'',
+			cyindex:0,
+			cylist:[{label:'是',id:'Y'},{label:'否',id:'N'}],
+			variables:{
+				"schoolName": "",
+				"userName": "",
+				"userPhone": "",
+				"registerSchoolFileList": [],
+			},
+			rules: {
+			  schoolName: {rules: [{required: true,errorMessage: '请输入学校名称'}]},
+			  userName: {rules: [{required: true,errorMessage: '请输入负责人姓名'}]},
+			  userPhone: {rules: [{required: true,errorMessage: '请输入联系方式'},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]},
+			  // registerSchoolFileList: {rules: [{required: true,errorMessage: '请上传附件' } ]},
+			},
+			wxInfo:{},
+			xxindex:[],
+			id:'',
+			type:'add',//页面类型
+			schooltit:{},
+			// procDefId:'flow_1se5q74i:17:32545',//流程定义id
+			// deploymentId:'32542',
+			// type:'',//0学校注册 1 家长  2 老师
+		}
+	},
+	methods:{
+		getSchoolFn(){
+			console.log(this.schooltit)
+			this.$tab.navigateTo(`/mine/pages/mine/school?id=`+this.schooltit.schoolNameId+'&name='+this.schooltit.schoolName)
+		},
+		// 选择学校
+		bindDateChangea(e) {
+			var val = e.detail.value;
+			var v = this.schoolval[val];
+			this.variables.schoolName=v.dictLabel
+			this.variables.schoolId=v.dictValue
+		},
+		getSubmit(){
+			var that=this;
+			this.$refs.form.validate().then(res => {
+				var params=JSON.parse(JSON.stringify(that.variables));
+				// params.openId=that.wxInfo.openId;
+				this.$emit('getschoolregFn',params)
+					
+			})
+			
+			
+		},
+		 onuploadEnd(item) {
+		 	var newobj={}
+		 	var responseText=JSON.parse(item.responseText)
+		 	// newobj.name=item.name;
+		 	newobj.name=responseText.originalFilename;
+		 	newobj.url=responseText.fileName;
+		 	this.filelist.push(newobj)
+		 		this.variables.registerSchoolFileList=JSON.parse(JSON.stringify(this.filelist))
+		 },
+		 getDelFj(idx){
+		 	this.filelist.splice(idx,1)
+		 		this.variables.registerSchoolFileList=JSON.parse(JSON.stringify(this.filelist))
+		 },
+		 getDown(e){
+		 	uni.showLoading({
+		 		title: '加载中'
+		 	});
+		 	var url=baseUrl+e;
+		 	uni.downloadFile({
+		 		url: url,//文件的下载路径
+		 		success(result) {
+		 				uni.hideLoading()
+		 			var filePath = result.tempFilePath;
+		 			   uni.openDocument({
+		 			     filePath: filePath,
+		 			     showMenu: true,
+		 			     success: function (res) {
+		 			     }
+		 			   });
+		 		},
+		 		fail(res) {uni.hideLoading()}
+		 	})
+		 },
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.infolist_a{height: 44rpx;flex: 1;text-align: right;font-size: 32rpx;}
+
+
+.cldelistbf {
+	padding: 20rpx 24rpx;
+		image{flex: 0 0 auto;}
+		.imgl{width: 40rpx;height: 40rpx;display: flex;align-items: center;justify-content: center;margin-right: 24rpx;
+			image{width: 40rpx;height: 34rpx;}
+		}
+		.imgr{width: 30rpx;height: 30rpx;margin-left: 24rpx;}
+		.tit{line-height: 40rpx;font-size: 32rpx;color: #161616;flex: 1;word-break: break-all;}
+	}
+.infolist_b{color: #aaaaaa;font-size: 26rpx;padding:0 24rpx;margin-top:10rpx;
+	text{word-break: break-all;margin: 0 4rpx;color: #ff0000;}
+}
+.infolist_tit{font-size: 26rpx;padding:0 24rpx;color: #ff0000;margin-top: 36rpx;}
+.regbox{padding: 20rpx 36rpx 80rpx;box-sizing: border-box;min-height: auto;overflow: auto;}
+.regbox /deep/ .uni-forms{flex: 1;}
+.regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.regbox /deep/ .uni-forms .uni-forms-item{padding: 36rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+}
+.regbox /deep/ .uni-forms .noborder  .uni-forms-item{margin-bottom: 0;border-bottom: 0;}
+.regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+</style>

+ 263 - 0
mine/components/login/applyteacher.vue

@@ -0,0 +1,263 @@
+<template>
+  <view class="regbox flexdc">
+	  <uni-forms ref="form" :rules="ruleas" :modelValue="datainfo">
+		 
+		 <picker  range-key='dictLabel' :value="xxindex" :range="schoolval" @change='bindDateChangea'>
+		 	<uni-forms-item label="学校" required name="schoolName">
+			<view  class="f16  flex1 txr" :class="datainfo.schoolName?'co16':'coa'">{{datainfo.schoolName||"请选择学校"}}
+			</view>
+		 	<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+		 	</uni-forms-item>
+		 </picker>
+		 <uni-forms-item label="姓名" required name="userName">
+		 	<uni-easyinput :inputBorder="false" v-model="datainfo.userName" placeholder="请输入您的姓名"></uni-easyinput>
+		 	<view class="rimg"></view>
+		 </uni-forms-item>
+		 <uni-forms-item label="联系方式" required name="userPhone">
+		 	<uni-easyinput :inputBorder="false" v-model="datainfo.userPhone" placeholder="请输入您的联系方式"></uni-easyinput>
+		 	<view class="rimg"></view>
+		 </uni-forms-item>
+		 <!-- 单选 -->
+		 <view v-for="(ite,idx) in classlist" class="pr" :key="idx" @click="getShow(idx)">
+			 <view @click="getDel(idx)" class="delbox" v-if="idx!=0">
+				 <image :src="tcdel"></image>
+			 </view>
+			 <picker  range-key='dictLabel' :value="bjindex" :range="classval" @change='bindDateChangeb'>
+			 	<uni-forms-item label="班级" required name="className" @click="getClass">
+			 		<view  class="f16  flex1 txr" :class="ite.className?'co16':'coa'">{{ite.className||"请选择班级"}}
+			 		</view>
+			 		<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			 	</uni-forms-item>
+			 </picker>
+			 <picker  range-key='dictLabel' :value="xkindex" :range="subject" @change='bindDateChangec'>
+			 	<uni-forms-item label="学科" required name="discipline" >
+			 		<view  class="f16  flex1 txr" :class="ite.discipline?'co16':'coa'">{{ite.discipline||"请选择学科"}}
+			 		</view>
+			 		<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			 	</uni-forms-item>
+			 </picker>
+			 <view class="line"></view>
+		 </view>
+		 
+		 <view class="addbox f17 co47 flexcc mt26" @click="getAddFn">
+		 	<image :src="addimg"></image>
+		 	新增班级信息
+		 </view>
+		 
+	  </uni-forms>
+	 
+	  <view class="mt26">
+	  	<view class="rbtn" @click="getSubmit">保存</view>
+	  	 <view class="apllytxt f15" @click="gethome">稍后完善</view>
+	  </view>
+  </view>
+</template>
+
+<script>
+	import {getDeptList,getDeptListminea} from "@/api/mine/mine.js"
+	import config from '@/config'
+	 const baseUrl = config.baseUrl
+	 import { getToken } from '@/utils/auth'
+	 import {getDictionaryFn,getteacherregFn,getteacherputFn,getteacherdetFn} from "@/api/mine/register.js"
+  export default {
+	  props:{
+	  	schoolval:{
+	  		type: Array,
+	  		default () {
+	  			return []
+	  		}
+	  	},
+		subject:{
+			type: Array,
+			default () {
+				return []
+			}
+		},
+		classvals:{
+			type: Array,
+			default () {
+				return []
+			}
+		}
+	  },
+	  watch:{
+		classvals(val){
+			this.classval=val
+		}
+	  },
+	data(){
+		return{
+			rimg:require("@/static/images/rimg.png"),
+			wimg:require('@/static/images/read.png'),
+			delimg:require('@/static/images/del.png'),
+			addimg:require('@/static/images/add.png'),
+			tcdel:require('@/static/images/tcdel.png'),
+			cyvalue:'',
+			xxindex:0,
+			bjindex:0,
+			xkindex:0,
+			ruleas: {
+			  schoolName: {rules: [{required: true,errorMessage: '请输入学校名称'}]},
+			  userName: {rules: [{required: true,errorMessage: '请输入姓名',}]},
+			  userPhone: {rules: [{required: true,errorMessage: '请输入联系方式'},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]},
+			},
+			datainfo:{
+				  "schoolId": "",
+				  "schoolName":"",
+				  "userName":"",
+				  "userPhone":"",
+				  "registerTeacherClassList":[{
+				      "classId":"",
+				      "className":"",
+				      "discipline":""
+				}]
+			},
+			classlist:[{
+				      "classId":"",
+				      "className":"",
+				      "discipline":""
+				  }],
+			classval:[],
+			checkidx:-1,
+			id:'',
+			type:'add',//页面类型
+		}
+	},
+	mounted: function(e) {
+	},
+	methods:{
+		
+		getAddFn(){
+			var obj={
+				    "classId":"",
+				    "className":"",
+				    "discipline":""
+				}
+			this.classlist.push(obj);
+		},
+		getDel(idx){
+			var that=this;
+			uni.showModal({
+				title: '确认删除',
+				content: "是否确认删除",
+				cancelText: '取消删除',
+				confirmText: '确认删除',
+				success: function(res) {
+					if (res.confirm) {
+						that.classlist.splice(idx,1)
+					} else if (res.cancel) {
+						// console.log('用户点击取消');
+					}
+				}
+			});
+		},
+		getShow(idx){
+			this.checkidx=idx;
+		},
+		// 选择学校
+		bindDateChangea(e){
+			var val=e.detail.value;
+			var v=this.schoolval[val];
+			var id=v.dictValue;
+			if(this.datainfo.schoolId!=id){
+				this.datainfo.schoolName=v.dictLabel;
+				this.datainfo.tenantId=v.tenantId;
+				this.datainfo.schoolId=id;
+				this.$emit("getclassListFn",id)
+				this.$emit("getinit",v.tenantId)
+				var obj={"classId":"","className":"","discipline":""};
+				var newarr=[];
+				newarr.push(obj)
+				this.classlist=JSON.parse(JSON.stringify(newarr))
+			}
+			
+		},
+		// 班级
+		bindDateChangeb(e) {
+			var val=e.detail.value;
+			var idx=this.checkidx;
+			this.classlist[idx].className=this.classval[val].dictLabel
+			this.classlist[idx].classId=this.classval[val].dictValue
+		},
+		// 学科
+		bindDateChangec(e){
+			var val=e.detail.value;
+			var idx=this.checkidx;
+			this.classlist[idx].discipline=this.subject[val].dictLabel
+		},
+		getSubmit(){
+			var that=this;
+			this.$refs.form.validate().then(res => {
+				var list=this.classlist;
+				var newArr = [];
+				var a=0;
+				Object.keys(list).some((key) => {
+					// 去重
+					if (list[key].className && list[key].discipline) {
+						newArr.push(list[key])
+					} else if (list[key].className && !list[key].discipline) {
+						a=1;
+						this.$toast("请选择"+list[key].className+"的学科")
+						return
+					} else {
+						a=1;
+						this.$toast("请选择班级")
+						return
+					}
+				})
+				// 相同班级去重
+				var newArrs = [];
+				const map = new Map();
+				 newArrs = list.filter(v => !map.has(v.classId) && map.set(v.classId, 1));
+				if(newArrs.length<newArr.length){
+					this.$toast("请勿添加同一年级")
+					return
+				}
+				
+				if(a==1){
+					return
+				}
+				var params=JSON.parse(JSON.stringify(this.datainfo))
+				params.registerTeacherClassList=JSON.parse(JSON.stringify(newArr))
+				this.$emit('getteacherregFn',params)
+				
+				// this.$tab.navigateTo(`/mine/pages/mine/success`)
+			})
+			
+		},
+		gethome(){
+			this.$tab.reLaunch(`/pages/index/index`)
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+
+.regbox{padding: 20rpx 36rpx 80rpx;box-sizing: border-box;min-height: auto;overflow: auto;
+	.apllytxt{font-size:30rpx ;}
+	.line{width: 40rpx;height: 6rpx;background: #FFB132;margin: 60rpx auto 0;}
+	
+	.addbox{font-weight: 500;
+		image{width: 44rpx;height: 44rpx;margin-right: 24rpx;flex: 0 0 auto;}
+	}
+	
+	.delbox{width: 40rpx;height: 40rpx;position: absolute;right: 0;top: -40rpx;padding: 0;display: flex;align-items: center;justify-content: center;
+		image{
+			width: 36rpx;height: 36rpx;
+		}
+	}
+}
+.regbox /deep/ .uni-forms{flex: 1;}
+.regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.regbox /deep/ .uni-forms .uni-forms-item{padding: 28rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+}
+.regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+</style>

+ 570 - 0
mine/components/popup/popup.vue

@@ -0,0 +1,570 @@
+<template>
+	<view>
+		<!-- 弹窗 -->
+		<view class="bgbox" @click="getClose" v-if="type&&type!=2"></view>
+		<view class="bgbox"  v-if="type&&type==2"></view>
+		<!-- 录入 -->
+		<block v-if="type==1">
+			<view class="importbox  sfixed" :class="type==1?'imp_bot':''">
+				<view class="list flexc btn1" @click="getEnter(1)">
+					<image :src="importimg" class="imgl"></image>
+					<view class="flex1">
+						<view class="f16 fw5 c16 mb4">导入{{titsta}}</view>
+						<view class="f14 coa">已有{{titsta}}单表格,一键导入</view>
+					</view>
+					<image :src="rimg" class="imgr"></image>
+				</view>
+				<view class="list flexc btn2" @click="getEnter(2)">
+					<image :src="enterimg" class="imgl"></image>
+					<view class="flex1">
+						<view class="f16 fw5 c16 mb4">录入{{titsta}}</view>
+						<view class="f14 coa">在线录入{{titsta}}</view>
+					</view>
+					<image :src="rimg" class="imgr"></image>
+				</view>
+			</view>
+		</block>
+		
+		<!-- 科目选择 -->
+		<view class="subject sfixed" v-if="type==2">
+			<view class="chose_top flexc">
+				<!-- <view class="topbtn topl" @click="getClose">取消</view> -->
+				<view class="topc">选择科目(可多选)</view>
+				<view class="topbtn topr" @click="getsubConfirm">确定</view>
+			</view>
+			<!-- <view class="chose_box">
+				<view class="pr list" v-for="(ite,idx) in subjectlist" :key="idx">
+					<view class="lista flexcc" :class="ite.check ?'act':''"  @click="getCheck(idx)" >{{ite.tit}}	</view>
+					<view class="listp" @click.stop="btns" v-if="ite.check">
+						<input placeholder="总分"  maxlength="6" v-model="ite.manfen" type="digit"/>
+					</view>
+				</view>
+			</view> -->
+			<!-- 新样式 -->
+			<view class="chose_nbox">
+				<view class="list" v-for="(ite,idx) in subjectlist" :key="idx">
+					<view class="listl over" :class="ite.check ?'act':''"  @click="getCheck(idx)">{{ite.tit}}</view>
+					<view class="listr flexc">
+						<view class="ltrtit">总分</view>
+						<input  placeholder="请输入总分" :disabled="!ite.check" maxlength="6" v-model="ite.manfen" type="digit" />
+					</view>
+				</view>
+				<view class="txt"><text>*</text>请先选择科目,再输入总分</view>
+			</view>
+		</view>
+		<!-- 录入成绩 -->
+		<view class="subject sfixed" v-if="type==3">
+			<view class="chose_top flexc">
+				<view class="topbtn topl" @click="getClose">取消</view>
+				<view class="topc">添加学生成绩</view>
+				<view class="topbtn topr" @click="getScore">完成</view>
+			</view>
+			<view class="chose_box">
+				<!-- <view class="lrlist">
+					<view class="label">学生姓名</view>
+					<input  placeholder="请输入学生姓名" v-model='studentinfo.scoreDataName'/>
+				</view> -->
+				<view style="width: 100%;">
+					<picker range-key="dictLabel" :range="studenlist"  :value="stuidx"  @change="bindDateChange">
+						<view class="lrlist">
+							<view class="label">学生姓名</view>
+							<view class="flex1 f15" :class="studentinfo.scoreDataName?'co16':'coa'">{{studentinfo.scoreDataName||'请选择学生姓名'}}</view>
+							<!-- <input  placeholder="请输入学生姓名" v-model='studentinfo.scoreDataName'/> -->
+							<image :src="rimg" class="ilrmgr"></image>
+						</view>
+					</picker>
+				</view>
+				
+				<view class="lrlist"  v-for="(ite,idx) in subList" :key="idx">
+					<view class="label">{{ite.xueke}}成绩</view>
+					<!-- 选择各个科目成绩 -->
+					<block><input type="digit"  maxlength="6"  placeholder="请输入分数" v-model="ite.score"/></block>
+					<!-- <block><input  placeholder="请输入分数" v-model="studentinfo[ite.val]"/></block> -->
+				</view>
+				<!-- params['params[role]'] -->
+				<!-- <view class="lrlist">
+					<view class="label">成绩总分</view>
+					<input  placeholder="请输入分数" v-model="studentinfo.zongfen"/>
+					<textarea auto-height="true" v-module='studentinfo.zongfen' placeholder="请输入点评成绩(选填)" class="input"></textarea>
+				</view> -->
+			</view>
+		</view>
+		<!-- 删除 -->
+		<view class="delbox" v-if="type==4">
+			<view class="tit">修改信息</view>
+			<view class="tit">删除学生</view>
+			<view class="zhan"></view>
+			<view class="tit close"  @click="getClose">取消</view>
+		</view>
+		<!-- 有成绩之后 -->
+		<view class="delbox" v-if="type==6">
+			<view class="tit" @click="getLook">查看{{titsta}}</view>
+			<view class="tit" @click="getDel">删除{{titsta}}</view>
+			<view class="zhan"></view>
+			<view class="tit close"  @click="getClose">取消</view>
+		</view>
+		<!-- 档案 -->
+		<!-- 隐私提示 -->
+		<view class="confirmbox flexdc" v-if="type==5">
+			<view class="tit flex0">隐私提示</view>
+			<view class="txt">根据学生一对一隐私协议,只能查看自己的成绩</view>
+			<view class="cfbtn flex ">
+				<view class="cbtn btn2" @click="getClose">我知道了</view>
+				<!-- <view class="cbtn btn2" @click="getConfirm">{{confdat.suretxt}}</view> -->
+			</view>
+		</view>
+		<!-- 孩子 -->
+		<view class="delbox" v-if="type==7">
+			<view class="tit" @click="getChose(ite)" v-for="(ite,idx) in childrens" :key="idx">{{ite.schoolName}}/{{ite.className}}/{{ite.studentName}}</view>
+			<view class="zhan"></view>
+			<view class="tit close"  @click="getClose">取消</view>
+		</view>
+		<!-- 防溺水计划 -->
+		<view class="fnsbox" v-if="type==8">
+			<view class="fns_top">
+				<image :src="fziconc" @click="getClose"></image>
+				<view>加入防溺水计划</view>
+			</view>
+			<view class="fns_ma">
+				<picker range-key="className" :range="classlist"  :value="classidx"  @change="bindDateChangea">
+					<view class="flexc mibox mb16">
+						<view class="tit" style="margin-bottom: 0;">选择班级</view>
+						<view class="f15 flex1 txr co16" v-if="classname" >{{classname}}</view>
+						<view class="f15 flex1 txr coa" v-else>请选择班级</view>
+						 <image :src="rimg" class="rimg"></image>
+					</view>
+				</picker>
+				<view class="fns_mab">
+					<image :src="fzicond"></image>
+					<view class="tip">提示:本防溺水计划仅作为辅助提示作用,我们 将做到尽力推送,请确保学生照片信息清晰准确 无误!确认提交前,请先阅读完安全协议信息!</view>
+				</view>
+				<view class="rebtn mb16" style="height: 80rpx;" @click="getJoin">确认</view>
+				<view class="lread" @click="checkflag=!checkflag">
+					<view class="lreadl">
+						<image :src="checkimg" v-if="checkflag"></image>
+						<image :src="ncheckimg" v-else></image>
+					</view>
+					<view class="tit">我已阅读并知晓<text @click.stop="handlePrivacy">安全协议</text>信息,选择即为自愿同意</view>
+				</view>
+			</view>
+		</view>
+		<!-- 老师新增班级 -->
+		<view class="subject sfixed" v-if="type==9">
+			<view class="chose_top flexc">
+				<view class="topbtn topl" @click="getClose">取消</view>
+				<view class="topc">添加班级</view>
+				<view class="topbtn topr" @click="getClassSure">完成</view>
+			</view>
+			<view class="chose_box">
+				<view style="width: 100%;">
+					<picker range-key="className" :range="classlist"  :value="classvalidx"  @change="bindDateChangeb">
+						<view class="lrlist">
+							<view class="label">班级</view>
+							<view class="flex1 f15" :class="classinfo.className?'co16':'coa'">{{classinfo.className||'请选择班级'}}</view>
+							<image :src="rimg" class="ilrmgr"></image>
+						</view>
+					</picker>
+				</view>
+				<view style="width: 100%;">
+					<picker range-key="dictLabel" :range="subjects"  :value="cstuidx"  @change="bindDateChangec">
+						<view class="lrlist">
+							<view class="label">学科</view>
+							<view class="flex1 f15" :class="classinfo.discipline?'co16':'coa'">{{classinfo.discipline||'请选择学科'}}</view>
+							<image :src="rimg" class="ilrmgr"></image>
+						</view>
+					</picker>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	//subLists 选择的科目
+	//subjectlist 字典值 成绩表科目
+	//nostudenlist  学生信息表
+	export default{
+		props:{
+			type: {
+				type: Number,
+				default () {
+					return 0
+				}
+			},
+			studentinfos:{
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			subLists:{},
+			subjectlists:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			titsta:{
+				type: String,
+				default () {
+					return '成绩'
+				}
+			},
+			nostudenlist:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			childrens:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			classlist:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			subjects:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			classinfos:{
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		watch:{
+			subLists(val){
+				if(val&&val.length>0){
+					this.subList=val
+				}
+			},
+			nostudenlist(val){
+				this.studenlist=val
+			},
+			subjectlists(val){
+				this.subjectlist=val
+			},
+			studentinfos(val){
+				this.studentinfo=JSON.parse(JSON.stringify(val))
+			},
+			classinfos(val){
+				this.classinfo=JSON.parse(JSON.stringify(val))
+			},
+			type(val){
+				if(val==0){
+					var newobj={
+						scoreDataName:'',//姓名
+						scoreDataNameId:'',//姓名id
+						studentNumber:''
+					}
+					this.studentinfo=JSON.parse(JSON.stringify(newobj))
+					var classinfo={className:'',classId:'',discipline:''};
+					this.classinfo=JSON.parse(JSON.stringify(classinfo))
+					this.subList=[]
+				}else{
+					if(this.studentinfos){
+						this.studentinfo=JSON.parse(JSON.stringify(this.studentinfos))
+					}
+					if(this.subLists){
+						this.subList=JSON.parse(JSON.stringify(this.subLists))
+					}
+					
+				}
+			}
+		},
+		data(){
+			return{
+				importimg:require("@/mine/static/score/import.png"),
+				enterimg:require("@/mine/static/score/enter.png"),
+				rimg:require("@/mine/static/score/rimg.png"),
+				fziconc:require("@/mine/static/score/fziconc.png"),
+				fzicond:require("@/mine/static/score/fzicond.png"),
+				checkimg:require('@/mine/static/score/check.png'),
+				ncheckimg:require('@/mine/static/score/ncheck.png'),
+				checkval:[],
+				subList:[],//选中的课表
+				stuidx:0,
+				classidx:0,
+				checkflag:false,
+				classname:'',
+				classId:'',
+				stuname:'',
+				studenlist:[],
+				scoreDataName:'',
+				subjectlist:[],
+				studentinfo:{},
+				classinfo:{
+					className:'',
+					classId:'',
+					discipline:'',
+				},
+				classvalidx:0,
+				cstuidx:0,
+			}
+		},
+		mounted() {
+			this.subjectlist=this.subjectlists
+		},
+		methods:{
+			inputChange(e){
+				var that = this
+				e.target.value = (e.target.value.match(/^\d*(\.?\d{0,2})/g)[0]) || null
+				this.$nextTick(() => {
+					that.rechargeMoney= e.target.value
+				})
+			},
+			btns(){
+				
+			},
+			getClose(){
+				this.$emit("getClose")
+			},
+			getEnter(e){
+				this.$emit("getEnter",e)
+			},
+			getConfirm(){
+				this.$emit("getConfirm")
+			},
+			getLook(){
+				this.$emit("getLook")
+			},
+			getDel(){
+				this.$emit("getDel")
+			},
+			getChose(e){
+				this.$emit("getChose",e)
+			},
+			getJoin(){
+				this.$emit("getJoin")
+			},
+			getClassSure(){
+				this.$emit("getClassSure",this.classinfo)
+			},
+			bindDateChange(e){
+				var idx=e.detail.value;
+				// this.scoreDataName=this.studenlist[idx].dictLabel
+				this.studentinfo.scoreDataName=this.studenlist[idx].dictLabel
+				this.studentinfo.scoreDataNameId=this.studenlist[idx].dictValue
+				this.studentinfo.studentNumber=this.studenlist[idx].studentNumber
+			},
+			bindDateChangea(e){
+				var idx=e.detail.value;
+				this.classname=this.classlist[idx].className
+				this.classId=this.classlist[idx].classId
+			},
+			bindDateChangeb(e){
+				var idx=e.detail.value;
+				this.classinfo.className=this.classlist[idx].className
+				this.classinfo.classId=this.classlist[idx].classId
+			},
+			bindDateChangec(e){
+				var idx=e.detail.value;
+				this.classinfo.discipline=this.subjects[idx].dictLabel
+			},
+			getScore(){
+				var info=JSON.parse(JSON.stringify(this.subList));
+				var a=0
+				Object.keys(info).some((key) => {
+					info[key].score=Number(info[key].score).toFixed(2)
+					if (info[key].score.trim()== '') {
+						a=1;
+						this.$toast("请输入"+info[key].xueke+"成绩")
+						return
+					}
+				})
+				// console.log(params)
+				if(a==1){
+					return
+				}
+				this.studentinfo.scoreDataDetailBoList=info;
+				this.$emit('getScore',this.studentinfo)
+			},
+			getCheck(idx){
+				var newArr=this.subjectlist;
+				newArr[idx].check=!newArr[idx].check;
+				this.subjectlist=JSON.parse(JSON.stringify(newArr))
+			},
+			getsubConfirm(){
+				var newArr=this.subjectlist;
+				var narr=[];
+				var mfboList=[];
+				var column1=[{ type:'index', fixed:true,width:80,align:'center', },{ name: 'scoreDataName', label: '姓名',fixed:true,width:140,emptyString:'--',align:'center' },];
+				var s={ name: 'operation', type:'operation',label: '操作',
+				renders:[
+					{name:'编辑',func:'edit'}, // func 代表子元素点击的事件 父元素接收的事件 父元素 @edit
+					{name:'删除',type:'warn',func:"dele"},
+				]}
+				var num=0
+				Object.keys(newArr).some((key) => {
+					if (newArr[key].check) {
+						if(newArr[key].manfen){
+							var obj={};
+							// obj.name=newArr[key].val;
+							obj.name=newArr[key].tit;
+							obj.label=newArr[key].tit;
+							obj.manfen=Number(newArr[key].manfen).toFixed(2);
+							obj.sorter=true
+							obj.align='center'
+							obj.width=190
+							column1.push(obj)
+							
+							var xobj={};
+							xobj.xueke=newArr[key].tit;
+							xobj.score='';
+							narr.push(xobj)
+							
+							var nobj={}
+							nobj.xueke=newArr[key].tit;
+							nobj.manfen=Number(newArr[key].manfen).toFixed(2);
+							mfboList.push(nobj)
+							return ;
+						}else{
+							num=1
+							var str='请填写'+newArr[key].tit+'总分'
+							this.$toast(str)
+							return true;
+						}
+						
+					}
+				})
+				// 判断是否填写总分
+				if(num==1){
+					return
+				}
+				if(narr.length<1){
+					this.$toast("请至少选中一门科目")
+					return
+				}
+				column1.push(s)
+				this.subList=JSON.parse(JSON.stringify(narr))
+				var newobj={
+					narr:narr,
+					column1:column1,
+					mfboList:mfboList
+				}
+				this.$emit('getsubConfirm',newobj)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+//录入
+.sfixed{position: fixed;bottom: 0;left: 0;right: 0;background: #fff;z-index: 5;}
+.importbox{transition: all linear 0.3s;transform: translateY(100%);padding:32rpx 32rpx 20rpx;box-sizing: border-box;
+	&.imp_bot{transform: translateY(0);}
+	.list{width: 100%;border-radius: 22rpx;padding: 24rpx 48rpx;margin-bottom: 24rpx;position: relative;
+		&.btn1{background: #EFF4FF;}
+		&.btn2{background: #E7FFF4;}
+		.imgl{width: 74rpx;height: 74rpx;flex: 0 0 auto;margin-right: 24rpx;}
+		.imgr{width: 18rpx;height: 32rpx;flex: 0 0 auto;margin-left: 24rpx;}
+	}	
+}
+
+.lrlist{width: 100%;min-height: 100rpx;background: #F2F2F2;border-radius: 10rpx;box-sizing: border-box;display: flex;align-items: center;padding: 0 48rpx;margin-bottom: 20rpx;
+	.label{font-size: 28rpx;font-weight: bold;color: #161616;flex: 0 0 auto;margin-right: 48rpx;}
+	input{font-size: 30rpx;color: #161616;}
+	.input{font-size: 30rpx;color: #161616;}
+	.ilrmgr{width: 12rpx;height: 22rpx;}
+}
+
+// 删除
+.delbox{position: fixed;left:0;right: 0;bottom: 0;z-index: 5;background: #ffffff;
+	.tit{font-size: 32rpx;font-weight: 500;color: #000000;height: 100rpx;display: flex;align-items: center;justify-content: center;}
+	.zhan{height: 24rpx;background: #f5f5f5;width: 100%;}
+	.close{color: #4775EA;}
+}
+// 科目
+.subject{padding: 20rpx 0;max-height: calc(100vh - 200rpx);display: flex;flex-direction: column;
+	.chose_top{margin-bottom: 20rpx;flex: 0 0 auto;
+		.topbtn{font-weight: 500;font-size: 30rpx;color: #666666;width: 108rpx;height: 88rpx;display: flex;align-items: center;justify-content: center;
+			&.topr{color: #4775EA;}
+		}
+		.topc{font-weight: 500;font-size: 30rpx;color: #161616;flex: 1;margin: 0 24rpx;text-align: center;}
+		
+	}
+	.chose_box{padding: 16rpx 32rpx 2rpx;display: flex;flex-wrap: wrap;flex: 1;overflow: auto;
+		.list{margin:0 52rpx 40rpx 0;position: relative;
+		&:nth-child(3n){margin-right: 0;}
+		.lista{
+			width: 190rpx;height:76rpx;background: #F2F2F2;border-radius: 38rpx;font-size: 30rpx;font-weight: 500;
+			color: #666666;
+			&.act{background: #1f57e6;color: #ffffff;}
+		}
+		
+		.listp{position: absolute;left: 0;top: 90%;padding: 2rpx 2rpx;border-radius: 5px;background-color: #d8e4ff;color: #fff;font-size: 24rpx;height: 50rpx;width: 110rpx;box-sizing: border-box;text-align: center;margin-top: -4rpx;
+			&::before{content: '';position: absolute;bottom: 100%;left: 50%;margin-left: -10rpx;border-width: 6rpx;border-style: solid;border-color: transparent  transparent #d8e4ff transparent; }
+			input{font-size: 26rpx;line-height: 40rpx;color: #161616;}
+		}
+}
+	}
+	// 新样式
+	.chose_nbox{
+		padding: 16rpx 32rpx 2rpx;display: flex;flex-wrap: wrap;flex: 1;overflow: auto;
+		.list{display: flex;align-items: center;width: 100%;margin-bottom: 24rpx;
+			.listl{width: 240rpx; height: 76rpx;background: #F2F2F2;border-radius: 10rpx;font-size: 30rpx;font-weight: 500;color: #666666;flex: 0 0 auto;margin-right: 32rpx;text-align: center;line-height: 76rpx;padding: 0 10rpx;box-sizing: border-box;
+			&.act{background: #1f57e6;color: #ffffff;}
+			}
+			.listr{height: 76rpx;width: 280rpx;background: #F2F2F2;border-radius: 10rpx;padding: 0 24rpx;box-sizing: border-box;flex: 1;
+				.ltrtit{flex: 0 0 auto;font-size: 28rpx;font-weight: bold;color: #161616;margin-right: 24rpx;}
+				input{font-size: 30rpx;line-height: 76rpx;color: #161616;}
+			}
+		}
+		.txt{font-size: 26rpx;color: #AAAAAA;display: flex;align-items: flex-start;line-height: 40rpx;
+			text{color: #F7082E;flex: 0 0 auto;}
+		}
+	}
+}
+// 隐私
+.confirmbox{
+	position: fixed;left: 82rpx;right: 82rpx;min-height: 300rpx;top: 50%;margin-top: -30%;border-radius: 24rpx;z-index: 10;background-color: #ffffff;padding-top: 30rpx;box-sizing: border-box;text-align: center;
+	.tit{font-size: 34rpx;font-weight: bold;
+color: #161616;line-height: 48rpx;}
+	.txt{font-size: 32rpx;color: #161616;flex: 1;padding: 28rpx;display: flex;align-items: center;justify-content: center;line-height: 48rpx;}
+	.cfbtn{border-top: 2rpx solid #DDDDDD;flex: 0 0 auto;
+		.cbtn{width: 100%;height: 88rpx;line-height: 88rpx;
+			&.btn1{font-size: 32rpx;font-weight: 500;
+color: #AAAAAA;position: relative;
+				&::after{position: absolute;right: 1rpx;top: 0;bottom: 0;content: "";width: 2rpx;background-color: #DDDDDD;}
+			}
+			&.btn2{font-size: 32rpx;font-weight: 500;color: #4775EA;}
+		}
+	}
+}
+// 防溺水
+.fnsbox{position: fixed;left:56rpx;right: 56rpx;min-height: 600rpx;box-sizing: border-box;padding: 32rpx 48rpx;background-color: #ffffff;border-radius: 10rpx;z-index: 10;top:0;top: 50%;transform: translateY(-50%);max-height: calc(100vh - 100rpx);overflow: auto;
+	image{flex: 0 0 auto;}
+	.fns_top{font-size: 30rpx;font-weight: bold;color: #161616;text-align: center;margin-bottom: 28rpx;
+		image{width: 28rpx;height: 28rpx;position: absolute;left: 48rpx;top: 32rpx;}
+	}
+	.fns_ma{
+		.mibox{padding: 12rpx 0;
+			.tit{font-size: 30rpx;font-weight: 500;color: #161616;flex: 0 0 auto;}
+			.rimg{width: 14rpx;height: 26rpx;margin-left:18rpx;}
+		}
+		
+		.fns_mab{display: flex;flex-wrap: wrap;margin-bottom: 52rpx;
+			image{width: 30rpx;height: 30rpx;margin-right: 14rpx;flex: 0 0 auto;}
+			.tip{flex: 1;font-size: 28rpx;font-weight: 500;color: #161616;}
+		}
+	}
+	.lread{display: flex;align-items: flex-start;justify-content: center;
+		.lreadl{padding-top: 4rpx;
+			image{width: 28rpx;height: 28rpx;margin-right: 14rpx;}
+		}
+		.tit{font-size: 26rpx;font-weight: 500;color: #666666;line-height: 40rpx;
+			text{color: #4775EA;text-decoration: underline;padding: 0 6rpx;}
+		}
+	}
+}
+
+</style>

+ 79 - 0
mine/components/popup/stepbar.vue

@@ -0,0 +1,79 @@
+<template>
+  <view class="stepbar" :class="fixeda?'sfixed':''">
+	  <block v-for="(ite,idx) in steps" :key="idx">
+		  <view class="steps" :class="ite.status>0?'act':''" v-if="reservatType!=2&&ite.val==2||ite.val!=2">
+		  	<!-- <image :src="filln" class="img" v-if="ite.status==0"></image>
+		  	<image :src="fillin" class="img" v-if="ite.status==1"></image>
+		  	<image :src="fillf" class="img" v-if="ite.status==2"></image> -->
+			<view class="txt">{{idx+1}}</view>
+		  	<view class="tit">{{ite.tit}}</view>
+		  	<view class="line"></view>
+		  </view>
+	  </block>
+  </view>
+</template>
+
+<script>
+//fixeda   固定
+  export default {
+	props:{
+		steps: {
+			type: Array,
+			default () {
+				return []
+			}
+		},
+		fixeda:{
+			type: Boolean,
+			default () {
+				return false
+			}
+		},
+		reservatType:{
+			type: [Number,String],
+			default () {
+				return 1
+			}
+		}
+	},
+	components:{
+		
+	},
+	data(){
+		return{
+			// fillin:require("@/static/images/order/come/fillin.png"),//填写
+			// fillf:require("@/static/images/order/come/fillf.png"), //完成
+			// filln:require("@/static/images/order/come/filln.png"),//未填
+		}
+	},
+	onLoad: function() {
+	},
+	methods:{
+		getDetail(e){
+			this.$emit('getDetail')
+		} 
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.sfixed{position: fixed;left: 0;right: 0;top: 0;z-index: 10;}
+.stepbar{background: #ffffff;display: flex;align-items: center;padding: 26rpx 0rpx;flex: 0 0 auto;
+	.steps{display: flex;flex-direction: column;flex: 1;align-items: center;position: relative;
+		.img{width: 46rpx;height: 46rpx;margin-bottom: 14rpx;}
+		.txt{font-weight: bold;font-size: 20rpx;color: #999999;width: 30rpx;height: 30rpx;background: #F0F1F6;border-radius: 50%;display: flex;align-items: center;justify-content: center;margin-bottom: 20rpx;}
+		.tit{font-size: 24rpx;font-weight: bold;color: #CDCDCD;
+
+		}
+		.line{position: absolute;width: 60%;border-bottom: 2rpx dashed #CCCACA;top: 14rpx;right: 0;transform: translateX(50%);}
+		&:last-of-type{.line{display: none;}}
+		&.act{
+			.txt{background: #4775EA;color: #ffffff;}
+			.line{border-color: #4775EA;}
+			.tit{color: #4775EA;}
+		}
+	}
+
+}
+</style>

+ 58 - 0
mine/components/popup/watermark.vue

@@ -0,0 +1,58 @@
+<template>
+    <view class="make">
+        <view class="list">
+            <view class="item" v-for="i in 20">
+                <text>{{info}}</text>
+            </view>
+        </view>
+    </view>
+</template>
+<script>
+    export default {
+        name: "watermark",
+        props: {
+            info: {
+                type: String,
+                default: '全局水印'
+            }
+        },
+        data() {
+            return {
+            };
+        }
+    }
+</script>
+<style lang="scss" scoped>
+    .make {
+        // position: fixed;
+        // width: 100%;
+        // height: 100%;
+		position: absolute;
+		right: 0;
+		bottom: 0;
+        top: 0;
+        left: 0;
+        z-index: 9;
+        background: rgba(0, 0, 0, 0);
+        pointer-events: none;
+        .list {
+            width: 150%;
+            height: 100%;
+            position: absolute;
+            top: 0%;
+            left: -30%;
+            transform: rotate(-45deg);
+            display: flex;
+            flex-wrap: wrap;
+            justify-content: space-between;
+            pointer-events: none;
+            .item {
+                font-size: 36rpx;
+                color: rgba(175,175,175,0.3);
+                // font-weight: bold;
+                padding: 30rpx;
+                pointer-events: none;
+            }
+        }
+    }
+</style>

+ 320 - 0
mine/components/qiun-data-charts/changelog.md

@@ -0,0 +1,320 @@
+## 2.5.0-20230101(2023-01-01)
+- 秋云图表组件 修改条件编译顺序,确保uniapp的cli方式的项目依赖不完整时可以正常显示
+- 秋云图表组件 恢复props属性directory的使用,以修复vue3项目中,开启echarts后,echarts目录识别错误的bug
+- uCharts.js 修复区域图、混合图只有一个数据时图表显示不正确的bug
+- uCharts.js 修复折线图、区域图中时间轴类别图表tooltip指示点显示不正确的bug
+- uCharts.js 修复x轴使用labelCount时,并且boundaryGap = 'justify' 并且关闭Y轴显示的时候,最后一个坐标值不显示的bug
+- uCharts.js 修复折线图只有一组数据时 ios16 渲染颜色不正确的bug
+- uCharts.js 修复玫瑰图半径显示不正确的bug
+- uCharts.js 柱状图、山峰图增加正负图功能,y轴网格如果需要显示0轴则由 min max 及 splitNumber 确定,后续版本优化自动显示0轴
+- uCharts.js 柱状图column增加 opts.extra.column.labelPosition,数据标签位置,有效值为 outside外部, insideTop内顶部, center内中间, bottom内底部
+- uCharts.js 雷达图radar增加 opts.extra.radar.labelShow,否显示各项标识文案是,默认true
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.boxPadding,提示窗边框填充距离,默认3px
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.fontSize,提示窗字体大小配置,默认13px
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.lineHeight,提示窗文字行高,默认20px
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShow,是否显示左侧图例,默认true
+- uCharts.js 提示窗tooltip增加 opts.extra.tooltip.legendShape,图例形状,图例标识样式,有效值为 auto自动跟随图例, diamond◆, circle●, triangle▲, square■, rect▬, line-
+- uCharts.js 标记线markLine增加 opts.extra.markLine.labelFontSize,字体大小配置,默认13px
+- uCharts.js 标记线markLine增加 opts.extra.markLine.labelPadding,标签边框内填充距离,默认6px
+- uCharts.js 折线图line增加 opts.extra.line.linearType,渐变色类型,可选值 none关闭渐变色,custom 自定义渐变色。使用自定义渐变色时请赋值serie.linearColor作为颜色值
+- uCharts.js 折线图line增加 serie.linearColor,渐变色数组,格式为2维数组[起始位置,颜色值],例如[[0,'#0EE2F8'],[0.3,'#2BDCA8'],[0.6,'#1890FF'],[1,'#9A60B4']]
+- uCharts.js 折线图line增加 opts.extra.line.onShadow,是否开启折线阴影,开启后请赋值serie.setShadow阴影设置
+- uCharts.js 折线图line增加 serie.setShadow,阴影配置,格式为4位数组:[offsetX,offsetY,blur,color]
+- uCharts.js 折线图line增加 opts.extra.line.animation,动画效果方向,可选值为vertical 垂直动画效果,horizontal 水平动画效果
+- uCharts.js X轴xAxis增加 opts.xAxis.lineHeight,X轴字体行高,默认20px
+- uCharts.js X轴xAxis增加 opts.xAxis.marginTop,X轴文字距离轴线的距离,默认0px
+- uCharts.js X轴xAxis增加 opts.xAxis.title,当前X轴标题
+- uCharts.js X轴xAxis增加 opts.xAxis.titleFontSize,标题字体大小,默认13px
+- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetY,标题纵向偏移距离,负数为向上偏移,正数向下偏移
+- uCharts.js X轴xAxis增加 opts.xAxis.titleOffsetX,标题横向偏移距离,负数为向左偏移,正数向右偏移
+- uCharts.js X轴xAxis增加 opts.xAxis.titleFontColor,标题字体颜色,默认#666666
+
+## 报错TypeError: Cannot read properties of undefined (reading 'length')
+- 如果是uni-modules版本组件,请先登录HBuilderX账号;
+- 在HBuilderX中的manifest.json,点击重新获取uniapp的appid,或者删除appid重新粘贴,重新运行;
+- 如果是cli项目请使用码云上的非uniCloud版本组件;
+- 或者添加uniCloud的依赖;
+- 或者使用原生uCharts;
+## 2.4.5-20221130(2022-11-30)
+- uCharts.js 优化tooltip当文字很多变为左侧显示时,如果画布仍显显示不下,提示框错位置变为以左侧0位置起画
+- uCharts.js 折线图修复特殊情况下只有单点数据,并改变线宽后点变为圆形的bug
+- uCharts.js 修复Y轴disabled启用后无效并报错的bug
+- uCharts.js 修复仪表盘起始结束角度特殊情况下显示不正确的bug
+- uCharts.js 雷达图新增参数 opts.extra.radar.radius , 自定义雷达图半径
+- uCharts.js 折线图、区域图增加tooltip指示点,opts.extra.line.activeType/opts.extra.area.activeType,可选值"none"不启用激活指示点,"hollow"空心点模式,"solid"实心点模式
+## 2.4.4-20221102(2022-11-02)
+- 秋云图表组件 修复使用echarts时reload、reshow无法调用重新渲染的bug,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/40)
+- 秋云图表组件 修复使用echarts时,初始化时宽高不正确的bug,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/42)
+- 秋云图表组件 修复uniapp的h5使用history模式时,无法加载echarts的bug
+- 秋云图表组件 小程序端@complete、@scrollLeft、@scrollRight、@getTouchStart、@getTouchMove、@getTouchEnd事件增加opts参数传出,方便一些特殊需求的交互获取数据。
+
+- uCharts.js 修复calTooltipYAxisData方法内formatter格式化方法未与y轴方法同步的问题,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/43)
+- uCharts.js 地图新增参数opts.series[i].fillOpacity,以透明度方式来设置颜色过度效果,[详见码云PR](https://gitee.com/uCharts/uCharts/pulls/38)
+- uCharts.js 地图新增参数opts.extra.map.active,是否启用点击激活变色
+- uCharts.js 地图新增参数opts.extra.map.activeTextColor,是否启用点击激活变色
+- uCharts.js 地图新增渲染完成事件renderComplete
+- uCharts.js 漏斗图修复当部分数据相同时tooltip提示窗点击错误的bug
+- uCharts.js 漏斗图新增参数series.data[i].centerText 居中标签文案
+- uCharts.js 漏斗图新增参数series.data[i].centerTextSize 居中标签文案字体大小,默认opts.fontSize
+- uCharts.js 漏斗图新增参数series.data[i].centerTextColor 居中标签文案字体颜色,默认#FFFFFF
+- uCharts.js 漏斗图新增参数opts.extra.funnel.minSize 最小值的最小宽度,默认0
+- uCharts.js 进度条新增参数opts.extra.arcbar.direction,动画方向,可选值为cw顺时针、ccw逆时针
+- uCharts.js 混合图新增参数opts.extra.mix.line.width,折线的宽度,默认2
+- uCharts.js 修复tooltip开启horizentalLine水平横线标注时,图表显示错位的bug
+- uCharts.js 优化tooltip当文字很多变为左侧显示时,如果画布仍显显示不下,提示框错位置变为以左侧0位置起画
+- uCharts.js 修复开启滚动条后X轴文字超出绘图区域后的隐藏逻辑
+- uCharts.js 柱状图、条状图修复堆叠模式不能通过{value,color}赋值单个柱子颜色的问题
+- uCharts.js 气泡图修复不识别series.textSize和series.textColor的bug
+
+## 报错TypeError: Cannot read properties of undefined (reading 'length')
+1. 如果是uni-modules版本组件,请先登录HBuilderX账号;
+2. 在HBuilderX中的manifest.json,点击重新获取uniapp的appid,或者删除appid重新粘贴,重新运行;
+3. 如果是cli项目请使用码云上的非uniCloud版本组件;
+4. 或者添加uniCloud的依赖;
+5. 或者使用原生uCharts;
+## 2.4.3-20220505(2022-05-05)
+- 秋云图表组件 修复开启canvas2d后将series赋值为空数组显示加载图标时,再次赋值后画布闪动的bug
+- 秋云图表组件 修复升级hbx最新版后ECharts的highlight方法报错的bug
+- uCharts.js 雷达图新增参数opts.extra.radar.gridEval,数据点位网格抽希,默认1
+- uCharts.js 雷达图新增参数opts.extra.radar.axisLabel,	是否显示刻度点值,默认false
+- uCharts.js 雷达图新增参数opts.extra.radar.axisLabelTofix,刻度点值小数位数,默认0
+- uCharts.js 雷达图新增参数opts.extra.radar.labelPointShow,是否显示末端刻度圆点,默认false
+- uCharts.js 雷达图新增参数opts.extra.radar.labelPointRadius,刻度圆点的半径,默认3
+- uCharts.js 雷达图新增参数opts.extra.radar.labelPointColor,刻度圆点的颜色,默认#cccccc
+- uCharts.js 雷达图新增参数opts.extra.radar.linearType,渐变色类型,可选值"none"关闭渐变,"custom"开启渐变
+- uCharts.js 雷达图新增参数opts.extra.radar.customColor,自定义渐变颜色,数组类型对应series的数组长度以匹配不同series颜色的不同配色方案,例如["#FA7D8D", "#EB88E2"]
+- uCharts.js 雷达图优化支持series.textColor、series.textSize属性
+- uCharts.js 柱状图中温度计式图标,优化支持全圆角类型,修复边框有缝隙的bug,详见官网【演示】中的温度计图表
+- uCharts.js 柱状图新增参数opts.extra.column.activeWidth,当前点击柱状图的背景宽度,默认一个单元格单位
+- uCharts.js 混合图增加opts.extra.mix.area.gradient 区域图是否开启渐变色
+- uCharts.js 混合图增加opts.extra.mix.area.opacity 区域图透明度,默认0.2
+- uCharts.js 饼图、圆环图、玫瑰图、漏斗图,增加opts.series[0].data[i].labelText,自定义标签文字,避免formatter格式化的繁琐,详见官网【演示】中的饼图
+- uCharts.js 饼图、圆环图、玫瑰图、漏斗图,增加opts.series[0].data[i].labelShow,自定义是否显示某一个指示标签,避免因饼图类别太多导致标签重复或者居多导致图形变形的问题,详见官网【演示】中的饼图
+- uCharts.js 增加opts.series[i].legendText/opts.series[0].data[i].legendText(与series.name同级)自定义图例显示文字的方法
+- uCharts.js 优化X轴、Y轴formatter格式化方法增加形参,统一为fromatter:function(value,index,opts){}
+- uCharts.js 修复横屏模式下无法使用双指缩放方法的bug
+- uCharts.js 修复当只有一条数据或者多条数据值相等的时候Y轴自动计算的最大值错误的bug
+- 【官网模板】增加外部自定义图例与图表交互的例子,[点击跳转](https://www.ucharts.cn/v2/#/layout/info?id=2)
+
+## 注意:非unimodules 版本如因更新 hbx 至 3.4.7 导致报错如下,请到码云更新非 unimodules 版本组件,[点击跳转](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6)
+> Error in callback for immediate watcher "uchartsOpts": "SyntaxError: Unexpected token u in JSON at position 0"
+## 2.4.2-20220421(2022-04-21)
+- 秋云图表组件 修复HBX升级3.4.6.20220420版本后echarts报错的问题
+## 2.4.2-20220420(2022-04-20)
+## 重要!此版本uCharts新增了很多功能,修复了诸多已知问题
+- 秋云图表组件 新增onzoom开启双指缩放功能(仅uCharts),前提需要直角坐标系类图表类型,并且ontouch为true、opts.enableScroll为true,详见实例项目K线图
+- 秋云图表组件 新增optsWatch是否监听opts变化,关闭optsWatch后,动态修改opts不会触发图表重绘
+- 秋云图表组件 修复开启canvas2d功能后,动态更新数据后画布闪动的bug
+- 秋云图表组件 去除directory属性,改为自动获取echarts.min.js路径(升级不受影响)
+- 秋云图表组件 增加getImage()方法及@getImage事件,通过ref调用getImage()方法获,触发@getImage事件获取当前画布的base64图片文件流。
+- 秋云图表组件 支付宝、字节跳动、飞书、快手小程序支持开启canvas2d同层渲染设置。
+- 秋云图表组件 新增加【非uniCloud】版本组件,避免有些不需要uniCloud的使用组件发布至小程序需要提交隐私声明问题,请到码云[【非uniCloud版本】](https://gitee.com/uCharts/uCharts/tree/master/uni-app/uCharts-%E7%BB%84%E4%BB%B6),或npm[【非uniCloud版本】](https://www.npmjs.com/package/@qiun/uni-ucharts)下载使用。
+- uCharts.js 新增dobuleZoom双指缩放功能
+- uCharts.js 新增山峰图type="mount",数据格式为饼图类格式,不需要传入categories,具体详见新版官网在线演示
+- uCharts.js 修复折线图当数据中存在null时tooltip报错的bug
+- uCharts.js 修复饼图类当画布比较小时自动计算的半径是负数报错的bug
+- uCharts.js 统一各图表类型的series.formatter格式化方法的形参为(val, index, series, opts),方便格式化时有更多参数可用
+- uCharts.js 标记线功能增加labelText自定义显示文字,增加labelAlign标签显示位置(左侧或右侧),增加标签显示位置微调labelOffsetX、labelOffsetY
+- uCharts.js 修复条状图当数值很小时开启圆角后样式错误的bug
+- uCharts.js 修复X轴开启disabled后,X轴仍占用空间的bug
+- uCharts.js 修复X轴开启滚动条并且开启rotateLabel后,X轴文字与滚动条重叠的bug
+- uCharts.js 增加X轴rotateAngle文字旋转自定义角度,取值范围(-90至90)
+- uCharts.js 修复地图文字标签层级显示不正确的bug
+- uCharts.js 修复饼图、圆环图、玫瑰图当数据全部为0的时候不显示数据标签的bug
+- uCharts.js 修复当opts.padding上边距为0时,Y轴顶部刻度标签位置不正确的bug
+
+## 另外我们还开发了各大原生小程序组件,已发布至码云和npm
+[https://gitee.com/uCharts/uCharts](https://gitee.com/uCharts/uCharts)
+[https://www.npmjs.com/~qiun](https://www.npmjs.com/~qiun)
+
+## 对于原生uCharts文档我们已上线新版官方网站,详情点击下面链接进入官网
+[https://www.uCharts.cn/v2/](https://www.ucharts.cn/v2/)
+## 2.3.7-20220122(2022-01-22)
+## 重要!使用vue3编译,请使用cli模式并升级至最新依赖,HbuilderX编译需要使用3.3.8以上版本
+- uCharts.js 修复uni-app平台组件模式使用vue3编译到小程序报错的bug。
+## 2.3.7-20220118(2022-01-18)
+## 注意,使用vue3的前提是需要3.3.8.20220114-alpha版本的HBuilder!
+## 2.3.67-20220118(2022-01-18)
+- 秋云图表组件 组件初步支持vue3,全端编译会有些问题,具体详见下面修改:
+1. 小程序端运行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new uni_modules_qiunDataCharts_js_sdk_uCharts_uCharts.uCharts,将.uCharts去掉。
+2. 小程序端发行时,在uni_modules文件夹的qiun-data-charts.js中搜索 new e.uCharts,将.uCharts去掉,变为 new e。
+3. 如果觉得上述步骤比较麻烦,如果您的项目只编译到小程序端,可以修改u-charts.js最后一行导出方式,将 export default uCharts;变更为 export default { uCharts: uCharts }; 这样变更后,H5和App端的renderjs会有问题,请开发者自行选择。(此问题非组件问题,请等待DC官方修复Vue3的小程序端)
+## 2.3.6-20220111(2022-01-11)
+- 秋云图表组件 修改组件 props 属性中的 background 默认值为 rgba(0,0,0,0)
+## 2.3.6-20211201(2021-12-01)
+- uCharts.js 修复bar条状图开启圆角模式时,值很小时圆角渲染错误的bug
+## 2.3.5-20211014(2021-10-15)
+- uCharts.js 增加vue3的编译支持(仅原生uCharts,qiun-data-charts组件后续会支持,请关注更新)
+## 2.3.4-20211012(2021-10-12)
+- 秋云图表组件 修复 mac os x 系统 mouseover 事件丢失的 bug
+## 2.3.3-20210706(2021-07-06)
+- uCharts.js 增加雷达图开启数据点值(opts.dataLabel)的显示
+## 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帮助页

+ 1620 - 0
mine/components/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue

@@ -0,0 +1,1620 @@
+<!-- 
+ * qiun-data-charts 秋云高性能跨全端图表组件
+ * Copyright (c) 2021 QIUN® 秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 复制使用请保留本段注释,感谢支持开源!
+ * 为方便更多开发者使用,如有更好的建议请提交码云 Pull Requests !
+ *
+ * uCharts®官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ -->
+<template>
+  <view class="chartsview" :id="'ChartBoxId'+cid">
+    <view v-if="mixinDatacomLoading">
+      <!-- 自定义加载状态,请改这里 -->
+      <qiun-loading :loadingType="loadingType" />
+    </view>
+    <view v-if="mixinDatacomErrorMessage && errorShow" @tap="reloading">
+      <!-- 自定义错误提示,请改这里 -->
+      <qiun-error :errorMessage="errorMessage" />
+    </view>
+    <!-- APP和H5采用renderjs渲染图表 -->
+    <!-- #ifdef APP-VUE || H5 -->
+    <block v-if="echarts">
+      <view
+        :style="{ background: background }"
+        style="width: 100%;height: 100%;"
+        :data-directory="directory"
+        :id="'EC'+cid" 
+        :prop="echartsOpts" 
+        :change:prop="rdcharts.ecinit" 
+        :resize="echartsResize"
+        :change:resize="rdcharts.ecresize"
+        v-show="showchart"
+      />
+    </block>
+    <block v-else>
+      <view
+        v-on:tap="rdcharts.tap"
+        v-on:mousemove="rdcharts.mouseMove"
+        v-on:mousedown="rdcharts.mouseDown"
+        v-on:mouseup="rdcharts.mouseUp"
+        v-on:touchstart="rdcharts.touchStart"
+        v-on:touchmove="rdcharts.touchMove"
+        v-on:touchend="rdcharts.touchEnd"
+        :id="'UC'+cid"
+        :prop="uchartsOpts"
+        :change:prop="rdcharts.ucinit"
+      >
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          :disable-scroll="disableScroll"
+          @error="_error"
+          v-show="showchart"
+        />
+      </view>
+    </block>
+    <!-- #endif -->
+    <!-- 支付宝小程序 -->
+    <!-- #ifdef MP-ALIPAY -->
+    <block v-if="ontouch">
+      <canvas
+        :id="cid"
+        :canvasId="cid"
+        :width="cWidth * pixel"
+        :height="cHeight * pixel"
+        :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+        :disable-scroll="disScroll"
+        @tap="_tap"
+        @touchstart="_touchStart"
+        @touchmove="_touchMove"
+        @touchend="_touchEnd"
+        @error="_error"
+        v-show="showchart"
+      />
+    </block>
+    <block v-if="!ontouch">
+      <canvas
+        :id="cid"
+        :canvasId="cid"
+        :width="cWidth * pixel"
+        :height="cHeight * pixel"
+        :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+        :disable-scroll="disScroll"
+        @tap="_tap"
+        @error="_error"
+        v-show="showchart"
+      />
+    </block>
+    <!-- #endif -->
+    <!-- 其他小程序通过vue渲染图表 -->
+    <!-- #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO || MP-KUAISHOU || MP-LARK || MP-JD || MP-360 -->
+    <block v-if="type2d">
+      <view v-if="ontouch" @tap="_tap">
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          type="2d"
+          :disable-scroll="disScroll"
+          @touchstart="_touchStart"
+          @touchmove="_touchMove"
+          @touchend="_touchEnd"
+          @error="_error"
+          v-show="showchart"
+        />
+      </view>
+      <view v-if="!ontouch" @tap="_tap">
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          type="2d"
+          :disable-scroll="disScroll"
+          @error="_error"
+          v-show="showchart"
+        />
+      </view>
+    </block>
+    <block v-if="!type2d">
+      <view v-if="ontouch" @tap="_tap">
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          @touchstart="_touchStart"
+          @touchmove="_touchMove"
+          @touchend="_touchEnd"
+          :disable-scroll="disScroll"
+          @error="_error"
+          v-if="showchart"
+        />
+      </view>
+      <view v-if="!ontouch" >
+        <canvas
+          :id="cid"
+          :canvasId="cid"
+          :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
+          :disable-scroll="disScroll"
+          @tap="_tap"
+          @error="_error"
+          v-if="showchart"
+        />
+      </view>
+    </block>
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+	import qiunLoading from "../qiun-loading/qiun-loading.vue";
+import uCharts from '../../js_sdk/u-charts/u-charts.js';
+import cfu from '../../js_sdk/u-charts/config-ucharts.js';
+// #ifdef APP-VUE || H5
+import cfe from '../../js_sdk/u-charts/config-echarts.js';
+// #endif
+
+function deepCloneAssign(origin = {}, ...args) {
+  for (let i in args) {
+    for (let key in args[i]) {
+      if (args[i].hasOwnProperty(key)) {
+        origin[key] = args[i][key] && typeof args[i][key] === 'object' ? deepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
+      }
+    }
+  }
+  return origin;
+}
+
+function formatterAssign(args,formatter) {
+  for (let key in args) {
+    if(args.hasOwnProperty(key) && args[key] !== null && typeof args[key] === 'object'){
+      formatterAssign(args[key],formatter)
+    }else if(key === 'format' && typeof args[key] === 'string'){
+      args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
+    }
+  }
+  return args;
+}
+
+// 时间转换函数,为了匹配uniClinetDB读取出的时间与categories不同
+function getFormatDate(date) {
+	var seperator = "-";
+	var year = date.getFullYear();
+	var month = date.getMonth() + 1;
+	var strDate = date.getDate();
+	if (month >= 1 && month <= 9) {
+			month = "0" + month;
+	}
+	if (strDate >= 0 && strDate <= 9) {
+			strDate = "0" + strDate;
+	}
+	var currentdate = year + seperator + month + seperator + strDate;
+	return currentdate;
+}
+
+var lastMoveTime = null;
+/**
+ * 防抖
+ *
+ * @param { Function } fn 要执行的方法
+ * @param { Number } wait  防抖多少毫秒
+ *
+ * 在 vue 中使用(注意:不能使用箭头函数,否则this指向不对,并且不能再次封装如:
+ * move(){  // 错误调用方式
+ *   debounce(function () {
+ *   console.log(this.title);
+ * }, 1000)});
+ * 应该直接使用:// 正确调用方式
+ * move: debounce(function () {
+ *   console.log(this.title);
+ * }, 1000)
+ */
+function debounce(fn, wait) {
+  let timer = false;
+  return function() {
+    clearTimeout(timer);
+    timer && clearTimeout(timer);
+    timer = setTimeout(() => {
+      timer = false;
+      fn.apply(this, arguments); // 把参数传进去
+    }, wait);
+  };
+}
+
+export default {
+components:{qiunLoading},
+  name: 'qiun-data-charts',
+  mixins: [uniCloud.mixinDatacom],
+  props: {
+    type: {
+      type: String,
+      default: null
+    },
+    canvasId: {
+      type: String,
+      default: 'uchartsid'
+    },
+    canvas2d: {
+      type: Boolean,
+      default: false
+    },
+    background: {
+      type: String,
+      default: 'rgba(0,0,0,0)'
+    },
+    animation: {
+      type: Boolean,
+      default: true
+    },
+    chartData: {
+      type: Object,
+      default() {
+        return {
+          categories: [],
+          series: []
+        };
+      }
+    },
+    opts: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    eopts: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    loadingType: {
+      type: Number,
+      default: 2
+    },
+    errorShow: {
+      type: Boolean,
+      default: true
+    },
+    errorReload: {
+      type: Boolean,
+      default: true
+    },
+    errorMessage: {
+      type: String,
+      default: null
+    },
+    inScrollView: {
+      type: Boolean,
+      default: false
+    },
+    reshow: {
+      type: Boolean,
+      default: false
+    },
+    reload: {
+      type: Boolean,
+      default: false
+    },
+    disableScroll: {
+      type: Boolean,
+      default: false
+    },
+    optsWatch: {
+      type: Boolean,
+      default: true
+    },
+    onzoom: {
+      type: Boolean,
+      default: false
+    },
+    ontap: {
+      type: Boolean,
+      default: true
+    },
+    ontouch: {
+      type: Boolean,
+      default: false
+    },
+    onmouse: {
+      type: Boolean,
+      default: true
+    },
+    onmovetip: {
+      type: Boolean,
+      default: false
+    },
+    echartsH5: {
+      type: Boolean,
+      default: false
+    },
+    echartsApp: {
+      type: Boolean,
+      default: false
+    },
+    tooltipShow: {
+      type: Boolean,
+      default: true
+    },
+    tooltipFormat: {
+      type: String,
+      default: undefined
+    },
+    tooltipCustom: {
+      type: Object,
+      default: undefined
+    },
+    startDate: {
+      type: String,
+      default: undefined
+    },
+    endDate: {
+      type: String,
+      default: undefined
+    },
+    textEnum: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    groupEnum: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    pageScrollTop: {
+      type: Number,
+      default: 0
+    },
+    directory: {
+      type: String,
+      default: '/'
+    },
+    tapLegend: {
+      type: Boolean,
+      default: true
+    },
+    menus: {
+      type: Array,
+      default () {
+        return []
+      }
+    }
+  },
+  data() {
+    return {
+      cid: 'uchartsid',
+      inWx: false,
+      inAli: false,
+      inTt: false,
+      inBd: false,
+      inH5: false,
+      inApp: false,
+      inWin: false,
+      type2d: true,
+      disScroll: false,
+      openmouse: false,
+      pixel: 1,
+      cWidth: 375,
+      cHeight: 250,
+      showchart: false,
+      echarts: false,
+      echartsResize:{
+        state:false
+      },
+      uchartsOpts: {},
+      echartsOpts: {},
+      drawData:{},
+      lastDrawTime:null,
+    };
+  },
+  created(){
+    this.cid = this.canvasId
+    if (this.canvasId == 'uchartsid' || this.canvasId == '') {
+      let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
+      let len = t.length
+      let id = ''
+      for (let i = 0; i < 32; i++) {
+        id += t.charAt(Math.floor(Math.random() * len))
+      }
+      this.cid = id
+    }
+    const systemInfo = uni.getSystemInfoSync()
+    if(systemInfo.platform === 'windows' || systemInfo.platform === 'mac'){
+      this.inWin = true;
+    }
+    // #ifdef MP-WEIXIN
+    this.inWx = true;
+    if (this.canvas2d === false || systemInfo.platform === 'windows' || systemInfo.platform === 'mac') {
+      this.type2d = false;
+    }else{
+      this.type2d = true;
+      this.pixel = systemInfo.pixelRatio;
+    }
+    // #endif
+    //非微信小程序端强制关闭canvas2d模式
+    // #ifndef MP-WEIXIN
+    this.type2d = false;
+    // #endif
+    // #ifdef  MP-TOUTIAO || MP-LARK || MP-ALIPAY
+    this.type2d = this.canvas2d;
+    // #endif
+    // #ifdef MP-ALIPAY
+    this.inAli = true;
+    this.pixel = systemInfo.pixelRatio;
+    // #endif
+    // #ifdef MP-BAIDU
+    this.inBd = true;
+    // #endif
+    // #ifdef MP-TOUTIAO
+    this.inTt = true;
+    // #endif
+    this.disScroll = this.disableScroll;
+  },
+  mounted() {
+    // #ifdef APP-VUE
+    this.inApp = true;
+    if (this.echartsApp === true) {
+      this.echarts = true;
+      this.openmouse = false;
+    }
+    // #endif
+    // #ifdef APP-NVUE
+    this.inApp = true;
+    this.mixinDatacomLoading = false
+    this.mixinDatacomErrorMessage = "暂不支持NVUE"
+    // #endif
+    // #ifdef H5
+    this.inH5 = true;
+    if(this.inWin === true){
+      this.openmouse = this.onmouse;
+    }
+    if (this.echartsH5 === true) {
+      this.echarts = true;
+    }
+    // #endif
+    this.$nextTick(()=>{
+      this.beforeInit();
+    })
+    // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || APP-VUE
+    const time = this.inH5 ? 500 : 200;
+    const _this = this;
+    uni.onWindowResize(
+      debounce(function(res) {
+        if (_this.mixinDatacomLoading == true) {
+          return;
+        }
+        let errmsg = _this.mixinDatacomErrorMessage;
+        if (errmsg !== null && errmsg !== 'null' && errmsg !== '') {
+          return;
+        }
+        if (_this.echarts) {
+          _this.echartsResize.state = !_this.echartsResize.state;
+        } else {
+          _this.resizeHandler();
+        }
+      }, time)
+    );
+    // #endif
+  },
+  destroyed(){
+    if(this.echarts === true){
+      delete cfe.option[this.cid]
+      delete cfe.instance[this.cid]
+    }else{
+      delete cfu.option[this.cid]
+      delete cfu.instance[this.cid]
+    }
+    // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
+    uni.offWindowResize(()=>{})
+    // #endif
+  },
+  watch: {
+    chartDataProps: {
+      handler(val, oldval) {
+        if (typeof val === 'object') {
+          if (JSON.stringify(val) !== JSON.stringify(oldval)) {
+            this._clearChart();
+            if (val.series && val.series.length > 0) {
+              this.beforeInit();
+            }else{
+              this.mixinDatacomLoading = true;
+              this.showchart = false;
+              this.mixinDatacomErrorMessage = null;
+            }
+          }
+        } else {
+          this.mixinDatacomLoading = false;
+          this._clearChart();
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:chartData数据类型错误';
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    localdata:{
+      handler(val, oldval) {
+        if (JSON.stringify(val) !== JSON.stringify(oldval)) {
+          if (val.length > 0) {
+            this.beforeInit();
+          }else{
+            this.mixinDatacomLoading = true;
+            this._clearChart();
+            this.showchart = false;
+            this.mixinDatacomErrorMessage = null;
+          }
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    optsProps: {
+      handler(val, oldval) {
+        if (typeof val === 'object') {
+          if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === false && this.optsWatch == true) {
+            this.checkData(this.drawData);
+          }
+        } else {
+          this.mixinDatacomLoading = false;
+          this._clearChart();
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:opts数据类型错误';
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    eoptsProps: {
+      handler(val, oldval) {
+        if (typeof val === 'object') {
+          if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === true) {
+            this.checkData(this.drawData);
+          }
+        } else {
+          this.mixinDatacomLoading = false;
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:eopts数据类型错误';
+        }
+      },
+      immediate: false,
+      deep: true
+    },
+    reshow(val, oldval) {
+      if (val === true && this.mixinDatacomLoading === false) {
+        setTimeout(() => {
+          this.mixinDatacomErrorMessage = null;
+          this.echartsResize.state = !this.echartsResize.state;
+          this.checkData(this.drawData);
+        }, 200);
+      }
+    },
+    reload(val, oldval) {
+      if (val === true) {
+        this.showchart = false;
+        this.mixinDatacomErrorMessage = null;
+        this.reloading();
+      }
+    },
+    mixinDatacomErrorMessage(val, oldval) {
+      if (val) {
+        this.emitMsg({name: 'error', params: {type:"error", errorShow: this.errorShow, msg: val, id: this.cid}});
+        if(this.errorShow){
+          console.log('[秋云图表组件]' + val);
+        }
+      }
+    },
+    errorMessage(val, oldval) {
+      if (val && this.errorShow && val !== null && val !== 'null' && val !== '') {
+        this.showchart = false;
+        this.mixinDatacomLoading = false;
+        this.mixinDatacomErrorMessage = val;
+      } else {
+        this.showchart = false;
+        this.mixinDatacomErrorMessage = null;
+        this.reloading();
+      }
+    }
+  },
+  computed: {
+    optsProps() {
+      return JSON.parse(JSON.stringify(this.opts));
+    },
+    eoptsProps() {
+      return JSON.parse(JSON.stringify(this.eopts));
+    },
+    chartDataProps() {
+      return JSON.parse(JSON.stringify(this.chartData));
+    },
+  },
+  methods: {
+    beforeInit(){
+      this.mixinDatacomErrorMessage = null;
+      if (typeof this.chartData === 'object' && this.chartData != null && this.chartData.series !== undefined && this.chartData.series.length > 0) {
+        //拷贝一下chartData,为了opts变更后统一数据来源
+        this.drawData = deepCloneAssign({}, this.chartData);
+        this.mixinDatacomLoading = false;
+        this.showchart = true;
+        this.checkData(this.chartData);
+      }else if(this.localdata.length>0){
+        this.mixinDatacomLoading = false;
+        this.showchart = true;
+        this.localdataInit(this.localdata);
+      }else if(this.collection !== ''){
+        this.mixinDatacomLoading = false;
+        this.getCloudData();
+      }else{
+        this.mixinDatacomLoading = true;
+      }
+    },
+    localdataInit(resdata){
+      //替换enum类型为正确的描述
+      if(this.groupEnum.length>0){
+        for (let i = 0; i < resdata.length; i++) {
+          for (let j = 0; j < this.groupEnum.length; j++) {
+            if(resdata[i].group === this.groupEnum[j].value){
+              resdata[i].group = this.groupEnum[j].text
+            }
+          }
+        }
+      }
+      if(this.textEnum.length>0){
+        for (let i = 0; i < resdata.length; i++) {
+          for (let j = 0; j < this.textEnum.length; j++) {
+            if(resdata[i].text === this.textEnum[j].value){
+              resdata[i].text = this.textEnum[j].text
+            }
+          }
+        }
+      }
+      let needCategories = false;
+      let tmpData = {categories:[], series:[]}
+      let tmpcategories = []
+      let tmpseries = [];
+      //拼接categories
+      if(this.echarts === true){
+        needCategories = cfe.categories.includes(this.type)
+      }else{
+        needCategories = cfu.categories.includes(this.type)
+      }
+      if(needCategories === true){
+        //如果props中的chartData带有categories,则优先使用chartData的categories
+        if(this.chartData && this.chartData.categories && this.chartData.categories.length>0){
+          tmpcategories = this.chartData.categories
+        }else{
+          //如果是日期类型的数据,不管是本地数据还是云数据,都按起止日期自动拼接categories
+          if(this.startDate && this.endDate){
+            let idate = new Date(this.startDate)
+            let edate = new Date(this.endDate)
+            while (idate <= edate) {
+            	tmpcategories.push(getFormatDate(idate))
+            	idate = idate.setDate(idate.getDate() + 1)
+            	idate = new Date(idate)
+            }
+          //否则从结果中去重并拼接categories
+          }else{
+            let tempckey = {};
+            resdata.map(function(item, index) {
+              if (item.text != undefined && !tempckey[item.text]) {
+                tmpcategories.push(item.text)
+                tempckey[item.text] = true
+              }
+            });
+          }
+        }
+        tmpData.categories = tmpcategories
+      }
+      //拼接series
+      let tempskey = {};
+      resdata.map(function(item, index) {
+        if (item.group != undefined && !tempskey[item.group]) {
+          tmpseries.push({ name: item.group, data: [] });
+          tempskey[item.group] = true;
+        }
+      });
+      //如果没有获取到分组名称(可能是带categories的数据,也可能是不带的饼图类)
+      if (tmpseries.length == 0) {
+        tmpseries = [{ name: '默认分组', data: [] }];
+        //如果是需要categories的图表类型
+        if(needCategories === true){
+          for (let j = 0; j < tmpcategories.length; j++) {
+            let seriesdata = 0;
+            for (let i = 0; i < resdata.length; i++) {
+              if (resdata[i].text == tmpcategories[j]) {
+                seriesdata = resdata[i].value;
+              }
+            }
+            tmpseries[0].data.push(seriesdata);
+          }
+        //如果是饼图类的图表类型
+        }else{
+          for (let i = 0; i < resdata.length; i++) {
+            tmpseries[0].data.push({"name": resdata[i].text,"value": resdata[i].value});
+          }
+        }
+      //如果有分组名
+      } else {
+        for (let k = 0; k < tmpseries.length; k++) {
+          //如果有categories
+          if (tmpcategories.length > 0) {
+            for (let j = 0; j < tmpcategories.length; j++) {
+              let seriesdata = 0;
+              for (let i = 0; i < resdata.length; i++) {
+                if (tmpseries[k].name == resdata[i].group && resdata[i].text == tmpcategories[j]) {
+                  seriesdata = resdata[i].value;
+                }
+              }
+              tmpseries[k].data.push(seriesdata);
+            }
+          //如果传了group而没有传text,即没有categories(正常情况下这种数据是不符合数据要求规范的)
+          } else {
+            for (let i = 0; i < resdata.length; i++) {
+              if (tmpseries[k].name == resdata[i].group) {
+                tmpseries[k].data.push(resdata[i].value);
+              }
+            }
+          }
+        }
+      }
+      tmpData.series = tmpseries
+      //拷贝一下chartData,为了opts变更后统一数据来源
+      this.drawData = deepCloneAssign({}, tmpData);
+      this.checkData(tmpData)
+    },
+    reloading() {
+      if(this.errorReload === false){
+        return;
+      }
+      this.showchart = false;
+      this.mixinDatacomErrorMessage = null;
+      if (this.collection !== '') {
+        this.mixinDatacomLoading = false;
+        this.onMixinDatacomPropsChange(true);
+      } else {
+        this.beforeInit();
+      }
+    },
+    checkData(anyData) {
+      let cid = this.cid
+      //复位opts或eopts
+      if(this.echarts === true){
+        cfe.option[cid] = deepCloneAssign({}, this.eopts);
+        cfe.option[cid].id = cid;
+        cfe.option[cid].type = this.type;
+      }else{
+        if (this.type && cfu.type.includes(this.type)) {
+          cfu.option[cid] = deepCloneAssign({}, cfu[this.type], this.opts);
+          cfu.option[cid].canvasId = cid;
+        } else {
+          this.mixinDatacomLoading = false;
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '参数错误:props参数中type类型不正确';
+        }
+      }
+      //挂载categories和series
+      let newData = deepCloneAssign({}, anyData);
+      if (newData.series !== undefined && newData.series.length > 0) {
+        this.mixinDatacomErrorMessage = null;
+        if (this.echarts === true) {
+          cfe.option[cid].chartData = newData;
+          this.$nextTick(()=>{
+            this.init()
+          })
+        }else{
+          cfu.option[cid].categories = newData.categories;
+          cfu.option[cid].series = newData.series;
+          this.$nextTick(()=>{
+            this.init()
+          })
+        }
+      }
+    },
+    resizeHandler() {
+      //渲染防抖
+      let currTime = Date.now();
+      let lastDrawTime = this.lastDrawTime?this.lastDrawTime:currTime-3000;
+      let duration = currTime - lastDrawTime;
+      if (duration < 1000) return;
+      let chartdom = uni
+        .createSelectorQuery()
+        // #ifndef MP-ALIPAY
+        .in(this)
+        // #endif
+        .select('#ChartBoxId'+this.cid)
+        .boundingClientRect(data => {
+          this.showchart = true;
+          if (data.width > 0 && data.height > 0) {
+            if (data.width !== this.cWidth || data.height !== this.cHeight) {
+              this.checkData(this.drawData)
+            }
+          }
+        })
+        .exec();
+    },
+    getCloudData() {
+      if (this.mixinDatacomLoading == true) {
+        return;
+      }
+      this.mixinDatacomLoading = true;
+      this.mixinDatacomGet()
+        .then(res => {
+          this.mixinDatacomResData = res.result.data;
+          this.localdataInit(this.mixinDatacomResData);
+        })
+        .catch(err => {
+          this.mixinDatacomLoading = false;
+          this.showchart = false;
+          this.mixinDatacomErrorMessage = '请求错误:' + err;
+        });
+    },
+    onMixinDatacomPropsChange(needReset, changed) {
+      if (needReset == true && this.collection !== '') {
+        this.showchart = false;
+        this.mixinDatacomErrorMessage = null;
+        this._clearChart();
+        this.getCloudData();
+      }
+    },
+    _clearChart() {
+      let cid = this.cid
+      if (this.echarts !== true && cfu.option[cid] && cfu.option[cid].context) {
+        const ctx = cfu.option[cid].context;
+        if(typeof ctx === "object" && !!!cfu.option[cid].update){
+          ctx.clearRect(0, 0, this.cWidth*this.pixel, this.cHeight*this.pixel);
+          ctx.draw();
+        }
+      }
+    },
+    init() {
+      let cid = this.cid
+      let chartdom = uni
+        .createSelectorQuery()
+        // #ifndef MP-ALIPAY
+        .in(this)
+        // #endif
+        .select('#ChartBoxId'+cid)
+        .boundingClientRect(data => {
+          if (data.width > 0 && data.height > 0) {
+            this.mixinDatacomLoading = false;
+            this.showchart = true;
+            this.lastDrawTime = Date.now();
+            this.cWidth = data.width;
+            this.cHeight = data.height;
+            if(this.echarts !== true){
+              cfu.option[cid].background = this.background == 'rgba(0,0,0,0)' ? '#FFFFFF' : this.background;
+              cfu.option[cid].canvas2d = this.type2d;
+              cfu.option[cid].pixelRatio = this.pixel;
+              cfu.option[cid].animation = this.animation;
+              cfu.option[cid].width = data.width * this.pixel;
+              cfu.option[cid].height = data.height * this.pixel;
+              cfu.option[cid].onzoom = this.onzoom;
+              cfu.option[cid].ontap = this.ontap;
+              cfu.option[cid].ontouch = this.ontouch;
+              cfu.option[cid].onmouse = this.openmouse;
+              cfu.option[cid].onmovetip = this.onmovetip;
+              cfu.option[cid].tooltipShow = this.tooltipShow;
+              cfu.option[cid].tooltipFormat = this.tooltipFormat;
+              cfu.option[cid].tooltipCustom = this.tooltipCustom;
+              cfu.option[cid].inScrollView = this.inScrollView;
+              cfu.option[cid].lastDrawTime = this.lastDrawTime;
+              cfu.option[cid].tapLegend = this.tapLegend;
+            }
+            //如果是H5或者App端,采用renderjs渲染图表
+            if (this.inH5 || this.inApp) {
+              if (this.echarts == true) {
+                cfe.option[cid].ontap = this.ontap;
+                cfe.option[cid].onmouse = this.openmouse;
+                cfe.option[cid].tooltipShow = this.tooltipShow;
+                cfe.option[cid].tooltipFormat = this.tooltipFormat;
+                cfe.option[cid].tooltipCustom = this.tooltipCustom;
+                cfe.option[cid].lastDrawTime = this.lastDrawTime;
+                this.echartsOpts = deepCloneAssign({}, cfe.option[cid]);
+              } else {
+                cfu.option[cid].rotateLock = cfu.option[cid].rotate;
+                this.uchartsOpts = deepCloneAssign({}, cfu.option[cid]);
+              }
+            //如果是小程序端,采用uCharts渲染
+            } else {
+              cfu.option[cid] = formatterAssign(cfu.option[cid],cfu.formatter)
+              this.mixinDatacomErrorMessage = null;
+              this.mixinDatacomLoading = false;
+              this.showchart = true;
+              this.$nextTick(()=>{
+                if (this.type2d === true) {
+                  const query = uni.createSelectorQuery().in(this)
+                  query
+                    .select('#' + cid)
+                    .fields({ node: true, size: true })
+                    .exec(res => {
+                      if (res[0]) {
+                        const canvas = res[0].node;
+                        const ctx = canvas.getContext('2d');
+                        cfu.option[cid].context = ctx;
+                        cfu.option[cid].rotateLock = cfu.option[cid].rotate;
+                        if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
+                          this._updataUChart(cid)
+                        }else{
+                          canvas.width = data.width * this.pixel;
+                          canvas.height = data.height * this.pixel;
+                          canvas._width = data.width * this.pixel;
+                          canvas._height = data.height * this.pixel;
+                          setTimeout(()=>{
+                            cfu.option[cid].context.restore();
+                            cfu.option[cid].context.save();
+                            this._newChart(cid)
+                          },100)
+                        }
+                      } else {
+                        this.showchart = false;
+                        this.mixinDatacomErrorMessage = '参数错误:开启2d模式后,未获取到dom节点,canvas-id:' + cid;
+                      }
+                    });
+                } else {
+                  if(this.inAli){
+                    cfu.option[cid].rotateLock = cfu.option[cid].rotate;
+                  }
+                  cfu.option[cid].context = uni.createCanvasContext(cid, this);
+                  if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
+                    this._updataUChart(cid)
+                  }else{
+                    setTimeout(()=>{
+                      cfu.option[cid].context.restore();
+                      cfu.option[cid].context.save();
+                      this._newChart(cid)
+                    },100)
+                  }
+                }
+              })
+            }
+          } else {
+            this.mixinDatacomLoading = false;
+            this.showchart = false;
+            if (this.reshow == true) {
+              this.mixinDatacomErrorMessage = '布局错误:未获取到父元素宽高尺寸!canvas-id:' + cid;
+            }
+          }
+        })
+        .exec();
+    },
+    saveImage(){
+    	uni.canvasToTempFilePath({
+    	  canvasId: this.cid,
+    	  success: res=>{
+    	    //#ifdef H5
+    			var a = document.createElement("a");
+    			a.href = res.tempFilePath;
+    			a.download = this.cid;
+    			a.target = '_blank'
+    			a.click();
+    	    //#endif
+    	    //#ifndef H5
+    	      uni.saveImageToPhotosAlbum({
+              filePath: res.tempFilePath,
+              success: function () {
+                uni.showToast({
+                  title: '保存成功',
+                  duration: 2000
+                });
+              }
+    	      });
+    	    //#endif
+    	  } 
+    	},this);
+    },
+    getImage(){
+      if(this.type2d == false){
+        uni.canvasToTempFilePath({
+          canvasId: this.cid,
+          success: res=>{
+            this.emitMsg({name: 'getImage', params: {type:"getImage", base64: res.tempFilePath}});
+          }
+        },this);
+      }else{
+        const query = uni.createSelectorQuery().in(this)
+        query
+          .select('#' + this.cid)
+          .fields({ node: true, size: true })
+          .exec(res => {
+            if (res[0]) {
+              const canvas = res[0].node;
+              this.emitMsg({name: 'getImage', params: {type:"getImage", base64: canvas.toDataURL('image/png')}});
+            }
+          });
+      }
+    },
+    // #ifndef APP-VUE || H5
+    _newChart(cid) {
+      if (this.mixinDatacomLoading == true) {
+        return;
+      }
+      this.showchart = true;
+      cfu.instance[cid] = new uCharts(cfu.option[cid]);
+      cfu.instance[cid].addEventListener('renderComplete', () => {
+        this.emitMsg({name: 'complete', params: {type:"complete", complete: true, id: cid, opts: cfu.instance[cid].opts}});
+        cfu.instance[cid].delEventListener('renderComplete')
+      });
+      cfu.instance[cid].addEventListener('scrollLeft', () => {
+        this.emitMsg({name: 'scrollLeft', params: {type:"scrollLeft", scrollLeft: true, id: cid, opts: cfu.instance[cid].opts}});
+      });
+      cfu.instance[cid].addEventListener('scrollRight', () => {
+        this.emitMsg({name: 'scrollRight', params: {type:"scrollRight", scrollRight: true, id: cid, opts: cfu.instance[cid].opts}});
+      });
+    },
+    _updataUChart(cid) {
+      cfu.instance[cid].updateData(cfu.option[cid])
+    },
+    _tooltipDefault(item, category, index, opts) {
+      if (category) {
+        let data = item.data
+        if(typeof item.data === "object"){
+          data = item.data.value
+        }
+        return category + ' ' + item.name + ':' + data;
+      } else {
+        if (item.properties && item.properties.name) {
+          return item.properties.name;
+        } else {
+          return item.name + ':' + item.data;
+        }
+      }
+    },
+    _showTooltip(e) {
+      let cid = this.cid
+      let tc = cfu.option[cid].tooltipCustom
+      if (tc && tc !== undefined && tc !== null) {
+        let offset = undefined;
+        if (tc.x >= 0 && tc.y >= 0) {
+          offset = { x: tc.x, y: tc.y + 10 };
+        }
+        cfu.instance[cid].showToolTip(e, {
+          index: tc.index,
+          offset: offset,
+          textList: tc.textList,
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this._tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      } else {
+        cfu.instance[cid].showToolTip(e, {
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this._tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      }
+    },
+    _tap(e,move) {
+      let cid = this.cid
+      let currentIndex = null;
+      let legendIndex = null;
+      if (this.inScrollView === true || this.inAli) {
+        let chartdom = uni
+          .createSelectorQuery()
+          // #ifndef MP-ALIPAY
+          .in(this)
+          .select('#ChartBoxId'+cid)
+          // #endif
+          // #ifdef MP-ALIPAY
+          .select('#'+this.cid)
+          // #endif
+          .boundingClientRect(data => {
+            e.changedTouches=[];
+            if (this.inAli) {
+              e.changedTouches.unshift({ x: e.detail.clientX - data.left, y: e.detail.clientY - data.top});
+            }else{
+              e.changedTouches.unshift({ x: e.detail.x - data.left, y: e.detail.y - data.top - this.pageScrollTop});
+            }
+            if(move){
+              if (this.tooltipShow === true) {
+                this._showTooltip(e);
+              }
+            }else{
+              currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
+              legendIndex = cfu.instance[cid].getLegendDataIndex(e);
+              if(this.tapLegend === true){
+                cfu.instance[cid].touchLegend(e);
+              }
+              if (this.tooltipShow === true) {
+                this._showTooltip(e);
+              }
+              this.emitMsg({name: 'getIndex', params: { type:"getIndex", event:{ x: e.detail.x - data.left, y: e.detail.y - data.top }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid, opts: cfu.instance[cid].opts}});
+            }
+          })
+          .exec();
+      } else {
+        if(move){
+          if (this.tooltipShow === true) {
+            this._showTooltip(e);
+          }
+        }else{
+          e.changedTouches=[];
+          e.changedTouches.unshift({ x: e.detail.x - e.currentTarget.offsetLeft, y: e.detail.y - e.currentTarget.offsetTop });
+          currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
+          legendIndex = cfu.instance[cid].getLegendDataIndex(e);
+          if(this.tapLegend === true){
+            cfu.instance[cid].touchLegend(e);
+          }
+          if (this.tooltipShow === true) {
+            this._showTooltip(e);
+          }
+          this.emitMsg({name: 'getIndex', params: {type:"getIndex", event:{ x: e.detail.x, y: e.detail.y - e.currentTarget.offsetTop }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid, opts: cfu.instance[cid].opts}});
+        }
+      }
+    },
+    _touchStart(e) {
+      let cid = this.cid
+      lastMoveTime=Date.now();
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 1){
+        cfu.instance[cid].scrollStart(e);
+      }
+      this.emitMsg({name:'getTouchStart', params:{type:"touchStart", event:e.changedTouches[0], id:cid, opts: cfu.instance[cid].opts}});
+    },
+    _touchMove(e) {
+      let cid = this.cid
+      let currMoveTime = Date.now();
+      let duration = currMoveTime - lastMoveTime;
+      let touchMoveLimit = cfu.option[cid].touchMoveLimit || 24;
+      if (duration < Math.floor(1000 / touchMoveLimit)) return;//每秒60帧
+      lastMoveTime = currMoveTime;
+      if(cfu.option[cid].enableScroll === true && e.changedTouches.length == 1){
+        cfu.instance[cid].scroll(e);
+      }
+      if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
+        this._tap(e,true)
+      }
+      if(this.ontouch === true && cfu.option[cid].enableScroll === true && this.onzoom === true && e.changedTouches.length == 2){
+        cfu.instance[cid].dobuleZoom(e);
+      }
+      this.emitMsg({name: 'getTouchMove', params: {type:"touchMove", event:e.changedTouches[0], id: cid, opts: cfu.instance[cid].opts}});
+    },
+    _touchEnd(e) {
+      let cid = this.cid
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 0){
+        cfu.instance[cid].scrollEnd(e);
+      }
+      this.emitMsg({name:'getTouchEnd', params:{type:"touchEnd", event:e.changedTouches[0], id:cid, opts: cfu.instance[cid].opts}});
+      if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
+        this._tap(e,true)
+      }
+    },
+    // #endif
+    _error(e) {
+      this.mixinDatacomErrorMessage = e.detail.errMsg;
+    },
+    emitMsg(msg) {
+      this.$emit(msg.name, msg.params);
+    },
+    getRenderType() {
+      //防止如果开启echarts且父元素为v-if的情况renderjs监听不到prop变化的问题
+      if(this.echarts===true && this.mixinDatacomLoading===false){
+        this.beforeInit()
+      }
+    },
+    toJSON(){
+      return this
+    }
+  }
+};
+</script>
+
+<!-- #ifdef APP-VUE || H5 -->
+<script module="rdcharts" lang="renderjs">
+import uChartsRD from '../../js_sdk/u-charts/u-charts.js';
+import cfu from '../../js_sdk/u-charts/config-ucharts.js';
+import cfe from '../../js_sdk/u-charts/config-echarts.js';
+
+var that = {};
+var rootdom = null;
+
+function rddeepCloneAssign(origin = {}, ...args) {
+  for (let i in args) {
+    for (let key in args[i]) {
+      if (args[i].hasOwnProperty(key)) {
+        origin[key] = args[i][key] && typeof args[i][key] === 'object' ? rddeepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
+      }
+    }
+  }
+  return origin;
+}
+
+function rdformatterAssign(args,formatter) {
+  for (let key in args) {
+    if(args.hasOwnProperty(key) && args[key] !== null && typeof args[key] === 'object'){
+      rdformatterAssign(args[key],formatter)
+    }else if(key === 'format' && typeof args[key] === 'string'){
+      args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
+    }
+  }
+  return args;
+}
+
+export default {
+  data() {
+    return {
+      rid:null
+    }
+  },
+  mounted() {
+    rootdom = {top:0,left:0}
+    // #ifdef H5
+    let dm = document.querySelectorAll('uni-main')[0]
+    if(dm === undefined){
+      dm = document.querySelectorAll('uni-page-wrapper')[0]
+    }
+    rootdom = {top:dm.offsetTop,left:dm.offsetLeft}
+    // #endif
+    setTimeout(()=>{
+      if(this.rid === null){
+        this.$ownerInstance && this.$ownerInstance.callMethod('getRenderType')
+      }
+    },200)
+  },
+  destroyed(){
+    delete cfu.option[this.rid]
+    delete cfu.instance[this.rid]
+    delete cfe.option[this.rid]
+    delete cfe.instance[this.rid]
+  },
+  methods: {
+    //==============以下是ECharts的方法====================
+    ecinit(newVal, oldVal, owner, instance){
+      let cid = JSON.stringify(newVal.id)
+      this.rid = cid
+      that[cid] = this.$ownerInstance || instance
+      let eopts = JSON.parse(JSON.stringify(newVal))
+      let type = eopts.type;
+      //载入并覆盖默认配置
+      if (type && cfe.type.includes(type)) {
+        cfe.option[cid] = rddeepCloneAssign({}, cfe[type], eopts);
+      }else{
+        cfe.option[cid] = rddeepCloneAssign({}, eopts);
+      }
+      let newData = eopts.chartData;
+      if(newData){
+        //挂载categories和series
+        if(cfe.option[cid].xAxis && cfe.option[cid].xAxis.type && cfe.option[cid].xAxis.type === 'category'){
+          cfe.option[cid].xAxis.data = newData.categories
+        }
+        if(cfe.option[cid].yAxis && cfe.option[cid].yAxis.type && cfe.option[cid].yAxis.type === 'category'){
+          cfe.option[cid].yAxis.data = newData.categories
+        }
+        cfe.option[cid].series = []
+        for (var i = 0; i < newData.series.length; i++) {
+          cfe.option[cid].seriesTemplate = cfe.option[cid].seriesTemplate ? cfe.option[cid].seriesTemplate : {}
+          let Template = rddeepCloneAssign({},cfe.option[cid].seriesTemplate,newData.series[i])
+          cfe.option[cid].series.push(Template)
+        }
+      }
+      
+      if (typeof window.echarts === 'object') {
+          this.newEChart()
+      }else{
+        const script = document.createElement('script')
+        // #ifdef APP-VUE
+        script.src = './uni_modules/qiun-data-charts/static/app-plus/echarts.min.js'
+        // #endif
+        // #ifdef H5
+        const rooturl = window.location.origin
+        const directory = instance.getDataset().directory
+        script.src = rooturl + directory + 'uni_modules/qiun-data-charts/static/h5/echarts.min.js'
+        // #endif
+        script.onload = this.newEChart
+        document.head.appendChild(script)
+      }
+    },
+    ecresize(newVal, oldVal, owner, instance){
+      if(cfe.instance[this.rid]){
+        cfe.instance[this.rid].resize()
+      }
+    },
+    newEChart(){
+      let cid = this.rid
+      if(cfe.instance[cid] === undefined){
+        cfe.instance[cid] = echarts.init(that[cid].$el.children[0])
+        //ontap开启后才触发click事件
+        if(cfe.option[cid].ontap === true){
+          cfe.instance[cid].on('click', resdata => {
+            let event = JSON.parse(JSON.stringify({
+              x:resdata.event.offsetX,y:resdata.event.offsetY
+            }))
+            that[cid].callMethod('emitMsg',{name:"getIndex", params:{type:"getIndex", event:event, currentIndex:resdata.dataIndex, value:resdata.data, seriesName: resdata.seriesName,id:cid}})
+          })
+          // 增加ECharts的highlight消息,实现按下移动返回索引功能。add by onefish 创建于 2021-12-11 09:50
+          cfe.instance[cid].on('highlight', resdata => {
+            that[cid].callMethod('emitMsg',{name:"getHighlight", params:{type:"highlight", res:resdata, id:cid}})
+          })
+        }
+        this.updataEChart(cid,cfe.option[cid])
+      }else{
+        this.updataEChart(cid,cfe.option[cid])
+      }
+    },
+    updataEChart(cid,option){
+      //替换option内format属性为formatter的预定义方法
+      option = rdformatterAssign(option,cfe.formatter)
+      if(option.tooltip){
+        option.tooltip.show = option.tooltipShow?true:false;
+        option.tooltip.position = this.tooltipPosition()
+        //tooltipFormat方法,替换组件的tooltipFormat为config-echarts.js内对应的方法
+        if (typeof option.tooltipFormat === 'string' && cfe.formatter[option.tooltipFormat]) {
+          option.tooltip.formatter = option.tooltip.formatter ? option.tooltip.formatter : cfe.formatter[option.tooltipFormat]
+        }
+      }
+      // 颜色渐变添加的方法
+      if (option.series) {
+      	for (let i in option.series) {
+      		let linearGradient = option.series[i].linearGradient
+      		if (linearGradient) {
+      			option.series[i].color = new echarts.graphic.LinearGradient(linearGradient[0],linearGradient[1],linearGradient[2],linearGradient[3],linearGradient[4])
+      		}
+      	}
+      }
+      cfe.instance[cid].setOption(option, option.notMerge)
+      cfe.instance[cid].on('finished', function(){
+        that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid}})
+        if(cfe.instance[cid]){
+          cfe.instance[cid].off('finished')
+        }
+      });
+
+      //修复init初始化实例获取宽高不正确问题
+      if(
+        typeof that[cid].$el.children[0].clientWidth != 'undefined' &&
+          (
+            Math.abs( that[cid].$el.children[0].clientWidth - cfe.instance[cid].getWidth() )>3 ||
+            Math.abs( that[cid].$el.children[0].clientHeight - cfe.instance[cid].getHeight() )>3
+          )
+      ){this.ecresize();}
+    },
+    tooltipPosition(){
+      return (point, params, dom, rect, size) => {
+      	let x = point[0]
+      	let y = point[1]
+      	let viewWidth = size.viewSize[0]
+      	let viewHeight = size.viewSize[1]
+      	let boxWidth = size.contentSize[0]
+      	let boxHeight = size.contentSize[1]
+      	let posX = x + 30 
+      	let posY = y + 30 
+      	if (posX + boxWidth > viewWidth) { 
+      		posX = x - boxWidth - 30
+      	}
+      	if (posY + boxHeight > viewHeight) {
+      		posY = y - boxHeight - 30
+      	}
+      	return [posX, posY]
+      }
+    },
+    //==============以下是uCharts的方法====================
+    ucinit(newVal, oldVal, owner, instance){
+      if(JSON.stringify(newVal) == JSON.stringify(oldVal)){
+        return;
+      }
+      if(!newVal.canvasId){
+        return;
+      }
+      let cid = JSON.parse(JSON.stringify(newVal.canvasId))
+      this.rid = cid
+      that[cid] = this.$ownerInstance || instance
+      cfu.option[cid] = JSON.parse(JSON.stringify(newVal))
+      cfu.option[cid] = rdformatterAssign(cfu.option[cid],cfu.formatter)
+      let canvasdom = document.getElementById(cid)
+      if(canvasdom && canvasdom.children[0]){
+        cfu.option[cid].context = canvasdom.children[0].getContext("2d")
+        if(cfu.instance[cid] && cfu.option[cid] && cfu.option[cid].update === true){
+          this.updataUChart()
+        }else{
+          setTimeout(()=>{
+            cfu.option[cid].context.restore();
+            cfu.option[cid].context.save();
+            this.newUChart()
+          },100)
+        }
+      }
+    },
+    newUChart() {
+      let cid = this.rid
+      cfu.instance[cid] = new uChartsRD(cfu.option[cid])
+      cfu.instance[cid].addEventListener('renderComplete', () => {
+        that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid, opts: cfu.instance[cid].opts}})
+        cfu.instance[cid].delEventListener('renderComplete')
+      });
+      cfu.instance[cid].addEventListener('scrollLeft', () => {
+        that[cid].callMethod('emitMsg',{name:"scrollLeft",params:{type:"scrollLeft",scrollLeft:true,id:cid, opts: cfu.instance[cid].opts}})
+      });
+      cfu.instance[cid].addEventListener('scrollRight', () => {
+        that[cid].callMethod('emitMsg',{name:"scrollRight",params:{type:"scrollRight",scrollRight:true,id:cid, opts: cfu.instance[cid].opts}})
+      });
+    },
+    updataUChart() {
+      let cid = this.rid
+      cfu.instance[cid].updateData(cfu.option[cid])
+    },
+    tooltipDefault(item, category, index, opts) {
+      if (category) {
+        let data = item.data
+        if(typeof item.data === "object"){
+          data = item.data.value
+        }
+        return category + ' ' + item.name + ':' + data;
+      } else {
+        if (item.properties && item.properties.name) {
+          return item.properties.name ;
+        } else {
+          return item.name + ':' + item.data;
+        }
+      }
+    },
+    showTooltip(e,cid) {
+      let tc = cfu.option[cid].tooltipCustom
+      if (tc && tc !== undefined && tc !== null) {
+        let offset = undefined;
+        if (tc.x >= 0 && tc.y >= 0) {
+          offset = { x: tc.x, y: tc.y + 10 };
+        }
+        cfu.instance[cid].showToolTip(e, {
+          index: tc.index,
+          offset: offset,
+          textList: tc.textList,
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this.tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      } else {
+        cfu.instance[cid].showToolTip(e, {
+          formatter: (item, category, index, opts) => {
+            if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
+              return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
+            } else {
+              return this.tooltipDefault(item, category, index, opts);
+            }
+          }
+        });
+      }
+    },
+    tap(e) {
+      let cid = this.rid
+      let ontap = cfu.option[cid].ontap
+      let tooltipShow = cfu.option[cid].tooltipShow
+      let tapLegend = cfu.option[cid].tapLegend
+      if(ontap == false) return;
+      let currentIndex=null
+      let legendIndex=null
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      if(e.detail.x){//tap或者click的事件
+        tmpe = { x: e.detail.x - rchartdom.left, y:e.detail.y - rchartdom.top + rootdom.top}
+      }else{//mouse的事件
+        tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      }
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      currentIndex=cfu.instance[cid].getCurrentDataIndex(e)
+      legendIndex=cfu.instance[cid].getLegendDataIndex(e)
+      if(tapLegend === true){
+        cfu.instance[cid].touchLegend(e);
+      }
+      if(tooltipShow==true){
+        this.showTooltip(e,cid)
+      }
+      that[cid].callMethod('emitMsg',{name:"getIndex",params:{type:"getIndex",event:tmpe,currentIndex:currentIndex,legendIndex:legendIndex,id:cid, opts: cfu.instance[cid].opts}})
+    },
+    touchStart(e) {
+      let cid = this.rid
+      let ontouch = cfu.option[cid].ontouch
+      if(ontouch == false) return;
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 1){
+        cfu.instance[cid].scrollStart(e);
+      }
+      that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"touchStart",event:e.changedTouches[0],id:cid, opts: cfu.instance[cid].opts}})
+    },
+    touchMove(e) {
+      let cid = this.rid
+      let ontouch = cfu.option[cid].ontouch
+      if(ontouch == false) return;
+      if(cfu.option[cid].enableScroll === true && e.changedTouches.length == 1){
+        cfu.instance[cid].scroll(e);
+      }
+      if(cfu.option[cid].ontap === true && cfu.option[cid].enableScroll === false && cfu.option[cid].onmovetip === true){
+        let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+        let tmpe = { x: e.changedTouches[0].clientX - rchartdom.left, y:e.changedTouches[0].clientY - rchartdom.top + rootdom.top}
+        e.changedTouches.unshift(tmpe)
+        if(cfu.option[cid].tooltipShow === true){
+          this.showTooltip(e,cid)
+        }
+      }
+      if(ontouch === true && cfu.option[cid].enableScroll === true && cfu.option[cid].onzoom === true && e.changedTouches.length == 2){
+        cfu.instance[cid].dobuleZoom(e);
+      }
+      that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"touchMove",event:e.changedTouches[0],id:cid, opts: cfu.instance[cid].opts}})
+    },
+    touchEnd(e) {
+      let cid = this.rid
+      let ontouch = cfu.option[cid].ontouch
+      if(ontouch == false) return;
+      if(cfu.option[cid].enableScroll === true && e.touches.length == 0){
+        cfu.instance[cid].scrollEnd(e);
+      }
+      that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"touchEnd",event:e.changedTouches[0],id:cid, opts: cfu.instance[cid].opts}})
+    },
+    mouseDown(e) {
+      let cid = this.rid
+      let onmouse = cfu.option[cid].onmouse
+      if(onmouse == false) return;
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      cfu.instance[cid].scrollStart(e)
+      cfu.option[cid].mousedown=true;
+      that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"mouseDown",event:tmpe,id:cid, opts: cfu.instance[cid].opts}})
+    },
+    mouseMove(e) {
+      let cid = this.rid
+      let onmouse = cfu.option[cid].onmouse
+      let tooltipShow = cfu.option[cid].tooltipShow
+      if(onmouse == false) return;
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      if(cfu.option[cid].mousedown){
+        cfu.instance[cid].scroll(e)
+        that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"mouseMove",event:tmpe,id:cid, opts: cfu.instance[cid].opts}})
+      }else if(cfu.instance[cid]){
+        if(tooltipShow==true){
+          this.showTooltip(e,cid)
+        }
+      }
+    },
+    mouseUp(e) {
+      let cid = this.rid
+      let onmouse = cfu.option[cid].onmouse
+      if(onmouse == false) return;
+      let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
+      let tmpe = {}
+      tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
+      e.changedTouches = [];
+      e.changedTouches.unshift(tmpe)
+      cfu.instance[cid].scrollEnd(e)
+      cfu.option[cid].mousedown=false;
+      that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"mouseUp",event:tmpe,id:cid, opts: cfu.instance[cid].opts}})
+    },
+  }
+}
+</script>
+<!-- #endif -->
+
+<style scoped>
+.chartsview {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex: 1;
+  justify-content: center;
+  align-items: center;
+}
+</style>

Файловите разлики са ограничени, защото са твърде много
+ 42 - 0
mine/components/qiun-data-charts/components/qiun-error/qiun-error.vue


+ 162 - 0
mine/components/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
mine/components/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
mine/components/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
mine/components/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
mine/components/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
mine/components/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>

+ 422 - 0
mine/components/qiun-data-charts/js_sdk/u-charts/config-echarts.js

@@ -0,0 +1,422 @@
+/*
+ * 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'];
+
+const cfe = {
+  //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": [],
+		},
+	}
+}
+
+export default cfe;

+ 633 - 0
mine/components/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];
+}
+
+const cfu = {
+  //demotype为自定义图表类型,一般不需要自定义图表类型,只需要改根节点上对应的类型即可
+	"type":["pie","ring","rose","word","funnel","map","arcbar","line","column","mount","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","mount","bar","area","radar","gauge","candle","mix","demotype"],
+  //instance为实例变量承载属性,不要删除
+  "instance":{},
+  //option为opts及eopts承载属性,不要删除
+  "option":{},
+  //下面是自定义format配置,因除H5端外的其他端无法通过props传递函数,只能通过此属性对应下标的方式来替换
+  "formatter":{
+    "yAxisDemo1":function(val, index, opts){return val+'元'},
+    "yAxisDemo2":function(val, index, opts){return val.toFixed(2)},
+    "xAxisDemo1":function(val, index, opts){return val+'年';},
+    "xAxisDemo2":function(val, index, opts){return formatDateTime(val,'h:m')},
+    "seriesDemo1":function(val, index, series, opts){return val+'元'},
+    "tooltipDemo1":function(item, category, index, opts){
+      if(index==0){
+      	return '随便用'+item.data+'年'
+      }else{
+      	return '其他我没改'+item.data+'天'
+      }
+    },
+    "pieDemo":function(val, index, series, opts){
+      if(index !== undefined){
+        return series[index].name+':'+series[index].data+'元'
+      }
+    },
+	// 超出换行
+	"overwarp":function(value){
+		console.log(value,7)
+			var str = "";
+            var num = 2; //每行显示字数
+            var valLength = value.length; //该项x轴字数
+            var rowNum = Math.ceil(valLength / num); // 行数
+			console.log(rowNum)
+            if(rowNum > 1)
+            {
+                for(var i = 0; i < rowNum; i++)
+                {
+                    var temp = "";
+                    var start = i * num;
+                    var end = start + num;
+    
+                    temp = value.substring(start, end) + "\n";
+                    str += temp;
+                }
+    
+                return str;
+            }
+            else
+            {
+                return value;
+            }
+    },
+  },
+  //这里演示了自定义您的图表类型的option,可以随意命名,之后在组件上 type="demotype" 后,组件会调用这个花括号里的option,如果组件上还存在opts参数,会将demotype与opts中option合并后渲染图表。
+  "demotype":{
+    //我这里把曲线图当做了自定义图表类型,您可以根据需要随意指定类型或配置
+    "type": "line",
+    "color": color,
+    "padding": [15,10,0,15],
+    "xAxis": {
+      "disableGrid": true,
+    },
+    "yAxis": {
+      "gridType": "dash",
+      "dashLength": 2,
+    },
+    "legend": {
+    },
+    "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,
+        "activeType": "hollow"
+			},
+		}
+	},
+  "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,
+        "activeType": "hollow"
+  		},
+  	}
+  },
+  "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,
+        "activeType": "hollow"
+  		},
+  	}
+  },
+	"column":{
+		"type": "column",
+    "color": color,
+		"padding": [15,15,0,5],
+		"xAxis": {
+      "disableGrid": true,
+		},
+		"yAxis": {
+      "data":[{"min":0}]
+		},
+		"legend": {
+		},
+		"extra": {
+			"column": {
+				"type": "group",
+				"width": 30,
+				"activeBgColor": "#000000",
+				"activeBgOpacity": 0.08
+			},
+		}
+	},
+  "mount":{
+  	"type": "mount",
+    "color": color,
+  	"padding": [15,15,0,5],
+  	"xAxis": {
+      "disableGrid": true,
+  	},
+  	"yAxis": {
+      "data":[{"min":0}]
+  	},
+  	"legend": {
+  	},
+  	"extra": {
+  		"mount": {
+  			"type": "mount",
+  			"widthRatio": 1.5,
+  		},
+  	}
+  },
+  "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,
+        "activeType": "hollow"
+			},
+		}
+	},
+	"radar":{
+		"type": "radar",
+		"color": color,
+		"padding": [5,5,5,5],
+    "dataLabel": false,
+		"legend": {
+			"show": true,
+			"position": "right",
+      "lineHeight": 25,
+		},
+		"extra": {
+			"radar": {
+				"gridType": "radar",
+				"gridColor": "#CCCCCC",
+				"gridCount": 3,
+				"opacity": 0.2,
+				"max": 200,
+				"labelShow": true
+			},
+		}
+	},
+	"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,
+    	},
+    }
+	}
+}
+
+export default cfu;

+ 5 - 0
mine/components/qiun-data-charts/js_sdk/u-charts/readme.md

@@ -0,0 +1,5 @@
+# uCharts JSSDK说明
+1、如不使用uCharts组件,可直接引用u-charts.js,打包编译后会`自动压缩`,压缩后体积约为`120kb`。
+2、如果120kb的体积仍需压缩,请手到uCharts官网通过在线定制选择您需要的图表。
+3、config-ucharts.js为uCharts组件的用户配置文件,升级前请`自行备份config-ucharts.js`文件,以免被强制覆盖。
+4、config-echarts.js为ECharts组件的用户配置文件,升级前请`自行备份config-echarts.js`文件,以免被强制覆盖。

+ 7706 - 0
mine/components/qiun-data-charts/js_sdk/u-charts/u-charts.js

@@ -0,0 +1,7706 @@
+/*
+ * uCharts (R)
+ * 高性能跨平台图表库,支持H5、APP、小程序(微信/支付宝/百度/头条/QQ/360/快手)、Vue、Taro等支持canvas的框架平台
+ * Copyright (C) 2018-2022 QIUN (R) 秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 复制使用请保留本段注释,感谢支持开源!
+ * 
+ * uCharts (R) 官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ */
+
+'use strict';
+
+var config = {
+  version: 'v2.5.0-20230101',
+  yAxisWidth: 15,
+  xAxisHeight: 22,
+  padding: [10, 10, 10, 10],
+  rotate: false,
+  fontSize: 13,
+  fontColor: '#666666',
+  dataPointShape: ['circle', 'circle', 'circle', 'circle'],
+  color: ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4', '#ea7ccc'],
+  linearColor: ['#0EE2F8', '#2BDCA8', '#FA7D8D', '#EB88E2', '#2AE3A0', '#0EE2F8', '#EB88E2', '#6773E3', '#F78A85'],
+  pieChartLinePadding: 15,
+  pieChartTextPadding: 5,
+  titleFontSize: 20,
+  subtitleFontSize: 15,
+  radarLabelTextMargin: 13,
+};
+
+var assign = function(target, ...varArgs) {
+  if (target == null) {
+    throw new TypeError('[uCharts] Cannot convert undefined or null to object');
+  }
+  if (!varArgs || varArgs.length <= 0) {
+    return target;
+  }
+  // 深度合并对象
+  function deepAssign(obj1, obj2) {
+    for (let key in obj2) {
+      obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" ?
+        deepAssign(obj1[key], obj2[key]) : obj1[key] = obj2[key];
+    }
+    return obj1;
+  }
+  varArgs.forEach(val => {
+    target = deepAssign(target, val);
+  });
+  return target;
+};
+
+var util = {
+  toFixed: function toFixed(num, limit) {
+    limit = limit || 2;
+    if (this.isFloat(num)) {
+      num = num.toFixed(limit);
+    }
+    return num;
+  },
+  isFloat: function isFloat(num) {
+    return num % 1 !== 0;
+  },
+  approximatelyEqual: function approximatelyEqual(num1, num2) {
+    return Math.abs(num1 - num2) < 1e-10;
+  },
+  isSameSign: function isSameSign(num1, num2) {
+    return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
+  },
+  isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
+    return this.isSameSign(p1.x, p2.x);
+  },
+  isCollision: function isCollision(obj1, obj2) {
+    obj1.end = {};
+    obj1.end.x = obj1.start.x + obj1.width;
+    obj1.end.y = obj1.start.y - obj1.height;
+    obj2.end = {};
+    obj2.end.x = obj2.start.x + obj2.width;
+    obj2.end.y = obj2.start.y - obj2.height;
+    var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y < obj1.end.y;
+    return !flag;
+  }
+};
+
+//兼容H5点击事件
+function getH5Offset(e) {
+  e.mp = {
+    changedTouches: []
+  };
+  e.mp.changedTouches.push({
+    x: e.offsetX,
+    y: e.offsetY
+  });
+  return e;
+}
+
+// hex 转 rgba
+function hexToRgb(hexValue, opc) {
+  var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+  var hex = hexValue.replace(rgx, function(m, r, g, b) {
+    return r + r + g + g + b + b;
+  });
+  var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+  var r = parseInt(rgb[1], 16);
+  var g = parseInt(rgb[2], 16);
+  var b = parseInt(rgb[3], 16);
+  return 'rgba(' + r + ',' + g + ',' + b + ',' + opc + ')';
+}
+
+function findRange(num, type, limit) {
+  if (isNaN(num)) {
+    throw new Error('[uCharts] series数据需为Number格式');
+  }
+  limit = limit || 10;
+  type = type ? type : 'upper';
+  var multiple = 1;
+  while (limit < 1) {
+    limit *= 10;
+    multiple *= 10;
+  }
+  if (type === 'upper') {
+    num = Math.ceil(num * multiple);
+  } else {
+    num = Math.floor(num * multiple);
+  }
+  while (num % limit !== 0) {
+    if (type === 'upper') {
+      if (num == num + 1) { //修复数据值过大num++无效的bug by 向日葵 @xrk_jy
+        break;
+      }
+      num++;
+    } else {
+      num--;
+    }
+  }
+  return num / multiple;
+}
+
+function calCandleMA(dayArr, nameArr, colorArr, kdata) {
+  let seriesTemp = [];
+  for (let k = 0; k < dayArr.length; k++) {
+    let seriesItem = {
+      data: [],
+      name: nameArr[k],
+      color: colorArr[k]
+    };
+    for (let i = 0, len = kdata.length; i < len; i++) {
+      if (i < dayArr[k]) {
+        seriesItem.data.push(null);
+        continue;
+      }
+      let sum = 0;
+      for (let j = 0; j < dayArr[k]; j++) {
+        sum += kdata[i - j][1];
+      }
+      seriesItem.data.push(+(sum / dayArr[k]).toFixed(3));
+    }
+    seriesTemp.push(seriesItem);
+  }
+  return seriesTemp;
+}
+
+function calValidDistance(self, distance, chartData, config, opts) {
+  var dataChartAreaWidth = opts.width - opts.area[1] - opts.area[3];
+  var dataChartWidth = chartData.eachSpacing * (opts.chartData.xAxisData.xAxisPoints.length - 1);
+  if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){
+    if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+    dataChartWidth += (opts.extra.mount.widthRatio - 1)*chartData.eachSpacing;
+  }
+  var validDistance = distance;
+  if (distance >= 0) {
+    validDistance = 0;
+    self.uevent.trigger('scrollLeft');
+    self.scrollOption.position = 'left'
+    opts.xAxis.scrollPosition = 'left';
+  } else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
+    validDistance = dataChartAreaWidth - dataChartWidth;
+    self.uevent.trigger('scrollRight');
+    self.scrollOption.position = 'right'
+    opts.xAxis.scrollPosition = 'right';
+  } else {
+    self.scrollOption.position = distance
+    opts.xAxis.scrollPosition = distance;
+  }
+  return validDistance;
+}
+
+function isInAngleRange(angle, startAngle, endAngle) {
+  function adjust(angle) {
+    while (angle < 0) {
+      angle += 2 * Math.PI;
+    }
+    while (angle > 2 * Math.PI) {
+      angle -= 2 * Math.PI;
+    }
+    return angle;
+  }
+  angle = adjust(angle);
+  startAngle = adjust(startAngle);
+  endAngle = adjust(endAngle);
+  if (startAngle > endAngle) {
+    endAngle += 2 * Math.PI;
+    if (angle < startAngle) {
+      angle += 2 * Math.PI;
+    }
+  }
+  return angle >= startAngle && angle <= endAngle;
+}
+
+function createCurveControlPoints(points, i) {
+  function isNotMiddlePoint(points, i) {
+    if (points[i - 1] && points[i + 1]) {
+      return points[i].y >= Math.max(points[i - 1].y, points[i + 1].y) || points[i].y <= Math.min(points[i - 1].y,
+        points[i + 1].y);
+    } else {
+      return false;
+    }
+  }
+  function isNotMiddlePointX(points, i) {
+    if (points[i - 1] && points[i + 1]) {
+      return points[i].x >= Math.max(points[i - 1].x, points[i + 1].x) || points[i].x <= Math.min(points[i - 1].x,
+        points[i + 1].x);
+    } else {
+      return false;
+    }
+  }
+  var a = 0.2;
+  var b = 0.2;
+  var pAx = null;
+  var pAy = null;
+  var pBx = null;
+  var pBy = null;
+  if (i < 1) {
+    pAx = points[0].x + (points[1].x - points[0].x) * a;
+    pAy = points[0].y + (points[1].y - points[0].y) * a;
+  } else {
+    pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
+    pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
+  }
+
+  if (i > points.length - 3) {
+    var last = points.length - 1;
+    pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
+    pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
+  } else {
+    pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
+    pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
+  }
+  if (isNotMiddlePoint(points, i + 1)) {
+    pBy = points[i + 1].y;
+  }
+  if (isNotMiddlePoint(points, i)) {
+    pAy = points[i].y;
+  }
+  if (isNotMiddlePointX(points, i + 1)) {
+    pBx = points[i + 1].x;
+  }
+  if (isNotMiddlePointX(points, i)) {
+    pAx = points[i].x;
+  }
+  if (pAy >= Math.max(points[i].y, points[i + 1].y) || pAy <= Math.min(points[i].y, points[i + 1].y)) {
+    pAy = points[i].y;
+  }
+  if (pBy >= Math.max(points[i].y, points[i + 1].y) || pBy <= Math.min(points[i].y, points[i + 1].y)) {
+    pBy = points[i + 1].y;
+  }
+  if (pAx >= Math.max(points[i].x, points[i + 1].x) || pAx <= Math.min(points[i].x, points[i + 1].x)) {
+    pAx = points[i].x;
+  }
+  if (pBx >= Math.max(points[i].x, points[i + 1].x) || pBx <= Math.min(points[i].x, points[i + 1].x)) {
+    pBx = points[i + 1].x;
+  }
+  return {
+    ctrA: {
+      x: pAx,
+      y: pAy
+    },
+    ctrB: {
+      x: pBx,
+      y: pBy
+    }
+  };
+}
+
+
+function convertCoordinateOrigin(x, y, center) {
+  return {
+    x: center.x + x,
+    y: center.y - y
+  };
+}
+
+function avoidCollision(obj, target) {
+  if (target) {
+    // is collision test
+    while (util.isCollision(obj, target)) {
+      if (obj.start.x > 0) {
+        obj.start.y--;
+      } else if (obj.start.x < 0) {
+        obj.start.y++;
+      } else {
+        if (obj.start.y > 0) {
+          obj.start.y++;
+        } else {
+          obj.start.y--;
+        }
+      }
+    }
+  }
+  return obj;
+}
+
+function fixPieSeries(series, opts, config){
+  let pieSeriesArr = [];
+  if(series.length>0 && series[0].data.constructor.toString().indexOf('Array') > -1){
+    opts._pieSeries_ = series;
+    let oldseries = series[0].data;
+    for (var i = 0; i < oldseries.length; i++) {
+      oldseries[i].formatter = series[0].formatter;
+      oldseries[i].data = oldseries[i].value;
+      pieSeriesArr.push(oldseries[i]);
+    }
+    opts.series = pieSeriesArr;
+  }else{
+    pieSeriesArr = series;
+  }
+  return pieSeriesArr;
+}
+
+function fillSeries(series, opts, config) {
+  var index = 0;
+  for (var i = 0; i < series.length; i++) {
+    let item = series[i];
+    if (!item.color) {
+      item.color = config.color[index];
+      index = (index + 1) % config.color.length;
+    }
+    if (!item.linearIndex) {
+      item.linearIndex = i;
+    }
+    if (!item.index) {
+      item.index = 0;
+    }
+    if (!item.type) {
+      item.type = opts.type;
+    }
+    if (typeof item.show == "undefined") {
+      item.show = true;
+    }
+    if (!item.type) {
+      item.type = opts.type;
+    }
+    if (!item.pointShape) {
+      item.pointShape = "circle";
+    }
+    if (!item.legendShape) {
+      switch (item.type) {
+        case 'line':
+          item.legendShape = "line";
+          break;
+        case 'column':
+        case 'bar':
+          item.legendShape = "rect";
+          break;
+        case 'area':
+        case 'mount':
+          item.legendShape = "triangle";
+          break;
+        default:
+          item.legendShape = "circle";
+      }
+    }
+  }
+  return series;
+}
+
+function fillCustomColor(linearType, customColor, series, config) {
+  var newcolor = customColor || [];
+  if (linearType == 'custom' && newcolor.length == 0 ) {
+    newcolor = config.linearColor;
+  }
+  if (linearType == 'custom' && newcolor.length < series.length) {
+    let chazhi = series.length - newcolor.length;
+    for (var i = 0; i < chazhi; i++) {
+      newcolor.push(config.linearColor[(i + 1) % config.linearColor.length]);
+    }
+  }
+  return newcolor;
+}
+
+function getDataRange(minData, maxData) {
+  var limit = 0;
+  var range = maxData - minData;
+  if (range >= 10000) {
+    limit = 1000;
+  } else if (range >= 1000) {
+    limit = 100;
+  } else if (range >= 100) {
+    limit = 10;
+  } else if (range >= 10) {
+    limit = 5;
+  } else if (range >= 1) {
+    limit = 1;
+  } else if (range >= 0.1) {
+    limit = 0.1;
+  } else if (range >= 0.01) {
+    limit = 0.01;
+  } else if (range >= 0.001) {
+    limit = 0.001;
+  } else if (range >= 0.0001) {
+    limit = 0.0001;
+  } else if (range >= 0.00001) {
+    limit = 0.00001;
+  } else {
+    limit = 0.000001;
+  }
+  return {
+    minRange: findRange(minData, 'lower', limit),
+    maxRange: findRange(maxData, 'upper', limit)
+  };
+}
+
+function measureText(text, fontSize, context) {
+  var width = 0;
+  text = String(text);
+  // #ifdef MP-ALIPAY || MP-BAIDU || APP-NVUE
+  context = false;
+  // #endif
+  if (context !== false && context !== undefined && context.setFontSize && context.measureText) {
+    context.setFontSize(fontSize);
+    return context.measureText(text).width;
+  } else {
+    var text = text.split('');
+    for (let i = 0; i < text.length; i++) {
+      let item = text[i];
+      if (/[a-zA-Z]/.test(item)) {
+        width += 7;
+      } else if (/[0-9]/.test(item)) {
+        width += 5.5;
+      } else if (/\./.test(item)) {
+        width += 2.7;
+      } else if (/-/.test(item)) {
+        width += 3.25;
+      } else if (/:/.test(item)) {
+        width += 2.5;
+      } else if (/[\u4e00-\u9fa5]/.test(item)) {
+        width += 10;
+      } else if (/\(|\)/.test(item)) {
+        width += 3.73;
+      } else if (/\s/.test(item)) {
+        width += 2.5;
+      } else if (/%/.test(item)) {
+        width += 8;
+      } else {
+        width += 10;
+      }
+    }
+    return width * fontSize / 10;
+  }
+}
+
+function dataCombine(series) {
+  return series.reduce(function(a, b) {
+    return (a.data ? a.data : a).concat(b.data);
+  }, []);
+}
+
+function dataCombineStack(series, len) {
+  var sum = new Array(len);
+  for (var j = 0; j < sum.length; j++) {
+    sum[j] = 0;
+  }
+  for (var i = 0; i < series.length; i++) {
+    for (var j = 0; j < sum.length; j++) {
+      sum[j] += series[i].data[j];
+    }
+  }
+  return series.reduce(function(a, b) {
+    return (a.data ? a.data : a).concat(b.data).concat(sum);
+  }, []);
+}
+
+function getTouches(touches, opts, e) {
+  let x, y;
+  if (touches.clientX) {
+    if (opts.rotate) {
+      y = opts.height - touches.clientX * opts.pix;
+      x = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix;
+    } else {
+      x = touches.clientX * opts.pix;
+      y = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pix / 2) * (opts.pix - 1)) * opts.pix;
+    }
+  } else {
+    if (opts.rotate) {
+      y = opts.height - touches.x * opts.pix;
+      x = touches.y * opts.pix;
+    } else {
+      x = touches.x * opts.pix;
+      y = touches.y * opts.pix;
+    }
+  }
+  return {
+    x: x,
+    y: y
+  }
+}
+
+function getSeriesDataItem(series, index, group) {
+  var data = [];
+  var newSeries = [];
+  var indexIsArr = index.constructor.toString().indexOf('Array') > -1;
+  if(indexIsArr){
+    let tempSeries = filterSeries(series);
+    for (var i = 0; i < group.length; i++) {
+      newSeries.push(tempSeries[group[i]]);
+    }
+  }else{
+    newSeries = series;
+  };
+  for (let i = 0; i < newSeries.length; i++) {
+    let item = newSeries[i];
+    let tmpindex = -1;
+    if(indexIsArr){
+      tmpindex = index[i];
+    }else{
+      tmpindex = index;
+    }
+    if (item.data[tmpindex] !== null && typeof item.data[tmpindex] !== 'undefined' && item.show) {
+      let seriesItem = {};
+      seriesItem.color = item.color;
+      seriesItem.type = item.type;
+      seriesItem.style = item.style;
+      seriesItem.pointShape = item.pointShape;
+      seriesItem.disableLegend = item.disableLegend;
+      seriesItem.legendShape = item.legendShape;
+      seriesItem.name = item.name;
+      seriesItem.show = item.show;
+      seriesItem.data = item.formatter ? item.formatter(item.data[tmpindex]) : item.data[tmpindex];
+      data.push(seriesItem);
+    }
+  }
+  return data;
+}
+
+function getMaxTextListLength(list, fontSize, context) {
+  var lengthList = list.map(function(item) {
+    return measureText(item, fontSize, context);
+  });
+  return Math.max.apply(null, lengthList);
+}
+
+function getRadarCoordinateSeries(length) {
+  var eachAngle = 2 * Math.PI / length;
+  var CoordinateSeries = [];
+  for (var i = 0; i < length; i++) {
+    CoordinateSeries.push(eachAngle * i);
+  }
+  return CoordinateSeries.map(function(item) {
+    return -1 * item + Math.PI / 2;
+  });
+}
+
+function getToolTipData(seriesData, opts, index, group, categories) {
+  var option = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
+  var calPoints = opts.chartData.calPoints?opts.chartData.calPoints:[];
+  let points = {};
+  if(group.length > 0){
+    let filterPoints = [];
+    for (let i = 0; i < group.length; i++) {
+      filterPoints.push(calPoints[group[i]])
+    }
+    points = filterPoints[0][index[0]];
+  }else{
+    for (let i = 0; i < calPoints.length; i++) {
+      if(calPoints[i][index]){
+        points = calPoints[i][index];
+        break;
+      }
+    }
+  };
+  var textList = seriesData.map(function(item) {
+    let titleText = null;
+    if (opts.categories && opts.categories.length>0) {
+      titleText = categories[index];
+    };
+    return {
+      text: option.formatter ? option.formatter(item, titleText, index, opts) : item.name + ': ' + item.data,
+      color: item.color,
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+  });
+  var offset = {
+    x: Math.round(points.x),
+    y: Math.round(points.y)
+  };
+  return {
+    textList: textList,
+    offset: offset
+  };
+}
+
+function getMixToolTipData(seriesData, opts, index, categories) {
+  var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
+  var points = opts.chartData.xAxisPoints[index] + opts.chartData.eachSpacing / 2;
+  var textList = seriesData.map(function(item) {
+    return {
+      text: option.formatter ? option.formatter(item, categories[index], index, opts) : item.name + ': ' + item.data,
+      color: item.color,
+      disableLegend: item.disableLegend ? true : false,
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+  });
+  textList = textList.filter(function(item) {
+    if (item.disableLegend !== true) {
+      return item;
+    }
+  });
+  var offset = {
+    x: Math.round(points),
+    y: 0
+  };
+  return {
+    textList: textList,
+    offset: offset
+  };
+}
+
+function getCandleToolTipData(series, seriesData, opts, index, categories, extra) {
+  var option = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
+  var calPoints = opts.chartData.calPoints;
+  let upColor = extra.color.upFill;
+  let downColor = extra.color.downFill;
+  //颜色顺序为开盘,收盘,最低,最高
+  let color = [upColor, upColor, downColor, upColor];
+  var textList = [];
+  seriesData.map(function(item) {
+    if (index == 0) {
+      if (item.data[1] - item.data[0] < 0) {
+        color[1] = downColor;
+      } else {
+        color[1] = upColor;
+      }
+    } else {
+      if (item.data[0] < series[index - 1][1]) {
+        color[0] = downColor;
+      }
+      if (item.data[1] < item.data[0]) {
+        color[1] = downColor;
+      }
+      if (item.data[2] > series[index - 1][1]) {
+        color[2] = upColor;
+      }
+      if (item.data[3] < series[index - 1][1]) {
+        color[3] = downColor;
+      }
+    }
+    let text1 = {
+      text: '开盘:' + item.data[0],
+      color: color[0],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    let text2 = {
+      text: '收盘:' + item.data[1],
+      color: color[1],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    let text3 = {
+      text: '最低:' + item.data[2],
+      color: color[2],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    let text4 = {
+      text: '最高:' + item.data[3],
+      color: color[3],
+      legendShape: opts.extra.tooltip.legendShape == 'auto'? item.legendShape : opts.extra.tooltip.legendShape
+    };
+    textList.push(text1, text2, text3, text4);
+  });
+  var validCalPoints = [];
+  var offset = {
+    x: 0,
+    y: 0
+  };
+  for (let i = 0; i < calPoints.length; i++) {
+    let points = calPoints[i];
+    if (typeof points[index] !== 'undefined' && points[index] !== null) {
+      validCalPoints.push(points[index]);
+    }
+  }
+  offset.x = Math.round(validCalPoints[0][0].x);
+  return {
+    textList: textList,
+    offset: offset
+  };
+}
+
+function filterSeries(series) {
+  let tempSeries = [];
+  for (let i = 0; i < series.length; i++) {
+    if (series[i].show == true) {
+      tempSeries.push(series[i])
+    }
+  }
+  return tempSeries;
+}
+
+function findCurrentIndex(currentPoints, calPoints, opts, config) {
+  var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
+  var current={ index:-1, group:[] };
+  var spacing = opts.chartData.eachSpacing / 2;
+  let xAxisPoints = [];
+  if (calPoints && calPoints.length > 0) {
+    if (!opts.categories) {
+      spacing = 0;
+    }else{
+      for (let i = 1; i < opts.chartData.xAxisPoints.length; i++) {
+        xAxisPoints.push(opts.chartData.xAxisPoints[i] - spacing);
+      }
+      if ((opts.type == 'line' || opts.type == 'area') && opts.xAxis.boundaryGap == 'justify') {
+        xAxisPoints = opts.chartData.xAxisPoints;
+      }
+    }
+    if (isInExactChartArea(currentPoints, opts, config)) {
+      if (!opts.categories) {
+        let timePoints = Array(calPoints.length);
+        for (let i = 0; i < calPoints.length; i++) {
+          timePoints[i] = Array(calPoints[i].length)
+          for (let j = 0; j < calPoints[i].length; j++) {
+            timePoints[i][j] = (Math.abs(calPoints[i][j].x - currentPoints.x));
+          }
+        };
+        let pointValue =  Array(timePoints.length);
+        let pointIndex =  Array(timePoints.length);
+        for (let i = 0; i < timePoints.length; i++) {
+          pointValue[i] = Math.min.apply(null, timePoints[i]);
+          pointIndex[i] = timePoints[i].indexOf(pointValue[i]);
+        }
+        let minValue = Math.min.apply(null, pointValue);
+        current.index = [];
+        for (let i = 0; i < pointValue.length; i++) {
+          if(pointValue[i] == minValue){
+            current.group.push(i);
+            current.index.push(pointIndex[i]);
+          }
+        };
+      }else{
+        xAxisPoints.forEach(function(item, index) {
+          if (currentPoints.x + offset + spacing > item) {
+            current.index = index;
+          }
+        });
+      }
+    }
+  }
+  return current;
+}
+
+function findBarChartCurrentIndex(currentPoints, calPoints, opts, config) {
+  var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
+  var current={ index:-1, group:[] };
+  var spacing = opts.chartData.eachSpacing / 2;
+  let yAxisPoints = opts.chartData.yAxisPoints;
+  if (calPoints && calPoints.length > 0) {
+    if (isInExactChartArea(currentPoints, opts, config)) {
+      yAxisPoints.forEach(function(item, index) {
+        if (currentPoints.y + offset + spacing > item) {
+          current.index = index;
+        }
+      });
+    }
+  }
+  return current;
+}
+
+function findLegendIndex(currentPoints, legendData, opts) {
+  let currentIndex = -1;
+  let gap = 0;
+  if (isInExactLegendArea(currentPoints, legendData.area)) {
+    let points = legendData.points;
+    let index = -1;
+    for (let i = 0, len = points.length; i < len; i++) {
+      let item = points[i];
+      for (let j = 0; j < item.length; j++) {
+        index += 1;
+        let area = item[j]['area'];
+        if (area && currentPoints.x > area[0] - gap && currentPoints.x < area[2] + gap && currentPoints.y > area[1] - gap && currentPoints.y < area[3] + gap) {
+          currentIndex = index;
+          break;
+        }
+      }
+    }
+    return currentIndex;
+  }
+  return currentIndex;
+}
+
+function isInExactLegendArea(currentPoints, area) {
+  return currentPoints.x > area.start.x && currentPoints.x < area.end.x && currentPoints.y > area.start.y && currentPoints.y < area.end.y;
+}
+
+function isInExactChartArea(currentPoints, opts, config) {
+  return currentPoints.x <= opts.width - opts.area[1] + 10 && currentPoints.x >= opts.area[3] - 10 && currentPoints.y >= opts.area[0] && currentPoints.y <= opts.height - opts.area[2];
+}
+
+function findRadarChartCurrentIndex(currentPoints, radarData, count) {
+  var eachAngleArea = 2 * Math.PI / count;
+  var currentIndex = -1;
+  if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) {
+    var fixAngle = function fixAngle(angle) {
+      if (angle < 0) {
+        angle += 2 * Math.PI;
+      }
+      if (angle > 2 * Math.PI) {
+        angle -= 2 * Math.PI;
+      }
+      return angle;
+    };
+    var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x);
+    angle = -1 * angle;
+    if (angle < 0) {
+      angle += 2 * Math.PI;
+    }
+    var angleList = radarData.angleList.map(function(item) {
+      item = fixAngle(-1 * item);
+      return item;
+    });
+    angleList.forEach(function(item, index) {
+      var rangeStart = fixAngle(item - eachAngleArea / 2);
+      var rangeEnd = fixAngle(item + eachAngleArea / 2);
+      if (rangeEnd < rangeStart) {
+        rangeEnd += 2 * Math.PI;
+      }
+      if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <= rangeEnd) {
+        currentIndex = index;
+      }
+    });
+  }
+  return currentIndex;
+}
+
+function findFunnelChartCurrentIndex(currentPoints, funnelData) {
+  var currentIndex = -1;
+  for (var i = 0, len = funnelData.series.length; i < len; i++) {
+    var item = funnelData.series[i];
+    if (currentPoints.x > item.funnelArea[0] && currentPoints.x < item.funnelArea[2] && currentPoints.y > item.funnelArea[1] && currentPoints.y < item.funnelArea[3]) {
+      currentIndex = i;
+      break;
+    }
+  }
+  return currentIndex;
+}
+
+function findWordChartCurrentIndex(currentPoints, wordData) {
+  var currentIndex = -1;
+  for (var i = 0, len = wordData.length; i < len; i++) {
+    var item = wordData[i];
+    if (currentPoints.x > item.area[0] && currentPoints.x < item.area[2] && currentPoints.y > item.area[1] && currentPoints.y < item.area[3]) {
+      currentIndex = i;
+      break;
+    }
+  }
+  return currentIndex;
+}
+
+function findMapChartCurrentIndex(currentPoints, opts) {
+  var currentIndex = -1;
+  var cData = opts.chartData.mapData;
+  var data = opts.series;
+  var tmp = pointToCoordinate(currentPoints.y, currentPoints.x, cData.bounds, cData.scale, cData.xoffset, cData.yoffset);
+  var poi = [tmp.x, tmp.y];
+  for (var i = 0, len = data.length; i < len; i++) {
+    var item = data[i].geometry.coordinates;
+    if (isPoiWithinPoly(poi, item, opts.chartData.mapData.mercator)) {
+      currentIndex = i;
+      break;
+    }
+  }
+  return currentIndex;
+}
+
+function findRoseChartCurrentIndex(currentPoints, pieData, opts) {
+  var currentIndex = -1;
+  var series = getRoseDataPoints(opts._series_, opts.extra.rose.type, pieData.radius, pieData.radius);
+  if (pieData && pieData.center && isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
+    var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
+    angle = -angle;
+    if(opts.extra.rose && opts.extra.rose.offsetAngle){
+      angle = angle - opts.extra.rose.offsetAngle * Math.PI / 180;
+    }
+    for (var i = 0, len = series.length; i < len; i++) {
+      if (isInAngleRange(angle, series[i]._start_, series[i]._start_ + series[i]._rose_proportion_ * 2 * Math.PI)) {
+        currentIndex = i;
+        break;
+      }
+    }
+  }
+  return currentIndex;
+}
+
+function findPieChartCurrentIndex(currentPoints, pieData, opts) {
+  var currentIndex = -1;
+  var series = getPieDataPoints(pieData.series);
+  if (pieData && pieData.center && isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
+    var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
+    angle = -angle;
+    if(opts.extra.pie && opts.extra.pie.offsetAngle){
+      angle = angle - opts.extra.pie.offsetAngle * Math.PI / 180;
+    }
+    if(opts.extra.ring && opts.extra.ring.offsetAngle){
+      angle = angle - opts.extra.ring.offsetAngle * Math.PI / 180;
+    }
+    for (var i = 0, len = series.length; i < len; i++) {
+      if (isInAngleRange(angle, series[i]._start_, series[i]._start_ + series[i]._proportion_ * 2 * Math.PI)) {
+        currentIndex = i;
+        break;
+      }
+    }
+  }
+  return currentIndex;
+}
+
+function isInExactPieChartArea(currentPoints, center, radius) {
+  return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2);
+}
+
+
+function splitPoints(points,eachSeries) {
+  var newPoints = [];
+  var items = [];
+  points.forEach(function(item, index) {
+    if(eachSeries.connectNulls){
+      if (item !== null) {
+        items.push(item);
+      }
+    }else{
+      if (item !== null) {
+        items.push(item);
+      } else {
+        if (items.length) {
+          newPoints.push(items);
+        }
+        items = [];
+      }
+    }
+    
+  });
+  if (items.length) {
+    newPoints.push(items);
+  }
+  return newPoints;
+}
+
+
+function calLegendData(series, opts, config, chartData, context) {
+  let legendData = {
+    area: {
+      start: {
+        x: 0,
+        y: 0
+      },
+      end: {
+        x: 0,
+        y: 0
+      },
+      width: 0,
+      height: 0,
+      wholeWidth: 0,
+      wholeHeight: 0
+    },
+    points: [],
+    widthArr: [],
+    heightArr: []
+  };
+  if (opts.legend.show === false) {
+    chartData.legendData = legendData;
+    return legendData;
+  }
+  let padding = opts.legend.padding * opts.pix;
+  let margin = opts.legend.margin * opts.pix;
+  let fontSize = opts.legend.fontSize ? opts.legend.fontSize * opts.pix : config.fontSize;
+  let shapeWidth = 15 * opts.pix;
+  let shapeRight = 5 * opts.pix;
+  let lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize);
+  if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+    let legendList = [];
+    let widthCount = 0;
+    let widthCountArr = [];
+    let currentRow = [];
+    for (let i = 0; i < series.length; i++) {
+      let item = series[i];
+      const legendText = item.legendText ? item.legendText : item.name;
+      let itemWidth = shapeWidth + shapeRight + measureText(legendText || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix;
+      if (widthCount + itemWidth > opts.width - opts.area[1] - opts.area[3]) {
+        legendList.push(currentRow);
+        widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix);
+        widthCount = itemWidth;
+        currentRow = [item];
+      } else {
+        widthCount += itemWidth;
+        currentRow.push(item);
+      }
+    }
+    if (currentRow.length) {
+      legendList.push(currentRow);
+      widthCountArr.push(widthCount - opts.legend.itemGap * opts.pix);
+      legendData.widthArr = widthCountArr;
+      let legendWidth = Math.max.apply(null, widthCountArr);
+      switch (opts.legend.float) {
+        case 'left':
+          legendData.area.start.x = opts.area[3];
+          legendData.area.end.x = opts.area[3] + legendWidth + 2 * padding;
+          break;
+        case 'right':
+          legendData.area.start.x = opts.width - opts.area[1] - legendWidth - 2 * padding;
+          legendData.area.end.x = opts.width - opts.area[1];
+          break;
+        default:
+          legendData.area.start.x = (opts.width - legendWidth) / 2 - padding;
+          legendData.area.end.x = (opts.width + legendWidth) / 2 + padding;
+      }
+      legendData.area.width = legendWidth + 2 * padding;
+      legendData.area.wholeWidth = legendWidth + 2 * padding;
+      legendData.area.height = legendList.length * lineHeight + 2 * padding;
+      legendData.area.wholeHeight = legendList.length * lineHeight + 2 * padding + 2 * margin;
+      legendData.points = legendList;
+    }
+  } else {
+    let len = series.length;
+    let maxHeight = opts.height - opts.area[0] - opts.area[2] - 2 * margin - 2 * padding;
+    let maxLength = Math.min(Math.floor(maxHeight / lineHeight), len);
+    legendData.area.height = maxLength * lineHeight + padding * 2;
+    legendData.area.wholeHeight = maxLength * lineHeight + padding * 2;
+    switch (opts.legend.float) {
+      case 'top':
+        legendData.area.start.y = opts.area[0] + margin;
+        legendData.area.end.y = opts.area[0] + margin + legendData.area.height;
+        break;
+      case 'bottom':
+        legendData.area.start.y = opts.height - opts.area[2] - margin - legendData.area.height;
+        legendData.area.end.y = opts.height - opts.area[2] - margin;
+        break;
+      default:
+        legendData.area.start.y = (opts.height - legendData.area.height) / 2;
+        legendData.area.end.y = (opts.height + legendData.area.height) / 2;
+    }
+    let lineNum = len % maxLength === 0 ? len / maxLength : Math.floor((len / maxLength) + 1);
+    let currentRow = [];
+    for (let i = 0; i < lineNum; i++) {
+      let temp = series.slice(i * maxLength, i * maxLength + maxLength);
+      currentRow.push(temp);
+    }
+    legendData.points = currentRow;
+    if (currentRow.length) {
+      for (let i = 0; i < currentRow.length; i++) {
+        let item = currentRow[i];
+        let maxWidth = 0;
+        for (let j = 0; j < item.length; j++) {
+          let itemWidth = shapeWidth + shapeRight + measureText(item[j].name || 'undefined', fontSize, context) + opts.legend.itemGap * opts.pix;
+          if (itemWidth > maxWidth) {
+            maxWidth = itemWidth;
+          }
+        }
+        legendData.widthArr.push(maxWidth);
+        legendData.heightArr.push(item.length * lineHeight + padding * 2);
+      }
+      let legendWidth = 0
+      for (let i = 0; i < legendData.widthArr.length; i++) {
+        legendWidth += legendData.widthArr[i];
+      }
+      legendData.area.width = legendWidth - opts.legend.itemGap * opts.pix + 2 * padding;
+      legendData.area.wholeWidth = legendData.area.width + padding;
+    }
+  }
+  switch (opts.legend.position) {
+    case 'top':
+      legendData.area.start.y = opts.area[0] + margin;
+      legendData.area.end.y = opts.area[0] + margin + legendData.area.height;
+      break;
+    case 'bottom':
+      legendData.area.start.y = opts.height - opts.area[2] - legendData.area.height - margin;
+      legendData.area.end.y = opts.height - opts.area[2] - margin;
+      break;
+    case 'left':
+      legendData.area.start.x = opts.area[3];
+      legendData.area.end.x = opts.area[3] + legendData.area.width;
+      break;
+    case 'right':
+      legendData.area.start.x = opts.width - opts.area[1] - legendData.area.width;
+      legendData.area.end.x = opts.width - opts.area[1];
+      break;
+  }
+  chartData.legendData = legendData;
+  return legendData;
+}
+
+function calCategoriesData(categories, opts, config, eachSpacing, context) {
+  var result = {
+    angle: 0,
+    xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix
+  };
+  var fontSize = opts.xAxis.fontSize * opts.pix;
+  var categoriesTextLenth = categories.map(function(item,index) {
+    var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item;
+    return measureText(String(xitem), fontSize, context);
+  });
+  var maxTextLength = Math.max.apply(this, categoriesTextLenth);
+  if (opts.xAxis.rotateLabel == true) {
+    result.angle = opts.xAxis.rotateAngle * Math.PI / 180;
+    let tempHeight = opts.xAxis.marginTop * opts.pix * 2 +  Math.abs(maxTextLength * Math.sin(result.angle))
+    tempHeight = tempHeight < fontSize + opts.xAxis.marginTop * opts.pix * 2 ? tempHeight + opts.xAxis.marginTop * opts.pix * 2 : tempHeight;
+    result.xAxisHeight = tempHeight;
+  }
+  if (opts.enableScroll && opts.xAxis.scrollShow) {
+    result.xAxisHeight += 6 * opts.pix;
+  }
+  if (opts.xAxis.disabled){
+    result.xAxisHeight = 0;
+  }
+  return result;
+}
+
+function getXAxisTextList(series, opts, config, stack) {
+  var index = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;
+  var data;
+  if (stack == 'stack') {
+    data = dataCombineStack(series, opts.categories.length);
+  } else {
+    data = dataCombine(series);
+  }
+  var sorted = [];
+  // remove null from data
+  data = data.filter(function(item) {
+    //return item !== null;
+    if (typeof item === 'object' && item !== null) {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        return item !== null;
+      } else {
+        return item.value !== null;
+      }
+    } else {
+      return item !== null;
+    }
+  });
+  data.map(function(item) {
+    if (typeof item === 'object') {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        if (opts.type == 'candle') {
+          item.map(function(subitem) {
+            sorted.push(subitem);
+          })
+        } else {
+          sorted.push(item[0]);
+        }
+      } else {
+        sorted.push(item.value);
+      }
+    } else {
+      sorted.push(item);
+    }
+  })
+
+  var minData = 0;
+  var maxData = 0;
+  if (sorted.length > 0) {
+    minData = Math.min.apply(this, sorted);
+    maxData = Math.max.apply(this, sorted);
+  }
+  //为了兼容v1.9.0之前的项目
+  if (index > -1) {
+    if (typeof opts.xAxis.data[index].min === 'number') {
+      minData = Math.min(opts.xAxis.data[index].min, minData);
+    }
+    if (typeof opts.xAxis.data[index].max === 'number') {
+      maxData = Math.max(opts.xAxis.data[index].max, maxData);
+    }
+  } else {
+    if (typeof opts.xAxis.min === 'number') {
+      minData = Math.min(opts.xAxis.min, minData);
+    }
+    if (typeof opts.xAxis.max === 'number') {
+      maxData = Math.max(opts.xAxis.max, maxData);
+    }
+  }
+  if (minData === maxData) {
+    var rangeSpan = maxData || 10;
+    maxData += rangeSpan;
+  }
+  //var dataRange = getDataRange(minData, maxData);
+  var minRange = minData;
+  var maxRange = maxData;
+  var range = [];
+  var eachRange = (maxRange - minRange) / opts.xAxis.splitNumber;
+  for (var i = 0; i <= opts.xAxis.splitNumber; i++) {
+    range.push(minRange + eachRange * i);
+  }
+  return range;
+}
+
+function calXAxisData(series, opts, config, context) {
+  //堆叠图重算Y轴
+  var columnstyle = assign({}, {
+    type: ""
+  }, opts.extra.bar);
+  var result = {
+    angle: 0,
+    xAxisHeight: opts.xAxis.lineHeight * opts.pix + opts.xAxis.marginTop * opts.pix
+  };
+  result.ranges = getXAxisTextList(series, opts, config, columnstyle.type);
+  result.rangesFormat = result.ranges.map(function(item) {
+    //item = opts.xAxis.formatter ? opts.xAxis.formatter(item) : util.toFixed(item, 2);
+    item = util.toFixed(item, 2);
+    return item;
+  });
+  var xAxisScaleValues = result.ranges.map(function(item) {
+    // 如果刻度值是浮点数,则保留两位小数
+    item = util.toFixed(item, 2);
+    // 若有自定义格式则调用自定义的格式化函数
+    //item = opts.xAxis.formatter ? opts.xAxis.formatter(Number(item)) : item;
+    return item;
+  });
+  result = Object.assign(result, getXAxisPoints(xAxisScaleValues, opts, config));
+  // 计算X轴刻度的属性譬如每个刻度的间隔,刻度的起始点\结束点以及总长
+  var eachSpacing = result.eachSpacing;
+  var textLength = xAxisScaleValues.map(function(item) {
+    return measureText(item, opts.xAxis.fontSize * opts.pix, context);
+  });
+  if (opts.xAxis.disabled === true) {
+    result.xAxisHeight = 0;
+  }
+  return result;
+}
+
+function getRadarDataPoints(angleList, center, radius, series, opts) {
+  var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+  var radarOption = opts.extra.radar || {};
+  radarOption.max = radarOption.max || 0;
+  var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));
+  var data = [];
+  for (let i = 0; i < series.length; i++) {
+    let each = series[i];
+    let listItem = {};
+    listItem.color = each.color;
+    listItem.legendShape = each.legendShape;
+    listItem.pointShape = each.pointShape;
+    listItem.data = [];
+    each.data.forEach(function(item, index) {
+      let tmp = {};
+      tmp.angle = angleList[index];
+      tmp.proportion = item / maxData;
+      tmp.value = item;
+      tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion * process * Math.sin(tmp.angle), center);
+      listItem.data.push(tmp);
+    });
+    data.push(listItem);
+  }
+  return data;
+}
+
+function getPieDataPoints(series, radius) {
+  var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+  var count = 0;
+  var _start_ = 0;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    count += item.data;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    if (count === 0) {
+      item._proportion_ = 1 / series.length * process;
+    } else {
+      item._proportion_ = item.data / count * process;
+    }
+    item._radius_ = radius;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item._start_ = _start_;
+    _start_ += 2 * item._proportion_ * Math.PI;
+  }
+  return series;
+}
+
+function getFunnelDataPoints(series, radius, option, eachSpacing) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  for (let i = 0; i < series.length; i++) {
+    if(option.type == 'funnel'){
+      series[i].radius = series[i].data / series[0].data * radius * process;
+    }else{
+      series[i].radius =  (eachSpacing * (series.length - i)) / (eachSpacing * series.length) * radius * process;
+    }
+    series[i]._proportion_ = series[i].data / series[0].data;
+  }
+  // if(option.type !== 'pyramid'){
+  //   series.reverse();
+  // }
+  return series;
+}
+
+function getRoseDataPoints(series, type, minRadius, radius) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var count = 0;
+  var _start_ = 0;
+  var dataArr = [];
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    count += item.data;
+    dataArr.push(item.data);
+  }
+  var minData = Math.min.apply(null, dataArr);
+  var maxData = Math.max.apply(null, dataArr);
+  var radiusLength = radius - minRadius;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    if (count === 0) {
+      item._proportion_ = 1 / series.length * process;
+      item._rose_proportion_ = 1 / series.length * process;
+    } else {
+      item._proportion_ = item.data / count * process;
+      if(type == 'area'){
+        item._rose_proportion_ = 1 / series.length * process;
+      }else{
+        item._rose_proportion_ = item.data / count * process;
+      }
+    }
+    item._radius_ = minRadius + radiusLength * ((item.data - minData) / (maxData - minData)) || radius;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item._start_ = _start_;
+    _start_ += 2 * item._rose_proportion_ * Math.PI;
+  }
+  return series;
+}
+
+function getArcbarDataPoints(series, arcbarOption) {
+  var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+  if (process == 1) {
+    process = 0.999999;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    let totalAngle;
+    if (arcbarOption.type == 'circle') {
+      totalAngle = 2;
+    } else {
+      if(arcbarOption.direction == 'ccw'){
+        if (arcbarOption.startAngle < arcbarOption.endAngle) {
+          totalAngle = 2 + arcbarOption.startAngle - arcbarOption.endAngle;
+        } else {
+          totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+        }
+      }else{
+        if (arcbarOption.endAngle < arcbarOption.startAngle) {
+          totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle;
+        } else {
+          totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+        }
+      }
+    }
+    item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
+    if(arcbarOption.direction == 'ccw'){
+      item._proportion_ = arcbarOption.startAngle - totalAngle * item.data * process ;
+    }
+    if (item._proportion_ >= 2) {
+      item._proportion_ = item._proportion_ % 2;
+    }
+  }
+  return series;
+}
+
+function getGaugeArcbarDataPoints(series, arcbarOption) {
+  var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
+  if (process == 1) {
+    process = 0.999999;
+  }
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    let totalAngle;
+    if (arcbarOption.type == 'circle') {
+      totalAngle = 2;
+    } else {
+      if (arcbarOption.endAngle < arcbarOption.startAngle) {
+        totalAngle = 2 + arcbarOption.endAngle - arcbarOption.startAngle;
+      } else {
+        totalAngle = arcbarOption.startAngle - arcbarOption.endAngle;
+      }
+    }
+    item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
+    if (item._proportion_ >= 2) {
+      item._proportion_ = item._proportion_ % 2;
+    }
+  }
+  return series;
+}
+
+function getGaugeAxisPoints(categories, startAngle, endAngle) {
+  let totalAngle;
+  if (endAngle < startAngle) {
+    totalAngle = 2 + endAngle - startAngle;
+  } else {
+    totalAngle = startAngle - endAngle;
+  }
+  let tempStartAngle = startAngle;
+  for (let i = 0; i < categories.length; i++) {
+    categories[i].value = categories[i].value === null ? 0 : categories[i].value;
+    categories[i]._startAngle_ = tempStartAngle;
+    categories[i]._endAngle_ = totalAngle * categories[i].value + startAngle;
+    if (categories[i]._endAngle_ >= 2) {
+      categories[i]._endAngle_ = categories[i]._endAngle_ % 2;
+    }
+    tempStartAngle = categories[i]._endAngle_;
+  }
+  return categories;
+}
+
+function getGaugeDataPoints(series, categories, gaugeOption) {
+  let process = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    item.data = item.data === null ? 0 : item.data;
+    if (gaugeOption.pointer.color == 'auto') {
+      for (let i = 0; i < categories.length; i++) {
+        if (item.data <= categories[i].value) {
+          item.color = categories[i].color;
+          break;
+        }
+      }
+    } else {
+      item.color = gaugeOption.pointer.color;
+    }
+    let totalAngle;
+    if (gaugeOption.endAngle < gaugeOption.startAngle) {
+      totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+    } else {
+      totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+    }
+    item._endAngle_ = totalAngle * item.data + gaugeOption.startAngle;
+    item._oldAngle_ = gaugeOption.oldAngle;
+    if (gaugeOption.oldAngle < gaugeOption.endAngle) {
+      item._oldAngle_ += 2;
+    }
+    if (item.data >= gaugeOption.oldData) {
+      item._proportion_ = (item._endAngle_ - item._oldAngle_) * process + gaugeOption.oldAngle;
+    } else {
+      item._proportion_ = item._oldAngle_ - (item._oldAngle_ - item._endAngle_) * process;
+    }
+    if (item._proportion_ >= 2) {
+      item._proportion_ = item._proportion_ % 2;
+    }
+  }
+  return series;
+}
+
+function getPieTextMaxLength(series, config, context, opts) {
+  series = getPieDataPoints(series);
+  let maxLength = 0;
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    let text = item.formatter ? item.formatter(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
+    maxLength = Math.max(maxLength, measureText(text, item.textSize * opts.pix || config.fontSize, context));
+  }
+  return maxLength;
+}
+
+function fixColumeData(points, eachSpacing, columnLen, index, config, opts) {
+  return points.map(function(item) {
+    if (item === null) {
+      return null;
+    }
+    var seriesGap = 0;
+    var categoryGap = 0;
+    if (opts.type == 'mix') {
+      seriesGap = opts.extra.mix.column.seriesGap * opts.pix || 0;
+      categoryGap = opts.extra.mix.column.categoryGap * opts.pix || 0;
+    } else {
+      seriesGap = opts.extra.column.seriesGap * opts.pix || 0;
+      categoryGap = opts.extra.column.categoryGap * opts.pix || 0;
+    }
+    seriesGap =  Math.min(seriesGap, eachSpacing / columnLen)
+    categoryGap =  Math.min(categoryGap, eachSpacing / columnLen)
+    item.width = Math.ceil((eachSpacing - 2 * categoryGap - seriesGap * (columnLen - 1)) / columnLen);
+    if (opts.extra.mix && opts.extra.mix.column.width && +opts.extra.mix.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.mix.column.width * opts.pix);
+    }
+    if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.column.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    item.x += (index + 0.5 - columnLen / 2) * (item.width + seriesGap);
+    return item;
+  });
+}
+
+function fixBarData(points, eachSpacing, columnLen, index, config, opts) {
+  return points.map(function(item) {
+    if (item === null) {
+      return null;
+    }
+    var seriesGap = 0;
+    var categoryGap = 0;
+    seriesGap = opts.extra.bar.seriesGap * opts.pix || 0;
+    categoryGap = opts.extra.bar.categoryGap * opts.pix || 0;
+    seriesGap =  Math.min(seriesGap, eachSpacing / columnLen)
+    categoryGap =  Math.min(categoryGap, eachSpacing / columnLen)
+    item.width = Math.ceil((eachSpacing - 2 * categoryGap - seriesGap * (columnLen - 1)) / columnLen);
+    if (opts.extra.bar && opts.extra.bar.width && +opts.extra.bar.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.bar.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    item.y += (index + 0.5 - columnLen / 2) * (item.width + seriesGap);
+    return item;
+  });
+}
+
+function fixColumeMeterData(points, eachSpacing, columnLen, index, config, opts, border) {
+  var categoryGap = opts.extra.column.categoryGap * opts.pix || 0;
+  return points.map(function(item) {
+    if (item === null) {
+      return null;
+    }
+    item.width = eachSpacing - 2 * categoryGap;
+    if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.column.width * opts.pix);
+    }
+    if (index > 0) {
+      item.width -= border;
+    }
+    return item;
+  });
+}
+
+function fixColumeStackData(points, eachSpacing, columnLen, index, config, opts, series) {
+  var categoryGap = opts.extra.column.categoryGap * opts.pix || 0;
+  return points.map(function(item, indexn) {
+    if (item === null) {
+      return null;
+    }
+    item.width = Math.ceil(eachSpacing - 2 * categoryGap);
+    if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.column.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    return item;
+  });
+}
+
+function fixBarStackData(points, eachSpacing, columnLen, index, config, opts, series) {
+  var categoryGap = opts.extra.bar.categoryGap * opts.pix || 0;
+  return points.map(function(item, indexn) {
+    if (item === null) {
+      return null;
+    }
+    item.width = Math.ceil(eachSpacing - 2 * categoryGap);
+    if (opts.extra.bar && opts.extra.bar.width && +opts.extra.bar.width > 0) {
+      item.width = Math.min(item.width, +opts.extra.bar.width * opts.pix);
+    }
+    if (item.width <= 0) {
+      item.width = 1;
+    }
+    return item;
+  });
+}
+
+function getXAxisPoints(categories, opts, config) {
+  var spacingValid = opts.width - opts.area[1] - opts.area[3];
+  var dataCount = opts.enableScroll ? Math.min(opts.xAxis.itemCount, categories.length) : categories.length;
+  if ((opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' || opts.type == 'bar') && dataCount > 1 && opts.xAxis.boundaryGap == 'justify') {
+    dataCount -= 1;
+  }
+  var widthRatio = 0;
+  if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){
+    if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+    widthRatio = opts.extra.mount.widthRatio - 1;
+    dataCount += widthRatio;
+  }
+  var eachSpacing = spacingValid / dataCount;
+  var xAxisPoints = [];
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  categories.forEach(function(item, index) {
+    xAxisPoints.push(startX + widthRatio / 2 * eachSpacing + index * eachSpacing);
+  });
+  if (opts.xAxis.boundaryGap !== 'justify') {
+    if (opts.enableScroll === true) {
+      xAxisPoints.push(startX + widthRatio * eachSpacing + categories.length * eachSpacing);
+    } else {
+      xAxisPoints.push(endX);
+    }
+  }
+  return {
+    xAxisPoints: xAxisPoints,
+    startX: startX,
+    endX: endX,
+    eachSpacing: eachSpacing
+  };
+}
+
+function getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
+  var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var cPoints = [];
+      item.forEach(function(items, indexs) {
+        var point = {};
+        point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
+        var value = items.value || items;
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        height *= process;
+        point.y = opts.height - Math.round(height) - opts.area[2];
+        cPoints.push(point);
+      });
+      points.push(cPoints);
+    }
+  });
+  return points;
+}
+
+function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
+  var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+  var boundaryGap = 'center';
+  if (opts.type == 'line' || opts.type == 'area' || opts.type == 'scatter' || opts.type == 'bubble' ) {
+    boundaryGap = opts.xAxis.boundaryGap;
+  }
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index];
+      var value = item;
+      if (typeof item === 'object' && item !== null) {
+        if (item.constructor.toString().indexOf('Array') > -1) {
+          let xranges, xminRange, xmaxRange;
+          xranges = [].concat(opts.chartData.xAxisData.ranges);
+          xminRange = xranges.shift();
+          xmaxRange = xranges.pop();
+          value = item[1];
+          point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+          if(opts.type == 'bubble'){
+            point.r = item[2];
+            point.t = item[3];
+          }
+        } else {
+          value = item.value;
+        }
+      }
+      if (boundaryGap == 'center') {
+        point.x += eachSpacing / 2;
+      }
+      var height = validHeight * (value - minRange) / (maxRange - minRange);
+      height *= process;
+      point.y = opts.height - height - opts.area[2];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process){
+  var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1;
+  var boundaryGap = opts.xAxis.boundaryGap;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      if(lineOption.animation == 'vertical'){
+        point.x = xAxisPoints[index];
+        var value = item;
+        if (typeof item === 'object' && item !== null) {
+          if (item.constructor.toString().indexOf('Array') > -1) {
+            let xranges, xminRange, xmaxRange;
+            xranges = [].concat(opts.chartData.xAxisData.ranges);
+            xminRange = xranges.shift();
+            xmaxRange = xranges.pop();
+            value = item[1];
+            point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+          } else {
+            value = item.value;
+          }
+        }
+        if (boundaryGap == 'center') {
+          point.x += eachSpacing / 2;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        height *= process;
+        point.y = opts.height - height - opts.area[2];
+        points.push(point);
+      }else{
+        point.x = xAxisPoints[0] + eachSpacing * index * process;
+        var value = item;
+        if (boundaryGap == 'center') {
+          point.x += eachSpacing / 2;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        point.y = opts.height - height - opts.area[2];
+        points.push(point);
+      }
+    }
+  });
+  return points;
+}
+
+function getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process){
+  var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index];
+      var value = item;
+      if (typeof item === 'object' && item !== null) {
+        if (item.constructor.toString().indexOf('Array') > -1) {
+          let xranges, xminRange, xmaxRange;
+          xranges = [].concat(opts.chartData.xAxisData.ranges);
+          xminRange = xranges.shift();
+          xmaxRange = xranges.pop();
+          value = item[1];
+          point.x = opts.area[3] + validWidth * (item[0] - xminRange) / (xmaxRange - xminRange);
+        } else {
+          value = item.value;
+        }
+      }
+      point.x += eachSpacing / 2;
+      var height = validHeight * (value * process - minRange) / (maxRange - minRange);
+      point.y = opts.height - height - opts.area[2];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints) {
+  var process = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  var mountWidth = eachSpacing * mountOption.widthRatio;
+  series.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index];
+      point.x += eachSpacing / 2;
+      var value = item.data;
+      var height = validHeight * (value * process - minRange) / (maxRange - minRange);
+      point.y = opts.height - height - opts.area[2];
+      point.value = value;
+      point.width = mountWidth;
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config) {
+  var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  var validWidth = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.y = yAxisPoints[index];
+      var value = item;
+      if (typeof item === 'object' && item !== null) {
+        value = item.value;
+      }
+      var height = validWidth * (value - minRange) / (maxRange - minRange);
+      height *= process;
+      point.height = height;
+      point.value = value;
+      point.x = height + opts.area[3];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) {
+  var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1;
+  var points = [];
+  var validHeight = opts.height - opts.area[0] - opts.area[2];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
+
+      if (seriesIndex > 0) {
+        var value = 0;
+        for (let i = 0; i <= seriesIndex; i++) {
+          value += stackSeries[i].data[index];
+        }
+        var value0 = value - item;
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = validHeight * (value0 - minRange) / (maxRange - minRange);
+      } else {
+        var value = item;
+        if (typeof item === 'object' && item !== null) {
+          value = item.value;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = 0;
+      }
+      var heightc = height0;
+      height *= process;
+      heightc *= process;
+      point.y = opts.height - Math.round(height) - opts.area[2];
+      point.y0 = opts.height - Math.round(heightc) - opts.area[2];
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) {
+  var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1;
+  var points = [];
+  var validHeight = opts.width - opts.area[1] - opts.area[3];
+  data.forEach(function(item, index) {
+    if (item === null) {
+      points.push(null);
+    } else {
+      var point = {};
+      point.color = item.color;
+      point.y = yAxisPoints[index];
+      if (seriesIndex > 0) {
+        var value = 0;
+        for (let i = 0; i <= seriesIndex; i++) {
+          value += stackSeries[i].data[index];
+        }
+        var value0 = value - item;
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = validHeight * (value0 - minRange) / (maxRange - minRange);
+      } else {
+        var value = item;
+        if (typeof item === 'object' && item !== null) {
+          value = item.value;
+        }
+        var height = validHeight * (value - minRange) / (maxRange - minRange);
+        var height0 = 0;
+      }
+      var heightc = height0;
+      height *= process;
+      heightc *= process;
+      point.height = height - heightc;
+      point.x = opts.area[3] + height;
+      point.x0 = opts.area[3] + heightc;
+      points.push(point);
+    }
+  });
+  return points;
+}
+
+function getYAxisTextList(series, opts, config, stack, yData) {
+  var index = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : -1;
+  var data;
+  if (stack == 'stack') {
+    data = dataCombineStack(series, opts.categories.length);
+  } else {
+    data = dataCombine(series);
+  }
+  var sorted = [];
+  // remove null from data
+  data = data.filter(function(item) {
+    //return item !== null;
+    if (typeof item === 'object' && item !== null) {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        return item !== null;
+      } else {
+        return item.value !== null;
+      }
+    } else {
+      return item !== null;
+    }
+  });
+  data.map(function(item) {
+    if (typeof item === 'object') {
+      if (item.constructor.toString().indexOf('Array') > -1) {
+        if (opts.type == 'candle') {
+          item.map(function(subitem) {
+            sorted.push(subitem);
+          })
+        } else {
+          sorted.push(item[1]);
+        }
+      } else {
+        sorted.push(item.value);
+      }
+    } else {
+      sorted.push(item);
+    }
+  })
+  var minData = yData.min || 0;
+  var maxData = yData.max || 0;
+  if (sorted.length > 0) {
+    minData = Math.min.apply(this, sorted);
+    maxData = Math.max.apply(this, sorted);
+  }
+  if (minData === maxData) {
+    if(maxData == 0){
+      maxData = 10;
+    }else{
+      minData = 0;
+    }
+  }
+  var dataRange = getDataRange(minData, maxData);
+  var minRange = (yData.min === undefined || yData.min === null) ? dataRange.minRange : yData.min;
+  var maxRange = (yData.max === undefined || yData.max === null) ? dataRange.maxRange : yData.max;
+  var eachRange = (maxRange - minRange) / opts.yAxis.splitNumber;
+  var range = [];
+  for (var i = 0; i <= opts.yAxis.splitNumber; i++) {
+    range.push(minRange + eachRange * i);
+  }
+  return range.reverse();
+}
+
+function calYAxisData(series, opts, config, context) {
+  //堆叠图重算Y轴
+  var columnstyle = assign({}, {
+    type: ""
+  }, opts.extra.column);
+  //如果是多Y轴,重新计算
+  var YLength = opts.yAxis.data.length;
+  var newSeries = new Array(YLength);
+  if (YLength > 0) {
+    for (let i = 0; i < YLength; i++) {
+      newSeries[i] = [];
+      for (let j = 0; j < series.length; j++) {
+        if (series[j].index == i) {
+          newSeries[i].push(series[j]);
+        }
+      }
+    }
+    var rangesArr = new Array(YLength);
+    var rangesFormatArr = new Array(YLength);
+    var yAxisWidthArr = new Array(YLength);
+
+    for (let i = 0; i < YLength; i++) {
+      let yData = opts.yAxis.data[i];
+      //如果总开关不显示,强制每个Y轴为不显示
+      if (opts.yAxis.disabled == true) {
+        yData.disabled = true;
+      }
+      if(yData.type === 'categories'){
+        if(!yData.formatter){
+          yData.formatter = (val,index,opts) => {return val + (yData.unit || '')};
+        }
+        yData.categories = yData.categories || opts.categories;
+        rangesArr[i] = yData.categories;
+      }else{
+        if(!yData.formatter){
+          yData.formatter = (val,index,opts) => {return util.toFixed(val, yData.tofix || 0) + (yData.unit || '')};
+        }
+        rangesArr[i] = getYAxisTextList(newSeries[i], opts, config, columnstyle.type, yData, i);
+      }
+      let yAxisFontSizes = yData.fontSize * opts.pix || config.fontSize;
+      yAxisWidthArr[i] = {
+        position: yData.position ? yData.position : 'left',
+        width: 0
+      };
+      rangesFormatArr[i] = rangesArr[i].map(function(items,index) {
+        items = yData.formatter(items,index,opts);
+        yAxisWidthArr[i].width = Math.max(yAxisWidthArr[i].width, measureText(items, yAxisFontSizes, context) + 5);
+        return items;
+      });
+      let calibration = yData.calibration ? 4 * opts.pix : 0;
+      yAxisWidthArr[i].width += calibration + 3 * opts.pix;
+      if (yData.disabled === true) {
+        yAxisWidthArr[i].width = 0;
+      }
+    }
+  } else {
+    var rangesArr = new Array(1);
+    var rangesFormatArr = new Array(1);
+    var yAxisWidthArr = new Array(1);
+    if(opts.type === 'bar'){
+      rangesArr[0] = opts.categories;
+      if(!opts.yAxis.formatter){
+        opts.yAxis.formatter = (val,index,opts) => {return val + (opts.yAxis.unit || '')}
+      }
+    }else{
+      if(!opts.yAxis.formatter){
+        opts.yAxis.formatter = (val,index,opts) => {return val.toFixed(opts.yAxis.tofix ) + (opts.yAxis.unit || '')}
+      }
+      rangesArr[0] = getYAxisTextList(series, opts, config, columnstyle.type, {});
+    }
+    yAxisWidthArr[0] = {
+      position: 'left',
+      width: 0
+    };
+    var yAxisFontSize = opts.yAxis.fontSize * opts.pix || config.fontSize;
+    rangesFormatArr[0] = rangesArr[0].map(function(item,index) {
+      item = opts.yAxis.formatter(item,index,opts);
+      yAxisWidthArr[0].width = Math.max(yAxisWidthArr[0].width, measureText(item, yAxisFontSize, context) + 5);
+      return item;
+    });
+    yAxisWidthArr[0].width += 3 * opts.pix;
+    if (opts.yAxis.disabled === true) {
+      yAxisWidthArr[0] = {
+        position: 'left',
+        width: 0
+      };
+      opts.yAxis.data[0] = {
+        disabled: true
+      };
+    } else {
+      opts.yAxis.data[0] = {
+        disabled: false,
+        position: 'left',
+        max: opts.yAxis.max,
+        min: opts.yAxis.min,
+        formatter: opts.yAxis.formatter
+      };
+      if(opts.type === 'bar'){
+        opts.yAxis.data[0].categories = opts.categories;
+        opts.yAxis.data[0].type = 'categories';
+      }
+    }
+  }
+  return {
+    rangesFormat: rangesFormatArr,
+    ranges: rangesArr,
+    yAxisWidth: yAxisWidthArr
+  };
+}
+
+function calTooltipYAxisData(point, series, opts, config, eachSpacing) {
+  let ranges = [].concat(opts.chartData.yAxisData.ranges);
+  let spacingValid = opts.height - opts.area[0] - opts.area[2];
+  let minAxis = opts.area[0];
+  let items = [];
+  for (let i = 0; i < ranges.length; i++) {
+    let maxVal = Math.max.apply(this, ranges[i]);
+    let minVal = Math.min.apply(this, ranges[i]);
+    let item = maxVal - (maxVal - minVal) * (point - minAxis) / spacingValid;
+    item = opts.yAxis.data && opts.yAxis.data[i].formatter ? opts.yAxis.data[i].formatter(item, i, opts) : item.toFixed(0);
+    items.push(String(item))
+  }
+  return items;
+}
+
+function calMarkLineData(points, opts) {
+  let minRange, maxRange;
+  let spacingValid = opts.height - opts.area[0] - opts.area[2];
+  for (let i = 0; i < points.length; i++) {
+    points[i].yAxisIndex = points[i].yAxisIndex ? points[i].yAxisIndex : 0;
+    let range = [].concat(opts.chartData.yAxisData.ranges[points[i].yAxisIndex]);
+    minRange = range.pop();
+    maxRange = range.shift();
+    let height = spacingValid * (points[i].value - minRange) / (maxRange - minRange);
+    points[i].y = opts.height - Math.round(height) - opts.area[2];
+  }
+  return points;
+}
+
+function contextRotate(context, opts) {
+  if (opts.rotateLock !== true) {
+    context.translate(opts.height, 0);
+    context.rotate(90 * Math.PI / 180);
+  } else if (opts._rotate_ !== true) {
+    context.translate(opts.height, 0);
+    context.rotate(90 * Math.PI / 180);
+    opts._rotate_ = true;
+  }
+}
+
+function drawPointShape(points, color, shape, context, opts) {
+  context.beginPath();
+  if (opts.dataPointShapeType == 'hollow') {
+    context.setStrokeStyle(color);
+    context.setFillStyle(opts.background);
+    context.setLineWidth(2 * opts.pix);
+  } else {
+    context.setStrokeStyle("#ffffff");
+    context.setFillStyle(color);
+    context.setLineWidth(1 * opts.pix);
+  }
+  if (shape === 'diamond') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y);
+        context.lineTo(item.x, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'circle') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x + 2.5 * opts.pix, item.y);
+        context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false);
+      }
+    });
+  } else if (shape === 'square') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x - 3.5, item.y - 3.5);
+        context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+      }
+    });
+  } else if (shape === 'triangle') {
+    points.forEach(function(item, index) {
+      if (item !== null) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y + 4.5);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'none') {
+    return;
+  }
+  context.closePath();
+  context.fill();
+  context.stroke();
+}
+
+function drawActivePoint(points, color, shape, context, opts, option, seriesIndex) {
+  if(!opts.tooltip){
+    return
+  }
+  if(opts.tooltip.group.length>0 && opts.tooltip.group.includes(seriesIndex) == false){
+    return
+  }
+  var pointIndex = typeof opts.tooltip.index === 'number' ? opts.tooltip.index : opts.tooltip.index[opts.tooltip.group.indexOf(seriesIndex)];
+  context.beginPath();
+  if (option.activeType == 'hollow') {
+    context.setStrokeStyle(color);
+    context.setFillStyle(opts.background);
+    context.setLineWidth(2 * opts.pix);
+  } else {
+    context.setStrokeStyle("#ffffff");
+    context.setFillStyle(color);
+    context.setLineWidth(1 * opts.pix);
+  }
+  if (shape === 'diamond') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index ) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y);
+        context.lineTo(item.x, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'circle') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index) {
+        context.moveTo(item.x + 2.5 * opts.pix, item.y);
+        context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false);
+      }
+    });
+  } else if (shape === 'square') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index) {
+        context.moveTo(item.x - 3.5, item.y - 3.5);
+        context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+      }
+    });
+  } else if (shape === 'triangle') {
+    points.forEach(function(item, index) {
+      if (item !== null && pointIndex == index) {
+        context.moveTo(item.x, item.y - 4.5);
+        context.lineTo(item.x - 4.5, item.y + 4.5);
+        context.lineTo(item.x + 4.5, item.y + 4.5);
+        context.lineTo(item.x, item.y - 4.5);
+      }
+    });
+  } else if (shape === 'none') {
+    return;
+  }
+  context.closePath();
+  context.fill();
+  context.stroke();
+}
+
+function drawRingTitle(opts, config, context, center) {
+  var titlefontSize = opts.title.fontSize || config.titleFontSize;
+  var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize;
+  var title = opts.title.name || '';
+  var subtitle = opts.subtitle.name || '';
+  var titleFontColor = opts.title.color || opts.fontColor;
+  var subtitleFontColor = opts.subtitle.color || opts.fontColor;
+  var titleHeight = title ? titlefontSize : 0;
+  var subtitleHeight = subtitle ? subtitlefontSize : 0;
+  var margin = 5;
+  if (subtitle) {
+    var textWidth = measureText(subtitle, subtitlefontSize * opts.pix, context);
+    var startX = center.x - textWidth / 2 + (opts.subtitle.offsetX|| 0) * opts.pix ;
+    var startY = center.y + subtitlefontSize * opts.pix / 2 + (opts.subtitle.offsetY || 0) * opts.pix;
+    if (title) {
+      startY += (titleHeight * opts.pix + margin) / 2;
+    }
+    context.beginPath();
+    context.setFontSize(subtitlefontSize * opts.pix);
+    context.setFillStyle(subtitleFontColor);
+    context.fillText(subtitle, startX, startY);
+    context.closePath();
+    context.stroke();
+  }
+  if (title) {
+    var _textWidth = measureText(title, titlefontSize * opts.pix, context);
+    var _startX = center.x - _textWidth / 2 + (opts.title.offsetX || 0);
+    var _startY = center.y + titlefontSize * opts.pix / 2 + (opts.title.offsetY || 0) * opts.pix;
+    if (subtitle) {
+      _startY -= (subtitleHeight * opts.pix + margin) / 2;
+    }
+    context.beginPath();
+    context.setFontSize(titlefontSize * opts.pix);
+    context.setFillStyle(titleFontColor);
+    context.fillText(title, _startX, _startY);
+    context.closePath();
+    context.stroke();
+  }
+}
+
+function drawPointText(points, series, config, context, opts) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series.textColor || opts.fontColor);
+      var value = data[index]
+      if (typeof data[index] === 'object' && data[index] !== null) {
+        if (data[index].constructor.toString().indexOf('Array')>-1) {
+          value = data[index][1];
+        } else {
+          value = data[index].value
+        }
+      }
+      var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value;
+      context.setTextAlign('center');
+      context.fillText(String(formatVal), item.x, item.y - 4 + textOffset * opts.pix);
+      context.closePath();
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  });
+}
+
+function drawColumePointText(points, series, config, context, opts) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  var Position = opts.extra.column.labelPosition;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series.textColor || opts.fontColor);
+      var value = data[index]
+      if (typeof data[index] === 'object' && data[index] !== null) {
+        if (data[index].constructor.toString().indexOf('Array')>-1) {
+          value = data[index][1];
+        } else {
+          value = data[index].value
+        }
+      }
+      var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value;
+      context.setTextAlign('center');
+      var startY = item.y - 4 * opts.pix + textOffset * opts.pix;
+      if(item.y > series.zeroPoints){
+        startY = item.y + textOffset * opts.pix + fontSize;
+      }
+      if(Position == 'insideTop'){
+        startY = item.y + fontSize + textOffset * opts.pix;
+        if(item.y > series.zeroPoints){
+          startY = item.y - textOffset * opts.pix - 4 * opts.pix;
+        }
+      }
+      if(Position == 'center'){
+        startY = item.y + textOffset * opts.pix + (opts.height - opts.area[2] - item.y + fontSize)/2;
+        if(series.zeroPoints < opts.height - opts.area[2]){
+          startY = item.y + textOffset * opts.pix + (series.zeroPoints - item.y + fontSize)/2;
+        }
+        if(item.y > series.zeroPoints){
+          startY = item.y - textOffset * opts.pix - (item.y - series.zeroPoints - fontSize)/2;
+        }
+        if(opts.extra.column.type == 'stack'){
+          startY = item.y + textOffset * opts.pix + (item.y0 - item.y + fontSize)/2;
+        }
+      }
+      if(Position == 'bottom'){
+        startY = opts.height - opts.area[2] + textOffset * opts.pix - 4 * opts.pix;
+        if(series.zeroPoints < opts.height - opts.area[2]){
+          startY = series.zeroPoints + textOffset * opts.pix - 4 * opts.pix;
+        }
+        if(item.y > series.zeroPoints){
+          startY = series.zeroPoints - textOffset * opts.pix + fontSize + 2 * opts.pix;
+        }
+        if(opts.extra.column.type == 'stack'){
+          startY = item.y0 + textOffset * opts.pix - 4 * opts.pix;
+        }
+      }
+      context.fillText(String(formatVal), item.x, startY);
+      context.closePath();
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  });
+}
+
+function drawMountPointText(points, series, config, context, opts, zeroPoints) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  var Position = opts.extra.mount.labelPosition;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series[index].textSize ? series[index].textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series[index].textColor || opts.fontColor);
+      var value = item.value
+      var formatVal = series[index].formatter ? series[index].formatter(value,index,series,opts) : value;
+      context.setTextAlign('center');
+      var startY = item.y - 4 * opts.pix + textOffset * opts.pix;
+      if(item.y > zeroPoints){
+        startY = item.y + textOffset * opts.pix + fontSize;
+      }
+      context.fillText(String(formatVal), item.x, startY);
+      context.closePath();
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  });
+}
+
+function drawBarPointText(points, series, config, context, opts) {
+  // 绘制数据文案
+  var data = series.data;
+  var textOffset = series.textOffset ? series.textOffset : 0;
+  points.forEach(function(item, index) {
+    if (item !== null) {
+      context.beginPath();
+      var fontSize = series.textSize ? series.textSize * opts.pix : config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(series.textColor || opts.fontColor);
+      var value = data[index]
+      if (typeof data[index] === 'object' && data[index] !== null) {
+        value = data[index].value ;
+      }
+      var formatVal = series.formatter ? series.formatter(value,index,series,opts) : value;
+      context.setTextAlign('left');
+      context.fillText(String(formatVal), item.x + 4 * opts.pix , item.y + fontSize / 2 - 3 );
+      context.closePath();
+      context.stroke();
+    }
+  });
+}
+
+function drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context) {
+  radius -= gaugeOption.width / 2 + gaugeOption.labelOffset * opts.pix;
+  radius = radius < 10 ? 10 : radius;
+  let totalAngle;
+  if (gaugeOption.endAngle < gaugeOption.startAngle) {
+    totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+  } else {
+    totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+  }
+  let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+  let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber;
+  let splitNumber = totalNumber / gaugeOption.splitLine.splitNumber;
+  let nowAngle = gaugeOption.startAngle;
+  let nowNumber = gaugeOption.startNumber;
+  for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
+    var pos = {
+      x: radius * Math.cos(nowAngle * Math.PI),
+      y: radius * Math.sin(nowAngle * Math.PI)
+    };
+    var labelText = gaugeOption.formatter ? gaugeOption.formatter(nowNumber,i,opts) : nowNumber;
+    pos.x += centerPosition.x - measureText(labelText, config.fontSize, context) / 2;
+    pos.y += centerPosition.y;
+    var startX = pos.x;
+    var startY = pos.y;
+    context.beginPath();
+    context.setFontSize(config.fontSize);
+    context.setFillStyle(gaugeOption.labelColor || opts.fontColor);
+    context.fillText(labelText, startX, startY + config.fontSize / 2);
+    context.closePath();
+    context.stroke();
+    nowAngle += splitAngle;
+    if (nowAngle >= 2) {
+      nowAngle = nowAngle % 2;
+    }
+    nowNumber += splitNumber;
+  }
+}
+
+function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) {
+  var radarOption = opts.extra.radar || {};
+  angleList.forEach(function(angle, index) {
+    if(radarOption.labelPointShow === true && opts.categories[index] !== ''){
+      var posPoint = {
+        x: radius * Math.cos(angle),
+        y: radius * Math.sin(angle)
+      };
+      var posPointAxis = convertCoordinateOrigin(posPoint.x, posPoint.y, centerPosition);
+      context.setFillStyle(radarOption.labelPointColor);
+      context.beginPath();
+      context.arc(posPointAxis.x, posPointAxis.y, radarOption.labelPointRadius * opts.pix, 0, 2 * Math.PI, false);
+      context.closePath();
+      context.fill();
+    }
+    if(radarOption.labelShow === true){
+      var pos = {
+        x: (radius + config.radarLabelTextMargin * opts.pix) * Math.cos(angle),
+        y: (radius + config.radarLabelTextMargin * opts.pix) * Math.sin(angle)
+      };
+      var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition);
+      var startX = posRelativeCanvas.x;
+      var startY = posRelativeCanvas.y;
+      if (util.approximatelyEqual(pos.x, 0)) {
+        startX -= measureText(opts.categories[index] || '', config.fontSize, context) / 2;
+      } else if (pos.x < 0) {
+        startX -= measureText(opts.categories[index] || '', config.fontSize, context);
+      }
+      context.beginPath();
+      context.setFontSize(config.fontSize);
+      context.setFillStyle(radarOption.labelColor || opts.fontColor);
+      context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2);
+      context.closePath();
+      context.stroke();
+    }
+  });
+
+}
+
+function drawPieText(series, opts, config, context, radius, center) {
+  var lineRadius = config.pieChartLinePadding;
+  var textObjectCollection = [];
+  var lastTextObject = null;
+  var seriesConvert = series.map(function(item,index) {
+    var text = item.formatter ? item.formatter(item,index,series,opts) : util.toFixed(item._proportion_.toFixed(4) * 100) + '%';
+    text = item.labelText ? item.labelText : text;
+    var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2);
+    if (item._rose_proportion_) {
+      arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._rose_proportion_ / 2);
+    }
+    var color = item.color;
+    var radius = item._radius_;
+    return {
+      arc: arc,
+      text: text,
+      color: color,
+      radius: radius,
+      textColor: item.textColor,
+      textSize: item.textSize,
+      labelShow: item.labelShow
+    };
+  });
+  for (let i = 0; i < seriesConvert.length; i++) {
+    let item = seriesConvert[i];
+    // line end
+    let orginX1 = Math.cos(item.arc) * (item.radius + lineRadius);
+    let orginY1 = Math.sin(item.arc) * (item.radius + lineRadius);
+    // line start
+    let orginX2 = Math.cos(item.arc) * item.radius;
+    let orginY2 = Math.sin(item.arc) * item.radius;
+    // text start
+    let orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding;
+    let orginY3 = orginY1;
+    let textWidth = measureText(item.text, item.textSize * opts.pix || config.fontSize, context);
+    let startY = orginY3;
+    if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, {
+        x: orginX3
+      })) {
+      if (orginX3 > 0) {
+        startY = Math.min(orginY3, lastTextObject.start.y);
+      } else if (orginX1 < 0) {
+        startY = Math.max(orginY3, lastTextObject.start.y);
+      } else {
+        if (orginY3 > 0) {
+          startY = Math.max(orginY3, lastTextObject.start.y);
+        } else {
+          startY = Math.min(orginY3, lastTextObject.start.y);
+        }
+      }
+    }
+    if (orginX3 < 0) {
+      orginX3 -= textWidth;
+    }
+    let textObject = {
+      lineStart: {
+        x: orginX2,
+        y: orginY2
+      },
+      lineEnd: {
+        x: orginX1,
+        y: orginY1
+      },
+      start: {
+        x: orginX3,
+        y: startY
+      },
+      width: textWidth,
+      height: config.fontSize,
+      text: item.text,
+      color: item.color,
+      textColor: item.textColor,
+      textSize: item.textSize
+    };
+    lastTextObject = avoidCollision(textObject, lastTextObject);
+    textObjectCollection.push(lastTextObject);
+  }
+  for (let i = 0; i < textObjectCollection.length; i++) {
+    if(seriesConvert[i].labelShow === false){
+      continue;
+    }
+    let item = textObjectCollection[i];
+    let lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center);
+    let lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center);
+    let textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center);
+    context.setLineWidth(1 * opts.pix);
+    context.setFontSize(item.textSize * opts.pix || config.fontSize);
+    context.beginPath();
+    context.setStrokeStyle(item.color);
+    context.setFillStyle(item.color);
+    context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
+    let curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x;
+    let textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5;
+    context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y);
+    context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
+    context.stroke();
+    context.closePath();
+    context.beginPath();
+    context.moveTo(textPosition.x + item.width, textPosition.y);
+    context.arc(curveStartX, textPosition.y, 2 * opts.pix, 0, 2 * Math.PI);
+    context.closePath();
+    context.fill();
+    context.beginPath();
+    context.setFontSize(item.textSize * opts.pix || config.fontSize);
+    context.setFillStyle(item.textColor || opts.fontColor);
+    context.fillText(item.text, textStartX, textPosition.y + 3);
+    context.closePath();
+    context.stroke();
+    context.closePath();
+  }
+}
+
+function drawToolTipSplitLine(offsetX, opts, config, context) {
+  var toolTipOption = opts.extra.tooltip || {};
+  toolTipOption.gridType = toolTipOption.gridType == undefined ? 'solid' : toolTipOption.gridType;
+  toolTipOption.dashLength = toolTipOption.dashLength == undefined ? 4 : toolTipOption.dashLength;
+  var startY = opts.area[0];
+  var endY = opts.height - opts.area[2];
+  if (toolTipOption.gridType == 'dash') {
+    context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
+  }
+  context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
+  context.setLineWidth(1 * opts.pix);
+  context.beginPath();
+  context.moveTo(offsetX, startY);
+  context.lineTo(offsetX, endY);
+  context.stroke();
+  context.setLineDash([]);
+  if (toolTipOption.xAxisLabel) {
+    let labelText = opts.categories[opts.tooltip.index];
+    context.setFontSize(config.fontSize);
+    let textWidth = measureText(labelText, config.fontSize, context);
+    let textX = offsetX - 0.5 * textWidth;
+    let textY = endY + 2 * opts.pix;
+    context.beginPath();
+    context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity));
+    context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
+    context.setLineWidth(1 * opts.pix);
+    context.rect(textX - toolTipOption.boxPadding * opts.pix, textY, textWidth + 2 * toolTipOption.boxPadding * opts.pix, config.fontSize + 2 * toolTipOption.boxPadding * opts.pix);
+    context.closePath();
+    context.stroke();
+    context.fill();
+    context.beginPath();
+    context.setFontSize(config.fontSize);
+    context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor);
+    context.fillText(String(labelText), textX, textY + toolTipOption.boxPadding * opts.pix + config.fontSize);
+    context.closePath();
+    context.stroke();
+  }
+}
+
+function drawMarkLine(opts, config, context) {
+  let markLineOption = assign({}, {
+    type: 'solid',
+    dashLength: 4,
+    data: []
+  }, opts.extra.markLine);
+  let startX = opts.area[3];
+  let endX = opts.width - opts.area[1];
+  let points = calMarkLineData(markLineOption.data, opts);
+  for (let i = 0; i < points.length; i++) {
+    let item = assign({}, {
+      lineColor: '#DE4A42',
+      showLabel: false,
+      labelFontSize: 13,
+      labelPadding: 6,
+      labelFontColor: '#666666',
+      labelBgColor: '#DFE8FF',
+      labelBgOpacity: 0.8,
+      labelAlign: 'left',
+      labelOffsetX: 0,
+      labelOffsetY: 0,
+    }, points[i]);
+    if (markLineOption.type == 'dash') {
+      context.setLineDash([markLineOption.dashLength, markLineOption.dashLength]);
+    }
+    context.setStrokeStyle(item.lineColor);
+    context.setLineWidth(1 * opts.pix);
+    context.beginPath();
+    context.moveTo(startX, item.y);
+    context.lineTo(endX, item.y);
+    context.stroke();
+    context.setLineDash([]);
+    if (item.showLabel) {
+      let fontSize = item.labelFontSize * opts.pix;
+      let labelText = item.labelText ? item.labelText : item.value;
+      context.setFontSize(fontSize);
+      let textWidth = measureText(labelText, fontSize, context);
+      let bgWidth = textWidth + item.labelPadding * opts.pix * 2;
+      let bgStartX = item.labelAlign == 'left' ? opts.area[3] - bgWidth : opts.width - opts.area[1];
+      bgStartX += item.labelOffsetX;
+      let bgStartY = item.y - 0.5 * fontSize - item.labelPadding * opts.pix;
+      bgStartY += item.labelOffsetY;
+      let textX = bgStartX + item.labelPadding * opts.pix;
+      let textY = item.y;
+      context.setFillStyle(hexToRgb(item.labelBgColor, item.labelBgOpacity));
+      context.setStrokeStyle(item.labelBgColor);
+      context.setLineWidth(1 * opts.pix);
+      context.beginPath();
+      context.rect(bgStartX, bgStartY, bgWidth, fontSize + 2 * item.labelPadding * opts.pix);
+      context.closePath();
+      context.stroke();
+      context.fill();
+      context.setFontSize(fontSize);
+      context.setTextAlign('left');
+      context.setFillStyle(item.labelFontColor);
+      context.fillText(String(labelText), textX, bgStartY + fontSize + item.labelPadding * opts.pix/2);
+      context.stroke();
+      context.setTextAlign('left');
+    }
+  }
+}
+
+function drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) {
+  var toolTipOption = assign({}, {
+    gridType: 'solid',
+    dashLength: 4
+  }, opts.extra.tooltip);
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  if (toolTipOption.gridType == 'dash') {
+    context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
+  }
+  context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
+  context.setLineWidth(1 * opts.pix);
+  context.beginPath();
+  context.moveTo(startX, opts.tooltip.offset.y);
+  context.lineTo(endX, opts.tooltip.offset.y);
+  context.stroke();
+  context.setLineDash([]);
+  if (toolTipOption.yAxisLabel) {
+    let boxPadding = toolTipOption.boxPadding * opts.pix;
+    let labelText = calTooltipYAxisData(opts.tooltip.offset.y, opts.series, opts, config, eachSpacing);
+    let widthArr = opts.chartData.yAxisData.yAxisWidth;
+    let tStartLeft = opts.area[3];
+    let tStartRight = opts.width - opts.area[1];
+    for (let i = 0; i < labelText.length; i++) {
+      context.setFontSize(toolTipOption.fontSize * opts.pix);
+      let textWidth = measureText(labelText[i], toolTipOption.fontSize * opts.pix, context);
+      let bgStartX, bgEndX, bgWidth;
+      if (widthArr[i].position == 'left') {
+        bgStartX = tStartLeft - (textWidth + boxPadding * 2) - 2 * opts.pix;
+        bgEndX = Math.max(bgStartX, bgStartX + textWidth + boxPadding * 2);
+      } else {
+        bgStartX = tStartRight + 2 * opts.pix;
+        bgEndX = Math.max(bgStartX + widthArr[i].width, bgStartX + textWidth + boxPadding * 2);
+      }
+      bgWidth = bgEndX - bgStartX;
+      let textX = bgStartX + (bgWidth - textWidth) / 2;
+      let textY = opts.tooltip.offset.y;
+      context.beginPath();
+      context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity || config.toolTipOpacity));
+      context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
+      context.setLineWidth(1 * opts.pix);
+      context.rect(bgStartX, textY - 0.5 * config.fontSize - boxPadding, bgWidth, config.fontSize + 2 * boxPadding);
+      context.closePath();
+      context.stroke();
+      context.fill();
+      context.beginPath();
+      context.setFontSize(config.fontSize);
+      context.setFillStyle(toolTipOption.labelFontColor || opts.fontColor);
+      context.fillText(labelText[i], textX, textY + 0.5 * config.fontSize);
+      context.closePath();
+      context.stroke();
+      if (widthArr[i].position == 'left') {
+        tStartLeft -= (widthArr[i].width + opts.yAxis.padding * opts.pix);
+      } else {
+        tStartRight += widthArr[i].width + opts.yAxis.padding * opts.pix;
+      }
+    }
+  }
+}
+
+function drawToolTipSplitArea(offsetX, opts, config, context, eachSpacing) {
+  var toolTipOption = assign({}, {
+    activeBgColor: '#000000',
+    activeBgOpacity: 0.08,
+    activeWidth: eachSpacing
+  }, opts.extra.column);
+  toolTipOption.activeWidth = toolTipOption.activeWidth > eachSpacing ? eachSpacing : toolTipOption.activeWidth;
+  var startY = opts.area[0];
+  var endY = opts.height - opts.area[2];
+  context.beginPath();
+  context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity));
+  context.rect(offsetX - toolTipOption.activeWidth / 2, startY, toolTipOption.activeWidth, endY - startY);
+  context.closePath();
+  context.fill();
+  context.setFillStyle("#FFFFFF");
+}
+
+function drawBarToolTipSplitArea(offsetX, opts, config, context, eachSpacing) {
+  var toolTipOption = assign({}, {
+    activeBgColor: '#000000',
+    activeBgOpacity: 0.08
+  }, opts.extra.bar);
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  context.beginPath();
+  context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity));
+  context.rect( startX ,offsetX - eachSpacing / 2 ,  endX - startX,eachSpacing);
+  context.closePath();
+  context.fill();
+  context.setFillStyle("#FFFFFF");
+}
+
+
+function drawToolTip(textList, offset, opts, config, context, eachSpacing, xAxisPoints) {
+  var toolTipOption = assign({}, {
+    showBox: true,
+    showArrow: true,
+    showCategory: false,
+    bgColor: '#000000',
+    bgOpacity: 0.7,
+    borderColor: '#000000',
+    borderWidth: 0,
+    borderRadius: 0,
+    borderOpacity: 0.7,
+    boxPadding: 3,
+    fontColor: '#FFFFFF',
+    fontSize: 13,
+    lineHeight: 20,
+    legendShow: true,
+    legendShape: 'auto',
+    splitLine: true,
+  }, opts.extra.tooltip);
+  if(toolTipOption.showCategory==true && opts.categories){
+    textList.unshift({text:opts.categories[opts.tooltip.index],color:null})
+  }
+  var fontSize = toolTipOption.fontSize * opts.pix;
+  var lineHeight = toolTipOption.lineHeight * opts.pix;
+  var boxPadding = toolTipOption.boxPadding * opts.pix;
+  var legendWidth = fontSize;
+  var legendMarginRight = 5 * opts.pix;
+  if(toolTipOption.legendShow == false){
+    legendWidth = 0;
+    legendMarginRight = 0;
+  }
+  var arrowWidth = toolTipOption.showArrow ? 8 * opts.pix : 0;
+  var isOverRightBorder = false;
+  if (opts.type == 'line' || opts.type == 'mount' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') {
+    if (toolTipOption.splitLine == true) {
+      drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
+    }
+  }
+  offset = assign({
+    x: 0,
+    y: 0
+  }, offset);
+  offset.y -= 8 * opts.pix;
+  var textWidth = textList.map(function(item) {
+    return measureText(item.text, fontSize, context);
+  });
+  var toolTipWidth = legendWidth + legendMarginRight + 4 * boxPadding + Math.max.apply(null, textWidth);
+  var toolTipHeight = 2 * boxPadding + textList.length * lineHeight;
+  if (toolTipOption.showBox == false) {
+    return
+  }
+  // if beyond the right border
+  if (offset.x - Math.abs(opts._scrollDistance_ || 0) + arrowWidth + toolTipWidth > opts.width) {
+    isOverRightBorder = true;
+  }
+  if (toolTipHeight + offset.y > opts.height) {
+    offset.y = opts.height - toolTipHeight;
+  }
+  // draw background rect
+  context.beginPath();
+  context.setFillStyle(hexToRgb(toolTipOption.bgColor, toolTipOption.bgOpacity));
+  context.setLineWidth(toolTipOption.borderWidth * opts.pix);
+  context.setStrokeStyle(hexToRgb(toolTipOption.borderColor, toolTipOption.borderOpacity));
+  var radius = toolTipOption.borderRadius;
+  if (isOverRightBorder) {
+    // 增加左侧仍然超出的判断
+    if(toolTipWidth + arrowWidth > opts.width){
+      offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width)
+    }
+    if(toolTipWidth > offset.x){
+      offset.x = opts.width + Math.abs(opts._scrollDistance_ || 0) + arrowWidth + (toolTipWidth - opts.width)
+    }
+    if (toolTipOption.showArrow) {
+      context.moveTo(offset.x, offset.y + 10 * opts.pix);
+      context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix);
+    }
+    context.arc(offset.x - arrowWidth - radius, offset.y + toolTipHeight - radius, radius, 0, Math.PI / 2, false);
+    context.arc(offset.x - arrowWidth - Math.round(toolTipWidth) + radius, offset.y + toolTipHeight - radius, radius,
+      Math.PI / 2, Math.PI, false);
+    context.arc(offset.x - arrowWidth - Math.round(toolTipWidth) + radius, offset.y + radius, radius, -Math.PI, -Math.PI / 2, false);
+    context.arc(offset.x - arrowWidth - radius, offset.y + radius, radius, -Math.PI / 2, 0, false);
+    if (toolTipOption.showArrow) {
+      context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pix - 5 * opts.pix);
+      context.lineTo(offset.x, offset.y + 10 * opts.pix);
+    }
+  } else {
+    if (toolTipOption.showArrow) {
+      context.moveTo(offset.x, offset.y + 10 * opts.pix);
+      context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pix - 5 * opts.pix);
+    }
+    context.arc(offset.x + arrowWidth + radius, offset.y + radius, radius, -Math.PI, -Math.PI / 2, false);
+    context.arc(offset.x + arrowWidth + Math.round(toolTipWidth) - radius, offset.y + radius, radius, -Math.PI / 2, 0,
+      false);
+    context.arc(offset.x + arrowWidth + Math.round(toolTipWidth) - radius, offset.y + toolTipHeight - radius, radius, 0,
+      Math.PI / 2, false);
+    context.arc(offset.x + arrowWidth + radius, offset.y + toolTipHeight - radius, radius, Math.PI / 2, Math.PI, false);
+    if (toolTipOption.showArrow) {
+      context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pix + 5 * opts.pix);
+      context.lineTo(offset.x, offset.y + 10 * opts.pix);
+    }
+  }
+  context.closePath();
+  context.fill();
+  if (toolTipOption.borderWidth > 0) {
+    context.stroke();
+  }
+  // draw legend
+  if(toolTipOption.legendShow){
+    textList.forEach(function(item, index) {
+      if (item.color !== null) {
+        context.beginPath();
+        context.setFillStyle(item.color);
+        var startX = offset.x + arrowWidth + 2 * boxPadding;
+        var startY = offset.y + (lineHeight - fontSize) / 2 + lineHeight * index + boxPadding + 1;
+        if (isOverRightBorder) {
+          startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding;
+        }
+        switch (item.legendShape) {
+          case 'line':
+            context.moveTo(startX, startY + 0.5 * legendWidth - 2 * opts.pix);
+            context.fillRect(startX, startY + 0.5 * legendWidth - 2 * opts.pix, legendWidth, 4 * opts.pix);
+            break;
+          case 'triangle':
+            context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix);
+            context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix);
+            context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            break;
+          case 'diamond':
+            context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * legendWidth);
+            context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth + 5 * opts.pix);
+            context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * legendWidth);
+            context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            break;
+          case 'circle':
+            context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth);
+            context.arc(startX + 7.5 * opts.pix, startY + 0.5 * legendWidth, 5 * opts.pix, 0, 2 * Math.PI);
+            break;
+          case 'rect':
+            context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+            break;
+          case 'square':
+            context.moveTo(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.fillRect(startX + 2 * opts.pix, startY + 0.5 * legendWidth - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix);
+            break;
+          default:
+            context.moveTo(startX, startY + 0.5 * legendWidth - 5 * opts.pix);
+            context.fillRect(startX, startY + 0.5 * legendWidth - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+        }
+        context.closePath();
+        context.fill();
+      }
+    });
+  }
+  
+  // draw text list
+  textList.forEach(function(item, index) {
+    var startX = offset.x + arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight;
+    if (isOverRightBorder) {
+      startX = offset.x - toolTipWidth - arrowWidth + 2 * boxPadding + legendWidth + legendMarginRight;
+    }
+    var startY = offset.y + lineHeight * index + (lineHeight - fontSize)/2 - 1 + boxPadding + fontSize;
+    context.beginPath();
+    context.setFontSize(fontSize);
+    context.setTextBaseline('normal');
+    context.setFillStyle(toolTipOption.fontColor);
+    context.fillText(item.text, startX, startY);
+    context.closePath();
+    context.stroke();
+  });
+}
+
+function drawColumnDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let columnOption = assign({}, {
+    type: 'group',
+    width: eachSpacing / 2,
+    meterBorder: 4,
+    meterFillColor: '#FFFFFF',
+    barBorderCircle: false,
+    barBorderRadius: [],
+    seriesGap: 2,
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+    labelPosition: 'outside'
+  }, opts.extra.column);
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+  }
+  if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+    drawToolTipSplitArea(opts.tooltip.offset.x, opts, config, context, eachSpacing);
+  }
+  columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config);
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    
+    // 计算0轴坐标
+    let spacingValid = opts.height - opts.area[0] - opts.area[2];
+    let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange);
+    let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2];
+    eachSeries.zeroPoints = zeroPoints;
+    var data = eachSeries.data;
+    switch (columnOption.type) {
+      case 'group':
+        var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, zeroPoints, process);
+        var tooltipPoints = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(tooltipPoints);
+        points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          //fix issues/I27B1N yyoinge & Joeshu
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - item.width / 2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color
+            var strokeColor = item.color || eachSeries.color
+            if (columnOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (columnOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+                grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex],columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            // 圆角边框
+            if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) {
+              const left = startX;
+              const top = item.y > zeroPoints ? zeroPoints : item.y;
+              const width = item.width;
+              const height = Math.abs(zeroPoints - item.y);
+              if (columnOption.barBorderCircle) {
+                columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+              }
+              if(item.y > zeroPoints){
+                columnOption.barBorderRadius = [0, 0,width / 2, width / 2];
+              }
+              let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+              let minRadius = Math.min(width/2,height/2);
+              r0 = r0 > minRadius ? minRadius : r0;
+              r1 = r1 > minRadius ? minRadius : r1;
+              r2 = r2 > minRadius ? minRadius : r2;
+              r3 = r3 > minRadius ? minRadius : r3;
+              r0 = r0 < 0 ? 0 : r0;
+              r1 = r1 < 0 ? 0 : r1;
+              r2 = r2 < 0 ? 0 : r2;
+              r3 = r3 < 0 ? 0 : r3;
+              context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+              context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+              context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+              context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+            } else {
+              context.moveTo(startX, item.y);
+              context.lineTo(startX + item.width, item.y);
+              context.lineTo(startX + item.width, zeroPoints);
+              context.lineTo(startX, zeroPoints);
+              context.lineTo(startX, item.y);
+              context.setLineWidth(1)
+              context.setStrokeStyle(strokeColor);
+            }
+            context.setFillStyle(fillColor);
+            context.closePath();
+            //context.stroke();
+            context.fill();
+          }
+        };
+        break;
+      case 'stack':
+        // 绘制堆叠数据图
+        var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(points);
+        points = fixColumeStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color;
+            var startX = item.x - item.width / 2 + 1;
+            var height = opts.height - item.y - opts.area[2];
+            var height0 = opts.height - item.y0 - opts.area[2];
+            if (seriesIndex > 0) {
+              height -= height0;
+            }
+            context.setFillStyle(fillColor);
+            context.moveTo(startX, item.y);
+            context.fillRect(startX, item.y, item.width, height);
+            context.closePath();
+            context.fill();
+          }
+        };
+        break;
+      case 'meter':
+        // 绘制温度计数据图
+        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+        calPoints.push(points);
+        points = fixColumeMeterData(points, eachSpacing, series.length, seriesIndex, config, opts, columnOption.meterBorder);
+          for (let i = 0; i < points.length; i++) {
+            let item = points[i];
+            if (item !== null && i > leftNum && i < rightNum) {
+              //画背景颜色
+              context.beginPath();
+              if (seriesIndex == 0 && columnOption.meterBorder > 0) {
+                context.setStrokeStyle(eachSeries.color);
+                context.setLineWidth(columnOption.meterBorder * opts.pix);
+              }
+              if(seriesIndex == 0){
+                context.setFillStyle(columnOption.meterFillColor);
+              }else{
+                context.setFillStyle(item.color || eachSeries.color);
+              }
+              var startX = item.x - item.width / 2;
+              var height = opts.height - item.y - opts.area[2];
+              if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) {
+                const left = startX;
+                const top = item.y;
+                const width = item.width;
+                const height = zeroPoints - item.y;
+                if (columnOption.barBorderCircle) {
+                  columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+                }
+                let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+                let minRadius = Math.min(width/2,height/2);
+                r0 = r0 > minRadius ? minRadius : r0;
+                r1 = r1 > minRadius ? minRadius : r1;
+                r2 = r2 > minRadius ? minRadius : r2;
+                r3 = r3 > minRadius ? minRadius : r3;
+                r0 = r0 < 0 ? 0 : r0;
+                r1 = r1 < 0 ? 0 : r1;
+                r2 = r2 < 0 ? 0 : r2;
+                r3 = r3 < 0 ? 0 : r3;
+                context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+                context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+                context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+                context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+                context.fill();
+              }else{
+                context.moveTo(startX, item.y);
+                context.lineTo(startX + item.width, item.y);
+                context.lineTo(startX + item.width, zeroPoints);
+                context.lineTo(startX, zeroPoints);
+                context.lineTo(startX, item.y);
+                context.fill();
+              }
+              if (seriesIndex == 0 && columnOption.meterBorder > 0) {
+                context.closePath();
+                context.stroke();
+              }
+            }
+          }
+        break;
+    }
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      switch (columnOption.type) {
+        case 'group':
+          var points = getColumnDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+          points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
+          drawColumePointText(points, eachSeries, config, context, opts);
+          break;
+        case 'stack':
+          var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+          drawColumePointText(points, eachSeries, config, context, opts);
+          break;
+        case 'meter':
+          var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+          drawColumePointText(points, eachSeries, config, context, opts);
+          break;
+      }
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawMountDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let mountOption = assign({}, {
+    type: 'mount',
+    widthRatio: 1,
+    borderWidth: 1,
+    barBorderCircle: false,
+    barBorderRadius: [],
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+  }, opts.extra.mount);
+  mountOption.widthRatio = mountOption.widthRatio <= 0 ? 0 : mountOption.widthRatio;
+  mountOption.widthRatio = mountOption.widthRatio >= 2 ? 2 : mountOption.widthRatio;
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+  }
+  mountOption.customColor = fillCustomColor(mountOption.linearType, mountOption.customColor, series, config);
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[0]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    
+    // 计算0轴坐标
+    let spacingValid = opts.height - opts.area[0] - opts.area[2];
+    let zeroHeight = spacingValid * (0 - minRange) / (maxRange - minRange);
+    let zeroPoints = opts.height - Math.round(zeroHeight) - opts.area[2];
+    
+    var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process);
+    switch (mountOption.type) {
+      case 'bar':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            // 圆角边框
+            if ((mountOption.barBorderRadius && mountOption.barBorderRadius.length === 4) || mountOption.barBorderCircle === true) {
+              const left = startX;
+              const top = item.y > zeroPoints ? zeroPoints : item.y;
+              const width = item.width;
+              const height = Math.abs(zeroPoints - item.y);
+              if (mountOption.barBorderCircle) {
+                mountOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+              }
+              if(item.y > zeroPoints){
+                mountOption.barBorderRadius = [0, 0,width / 2, width / 2];
+              }
+              let [r0, r1, r2, r3] = mountOption.barBorderRadius;
+              let minRadius = Math.min(width/2,height/2);
+              r0 = r0 > minRadius ? minRadius : r0;
+              r1 = r1 > minRadius ? minRadius : r1;
+              r2 = r2 > minRadius ? minRadius : r2;
+              r3 = r3 > minRadius ? minRadius : r3;
+              r0 = r0 < 0 ? 0 : r0;
+              r1 = r1 < 0 ? 0 : r1;
+              r2 = r2 < 0 ? 0 : r2;
+              r3 = r3 < 0 ? 0 : r3;
+              context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+              context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+              context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+              context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+            } else {
+              context.moveTo(startX, item.y);
+              context.lineTo(startX + item.width, item.y);
+              context.lineTo(startX + item.width, zeroPoints);
+              context.lineTo(startX, zeroPoints);
+              context.lineTo(startX, item.y);
+            }
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.closePath();
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+      case 'triangle':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            context.moveTo(startX, zeroPoints);
+            context.lineTo(item.x, item.y);
+            context.lineTo(startX + item.width, zeroPoints);
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+      case 'mount':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            context.moveTo(startX, zeroPoints);
+            context.bezierCurveTo(item.x - item.width/4, zeroPoints, item.x - item.width/4, item.y, item.x, item.y);
+            context.bezierCurveTo(item.x + item.width/4, item.y, item.x + item.width/4, zeroPoints, startX + item.width, zeroPoints);
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+      case 'sharp':
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            var startX = item.x - eachSpacing*mountOption.widthRatio/2;
+            var height = opts.height - item.y - opts.area[2];
+            context.beginPath();
+            var fillColor = item.color || series[i].color
+            var strokeColor = item.color || series[i].color
+            if (mountOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, startX, zeroPoints);
+              //透明渐变
+              if (mountOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(mountOption.customColor[series[i].linearIndex], mountOption.linearOpacity));
+                grd.addColorStop(mountOption.colorStop, hexToRgb(mountOption.customColor[series[i].linearIndex],mountOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            context.moveTo(startX, zeroPoints);
+            context.quadraticCurveTo(item.x - 0, zeroPoints - height/4, item.x, item.y);
+            context.quadraticCurveTo(item.x + 0, zeroPoints - height/4, startX + item.width, zeroPoints)
+            context.setStrokeStyle(strokeColor);
+            context.setFillStyle(fillColor);
+            if(mountOption.borderWidth > 0){
+              context.setLineWidth(mountOption.borderWidth * opts.pix);
+              context.stroke();
+            }
+            context.fill();
+          }
+        };
+        break;
+    }
+
+  if (opts.dataLabel !== false && process === 1) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[0]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var points = getMountDataPoints(series, minRange, maxRange, xAxisPoints, eachSpacing, opts, mountOption, zeroPoints, process);
+    drawMountPointText(points, series, config, context, opts, zeroPoints);
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: points,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawBarDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let yAxisPoints = [];
+  let eachSpacing = (opts.height - opts.area[0] - opts.area[2])/opts.categories.length;
+  for (let i = 0; i < opts.categories.length; i++) {
+    yAxisPoints.push(opts.area[0] + eachSpacing / 2 + eachSpacing * i);
+  }
+  let columnOption = assign({}, {
+    type: 'group',
+    width: eachSpacing / 2,
+    meterBorder: 4,
+    meterFillColor: '#FFFFFF',
+    barBorderCircle: false,
+    barBorderRadius: [],
+    seriesGap: 2,
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+  }, opts.extra.bar);
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = yAxisPoints.length + 2;
+  if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+    drawBarToolTipSplitArea(opts.tooltip.offset.y, opts, config, context, eachSpacing);
+  }
+  columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config);
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.xAxisData.ranges);
+    maxRange = ranges.pop();
+    minRange = ranges.shift();
+    var data = eachSeries.data;
+    switch (columnOption.type) {
+      case 'group':
+        var points = getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, process);
+        var tooltipPoints = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(tooltipPoints);
+        points = fixBarData(points, eachSpacing, series.length, seriesIndex, config, opts);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          //fix issues/I27B1N yyoinge & Joeshu
+          if (item !== null && i > leftNum && i < rightNum) {
+            //var startX = item.x - item.width / 2;
+            var startX = opts.area[3];
+            var startY = item.y - item.width / 2;
+            var height = item.height;
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color
+            var strokeColor = item.color || eachSeries.color
+            if (columnOption.linearType !== 'none') {
+              var grd = context.createLinearGradient(startX, item.y, item.x, item.y);
+              //透明渐变
+              if (columnOption.linearType == 'opacity') {
+                grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              } else {
+                grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+                grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex],columnOption.linearOpacity));
+                grd.addColorStop(1, hexToRgb(fillColor, 1));
+              }
+              fillColor = grd
+            }
+            // 圆角边框
+            if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle === true) {
+              const left = startX;
+              const width = item.width;
+              const top = item.y - item.width / 2;
+              const height = item.height;
+              if (columnOption.barBorderCircle) {
+                columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+              }
+              let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+              let minRadius = Math.min(width/2,height/2);
+              r0 = r0 > minRadius ? minRadius : r0;
+              r1 = r1 > minRadius ? minRadius : r1;
+              r2 = r2 > minRadius ? minRadius : r2;
+              r3 = r3 > minRadius ? minRadius : r3;
+              r0 = r0 < 0 ? 0 : r0;
+              r1 = r1 < 0 ? 0 : r1;
+              r2 = r2 < 0 ? 0 : r2;
+              r3 = r3 < 0 ? 0 : r3;
+              
+              context.arc(left + r3, top + r3, r3, -Math.PI, -Math.PI / 2);
+              context.arc(item.x - r0, top + r0, r0, -Math.PI / 2, 0);
+              context.arc(item.x - r1, top + width - r1, r1, 0, Math.PI / 2);
+              context.arc(left + r2, top + width - r2, r2, Math.PI / 2, Math.PI);
+            } else {
+              context.moveTo(startX, startY);
+              context.lineTo(item.x, startY);
+              context.lineTo(item.x, startY + item.width);
+              context.lineTo(startX, startY + item.width);
+              context.lineTo(startX, startY);
+              context.setLineWidth(1)
+              context.setStrokeStyle(strokeColor);
+            }
+            context.setFillStyle(fillColor);
+            context.closePath();
+            //context.stroke();
+            context.fill();
+          }
+        };
+        break;
+      case 'stack':
+        // 绘制堆叠数据图
+        var points = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+        calPoints.push(points);
+        points = fixBarStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series);
+        for (let i = 0; i < points.length; i++) {
+          let item = points[i];
+          if (item !== null && i > leftNum && i < rightNum) {
+            context.beginPath();
+            var fillColor = item.color || eachSeries.color;
+            var startX = item.x0;
+            context.setFillStyle(fillColor);
+            context.moveTo(startX, item.y - item.width/2);
+            context.fillRect(startX, item.y - item.width/2, item.height , item.width);
+            context.closePath();
+            context.fill();
+          }
+        };
+        break;
+    }
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.xAxisData.ranges);
+      maxRange = ranges.pop();
+      minRange = ranges.shift();
+      var data = eachSeries.data;
+      switch (columnOption.type) {
+        case 'group':
+          var points = getBarDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, process);
+          points = fixBarData(points, eachSpacing, series.length, seriesIndex, config, opts);
+          drawBarPointText(points, eachSeries, config, context, opts);
+          break;
+        case 'stack':
+          var points = getBarStackDataPoints(data, minRange, maxRange, yAxisPoints, eachSpacing, opts, config, seriesIndex, series, process);
+          drawBarPointText(points, eachSeries, config, context, opts);
+          break;
+      }
+    });
+  }
+  return {
+    yAxisPoints: yAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawCandleDataPoints(series, seriesMA, opts, config, context) {
+  var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+  var candleOption = assign({}, {
+    color: {},
+    average: {}
+  }, opts.extra.candle);
+  candleOption.color = assign({}, {
+    upLine: '#f04864',
+    upFill: '#f04864',
+    downLine: '#2fc25b',
+    downFill: '#2fc25b'
+  }, candleOption.color);
+  candleOption.average = assign({}, {
+    show: false,
+    name: [],
+    day: [],
+    color: config.color
+  }, candleOption.average);
+  opts.extra.candle = candleOption;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let calPoints = [];
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  //画均线
+  if (candleOption.average.show || seriesMA) { //Merge pull request !12 from 邱贵翔
+    seriesMA.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      var splitPointList = splitPoints(points,eachSeries);
+      for (let i = 0; i < splitPointList.length; i++) {
+        let points = splitPointList[i];
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setLineWidth(1);
+        if (points.length === 1) {
+          context.moveTo(points[0].x, points[0].y);
+          context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+        } else {
+          context.moveTo(points[0].x, points[0].y);
+          let startPoint = 0;
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              var ctrlPoint = createCurveControlPoints(points, j - 1);
+              context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x,
+                item.y);
+            }
+          }
+          context.moveTo(points[0].x, points[0].y);
+        }
+        context.closePath();
+        context.stroke();
+      }
+    });
+  }
+  //画K线
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    calPoints.push(points);
+    var splitPointList = splitPoints(points,eachSeries);
+    for (let i = 0; i < splitPointList[0].length; i++) {
+      if (i > leftNum && i < rightNum) {
+        let item = splitPointList[0][i];
+        context.beginPath();
+        //如果上涨
+        if (data[i][1] - data[i][0] > 0) {
+          context.setStrokeStyle(candleOption.color.upLine);
+          context.setFillStyle(candleOption.color.upFill);
+          context.setLineWidth(1 * opts.pix);
+          context.moveTo(item[3].x, item[3].y); //顶点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点
+          context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.lineTo(item[2].x, item[2].y); //底点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点
+          context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.moveTo(item[3].x, item[3].y); //顶点
+        } else {
+          context.setStrokeStyle(candleOption.color.downLine);
+          context.setFillStyle(candleOption.color.downFill);
+          context.setLineWidth(1 * opts.pix);
+          context.moveTo(item[3].x, item[3].y); //顶点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.lineTo(item[0].x - eachSpacing / 4, item[0].y); //开盘左侧点
+          context.lineTo(item[1].x - eachSpacing / 4, item[1].y); //收盘左侧点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.lineTo(item[2].x, item[2].y); //底点
+          context.lineTo(item[1].x, item[1].y); //收盘中间点
+          context.lineTo(item[1].x + eachSpacing / 4, item[1].y); //收盘右侧点
+          context.lineTo(item[0].x + eachSpacing / 4, item[0].y); //开盘右侧点
+          context.lineTo(item[0].x, item[0].y); //开盘中间点
+          context.moveTo(item[3].x, item[3].y); //顶点
+        }
+        context.closePath();
+        context.fill();
+        context.stroke();
+      }
+    }
+  });
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawAreaDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var areaOption = assign({}, {
+    type: 'straight',
+    opacity: 0.2,
+    addLine: false,
+    width: 2,
+    gradient: false,
+    activeType: 'none'
+  }, opts.extra.area);
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let endY = opts.height - opts.area[2];
+  let calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    let data = eachSeries.data;
+    let points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    calPoints.push(points);
+    let splitPointList = splitPoints(points,eachSeries);
+    for (let i = 0; i < splitPointList.length; i++) {
+      let points = splitPointList[i];
+      // 绘制区域数
+      context.beginPath();
+      context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+      if (areaOption.gradient) {
+        let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]);
+        gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity));
+        gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+        context.setFillStyle(gradient);
+      } else {
+        context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+      }
+      context.setLineWidth(areaOption.width * opts.pix);
+      if (points.length > 1) {
+        let firstPoint = points[0];
+        let lastPoint = points[points.length - 1];
+        context.moveTo(firstPoint.x, firstPoint.y);
+        let startPoint = 0;
+        if (areaOption.type === 'curve') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              let ctrlPoint = createCurveControlPoints(points, j - 1);
+              context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+            }
+          };
+        } 
+        if (areaOption.type === 'straight') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        if (areaOption.type === 'step') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, points[j - 1].y);
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        context.lineTo(lastPoint.x, endY);
+        context.lineTo(firstPoint.x, endY);
+        context.lineTo(firstPoint.x, firstPoint.y);
+      } else {
+        let item = points[0];
+        context.moveTo(item.x - eachSpacing / 2, item.y);
+        // context.lineTo(item.x + eachSpacing / 2, item.y);
+        // context.lineTo(item.x + eachSpacing / 2, endY);
+        // context.lineTo(item.x - eachSpacing / 2, endY);
+        // context.moveTo(item.x - eachSpacing / 2, item.y);
+      }
+      context.closePath();
+      context.fill();
+      //画连线
+      if (areaOption.addLine) {
+        if (eachSeries.lineType == 'dash') {
+          let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+          dashLength *= opts.pix;
+          context.setLineDash([dashLength, dashLength]);
+        }
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setLineWidth(areaOption.width * opts.pix);
+        if (points.length === 1) {
+          context.moveTo(points[0].x, points[0].y);
+          // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+        } else {
+          context.moveTo(points[0].x, points[0].y);
+          let startPoint = 0;
+          if (areaOption.type === 'curve') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                let ctrlPoint = createCurveControlPoints(points, j - 1);
+                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+              }
+            };
+          }
+          if (areaOption.type === 'straight') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, item.y);
+              }
+            };
+          }
+          if (areaOption.type === 'step') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, points[j - 1].y);
+                context.lineTo(item.x, item.y);
+              }
+            };
+          }
+          context.moveTo(points[0].x, points[0].y);
+        }
+        context.stroke();
+        context.setLineDash([]);
+      }
+    }
+    //画点
+    if (opts.dataPointShape !== false) {
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+    drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, areaOption,seriesIndex);
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      drawPointText(points, eachSeries, config, context, opts);
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawScatterDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var scatterOption = assign({}, {
+    type: 'circle'
+  }, opts.extra.scatter);
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  var calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    context.beginPath();
+    context.setStrokeStyle(eachSeries.color);
+    context.setFillStyle(eachSeries.color);
+    context.setLineWidth(1 * opts.pix);
+    var shape = eachSeries.pointShape;
+    if (shape === 'diamond') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x, item.y - 4.5);
+          context.lineTo(item.x - 4.5, item.y);
+          context.lineTo(item.x, item.y + 4.5);
+          context.lineTo(item.x + 4.5, item.y);
+          context.lineTo(item.x, item.y - 4.5);
+        }
+      });
+    } else if (shape === 'circle') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x + 2.5 * opts.pix, item.y);
+          context.arc(item.x, item.y, 3 * opts.pix, 0, 2 * Math.PI, false);
+        }
+      });
+    } else if (shape === 'square') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x - 3.5, item.y - 3.5);
+          context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
+        }
+      });
+    } else if (shape === 'triangle') {
+      points.forEach(function(item, index) {
+        if (item !== null) {
+          context.moveTo(item.x, item.y - 4.5);
+          context.lineTo(item.x - 4.5, item.y + 4.5);
+          context.lineTo(item.x + 4.5, item.y + 4.5);
+          context.lineTo(item.x, item.y - 4.5);
+        }
+      });
+    } else if (shape === 'triangle') {
+      return;
+    }
+    context.closePath();
+    context.fill();
+    context.stroke();
+  });
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      drawPointText(points, eachSeries, config, context, opts);
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawBubbleDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var bubbleOption = assign({}, {
+    opacity: 1,
+    border:2
+  }, opts.extra.bubble);
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  var calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    context.beginPath();
+    context.setStrokeStyle(eachSeries.color);
+    context.setLineWidth(bubbleOption.border * opts.pix);
+    context.setFillStyle(hexToRgb(eachSeries.color, bubbleOption.opacity));
+    points.forEach(function(item, index) {
+      context.moveTo(item.x + item.r, item.y);
+      context.arc(item.x, item.y, item.r * opts.pix, 0, 2 * Math.PI, false);
+    });
+    context.closePath();
+    context.fill();
+    context.stroke();
+    
+    if (opts.dataLabel !== false && process === 1) {
+      points.forEach(function(item, index) {
+        context.beginPath();
+        var fontSize = eachSeries.textSize * opts.pix || config.fontSize;
+        context.setFontSize(fontSize);
+        context.setFillStyle(eachSeries.textColor || "#FFFFFF");
+        context.setTextAlign('center');
+        context.fillText(String(item.t), item.x, item.y + fontSize/2);
+        context.closePath();
+        context.stroke();
+        context.setTextAlign('left');
+      });
+    }
+  });
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawLineDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var lineOption = assign({}, {
+    type: 'straight',
+    width: 2,
+    activeType: 'none',
+    linearType: 'none',
+    onShadow: false,
+    animation: 'vertical',
+  }, opts.extra.line);
+  lineOption.width *= opts.pix;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  var calPoints = [];
+  context.save();
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  series.forEach(function(eachSeries, seriesIndex) {
+    // 这段很神奇的代码用于解决ios16的setStrokeStyle失效的bug
+    context.beginPath();
+    context.setStrokeStyle(eachSeries.color);
+    context.moveTo(-10000, -10000);
+    context.lineTo(-10001, -10001);
+    context.stroke();
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getLineDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, lineOption, process);
+    calPoints.push(points);
+    var splitPointList = splitPoints(points,eachSeries);
+    if (eachSeries.lineType == 'dash') {
+      let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+      dashLength *= opts.pix;
+      context.setLineDash([dashLength, dashLength]);
+    }
+    context.beginPath();
+    var strokeColor = eachSeries.color;
+    if (lineOption.linearType !== 'none' && eachSeries.linearColor && eachSeries.linearColor.length > 0) {
+      var grd = context.createLinearGradient(opts.chartData.xAxisData.startX, opts.height/2, opts.chartData.xAxisData.endX, opts.height/2);
+      for (var i = 0; i < eachSeries.linearColor.length; i++) {
+        grd.addColorStop(eachSeries.linearColor[i][0], hexToRgb(eachSeries.linearColor[i][1], 1));
+      }
+      strokeColor = grd
+    }
+    context.setStrokeStyle(strokeColor);
+    if (lineOption.onShadow == true && eachSeries.setShadow && eachSeries.setShadow.length > 0) {
+      context.setShadow(eachSeries.setShadow[0], eachSeries.setShadow[1], eachSeries.setShadow[2], eachSeries.setShadow[3]);
+    }else{
+      context.setShadow(0, 0, 0, 'rgba(0,0,0,0)');
+    }
+    context.setLineWidth(lineOption.width);
+    splitPointList.forEach(function(points, index) {
+      if (points.length === 1) {
+        context.moveTo(points[0].x, points[0].y);
+        // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+      } else {
+        context.moveTo(points[0].x, points[0].y);
+        let startPoint = 0;
+        if (lineOption.type === 'curve') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              var ctrlPoint = createCurveControlPoints(points, j - 1);
+              context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+            }
+          };
+        }
+        if (lineOption.type === 'straight') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        if (lineOption.type === 'step') {
+          for (let j = 0; j < points.length; j++) {
+            let item = points[j];
+            if (startPoint == 0 && item.x > leftSpace) {
+              context.moveTo(item.x, item.y);
+              startPoint = 1;
+            }
+            if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+              context.lineTo(item.x, points[j - 1].y);
+              context.lineTo(item.x, item.y);
+            }
+          };
+        }
+        context.moveTo(points[0].x, points[0].y);
+      }
+    });
+    context.stroke();
+    context.setLineDash([]);
+    if (opts.dataPointShape !== false) {
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+    drawActivePoint(points, eachSeries.color, eachSeries.pointShape, context, opts, lineOption);
+  });
+  if (opts.dataLabel !== false && process === 1) {
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      drawPointText(points, eachSeries, config, context, opts);
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing
+  };
+}
+
+function drawMixDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    eachSpacing = xAxisData.eachSpacing;
+  let columnOption = assign({}, {
+    width: eachSpacing / 2,
+    barBorderCircle: false,
+    barBorderRadius: [],
+    seriesGap: 2,
+    linearType: 'none',
+    linearOpacity: 1,
+    customColor: [],
+    colorStop: 0,
+  }, opts.extra.mix.column);
+  let areaOption = assign({}, {
+    opacity: 0.2,
+    gradient: false
+  }, opts.extra.mix.area);
+  let lineOption = assign({}, {
+    width: 2
+  }, opts.extra.mix.line);
+  let endY = opts.height - opts.area[2];
+  let calPoints = [];
+  var columnIndex = 0;
+  var columnLength = 0;
+  series.forEach(function(eachSeries, seriesIndex) {
+    if (eachSeries.type == 'column') {
+      columnLength += 1;
+    }
+  });
+  context.save();
+  let leftNum = -2;
+  let rightNum = xAxisPoints.length + 2;
+  let leftSpace = 0;
+  let rightSpace = opts.width + eachSpacing;
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+    leftNum = Math.floor(-opts._scrollDistance_ / eachSpacing) - 2;
+    rightNum = leftNum + opts.xAxis.itemCount + 4;
+    leftSpace = -opts._scrollDistance_ - eachSpacing * 2 + opts.area[3];
+    rightSpace = leftSpace + (opts.xAxis.itemCount + 4) * eachSpacing;
+  }
+  columnOption.customColor = fillCustomColor(columnOption.linearType, columnOption.customColor, series, config);
+  series.forEach(function(eachSeries, seriesIndex) {
+    let ranges, minRange, maxRange;
+    ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+    minRange = ranges.pop();
+    maxRange = ranges.shift();
+    var data = eachSeries.data;
+    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+    calPoints.push(points);
+    // 绘制柱状数据图
+    if (eachSeries.type == 'column') {
+      points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
+      for (let i = 0; i < points.length; i++) {
+        let item = points[i];
+        if (item !== null && i > leftNum && i < rightNum) {
+          var startX = item.x - item.width / 2;
+          var height = opts.height - item.y - opts.area[2];
+          context.beginPath();
+          var fillColor = item.color || eachSeries.color
+          var strokeColor = item.color || eachSeries.color
+          if (columnOption.linearType !== 'none') {
+            var grd = context.createLinearGradient(startX, item.y, startX, opts.height - opts.area[2]);
+            //透明渐变
+            if (columnOption.linearType == 'opacity') {
+              grd.addColorStop(0, hexToRgb(fillColor, columnOption.linearOpacity));
+              grd.addColorStop(1, hexToRgb(fillColor, 1));
+            } else {
+              grd.addColorStop(0, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+              grd.addColorStop(columnOption.colorStop, hexToRgb(columnOption.customColor[eachSeries.linearIndex], columnOption.linearOpacity));
+              grd.addColorStop(1, hexToRgb(fillColor, 1));
+            }
+            fillColor = grd
+          }
+          // 圆角边框
+          if ((columnOption.barBorderRadius && columnOption.barBorderRadius.length === 4) || columnOption.barBorderCircle) {
+            const left = startX;
+            const top = item.y;
+            const width = item.width;
+            const height = opts.height - opts.area[2] - item.y;
+            if (columnOption.barBorderCircle) {
+              columnOption.barBorderRadius = [width / 2, width / 2, 0, 0];
+            }
+            let [r0, r1, r2, r3] = columnOption.barBorderRadius;
+            let minRadius = Math.min(width/2,height/2);
+            r0 = r0 > minRadius ? minRadius : r0;
+            r1 = r1 > minRadius ? minRadius : r1;
+            r2 = r2 > minRadius ? minRadius : r2;
+            r3 = r3 > minRadius ? minRadius : r3;
+            r0 = r0 < 0 ? 0 : r0;
+            r1 = r1 < 0 ? 0 : r1;
+            r2 = r2 < 0 ? 0 : r2;
+            r3 = r3 < 0 ? 0 : r3;
+            context.arc(left + r0, top + r0, r0, -Math.PI, -Math.PI / 2);
+            context.arc(left + width - r1, top + r1, r1, -Math.PI / 2, 0);
+            context.arc(left + width - r2, top + height - r2, r2, 0, Math.PI / 2);
+            context.arc(left + r3, top + height - r3, r3, Math.PI / 2, Math.PI);
+          } else {
+            context.moveTo(startX, item.y);
+            context.lineTo(startX + item.width, item.y);
+            context.lineTo(startX + item.width, opts.height - opts.area[2]);
+            context.lineTo(startX, opts.height - opts.area[2]);
+            context.lineTo(startX, item.y);
+            context.setLineWidth(1)
+            context.setStrokeStyle(strokeColor);
+          }
+          context.setFillStyle(fillColor);
+          context.closePath();
+          context.fill();
+        }
+      }
+      columnIndex += 1;
+    }
+    //绘制区域图数据
+    if (eachSeries.type == 'area') {
+      let splitPointList = splitPoints(points,eachSeries);
+      for (let i = 0; i < splitPointList.length; i++) {
+        let points = splitPointList[i];
+        // 绘制区域数据
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+        if (areaOption.gradient) {
+          let gradient = context.createLinearGradient(0, opts.area[0], 0, opts.height - opts.area[2]);
+          gradient.addColorStop('0', hexToRgb(eachSeries.color, areaOption.opacity));
+          gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+          context.setFillStyle(gradient);
+        } else {
+          context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity));
+        }
+        context.setLineWidth(2 * opts.pix);
+        if (points.length > 1) {
+          var firstPoint = points[0];
+          let lastPoint = points[points.length - 1];
+          context.moveTo(firstPoint.x, firstPoint.y);
+          let startPoint = 0;
+          if (eachSeries.style === 'curve') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                var ctrlPoint = createCurveControlPoints(points, j - 1);
+                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item.y);
+              }
+            };
+          } else {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, item.y);
+              }
+            };
+          }
+          context.lineTo(lastPoint.x, endY);
+          context.lineTo(firstPoint.x, endY);
+          context.lineTo(firstPoint.x, firstPoint.y);
+        } else {
+          let item = points[0];
+          context.moveTo(item.x - eachSpacing / 2, item.y);
+          // context.lineTo(item.x + eachSpacing / 2, item.y);
+          // context.lineTo(item.x + eachSpacing / 2, endY);
+          // context.lineTo(item.x - eachSpacing / 2, endY);
+          // context.moveTo(item.x - eachSpacing / 2, item.y);
+        }
+        context.closePath();
+        context.fill();
+      }
+    }
+    // 绘制折线数据图
+    if (eachSeries.type == 'line') {
+      var splitPointList = splitPoints(points,eachSeries);
+      splitPointList.forEach(function(points, index) {
+        if (eachSeries.lineType == 'dash') {
+          let dashLength = eachSeries.dashLength ? eachSeries.dashLength : 8;
+          dashLength *= opts.pix;
+          context.setLineDash([dashLength, dashLength]);
+        }
+        context.beginPath();
+        context.setStrokeStyle(eachSeries.color);
+        context.setLineWidth(lineOption.width * opts.pix);
+        if (points.length === 1) {
+          context.moveTo(points[0].x, points[0].y);
+          // context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
+        } else {
+          context.moveTo(points[0].x, points[0].y);
+          let startPoint = 0;
+          if (eachSeries.style == 'curve') {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                var ctrlPoint = createCurveControlPoints(points, j - 1);
+                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y,
+                  item.x, item.y);
+              }
+            }
+          } else {
+            for (let j = 0; j < points.length; j++) {
+              let item = points[j];
+              if (startPoint == 0 && item.x > leftSpace) {
+                context.moveTo(item.x, item.y);
+                startPoint = 1;
+              }
+              if (j > 0 && item.x > leftSpace && item.x < rightSpace) {
+                context.lineTo(item.x, item.y);
+              }
+            }
+          }
+          context.moveTo(points[0].x, points[0].y);
+        }
+        context.stroke();
+        context.setLineDash([]);
+      });
+    }
+    // 绘制点数据图
+    if (eachSeries.type == 'point') {
+      eachSeries.addPoint = true;
+    }
+    if (eachSeries.addPoint == true && eachSeries.type !== 'column') {
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+  });
+  if (opts.dataLabel !== false && process === 1) {
+    var columnIndex = 0;
+    series.forEach(function(eachSeries, seriesIndex) {
+      let ranges, minRange, maxRange;
+      ranges = [].concat(opts.chartData.yAxisData.ranges[eachSeries.index]);
+      minRange = ranges.pop();
+      maxRange = ranges.shift();
+      var data = eachSeries.data;
+      var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
+      if (eachSeries.type !== 'column') {
+        drawPointText(points, eachSeries, config, context, opts);
+      } else {
+        points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
+        drawPointText(points, eachSeries, config, context, opts);
+        columnIndex += 1;
+      }
+    });
+  }
+  context.restore();
+  return {
+    xAxisPoints: xAxisPoints,
+    calPoints: calPoints,
+    eachSpacing: eachSpacing,
+  }
+}
+
+
+function drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints) {
+  var toolTipOption = opts.extra.tooltip || {};
+  if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' || opts.type == 'column' || opts.type == 'mount' || opts.type == 'candle' || opts.type == 'mix')) {
+    drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints)
+  }
+  context.save();
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
+    context.translate(opts._scrollDistance_, 0);
+  }
+  if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
+    drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context, eachSpacing, xAxisPoints);
+  }
+  context.restore();
+
+}
+
+function drawXAxis(categories, opts, config, context) {
+
+  let xAxisData = opts.chartData.xAxisData,
+    xAxisPoints = xAxisData.xAxisPoints,
+    startX = xAxisData.startX,
+    endX = xAxisData.endX,
+    eachSpacing = xAxisData.eachSpacing;
+  var boundaryGap = 'center';
+  if (opts.type == 'bar' || opts.type == 'line' || opts.type == 'area'|| opts.type == 'scatter' || opts.type == 'bubble') {
+    boundaryGap = opts.xAxis.boundaryGap;
+  }
+  var startY = opts.height - opts.area[2];
+  var endY = opts.area[0];
+
+  //绘制滚动条
+  if (opts.enableScroll && opts.xAxis.scrollShow) {
+    var scrollY = opts.height - opts.area[2] + config.xAxisHeight;
+    var scrollScreenWidth = endX - startX;
+    var scrollTotalWidth = eachSpacing * (xAxisPoints.length - 1);
+    if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1){
+      if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+      scrollTotalWidth += (opts.extra.mount.widthRatio - 1)*eachSpacing;
+    }
+    var scrollWidth = scrollScreenWidth * scrollScreenWidth / scrollTotalWidth;
+    var scrollLeft = 0;
+    if (opts._scrollDistance_) {
+      scrollLeft = -opts._scrollDistance_ * (scrollScreenWidth) / scrollTotalWidth;
+    }
+    context.beginPath();
+    context.setLineCap('round');
+    context.setLineWidth(6 * opts.pix);
+    context.setStrokeStyle(opts.xAxis.scrollBackgroundColor || "#EFEBEF");
+    context.moveTo(startX, scrollY);
+    context.lineTo(endX, scrollY);
+    context.stroke();
+    context.closePath();
+    context.beginPath();
+    context.setLineCap('round');
+    context.setLineWidth(6 * opts.pix);
+    context.setStrokeStyle(opts.xAxis.scrollColor || "#A6A6A6");
+    context.moveTo(startX + scrollLeft, scrollY);
+    context.lineTo(startX + scrollLeft + scrollWidth, scrollY);
+    context.stroke();
+    context.closePath();
+    context.setLineCap('butt');
+  }
+  context.save();
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
+    context.translate(opts._scrollDistance_, 0);
+  }
+  //绘制X轴刻度线
+  if (opts.xAxis.calibration === true) {
+    context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
+    context.setLineCap('butt');
+    context.setLineWidth(1 * opts.pix);
+    xAxisPoints.forEach(function(item, index) {
+      if (index > 0) {
+        context.beginPath();
+        context.moveTo(item - eachSpacing / 2, startY);
+        context.lineTo(item - eachSpacing / 2, startY + 3 * opts.pix);
+        context.closePath();
+        context.stroke();
+      }
+    });
+  }
+  //绘制X轴网格
+  if (opts.xAxis.disableGrid !== true) {
+    context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
+    context.setLineCap('butt');
+    context.setLineWidth(1 * opts.pix);
+    if (opts.xAxis.gridType == 'dash') {
+      context.setLineDash([opts.xAxis.dashLength * opts.pix, opts.xAxis.dashLength * opts.pix]);
+    }
+    opts.xAxis.gridEval = opts.xAxis.gridEval || 1;
+    xAxisPoints.forEach(function(item, index) {
+      if (index % opts.xAxis.gridEval == 0) {
+        context.beginPath();
+        context.moveTo(item, startY);
+        context.lineTo(item, endY);
+        context.stroke();
+      }
+    });
+    context.setLineDash([]);
+  }
+  //绘制X轴文案
+  if (opts.xAxis.disabled !== true) {
+    // 对X轴列表做抽稀处理
+    //默认全部显示X轴标签
+    let maxXAxisListLength = categories.length;
+    //如果设置了X轴单屏数量
+    if (opts.xAxis.labelCount) {
+      //如果设置X轴密度
+      if (opts.xAxis.itemCount) {
+        maxXAxisListLength = Math.ceil(categories.length / opts.xAxis.itemCount * opts.xAxis.labelCount);
+      } else {
+        maxXAxisListLength = opts.xAxis.labelCount;
+      }
+      maxXAxisListLength -= 1;
+    }
+
+    let ratio = Math.ceil(categories.length / maxXAxisListLength);
+
+    let newCategories = [];
+    let cgLength = categories.length;
+    for (let i = 0; i < cgLength; i++) {
+      if (i % ratio !== 0) {
+        newCategories.push("");
+      } else {
+        newCategories.push(categories[i]);
+      }
+    }
+    newCategories[cgLength - 1] = categories[cgLength - 1];
+    var xAxisFontSize = opts.xAxis.fontSize * opts.pix || config.fontSize;
+    if (config._xAxisTextAngle_ === 0) {
+      newCategories.forEach(function(item, index) {
+        var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item,index,opts) : item;
+        var offset = -measureText(String(xitem), xAxisFontSize, context) / 2;
+        if (boundaryGap == 'center') {
+          offset += eachSpacing / 2;
+        }
+        var scrollHeight = 0;
+        if (opts.xAxis.scrollShow) {
+          scrollHeight = 6 * opts.pix;
+        }
+        // 如果在主视图区域内
+        var _scrollDistance_ = opts._scrollDistance_ || 0;
+        var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index];
+        if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){
+          context.beginPath();
+          context.setFontSize(xAxisFontSize);
+          context.setFillStyle(opts.xAxis.fontColor || opts.fontColor);
+          context.fillText(String(xitem), xAxisPoints[index] + offset, startY + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.fontSize) * opts.pix / 2 + opts.xAxis.fontSize * opts.pix);
+          context.closePath();
+          context.stroke();
+        }
+      });
+    } else {
+      newCategories.forEach(function(item, index) {
+        var xitem = opts.xAxis.formatter ? opts.xAxis.formatter(item) : item;
+        // 如果在主视图区域内
+        var _scrollDistance_ = opts._scrollDistance_ || 0;
+        var truePoints = boundaryGap == 'center' ? xAxisPoints[index] + eachSpacing / 2 : xAxisPoints[index];
+        if((truePoints - Math.abs(_scrollDistance_)) >= (opts.area[3] - 1) && (truePoints - Math.abs(_scrollDistance_)) <= (opts.width - opts.area[1] + 1)){
+          context.save();
+          context.beginPath();
+          context.setFontSize(xAxisFontSize);
+          context.setFillStyle(opts.xAxis.fontColor || opts.fontColor);
+          var textWidth = measureText(String(xitem), xAxisFontSize, context);
+          var offsetX = xAxisPoints[index];
+          if (boundaryGap == 'center') {
+            offsetX = xAxisPoints[index] + eachSpacing / 2;
+          }
+          var scrollHeight = 0;
+          if (opts.xAxis.scrollShow) {
+            scrollHeight = 6 * opts.pix;
+          }
+          var offsetY = startY + opts.xAxis.marginTop * opts.pix + xAxisFontSize - xAxisFontSize * Math.abs(Math.sin(config._xAxisTextAngle_));
+          if(opts.xAxis.rotateAngle < 0){
+            offsetX -= xAxisFontSize / 2;
+            textWidth = 0;
+          }else{
+            offsetX += xAxisFontSize / 2;
+            textWidth = -textWidth;
+          }
+          context.translate(offsetX, offsetY);
+          context.rotate(-1 * config._xAxisTextAngle_);
+          context.fillText(String(xitem), textWidth , 0 );
+          context.closePath();
+          context.stroke();
+          context.restore();
+        }
+      });
+    }
+  }
+  context.restore();
+  
+  //画X轴标题
+  if (opts.xAxis.title) {
+    context.beginPath();
+    context.setFontSize(opts.xAxis.titleFontSize * opts.pix);
+    context.setFillStyle(opts.xAxis.titleFontColor);
+    context.fillText(String(opts.xAxis.title), opts.width - opts.area[1] + opts.xAxis.titleOffsetX * opts.pix,opts.height - opts.area[2] + opts.xAxis.marginTop * opts.pix + (opts.xAxis.lineHeight - opts.xAxis.titleFontSize) * opts.pix / 2 + (opts.xAxis.titleFontSize + opts.xAxis.titleOffsetY) * opts.pix);
+    context.closePath();
+    context.stroke();
+  }
+  
+  //绘制X轴轴线
+  if (opts.xAxis.axisLine) {
+    context.beginPath();
+    context.setStrokeStyle(opts.xAxis.axisLineColor);
+    context.setLineWidth(1 * opts.pix);
+    context.moveTo(startX, opts.height - opts.area[2]);
+    context.lineTo(endX, opts.height - opts.area[2]);
+    context.stroke();
+  }
+}
+
+function drawYAxisGrid(categories, opts, config, context) {
+  if (opts.yAxis.disableGrid === true) {
+    return;
+  }
+  let spacingValid = opts.height - opts.area[0] - opts.area[2];
+  let eachSpacing = spacingValid / opts.yAxis.splitNumber;
+  let startX = opts.area[3];
+  let xAxisPoints = opts.chartData.xAxisData.xAxisPoints,
+    xAxiseachSpacing = opts.chartData.xAxisData.eachSpacing;
+  let TotalWidth = xAxiseachSpacing * (xAxisPoints.length - 1);
+  if(opts.type == 'mount' && opts.extra && opts.extra.mount && opts.extra.mount.widthRatio && opts.extra.mount.widthRatio > 1 ){
+    if(opts.extra.mount.widthRatio>2) opts.extra.mount.widthRatio = 2
+    TotalWidth += (opts.extra.mount.widthRatio - 1) * xAxiseachSpacing;
+  }
+  let endX = startX + TotalWidth;
+  let points = [];
+  let startY = 1
+  if (opts.xAxis.axisLine === false) {
+    startY = 0
+  }
+  for (let i = startY; i < opts.yAxis.splitNumber + 1; i++) {
+    points.push(opts.height - opts.area[2] - eachSpacing * i);
+  }
+  context.save();
+  if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
+    context.translate(opts._scrollDistance_, 0);
+  }
+  if (opts.yAxis.gridType == 'dash') {
+    context.setLineDash([opts.yAxis.dashLength * opts.pix, opts.yAxis.dashLength * opts.pix]);
+  }
+  context.setStrokeStyle(opts.yAxis.gridColor);
+  context.setLineWidth(1 * opts.pix);
+  points.forEach(function(item, index) {
+    context.beginPath();
+    context.moveTo(startX, item);
+    context.lineTo(endX, item);
+    context.stroke();
+  });
+  context.setLineDash([]);
+  context.restore();
+}
+
+function drawYAxis(series, opts, config, context) {
+  if (opts.yAxis.disabled === true) {
+    return;
+  }
+  var spacingValid = opts.height - opts.area[0] - opts.area[2];
+  var eachSpacing = spacingValid / opts.yAxis.splitNumber;
+  var startX = opts.area[3];
+  var endX = opts.width - opts.area[1];
+  var endY = opts.height - opts.area[2];
+  // set YAxis background
+  context.beginPath();
+  context.setFillStyle(opts.background);
+  if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'left') {
+    context.fillRect(0, 0, startX, endY + 2 * opts.pix);
+  }
+  if (opts.enableScroll == true && opts.xAxis.scrollPosition && opts.xAxis.scrollPosition !== 'right') {
+    context.fillRect(endX, 0, opts.width, endY + 2 * opts.pix);
+  }
+  context.closePath();
+  context.stroke();
+  
+  let tStartLeft = opts.area[3];
+  let tStartRight = opts.width - opts.area[1];
+  let tStartCenter = opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2;
+  if (opts.yAxis.data) {
+    for (let i = 0; i < opts.yAxis.data.length; i++) {
+      let yData = opts.yAxis.data[i];
+      var points = [];
+      if(yData.type === 'categories'){
+        for (let i = 0; i <= yData.categories.length; i++) {
+          points.push(opts.area[0] + spacingValid / yData.categories.length / 2 + spacingValid / yData.categories.length * i);
+        }
+      }else{
+        for (let i = 0; i <= opts.yAxis.splitNumber; i++) {
+          points.push(opts.area[0] + eachSpacing * i);
+        }
+      }
+      if (yData.disabled !== true) {
+        let rangesFormat = opts.chartData.yAxisData.rangesFormat[i];
+        let yAxisFontSize = yData.fontSize ? yData.fontSize * opts.pix : config.fontSize;
+        let yAxisWidth = opts.chartData.yAxisData.yAxisWidth[i];
+        let textAlign = yData.textAlign || "right";
+        //画Y轴刻度及文案
+        rangesFormat.forEach(function(item, index) {
+          var pos = points[index];
+          context.beginPath();
+          context.setFontSize(yAxisFontSize);
+          context.setLineWidth(1 * opts.pix);
+          context.setStrokeStyle(yData.axisLineColor || '#cccccc');
+          context.setFillStyle(yData.fontColor || opts.fontColor);
+          let tmpstrat = 0;
+          let gapwidth = 4 * opts.pix;
+          if (yAxisWidth.position == 'left') {
+            //画刻度线
+            if (yData.calibration == true) {
+              context.moveTo(tStartLeft, pos);
+              context.lineTo(tStartLeft - 3 * opts.pix, pos);
+              gapwidth += 3 * opts.pix;
+            }
+            //画文字
+            switch (textAlign) {
+              case "left":
+                context.setTextAlign('left');
+                tmpstrat = tStartLeft - yAxisWidth.width
+                break;
+              case "right":
+                context.setTextAlign('right');
+                tmpstrat = tStartLeft - gapwidth
+                break;
+              default:
+                context.setTextAlign('center');
+                tmpstrat = tStartLeft - yAxisWidth.width / 2
+            }
+            context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix);
+
+          } else if (yAxisWidth.position == 'right') {
+            //画刻度线
+            if (yData.calibration == true) {
+              context.moveTo(tStartRight, pos);
+              context.lineTo(tStartRight + 3 * opts.pix, pos);
+              gapwidth += 3 * opts.pix;
+            }
+            switch (textAlign) {
+              case "left":
+                context.setTextAlign('left');
+                tmpstrat = tStartRight + gapwidth
+                break;
+              case "right":
+                context.setTextAlign('right');
+                tmpstrat = tStartRight + yAxisWidth.width
+                break;
+              default:
+                context.setTextAlign('center');
+                tmpstrat = tStartRight + yAxisWidth.width / 2
+            }
+            context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix);
+          } else if (yAxisWidth.position == 'center') {
+            //画刻度线
+            if (yData.calibration == true) {
+              context.moveTo(tStartCenter, pos);
+              context.lineTo(tStartCenter - 3 * opts.pix, pos);
+              gapwidth += 3 * opts.pix;
+            }
+            //画文字
+            switch (textAlign) {
+              case "left":
+                context.setTextAlign('left');
+                tmpstrat = tStartCenter - yAxisWidth.width
+                break;
+              case "right":
+                context.setTextAlign('right');
+                tmpstrat = tStartCenter - gapwidth
+                break;
+              default:
+                context.setTextAlign('center');
+                tmpstrat = tStartCenter - yAxisWidth.width / 2
+            }
+            context.fillText(String(item), tmpstrat, pos + yAxisFontSize / 2 - 3 * opts.pix);
+          }
+          context.closePath();
+          context.stroke();
+          context.setTextAlign('left');
+        });
+        //画Y轴轴线
+        if (yData.axisLine !== false) {
+          context.beginPath();
+          context.setStrokeStyle(yData.axisLineColor || '#cccccc');
+          context.setLineWidth(1 * opts.pix);
+          if (yAxisWidth.position == 'left') {
+            context.moveTo(tStartLeft, opts.height - opts.area[2]);
+            context.lineTo(tStartLeft, opts.area[0]);
+          } else if (yAxisWidth.position == 'right') {
+            context.moveTo(tStartRight, opts.height - opts.area[2]);
+            context.lineTo(tStartRight, opts.area[0]);
+          } else if (yAxisWidth.position == 'center') {
+            context.moveTo(tStartCenter, opts.height - opts.area[2]);
+            context.lineTo(tStartCenter, opts.area[0]);
+          }
+          context.stroke();
+        }
+        //画Y轴标题
+        if (opts.yAxis.showTitle) {
+          let titleFontSize = yData.titleFontSize * opts.pix || config.fontSize;
+          let title = yData.title;
+          context.beginPath();
+          context.setFontSize(titleFontSize);
+          context.setFillStyle(yData.titleFontColor || opts.fontColor);
+          if (yAxisWidth.position == 'left') {
+            context.fillText(title, tStartLeft - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix);
+          } else if (yAxisWidth.position == 'right') {
+            context.fillText(title, tStartRight - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix);
+          } else if (yAxisWidth.position == 'center') {
+            context.fillText(title, tStartCenter - measureText(title, titleFontSize, context) / 2 + (yData.titleOffsetX || 0), opts.area[0] - (10 - (yData.titleOffsetY || 0)) * opts.pix);
+          }
+          context.closePath();
+          context.stroke();
+        }
+        if (yAxisWidth.position == 'left') {
+          tStartLeft -= (yAxisWidth.width + opts.yAxis.padding * opts.pix);
+        } else {
+          tStartRight += yAxisWidth.width + opts.yAxis.padding * opts.pix;
+        }
+      }
+    }
+  }
+
+}
+
+function drawLegend(series, opts, config, context, chartData) {
+  if (opts.legend.show === false) {
+    return;
+  }
+  let legendData = chartData.legendData;
+  let legendList = legendData.points;
+  let legendArea = legendData.area;
+  let padding = opts.legend.padding * opts.pix;
+  let fontSize = opts.legend.fontSize * opts.pix;
+  let shapeWidth = 15 * opts.pix;
+  let shapeRight = 5 * opts.pix;
+  let itemGap = opts.legend.itemGap * opts.pix;
+  let lineHeight = Math.max(opts.legend.lineHeight * opts.pix, fontSize);
+  //画背景及边框
+  context.beginPath();
+  context.setLineWidth(opts.legend.borderWidth * opts.pix);
+  context.setStrokeStyle(opts.legend.borderColor);
+  context.setFillStyle(opts.legend.backgroundColor);
+  context.moveTo(legendArea.start.x, legendArea.start.y);
+  context.rect(legendArea.start.x, legendArea.start.y, legendArea.width, legendArea.height);
+  context.closePath();
+  context.fill();
+  context.stroke();
+  legendList.forEach(function(itemList, listIndex) {
+    let width = 0;
+    let height = 0;
+    width = legendData.widthArr[listIndex];
+    height = legendData.heightArr[listIndex];
+    let startX = 0;
+    let startY = 0;
+    if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+      switch (opts.legend.float) {
+        case 'left':
+          startX = legendArea.start.x + padding;
+        break;
+        case 'right':
+          startX = legendArea.start.x + legendArea.width - width;
+        break;
+        default:
+        startX = legendArea.start.x + (legendArea.width - width) / 2;
+      }
+      startY = legendArea.start.y + padding + listIndex * lineHeight;
+    } else {
+      if (listIndex == 0) {
+        width = 0;
+      } else {
+        width = legendData.widthArr[listIndex - 1];
+      }
+      startX = legendArea.start.x + padding + width;
+      startY = legendArea.start.y + padding + (legendArea.height - height) / 2;
+    }
+    context.setFontSize(config.fontSize);
+    for (let i = 0; i < itemList.length; i++) {
+      let item = itemList[i];
+      item.area = [0, 0, 0, 0];
+      item.area[0] = startX;
+      item.area[1] = startY;
+      item.area[3] = startY + lineHeight;
+      context.beginPath();
+      context.setLineWidth(1 * opts.pix);
+      context.setStrokeStyle(item.show ? item.color : opts.legend.hiddenColor);
+      context.setFillStyle(item.show ? item.color : opts.legend.hiddenColor);
+      switch (item.legendShape) {
+        case 'line':
+          context.moveTo(startX, startY + 0.5 * lineHeight - 2 * opts.pix);
+          context.fillRect(startX, startY + 0.5 * lineHeight - 2 * opts.pix, 15 * opts.pix, 4 * opts.pix);
+          break;
+        case 'triangle':
+          context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix);
+          context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix);
+          context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          break;
+        case 'diamond':
+          context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.lineTo(startX + 2.5 * opts.pix, startY + 0.5 * lineHeight);
+          context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight + 5 * opts.pix);
+          context.lineTo(startX + 12.5 * opts.pix, startY + 0.5 * lineHeight);
+          context.lineTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          break;
+        case 'circle':
+          context.moveTo(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight);
+          context.arc(startX + 7.5 * opts.pix, startY + 0.5 * lineHeight, 5 * opts.pix, 0, 2 * Math.PI);
+          break;
+        case 'rect':
+          context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+          break;
+        case 'square':
+          context.moveTo(startX + 5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.fillRect(startX + 5 * opts.pix, startY + 0.5 * lineHeight - 5 * opts.pix, 10 * opts.pix, 10 * opts.pix);
+          break;
+        case 'none':
+          break;
+        default:
+          context.moveTo(startX, startY + 0.5 * lineHeight - 5 * opts.pix);
+          context.fillRect(startX, startY + 0.5 * lineHeight - 5 * opts.pix, 15 * opts.pix, 10 * opts.pix);
+      }
+      context.closePath();
+      context.fill();
+      context.stroke();
+      startX += shapeWidth + shapeRight;
+      let fontTrans = 0.5 * lineHeight + 0.5 * fontSize - 2;
+      const legendText = item.legendText ? item.legendText : item.name;
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.show ? opts.legend.fontColor : opts.legend.hiddenColor);
+      context.fillText(legendText, startX, startY + fontTrans);
+      context.closePath();
+      context.stroke();
+      if (opts.legend.position == 'top' || opts.legend.position == 'bottom') {
+        startX += measureText(legendText, fontSize, context) + itemGap;
+        item.area[2] = startX;
+      } else {
+        item.area[2] = startX + measureText(legendText, fontSize, context) + itemGap;;
+        startX -= shapeWidth + shapeRight;
+        startY += lineHeight;
+      }
+    }
+  });
+}
+
+function drawPieDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var pieOption = assign({}, {
+    activeOpacity: 0.5,
+    activeRadius: 10,
+    offsetAngle: 0,
+    labelWidth: 15,
+    ringWidth: 30,
+    customRadius: 0,
+    border: false,
+    borderWidth: 2,
+    borderColor: '#FFFFFF',
+    centerColor: '#FFFFFF',
+    linearType: 'none',
+    customColor: [],
+  }, opts.type == "pie" ? opts.extra.pie : opts.extra.ring);
+  var centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+  };
+  if (config.pieChartLinePadding == 0) {
+    config.pieChartLinePadding = pieOption.activeRadius * opts.pix;
+  }
+
+  var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding);
+  radius = radius < 10 ? 10 : radius;
+  if (pieOption.customRadius > 0) {
+    radius = pieOption.customRadius * opts.pix;
+  }
+  series = getPieDataPoints(series, radius, process);
+  var activeRadius = pieOption.activeRadius * opts.pix;
+  pieOption.customColor = fillCustomColor(pieOption.linearType, pieOption.customColor, series, config);
+  series = series.map(function(eachSeries) {
+    eachSeries._start_ += (pieOption.offsetAngle) * Math.PI / 180;
+    return eachSeries;
+  });
+  series.forEach(function(eachSeries, seriesIndex) {
+    if (opts.tooltip) {
+      if (opts.tooltip.index == seriesIndex) {
+        context.beginPath();
+        context.setFillStyle(hexToRgb(eachSeries.color, pieOption.activeOpacity || 0.5));
+        context.moveTo(centerPosition.x, centerPosition.y);
+        context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_ + activeRadius, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
+        context.closePath();
+        context.fill();
+      }
+    }
+    context.beginPath();
+    context.setLineWidth(pieOption.borderWidth * opts.pix);
+    context.lineJoin = "round";
+    context.setStrokeStyle(pieOption.borderColor);
+    var fillcolor = eachSeries.color;
+    if (pieOption.linearType == 'custom') {
+      var grd;
+      if(context.createCircularGradient){
+        grd = context.createCircularGradient(centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }else{
+        grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }
+      grd.addColorStop(0, hexToRgb(pieOption.customColor[eachSeries.linearIndex], 1))
+      grd.addColorStop(1, hexToRgb(eachSeries.color, 1))
+      fillcolor = grd
+    }
+    context.setFillStyle(fillcolor);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
+    context.closePath();
+    context.fill();
+    if (pieOption.border == true) {
+      context.stroke();
+    }
+  });
+  if (opts.type === 'ring') {
+    var innerPieWidth = radius * 0.6;
+    if (typeof pieOption.ringWidth === 'number' && pieOption.ringWidth > 0) {
+      innerPieWidth = Math.max(0, radius - pieOption.ringWidth * opts.pix);
+    }
+    context.beginPath();
+    context.setFillStyle(pieOption.centerColor);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI);
+    context.closePath();
+    context.fill();
+  }
+  if (opts.dataLabel !== false && process === 1) {
+    drawPieText(series, opts, config, context, radius, centerPosition);
+  }
+  if (process === 1 && opts.type === 'ring') {
+    drawRingTitle(opts, config, context, centerPosition);
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: series
+  };
+}
+
+function drawRoseDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var roseOption = assign({}, {
+    type: 'area',
+    activeOpacity: 0.5,
+    activeRadius: 10,
+    offsetAngle: 0,
+    labelWidth: 15,
+    border: false,
+    borderWidth: 2,
+    borderColor: '#FFFFFF',
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.rose);
+  if (config.pieChartLinePadding == 0) {
+    config.pieChartLinePadding = roseOption.activeRadius * opts.pix;
+  }
+  var centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+  };
+  var radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_, (opts.height - opts.area[0] - opts.area[2]) / 2 - config.pieChartLinePadding - config.pieChartTextPadding);
+  radius = radius < 10 ? 10 : radius;
+  var minRadius = roseOption.minRadius || radius * 0.5;
+  if(radius < minRadius){
+    radius = minRadius + 10;
+  }
+  series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process);
+  var activeRadius = roseOption.activeRadius * opts.pix;
+  roseOption.customColor = fillCustomColor(roseOption.linearType, roseOption.customColor, series, config);
+  series = series.map(function(eachSeries) {
+    eachSeries._start_ += (roseOption.offsetAngle || 0) * Math.PI / 180;
+    return eachSeries;
+  });
+  series.forEach(function(eachSeries, seriesIndex) {
+    if (opts.tooltip) {
+      if (opts.tooltip.index == seriesIndex) {
+        context.beginPath();
+        context.setFillStyle(hexToRgb(eachSeries.color, roseOption.activeOpacity || 0.5));
+        context.moveTo(centerPosition.x, centerPosition.y);
+        context.arc(centerPosition.x, centerPosition.y, activeRadius + eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI);
+        context.closePath();
+        context.fill();
+      }
+    }
+    context.beginPath();
+    context.setLineWidth(roseOption.borderWidth * opts.pix);
+    context.lineJoin = "round";
+    context.setStrokeStyle(roseOption.borderColor);
+    var fillcolor = eachSeries.color;
+    if (roseOption.linearType == 'custom') {
+      var grd;
+      if(context.createCircularGradient){
+        grd = context.createCircularGradient(centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }else{
+        grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, eachSeries._radius_)
+      }
+      grd.addColorStop(0, hexToRgb(roseOption.customColor[eachSeries.linearIndex], 1))
+      grd.addColorStop(1, hexToRgb(eachSeries.color, 1))
+      fillcolor = grd
+    }
+    context.setFillStyle(fillcolor);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._rose_proportion_ * Math.PI);
+    context.closePath();
+    context.fill();
+    if (roseOption.border == true) {
+      context.stroke();
+    }
+  });
+
+  if (opts.dataLabel !== false && process === 1) {
+    drawPieText(series, opts, config, context, radius, centerPosition);
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: series
+  };
+}
+
+function drawArcbarDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var arcbarOption = assign({}, {
+    startAngle: 0.75,
+    endAngle: 0.25,
+    type: 'default',
+    direction: 'cw',
+    lineCap: 'round',
+    width: 12 ,
+    gap: 2 ,
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.arcbar);
+  series = getArcbarDataPoints(series, arcbarOption, process);
+  var centerPosition;
+  if (arcbarOption.centerX || arcbarOption.centerY) {
+    centerPosition = {
+      x: arcbarOption.centerX ? arcbarOption.centerX : opts.width / 2,
+      y: arcbarOption.centerY ? arcbarOption.centerY : opts.height / 2
+    };
+  } else {
+    centerPosition = {
+      x: opts.width / 2,
+      y: opts.height / 2
+    };
+  }
+  var radius;
+  if (arcbarOption.radius) {
+    radius = arcbarOption.radius;
+  } else {
+    radius = Math.min(centerPosition.x, centerPosition.y);
+    radius -= 5 * opts.pix;
+    radius -= arcbarOption.width / 2;
+  }
+  radius = radius < 10 ? 10 : radius;
+  arcbarOption.customColor = fillCustomColor(arcbarOption.linearType, arcbarOption.customColor, series, config);
+  
+  for (let i = 0; i < series.length; i++) {
+    let eachSeries = series[i];
+    //背景颜色
+    context.setLineWidth(arcbarOption.width * opts.pix);
+    context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9');
+    context.setLineCap(arcbarOption.lineCap);
+    context.beginPath();
+    if (arcbarOption.type == 'default') {
+      context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle * Math.PI, arcbarOption.direction == 'ccw');
+    } else {
+      context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, 0, 2 * Math.PI, arcbarOption.direction == 'ccw');
+    }
+    context.stroke();
+    //进度条
+    var fillColor = eachSeries.color
+    if(arcbarOption.linearType == 'custom'){
+      var grd = context.createLinearGradient(centerPosition.x - radius, centerPosition.y, centerPosition.x + radius, centerPosition.y);
+      grd.addColorStop(1, hexToRgb(arcbarOption.customColor[eachSeries.linearIndex], 1))
+      grd.addColorStop(0, hexToRgb(eachSeries.color, 1))
+      fillColor = grd;
+    }
+    context.setLineWidth(arcbarOption.width * opts.pix);
+    context.setStrokeStyle(fillColor);
+    context.setLineCap(arcbarOption.lineCap);
+    context.beginPath();
+    context.arc(centerPosition.x, centerPosition.y, radius - (arcbarOption.width * opts.pix + arcbarOption.gap * opts.pix) * i, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ * Math.PI, arcbarOption.direction == 'ccw');
+    context.stroke();
+  }
+  drawRingTitle(opts, config, context, centerPosition);
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: series
+  };
+}
+
+function drawGaugeDataPoints(categories, series, opts, config, context) {
+  var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
+  var gaugeOption = assign({}, {
+    type: 'default',
+    startAngle: 0.75,
+    endAngle: 0.25,
+    width: 15,
+    labelOffset:13,
+    splitLine: {
+      fixRadius: 0,
+      splitNumber: 10,
+      width: 15,
+      color: '#FFFFFF',
+      childNumber: 5,
+      childWidth: 5
+    },
+    pointer: {
+      width: 15,
+      color: 'auto'
+    }
+  }, opts.extra.gauge);
+  if (gaugeOption.oldAngle == undefined) {
+    gaugeOption.oldAngle = gaugeOption.startAngle;
+  }
+  if (gaugeOption.oldData == undefined) {
+    gaugeOption.oldData = 0;
+  }
+  categories = getGaugeAxisPoints(categories, gaugeOption.startAngle, gaugeOption.endAngle);
+  var centerPosition = {
+    x: opts.width / 2,
+    y: opts.height / 2
+  };
+  var radius = Math.min(centerPosition.x, centerPosition.y);
+  radius -= 5 * opts.pix;
+  radius -= gaugeOption.width / 2;
+  radius = radius < 10 ? 10 : radius;
+  var innerRadius = radius - gaugeOption.width;
+  var totalAngle = 0;
+  //判断仪表盘的样式:default百度样式,progress新样式
+  if (gaugeOption.type == 'progress') {
+    //## 第一步画中心圆形背景和进度条背景
+    //中心圆形背景
+    var pieRadius = radius - gaugeOption.width * 3;
+    context.beginPath();
+    let gradient = context.createLinearGradient(centerPosition.x, centerPosition.y - pieRadius, centerPosition.x, centerPosition.y + pieRadius);
+    //配置渐变填充(起点:中心点向上减半径;结束点中心点向下加半径)
+    gradient.addColorStop('0', hexToRgb(series[0].color, 0.3));
+    gradient.addColorStop('1.0', hexToRgb("#FFFFFF", 0.1));
+    context.setFillStyle(gradient);
+    context.arc(centerPosition.x, centerPosition.y, pieRadius, 0, 2 * Math.PI, false);
+    context.fill();
+    //画进度条背景
+    context.setLineWidth(gaugeOption.width);
+    context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+    context.setLineCap('round');
+    context.beginPath();
+    context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, gaugeOption.endAngle * Math.PI, false);
+    context.stroke();
+    //## 第二步画刻度线
+    if (gaugeOption.endAngle < gaugeOption.startAngle) {
+      totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+    } else {
+      totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+    }
+    let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+    let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
+    let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
+    let endX = -radius - gaugeOption.width - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
+    context.save();
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+    let len = gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1;
+    let proc = series[0].data * process;
+    for (let i = 0; i < len; i++) {
+      context.beginPath();
+      //刻度线随进度变色
+      if (proc > (i / len)) {
+        context.setStrokeStyle(hexToRgb(series[0].color, 1));
+      } else {
+        context.setStrokeStyle(hexToRgb(series[0].color, 0.3));
+      }
+      context.setLineWidth(3 * opts.pix);
+      context.moveTo(startX, 0);
+      context.lineTo(endX, 0);
+      context.stroke();
+      context.rotate(childAngle * Math.PI);
+    }
+    context.restore();
+    //## 第三步画进度条
+    series = getGaugeArcbarDataPoints(series, gaugeOption, process);
+    context.setLineWidth(gaugeOption.width);
+    context.setStrokeStyle(series[0].color);
+    context.setLineCap('round');
+    context.beginPath();
+    context.arc(centerPosition.x, centerPosition.y, innerRadius, gaugeOption.startAngle * Math.PI, series[0]._proportion_ * Math.PI, false);
+    context.stroke();
+    //## 第四步画指针
+    let pointerRadius = radius - gaugeOption.width * 2.5;
+    context.save();
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((series[0]._proportion_ - 1) * Math.PI);
+    context.beginPath();
+    context.setLineWidth(gaugeOption.width / 3);
+    let gradient3 = context.createLinearGradient(0, -pointerRadius * 0.6, 0, pointerRadius * 0.6);
+    gradient3.addColorStop('0', hexToRgb('#FFFFFF', 0));
+    gradient3.addColorStop('0.5', hexToRgb(series[0].color, 1));
+    gradient3.addColorStop('1.0', hexToRgb('#FFFFFF', 0));
+    context.setStrokeStyle(gradient3);
+    context.arc(0, 0, pointerRadius, 0.85 * Math.PI, 1.15 * Math.PI, false);
+    context.stroke();
+    context.beginPath();
+    context.setLineWidth(1);
+    context.setStrokeStyle(series[0].color);
+    context.setFillStyle(series[0].color);
+    context.moveTo(-pointerRadius - gaugeOption.width / 3 / 2, -4);
+    context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2 - 4, 0);
+    context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, 4);
+    context.lineTo(-pointerRadius - gaugeOption.width / 3 / 2, -4);
+    context.stroke();
+    context.fill();
+    context.restore();
+    //default百度样式
+  } else {
+    //画背景
+    context.setLineWidth(gaugeOption.width);
+    context.setLineCap('butt');
+    for (let i = 0; i < categories.length; i++) {
+      let eachCategories = categories[i];
+      context.beginPath();
+      context.setStrokeStyle(eachCategories.color);
+      context.arc(centerPosition.x, centerPosition.y, radius, eachCategories._startAngle_ * Math.PI, eachCategories._endAngle_ * Math.PI, false);
+      context.stroke();
+    }
+    context.save();
+    //画刻度线
+    if (gaugeOption.endAngle < gaugeOption.startAngle) {
+      totalAngle = 2 + gaugeOption.endAngle - gaugeOption.startAngle;
+    } else {
+      totalAngle = gaugeOption.startAngle - gaugeOption.endAngle;
+    }
+    let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
+    let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
+    let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
+    let endX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
+    let childendX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.childWidth;
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+    for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
+      context.beginPath();
+      context.setStrokeStyle(gaugeOption.splitLine.color);
+      context.setLineWidth(2 * opts.pix);
+      context.moveTo(startX, 0);
+      context.lineTo(endX, 0);
+      context.stroke();
+      context.rotate(splitAngle * Math.PI);
+    }
+    context.restore();
+    context.save();
+    context.translate(centerPosition.x, centerPosition.y);
+    context.rotate((gaugeOption.startAngle - 1) * Math.PI);
+    for (let i = 0; i < gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1; i++) {
+      context.beginPath();
+      context.setStrokeStyle(gaugeOption.splitLine.color);
+      context.setLineWidth(1 * opts.pix);
+      context.moveTo(startX, 0);
+      context.lineTo(childendX, 0);
+      context.stroke();
+      context.rotate(childAngle * Math.PI);
+    }
+    context.restore();
+    //画指针
+    series = getGaugeDataPoints(series, categories, gaugeOption, process);
+    for (let i = 0; i < series.length; i++) {
+      let eachSeries = series[i];
+      context.save();
+      context.translate(centerPosition.x, centerPosition.y);
+      context.rotate((eachSeries._proportion_ - 1) * Math.PI);
+      context.beginPath();
+      context.setFillStyle(eachSeries.color);
+      context.moveTo(gaugeOption.pointer.width, 0);
+      context.lineTo(0, -gaugeOption.pointer.width / 2);
+      context.lineTo(-innerRadius, 0);
+      context.lineTo(0, gaugeOption.pointer.width / 2);
+      context.lineTo(gaugeOption.pointer.width, 0);
+      context.closePath();
+      context.fill();
+      context.beginPath();
+      context.setFillStyle('#FFFFFF');
+      context.arc(0, 0, gaugeOption.pointer.width / 6, 0, 2 * Math.PI, false);
+      context.fill();
+      context.restore();
+    }
+    if (opts.dataLabel !== false) {
+      drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context);
+    }
+  }
+  //画仪表盘标题,副标题
+  drawRingTitle(opts, config, context, centerPosition);
+  if (process === 1 && opts.type === 'gauge') {
+    opts.extra.gauge.oldAngle = series[0]._proportion_;
+    opts.extra.gauge.oldData = series[0].data;
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    innerRadius: innerRadius,
+    categories: categories,
+    totalAngle: totalAngle
+  };
+}
+
+function drawRadarDataPoints(series, opts, config, context) {
+  var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  var radarOption = assign({}, {
+    gridColor: '#cccccc',
+    gridType: 'radar',
+    gridEval:1,
+    axisLabel:false,
+    axisLabelTofix:0,
+    labelShow:true,
+    labelColor:'#666666',
+    labelPointShow:false,
+    labelPointRadius:3,
+    labelPointColor:'#cccccc',
+    opacity: 0.2,
+    gridCount: 3,
+    border:false,
+    borderWidth:2,
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.radar);
+  var coordinateAngle = getRadarCoordinateSeries(opts.categories.length);
+  var centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.area[0] + (opts.height - opts.area[0] - opts.area[2]) / 2
+  };
+  var xr = (opts.width - opts.area[1] - opts.area[3]) / 2
+  var yr = (opts.height - opts.area[0] - opts.area[2]) / 2
+  var radius = Math.min(xr - (getMaxTextListLength(opts.categories, config.fontSize, context) + config.radarLabelTextMargin), yr - config.radarLabelTextMargin);
+  radius -= config.radarLabelTextMargin * opts.pix;
+  radius = radius < 10 ? 10 : radius;
+  radius = radarOption.radius ? radarOption.radius : radius;
+  // 画分割线
+  context.beginPath();
+  context.setLineWidth(1 * opts.pix);
+  context.setStrokeStyle(radarOption.gridColor);
+  coordinateAngle.forEach(function(angle,index) {
+    var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition);
+    context.moveTo(centerPosition.x, centerPosition.y);
+    if (index % radarOption.gridEval == 0) {
+      context.lineTo(pos.x, pos.y);
+    }
+  });
+  context.stroke();
+  context.closePath();
+  
+  // 画背景网格
+  var _loop = function _loop(i) {
+    var startPos = {};
+    context.beginPath();
+    context.setLineWidth(1 * opts.pix);
+    context.setStrokeStyle(radarOption.gridColor);
+    if (radarOption.gridType == 'radar') {
+      coordinateAngle.forEach(function(angle, index) {
+        var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(angle), radius /
+          radarOption.gridCount * i * Math.sin(angle), centerPosition);
+        if (index === 0) {
+          startPos = pos;
+          context.moveTo(pos.x, pos.y);
+        } else {
+          context.lineTo(pos.x, pos.y);
+        }
+      });
+      context.lineTo(startPos.x, startPos.y);
+    } else {
+      var pos = convertCoordinateOrigin(radius / radarOption.gridCount * i * Math.cos(1.5), radius / radarOption.gridCount * i * Math.sin(1.5), centerPosition);
+      context.arc(centerPosition.x, centerPosition.y, centerPosition.y - pos.y, 0, 2 * Math.PI, false);
+    }
+    context.stroke();
+    context.closePath();
+  };
+  for (var i = 1; i <= radarOption.gridCount; i++) {
+    _loop(i);
+  }
+  radarOption.customColor = fillCustomColor(radarOption.linearType, radarOption.customColor, series, config);
+  var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process);
+  radarDataPoints.forEach(function(eachSeries, seriesIndex) {
+    // 绘制区域数据
+    context.beginPath();
+    context.setLineWidth(radarOption.borderWidth * opts.pix);
+    context.setStrokeStyle(eachSeries.color);
+    
+    var fillcolor = hexToRgb(eachSeries.color, radarOption.opacity);
+    if (radarOption.linearType == 'custom') {
+      var grd;
+      if(context.createCircularGradient){
+        grd = context.createCircularGradient(centerPosition.x, centerPosition.y, radius)
+      }else{
+        grd = context.createRadialGradient(centerPosition.x, centerPosition.y, 0,centerPosition.x, centerPosition.y, radius)
+      }
+      grd.addColorStop(0, hexToRgb(radarOption.customColor[series[seriesIndex].linearIndex], radarOption.opacity))
+      grd.addColorStop(1, hexToRgb(eachSeries.color, radarOption.opacity))
+      fillcolor = grd
+    }
+    
+    context.setFillStyle(fillcolor);
+    eachSeries.data.forEach(function(item, index) {
+      if (index === 0) {
+        context.moveTo(item.position.x, item.position.y);
+      } else {
+        context.lineTo(item.position.x, item.position.y);
+      }
+    });
+    context.closePath();
+    context.fill();
+    if(radarOption.border === true){
+      context.stroke();
+    }
+    context.closePath();
+    if (opts.dataPointShape !== false) {
+      var points = eachSeries.data.map(function(item) {
+        return item.position;
+      });
+      drawPointShape(points, eachSeries.color, eachSeries.pointShape, context, opts);
+    }
+  });
+  // 画刻度值
+  if(radarOption.axisLabel === true){
+    const maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));
+    const stepLength = radius / radarOption.gridCount;
+    const fontSize = opts.fontSize * opts.pix;
+    context.setFontSize(fontSize);
+    context.setFillStyle(opts.fontColor);
+    context.setTextAlign('left');
+    for (var i = 0; i < radarOption.gridCount + 1; i++) {
+      let label = i * maxData / radarOption.gridCount;
+      label = label.toFixed(radarOption.axisLabelTofix);
+      context.fillText(String(label), centerPosition.x + 3 * opts.pix, centerPosition.y - i * stepLength + fontSize / 2);
+    }
+  }
+  
+  // draw label text
+  drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context);
+  
+  // draw dataLabel
+  if (opts.dataLabel !== false && process === 1) {
+    radarDataPoints.forEach(function(eachSeries, seriesIndex) {
+      context.beginPath();
+      var fontSize = eachSeries.textSize * opts.pix || config.fontSize;
+      context.setFontSize(fontSize);
+      context.setFillStyle(eachSeries.textColor || opts.fontColor);
+      eachSeries.data.forEach(function(item, index) {
+        //如果是中心点垂直的上下点位
+        if(Math.abs(item.position.x - centerPosition.x)<2){
+          //如果在上面
+          if(item.position.y < centerPosition.y){
+            context.setTextAlign('center');
+            context.fillText(item.value, item.position.x, item.position.y - 4);
+          }else{
+            context.setTextAlign('center');
+            context.fillText(item.value, item.position.x, item.position.y + fontSize + 2);
+          }
+        }else{
+          //如果在左侧
+          if(item.position.x < centerPosition.x){
+            context.setTextAlign('right');
+            context.fillText(item.value, item.position.x - 4, item.position.y + fontSize / 2 - 2);
+          }else{
+            context.setTextAlign('left');
+            context.fillText(item.value, item.position.x + 4, item.position.y + fontSize / 2 - 2);
+          }
+        }
+      });
+      context.closePath();
+      context.stroke();
+    });
+    context.setTextAlign('left');
+  }
+  
+  return {
+    center: centerPosition,
+    radius: radius,
+    angleList: coordinateAngle
+  };
+}
+
+// 经纬度转墨卡托
+function lonlat2mercator(longitude, latitude) {
+  var mercator = Array(2);
+  var x = longitude * 20037508.34 / 180;
+  var y = Math.log(Math.tan((90 + latitude) * Math.PI / 360)) / (Math.PI / 180);
+  y = y * 20037508.34 / 180;
+  mercator[0] = x;
+  mercator[1] = y;
+  return mercator;
+}
+
+// 墨卡托转经纬度
+function mercator2lonlat(longitude, latitude) {
+  var lonlat = Array(2)
+  var x = longitude / 20037508.34 * 180;
+  var y = latitude / 20037508.34 * 180;
+  y = 180 / Math.PI * (2 * Math.atan(Math.exp(y * Math.PI / 180)) - Math.PI / 2);
+  lonlat[0] = x;
+  lonlat[1] = y;
+  return lonlat;
+}
+
+function getBoundingBox(data) {
+  var bounds = {},coords;
+  bounds.xMin = 180;
+  bounds.xMax = 0;
+  bounds.yMin = 90;
+  bounds.yMax = 0
+  for (var i = 0; i < data.length; i++) {
+    var coorda = data[i].geometry.coordinates
+    for (var k = 0; k < coorda.length; k++) {
+      coords = coorda[k];
+      if (coords.length == 1) {
+        coords = coords[0]
+      }
+      for (var j = 0; j < coords.length; j++) {
+        var longitude = coords[j][0];
+        var latitude = coords[j][1];
+        var point = {
+          x: longitude,
+          y: latitude
+        }
+        bounds.xMin = bounds.xMin < point.x ? bounds.xMin : point.x;
+        bounds.xMax = bounds.xMax > point.x ? bounds.xMax : point.x;
+        bounds.yMin = bounds.yMin < point.y ? bounds.yMin : point.y;
+        bounds.yMax = bounds.yMax > point.y ? bounds.yMax : point.y;
+      }
+    }
+  }
+  return bounds;
+}
+
+function coordinateToPoint(latitude, longitude, bounds, scale, xoffset, yoffset) {
+  return {
+    x: (longitude - bounds.xMin) * scale + xoffset,
+    y: (bounds.yMax - latitude) * scale + yoffset
+  };
+}
+
+function pointToCoordinate(pointY, pointX, bounds, scale, xoffset, yoffset) {
+  return {
+    x: (pointX - xoffset) / scale + bounds.xMin,
+    y: bounds.yMax - (pointY - yoffset) / scale
+  };
+}
+
+function isRayIntersectsSegment(poi, s_poi, e_poi) {
+  if (s_poi[1] == e_poi[1]) {
+    return false;
+  }
+  if (s_poi[1] > poi[1] && e_poi[1] > poi[1]) {
+    return false;
+  }
+  if (s_poi[1] < poi[1] && e_poi[1] < poi[1]) {
+    return false;
+  }
+  if (s_poi[1] == poi[1] && e_poi[1] > poi[1]) {
+    return false;
+  }
+  if (e_poi[1] == poi[1] && s_poi[1] > poi[1]) {
+    return false;
+  }
+  if (s_poi[0] < poi[0] && e_poi[1] < poi[1]) {
+    return false;
+  }
+  let xseg = e_poi[0] - (e_poi[0] - s_poi[0]) * (e_poi[1] - poi[1]) / (e_poi[1] - s_poi[1]);
+  if (xseg < poi[0]) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+function isPoiWithinPoly(poi, poly, mercator) {
+  let sinsc = 0;
+  for (let i = 0; i < poly.length; i++) {
+    let epoly = poly[i][0];
+    if (poly.length == 1) {
+      epoly = poly[i][0]
+    }
+    for (let j = 0; j < epoly.length - 1; j++) {
+      let s_poi = epoly[j];
+      let e_poi = epoly[j + 1];
+      if (mercator) {
+        s_poi = lonlat2mercator(epoly[j][0], epoly[j][1]);
+        e_poi = lonlat2mercator(epoly[j + 1][0], epoly[j + 1][1]);
+      }
+      if (isRayIntersectsSegment(poi, s_poi, e_poi)) {
+        sinsc += 1;
+      }
+    }
+  }
+  if (sinsc % 2 == 1) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+function drawMapDataPoints(series, opts, config, context) {
+  var mapOption = assign({}, {
+    border: true,
+    mercator: false,
+    borderWidth: 1,
+    active:true,
+    borderColor: '#666666',
+    fillOpacity: 0.6,
+    activeBorderColor: '#f04864',
+    activeFillColor: '#facc14',
+    activeFillOpacity: 1
+  }, opts.extra.map);
+  var coords, point;
+  var data = series;
+  var bounds = getBoundingBox(data);
+  if (mapOption.mercator) {
+    var max = lonlat2mercator(bounds.xMax, bounds.yMax)
+    var min = lonlat2mercator(bounds.xMin, bounds.yMin)
+    bounds.xMax = max[0]
+    bounds.yMax = max[1]
+    bounds.xMin = min[0]
+    bounds.yMin = min[1]
+  }
+  var xScale = opts.width / Math.abs(bounds.xMax - bounds.xMin);
+  var yScale = opts.height / Math.abs(bounds.yMax - bounds.yMin);
+  var scale = xScale < yScale ? xScale : yScale;
+  var xoffset = opts.width / 2 - Math.abs(bounds.xMax - bounds.xMin) / 2 * scale;
+  var yoffset = opts.height / 2 - Math.abs(bounds.yMax - bounds.yMin) / 2 * scale;
+  for (var i = 0; i < data.length; i++) {
+    context.beginPath();
+    context.setLineWidth(mapOption.borderWidth * opts.pix);
+    context.setStrokeStyle(mapOption.borderColor);
+    context.setFillStyle(hexToRgb(series[i].color, series[i].fillOpacity||mapOption.fillOpacity));
+    if (mapOption.active == true && opts.tooltip) {
+      if (opts.tooltip.index == i) {
+        context.setStrokeStyle(mapOption.activeBorderColor);
+        context.setFillStyle(hexToRgb(mapOption.activeFillColor, mapOption.activeFillOpacity));
+      }
+    }
+    var coorda = data[i].geometry.coordinates
+    for (var k = 0; k < coorda.length; k++) {
+      coords = coorda[k];
+      if (coords.length == 1) {
+        coords = coords[0]
+      }
+      for (var j = 0; j < coords.length; j++) {
+        var gaosi = Array(2);
+        if (mapOption.mercator) {
+          gaosi = lonlat2mercator(coords[j][0], coords[j][1])
+        } else {
+          gaosi = coords[j]
+        }
+        point = coordinateToPoint(gaosi[1], gaosi[0], bounds, scale, xoffset, yoffset)
+        if (j === 0) {
+          context.beginPath();
+          context.moveTo(point.x, point.y);
+        } else {
+          context.lineTo(point.x, point.y);
+        }
+      }
+      context.fill();
+      if (mapOption.border == true) {
+        context.stroke();
+      }
+    }
+  }
+  if (opts.dataLabel == true) {
+    for (var i = 0; i < data.length; i++) {
+      var centerPoint = data[i].properties.centroid;
+      if (centerPoint) {
+        if (mapOption.mercator) {
+          centerPoint = lonlat2mercator(data[i].properties.centroid[0], data[i].properties.centroid[1])
+        }
+        point = coordinateToPoint(centerPoint[1], centerPoint[0], bounds, scale, xoffset, yoffset);
+        let fontSize = data[i].textSize * opts.pix || config.fontSize;
+        let fontColor = data[i].textColor || opts.fontColor;
+        if(mapOption.active && mapOption.activeTextColor && opts.tooltip && opts.tooltip.index == i){
+          fontColor = mapOption.activeTextColor;
+        }
+        let text = data[i].properties.name;
+        context.beginPath();
+        context.setFontSize(fontSize)
+        context.setFillStyle(fontColor)
+        context.fillText(text, point.x - measureText(text, fontSize, context) / 2, point.y + fontSize / 2);
+        context.closePath();
+        context.stroke();
+      }
+    }
+  }
+  opts.chartData.mapData = {
+    bounds: bounds,
+    scale: scale,
+    xoffset: xoffset,
+    yoffset: yoffset,
+    mercator: mapOption.mercator
+  }
+  drawToolTipBridge(opts, config, context, 1);
+  context.draw();
+}
+
+function normalInt(min, max, iter) {
+  iter = iter == 0 ? 1 : iter;
+  var arr = [];
+  for (var i = 0; i < iter; i++) {
+    arr[i] = Math.random();
+  };
+  return Math.floor(arr.reduce(function(i, j) {
+    return i + j
+  }) / iter * (max - min)) + min;
+};
+
+function collisionNew(area, points, width, height) {
+  var isIn = false;
+  for (let i = 0; i < points.length; i++) {
+    if (points[i].area) {
+      if (area[3] < points[i].area[1] || area[0] > points[i].area[2] || area[1] > points[i].area[3] || area[2] < points[i].area[0]) {
+        if (area[0] < 0 || area[1] < 0 || area[2] > width || area[3] > height) {
+          isIn = true;
+          break;
+        } else {
+          isIn = false;
+        }
+      } else {
+        isIn = true;
+        break;
+      }
+    }
+  }
+  return isIn;
+};
+
+function getWordCloudPoint(opts, type, context) {
+  let points = opts.series;
+  switch (type) {
+    case 'normal':
+      for (let i = 0; i < points.length; i++) {
+        let text = points[i].name;
+        let tHeight = points[i].textSize * opts.pix;
+        let tWidth = measureText(text, tHeight, context);
+        let x, y;
+        let area;
+        let breaknum = 0;
+        while (true) {
+          breaknum++;
+          x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+          y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+          area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 +
+            opts.height / 2
+          ];
+          let isCollision = collisionNew(area, points, opts.width, opts.height);
+          if (!isCollision) break;
+          if (breaknum == 1000) {
+            area = [-100, -100, -100, -100];
+            break;
+          }
+        };
+        points[i].area = area;
+      }
+      break;
+    case 'vertical':
+      function Spin() {
+        //获取均匀随机值,是否旋转,旋转的概率为(1-0.5)
+        if (Math.random() > 0.7) {
+          return true;
+        } else {
+          return false
+        };
+      };
+      for (let i = 0; i < points.length; i++) {
+        let text = points[i].name;
+        let tHeight = points[i].textSize * opts.pix;
+        let tWidth = measureText(text, tHeight, context);
+        let isSpin = Spin();
+        let x, y, area, areav;
+        let breaknum = 0;
+        while (true) {
+          breaknum++;
+          let isCollision;
+          if (isSpin) {
+            x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+            y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+            area = [y - 5 - tWidth + opts.width / 2, (-x - 5 + opts.height / 2), y + 5 + opts.width / 2, (-x + tHeight + 5 + opts.height / 2)];
+            areav = [opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) - 5, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) - 5, opts.width - (opts.width / 2 - opts.height / 2) - (-x + tHeight + 5 + opts.height / 2) + tHeight, (opts.height / 2 - opts.width / 2) + (y - 5 - tWidth + opts.width / 2) + tWidth + 5];
+            isCollision = collisionNew(areav, points, opts.height, opts.width);
+          } else {
+            x = normalInt(-opts.width / 2, opts.width / 2, 5) - tWidth / 2;
+            y = normalInt(-opts.height / 2, opts.height / 2, 5) + tHeight / 2;
+            area = [x - 5 + opts.width / 2, y - 5 - tHeight + opts.height / 2, x + tWidth + 5 + opts.width / 2, y + 5 + opts.height / 2];
+            isCollision = collisionNew(area, points, opts.width, opts.height);
+          }
+          if (!isCollision) break;
+          if (breaknum == 1000) {
+            area = [-1000, -1000, -1000, -1000];
+            break;
+          }
+        };
+        if (isSpin) {
+          points[i].area = areav;
+          points[i].areav = area;
+        } else {
+          points[i].area = area;
+        }
+        points[i].rotate = isSpin;
+      };
+      break;
+  }
+  return points;
+}
+
+function drawWordCloudDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let wordOption = assign({}, {
+    type: 'normal',
+    autoColors: true
+  }, opts.extra.word);
+  if (!opts.chartData.wordCloudData) {
+    opts.chartData.wordCloudData = getWordCloudPoint(opts, wordOption.type, context);
+  }
+  context.beginPath();
+  context.setFillStyle(opts.background);
+  context.rect(0, 0, opts.width, opts.height);
+  context.fill();
+  context.save();
+  let points = opts.chartData.wordCloudData;
+  context.translate(opts.width / 2, opts.height / 2);
+  for (let i = 0; i < points.length; i++) {
+    context.save();
+    if (points[i].rotate) {
+      context.rotate(90 * Math.PI / 180);
+    }
+    let text = points[i].name;
+    let tHeight = points[i].textSize * opts.pix;
+    let tWidth = measureText(text, tHeight, context);
+    context.beginPath();
+    context.setStrokeStyle(points[i].color);
+    context.setFillStyle(points[i].color);
+    context.setFontSize(tHeight);
+    if (points[i].rotate) {
+      if (points[i].areav[0] > 0) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.strokeText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+          } else {
+            context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+          }
+        } else {
+          context.fillText(text, (points[i].areav[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].areav[1] + 5 + tHeight - opts.height / 2) * process);
+        }
+      }
+    } else {
+      if (points[i].area[0] > 0) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.strokeText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process);
+          } else {
+            context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process);
+          }
+        } else {
+          context.fillText(text, (points[i].area[0] + 5 - opts.width / 2) * process - tWidth * (1 - process) / 2, (points[i].area[1] + 5 + tHeight - opts.height / 2) * process);
+        }
+      }
+    }
+    context.stroke();
+    context.restore();
+  }
+  context.restore();
+}
+
+function drawFunnelDataPoints(series, opts, config, context) {
+  let process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
+  let funnelOption = assign({}, {
+    type:'funnel',
+    activeWidth: 10,
+    activeOpacity: 0.3,
+    border: false,
+    borderWidth: 2,
+    borderColor: '#FFFFFF',
+    fillOpacity: 1,
+    minSize: 0,
+    labelAlign: 'right',
+    linearType: 'none',
+    customColor: [],
+  }, opts.extra.funnel);
+  let eachSpacing = (opts.height - opts.area[0] - opts.area[2]) / series.length;
+  let centerPosition = {
+    x: opts.area[3] + (opts.width - opts.area[1] - opts.area[3]) / 2,
+    y: opts.height - opts.area[2]
+  };
+  let activeWidth = funnelOption.activeWidth * opts.pix;
+  let radius = Math.min((opts.width - opts.area[1] - opts.area[3]) / 2 - activeWidth, (opts.height - opts.area[0] - opts.area[2]) / 2 - activeWidth);
+  let seriesNew = getFunnelDataPoints(series, radius, funnelOption, eachSpacing, process);
+  context.save();
+  context.translate(centerPosition.x, centerPosition.y);
+  funnelOption.customColor = fillCustomColor(funnelOption.linearType, funnelOption.customColor, series, config);
+  if(funnelOption.type == 'pyramid'){
+    for (let i = 0; i < seriesNew.length; i++) {
+      if (i == seriesNew.length -1) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(-activeWidth, -eachSpacing);
+            context.lineTo(-seriesNew[i].radius - activeWidth, 0);
+            context.lineTo(seriesNew[i].radius + activeWidth, 0);
+            context.lineTo(activeWidth, -eachSpacing);
+            context.lineTo(-activeWidth, -eachSpacing);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, -eachSpacing);
+        context.lineTo(-seriesNew[i].radius, 0);
+        context.lineTo(seriesNew[i].radius, 0);
+        context.lineTo(0, -eachSpacing);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      } else {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(0, 0);
+            context.lineTo(-seriesNew[i].radius - activeWidth, 0);
+            context.lineTo(-seriesNew[i + 1].radius - activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i + 1].radius + activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i].radius + activeWidth, 0);
+            context.lineTo(0, 0);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (i + 1), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * i];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, 0);
+        context.lineTo(-seriesNew[i].radius, 0);
+        context.lineTo(-seriesNew[i + 1].radius, -eachSpacing);
+        context.lineTo(seriesNew[i + 1].radius, -eachSpacing);
+        context.lineTo(seriesNew[i].radius, 0);
+        context.lineTo(0, 0);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      }
+      context.translate(0, -eachSpacing)
+    }
+  }else{
+    context.translate(0, - (seriesNew.length - 1) * eachSpacing);
+    for (let i = 0; i < seriesNew.length; i++) {
+      if (i == seriesNew.length - 1) {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(-activeWidth - funnelOption.minSize/2, 0);
+            context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing);
+            context.lineTo(activeWidth + funnelOption.minSize/2, 0);
+            context.lineTo(-activeWidth - funnelOption.minSize/2, 0);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing, centerPosition.x + seriesNew[i].radius, centerPosition.y ];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, 0);
+        context.lineTo(-funnelOption.minSize/2, 0);
+        context.lineTo(-seriesNew[i].radius, -eachSpacing);
+        context.lineTo(seriesNew[i].radius, -eachSpacing);
+        context.lineTo(funnelOption.minSize/2, 0);
+        context.lineTo(0, 0);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      } else {
+        if (opts.tooltip) {
+          if (opts.tooltip.index == i) {
+            context.beginPath();
+            context.setFillStyle(hexToRgb(seriesNew[i].color, funnelOption.activeOpacity));
+            context.moveTo(0, 0);
+            context.lineTo(-seriesNew[i + 1].radius - activeWidth, 0);
+            context.lineTo(-seriesNew[i].radius - activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i].radius + activeWidth, -eachSpacing);
+            context.lineTo(seriesNew[i + 1].radius + activeWidth, 0);
+            context.lineTo(0, 0);
+            context.closePath();
+            context.fill();
+          }
+        }
+        seriesNew[i].funnelArea = [centerPosition.x - seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i), centerPosition.x + seriesNew[i].radius, centerPosition.y - eachSpacing * (seriesNew.length - i - 1)];
+        context.beginPath();
+        context.setLineWidth(funnelOption.borderWidth * opts.pix);
+        context.setStrokeStyle(funnelOption.borderColor);
+        var fillColor = hexToRgb(seriesNew[i].color, funnelOption.fillOpacity);
+        if (funnelOption.linearType == 'custom') {
+          var grd = context.createLinearGradient(seriesNew[i].radius, -eachSpacing, -seriesNew[i].radius, -eachSpacing);
+          grd.addColorStop(0, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          grd.addColorStop(0.5, hexToRgb(funnelOption.customColor[seriesNew[i].linearIndex], funnelOption.fillOpacity));
+          grd.addColorStop(1, hexToRgb(seriesNew[i].color, funnelOption.fillOpacity));
+          fillColor = grd
+        }
+        context.setFillStyle(fillColor);
+        context.moveTo(0, 0);
+        context.lineTo(-seriesNew[i + 1].radius, 0);
+        context.lineTo(-seriesNew[i].radius, -eachSpacing);
+        context.lineTo(seriesNew[i].radius, -eachSpacing);
+        context.lineTo(seriesNew[i + 1].radius, 0);
+        context.lineTo(0, 0);
+        context.closePath();
+        context.fill();
+        if (funnelOption.border == true) {
+          context.stroke();
+        }
+      }
+      context.translate(0, eachSpacing)
+    }
+  }
+  
+  context.restore();
+  if (opts.dataLabel !== false && process === 1) {
+    drawFunnelText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition);
+  }
+  if (process === 1) {
+    drawFunnelCenterText(seriesNew, opts, context, eachSpacing, funnelOption.labelAlign, activeWidth, centerPosition);
+  }
+  return {
+    center: centerPosition,
+    radius: radius,
+    series: seriesNew
+  };
+}
+
+function drawFunnelText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) {
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    if(item.labelShow === false){
+      continue;
+    }
+    let startX, endX, startY, fontSize;
+    let text = item.formatter ? item.formatter(item,i,series,opts) : util.toFixed(item._proportion_ * 100) + '%';
+    text = item.labelText ? item.labelText : text;
+    if (labelAlign == 'right') {
+      if (i == series.length -1) {
+        startX = (item.funnelArea[2] + centerPosition.x) / 2;
+      } else {
+        startX = (item.funnelArea[2] + series[i + 1].funnelArea[2]) / 2;
+      }
+      endX = startX + activeWidth * 2;
+      startY = item.funnelArea[1] + eachSpacing / 2;
+      fontSize = item.textSize * opts.pix || opts.fontSize * opts.pix;
+      context.setLineWidth(1 * opts.pix);
+      context.setStrokeStyle(item.color);
+      context.setFillStyle(item.color);
+      context.beginPath();
+      context.moveTo(startX, startY);
+      context.lineTo(endX, startY);
+      context.stroke();
+      context.closePath();
+      context.beginPath();
+      context.moveTo(endX, startY);
+      context.arc(endX, startY, 2 * opts.pix, 0, 2 * Math.PI);
+      context.closePath();
+      context.fill();
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.textColor || opts.fontColor);
+      context.fillText(text, endX + 5, startY + fontSize / 2 - 2);
+      context.closePath();
+      context.stroke();
+      context.closePath();
+    }
+    if (labelAlign == 'left') {
+      if (i == series.length -1) {
+        startX = (item.funnelArea[0] + centerPosition.x) / 2;
+      } else {
+        startX = (item.funnelArea[0] + series[i + 1].funnelArea[0]) / 2;
+      }
+      endX = startX - activeWidth * 2;
+      startY = item.funnelArea[1] + eachSpacing / 2;
+      fontSize = item.textSize * opts.pix || opts.fontSize * opts.pix;
+      context.setLineWidth(1 * opts.pix);
+      context.setStrokeStyle(item.color);
+      context.setFillStyle(item.color);
+      context.beginPath();
+      context.moveTo(startX, startY);
+      context.lineTo(endX, startY);
+      context.stroke();
+      context.closePath();
+      context.beginPath();
+      context.moveTo(endX, startY);
+      context.arc(endX, startY, 2, 0, 2 * Math.PI);
+      context.closePath();
+      context.fill();
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.textColor || opts.fontColor);
+      context.fillText(text, endX - 5 - measureText(text, fontSize, context), startY + fontSize / 2 - 2);
+      context.closePath();
+      context.stroke();
+      context.closePath();
+    }
+  }
+}
+
+function drawFunnelCenterText(series, opts, context, eachSpacing, labelAlign, activeWidth, centerPosition) {
+  for (let i = 0; i < series.length; i++) {
+    let item = series[i];
+    let startY, fontSize;
+    if (item.centerText) {
+      startY = item.funnelArea[1] + eachSpacing / 2;
+      fontSize = item.centerTextSize * opts.pix || opts.fontSize * opts.pix;
+      context.beginPath();
+      context.setFontSize(fontSize);
+      context.setFillStyle(item.centerTextColor || "#FFFFFF");
+      context.fillText(item.centerText, centerPosition.x - measureText(item.centerText, fontSize, context) / 2, startY + fontSize / 2 - 2);
+      context.closePath();
+      context.stroke();
+      context.closePath();
+    }
+  }
+}
+
+
+function drawCanvas(opts, context) {
+  context.save();
+  context.translate(0, 0.5);
+  context.restore();
+  context.draw();
+}
+
+var Timing = {
+  easeIn: function easeIn(pos) {
+    return Math.pow(pos, 3);
+  },
+  easeOut: function easeOut(pos) {
+    return Math.pow(pos - 1, 3) + 1;
+  },
+  easeInOut: function easeInOut(pos) {
+    if ((pos /= 0.5) < 1) {
+      return 0.5 * Math.pow(pos, 3);
+    } else {
+      return 0.5 * (Math.pow(pos - 2, 3) + 2);
+    }
+  },
+  linear: function linear(pos) {
+    return pos;
+  }
+};
+
+function Animation(opts) {
+  this.isStop = false;
+  opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
+  opts.timing = opts.timing || 'easeInOut';
+  var delay = 17;
+  function createAnimationFrame() {
+    if (typeof setTimeout !== 'undefined') {
+      return function(step, delay) {
+        setTimeout(function() {
+          var timeStamp = +new Date();
+          step(timeStamp);
+        }, delay);
+      };
+    } else if (typeof requestAnimationFrame !== 'undefined') {
+      return requestAnimationFrame;
+    } else {
+      return function(step) {
+        step(null);
+      };
+    }
+  };
+  var animationFrame = createAnimationFrame();
+  var startTimeStamp = null;
+  var _step = function step(timestamp) {
+    if (timestamp === null || this.isStop === true) {
+      opts.onProcess && opts.onProcess(1);
+      opts.onAnimationFinish && opts.onAnimationFinish();
+      return;
+    }
+    if (startTimeStamp === null) {
+      startTimeStamp = timestamp;
+    }
+    if (timestamp - startTimeStamp < opts.duration) {
+      var process = (timestamp - startTimeStamp) / opts.duration;
+      var timingFunction = Timing[opts.timing];
+      process = timingFunction(process);
+      opts.onProcess && opts.onProcess(process);
+      animationFrame(_step, delay);
+    } else {
+      opts.onProcess && opts.onProcess(1);
+      opts.onAnimationFinish && opts.onAnimationFinish();
+    }
+  };
+  _step = _step.bind(this);
+  animationFrame(_step, delay);
+}
+
+Animation.prototype.stop = function() {
+  this.isStop = true;
+};
+
+function drawCharts(type, opts, config, context) {
+  var _this = this;
+  var series = opts.series;
+  //兼容ECharts饼图类数据格式
+  if (type === 'pie' || type === 'ring' || type === 'mount' || type === 'rose' || type === 'funnel') {
+    series = fixPieSeries(series, opts, config);
+  }
+  var categories = opts.categories;
+  if (type === 'mount') {
+    categories = [];
+    for (let j = 0; j < series.length; j++) {
+      if(series[j].show !== false) categories.push(series[j].name)
+    }
+    opts.categories = categories;
+  }
+  series = fillSeries(series, opts, config);
+  var duration = opts.animation ? opts.duration : 0;
+  _this.animationInstance && _this.animationInstance.stop();
+  var seriesMA = null;
+  if (type == 'candle') {
+    let average = assign({}, opts.extra.candle.average);
+    if (average.show) {
+      seriesMA = calCandleMA(average.day, average.name, average.color, series[0].data);
+      seriesMA = fillSeries(seriesMA, opts, config);
+      opts.seriesMA = seriesMA;
+    } else if (opts.seriesMA) {
+      seriesMA = opts.seriesMA = fillSeries(opts.seriesMA, opts, config);
+    } else {
+      seriesMA = series;
+    }
+  } else {
+    seriesMA = series;
+  }
+  /* 过滤掉show=false的series */
+  opts._series_ = series = filterSeries(series);
+  //重新计算图表区域
+  opts.area = new Array(4);
+  //复位绘图区域
+  for (let j = 0; j < 4; j++) {
+    opts.area[j] = opts.padding[j] * opts.pix;
+  }
+  //通过计算三大区域:图例、X轴、Y轴的大小,确定绘图区域
+  var _calLegendData = calLegendData(seriesMA, opts, config, opts.chartData, context),
+    legendHeight = _calLegendData.area.wholeHeight,
+    legendWidth = _calLegendData.area.wholeWidth;
+
+  switch (opts.legend.position) {
+    case 'top':
+      opts.area[0] += legendHeight;
+      break;
+    case 'bottom':
+      opts.area[2] += legendHeight;
+      break;
+    case 'left':
+      opts.area[3] += legendWidth;
+      break;
+    case 'right':
+      opts.area[1] += legendWidth;
+      break;
+  }
+
+  let _calYAxisData = {},
+    yAxisWidth = 0;
+  if (opts.type === 'line' || opts.type === 'column'|| opts.type === 'mount' || opts.type === 'area' || opts.type === 'mix' || opts.type === 'candle' || opts.type === 'scatter'  || opts.type === 'bubble' || opts.type === 'bar') {
+      _calYAxisData = calYAxisData(series, opts, config, context);
+      yAxisWidth = _calYAxisData.yAxisWidth;
+    //如果显示Y轴标题
+    if (opts.yAxis.showTitle) {
+      let maxTitleHeight = 0;
+      for (let i = 0; i < opts.yAxis.data.length; i++) {
+        maxTitleHeight = Math.max(maxTitleHeight, opts.yAxis.data[i].titleFontSize ? opts.yAxis.data[i].titleFontSize * opts.pix : config.fontSize)
+      }
+      opts.area[0] += maxTitleHeight;
+    }
+    let rightIndex = 0,
+      leftIndex = 0;
+    //计算主绘图区域左右位置
+    for (let i = 0; i < yAxisWidth.length; i++) {
+      if (yAxisWidth[i].position == 'left') {
+        if (leftIndex > 0) {
+          opts.area[3] += yAxisWidth[i].width + opts.yAxis.padding * opts.pix;
+        } else {
+          opts.area[3] += yAxisWidth[i].width;
+        }
+        leftIndex += 1;
+      } else if (yAxisWidth[i].position == 'right') {
+        if (rightIndex > 0) {
+          opts.area[1] += yAxisWidth[i].width + opts.yAxis.padding * opts.pix;
+        } else {
+          opts.area[1] += yAxisWidth[i].width;
+        }
+        rightIndex += 1;
+      }
+    }
+  } else {
+    config.yAxisWidth = yAxisWidth;
+  }
+  opts.chartData.yAxisData = _calYAxisData;
+
+  if (opts.categories && opts.categories.length && opts.type !== 'radar' && opts.type !== 'gauge' && opts.type !== 'bar') {
+    opts.chartData.xAxisData = getXAxisPoints(opts.categories, opts, config);
+    let _calCategoriesData = calCategoriesData(opts.categories, opts, config, opts.chartData.xAxisData.eachSpacing, context),
+      xAxisHeight = _calCategoriesData.xAxisHeight,
+      angle = _calCategoriesData.angle;
+    config.xAxisHeight = xAxisHeight;
+    config._xAxisTextAngle_ = angle;
+    opts.area[2] += xAxisHeight;
+    opts.chartData.categoriesData = _calCategoriesData;
+  } else {
+    if (opts.type === 'line' || opts.type === 'area' || opts.type === 'scatter' || opts.type === 'bubble' || opts.type === 'bar') {
+      opts.chartData.xAxisData = calXAxisData(series, opts, config, context);
+      categories = opts.chartData.xAxisData.rangesFormat;
+      let _calCategoriesData = calCategoriesData(categories, opts, config, opts.chartData.xAxisData.eachSpacing, context),
+        xAxisHeight = _calCategoriesData.xAxisHeight,
+        angle = _calCategoriesData.angle;
+      config.xAxisHeight = xAxisHeight;
+      config._xAxisTextAngle_ = angle;
+      opts.area[2] += xAxisHeight;
+      opts.chartData.categoriesData = _calCategoriesData;
+    } else {
+      opts.chartData.xAxisData = {
+        xAxisPoints: []
+      };
+    }
+  }
+
+  //计算右对齐偏移距离
+  if (opts.enableScroll && opts.xAxis.scrollAlign == 'right' && opts._scrollDistance_ === undefined) {
+    let offsetLeft = 0,
+      xAxisPoints = opts.chartData.xAxisData.xAxisPoints,
+      startX = opts.chartData.xAxisData.startX,
+      endX = opts.chartData.xAxisData.endX,
+      eachSpacing = opts.chartData.xAxisData.eachSpacing;
+    let totalWidth = eachSpacing * (xAxisPoints.length - 1);
+    let screenWidth = endX - startX;
+    offsetLeft = screenWidth - totalWidth;
+    _this.scrollOption.currentOffset = offsetLeft;
+    _this.scrollOption.startTouchX = offsetLeft;
+    _this.scrollOption.distance = 0;
+    _this.scrollOption.lastMoveTime = 0;
+    opts._scrollDistance_ = offsetLeft;
+  }
+
+  if (type === 'pie' || type === 'ring' || type === 'rose') {
+    config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(seriesMA, config, context, opts);
+  }
+  
+  switch (type) {
+    case 'word':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawWordCloudDataPoints(series, opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'map':
+      context.clearRect(0, 0, opts.width, opts.height);
+      drawMapDataPoints(series, opts, config, context);
+      setTimeout(()=>{
+        this.uevent.trigger('renderComplete');
+      },50)
+      break;
+    case 'funnel':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.funnelData = drawFunnelDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'line':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawLineDataPoints = drawLineDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawLineDataPoints.xAxisPoints,
+            calPoints = _drawLineDataPoints.calPoints,
+            eachSpacing = _drawLineDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'scatter':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawScatterDataPoints = drawScatterDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawScatterDataPoints.xAxisPoints,
+            calPoints = _drawScatterDataPoints.calPoints,
+            eachSpacing = _drawScatterDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'bubble':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawBubbleDataPoints = drawBubbleDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawBubbleDataPoints.xAxisPoints,
+            calPoints = _drawBubbleDataPoints.calPoints,
+            eachSpacing = _drawBubbleDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'mix':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawMixDataPoints = drawMixDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawMixDataPoints.xAxisPoints,
+            calPoints = _drawMixDataPoints.calPoints,
+            eachSpacing = _drawMixDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'column':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawColumnDataPoints = drawColumnDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawColumnDataPoints.xAxisPoints,
+            calPoints = _drawColumnDataPoints.calPoints,
+            eachSpacing = _drawColumnDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'mount':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawMountDataPoints = drawMountDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawMountDataPoints.xAxisPoints,
+            calPoints = _drawMountDataPoints.calPoints,
+            eachSpacing = _drawMountDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'bar':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawXAxis(categories, opts, config, context);
+          var _drawBarDataPoints = drawBarDataPoints(series, opts, config, context, process),
+            yAxisPoints = _drawBarDataPoints.yAxisPoints,
+            calPoints = _drawBarDataPoints.calPoints,
+            eachSpacing = _drawBarDataPoints.eachSpacing;
+          opts.chartData.yAxisPoints = yAxisPoints;
+          opts.chartData.xAxisPoints = opts.chartData.xAxisData.xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, yAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'area':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawAreaDataPoints = drawAreaDataPoints(series, opts, config, context, process),
+            xAxisPoints = _drawAreaDataPoints.xAxisPoints,
+            calPoints = _drawAreaDataPoints.calPoints,
+            eachSpacing = _drawAreaDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'ring':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'pie':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'rose':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.pieData = drawRoseDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'radar':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process);
+          drawLegend(opts.series, opts, config, context, opts.chartData);
+          drawToolTipBridge(opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'arcbar':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.arcbarData = drawArcbarDataPoints(series, opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'gauge':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          opts.chartData.gaugeData = drawGaugeDataPoints(categories, series, opts, config, context, process);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+    case 'candle':
+      this.animationInstance = new Animation({
+        timing: opts.timing,
+        duration: duration,
+        onProcess: function onProcess(process) {
+          context.clearRect(0, 0, opts.width, opts.height);
+          if (opts.rotate) {
+            contextRotate(context, opts);
+          }
+          drawYAxisGrid(categories, opts, config, context);
+          drawXAxis(categories, opts, config, context);
+          var _drawCandleDataPoints = drawCandleDataPoints(series, seriesMA, opts, config, context, process),
+            xAxisPoints = _drawCandleDataPoints.xAxisPoints,
+            calPoints = _drawCandleDataPoints.calPoints,
+            eachSpacing = _drawCandleDataPoints.eachSpacing;
+          opts.chartData.xAxisPoints = xAxisPoints;
+          opts.chartData.calPoints = calPoints;
+          opts.chartData.eachSpacing = eachSpacing;
+          drawYAxis(series, opts, config, context);
+          if (opts.enableMarkLine !== false && process === 1) {
+            drawMarkLine(opts, config, context);
+          }
+          if (seriesMA) {
+            drawLegend(seriesMA, opts, config, context, opts.chartData);
+          } else {
+            drawLegend(opts.series, opts, config, context, opts.chartData);
+          }
+          drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
+          drawCanvas(opts, context);
+        },
+        onAnimationFinish: function onAnimationFinish() {
+          _this.uevent.trigger('renderComplete');
+        }
+      });
+      break;
+  }
+}
+
+function uChartsEvent() {
+  this.events = {};
+}
+
+uChartsEvent.prototype.addEventListener = function(type, listener) {
+  this.events[type] = this.events[type] || [];
+  this.events[type].push(listener);
+};
+
+uChartsEvent.prototype.delEventListener = function(type) {
+  this.events[type] = [];
+};
+
+uChartsEvent.prototype.trigger = function() {
+  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+    args[_key] = arguments[_key];
+  }
+  var type = args[0];
+  var params = args.slice(1);
+  if (!!this.events[type]) {
+    this.events[type].forEach(function(listener) {
+      try {
+        listener.apply(null, params);
+      } catch (e) {
+          //console.log('[uCharts] '+e);
+      }
+    });
+  }
+};
+
+var uCharts = function uCharts(opts) {
+  opts.pix = opts.pixelRatio ? opts.pixelRatio : 1;
+  opts.fontSize = opts.fontSize ? opts.fontSize : 13;
+  opts.fontColor = opts.fontColor ? opts.fontColor : config.fontColor;
+  if (opts.background == "" || opts.background == "none") {
+    opts.background = "#FFFFFF"
+  }
+  opts.title = assign({}, opts.title);
+  opts.subtitle = assign({}, opts.subtitle);
+  opts.duration = opts.duration ? opts.duration : 1000;
+  opts.yAxis = assign({}, {
+    data: [],
+    showTitle: false,
+    disabled: false,
+    disableGrid: false,
+    gridSet: 'number',
+    splitNumber: 5,
+    gridType: 'solid',
+    dashLength: 4 * opts.pix,
+    gridColor: '#cccccc',
+    padding: 10,
+    fontColor: '#666666'
+  }, opts.yAxis);
+  opts.xAxis = assign({}, {
+    rotateLabel: false,
+    rotateAngle:45,
+    disabled: false,
+    disableGrid: false,
+    splitNumber: 5,
+    calibration:false,
+    fontColor: '#666666',
+    fontSize: 13,
+    lineHeight: 20,
+    marginTop: 0,
+    gridType: 'solid',
+    dashLength: 4,
+    scrollAlign: 'left',
+    boundaryGap: 'center',
+    axisLine: true,
+    axisLineColor: '#cccccc',
+    titleFontSize: 13,
+    titleOffsetY: 0,
+    titleOffsetX: 0,
+    titleFontColor: '#666666'
+  }, opts.xAxis);
+  opts.xAxis.scrollPosition = opts.xAxis.scrollAlign;
+  opts.legend = assign({}, {
+    show: true,
+    position: 'bottom',
+    float: 'center',
+    backgroundColor: 'rgba(0,0,0,0)',
+    borderColor: 'rgba(0,0,0,0)',
+    borderWidth: 0,
+    padding: 5,
+    margin: 5,
+    itemGap: 10,
+    fontSize: opts.fontSize,
+    lineHeight: opts.fontSize,
+    fontColor: opts.fontColor,
+    formatter: {},
+    hiddenColor: '#CECECE'
+  }, opts.legend);
+  opts.extra = assign({
+    tooltip:{
+      legendShape: 'auto'
+    }
+  }, opts.extra);
+  opts.rotate = opts.rotate ? true : false;
+  opts.animation = opts.animation ? true : false;
+  opts.rotate = opts.rotate ? true : false;
+  opts.canvas2d = opts.canvas2d ? true : false;
+  
+  let config$$1 = assign({}, config);
+  config$$1.color = opts.color ? opts.color : config$$1.color;
+  if (opts.type == 'pie') {
+    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix;
+  }
+  if (opts.type == 'ring') {
+    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.ring.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix;
+  }
+  if (opts.type == 'rose') {
+    config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth * opts.pix || config$$1.pieChartLinePadding * opts.pix;
+  }
+  config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding * opts.pix;
+
+  //屏幕旋转
+  config$$1.rotate = opts.rotate;
+  if (opts.rotate) {
+    let tempWidth = opts.width;
+    let tempHeight = opts.height;
+    opts.width = tempHeight;
+    opts.height = tempWidth;
+  }
+
+  //适配高分屏
+  opts.padding = opts.padding ? opts.padding : config$$1.padding;
+  config$$1.yAxisWidth = config.yAxisWidth * opts.pix;
+  config$$1.fontSize = opts.fontSize * opts.pix;
+  config$$1.titleFontSize = config.titleFontSize * opts.pix;
+  config$$1.subtitleFontSize = config.subtitleFontSize * opts.pix;
+  if(!opts.context){
+    throw new Error('[uCharts] 未获取到context!注意:v2.0版本后,需要自行获取canvas的绘图上下文并传入opts.context!');
+  }
+  this.context = opts.context;
+  if (!this.context.setTextAlign) {
+    this.context.setStrokeStyle = function(e) {
+      return this.strokeStyle = e;
+    }
+    this.context.setLineWidth = function(e) {
+      return this.lineWidth = e;
+    }
+    this.context.setLineCap = function(e) {
+      return this.lineCap = e;
+    }
+    this.context.setFontSize = function(e) {
+      return this.font = e + "px sans-serif";
+    }
+    this.context.setFillStyle = function(e) {
+      return this.fillStyle = e;
+    }
+    this.context.setTextAlign = function(e) {
+      return this.textAlign = e;
+    }
+    this.context.setTextBaseline = function(e) {
+      return this.textBaseline = e;
+    }
+    this.context.setShadow = function(offsetX,offsetY,blur,color) {
+      this.shadowColor = color;
+      this.shadowOffsetX = offsetX;
+      this.shadowOffsetY = offsetY;
+      this.shadowBlur = blur;
+    }
+    this.context.draw = function() {}
+  }
+  //兼容NVUEsetLineDash
+  if(!this.context.setLineDash){
+    this.context.setLineDash = function(e) {}
+  }
+  opts.chartData = {};
+  this.uevent = new uChartsEvent();
+  this.scrollOption = {
+    currentOffset: 0,
+    startTouchX: 0,
+    distance: 0,
+    lastMoveTime: 0
+  };
+  this.opts = opts;
+  this.config = config$$1;
+  drawCharts.call(this, opts.type, opts, config$$1, this.context);
+};
+
+uCharts.prototype.updateData = function() {
+  let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+  this.opts = assign({}, this.opts, data);
+  this.opts.updateData = true;
+  let scrollPosition = data.scrollPosition || 'current';
+  switch (scrollPosition) {
+    case 'current':
+      this.opts._scrollDistance_ = this.scrollOption.currentOffset;
+      break;
+    case 'left':
+      this.opts._scrollDistance_ = 0;
+      this.scrollOption = {
+        currentOffset: 0,
+        startTouchX: 0,
+        distance: 0,
+        lastMoveTime: 0
+      };
+      break;
+    case 'right':
+      let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context), yAxisWidth = _calYAxisData.yAxisWidth;
+      this.config.yAxisWidth = yAxisWidth;
+      let offsetLeft = 0;
+      let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config), xAxisPoints = _getXAxisPoints0.xAxisPoints,
+        startX = _getXAxisPoints0.startX,
+        endX = _getXAxisPoints0.endX,
+        eachSpacing = _getXAxisPoints0.eachSpacing;
+      let totalWidth = eachSpacing * (xAxisPoints.length - 1);
+      let screenWidth = endX - startX;
+      offsetLeft = screenWidth - totalWidth;
+      this.scrollOption = {
+        currentOffset: offsetLeft,
+        startTouchX: offsetLeft,
+        distance: 0,
+        lastMoveTime: 0
+      };
+      this.opts._scrollDistance_ = offsetLeft;
+      break;
+  }
+  drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+};
+
+uCharts.prototype.zoom = function() {
+  var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.opts.xAxis.itemCount;
+  if (this.opts.enableScroll !== true) {
+    console.log('[uCharts] 请启用滚动条后使用')
+    return;
+  }
+  //当前屏幕中间点
+  let centerPoint = Math.round(Math.abs(this.scrollOption.currentOffset) / this.opts.chartData.eachSpacing) + Math.round(this.opts.xAxis.itemCount / 2);
+  this.opts.animation = false;
+  this.opts.xAxis.itemCount = val.itemCount;
+  //重新计算x轴偏移距离
+  let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config, this.context),
+    yAxisWidth = _calYAxisData.yAxisWidth;
+  this.config.yAxisWidth = yAxisWidth;
+  let offsetLeft = 0;
+  let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
+    xAxisPoints = _getXAxisPoints0.xAxisPoints,
+    startX = _getXAxisPoints0.startX,
+    endX = _getXAxisPoints0.endX,
+    eachSpacing = _getXAxisPoints0.eachSpacing;
+  let centerLeft = eachSpacing * centerPoint;
+  let screenWidth = endX - startX;
+  let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
+  offsetLeft = screenWidth / 2 - centerLeft;
+  if (offsetLeft > 0) {
+    offsetLeft = 0;
+  }
+  if (offsetLeft < MaxLeft) {
+    offsetLeft = MaxLeft;
+  }
+  this.scrollOption = {
+    currentOffset: offsetLeft,
+    startTouchX: 0,
+    distance: 0,
+    lastMoveTime: 0
+  };
+  calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts);
+  this.opts._scrollDistance_ = offsetLeft;
+  drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+};
+
+uCharts.prototype.dobuleZoom = function(e) {
+  if (this.opts.enableScroll !== true) {
+    console.log('[uCharts] 请启用滚动条后使用')
+    return;
+  }
+  const tcs = e.changedTouches;
+  if (tcs.length < 2) {
+    return;
+  }
+  for (var i = 0; i < tcs.length; i++) {
+    tcs[i].x = tcs[i].x ? tcs[i].x : tcs[i].clientX;
+    tcs[i].y = tcs[i].y ? tcs[i].y : tcs[i].clientY;
+  }
+  const ntcs = [getTouches(tcs[0], this.opts, e),getTouches(tcs[1], this.opts, e)]; 
+  const xlength = Math.abs(ntcs[0].x - ntcs[1].x);
+  // 记录初始的两指之间的数据
+  if(!this.scrollOption.moveCount){
+    let cts0 = {changedTouches:[{x:tcs[0].x,y:this.opts.area[0] / this.opts.pix + 2}]};
+    let cts1 = {changedTouches:[{x:tcs[1].x,y:this.opts.area[0] / this.opts.pix + 2}]};
+    if(this.opts.rotate){
+      cts0 = {changedTouches:[{x:this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2,y:tcs[0].y}]};
+      cts1 = {changedTouches:[{x:this.opts.height / this.opts.pix - this.opts.area[0] / this.opts.pix - 2,y:tcs[1].y}]};
+    }
+    const moveCurrent1 = this.getCurrentDataIndex(cts0).index;
+    const moveCurrent2 = this.getCurrentDataIndex(cts1).index;
+    const moveCount = Math.abs(moveCurrent1 - moveCurrent2);
+    this.scrollOption.moveCount = moveCount;
+    this.scrollOption.moveCurrent1 = Math.min(moveCurrent1, moveCurrent2);
+    this.scrollOption.moveCurrent2 = Math.max(moveCurrent1, moveCurrent2);
+    return;
+  }
+  
+  let currentEachSpacing = xlength / this.scrollOption.moveCount;
+  let itemCount = (this.opts.width - this.opts.area[1] - this.opts.area[3]) / currentEachSpacing;
+  itemCount = itemCount <= 2 ? 2 : itemCount;
+  itemCount = itemCount >= this.opts.categories.length ? this.opts.categories.length : itemCount;
+  this.opts.animation = false;
+  this.opts.xAxis.itemCount = itemCount;
+  // 重新计算滚动条偏移距离
+  let offsetLeft = 0;
+  let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
+    xAxisPoints = _getXAxisPoints0.xAxisPoints,
+    startX = _getXAxisPoints0.startX,
+    endX = _getXAxisPoints0.endX,
+    eachSpacing = _getXAxisPoints0.eachSpacing;
+  let currentLeft = eachSpacing * this.scrollOption.moveCurrent1;
+  let screenWidth = endX - startX;
+  let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
+  offsetLeft = -currentLeft+Math.min(ntcs[0].x,ntcs[1].x)-this.opts.area[3]-eachSpacing;
+  if (offsetLeft > 0) {
+    offsetLeft = 0;
+  }
+  if (offsetLeft < MaxLeft) {
+    offsetLeft = MaxLeft;
+  }
+  this.scrollOption.currentOffset= offsetLeft;
+  this.scrollOption.startTouchX= 0;
+  this.scrollOption.distance=0;
+  calValidDistance(this, offsetLeft, this.opts.chartData, this.config, this.opts);
+  this.opts._scrollDistance_ = offsetLeft;
+  drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+}
+
+uCharts.prototype.stopAnimation = function() {
+  this.animationInstance && this.animationInstance.stop();
+};
+
+uCharts.prototype.addEventListener = function(type, listener) {
+  this.uevent.addEventListener(type, listener);
+};
+
+uCharts.prototype.delEventListener = function(type) {
+  this.uevent.delEventListener(type);
+};
+
+uCharts.prototype.getCurrentDataIndex = function(e) {
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches) {
+    let _touches$ = getTouches(touches, this.opts, e);
+    if (this.opts.type === 'pie' || this.opts.type === 'ring') {
+      return findPieChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.pieData, this.opts);
+    } else if (this.opts.type === 'rose') {
+      return findRoseChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.pieData, this.opts);
+    } else if (this.opts.type === 'radar') {
+      return findRadarChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.radarData, this.opts.categories.length);
+    } else if (this.opts.type === 'funnel') {
+      return findFunnelChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.funnelData);
+    } else if (this.opts.type === 'map') {
+      return findMapChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts);
+    } else if (this.opts.type === 'word') {
+      return findWordChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.wordCloudData);
+    } else if (this.opts.type === 'bar') {
+      return findBarChartCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
+    } else {
+      return findCurrentIndex({
+        x: _touches$.x,
+        y: _touches$.y
+      }, this.opts.chartData.calPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
+    }
+  }
+  return -1;
+};
+
+uCharts.prototype.getLegendDataIndex = function(e) {
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches) {
+    let _touches$ = getTouches(touches, this.opts, e);
+    return findLegendIndex({
+      x: _touches$.x,
+      y: _touches$.y
+    }, this.opts.chartData.legendData);
+  }
+  return -1;
+};
+
+uCharts.prototype.touchLegend = function(e) {
+  var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches) {
+    var _touches$ = getTouches(touches, this.opts, e);
+    var index = this.getLegendDataIndex(e);
+    if (index >= 0) {
+      if (this.opts.type == 'candle') {
+        this.opts.seriesMA[index].show = !this.opts.seriesMA[index].show;
+      } else {
+        this.opts.series[index].show = !this.opts.series[index].show;
+      }
+      this.opts.animation = option.animation ? true : false;
+      this.opts._scrollDistance_ = this.scrollOption.currentOffset;
+      drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
+    }
+  }
+
+};
+
+uCharts.prototype.showToolTip = function(e) {
+  var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (!touches) {
+    console.log("[uCharts] 未获取到event坐标信息");
+  }
+  var _touches$ = getTouches(touches, this.opts, e);
+  var currentOffset = this.scrollOption.currentOffset;
+  var opts = assign({}, this.opts, {
+    _scrollDistance_: currentOffset,
+    animation: false
+  });
+  if (this.opts.type === 'line' || this.opts.type === 'area' || this.opts.type === 'column' || this.opts.type === 'scatter' || this.opts.type === 'bubble') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1 || index.length>0) {
+      var seriesData = getSeriesDataItem(this.opts.series, index, current.group);
+      if (seriesData.length !== 0) {
+        var _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option),
+          textList = _getToolTipData.textList,
+          offset = _getToolTipData.offset;
+        offset.y = _touches$.y;
+        opts.tooltip = {
+          textList: option.textList !== undefined ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index,
+          group: current.group
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'mount') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e).index : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, opts._series_[index]);
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: opts.chartData.calPoints[index].x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'bar') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1 || index.length>0) {
+      var seriesData = getSeriesDataItem(this.opts.series, index, current.group);
+      if (seriesData.length !== 0) {
+        var _getToolTipData = getToolTipData(seriesData, this.opts, index, current.group, this.opts.categories, option),
+          textList = _getToolTipData.textList,
+          offset = _getToolTipData.offset;
+        offset.x = _touches$.x;
+        opts.tooltip = {
+          textList: option.textList !== undefined ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'mix') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1) {
+      var currentOffset = this.scrollOption.currentOffset;
+      var opts = assign({}, this.opts, {
+        _scrollDistance_: currentOffset,
+        animation: false
+      });
+      var seriesData = getSeriesDataItem(this.opts.series, index);
+      if (seriesData.length !== 0) {
+        var _getMixToolTipData = getMixToolTipData(seriesData, this.opts, index, this.opts.categories, option),
+          textList = _getMixToolTipData.textList,
+          offset = _getMixToolTipData.offset;
+        offset.y = _touches$.y;
+        opts.tooltip = {
+          textList: option.textList ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'candle') {
+    var current = this.getCurrentDataIndex(e);
+    var index = option.index == undefined ? current.index : option.index;
+    if (index > -1) {
+      var currentOffset = this.scrollOption.currentOffset;
+      var opts = assign({}, this.opts, {
+        _scrollDistance_: currentOffset,
+        animation: false
+      });
+      var seriesData = getSeriesDataItem(this.opts.series, index);
+      if (seriesData.length !== 0) {
+        var _getToolTipData = getCandleToolTipData(this.opts.series[0].data, seriesData, this.opts, index, this.opts.categories, this.opts.extra.candle, option),
+          textList = _getToolTipData.textList,
+          offset = _getToolTipData.offset;
+        offset.y = _touches$.y;
+        opts.tooltip = {
+          textList: option.textList ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose' || this.opts.type === 'funnel') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, opts._series_[index]);
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, opts) : seriesData.name + ': ' + seriesData.data,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: _touches$.x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'map') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, this.opts.series[index]);
+      seriesData.name = seriesData.properties.name
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: _touches$.x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    opts.updateData = false;
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'word') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = assign({}, this.opts.series[index]);
+      var textList = [{
+        text: option.formatter ? option.formatter(seriesData, undefined, index, this.opts) : seriesData.name,
+        color: seriesData.color,
+        legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? seriesData.legendShape : this.opts.extra.tooltip.legendShape
+      }];
+      var offset = {
+        x: _touches$.x,
+        y: _touches$.y
+      };
+      opts.tooltip = {
+        textList: option.textList ? option.textList : textList,
+        offset: option.offset !== undefined ? option.offset : offset,
+        option: option,
+        index: index
+      };
+    }
+    opts.updateData = false;
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+  if (this.opts.type === 'radar') {
+    var index = option.index == undefined ? this.getCurrentDataIndex(e) : option.index;
+    if (index > -1) {
+      var opts = assign({}, this.opts, {animation: false});
+      var seriesData = getSeriesDataItem(this.opts.series, index);
+      if (seriesData.length !== 0) {
+        var textList = seriesData.map((item) => {
+          return {
+            text: option.formatter ? option.formatter(item, this.opts.categories[index], index, this.opts) : item.name + ': ' + item.data,
+            color: item.color,
+            legendShape: this.opts.extra.tooltip.legendShape == 'auto' ? item.legendShape : this.opts.extra.tooltip.legendShape
+          };
+        });
+        var offset = {
+          x: _touches$.x,
+          y: _touches$.y
+        };
+        opts.tooltip = {
+          textList: option.textList ? option.textList : textList,
+          offset: option.offset !== undefined ? option.offset : offset,
+          option: option,
+          index: index
+        };
+      }
+    }
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+  }
+};
+
+uCharts.prototype.translate = function(distance) {
+  this.scrollOption = {
+    currentOffset: distance,
+    startTouchX: distance,
+    distance: 0,
+    lastMoveTime: 0
+  };
+  let opts = assign({}, this.opts, {
+    _scrollDistance_: distance,
+    animation: false
+  });
+  drawCharts.call(this, this.opts.type, opts, this.config, this.context);
+};
+
+uCharts.prototype.scrollStart = function(e) {
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  var _touches$ = getTouches(touches, this.opts, e);
+  if (touches && this.opts.enableScroll === true) {
+    this.scrollOption.startTouchX = _touches$.x;
+  }
+};
+
+uCharts.prototype.scroll = function(e) {
+  if (this.scrollOption.lastMoveTime === 0) {
+    this.scrollOption.lastMoveTime = Date.now();
+  }
+  let Limit = this.opts.touchMoveLimit || 60;
+  let currMoveTime = Date.now();
+  let duration = currMoveTime - this.scrollOption.lastMoveTime;
+  if (duration < Math.floor(1000 / Limit)) return;
+  if (this.scrollOption.startTouchX == 0) return;
+  this.scrollOption.lastMoveTime = currMoveTime;
+  var touches = null;
+  if (e.changedTouches) {
+    touches = e.changedTouches[0];
+  } else {
+    touches = e.mp.changedTouches[0];
+  }
+  if (touches && this.opts.enableScroll === true) {
+    var _touches$ = getTouches(touches, this.opts, e);
+    var _distance;
+    _distance = _touches$.x - this.scrollOption.startTouchX;
+    var currentOffset = this.scrollOption.currentOffset;
+    var validDistance = calValidDistance(this, currentOffset + _distance, this.opts.chartData, this.config, this.opts);
+    this.scrollOption.distance = _distance = validDistance - currentOffset;
+    var opts = assign({}, this.opts, {
+      _scrollDistance_: currentOffset + _distance,
+      animation: false
+    });
+		this.opts = opts;
+    drawCharts.call(this, opts.type, opts, this.config, this.context);
+    return currentOffset + _distance;
+  }
+};
+
+uCharts.prototype.scrollEnd = function(e) {
+  if (this.opts.enableScroll === true) {
+    var _scrollOption = this.scrollOption,
+      currentOffset = _scrollOption.currentOffset,
+      distance = _scrollOption.distance;
+    this.scrollOption.currentOffset = currentOffset + distance;
+    this.scrollOption.distance = 0;
+    this.scrollOption.moveCount = 0;
+  }
+};
+
+export default uCharts;

Файловите разлики са ограничени, защото са твърде много
+ 17 - 0
mine/components/qiun-data-charts/js_sdk/u-charts/u-charts.min.js


+ 201 - 0
mine/components/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.

+ 81 - 0
mine/components/qiun-data-charts/package.json

@@ -0,0 +1,81 @@
+{
+  "id": "qiun-data-charts",
+  "displayName": "秋云 ucharts echarts 高性能跨全端图表组件",
+  "version": "2.5.0-20230101",
+  "description": "uCharts 新增正负柱状图!支持H5及APP用 ucharts echarts 渲染图表,uniapp可视化首选组件",
+  "keywords": [
+    "ucharts",
+    "echarts",
+    "f2",
+    "图表",
+    "可视化"
+],
+  "repository": "https://gitee.com/uCharts/uCharts",
+  "engines": {
+    "HBuilderX": "^3.3.8"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": "474119"
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/~qiun",
+    "type": "component-vue"
+  },
+  "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"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 84 - 0
mine/components/qiun-data-charts/readme.md

@@ -0,0 +1,84 @@
+![logo](https://img-blog.csdnimg.cn/4a276226973841468c1be356f8d9438b.png)
+
+
+[![star](https://gitee.com/uCharts/uCharts/badge/star.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/stargazers)
+[![fork](https://gitee.com/uCharts/uCharts/badge/fork.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/members)
+[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
+[![npm package](https://img.shields.io/npm/v/@qiun/ucharts.svg?style=flat-square)](https://www.npmjs.com/~qiun)
+
+
+## uCharts简介
+
+`uCharts`是一款基于`canvas API`开发的适用于所有前端应用的图表库,开发者编写一套代码,可运行到 Web、iOS、Android(基于 uni-app / taro )、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等更多支持 canvas API 的平台。
+
+## 官方网站
+
+## [https://www.ucharts.cn](https://www.ucharts.cn)
+
+## 快速体验
+
+一套代码编到多个平台,依次扫描二维码,亲自体验uCharts图表跨平台效果!其他平台请自行编译。
+
+![](https://www.ucharts.cn/images/web/guide/qrcode20220224.png)
+
+![](https://img-blog.csdnimg.cn/7d0115593ff24ac39a224fb7c6ed72a4.png)
+
+## 致开发者
+
+感谢各位开发者`五年`来对秋云及uCharts的支持,uCharts的进步离不开各位开发者的鼓励与贡献。为更好的帮助各位开发者使用图表工具,我们推出了新版官网,增加了在线定制、问答社区、在线配置等一些增值服务,为确保您能更好的应用图表组件,建议您先`仔细阅读官网指南`以及`常见问题`,而不是下载下来`直接使用`。如仍然不能解决,请到`官网社区`或开通会员后加入`专属VIP会员群`提问将会很快得到回答。
+
+## 视频教程
+
+## [uCharts新手入门教程](https://www.bilibili.com/video/BV1qA411Q7se/?share_source=copy_web&vd_source=42a1242f9aaade6427736af69eb2e1d9)
+
+
+## 社群支持
+
+uCharts官方拥有5个2000人的QQ群及专属VIP会员群支持,庞大的用户量证明我们一直在努力,请各位放心使用!uCharts的开源图表组件的开发,团队付出了大量的时间与精力,经过四来的考验,不会有比较明显的bug,请各位放心使用。如果您有更好的想法,可以在`码云提交Pull Requests`以帮助更多开发者完成需求,再次感谢各位对uCharts的鼓励与支持!
+
+#### 官方交流群
+- 交流群1:371774600(已满)
+- 交流群2:619841586(已满)
+- 交流群3:955340127(已满)
+- 交流群4:641669795(已满)
+- 交流群5:236294809(只能扫码加入)
+
+![](https://www.ucharts.cn/images/web/qq5.jpg)
+
+- 口令`uniapp`
+
+#### 专属VIP会员群
+- 开通会员后详见【账号详情】页面中顶部的滚动通知
+- 口令`您的用户ID`
+
+## 版权信息
+
+uCharts始终坚持开源,遵循 [Apache Licence 2.0](https://www.apache.org/licenses/LICENSE-2.0.html) 开源协议,意味着您无需支付任何费用,即可将uCharts应用到您的产品中。
+
+注意:这并不意味着您可以将uCharts应用到非法的领域,比如涉及赌博,暴力等方面。如因此产生纠纷或法律问题,uCharts相关方及秋云科技不承担任何责任。
+
+## 合作伙伴
+
+[![DIY官网](https://www.ucharts.cn/images/web/guide/links/diy-gw.png)](https://www.diygw.com/)
+[![HasChat](https://www.ucharts.cn/images/web/guide/links/haschat.png)](https://gitee.com/howcode/has-chat)
+[![uViewUI](https://www.ucharts.cn/images/web/guide/links/uView.png)](https://www.uviewui.com/)
+[![图鸟UI](https://www.ucharts.cn/images/web/guide/links/tuniao.png)](https://ext.dcloud.net.cn/plugin?id=7088)
+[![thorui](https://www.ucharts.cn/images/web/guide/links/thorui.png)](https://ext.dcloud.net.cn/publisher?id=202)
+[![FirstUI](https://www.ucharts.cn/images/web/guide/links/first.png)](https://www.firstui.cn/)
+[![nProUI](https://www.ucharts.cn/images/web/guide/links/nPro.png)](https://ext.dcloud.net.cn/plugin?id=5169)
+[![GraceUI](https://www.ucharts.cn/images/web/guide/links/grace.png)](https://www.graceui.com/)
+
+
+## 更新记录
+
+详见官网指南中说明,[点击此处查看](https://www.ucharts.cn/v2/#/guide/index?id=100)
+
+
+## 相关链接
+- [uCharts官网](https://www.ucharts.cn)
+- [DCloud插件市场地址](https://ext.dcloud.net.cn/plugin?id=271)
+- [uCharts码云开源托管地址](https://gitee.com/uCharts/uCharts) [![star](https://gitee.com/uCharts/uCharts/badge/star.svg?theme=gvp)](https://gitee.com/uCharts/uCharts/stargazers)
+- [uCharts npm开源地址](https://www.ucharts.cn)
+- [ECharts官网](https://echarts.apache.org/zh/index.html)
+- [ECharts配置手册](https://echarts.apache.org/zh/option.html)
+- [图表组件在项目中的应用 ReportPlus数据报表](https://www.ucharts.cn/v2/#/layout/info?id=1) 

Файловите разлики са ограничени, защото са твърде много
+ 22 - 0
mine/components/qiun-data-charts/static/app-plus/echarts.min.js


Файловите разлики са ограничени, защото са твърде много
+ 22 - 0
mine/components/qiun-data-charts/static/h5/echarts.min.js


+ 92 - 0
mine/components/search/search.vue

@@ -0,0 +1,92 @@
+<template>
+	<view class="alldata flexc">
+		<!-- :start="startDate" :end="endDate" -->
+		<!-- <view class="list">
+			<picker :value="className" range-key="className" :range="tablist"  @change="bindDateChange" >
+				<view class="flexc">
+					<view class="alldatain f15 cofe f500" :style="'text-align:'+textAlign">{{date||'考试班级'}}</view>
+					<image :src="upimg"></image>
+				</view>
+			</picker>
+		</view> -->
+		<view class="list">
+			<picker mode="date"  :value="date"  @change="bindDateChangea">
+				<view class="flexc">
+					<view class="alldatain f15 cofe f500" :style="'text-align:'+textAlign">{{date||'考试时间'}}</view>
+					<image :src="upimg"></image>
+				</view>
+			</picker>
+		</view>
+	</view>
+</template>
+
+<script>
+	//:fields="fields" 表示选择器的粒度,默认为 day,App
+	export default{
+		props:{
+			textAlign:{
+				type: String,
+				default () {
+					return 'left'
+				}
+			},
+			fields:{
+				type: String,
+				default () {
+					return 'year'
+				}
+			},
+			timedate:{
+				type: String,
+				default () {
+					return ''
+				}
+			},
+			tablist:{
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			className:{
+				type: Array,
+				default () {
+					return []
+				}
+			}
+			
+		},
+		data(){
+			return{
+				upimg:require("@/mine/static/score/up.png"),
+				date:''
+			}
+		},
+		mounted() {
+			if(this.timedate){
+				this.date=this.timedate;
+			}
+		},
+		methods:{
+			bindDateChange(e){
+				var val=e.detail.value
+				this.date=e.detail.value;
+				this.$emit("bindDateChange",val)
+			},
+			bindDateChangea(e){
+				var val=e.detail.value
+				this.date=e.detail.value;
+				this.$emit("getSearch",this.date)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+ // 选择年份
+ .alldata{padding: 20rpx 36rpx;height: 100rpx;box-sizing: border-box;
+	.list{width: 33.3%;}
+	image{width: 22rpx;height: 16rpx;margin-left: 14rpx;}
+	.alldatain{min-width: 124rpx;}
+ }	
+</style>

+ 164 - 0
mine/components/share/share.vue

@@ -0,0 +1,164 @@
+<template>
+  <view class="share_all">
+	  <view class="shadow" v-if="shaflag" @click="getClose"></view>
+	  
+	  <transition name="fade">
+	  	<view v-if="wxshareflag" @click="wxzheFn">
+	  		<image :src="tipimg"  class="tipimg"></image>
+	  	</view>
+	  </transition>
+	  <view :class="shareflag ? 'share_btn share_bot' : 'share_btn'">
+		  <view class="f15 c16 fw5 txc">分享至</view>
+		  <view class="box">
+			  <!-- #ifdef MP-WEIXIN -->
+				<view class="list">
+					<image :src="wximg" class="share_img"></image>
+					<view class="share_tit">微信好友</view>
+					<button open-type="share" class="sharebox"></button>
+					<!-- :data-id="datainfo.noticeId" :data-tit="datainfo.noticeContent" :data-img="photo.length?photo[0]:''" -->
+				</view>
+				<view class="list" @click="getPshare">
+					<image :src="pyqimg" class="share_img"></image>
+					<view class="share_tit">朋友圈</view>
+				</view>
+			  <!-- #endif -->
+			  <!-- #ifdef APP-PLUS -->
+				<view class="list" @click="getAppwshare">
+					<image :src="wximg" class="share_img"></image>
+					<view class="share_tit">微信好友</view>
+				</view>
+				<view class="list" @click="getApppshare">
+					<image :src="pyqimg" class="share_img"></image>
+					<view class="share_tit">朋友圈</view>
+				</view>
+			  <!-- #endif -->
+		  </view>
+		  <view class="zhan"></view>
+		  <view class="share_close" @click="getClose">取消</view>
+	  </view>
+  </view>
+</template>
+
+<script>
+	import {  mapState,  mapMutations  } from 'vuex';
+  export default {
+	props:{
+		// notxt:{
+		// 	type: String,
+		// 	default () {
+		// 		return '暂无数据'
+		// 	}
+		// },
+		// padtop:{
+		// 	type: Number,
+		// 	default () {
+		// 		return 200
+		// 	}
+		// }
+	},
+	data(){
+		return{
+			wximg:require("@/static/images/share/WeChat.png"), 
+			pyqimg:require("@/static/images/share/friend.png"),
+			tipimg:require("@/static/images/share/pytip.png"),
+			wxshareflag:false,
+			
+		}
+	},
+	onLoad: function() {
+	},
+	computed: {
+	    ...mapState({
+		   shareflag: state => state.user.shareflag,
+		   shaflag: state => state.user.shaflag,
+		   sharetit: state => state.user.sharetit,
+		   sharedesc: state => state.user.sharedesc,
+		   sharelink: state => state.user.sharelink,
+		 }),
+	},
+	methods:{
+		...mapMutations({
+			"shasFn": "share"
+		}),
+		wxzheFn(){
+			var that = this;
+			that.wxshareflag = false;
+			that.getClose();
+		},
+		getAppwshare(){
+			uni.share({
+				provider: "weixin",
+				scene: "WXSceneSession",
+				type: 0,
+				href: this.sharelink,
+				title: this.sharetit,
+				summary: "我正在使用智能校管家,赶紧跟我一起来体验!",
+				imageUrl: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png",
+				success: function (res) {
+					console.log("success:" + JSON.stringify(res));
+				},
+				fail: function (err) {
+					console.log("fail:" + JSON.stringify(err));
+				}
+			});
+		},
+		getApppshare(){
+			uni.share({
+				provider: "weixin",
+				scene: "WXSceneTimeline",
+				type: 0,
+				href: this.sharelink,
+				title: this.sharetit,
+				summary: "我正在使用智能校管家,赶紧跟我一起来体验!",
+				imageUrl: "https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png",
+				success: function (res) {
+					console.log("success:" + JSON.stringify(res));
+				},
+				fail: function (err) {
+					console.log("fail:" + JSON.stringify(err));
+				}
+			});
+		},
+		getPshare(){
+			this.wxshareflag=true;
+		},
+		getClose(){
+			var that = this;
+			that.wxshareflag=false;
+			var data = [
+				{
+					shareflag: false,
+					shaflag: false,
+					homeflag: false,
+					sharetit: '',
+					sharedesc: '',
+					sharelink: '',
+					shareimg: '',
+					life_id: '',
+				}
+			];
+			that.$nextTick(function(){
+				this.shasFn(data);
+			})
+		} 
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.shadow{position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0,0,0,0.4);z-index: 97;}
+.tipimg{width: 432rpx;height: 174rpx;position: fixed;top: 0;right: 120rpx;bottom: 0;z-index: 98;}
+.share_btn{position: fixed;bottom: 0;left: 0;right: 0;background: #fff;z-index: 99;transition: all linear 0.3s;transform: translateY(100%);padding-top: 26rpx;
+	.zhan{width: 100%;height: 24rpx;background-color: #f5f5f5;}
+	.box{padding: 50rpx 0;display: flex;align-items: center;flex-wrap: nowrap;
+		.list{flex: 1;display: flex;flex-direction: column;align-items: center;position: relative;
+			.sharebox{position: absolute;left: 0;right: 0;top: 0;bottom: 0;opacity: 0;}
+			.share_img{width: 90rpx;height: 90rpx;}
+			.share_tit{color: #666666;font-size: 30rpx;padding-top: 40rpx;}
+		}
+	}
+	.share_close{height: 100rpx;background: #FFFFFF;font-size: 32rpx;font-weight: 500;color: #4775EA;display: flex;align-items: center;justify-content: center;}
+}
+.share_bot{transform: translateY(0);}
+</style>

+ 577 - 0
mine/components/shmily-drag-image/shmily-drag-image.vue

@@ -0,0 +1,577 @@
+<template>
+  <view class="con">
+    <template v-if="viewWidth">
+      <movable-area class="area" :style="{ height: areaHeight }" @mouseenter="mouseenter" @mouseleave="mouseleave">
+        <movable-view v-for="(item, index) in imageList" :key="item.id" class="view" direction="all" :y="item.y"
+          :x="item.x" :damping="40" :disabled="item.disable" @change="onChange($event, item)"
+          @touchstart="touchstart(item)" @mousedown="touchstart(item)" @touchend="touchend(item)"
+          @mouseup="touchend(item)" :style="{
+          width: viewWidth + 'px', 
+          height: viewWidth + 'px', 
+          'z-index': item.zIndex, 
+          opacity: item.opacity 
+        }">
+          <view class="area-con" :style="{
+            width: childWidth, 
+            height: childWidth, 
+            borderRadius: borderRadius + 'rpx',
+            transform: 'scale(' + item.scale + ')' 
+          }">
+            <image class="pre-image" :src="baseUrl+item.src"  mode="aspectFill"></image>
+            <view class="del-con" @click="delImages(item, index)" @touchstart.stop="delImageMp(item, index)"
+              @touchend.stop="nothing()" @mousedown.stop="nothing()" @mouseup.stop="nothing()">
+              <view class="del-wrap">
+                <image class="del-image"
+                  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhdEVYdENyZWF0aW9uIFRpbWUAMjAyMDowNzoyNSAyMTo1NDoyOU4TkJAAAADcSURBVFhH7ZfRCoMwDEXLvkjwwVf/bH/emmAyN6glTW9WBjsgwm28OeCLpj81Sil7zvlJ90UiONS/yY5VogsO6XrBg3IEQ5a/s8vRSWUAKmLqp2w5jz5BiNQEGMo3GbloDLtFXJ1IkaEuhAiiY6gEIqB4yqACSk9piIBiKQ8VUFpLviKg3C2rESKgWERCBZSWiEfgIfffYvrrsAgoISJ3Apy3zuTxcSxLQkV6ykNEPKVQkZEyiAiiZKgDIaC4upACSlcn5fM/+WuDCAHF1E/Z/N9AhkMZnPNDPI+UDjPIXgAQIGjNAAAAAElFTkSuQmCC">
+                </image>
+              </view>
+            </view>
+          </view>
+        </movable-view>
+        <view class="add" v-if="imageList.length < number"
+          :style="{ top: add.y, left: add.x, width: viewWidth + 'px', height: viewWidth + 'px' }" @click="addImages">
+          <view class="add-wrap" :style="{ width: childWidth, height: childWidth, borderRadius: borderRadius + 'rpx' }">
+            <image style="width: 54rpx;height: 54rpx;"
+              src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAABIUlEQVRoQ+2a2w2DMAxFeQzWrsMUbadAsEw3S1CqVgppKwLX8BEOP4iHTXx8uUgWdVXoVhdaV0VhSmf7vr/H8V3XzY6V3P9iD+nYOI5P7/01LMI596AwoZV0TIBXIUWFXhKLFBWYSFGhhxQN6SFFQ5i4ogITKSr0cEVDekjRECauqMBEigq9U7piOk2yAti27SUe5ljlTfPEQ6KZecTvwl4P3ytvOv06R2HDMNzes7+6aRrvnHvtf50L13Lp50rx88zcvNlS3JpwKQ67XyK04nq2nFbk/LqVjin0TvmBNgQ2S4UUDcliHgpMpKjQwxUN6SFFQ5i4ogITKSr0cEVDekjRECauqMAsVoph+hVPtYr5+03p9tbYQ96xrYtT4ootbAJGVxxVTapVswAAAABJRU5ErkJggg==">
+            </image>
+          </view>
+        </view>
+      </movable-area>
+
+    </template>
+  </view>
+</template>
+
+<script>
+import config from '@/config'
+const baseUrl = config.baseUrl
+import {uploadmore} from '@/utils/common.js'
+  export default {
+    emits: ['input', 'update:modelValue'],
+    props: {
+      // 排序图片
+      value: {
+        type: Array,
+        default: function() {
+          return []
+        }
+      },
+      // 排序图片
+      modelValue: {
+        type: Array,
+        default: function() {
+          return []
+        }
+      },
+      // 从 list 元素对象中读取的键名
+      keyName: {
+        type: String,
+        default: null
+      },
+      // 选择图片数量限制
+      number: {
+        type: Number,
+        default: 9
+      },
+      // 图片父容器宽度(实际显示的图片宽度为 imageWidth / 1.1 ),单位 rpx
+      // imageWidth > 0 则 cols 无效
+      imageWidth: {
+        type: Number,
+        default: 0
+      },
+      // 图片列数
+      cols: {
+        type: Number,
+        default: 3
+      },
+      // 图片圆角,单位 rpx
+      borderRadius: {
+        type: Number,
+        default: 0
+      },
+      // 图片周围空白填充,单位 rpx
+      padding: {
+        type: Number,
+        default: 10
+      },
+      // 拖动图片时放大倍数 [0, ∞)
+      scale: {
+        type: Number,
+        default: 1.1
+      },
+      // 拖动图片时不透明度
+      opacity: {
+        type: Number,
+        default: 0.7
+      },
+      // 自定义添加
+      addImage: {
+        type: Function,
+        default: null
+      },
+      // 删除确认
+      delImage: {
+        type: Function,
+        default: null
+      }
+    },
+    data() {
+      return {
+        imageList: [],
+        width: 0,
+        add: {
+          x: 0,
+          y: 0
+        },
+        colsValue: 0,
+        viewWidth: 0,
+        tempItem: null,
+        timer: null,
+        changeStatus: true,
+        preStatus: true,
+        first: true,
+		baseUrl:'',
+      }
+    },
+    computed: {
+      areaHeight() {
+        let height = ''
+        // return '355px'
+        if (this.imageList.length < this.number) {
+          height = (Math.ceil((this.imageList.length + 1) / this.colsValue) * this.viewWidth).toFixed() + 'px'
+        } else {
+          height = (Math.ceil(this.imageList.length / this.colsValue) * this.viewWidth).toFixed() + 'px'
+        }
+        console.log('areaHeight', height)
+        return height
+      },
+      childWidth() {
+        return this.viewWidth - this.rpx2px(this.padding) * 2 + 'px'
+      },
+    },
+    watch: {
+      value: {
+        handler(n) {
+          if (!this.first && this.changeStatus) {
+            // console.log('watch', n)
+            let flag = false
+            for (let i = 0; i < n.length; i++) {
+              if (flag) {
+                this.addProperties(this.getSrc(n[i]))
+                continue
+              }
+              if (this.imageList.length === i || this.imageList[i].src !== this.getSrc(n[i])) {
+                flag = true
+                this.imageList.splice(i)
+                this.addProperties(this.getSrc(n[i]))
+              }
+            }
+          }
+        },
+        deep: true
+      },
+      modelValue: {
+        handler(n) {
+          if (!this.first && this.changeStatus) {
+            console.log('watch', n)
+            let flag = false
+            for (let i = 0; i < n.length; i++) {
+              if (flag) {
+                this.addProperties(this.getSrc(n[i]))
+                continue
+              }
+              if (this.imageList.length === i || this.imageList[i].src !== this.getSrc(n[i])) {
+                flag = true
+                this.imageList.splice(i)
+                this.addProperties(this.getSrc(n[i]))
+              }
+            }
+          }
+        },
+        deep: true
+      },
+    },
+    created() {
+      this.width = uni.getSystemInfoSync().windowWidth
+	  this.baseUrl=baseUrl;
+    },
+    mounted() {
+      const query = uni.createSelectorQuery().in(this)
+      query.select('.con').boundingClientRect(data => {
+        this.colsValue = this.cols
+        this.viewWidth = data.width / this.cols
+        if (this.imageWidth > 0) {
+          this.viewWidth = this.rpx2px(this.imageWidth)
+          this.colsValue = Math.floor(data.width / this.viewWidth)
+        }
+        let list = this.value
+        // #ifdef VUE3
+        list = this.modelValue
+        // #endif
+        for (let item of list) {
+          this.addProperties(this.getSrc(item))
+        }
+        this.first = false
+
+      })
+      query.exec()
+    },
+    methods: {
+      getSrc(item) {
+        if(this.keyName !== null) {
+          return item[this.keyName]
+        }
+        return item
+      },
+      onChange(e, item) {
+        if (!item) return
+        item.oldX = e.detail.x
+        item.oldY = e.detail.y
+        if (e.detail.source === 'touch') {
+          if (item.moveEnd) {
+            item.offset = Math.sqrt(Math.pow(item.oldX - item.absX * this.viewWidth, 2) + Math.pow(item.oldY - item
+              .absY * this.viewWidth, 2))
+          }
+          let x = Math.floor((e.detail.x + this.viewWidth / 2) / this.viewWidth)
+          if (x >= this.colsValue) return
+          let y = Math.floor((e.detail.y + this.viewWidth / 2) / this.viewWidth)
+          let index = this.colsValue * y + x
+          if (item.index != index && index < this.imageList.length) {
+            this.changeStatus = false
+            for (let obj of this.imageList) {
+              if (item.index > index && obj.index >= index && obj.index < item.index) {
+                this.change(obj, 1)
+              } else if (item.index < index && obj.index <= index && obj.index > item.index) {
+                this.change(obj, -1)
+              } else if (obj.id != item.id) {
+                obj.offset = 0
+                obj.x = obj.oldX
+                obj.y = obj.oldY
+                setTimeout(() => {
+                  this.$nextTick(() => {
+                    obj.x = obj.absX * this.viewWidth
+                    obj.y = obj.absY * this.viewWidth
+                  })
+                }, 0)
+              }
+            }
+            item.index = index
+            item.absX = x
+            item.absY = y
+            if (!item.moveEnd) {
+              setTimeout(() => {
+                this.$nextTick(() => {
+                  item.x = item.absX * this.viewWidth
+                  item.y = item.absY * this.viewWidth
+                })
+              }, 0)
+            }
+            // console.log('bbb', JSON.parse(JSON.stringify(item)));
+            this.sortList()
+          }
+        }
+      },
+      change(obj, i) {
+        obj.index += i
+        obj.offset = 0
+        obj.x = obj.oldX
+        obj.y = obj.oldY
+        obj.absX = obj.index % this.colsValue
+        obj.absY = Math.floor(obj.index / this.colsValue)
+        setTimeout(() => {
+          this.$nextTick(() => {
+            obj.x = obj.absX * this.viewWidth
+            obj.y = obj.absY * this.viewWidth
+          })
+        }, 0)
+      },
+      touchstart(item) {
+        this.imageList.forEach(v => {
+          v.zIndex = v.index + 9
+        })
+        item.zIndex = 99
+        item.moveEnd = true
+        this.tempItem = item
+        this.timer = setTimeout(() => {
+          item.scale = this.scale
+          item.opacity = this.opacity
+          clearTimeout(this.timer)
+          this.timer = null
+        }, 200)
+      },
+      touchend(item) {
+        this.previewImage(item)
+        item.scale = 1
+        item.opacity = 1
+        item.x = item.oldX
+        item.y = item.oldY
+        item.offset = 0
+        item.moveEnd = false
+        setTimeout(() => {
+          this.$nextTick(() => {
+            item.x = item.absX * this.viewWidth
+            item.y = item.absY * this.viewWidth
+            this.tempItem = null
+            this.changeStatus = true
+          })
+          // console.log('ccc', JSON.parse(JSON.stringify(item)));
+        }, 0)
+        // console.log('ddd', JSON.parse(JSON.stringify(item)));
+      },
+      previewImage(item) {
+        if (this.timer && this.preStatus && this.changeStatus && item.offset < 28.28) {
+          clearTimeout(this.timer)
+          this.timer = null
+          const list = this.value || this.modelValue
+          let srcList = list.map(v => this.baseUrl+this.getSrc(v))
+          // console.log(list, srcList);
+          uni.previewImage({
+            urls: srcList,
+            current: item.src,
+            success: () => {
+              this.preStatus = false
+              setTimeout(() => {
+                this.preStatus = true
+              }, 600)
+            },
+            fail: (e) => {
+              console.log(e);
+            }
+          })
+        } else if (this.timer) {
+          clearTimeout(this.timer)
+          this.timer = null
+        }
+      },
+      mouseenter() {
+        //#ifdef H5
+        this.imageList.forEach(v => {
+          v.disable = false
+        })
+        //#endif
+
+      },
+      mouseleave() {
+        //#ifdef H5
+        if (this.tempItem) {
+          this.imageList.forEach(v => {
+            v.disable = true
+            v.zIndex = v.index + 9
+            v.offset = 0
+            v.moveEnd = false
+            if (v.id == this.tempItem.id) {
+              if (this.timer) {
+                clearTimeout(this.timer)
+                this.timer = null
+              }
+              v.scale = 1
+              v.opacity = 1
+              v.x = v.oldX
+              v.y = v.oldY
+              this.$nextTick(() => {
+                v.x = v.absX * this.viewWidth
+                v.y = v.absY * this.viewWidth
+                this.tempItem = null
+              })
+            }
+          })
+          this.changeStatus = true
+        }
+        //#endif
+      },
+      addImages() {
+		  var that=this;
+        if (typeof this.addImage === 'function') {
+          this.addImage.bind(this.$parent)()
+        } else {
+          let checkNumber = this.number - this.imageList.length
+          uni.chooseImage({
+            count: checkNumber,
+            sourceType: ['album', 'camera'],
+            success: res => {
+              let count = checkNumber <= res.tempFilePaths.length ? checkNumber : res.tempFilePaths.length
+              // for (let i = 0; i < count; i++) {
+              //   this.addProperties(res.tempFilePaths[i])
+              // }
+			  let img= res.tempFilePaths;
+			  let imglen = res.tempFilePaths.length;
+			  var fuwufile = [];
+			  uploadmore('/common/upload',img,0,0,0,imglen,fuwufile,function(rs){
+				// console.log(rs,123)
+				for (let i = 0; i < count; i++) {
+				  that.addProperties(rs[i])
+				}
+				that.sortList()
+			  })
+			  
+				  // that.imageList = that.imageList.concat(rs);
+			  // 上传
+              
+            }
+          })
+        }
+      },
+      delImages(item, index) {
+        if (typeof this.delImage === 'function') {
+          this.delImage.bind(this.$parent)(() => {
+            this.delImageHandle(item, index)
+          })
+        } else {
+          this.delImageHandle(item, index)
+        }
+      },
+      delImageHandle(item, index) {
+        this.imageList.splice(index, 1)
+        for (let obj of this.imageList) {
+          if (obj.index > item.index) {
+            obj.index -= 1
+            obj.x = obj.oldX
+            obj.y = obj.oldY
+            obj.absX = obj.index % this.colsValue
+            obj.absY = Math.floor(obj.index / this.colsValue)
+            this.$nextTick(() => {
+              obj.x = obj.absX * this.viewWidth
+              obj.y = obj.absY * this.viewWidth
+            })
+          }
+        }
+        this.add.x = (this.imageList.length % this.colsValue) * this.viewWidth + 'px'
+        this.add.y = Math.floor(this.imageList.length / this.colsValue) * this.viewWidth + 'px'
+        this.sortList()
+      },
+      delImageMp(item, index) {
+        //#ifdef MP
+        this.delImages(item, index)
+        //#endif
+      },
+      sortList() {
+        console.log('sortList');
+        const result = []
+        let source = this.value
+        // #ifdef VUE3
+        source = this.modelValue
+        // #endif
+        
+        let list = this.imageList.slice()
+        list.sort((a, b) => {
+          return a.index - b.index
+        })
+        for (let s of list) {
+          let item = source.find(d => this.getSrc(d) == s.src)
+          if (item) {
+            result.push(item)
+          } else {
+            if(this.keyName !== null) {
+              result.push({
+                [this.keyName]: s.src
+              })
+            } else {
+              result.push(s.src)
+            }
+          }
+        }
+        this.$emit("input", result);
+        this.$emit("update:modelValue", result);
+      },
+      addProperties(item) {
+        let absX = this.imageList.length % this.colsValue
+        let absY = Math.floor(this.imageList.length / this.colsValue)
+        let x = absX * this.viewWidth
+        let y = absY * this.viewWidth
+        this.imageList.push({
+          src: item,
+          x,
+          y,
+          oldX: x,
+          oldY: y,
+          absX,
+          absY,
+          scale: 1,
+          zIndex: 9,
+          opacity: 1,
+          index: this.imageList.length,
+          id: this.guid(16),
+          disable: false,
+          offset: 0,
+          moveEnd: false
+        })
+        this.add.x = (this.imageList.length % this.colsValue) * this.viewWidth + 'px'
+        this.add.y = Math.floor(this.imageList.length / this.colsValue) * this.viewWidth + 'px'
+      },
+      nothing() {},
+      rpx2px(v) {
+        return this.width * v / 750
+      },
+      guid(len = 32) {
+        const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+        const uuid = []
+        const radix = chars.length
+        for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
+        uuid.shift()
+        return `u${uuid.join('')}`
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .con {
+    // padding: 30rpx;
+
+    .area {
+      width: 100%;
+
+      .view {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        .area-con {
+          position: relative;
+          overflow: hidden;
+
+          .pre-image {
+            width: 100%;
+            height: 100%;
+          }
+
+          .del-con {
+            position: absolute;
+            top: 0rpx;
+            right: 0rpx;
+            padding: 0 0 20rpx 20rpx;
+
+            .del-wrap {
+              width: 36rpx;
+              height: 36rpx;
+              background-color: rgba(0, 0, 0, 0.4);
+              border-radius: 0 0 0 10rpx;
+              display: flex;
+              justify-content: center;
+              align-items: center;
+
+              .del-image {
+                width: 20rpx;
+                height: 20rpx;
+              }
+            }
+          }
+        }
+      }
+
+      .add {
+        position: absolute;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        .add-wrap {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          background-color: #eeeeee;
+        }
+      }
+    }
+  }
+</style>

+ 65 - 0
mine/components/zb-table/all.js

@@ -0,0 +1,65 @@
+export const column1 = [
+    { type:'index', fixed:true,width:100 },
+    { name: 'name', label: '姓名',fixed:true,width:160,emptyString:'--' },
+    { name: 'yw', label: '语文',sorter:true},
+    // { name: 'sex', label: '性别',filters:{0:'男',1:'女'}},
+    { name: 'sx', label: '数学',sorter:true },
+    { name: 'yy', label: '英语',sorter:true },
+	{ name: 'operation', type:'operation',label: '操作',renders:[
+		{
+		    name:'编辑',
+		    func:'edit' // func 代表子元素点击的事件 父元素接收的事件 父元素 @edit
+		  },
+		  {
+		    name:'删除',
+		    type:'warn',
+		    func:"dele"
+		  },
+	]},
+
+]
+// 历史
+export const column2 = [
+    { name: 'updateTime', label: '更新日期',fixed:true,width:180,},
+    { name: 'height', label: '身高(cm)'},
+    { name: 'weight', label: '体重(kg)'},
+    // { name: 'degreeMyopia', label: '视力'},
+]
+export const column3 = [
+    { type:'selection', fixed:true,width:100 },
+    { name: 'name', label: '姓名',fixed:true,width:160,emptyString:'--' },
+    { name: 'age', label: '年纪',},
+    { name: 'sex', label: '性别',filters:{0:'男',1:'女'}},
+    { name: 'address', label: '地址' },
+    { name: 'date', label: '日期', },
+    { name: 'province', label: '省份' },
+    { name: 'city', label: '城市' },
+    { name: 'zip', label: '邮编' },
+]
+
+// 添加的时候
+export const column4 = [
+    // { type:'selection', fixed:true,width:50 },
+    { type:'index', fixed:true,width:60,align:'center', },
+    { name: 'scoreDataName', label: '姓名',fixed:true,width:140,emptyString:'--',align:'center' },
+    { name: 'yuwen', label: '语文',sorter:true,align:'center',width:112},
+    { name: 'shuxue', label: '数学',sorter:true,align:'center',width:112 },
+    { name: 'yingyu', label: '英语',sorter:true,align:'center',width:112 },
+    { name: 'wuli', label: '物理',sorter:true,align:'center',width:112 },
+    { name: 'huaxue', label: '化学',sorter:true,align:'center',width:112 },
+    { name: 'shengwu', label: '生物',sorter:true,align:'center',width:112 },
+    { name: 'lishi', label: '历史',sorter:true,align:'center',width:112 },
+    { name: 'dili', label: '地理',sorter:true,align:'center',width:112 },
+    { name: 'zhengzhi', label: '政治',sorter:true,align:'center',width:112 },
+    { name: 'tiyu', label: '体育',sorter:true,align:'center',width:112 },
+    { name: 'kexue', label: '科学',sorter:true,align:'center',width:112 },
+    { name: 'meishu', label: '美术',sorter:true,align:'center',width:112 },
+    { name: 'yinyue', label: '音乐',sorter:true,align:'center',width:112 },
+    { name: 'yishu', label: '艺术',sorter:true,align:'center',width:112 },
+    { name: 'wenzong', label: '文综',sorter:true,align:'center',width:112 },
+    { name: 'lizong', label: '理综',sorter:true,align:'center',width:112 },
+    { name: 'zongfen', label: '总分',sorter:true,align:'center',width:112 },
+    { name: 'scoreSort', label: '排名',sorter:true,align:'center',width:112 },
+]
+
+

+ 180 - 0
mine/components/zb-table/components/table-checkbox.vue

@@ -0,0 +1,180 @@
+<template>
+	<view class="uni-table-checkbox" @click.stop="selected">
+		<view v-if="!indeterminate" class="checkbox__inner" :class="{'is-checked':isChecked,'is-disable':isDisabled}">
+			<view class="checkbox__inner-icon"></view>
+		</view>
+		<view v-else class="checkbox__inner checkbox--indeterminate">
+			<view class="checkbox__inner-icon"></view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'TableCheckbox',
+		emits:['checkboxSelected'],
+		props: {
+			indeterminate: {
+				type: Boolean,
+				default: false
+			},
+			checked: {
+				type: [Boolean,String],
+				default: false
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			index: {
+				type: Number,
+				default: -1
+			},
+			cellData: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		watch:{
+			checked(newVal){
+				if(typeof this.checked === 'boolean'){
+					this.isChecked = newVal
+				}else{
+					this.isChecked = true
+				}
+			},
+			indeterminate(newVal){
+				this.isIndeterminate = newVal
+			}
+		},
+		data() {
+			return {
+				isChecked: false,
+				isDisabled: false,
+				isIndeterminate:false
+			}
+		},
+		created() {
+			if(typeof this.checked === 'boolean'){
+				this.isChecked = this.checked
+			}
+			this.isDisabled = this.disabled
+		},
+		methods: {
+			selected() {
+				if (this.isDisabled) return
+				this.isIndeterminate = false
+				this.isChecked = !this.isChecked
+        console.log('===',this.indeterminate,this.isChecked)
+				this.$emit('checkboxSelected', {
+					checked: this.isChecked,
+					data: this.cellData
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	$checked-color: #007aff;
+	$border-color: #DCDFE6;
+	$disable:0.4;
+
+	.uni-table-checkbox {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+		margin: 10rpx 0;
+		cursor: pointer;
+
+		// 多选样式
+		.checkbox__inner {
+			/* #ifndef APP-NVUE */
+			flex-shrink: 0;
+			box-sizing: border-box;
+			/* #endif */
+			position: relative;
+			width: 32rpx;
+			height: 32rpx;
+			border: 2rpx solid $border-color;
+			border-radius: 4rpx;
+			background-color: #fff;
+			z-index: 1;
+
+			.checkbox__inner-icon {
+				position: absolute;
+				/* #ifdef APP-NVUE */
+				top: 4rpx;
+				/* #endif */
+				/* #ifndef APP-NVUE */
+				top: 4rpx;
+				/* #endif */
+				left: 10rpx;
+				height: 14rpx;
+				width: 6rpx;
+				border: 2rpx solid #fff;
+				border-left: 0;
+				border-top: 0;
+				opacity: 0;
+				transform-origin: center;
+				transform: rotate(45deg);
+				box-sizing: content-box;
+			}
+
+			&.checkbox--indeterminate {
+				border-color: $checked-color;
+				background-color: $checked-color;
+
+				.checkbox__inner-icon {
+					position: absolute;
+					opacity: 1;
+					transform: rotate(0deg);
+					height: 4rpx;
+					top: 0;
+					bottom: 0;
+					margin: auto;
+					left: 0px;
+					right: 0px;
+					bottom: 0;
+					width: auto;
+					border: none;
+					border-radius: 4rpx;
+					transform: scale(0.5);
+					background-color: #fff;
+				}
+			}
+			&:hover{
+				border-color: $checked-color;
+			}
+			// 禁用
+			&.is-disable {
+				/* #ifdef H5 */
+				cursor: not-allowed;
+				/* #endif */
+				background-color: #F2F6FC;
+				border-color: $border-color;
+			}
+
+			// 选中
+			&.is-checked {
+				border-color: $checked-color;
+				background-color: $checked-color;
+
+				.checkbox__inner-icon {
+					opacity: 1;
+					transform: rotate(45deg);
+				}
+
+				// 选中禁用
+				&.is-disable {
+					opacity: $disable;
+				}
+			}
+
+		}
+	}
+</style>

+ 78 - 0
mine/components/zb-table/components/table-h5-summary.vue

@@ -0,0 +1,78 @@
+<template>
+  <view class="table-h5-footer top-header-uni" :style="{paddingRight:`${scrollbarSize}rpx`}">
+    <scroll-view class="zb-table-headers"
+                 @scroll="handleFooterTableScrollLeft"
+                 scroll-x="true"
+                 scroll-y="false"
+                 id="tableFooterHeaders"
+                 scroll-anchoring="true"
+                 :scroll-left="headerFooterTableLeft"
+                 style="padding-bottom: 0px;
+						background: #fafafa;height: 100%">
+      <view class="zb-table-fixed" >
+        <view class="zb-table-thead" style="position: relative;" >
+          <view class="item-tr">
+            <view
+                class="item-th"
+                :style="{
+	                              width:`${item.width?item.width:'200'}rpx`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'200'}rpx`,
+															  borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+															  borderTop:`${border?'2rpx solid #e8e8e8':''}`,
+															  textAlign:item.align||'left'
+														  }"
+                v-for="(item,index) in transColumns" :key="index">
+              {{ sums[index] }}
+            </view>
+          </view>
+        </view>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+<script>
+import summary from '../js/summary.js'
+export default {
+  name:'table-footer',
+  mixins:[summary],
+}
+</script>
+<style lang="scss" scoped>
+.table-h5-footer {
+  background: #fafafa;
+  /*每个页面公共css */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+  //第二种
+  ::-webkit-scrollbar{
+    display: none;
+  }
+  .item-tr{
+    display: flex;
+  }
+  .item-th{
+    padding-left: 8rpx;
+    line-height: 78rpx;
+    height: 80rpx;
+    //display: flex;
+    //align-items: center;
+    box-sizing: border-box;
+    flex-shrink: 0;
+    width: 200rpx;
+    padding-right: 8rpx;
+    word-break: keep-all;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    overflow-wrap: break-word;
+    border-bottom: 2rpx solid #e8e8e8;
+  }
+
+}
+</style>

+ 59 - 0
mine/components/zb-table/components/table-side-summary.vue

@@ -0,0 +1,59 @@
+<template>
+  <view class="zb-table-header" style="display: flex;" >
+    <view class="item-tr" >
+      <view class='item-td'
+            :style="{
+	                       width:`${item.width?item.width:'200'}rpx`,
+	                       borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+	                       textAlign:item.align||'left'
+	                      }"
+            :key="`${index}`"
+            v-for="(item,index) in fixedLeftColumns">
+        <template >
+          {{sums[index]}}
+        </template>
+      </view>
+    </view>
+  </view>
+
+</template>
+<script>
+import summary from '../js/summary.js'
+export default {
+  mixins:[summary]
+}
+</script>
+<style lang="scss" scoped>
+.zb-table-header {
+  overflow: hidden;
+  background: #fafafa;
+  .item-th{
+    padding-left: 8rpx;
+    line-height: 78rpx;
+    height: 80rpx;
+    //display: flex;
+    //align-items: center;
+    box-sizing: border-box;
+  }
+}
+.item-tr{
+  display: flex;
+  box-sizing: border-box;
+}
+.item-td{
+  flex-shrink: 0;
+  width: 200rpx;
+  padding-left:8rpx;
+  height: 80rpx;
+  line-height: 80rpx;
+  padding-right: 8rpx;
+  box-sizing: border-box;
+  word-break: keep-all;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  overflow-wrap: break-word;
+  border-bottom: 2rpx solid #e8e8e8;
+  background: rgb(250, 250, 250);
+}
+</style>

+ 77 - 0
mine/components/zb-table/components/table-summary.vue

@@ -0,0 +1,77 @@
+<template>
+  <view class="zb-table-footer" style="height: 80rpx;">
+    <view class="zb-table-fixed" >
+      <view class="zb-table-thead" style="position: relative;" >
+        <view class="item-tr">
+          <view
+              :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side']"
+              :style="{
+	                              left:`${item.left}rpx`,
+	                              width:`${item.width?item.width:'200'}rpx`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'200'}rpx`,
+															   borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+															  borderTop:`${border?'2rpx solid #e8e8e8':''}`,
+															   textAlign:item.align||'left'
+														  }"
+              v-for="(item,index) in transColumns" :key="index">
+            <template>
+              {{ sums[index]||item.emptyString }}
+            </template>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+<script>
+  import summary from '../js/summary.js'
+  export default {
+    mixins:[summary]
+  }
+</script>
+<style lang="scss" scoped>
+  .zb-table-footer {
+    background: #fafafa;
+    width: fit-content;
+    min-width: 100%;
+    position: sticky;
+    bottom: 0;
+    z-index: 2;
+    .item-tr{
+      display: flex;
+      min-width: 100%;
+    }
+    .item-th{
+      padding-left: 8rpx;
+      line-height: 78rpx;
+      height: 80rpx;
+      //display: flex;
+      //align-items: center;
+      box-sizing: border-box;
+      flex-shrink: 0;
+      width: 200rpx;
+      padding-right: 8rpx;
+      word-break: keep-all;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      overflow-wrap: break-word;
+      border-bottom: 2rpx solid #e8e8e8;
+    }
+    .zb-table-fixed{
+      min-width: 100%;
+
+    }
+    .zb-stick-side{
+      position: sticky;
+      bottom:0 ;
+      left: 0;
+      z-index: 2;
+      //border-right: solid 1rpx #dbdbdb;
+      box-sizing: border-box;
+      background: #fafafa;
+      //box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+</style>

+ 50 - 0
mine/components/zb-table/components/zb-load-more.vue

@@ -0,0 +1,50 @@
+<template >
+  <view class="zb-load-more">
+    <image :src="base64Flower" style="" class="loading-custom-image"></image>
+    <text>正在加载中...</text>
+  </view>
+</template>
+<script>
+const base64Flower = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkBAMAAACCzIhnAAAAKlBMVEVHcEzDw8Ovr6+pqamUlJTCwsKenp61tbWxsbGysrLNzc2bm5u5ubmjo6MpovhuAAAACnRSTlMA/P79/sHDhiZS0DxZowAABBBJREFUWMPtl89rE0EUx7ctTXatB3MI1SWnDbUKPUgXqh4ED8Uf7KUVSm3ooVSpSii0Fn/gD4j4o+APiEoVmos9FO2celiqZVgwgaKHPQiCCkv+F99kM7Ozm5kxq1dfD91k9pPve9/3ZjbRNHHok/mKli4eIPNgSuRObuN9SqSEzM20iGnm0yIbqCuV7NSSSIV7uyPM6JMBYdeTOanh/QihJYZsUCSby+VkMj2AvOt0rAeQAwqE3lfKMZVlQCZk1QOCKkkVPadITCfIRNKxfoJI5+0OIFtJx14CMSg1mRSDko7VAfksRQzEbGYqxOJcVTWMCH2I1/IACNW0PWU2M8cmAVHtnH5mM1VRWtwKZjOd5JbF6s1IbaYqaotjNlPHgDAnlAizubTR6ovMYn052g/U5qcmOpi0WL8xTS/3IfSet5m8MEr5ajjF5le6dq/OJpobrdY0t3i9QgefWrxW9/1BLhk0E9m8FeUMhhXal499iD0eQRfDF+ts/tttORRerfp+oV7f4xJj82iUYm1Yzod+ZQEAlS/8mMBwKebVmCVp1f0JLS6zKd17+iwRKTARVg2SHtz3iEbBH+Q+U28zW2Jiza8Tjb1YFoYZMsJyjDqp3M9XBQdSdPLFdxEpvOB37JrHcmR/y9+LgoTlCFGZEa2sc6d4PGlweEa2JSVPoVm+IfGG3ZL037iV9oH+P+Jxc4HGVflNq1M0pivao/EopO4b/ojVCP9GjmiXOeS0DOn1o/iiccT4ORnyvBGF3yUywkQajW4Ti0SGuiy/wVSg/L8w+X/8Q+hvUx8Xd90z4oV5a1i88MbFWHz0WZZ1UrTwBGPX3Rat9AFiXRMRjoMdIdJLEOt2h7jrYOzgOamKZSWSNspOS0X8SAqRYmxRL7sg4eLzYmNehcxh3uoyud/BH2Udux4ywxFTc1xC7Mgf4vMhc5S+kSH3Y7yj+qpwIWSoPTVCOOPVthGx9FbGqrwFw6wSFxJr+17zeKcztt3u+2roAEVgUjDd+AHGuxHy2rZHaa8JMkTHEeyi85ANPO9j9BVuBRD2FY5LDMo/Sz/2hReqGIs/KiFin+CsPsYO/yvM3jL2vE8EbX7/Bf8ejtr2GLN65bioAdgLd8Bis/mD5GmP2qeqyo2ZwQEOtAjRIDH7mBKpUcMoApbZJ5UIxkEwxyMZyMxW/uKFvHCFR3SSmerHyDNQ2dF4JG6zIMpBgLfjSF9x1D6smFcYnGApjmSLICO3ecCDWrQ48geba9DI3STy2i7ax6WIB62fSyIZIiO3GFQqSURp8wCo7GhJBGwuSovJBNjb7kT6FPVnIa9qJ2Ko+l9mefGIdinaMp0yC1URYiwsdfNE45EuA5Cx9EhalfvN5s+UyItm81vaB3p4joniN+SCP7Qc1hblAAAAAElFTkSuQmCC';
+export default {
+  data(){
+    return{
+      base64Flower
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.zb-load-more {
+  width: 100%;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  z-index: 999;
+  background: white;
+  display: flex;
+  height: 80rpx;
+  flex-shrink: 0;
+  align-items: center;
+  justify-content: center;
+  .loading-custom-image{
+    color: #a4a4a4;
+    margin-right: 8rpx;
+    width: 48rpx;
+    height: 48rpx;
+    /* #ifndef APP-NVUE */
+    animation: loading-circle 1s linear infinite;
+    /* #endif */
+  }
+  @keyframes loading-circle {
+    0% {
+      -webkit-transform: rotate(0deg);
+      transform: rotate(0deg);
+    }
+    100% {
+      -webkit-transform: rotate(360deg);
+      transform: rotate(360deg);
+    }
+  }
+}
+</style>

+ 88 - 0
mine/components/zb-table/js/summary.js

@@ -0,0 +1,88 @@
+export default {
+    props:{
+        scrollbarSize:{
+            type:Number,
+            default:0
+        },
+        fixedLeftColumns:{
+            type:Array,
+            default:()=>[]
+        },
+        data:{
+            type:Array,
+            default:()=>[]
+        },
+        transColumns:{
+            type:Array,
+            default:()=>[]
+        },
+        border:{
+            type:Boolean,
+            default:false
+        },
+        showSummary:{
+            type:Boolean,
+            default:false
+        },
+        summaryMethod:{
+            type:Function
+        },
+        sumText:{
+            type:String,
+            default:'合计'
+        },
+        headerFooterTableLeft:{
+            type:Number,
+            default:0
+        },
+        handleFooterTableScrollLeft:Function,
+    },
+    data(){
+        return{
+            sums:[]
+        }
+    },
+    watch:{
+        'data':{
+            deep:true,
+            immediate:true,
+            handler(newValue,oldValue){
+                let sums = [];
+                if (this.summaryMethod) {
+                    sums = this.summaryMethod({ columns: this.transColumns, data: this.data });
+                } else {
+                    this.transColumns.forEach((column, index) => {
+                        if (index === 0) {
+                            sums[index] = this.sumText;
+                            return;
+                        }
+                        const values = this.data.map(item => Number(item[column.name]));
+                        const precisions = [];
+                        let notNumber = true;
+                        values.forEach(value => {
+                            if (!isNaN(value)) {
+                                notNumber = false;
+                                let decimal = ('' + value).split('.')[1];
+                                precisions.push(decimal ? decimal.length : 0);
+                            }
+                        });
+                        const precision = Math.max.apply(null, precisions);
+                        if (!notNumber) {
+                            sums[index] = values.reduce((prev, curr) => {
+                                const value = Number(curr);
+                                if (!isNaN(value)) {
+                                    return parseFloat((prev + curr).toFixed(Math.min(precision, 20)));
+                                } else {
+                                    return prev;
+                                }
+                            }, 0);
+                        } else {
+                            sums[index] = '';
+                        }
+                    });
+                }
+                this.sums = sums
+            },
+        }
+    }
+}

+ 51 - 0
mine/components/zb-table/js/util.js

@@ -0,0 +1,51 @@
+/**
+ * 获取滚动条宽度
+ */
+let cached = undefined;
+
+export const getScrollbarSize = fresh => {
+	// #ifdef H5
+	
+    if (fresh || cached === undefined) {
+        let inner = document.createElement("div");
+        let innerStyle = inner.style;
+
+        innerStyle.width = "100%";
+        innerStyle.height = "200px";
+
+        let outer = document.createElement("div");
+        let outerStyle = outer.style;
+
+        outerStyle.position = "absolute";
+        outerStyle.top = 0;
+        outerStyle.left = 0;
+        outerStyle.pointerEvents = "none";
+        outerStyle.width = "200px";
+        outerStyle.height = "150px";
+        outerStyle.visibility = "hidden";
+
+        outer.appendChild(inner);
+        document.body.appendChild(outer);
+
+        // 设置子元素超出部分隐藏
+        outerStyle.overflow = "hidden";
+
+        let width1 = inner.offsetWidth;
+
+        // 设置子元素超出部分滚动
+        outer.style.overflow = "scroll";
+
+        let width2 = inner.offsetWidth;
+
+        if (width1 === width2) {
+            width2 = outer.clientWidth;
+        }
+
+        document.body.removeChild(outer);
+
+        cached = width1 - width2;
+    }
+	//#endif
+
+    return cached;
+};

+ 1255 - 0
mine/components/zb-table/zb-table.vue

@@ -0,0 +1,1255 @@
+<template>
+	<!-- #ifdef H5 || APP-PLUS -->
+	<view :class="['zb-table','zb-table-fixed-header',!border&&(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
+	  <view class="zb-table-content" style="flex: 1">
+	    <view class="zb-table-scroll" style="height: 100%;">
+	      <template v-if="showHeader">
+	        <view class="zb-table-header top-header-uni" :style="{paddingRight:`${scrollbarSize}px`}"
+          >
+	          <scroll-view class="zb-table-headers"
+							@touchmove.stop="getMove"
+	                       @scroll="handleTableScrollLeft"
+	                       scroll-x="true"
+	                       scroll-y="false"
+	                       id="tableHeaders"
+	                       scroll-anchoring="true"
+	                       :scroll-left="headerTableLeft"
+	                       style="
+						height: 100%">
+	            <view class="zb-table-fixed" >
+	              <view class="zb-table-thead" style="position: relative;" >
+	                <view class="item-tr">
+	                  <view
+	                      @click.stop="sortAction(item,index)"
+	                      class="item-th"
+	                      :style="[{
+	                              width:`${item.width?item.width:'100'}px`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'100'}px`,
+															  borderRight:`${border?'1px solid #e8e8e8':''}`,
+															  borderRight:`${(scrollbarSize&&index===transColumns.length-1)?'':border?'1px solid #e8e8e8':''}`,
+															  borderTop:`${border?'1px solid #e8e8e8':''}`,
+															  textAlign:item.align||'left'
+														  },getHeaderCellStyle(item,index)]"
+	                      v-for="(item,index) in transColumns" :key="index">
+                      <template v-if="item.type==='selection'">
+                        <view class="checkbox-item">
+                          <tableCheckbox
+                              :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                        </view>
+                      </template>
+                      <template v-else>
+                        {{ item.label }}
+                        <view class="sorter-table" v-if="item.sorter">
+                          <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                          <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                        </view>
+                      </template>
+                    </view>
+	                </view>
+	              </view>
+	            </view>
+	          </scroll-view>
+	        </view>
+	      </template>
+	      <template v-if="!data.length">
+	        <view class="no-data">暂无数据~~</view>
+	      </template>
+	      <scroll-view
+            class="zb-table-body" ref="tableBody"	scroll-x="true"	scroll-y="true"	id="tableBody"
+	                   :lower-threshold="40"
+	                   :upper-threshold="10"
+					   @touchmove.stop="getMove"
+                     @scrolltolower="scrolltolower"
+	                   @scrolltoupper="(e)=>debounce(scrollToLeft)(e)"
+                     @scroll="handleBodyScroll"	:scroll-left="bodyTableLeft"	:scroll-top="bodyScrollTop"
+                     :style=" `height: calc(100% - ${showSummary?80:40}px)`" >
+	          <view class="zb-table-fixed">
+	            <view class="zb-table-tbody">
+	              <view  :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']"
+                       @click.stop="rowClick(item,index)"
+	                     v-for="(item,index) in transData" :key="item.key" >
+	                <view
+	                    :style="[{
+									              width:`${ite.width?ite.width:'100'}px`,
+															  flex:i===transColumns.length-1?1:'none',
+															  minWidth:`${ite.width?ite.width:'100'}px`,
+															  borderRight:`${border?'1px solid #e8e8e8':''}`,
+                                textAlign:ite.align||'left',
+														  },cellStyle&&getCellStyle(item,ite,index,i)]"
+
+	                    :class="['item-td',stripe?(index % 2) != 0?'odd':'even':'']"
+	                    v-for="(ite,i) in transColumns" :key="i">
+	                  <template  v-if="ite.type==='operation'">
+	                    <view style="display: flex;align-items: center;height: 100%">
+	                      <view
+                            v-for="ren,ind in permission(item,ite.renders,index)"
+	                          :key="ind"
+	                          @click.stop="$emit(ren.func,item,index)"
+	                          :style="{
+	                          display:'flex',
+	                          alignItems: 'center',
+	                          marginRight:ite.renders.length>1?'8px':'0'
+	                        }">
+                          <template v-if="ren.type==='custom'">
+                            <view :class="ren.class||''" style="cursor: pointer">
+                              {{ren.name}}
+                            </view>
+                          </template>
+                          <template v-else>
+                            <button
+                                :class="ren.class||''"
+                                :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
+                          </template>
+	                      </view>
+	                    </view>
+	                  </template>
+                    <template v-else-if="ite.type==='selection'">
+                      <view class="checkbox-item">
+                        <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
+                      </view>
+                    </template>
+                    <template v-else-if="ite.type==='index'">
+                      {{index+1}}
+                    </template>
+                  <template v-else-if="ite.type==='img'">
+                    <view class="checkbox-item">
+                      <image
+                    @click.stop="previewImage(item,item[ite.name],index)"
+                    v-if="item[ite.name]"
+                    :show-menu-by-longpress="false"
+                    :src="item[ite.name]" style="width: 40px;height:30px; " mode="aspectFit"></image>
+                    <text v-else>{{ite.emptyString}}</text>
+                    </view>
+                  </template>
+	                  <template  v-else>
+<!--                      {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
+                      {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
+	                  </template>
+	                </view>
+	              </view>
+	            </view>
+	          </view>
+	        </scroll-view>
+       <table-h5-summary
+           :scrollbarSize="scrollbarSize"
+           :data="data"
+           :handleFooterTableScrollLeft="handleFooterTableScrollLeft"
+           :headerFooterTableLeft="headerFooterTableLeft"
+           v-if="showSummary"
+           :showSummary="showSummary"
+           :transColumns="transColumns"
+           :border="border"
+           :summary-method="summaryMethod"
+           :sumText="sumText"
+           :fixedLeftColumns="fixedLeftColumns"/>
+	    </view>
+	    <view class="zb-table-fixed-left"
+            v-if="isFixedLeft"
+            :style=" {height:  `calc(100% - ${scrollbarSize}px)`}"
+      >
+	      <template v-if="showHeader">
+	        <view class="zb-table-header" style="display: flex">
+	          <view class="item-tr"
+                  style=""
+                  @click.stop="rowClick(item,index)"
+                  v-for="(item,index) in fixedLeftColumns" :key="index">
+	            <view
+	                :style="{
+	               width:`${item.width?item.width:'100'}px`,
+	               borderRight:`${border?'1px solid #e8e8e8':''}`,
+	               borderTop:`${border?'1px solid #e8e8e8':''}`,
+                textAlign:item.align||'left'
+	            }"
+	                @click.stop="sortAction(item,index)"
+	                class="item-th"
+	            >
+                <template v-if="item.type==='selection'">
+                  <view class="checkbox-item">
+                    <tableCheckbox
+                        :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                  </view>
+                </template>
+                <template v-else>
+                  {{ item.label }}
+                  <view class="sorter-table" v-if="item.sorter">
+                    <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                    <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                  </view>
+                </template>
+              </view>
+	          </view>
+
+	        </view>
+	      </template>
+        <scroll-view
+            scroll-y="true"
+            id="leftTableFixed"
+            :upper-threshold="15"
+            @scrolltoupper="(e)=>scrollToFixedLeft(e)"
+            @scroll="leftFixedScrollAction"
+            :scroll-top="leftFiexScrollTop"
+            class="zb-table-body-inner"
+            :style=" `height: calc(100% - ${showSummary?80:40}px)`">
+          <view class="zb-table-fixed">
+            <view class="zb-table-tbody">
+              <view
+                  :class="['item-tr',stripe?(i % 2) != 0?'odd':'even':'',highlight&&isHighlight(ite,i)?'current-row':'']"
+                    v-for="(ite,i) in transData"
+                    @click.stop="rowClick(ite,i)"
+                    :key="ite.key"
+                    style="">
+                <view class='item-td'
+                      :style="[{
+	                       width:`${item.width?item.width:'100'}px`,
+	                       borderRight:`${border?'1px solid #e8e8e8':''}`,
+	                       textAlign:item.align||'left'
+	                      },cellStyle&&getCellStyle(ite,item,i,index)]"
+                      :key="index"
+                      v-for="(item,index) in fixedLeftColumns">
+                  <template v-if="item.type==='selection'">
+                    <view class="checkbox-item">
+                      <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked"/>
+                    </view>
+                  </template>
+                  <template v-else-if="item.type==='index'">
+                    {{i+1}}
+                  </template>
+                  <template v-else>
+                    {{ite[item.name]||item.emptyString}}
+                  </template>
+                </view>
+              </view>
+            </view>
+          </view>
+        </scroll-view>
+        <table-side-summary
+            :scrollbarSize="scrollbarSize"
+            v-if="showSummary&&!(scrollbarSize>0)"
+            :data="data"
+            :showSummary="showSummary"
+            :transColumns="transColumns"
+            :border="border"
+            :summary-method="summaryMethod"
+            :sumText="sumText"
+            :fixedLeftColumns="fixedLeftColumns"/>
+	    </view>
+	  </view>
+    <zb-load-more v-if="isLoadMore&&!completeLoading"/>
+	</view>
+	<!-- #endif -->
+	<!-- #ifndef H5 || APP-PLUS -->
+	<view class="zb-table-applet">
+	  <view class="zb-table-content">
+      <scroll-view
+		<!-- #ifdef MP-ALIPAY -->
+		@scroll="scrollAlipay"
+		<!-- #endif  -->
+
+          @scrolltolower="scrolltolower"
+					<!-- #ifdef MP-ALIPAY -->
+                   style=" height: 100%;overflow-x:scroll"
+				   <!-- #endif  -->
+				   <!-- #ifndef MP-ALIPAY -->
+				   style=" height: 100%"
+				   <!-- #endif  -->
+                   scroll-y="true"
+				   scroll-x="true">
+	    <view class="zb-table-scroll" >
+	      <template v-if="showHeader">
+	        <view class="zb-table-header top-header-uni" style="">
+	            <view class="zb-table-fixed" >
+	              <view class="zb-table-thead" style="position: relative;" >
+	                <view class="item-tr">
+	                  <view
+	                      @click.stop="sortAction(item,index)"
+	                      :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side']"
+	                      :style="{
+	                              left:`${item.left}px`,
+	                              width:`${item.width?item.width:'100'}px`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'100'}px`,
+															   borderRight:`${border?'1px solid #e8e8e8':''}`,
+															  borderTop:`${border?'1px solid #e8e8e8':''}`,
+															   textAlign:item.align||'left'
+														  }"
+	                      v-for="(item,index) in transColumns" :key="index">
+                      <template v-if="item.type==='selection'">
+                        <view class="checkbox-item">
+                          <tableCheckbox
+                              :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                        </view>
+                      </template>
+                      <template v-else>
+                        {{ item.label||'' }}
+                        <view class="sorter-table" v-if="item.sorter">
+                          <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                          <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                        </view>
+                      </template>
+                    </view>
+	                </view>
+	              </view>
+	            </view>
+	        </view>
+	      </template>
+	      <template v-if="!data.length">
+	        <view class="no-data">暂无数据~~</view>
+	      </template>
+          <view class="zb-table-fixed">
+            <view class="zb-table-tbody">
+              <view  :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']"
+                     @click.stop="rowClick(item,index)"
+                     v-for="(item,index) in transData" :key="item.key" >
+                <view
+                    :style="[{
+                      left:`${ite.left}px`,
+                      width:`${ite.width?ite.width:'100'}px`,
+                      flex:i===transColumns.length-1?1:'none',
+                      minWidth:`${ite.width?ite.width:'100'}px`,
+                      borderRight:`${border?'1px solid #e8e8e8':''}`,
+                      textAlign:ite.align||'left',
+                    },getCellStyle(item,ite,index,i)]"
+                    :class="['item-td', i <fixedLeftColumns.length&&'zb-stick-side',stripe?(index % 2) != 0?'odd':'even':'']"
+                    v-for="(ite,i) in transColumns" :key="i">
+                  <template  v-if="ite.type==='operation'">
+                    <view style="display: flex;align-items: center;height: 100%">
+                      <view
+                          v-for="ren,ind in permission(item,ite.renders,index)"
+                          :key="ind"
+                          @click.stop="$emit(ren.func,item,index)"
+                          :style="{
+	                          display:'flex',
+	                          alignItems: 'center',
+	                          marginRight:ite.renders.length>1?'8px':'0'
+	                        }">
+                        <template v-if="ren.type==='custom'">
+                          <view :class="ren.class||''" style="cursor: pointer">
+                            {{ren.name}}
+                          </view>
+                        </template>
+                        <template v-else>
+                          <button
+                              :class="ren.class||''"
+                              :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
+                        </template>
+                      </view>
+                    </view>
+                  </template>
+                  <template v-else-if="ite.type==='selection'">
+                    <view class="checkbox-item">
+                      <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
+                    </view>
+                  </template>
+                  <template v-else-if="ite.type==='img'">
+                    <image
+                        @click.stop="previewImage(item,item[ite.name],index)"
+                        v-if="item[ite.name]"
+                        :show-menu-by-longpress="false"
+                        :src="item[ite.name]" style="width: 40px;height:30px; " mode="aspectFit"></image>
+                    <text v-else>{{ite.emptyString}}</text>
+                  </template>
+                  <template v-else-if="ite.type==='index'">
+                    {{index+1}}
+                  </template>
+                  <template  v-else>
+<!--                    {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
+                    {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
+                  </template>
+                </view>
+              </view>
+            </view>
+          </view>
+        <table-summary
+            v-if="showSummary"
+            :data="data"
+            :showSummary="showSummary"
+            :fixedLeftColumns="fixedLeftColumns"
+            :transColumns="transColumns"
+            :border="border"
+            :summary-method="summaryMethod"
+            :sumText="sumText"
+        />
+	    </view>
+      </scroll-view>
+	  </view>
+    <zb-load-more v-if="isLoadMore&&!completeLoading"/>
+	</view>
+	<!-- #endif -->
+</template>
+<script>
+import TableCheckbox from './components/table-checkbox.vue'
+import TableSummary from "./components/table-summary.vue";
+import TableSideSummary from "./components/table-side-summary.vue";
+import TableH5Summary from './components/table-h5-summary'
+import ZbLoadMore from './components/zb-load-more'
+
+import {getScrollbarSize} from "./js/util";
+export default {
+  components:{
+    TableCheckbox,
+    TableSummary,
+    TableSideSummary,
+    TableH5Summary,
+    ZbLoadMore
+  },
+  props:{
+    highlight:{
+      type:Boolean,
+      default:false
+    },
+    itemDate:{
+      type:Object,
+      default:()=>{}
+    },
+    columns:{
+      type:Array,
+      default:()=>[]
+    },
+    showSummary:{
+      type:Boolean,
+      default:false
+    },
+    isShowLoadMore:{
+      type:Boolean,
+      default:false
+    },
+    data:{
+      type:[Object,Array],
+      default:()=>[]
+    },
+    sumText:{
+      type:String,
+      default:'合计'
+    },
+    showHeader:{
+      type:Boolean,
+      default:true
+    },
+    border:{
+      type:Boolean,
+      default:false
+    },
+    stripe:{
+      type:Boolean,
+      default:true
+    },
+    fit:{
+      type:Boolean,
+      default:false
+    },
+    rowKey:[String, Function],
+    summaryMethod:Function,
+    pullUpLoading:Function,
+    formatter:Function,
+    cellStyle:Function,
+    cellHeaderStyle:Function,
+    permissionBtn:Function,
+  },
+  computed:{
+    loadMoreHeight(){
+      return this.isLoadMore?40:0
+    },
+    fixedLeftColumns(){
+      let arr = []
+      for(let i=0;i<this.columns.length;i++){
+        let item = this.columns[i]
+        if(item.fixed){
+          arr.push(item)
+        }else {
+          break
+        }
+      }
+      return arr
+    },
+    itemfilters(){
+      return(item,ite)=>{
+        if(item[ite.name]==null){
+          return ite.emptyString
+        }
+        return item[ite.name]
+      }
+    },
+    scrollbarSize(){
+		// #ifdef H5
+      return getScrollbarSize()
+	  // #endif
+
+	  // #ifndef H5
+	  return 0
+	  // #endif
+    },
+    isFixedLeft(){
+      if(!this.columns.length){
+        return false
+      }
+      if(!this.data.length){
+        return false
+      }
+      let [firstArr] = this.columns
+      return !!firstArr.fixed;
+    },
+    transColumns(){
+      if(this.fit){
+        this.columns.forEach(column=>{
+          if(column.type==="operation"&&column.renders){
+			      let str = ''
+            column.renders.map((item)=>{
+              str+=item.name
+            })
+            column.width = this.getTextWidth(str)+column.renders.length*40
+          }else if(column.type==="img"){
+			   }else if(column.type==="selection"){
+			}else{
+			let arr = [this.getTextWidth(column.label)]
+            this.data.forEach(data=>{
+              let str = (data[column.name]+'')
+			  if(str==='undefined'){
+				   arr.push(30)
+			  }else{
+				   let width = this.getTextWidth(str)
+				   arr.push(width)
+			  }
+            })
+			      column.width = Math.max(...arr)+20
+          }
+        })
+      }
+      let number = 0
+      this.columns.forEach((item,index)=>{
+        if(item.type==="operation"&&item.renders&&!item.width){
+          let str = ''
+          item.renders.map((item)=>{
+            str+=item.name
+          })
+          item.width = this.getTextWidth(str)+item.renders.length*40
+        }
+        if(item.fixed){
+          if(index===0){
+            item.left = 0
+            number+=item.width
+          }else {
+            item.left = number
+            number+=item.width
+          }
+        }
+        item.emptyString = item.emptyString||'--'
+      })
+      return this.columns
+    },
+    transData(){
+      let flag = this.columns.some(item=>item.type==='selection')
+      this.data.forEach((item,index)=>{
+        if(flag){
+          if(item.checked){
+            if(!this.selectArr.length){
+              this.selectArr.push(item)
+            }
+          }
+        }
+        if(this.rowKey){
+          if(typeof this.rowKey==='function'){
+            item.key = Object.freeze(this.rowKey(item))||Date.now()
+          }else {
+            item.key = Object.freeze(item[this.rowKey])||Date.now()
+          }
+        }else {
+          item.key = index
+        }
+      })
+      if(flag&&this.data.length){
+        let le = this.data.filter(item=>item.checked).length
+        if(le){
+          if(le===this.data.length){
+            this.checkedAll = true
+          }else {
+            this.indeterminate = true
+          }
+        }
+      }
+      return this.data
+    },
+    isHighlight(){
+      return (item,index)=>{
+        if(this.rowKey){
+          return item.key === this.currentRow['key']
+        }else{
+          return index === this.currentRowIndex
+        }
+      }
+    },
+    getHeaderCellStyle() {
+      return (column,  columnIndex,childIndex)=>{
+        const cellStyle = this.cellHeaderStyle;
+        if(typeof cellStyle==='function'){
+          return cellStyle({ column, columnIndex})
+        }
+        return {}
+      }
+    },
+    getCellStyle() {
+     return (row, column, rowIndex, columnIndex)=>{
+       const cellStyle = this.cellStyle;
+       if(typeof cellStyle==='function'){
+         return cellStyle({row, column, rowIndex, columnIndex})
+       }
+       return {}
+     }
+    },
+  },
+  data() {
+    return {
+      button:[],
+	    alipayScrollTop:0,
+      alipayScrollOldTop:0,
+      alipayFlag:false,
+      bodyTableLeft:0,
+      headerTableLeft:0,
+      lastScrollLeft:0,
+      isLoadMore:false,
+      headerFooterTableLeft:0,
+      leftFiexScrollTop:0,
+      bodyScrollTop:0,
+      currentDriver:null,
+      currentDriver1:null,
+      bodyTime:null,
+      currentRowIndex:null,
+      currentRow: {},
+      bodyTime1:null,
+      headerTime:null,
+      debounceTime:null,
+      operation:{},
+      completedFlag:false,
+      selectArr:[],
+      indeterminate:false,
+      checkedAll:false,
+      completeLoading:false,
+      aliTime:null,
+    }
+  },
+  created(){
+  },
+  mounted(){
+  },
+  methods: {
+getMove(){
+	
+},
+    formatterAction(row,column,rowIndex,columnIndex){
+      if(column.formatter&&typeof this.formatter==='function'){
+        return this.formatter(row,column,rowIndex,columnIndex)
+      }
+      return (row[column.name]==null||row[column.name]==='')?column.emptyString:row[column.name]
+    },
+    permission(item,renders,index){
+      if(this.permissionBtn&&typeof this.permissionBtn==='function'){
+        return this.permissionBtn(item,renders,index)
+      }
+      return renders
+    },
+    pullUpCompleteLoading(type){
+      this.isLoadMore = false
+      if(type==='ok'){
+        this.completeLoading = true
+      }
+    },
+    scrollAlipay(e){
+
+      if(!this.alipayScrollOldTop){
+        this.alipayScrollOldTop = e.detail.scrollTop
+      }
+      this.aliTime&&clearTimeout(this.aliTime)
+      this.aliTime = setTimeout(()=>{
+
+        if(this.alipayFlag&&e.detail.scrollTop>this.alipayScrollOldTop){
+          this.pullLoad()
+        }
+        this.alipayFlag = false
+        this.alipayScrollOldTop = null
+      },500)
+    },
+    pullLoad(){
+      if(this.isShowLoadMore){
+        this.isLoadMore = true
+        this.$emit('pullUpLoading')
+        let that = this
+        this.pullUpLoading&&this.pullUpLoading.call(this.$parent.$parent, (type)=>{
+          that.isLoadMore = false
+          if(type==='ok'){
+            that.completeLoading=true
+          }
+        })
+      }
+
+    },
+    scrolltolower(e){
+      this.alipayFlag = true
+      if(e.detail.direction==='bottom'){
+        this.pullLoad()
+      }
+
+      // this.pullUpLoading.call(this.$parent)
+    },
+	  previewImage(item,url,current){
+		  uni.previewImage({
+			  current,
+			  urls:[url]
+		  })
+	  },
+    resetHighlight(){
+      this.currentRowIndex = null
+      this.currentRow = {}
+    },
+    rowClick(row,index){
+      if(this.highlight){
+        this.currentRowIndex = index
+        this.currentRow = row
+        this.$emit('currentChange',row,index)
+      }
+      this.$emit('rowClick',row,index)
+    },
+    checkboxSelectedAll(e){
+      this.indeterminate = false
+      if(e.checked){
+        this.selectArr = []
+        this.checkedAll = true
+        this.data.forEach(item=>{
+          // this.$set(item,'checked',true)
+          item.checked = true
+          this.selectArr.push(item)
+        })
+      }else{
+        this.checkedAll = false
+        this.data.forEach(item=>{
+          this.$set(item,'checked',false)
+        })
+        this.selectArr = []
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+      this.$emit('toggleAllSelection',e.checked,this.selectArr)
+    },
+    checkboxSelected(e,item){
+      // #ifdef H5 || APP-PLUS
+      this.$set(item,'checked',e.checked)
+      // #endif
+      // #ifndef H5 || APP-PLUS
+      this.data.forEach(item=>{
+        if(item.key===e.data.key){
+          item.checked = e.checked
+        }
+      })
+      // #endif
+      item.checked = e.checked
+      e.data.checked = e.checked
+      if(e.checked){
+        this.selectArr.push(e.data)
+      }else{
+        this.selectArr = this.selectArr.filter(item=>item.key!==e.data.key)
+      }
+      if(this.selectArr.length===this.transData.length){
+        this.indeterminate = false
+        this.checkedAll = true
+      }else{
+        this.indeterminate = true
+        this.checkedAll = false
+      }
+      if(!this.selectArr.length){
+        this.checkedAll = false
+        this.indeterminate = false
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+      this.$emit('toggleRowSelection',e.checked,this.selectArr)
+    },
+    itemFilter(item,ite){
+      if(ite.filters&&ite.name){
+        let key = item[ite.name]
+        return ite.filters[key]||''
+      }
+      return item[ite.name]||ite.emptyString
+    },
+    // 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
+    getTextWidth(str) {
+      if(str.length<3){
+        return 40
+      }
+      let regx = /^[0-9]+.?[0-9]*$/
+      let flexWidth = 0
+      for (const char of str) {
+        if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
+          // 如果是英文字符,为字符分配8个单位宽度
+          flexWidth += 10
+        } else if (char >= '\u4e00' && char <= '\u9fa5') {
+          // 如果是中文字符,为字符分配15个单位宽度
+          flexWidth += 15
+        } else if(regx.test(char)){
+          flexWidth += 9
+        }else {
+          // 其他种类字符,为字符分配8个单位宽度
+          flexWidth += 7
+        }
+      }
+      return flexWidth
+    },
+    width(item){
+      return `${item.width?item.width:'100'}px`
+    },
+    showStripe(index){
+      if(this.currentDriver)return
+      if(this.stripe){
+        return (index % 2) != 0?'odd':'even'
+      }else{
+        return ''
+      }
+    },
+    //验证字符串是否是数字
+    checkNumber(theObj) {
+      var reg = /^[0-9]+.?[0-9]*$/;
+      if (reg.test(theObj)) {
+        return true;
+      }
+      return false;
+    },
+    isDate(data){
+      if(isNaN(data)&&!isNaN(Date.parse(data))){
+        return true
+      }
+      return false
+    },
+    sortAction(item,index){
+      if(!item.sorter){return false}
+      this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
+      if(item.sorter==='custom'){
+        this.$emit('sort-change',item,item.sorterMode.replace('_',''),index)
+      }else {
+        this.sortData(item)
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+    },
+    sortData(item){
+      let key = item.name
+
+      if(item.sorterMode==='_asc'){
+        this.data.sort((a,b)=>{
+          if(this.checkNumber(a[key])){
+            return a[key]-b[key]
+          }
+          if(this.isDate(a[key])){
+            let a1 = new Date(a[key]).getTime()
+            let b1 = new Date(b[key]).getTime()
+            return a1-b1
+          }
+        })
+      }else {
+        this.data.sort((a,b)=>{
+          if(this.checkNumber(a[key])){
+            return b[key]-a[key]
+          }
+          if(this.isDate(a[key])){
+            let a1 = new Date(a[key]).getTime()
+            let b1 = new Date(b[key]).getTime()
+            return b1-a1
+          }
+        })
+      }
+    },
+    throttle(method,delay=60){
+      let time = null
+      return (...args)=>{
+        if(!time){
+          time = setTimeout(()=>{
+            method(...args)
+            time = null;
+          },delay)
+        }
+      }
+    },
+    debounce(method,delay=1000){
+      return (...args)=>{
+        this.debounceTime&&clearTimeout(this.debounceTime)
+        this.debounceTime = setTimeout(()=>{
+          method(...args)
+        },delay)
+      }
+    },
+    handleBodyScroll(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.headerTableLeft = e.detail.scrollLeft
+      this.headerFooterTableLeft = e.detail.scrollLeft
+      this.leftFiexScrollTop = e.detail.scrollTop
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+
+    },
+    leftFixedScrollAction(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyScrollTop = e.detail.scrollTop
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    },
+    scrollToLeft(e){
+      if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
+      this.currentDriver1 = e.currentTarget.id
+      if(e.detail.direction==='left'&&this.headerTableLeft<10){
+        this.headerTableLeft = 0
+      }else if(e.detail.direction==='top'&&this.leftFiexScrollTop<10){
+        this.leftFiexScrollTop = 0
+      }
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver1=null
+      },200)
+    },
+    scrollToFixedLeft(e){
+      if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
+      this.currentDriver1 = e.currentTarget.id
+      if(e.detail.direction==='top'&&this.bodyScrollTop<10){
+        this.bodyScrollTop = 0
+      }
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver1=null
+      },200)
+    },
+    handleTableScrollLeft(e,type){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyTableLeft = e.detail.scrollLeft
+      this.headerFooterTableLeft = e.detail.scrollLeft
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    },
+    handleFooterTableScrollLeft(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyTableLeft = e.detail.scrollLeft
+      this.headerTableLeft = e.detail.scrollLeft
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    }
+  }
+}
+</script>
+<style lang="scss">
+.zb-table-fixed-left{
+  /*去除左边滚动条 */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+}
+.zb-table-header{
+  ///*去除头部滚动条 */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+}
+
+</style>
+<style lang="scss" scoped>
+.sorter-table{
+  position: absolute;
+  right: 6px;
+  top:50%;
+  transform:translateY(-50%);
+  .sorter-table-icon{
+    width: 0;
+    height: 0;
+    color: #dcdcdc;
+    border-right: 4px solid transparent;
+    border-left: 4px solid transparent;
+  }
+  .sorter-table-icon:first-child{
+    border-bottom: 5px solid currentColor;
+  }
+  .sorter-table-icon:last-child{
+    margin-top: 1.5px;
+    border-top: 5px solid currentColor;
+  }
+  .sorting_desc{
+    color: #2979ff;
+  }
+  .sorting_asc{
+    color: #2979ff;
+  }
+}
+.checkbox-item{
+  display: flex;align-items: center;justify-content: center;width: 100%;height: 100%
+}
+.no-data{
+  width: 100%;
+  height: 80rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  border-bottom: 1px solid #e8e8e8;
+}
+.item-th{
+  position: relative;
+  flex-shrink: 0;
+  width: 100px;
+  overflow-wrap: break-word;
+  border-bottom: 1px solid #e8e8e8;
+  transition: background 0.3s;
+  padding-right: 4px;
+  word-break:keep-all;           /* 不换行 */
+  white-space:nowrap;          /* 不换行 */
+  overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+  text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+  overflow-wrap: break-word;
+}
+.zb-table{
+  height: 100%;
+  overflow: hidden;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  font-size: 12px;
+  position: relative;
+  .zb-table-content{
+    //height: 100%;
+    //flex: 1;
+    position: relative;
+    overflow: hidden;
+  }
+  .zb-table-fixed{
+    min-width: 100%;
+  }
+  .zb-table-body{
+    position: relative;
+    background: #fff;
+    transition: opacity 0.3s;
+  }
+  .item-tr{
+    display: flex;
+    //height: 41px;
+  }
+  .item-td{
+    flex-shrink: 0;
+    width: 100px;
+    padding-left: 4px;
+    height: 40px;
+    line-height: 40px;
+	padding-right: 4px;
+    box-sizing: border-box;
+    word-break:keep-all;           /* 不换行 */
+    white-space:nowrap;          /* 不换行 */
+    overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+    text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+    overflow-wrap: break-word;
+    border-bottom: 1px solid #e8e8e8;
+    //transition: background 0.3s;
+  }
+
+  .zb-table-fixed-left .zb-table-header{
+    overflow-y: hidden;
+  }
+  .zb-table-header {
+    overflow: hidden;
+    background: #fafafa;
+    .item-th{
+      padding-left: 4px;
+      line-height: 39px;
+      height: 40px;
+      //display: flex;
+      //align-items: center;
+      box-sizing: border-box;
+    }
+  }
+  .zb-table-fixed-left .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-right .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-body-inner{
+    height: 100%;
+    // overflow: scroll;
+  }
+  .zb-table-fixed-left{
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    overflow: hidden;
+    border-radius: 0;
+    height: 100%;
+    //transition: box-shadow 0.3s ease;
+  }
+  .odd{
+    background-color:rgba(249,249,249,0.6);
+    //height: 100%;
+    width: 100%;
+  }
+  .even{
+    background-color:white ;
+    //height: 100%;
+    width: 100%;
+  }
+}
+.scroll-left-fixed{
+  .zb-table-fixed-left {
+    left: 0;
+    box-shadow: 6px 0 6px -4px #ccc;
+  }
+}
+.zb-table-applet{
+  height: 100%;
+  //overflow: hidden;
+  width: 100%;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  font-size: 12px;
+  .zb-table-content{
+    //height: 100%;
+    flex: 1;
+    overflow: hidden;
+    position: relative;
+
+  }
+  .zb-table-fixed{
+    min-width: 100%;
+    width: fit-content;
+  }
+
+  .zb-table-body{
+    position: relative;
+    background: #fff;
+    transition: opacity 0.3s;
+  }
+  .item-tr{
+    display: flex;
+    //height: 41px;
+  }
+  .item-td{
+    flex-shrink: 0;
+    width: 100px;
+    padding-left: 4px;
+    height: 40px;
+    line-height: 40px;
+	padding-right:4px;
+    box-sizing: border-box;
+    word-break:keep-all;           /* 不换行 */
+    white-space:nowrap;          /* 不换行 */
+    overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+    text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+    overflow-wrap: break-word;
+    border-bottom: 1px solid #e8e8e8;
+    //transition: background 0.3s;
+  }
+  .zb-table-header {
+    //overflow: hidden;
+    position: sticky;
+    top: 0;
+    z-index: 2;
+    //width: fit-content;
+    .item-th{
+      padding-left: 4px;
+      line-height: 39px;
+      height: 40px;
+      box-sizing: border-box;
+      background: #fafafa;
+    }
+    .zb-stick-side{
+      position: sticky;
+      top: 0;
+      left: 0;
+      z-index: 2;
+      //border-right: solid 1rpx #dbdbdb;
+      box-sizing: border-box;
+      background: #fafafa;
+      //box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+  .zb-table-fixed-left .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-right .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-header .zb-table-body-inner{
+    height: 100%;
+    // overflow: scroll;
+  }
+  .zb-table-fixed-left{
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    overflow: hidden;
+    border-radius: 0;
+    height: 100%;
+    //transition: box-shadow 0.3s ease;
+  }
+  .scroll-left-fixed{
+    .zb-table-fixed-left {
+      left: 0;
+      box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+  .odd{
+    background-color:rgba(249,249,249,0.6);
+    //height: 100%;
+    width: 100%;
+  }
+  .even{
+    background-color:white ;
+    //height: 100%;
+    width: 100%;
+  }
+  .zb-table-tbody {
+    .zb-stick-side{
+      position: sticky;
+      left: 0;
+      z-index: 1;
+      box-sizing: border-box;
+      background:white;
+      //box-shadow: 6px 0 6px -2px #ccc;
+    }
+    .odd{
+      background:#f9f9f9;
+      //height: 100%;
+      width: 100%;
+    }
+    .even{
+      background:white ;
+      //height: 100%;
+      width: 100%;
+    }
+  }
+  .current-row{
+    .item-td{
+      background-color: #ecf5ff;
+    }
+  }
+}
+.current-row{
+  .item-td{
+    background-color: #ecf5ff;
+  }
+}
+.zb-table-header{
+  height: 40px;
+}
+</style>

+ 1264 - 0
mine/components/zb-table/zb-tables.vue

@@ -0,0 +1,1264 @@
+<template>
+	<!-- #ifdef H5 || APP-PLUS -->
+	<view :class="['zb-table','zb-table-fixed-header',!border&&(bodyTableLeft>50||headerTableLeft>50)&&'scroll-left-fixed']">
+	  <view class="zb-table-content" style="flex: 1">
+	    <view class="zb-table-scroll" style="height: 100%;">
+	      <template v-if="showHeader">
+	        <view class="zb-table-header top-header-uni" :style="{paddingRight:`${scrollbarSize}rpx`}"
+          >
+	          <scroll-view class="zb-table-headers"
+							@touchmove.stop="getMove"
+	                       @scroll="handleTableScrollLeft"
+	                       scroll-x="true"
+	                       scroll-y="false"
+	                       id="tableHeaders"
+	                       scroll-anchoring="true"
+	                       :scroll-left="headerTableLeft"
+	                       style="
+						height: 100%">
+	            <view class="zb-table-fixed" >
+	              <view class="zb-table-thead" style="position: relative;" >
+	                <view class="item-tr">
+	                  <view
+	                      @click.stop="sortAction(item,index)"
+	                      class="item-th"
+	                      :style="[{
+	                              width:`${item.width?item.width:'200'}rpx`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'200'}rpx`,
+															  borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+															  borderRight:`${(scrollbarSize&&index===transColumns.length-1)?'':border?'2rpx solid #e8e8e8':''}`,
+															  borderTop:`${border?'2rpx solid #e8e8e8':''}`,
+															  textAlign:item.align||'left',
+															  paddingRight:`${item.paddingRight?item.paddingRight:'8'}rpx`,
+														  },getHeaderCellStyle(item,index)]"
+	                      v-for="(item,index) in transColumns" :key="index">
+                      <template v-if="item.type==='selection'">
+                        <view class="checkbox-item">
+                          <tableCheckbox
+                              :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                        </view>
+                      </template>
+                      <template v-else>
+						  {{ item.label }}
+						  <block v-if="item.manfen">/{{item.manfen}}</block>
+                        <view class="sorter-table" v-if="item.sorter">
+                          <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                          <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                        </view>
+                      </template>
+                    </view>
+	                </view>
+	              </view>
+	            </view>
+	          </scroll-view>
+	        </view>
+	      </template>
+	      <template v-if="!data.length">
+	        <view class="no-data">暂无数据~~</view>
+	      </template>
+	      <scroll-view
+            class="zb-table-body" ref="tableBody"	scroll-x="true"	scroll-y="true"	id="tableBody"
+	                   :lower-threshold="40"
+	                   :upper-threshold="10"
+					   @touchmove.stop="getMove"
+                     @scrolltolower="scrolltolower"
+	                   @scrolltoupper="(e)=>debounce(scrollToLeft)(e)"
+                     @scroll="handleBodyScroll"	:scroll-left="bodyTableLeft"	:scroll-top="bodyScrollTop"
+                     :style=" `height: calc(100% - ${showSummary?160:80}rpx)`" >
+	          <view class="zb-table-fixed">
+	            <view class="zb-table-tbody">
+	              <view  :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']"
+                       @click.stop="rowClick(item,index)"
+	                     v-for="(item,index) in transData" :key="item.key" >
+	                <view
+	                    :style="[{
+									              width:`${ite.width?ite.width:'200'}rpx`,
+															  flex:i===transColumns.length-1?1:'none',
+															  minWidth:`${ite.width?ite.width:'200'}rpx`,
+															  borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+                                textAlign:ite.align||'left',
+														  },cellStyle&&getCellStyle(item,ite,index,i)]"
+
+	                    :class="['item-td',stripe?(index % 2) != 0?'odd':'even':'']"
+	                    v-for="(ite,i) in transColumns" :key="i">
+	                  <template  v-if="ite.type==='operation'">
+	                    <view style="display: flex;align-items: center;height: 100%">
+	                      <view
+                            v-for="ren,ind in permission(item,ite.renders,index)"
+	                          :key="ind"
+	                          @click.stop="$emit(ren.func,item,index)"
+	                          :style="{
+	                          display:'flex',
+	                          alignItems: 'center',
+	                          marginRight:ite.renders.length>1?'16rpx':'0'
+	                        }">
+                          <template v-if="ren.type==='custom'">
+                            <view :class="ren.class||''" style="cursor: pointer">
+                              {{ren.name}}
+                            </view>
+                          </template>
+                          <template v-else>
+                            <button
+                                :class="ren.class||''"
+                                :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
+                          </template>
+	                      </view>
+	                    </view>
+	                  </template>
+                    <template v-else-if="ite.type==='selection'">
+                      <view class="checkbox-item">
+                        <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
+                      </view>
+                    </template>
+                    <template v-else-if="ite.type==='index'">
+                      {{index+1}}
+                    </template>
+                  <template v-else-if="ite.type==='img'">
+                    <view class="checkbox-item">
+                      <image
+                    @click.stop="previewImage(item,item[ite.name],index)"
+                    v-if="item[ite.name]"
+                    :show-menu-by-longpress="false"
+                    :src="item[ite.name]" style="width: 80rpx;height:60rpx; " mode="aspectFit"></image>
+                    <text v-else>{{ite.emptyString}}</text>
+                    </view>
+                  </template>
+	                  <template  v-else>
+<!--                      {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
+                      {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
+	                  </template>
+	                </view>
+	              </view>
+	            </view>
+	          </view>
+	        </scroll-view>
+       <table-h5-summary
+           :scrollbarSize="scrollbarSize"
+           :data="data"
+           :handleFooterTableScrollLeft="handleFooterTableScrollLeft"
+           :headerFooterTableLeft="headerFooterTableLeft"
+           v-if="showSummary"
+           :showSummary="showSummary"
+           :transColumns="transColumns"
+           :border="border"
+           :summary-method="summaryMethod"
+           :sumText="sumText"
+           :fixedLeftColumns="fixedLeftColumns"/>
+	    </view>
+	    <view class="zb-table-fixed-left"
+            v-if="isFixedLeft"
+            :style=" {height:  `calc(100% - ${scrollbarSize}rpx)`}"
+      >
+	      <template v-if="showHeader">
+	        <view class="zb-table-header" style="display: flex">
+	          <view class="item-tr"
+                  style=""
+                  @click.stop="rowClick(item,index)"
+                  v-for="(item,index) in fixedLeftColumns" :key="index">
+	            <view
+	                :style="{
+	               width:`${item.width?item.width:'200'}rpx`,
+	               borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+	               borderTop:`${border?'2rpx solid #e8e8e8':''}`,
+                textAlign:item.align||'left'
+	            }"
+	                @click.stop="sortAction(item,index)"
+	                class="item-th"
+	            >
+                <template v-if="item.type==='selection'">
+                  <view class="checkbox-item">
+                    <tableCheckbox
+                        :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                  </view>
+                </template>
+                <template v-else>
+                  {{ item.label }}
+				  <block v-if="item.manfen">/{{item.manfen}}</block>
+                  <view class="sorter-table" v-if="item.sorter">
+                    <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                    <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                  </view>
+                </template>
+              </view>
+	          </view>
+
+	        </view>
+	      </template>
+        <scroll-view
+            scroll-y="true"
+            id="leftTableFixed"
+            :upper-threshold="15"
+            @scrolltoupper="(e)=>scrollToFixedLeft(e)"
+            @scroll="leftFixedScrollAction"
+            :scroll-top="leftFiexScrollTop"
+            class="zb-table-body-inner"
+            :style=" `height: calc(100% - ${showSummary?160:80}rpx)`">
+          <view class="zb-table-fixed">
+            <view class="zb-table-tbody">
+              <view
+                  :class="['item-tr',stripe?(i % 2) != 0?'odd':'even':'',highlight&&isHighlight(ite,i)?'current-row':'']"
+                    v-for="(ite,i) in transData"
+                    @click.stop="rowClick(ite,i)"
+                    :key="ite.key"
+                    style="">
+                <view class='item-td'
+                      :style="[{
+	                       width:`${item.width?item.width:'200'}rpx`,
+	                       borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+	                       textAlign:item.align||'left'
+	                      },cellStyle&&getCellStyle(ite,item,i,index)]"
+                      :key="index"
+                      v-for="(item,index) in fixedLeftColumns">
+                  <template v-if="item.type==='selection'">
+                    <view class="checkbox-item">
+                      <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,ite)" :cellData="ite" :checked="ite.checked"/>
+                    </view>
+                  </template>
+                  <template v-else-if="item.type==='index'">
+                    {{i+1}}
+                  </template>
+                  <template v-else>
+                    {{ite[item.name]||item.emptyString}}
+                  </template>
+                </view>
+              </view>
+            </view>
+          </view>
+        </scroll-view>
+        <table-side-summary
+            :scrollbarSize="scrollbarSize"
+            v-if="showSummary&&!(scrollbarSize>0)"
+            :data="data"
+            :showSummary="showSummary"
+            :transColumns="transColumns"
+            :border="border"
+            :summary-method="summaryMethod"
+            :sumText="sumText"
+            :fixedLeftColumns="fixedLeftColumns"/>
+	    </view>
+	  </view>
+    <zb-load-more v-if="isLoadMore&&!completeLoading"/>
+	</view>
+	<!-- #endif -->
+	<!-- #ifndef H5 || APP-PLUS -->
+	<view class="zb-table-applet">
+	  <view class="zb-table-content">
+      <scroll-view
+		<!-- #ifdef MP-ALIPAY -->
+		@scroll="scrollAlipay"
+		<!-- #endif  -->
+
+          @scrolltolower="scrolltolower"
+					<!-- #ifdef MP-ALIPAY -->
+                   style=" height: 100%;overflow-x:scroll"
+				   <!-- #endif  -->
+				   <!-- #ifndef MP-ALIPAY -->
+				   style=" height: 100%"
+				   <!-- #endif  -->
+                   scroll-y="true"
+				   scroll-x="true">
+	    <view class="zb-table-scroll" >
+	      <template v-if="showHeader">
+	        <view class="zb-table-header top-header-uni" style="">
+	            <view class="zb-table-fixed" >
+	              <view class="zb-table-thead" style="position: relative;" >
+	                <view class="item-tr">
+	                  <view
+	                      @click.stop="sortAction(item,index)"
+	                      :class="['item-th',index <fixedLeftColumns.length&&'zb-stick-side']"
+	                      :style="{
+	                              left:`${item.left}rpx`,
+	                              width:`${item.width?item.width:'200'}rpx`,
+															  flex:index===transColumns.length-1?1:'none',
+															  minWidth:`${item.width?item.width:'200'}rpx`,
+															   borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+															  borderTop:`${border?'2rpx solid #e8e8e8':''}`,
+															   textAlign:item.align||'left'
+														  }"
+	                      v-for="(item,index) in transColumns" :key="index">
+                      <template v-if="item.type==='selection'">
+                        <view class="checkbox-item">
+                          <tableCheckbox
+                              :indeterminate="indeterminate" :checked="checkedAll" @checkboxSelected="checkboxSelectedAll"></tableCheckbox>
+                        </view>
+                      </template>
+                      <template v-else>
+                        {{ item.label||'' }}
+						<block v-if="item.manfen">/{{item.manfen}}</block>
+                        <view class="sorter-table" v-if="item.sorter">
+                          <view :class="['sorter-table-icon',item.sorterMode==='_asc'&&`sorting${item.sorterMode||''}`]"></view>
+                          <view :class="['sorter-table-icon',item.sorterMode==='_desc'&&`sorting${item.sorterMode||''}`]"></view>
+                        </view>
+                      </template>
+                    </view>
+	                </view>
+	              </view>
+	            </view>
+	        </view>
+	      </template>
+	      <template v-if="!data.length">
+	        <view class="no-data">暂无数据~~</view>
+	      </template>
+          <view class="zb-table-fixed">
+            <view class="zb-table-tbody">
+              <view  :class="['item-tr',highlight&&isHighlight(item,index)?'current-row':'']"
+                     @click.stop="rowClick(item,index)"
+                     v-for="(item,index) in transData" :key="item.key" >
+                <view
+                    :style="[{
+                      left:`${ite.left}rpx`,
+                      width:`${ite.width?ite.width:'200'}rpx`,
+                      flex:i===transColumns.length-1?1:'none',
+                      minWidth:`${ite.width?ite.width:'200'}rpx`,
+                      borderRight:`${border?'2rpx solid #e8e8e8':''}`,
+                      textAlign:ite.align||'left',
+                    },getCellStyle(item,ite,index,i)]"
+                    :class="['item-td', i <fixedLeftColumns.length&&'zb-stick-side',stripe?(index % 2) != 0?'odd':'even':'']"
+                    v-for="(ite,i) in transColumns" :key="i">
+                  <template  v-if="ite.type==='operation'">
+                    <view style="display: flex;align-items: center;height: 100%">
+                      <view
+                          v-for="ren,ind in permission(item,ite.renders,index)"
+                          :key="ind"
+                          @click.stop="$emit(ren.func,item,index)"
+                          :style="{
+	                          display:'flex',
+	                          alignItems: 'center',
+	                          marginRight:ite.renders.length>1?'16rpx':'0'
+	                        }">
+                        <template v-if="ren.type==='custom'">
+                          <view :class="ren.class||''" style="cursor: pointer">
+                            {{ren.name}}
+                          </view>
+                        </template>
+                        <template v-else>
+                          <button
+                              :class="ren.class||''"
+                              :type="ren.type||'primary'" :size="ren.size||'mini'">{{ren.name}}</button>
+                        </template>
+                      </view>
+                    </view>
+                  </template>
+                  <template v-else-if="ite.type==='selection'">
+                    <view class="checkbox-item">
+                      <tableCheckbox @checkboxSelected="(e)=>checkboxSelected(e,item)" :cellData="item" :checked="item.checked"/>
+                    </view>
+                  </template>
+                  <template v-else-if="ite.type==='img'">
+                    <image
+                        @click.stop="previewImage(item,item[ite.name],index)"
+                        v-if="item[ite.name]"
+                        :show-menu-by-longpress="false"
+                        :src="item[ite.name]" style="width: 80rpx;height:60rpx; " mode="aspectFit"></image>
+                    <text v-else>{{ite.emptyString}}</text>
+                  </template>
+                  <template v-else-if="ite.type==='index'">
+                    {{index+1}}
+                  </template>
+                  <template  v-else>
+<!--                    {{ ite.filters?itemFilter(item,ite):(item[ite.name]==null||item[ite.name]==='')?ite.emptyString:item[ite.name] }}-->
+                    {{ ite.filters?itemFilter(item,ite):formatterAction(item,ite,index,i) }}
+                  </template>
+                </view>
+              </view>
+            </view>
+          </view>
+        <table-summary
+            v-if="showSummary"
+            :data="data"
+            :showSummary="showSummary"
+            :fixedLeftColumns="fixedLeftColumns"
+            :transColumns="transColumns"
+            :border="border"
+            :summary-method="summaryMethod"
+            :sumText="sumText"
+        />
+	    </view>
+      </scroll-view>
+	  </view>
+    <zb-load-more v-if="isLoadMore&&!completeLoading"/>
+	</view>
+	<!-- #endif -->
+</template>
+<script>
+import TableCheckbox from './components/table-checkbox.vue'
+import TableSummary from "./components/table-summary.vue";
+import TableSideSummary from "./components/table-side-summary.vue";
+import TableH5Summary from './components/table-h5-summary'
+import ZbLoadMore from './components/zb-load-more'
+
+import {getScrollbarSize} from "./js/util";
+// fit 列的宽度是否自撑开
+// column 显示的列数据
+// stripe 是否为斑马纹 table
+// show-header 是否显示表头
+export default {
+  components:{
+    TableCheckbox,
+    TableSummary,
+    TableSideSummary,
+    TableH5Summary,
+    ZbLoadMore
+  },
+  props:{
+    highlight:{
+      type:Boolean,
+      default:false
+    },
+    itemDate:{
+      type:Object,
+      default:()=>{}
+    },
+    columns:{
+      type:Array,
+      default:()=>[]
+    },
+    showSummary:{
+      type:Boolean,
+      default:false
+    },
+    isShowLoadMore:{
+      type:Boolean,
+      default:false
+    },
+    data:{
+      type:[Object,Array],
+      default:()=>[]
+    },
+    sumText:{
+      type:String,
+      default:'合计'
+    },
+    showHeader:{
+      type:Boolean,
+      default:true
+    },
+    border:{
+      type:Boolean,
+      default:false
+    },
+    stripe:{
+      type:Boolean,
+      default:true
+    },
+    fit:{
+      type:Boolean,
+      default:false
+    },
+    rowKey:[String, Function],
+    summaryMethod:Function,
+    pullUpLoading:Function,
+    formatter:Function,
+    cellStyle:Function,
+    cellHeaderStyle:Function,
+    permissionBtn:Function,
+  },
+  computed:{
+    loadMoreHeight(){
+      return this.isLoadMore?40:0
+    },
+    fixedLeftColumns(){
+      let arr = []
+      for(let i=0;i<this.columns.length;i++){
+        let item = this.columns[i]
+        if(item.fixed){
+          arr.push(item)
+        }else {
+          break
+        }
+      }
+      return arr
+    },
+    itemfilters(){
+      return(item,ite)=>{
+        if(item[ite.name]==null){
+          return ite.emptyString
+        }
+        return item[ite.name]
+      }
+    },
+    scrollbarSize(){
+		// #ifdef H5
+      return getScrollbarSize()
+	  // #endif
+
+	  // #ifndef H5
+	  return 0
+	  // #endif
+    },
+    isFixedLeft(){
+      if(!this.columns.length){
+        return false
+      }
+      if(!this.data.length){
+        return false
+      }
+      let [firstArr] = this.columns
+      return !!firstArr.fixed;
+    },
+    transColumns(){
+      if(this.fit){
+        this.columns.forEach(column=>{
+          if(column.type==="operation"&&column.renders){
+			      let str = ''
+            column.renders.map((item)=>{
+              str+=item.name
+            })
+            column.width = this.getTextWidth(str)+column.renders.length*40
+          }else if(column.type==="img"){
+			   }else if(column.type==="selection"){
+			}else{
+				console.log(column,23)
+			let arr = [this.getTextWidth(column.label)]
+            this.data.forEach(data=>{
+              let str = (data[column.name]+'')
+			  if(str==='undefined'){
+				   arr.push(60)
+			  }else{
+				   let width = this.getTextWidth(str)
+				   arr.push(width)
+			  }
+            })
+			      column.width = Math.max(...arr)+40
+          }
+        })
+      }
+      let number = 0
+      this.columns.forEach((item,index)=>{
+        if(item.type==="operation"&&item.renders&&!item.width){
+          let str = ''
+          item.renders.map((item)=>{
+            str+=item.name
+          })
+          item.width = this.getTextWidth(str)+item.renders.length*40
+        }
+        if(item.fixed){
+          if(index===0){
+            item.left = 0
+            number+=item.width
+          }else {
+            item.left = number
+            number+=item.width
+          }
+        }
+        item.emptyString = item.emptyString||'--'
+      })
+      return this.columns
+    },
+    transData(){
+      let flag = this.columns.some(item=>item.type==='selection')
+      this.data.forEach((item,index)=>{
+        if(flag){
+          if(item.checked){
+            if(!this.selectArr.length){
+              this.selectArr.push(item)
+            }
+          }
+        }
+        if(this.rowKey){
+          if(typeof this.rowKey==='function'){
+            item.key = Object.freeze(this.rowKey(item))||Date.now()
+          }else {
+            item.key = Object.freeze(item[this.rowKey])||Date.now()
+          }
+        }else {
+          item.key = index
+        }
+      })
+      if(flag&&this.data.length){
+        let le = this.data.filter(item=>item.checked).length
+        if(le){
+          if(le===this.data.length){
+            this.checkedAll = true
+          }else {
+            this.indeterminate = true
+          }
+        }
+      }
+      return this.data
+    },
+    isHighlight(){
+      return (item,index)=>{
+        if(this.rowKey){
+          return item.key === this.currentRow['key']
+        }else{
+          return index === this.currentRowIndex
+        }
+      }
+    },
+    getHeaderCellStyle() {
+      return (column,  columnIndex,childIndex)=>{
+        const cellStyle = this.cellHeaderStyle;
+        if(typeof cellStyle==='function'){
+          return cellStyle({ column, columnIndex})
+        }
+        return {}
+      }
+    },
+    getCellStyle() {
+     return (row, column, rowIndex, columnIndex)=>{
+       const cellStyle = this.cellStyle;
+       if(typeof cellStyle==='function'){
+         return cellStyle({row, column, rowIndex, columnIndex})
+       }
+       return {}
+     }
+    },
+  },
+  data() {
+    return {
+      button:[],
+	    alipayScrollTop:0,
+      alipayScrollOldTop:0,
+      alipayFlag:false,
+      bodyTableLeft:0,
+      headerTableLeft:0,
+      lastScrollLeft:0,
+      isLoadMore:false,
+      headerFooterTableLeft:0,
+      leftFiexScrollTop:0,
+      bodyScrollTop:0,
+      currentDriver:null,
+      currentDriver1:null,
+      bodyTime:null,
+      currentRowIndex:null,
+      currentRow: {},
+      bodyTime1:null,
+      headerTime:null,
+      debounceTime:null,
+      operation:{},
+      completedFlag:false,
+      selectArr:[],
+      indeterminate:false,
+      checkedAll:false,
+      completeLoading:false,
+      aliTime:null,
+    }
+  },
+  created(){
+  },
+  mounted(){
+  },
+  methods: {
+getMove(){
+	
+},
+    formatterAction(row,column,rowIndex,columnIndex){
+      if(column.formatter&&typeof this.formatter==='function'){
+        return this.formatter(row,column,rowIndex,columnIndex)
+      }
+      return (row[column.name]==null||row[column.name]==='')?column.emptyString:row[column.name]
+    },
+    permission(item,renders,index){
+      if(this.permissionBtn&&typeof this.permissionBtn==='function'){
+        return this.permissionBtn(item,renders,index)
+      }
+      return renders
+    },
+    pullUpCompleteLoading(type){
+      this.isLoadMore = false
+      if(type==='ok'){
+        this.completeLoading = true
+      }
+    },
+    scrollAlipay(e){
+
+      if(!this.alipayScrollOldTop){
+        this.alipayScrollOldTop = e.detail.scrollTop
+      }
+      this.aliTime&&clearTimeout(this.aliTime)
+      this.aliTime = setTimeout(()=>{
+
+        if(this.alipayFlag&&e.detail.scrollTop>this.alipayScrollOldTop){
+          this.pullLoad()
+        }
+        this.alipayFlag = false
+        this.alipayScrollOldTop = null
+      },500)
+    },
+    pullLoad(){
+      if(this.isShowLoadMore){
+        this.isLoadMore = true
+        this.$emit('pullUpLoading')
+        let that = this
+        this.pullUpLoading&&this.pullUpLoading.call(this.$parent.$parent, (type)=>{
+          that.isLoadMore = false
+          if(type==='ok'){
+            that.completeLoading=true
+          }
+        })
+      }
+
+    },
+    scrolltolower(e){
+      this.alipayFlag = true
+      if(e.detail.direction==='bottom'){
+        this.pullLoad()
+      }
+
+      // this.pullUpLoading.call(this.$parent)
+    },
+	  previewImage(item,url,current){
+		  uni.previewImage({
+			  current,
+			  urls:[url]
+		  })
+	  },
+    resetHighlight(){
+      this.currentRowIndex = null
+      this.currentRow = {}
+    },
+    rowClick(row,index){
+      if(this.highlight){
+        this.currentRowIndex = index
+        this.currentRow = row
+        this.$emit('currentChange',row,index)
+      }
+      this.$emit('rowClick',row,index)
+    },
+    checkboxSelectedAll(e){
+      this.indeterminate = false
+      if(e.checked){
+        this.selectArr = []
+        this.checkedAll = true
+        this.data.forEach(item=>{
+          // this.$set(item,'checked',true)
+          item.checked = true
+          this.selectArr.push(item)
+        })
+      }else{
+        this.checkedAll = false
+        this.data.forEach(item=>{
+          this.$set(item,'checked',false)
+        })
+        this.selectArr = []
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+      this.$emit('toggleAllSelection',e.checked,this.selectArr)
+    },
+    checkboxSelected(e,item){
+      // #ifdef H5 || APP-PLUS
+      this.$set(item,'checked',e.checked)
+      // #endif
+      // #ifndef H5 || APP-PLUS
+      this.data.forEach(item=>{
+        if(item.key===e.data.key){
+          item.checked = e.checked
+        }
+      })
+      // #endif
+      item.checked = e.checked
+      e.data.checked = e.checked
+      if(e.checked){
+        this.selectArr.push(e.data)
+      }else{
+        this.selectArr = this.selectArr.filter(item=>item.key!==e.data.key)
+      }
+      if(this.selectArr.length===this.transData.length){
+        this.indeterminate = false
+        this.checkedAll = true
+      }else{
+        this.indeterminate = true
+        this.checkedAll = false
+      }
+      if(!this.selectArr.length){
+        this.checkedAll = false
+        this.indeterminate = false
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+      this.$emit('toggleRowSelection',e.checked,this.selectArr)
+    },
+    itemFilter(item,ite){
+      if(ite.filters&&ite.name){
+        let key = item[ite.name]
+        return ite.filters[key]||''
+      }
+      return item[ite.name]||ite.emptyString
+    },
+    // 默认字体为微软雅黑 Microsoft YaHei,字体大小为 14px
+    getTextWidth(str) {
+      if(str.length<3){
+        return 80
+      }
+      let regx = /^[0-9]+.?[0-9]*$/
+      let flexWidth = 0
+      for (const char of str) {
+        if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
+          // 如果是英文字符,为字符分配8个单位宽度
+          flexWidth += 20
+        } else if (char >= '\u4e00' && char <= '\u9fa5') {
+          // 如果是中文字符,为字符分配15个单位宽度
+          flexWidth += 30
+        } else if(regx.test(char)){
+          flexWidth += 18
+        }else {
+          // 其他种类字符,为字符分配8个单位宽度
+          flexWidth += 14
+        }
+      }
+      return flexWidth
+    },
+    width(item){
+      return `${item.width?item.width:'200'}rpx`
+    },
+    showStripe(index){
+      if(this.currentDriver)return
+      if(this.stripe){
+        return (index % 2) != 0?'odd':'even'
+      }else{
+        return ''
+      }
+    },
+    //验证字符串是否是数字
+    checkNumber(theObj) {
+      var reg = /^[0-9]+.?[0-9]*$/;
+      if (reg.test(theObj)) {
+        return true;
+      }
+      return false;
+    },
+    isDate(data){
+      if(isNaN(data)&&!isNaN(Date.parse(data))){
+        return true
+      }
+      return false
+    },
+    sortAction(item,index){
+      if(!item.sorter){return false}
+      this.$set(item,'sorterMode',item.sorterMode==='_asc'?'_desc':'_asc')
+      if(item.sorter==='custom'){
+        this.$emit('sort-change',item,item.sorterMode.replace('_',''),index)
+      }else {
+        this.sortData(item)
+      }
+      // #ifndef H5 || APP-PLUS
+      this.$forceUpdate()
+      // #endif
+    },
+    sortData(item){
+      let key = item.name
+
+      if(item.sorterMode==='_asc'){
+        this.data.sort((a,b)=>{
+          if(this.checkNumber(a[key])){
+            return a[key]-b[key]
+          }
+          if(this.isDate(a[key])){
+            let a1 = new Date(a[key]).getTime()
+            let b1 = new Date(b[key]).getTime()
+            return a1-b1
+          }
+        })
+      }else {
+        this.data.sort((a,b)=>{
+          if(this.checkNumber(a[key])){
+            return b[key]-a[key]
+          }
+          if(this.isDate(a[key])){
+            let a1 = new Date(a[key]).getTime()
+            let b1 = new Date(b[key]).getTime()
+            return b1-a1
+          }
+        })
+      }
+    },
+    throttle(method,delay=60){
+      let time = null
+      return (...args)=>{
+        if(!time){
+          time = setTimeout(()=>{
+            method(...args)
+            time = null;
+          },delay)
+        }
+      }
+    },
+    debounce(method,delay=1000){
+      return (...args)=>{
+        this.debounceTime&&clearTimeout(this.debounceTime)
+        this.debounceTime = setTimeout(()=>{
+          method(...args)
+        },delay)
+      }
+    },
+    handleBodyScroll(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.headerTableLeft = e.detail.scrollLeft
+      this.headerFooterTableLeft = e.detail.scrollLeft
+      this.leftFiexScrollTop = e.detail.scrollTop
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+
+    },
+    leftFixedScrollAction(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyScrollTop = e.detail.scrollTop
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    },
+    scrollToLeft(e){
+      if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
+      this.currentDriver1 = e.currentTarget.id
+      if(e.detail.direction==='left'&&this.headerTableLeft<10){
+        this.headerTableLeft = 0
+      }else if(e.detail.direction==='top'&&this.leftFiexScrollTop<10){
+        this.leftFiexScrollTop = 0
+      }
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver1=null
+      },200)
+    },
+    scrollToFixedLeft(e){
+      if(this.currentDriver1&&this.currentDriver1!==e.currentTarget.id)return
+      this.currentDriver1 = e.currentTarget.id
+      if(e.detail.direction==='top'&&this.bodyScrollTop<10){
+        this.bodyScrollTop = 0
+      }
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver1=null
+      },200)
+    },
+    handleTableScrollLeft(e,type){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyTableLeft = e.detail.scrollLeft
+      this.headerFooterTableLeft = e.detail.scrollLeft
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    },
+    handleFooterTableScrollLeft(e){
+      if(this.currentDriver&&this.currentDriver!==e.currentTarget.id)return
+      this.currentDriver = e.currentTarget.id
+      this.bodyTableLeft = e.detail.scrollLeft
+      this.headerTableLeft = e.detail.scrollLeft
+      this.bodyTime&&clearTimeout(this.bodyTime)
+      this.bodyTime = setTimeout(()=>{
+        this.currentDriver=null
+      },200)
+    }
+  }
+}
+</script>
+<style lang="scss">
+.zb-table-fixed-left{
+  /*去除左边滚动条 */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+}
+.zb-table-header{
+  ///*去除头部滚动条 */
+  scroll-view ::-webkit-scrollbar {
+    display: none !important;
+    width: 0 !important;
+    height: 0 !important;
+    -webkit-appearance: none;
+    background: transparent;
+  }
+}
+
+</style>
+<style lang="scss" scoped>
+.sorter-table{
+  position: absolute;
+  right: 2rpx;
+  top:50%;
+  transform:translateY(-50%);
+  .sorter-table-icon{
+    width: 0;
+    height: 0;
+    color: #dcdcdc;
+    border-right: 8rpx solid transparent;
+    border-left: 8rpx solid transparent;
+  }
+  .sorter-table-icon:first-child{
+    border-bottom: 14rpx solid currentColor;
+  }
+  .sorter-table-icon:last-child{
+    margin-top: 3rpx;
+    border-top: 14rpx solid currentColor;
+  }
+  .sorting_desc{
+    color: #2979ff;
+  }
+  .sorting_asc{
+    color: #2979ff;
+  }
+}
+.checkbox-item{
+  display: flex;align-items: center;justify-content: center;width: 100%;height: 100%
+}
+.no-data{
+  width: 100%;
+  height: 80rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  // border-bottom: 1px solid #e8e8e8;
+}
+.item-th{
+  position: relative;
+  flex-shrink: 0;
+  width: 200rpx;
+  overflow-wrap: break-word;
+  border-bottom: 2rpx solid #e8e8e8;
+  transition: background 0.3s;
+  padding-right: 8rpx;
+  word-break:keep-all;           /* 不换行 */
+  white-space:nowrap;          /* 不换行 */
+  overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+  text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+  overflow-wrap: break-word;
+}
+.zb-table{
+  height: 100%;
+  overflow: hidden;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  font-size: 28rpx;
+  position: relative;
+  .zb-table-content{
+    //height: 100%;
+    //flex: 1;
+    position: relative;
+    overflow: hidden;
+  }
+  .zb-table-fixed{
+    min-width: 100%;
+  }
+  .zb-table-body{
+    position: relative;
+    background: #fff;
+    transition: opacity 0.3s;
+  }
+  .item-tr{
+    display: flex;
+    //height: 41px;
+  }
+  .item-td{
+    flex-shrink: 0;
+    width:200rpx;
+    padding-left: 8rpx;
+    height: 80rpx;
+    line-height: 80rpx;
+	padding-right: 8rpx;
+    box-sizing: border-box;
+    word-break:keep-all;           /* 不换行 */
+    white-space:nowrap;          /* 不换行 */
+    overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+    text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+    overflow-wrap: break-word;
+    border-bottom: 2rpx solid #e8e8e8;
+    //transition: background 0.3s;
+  }
+
+  .zb-table-fixed-left .zb-table-header{
+    overflow-y: hidden;
+  }
+  .zb-table-header {
+    overflow: hidden;
+    background: #fafafa;
+    .item-th{
+      padding-left: 8rpx;
+      line-height: 78rpx;
+      height: 80rpx;
+      //display: flex;
+      //align-items: center;
+      box-sizing: border-box;
+    }
+  }
+  .zb-table-fixed-left .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-right .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-body-inner{
+    height: 100%;
+    // overflow: scroll;
+  }
+  .zb-table-fixed-left{
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    overflow: hidden;
+    border-radius: 0;
+    height: 100%;
+    //transition: box-shadow 0.3s ease;
+  }
+  .odd{
+    background-color:rgba(249,249,249,0.6);
+    //height: 100%;
+    width: 100%;
+  }
+  .even{
+    background-color:white ;
+    //height: 100%;
+    width: 100%;
+  }
+}
+.scroll-left-fixed{
+  .zb-table-fixed-left {
+    left: 0;
+    box-shadow: 12rpx 0 12rpx -8rpx #ccc;
+  }
+}
+.zb-table-applet{
+  height: 100%;
+  //overflow: hidden;
+  width: 100%;
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  font-size: 28rpx;
+  .zb-table-content{
+    //height: 100%;
+    flex: 1;
+    overflow: hidden;
+    position: relative;
+
+  }
+  .zb-table-fixed{
+    min-width: 100%;
+    width: fit-content;
+  }
+
+  .zb-table-body{
+    position: relative;
+    background: #fff;
+    transition: opacity 0.3s;
+  }
+  .item-tr{
+    display: flex;
+    //height: 41px;
+  }
+  .item-td{
+    flex-shrink: 0;
+    width: 200rpx;
+    padding-left: 8rpx;
+    height: 80rpx;
+    line-height: 80rpx;
+	padding-right:8rpx;
+    box-sizing: border-box;
+    word-break:keep-all;           /* 不换行 */
+    white-space:nowrap;          /* 不换行 */
+    overflow:hidden;               /* 内容超出宽度时隐藏超出部分的内容 */
+    text-overflow:ellipsis;         /* 当对象内文本溢出时显示省略标记(...) ;需与overflow:hidden;一起使用。*/
+    overflow-wrap: break-word;
+    border-bottom: 2rpx solid #e8e8e8;
+    //transition: background 0.3s;
+  }
+  .zb-table-header {
+    //overflow: hidden;
+    position: sticky;
+    top: 0;
+    z-index: 2;
+    //width: fit-content;
+    .item-th{
+      padding-left: 8rpx;
+      line-height: 78rpx;
+      height: 80rpx;
+      box-sizing: border-box;
+      background: #fafafa;
+    }
+    .zb-stick-side{
+      position: sticky;
+      top: 0;
+      left: 0;
+      z-index: 2;
+      //border-right: solid 1rpx #dbdbdb;
+      box-sizing: border-box;
+      background: #fafafa;
+      //box-shadow: 6px 0 6px -4px #ccc;
+    }
+  }
+  .zb-table-fixed-left .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-right .zb-table-fixed{
+    background: #fff;
+  }
+  .zb-table-fixed-header .zb-table-body-inner{
+    height: 100%;
+    // overflow: scroll;
+  }
+  .zb-table-fixed-left{
+    position: absolute;
+    top: 0;
+    z-index: 1;
+    overflow: hidden;
+    border-radius: 0;
+    height: 100%;
+    //transition: box-shadow 0.3s ease;
+  }
+  .scroll-left-fixed{
+    .zb-table-fixed-left {
+      left: 0;
+      box-shadow: 12rpx 0 12rpx -8rpx #ccc;
+    }
+  }
+  .odd{
+    background-color:rgba(249,249,249,0.6);
+    //height: 100%;
+    width: 100%;
+  }
+  .even{
+    background-color:white ;
+    //height: 100%;
+    width: 100%;
+  }
+  .zb-table-tbody {
+    .zb-stick-side{
+      position: sticky;
+      left: 0;
+      z-index: 1;
+      box-sizing: border-box;
+      background:white;
+      //box-shadow: 6px 0 6px -2px #ccc;
+    }
+    .odd{
+      background:#f9f9f9;
+      //height: 100%;
+      width: 100%;
+    }
+    .even{
+      background:white ;
+      //height: 100%;
+      width: 100%;
+    }
+  }
+  .current-row{
+    .item-td{
+      background-color: #ecf5ff;
+    }
+  }
+}
+.current-row{
+  .item-td{
+    background-color: #ecf5ff;
+  }
+}
+.zb-table-header{
+  height: 80rpx;
+}
+</style>

+ 876 - 0
mine/pages/files/addstudent.vue

@@ -0,0 +1,876 @@
+<template>
+  <view class="addbox">
+	  <uni-forms ref="form" :rules="rules" :modelValue="datainfo">
+	  		  <!-- 家长 -->
+			<view class="ftit">基本信息</view>
+			<view class="fbox">
+				<!-- 选择学生 -->
+				<picker range-key="dictLabel" v-if="roles!='parents'&&pagetype=='add'" :range="classlist"  :value="classidx"  @change="bindDateChangee">
+					<uni-forms-item name="className"  label="班级">
+						<view class="f15 flex1 txr co16" v-if="datainfo.className" >{{datainfo.className}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择班级</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+				<picker range-key="dictLabel" :disabled="pagetype=='update'||!stuflag" :range="studentlist"  :value="nameidx"  @change="bindDateChangef">
+					<uni-forms-item name="name" :disabled="pagetype=='update'||!stuflag" required  label="姓名">
+						<view class="f15 flex1 txr co16" v-if="datainfo.name" >{{datainfo.name}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择姓名</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="身份证号"  name="idCard">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.idCard" @blur="getIdcardInfo"  placeholder="请输入身份证号">
+					</uni-easyinput>
+				</uni-forms-item>
+				<!-- <uni-forms-item label="姓名" required name="name">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.name" placeholder="请输入姓名">
+					</uni-easyinput>
+				</uni-forms-item> -->
+				<picker range-key="text" :range="sexrange"  :value="sexidx"  @change="bindDateChange">
+					<uni-forms-item name="sex" required  label="性别">
+						<view class="f15 flex1 txr co16" v-if="datainfo.sex" >{{datainfo.sex==1?'男':'女'}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择性别</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="年龄"  name="age">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.age" placeholder="请输入年龄">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="民族"  name="familyName">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.familyName" placeholder="请输入民族">
+					</uni-easyinput>
+				</uni-forms-item>
+				<picker range-key="dictLabel" :range="outlook"  :value="lookidx"  @change="bindDateChangea">
+					<uni-forms-item name="politicalStatus"  label="政治面貌">
+						<view class="f15 flex1 txr" :class="datainfo.politicalStatus?'co16':'coa'">{{datainfo.politicalStatus||'请选择政治面貌'}}</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+				<picker range-key="dictLabel" :range="schoolval"  :value="schoolidx"  @change="bindDateChangeb">
+					<uni-forms-item name="school"  label="学校">
+						<view class="f15 flex1 txr" :class="datainfo.school?'co16':'coa'">{{datainfo.school||'请选择学校名称'}}</view>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="学号"  name="studentNumber">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.studentNumber" placeholder="请输入学号">
+					</uni-easyinput>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">照片信息</view>
+			<view class="fbox">
+				<uni-forms-item label="证件照"  name="identificationPhoto">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in zjfile" :key='index' @click="getPreview(zjfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('zj',index)" ></image>
+						</view>
+						<image :src="addimg" class="photos" v-if="zjfile.length<9" @click.stop="getphotoFn('zj')"></image>
+					</view>
+					
+				</uni-forms-item>
+				<uni-forms-item label="门禁照"  name="entrancePermit">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in mjfile" :key='index' @click="getPreview(mjfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('mj',index)" ></image>
+						</view>
+						<image :src="addimg" class="photos" v-if="mjfile.length<9" @click.stop="getphotoFn('mj')"></image>
+					</view>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">其他信息</view>
+			<view class="fbox">
+				<uni-forms-item label="身高"  name="height">
+					<uni-easyinput :inputBorder="false" :disabled="pagetype=='update'" v-model="datainfo.height" placeholder="请输入身高">
+					</uni-easyinput>
+					<view class="f16 co16 ml6">cm</view>
+				</uni-forms-item>
+				<uni-forms-item label="体重"  name="weight">
+					<uni-easyinput :inputBorder="false" :disabled="pagetype=='update'" v-model="datainfo.weight" placeholder="请输入体重">
+					</uni-easyinput>
+					<view class="f16 co16 ml6">kg</view>
+				</uni-forms-item>
+				<!-- <uni-forms-item label="血型"  name="bloodType">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.bloodType" placeholder="请输入血型">
+					</uni-easyinput>
+				</uni-forms-item> -->
+				<picker range-key="dictLabel" :range="bloodrange"  :value="bloodidx"  @change="bindDateChangeg">
+					<uni-forms-item name="bloodType"  label="血型">
+						<view class="f15 flex1 txr" :class="datainfo.bloodType?'co16':'coa'">{{datainfo.bloodType||'请选择血型'}}</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+			</view>
+			<view class="ftit">视力信息</view>
+			<view class="fbox">
+				<uni-forms-item label="是否近视"  name="isNearsightedness">
+					<uni-data-checkbox v-model="datainfo.isNearsightedness" :localdata="isjinshi"></uni-data-checkbox>
+				</uni-forms-item>
+				<uni-forms-item label="近视度数"  name="degreeMyopia">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.degreeMyopia" placeholder="请输入度数,例:左300 右200">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="是否远视"  name="isFarsightedness">
+					<uni-data-checkbox v-model="datainfo.isFarsightedness" :localdata="isjinshi"></uni-data-checkbox>
+				</uni-forms-item>
+				<uni-forms-item label="远视度数"  name="farsightedness">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.farsightedness" placeholder="请输入度数,例:左300 右200">
+					</uni-easyinput>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">健康信息</view>
+			<view class="fbox">
+				<picker range-key="dictLabel" :range="healthrange"  :value="healthidx"  @change="bindDateChangec">
+					<uni-forms-item name="health"   label="健康状态">
+						<view class="f15 flex1 txr co16" v-if="datainfo.health" >{{datainfo.health}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择健康状态</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="有无过往病史"  name="isMedicalHistory">
+					<uni-data-checkbox v-model="datainfo.isMedicalHistory" :localdata="ynrange"></uni-data-checkbox>
+				</uni-forms-item>
+				<uni-forms-item label="病史描述"  name="medicalDescription">
+					<view class="comboxl">
+						<textarea placeholder="请输入病史描述详情"  v-model="datainfo.medicalDescription" placeholder-style="color:#aaa;" :auto-height="autoHeight"  ></textarea>
+					</view>
+				</uni-forms-item>
+				<picker range-key="dictLabel" :disabled="pagetype=='update'" :range="xlhealthrange"  :value="mindidx"  @change="bindDateChanged">
+					<uni-forms-item name="mind"  label="心理健康状态">
+						<view :class="pagetype=='update'?'is_disabled':''" class="flexc flex1">
+							<view class="f15 flex1 txr co16"  v-if="datainfo.mind" >{{datainfo.mind}}</view>
+							<view class="f15 flex1 txr coa" :class="pagetype=='update'?'is_disabled':''"  v-else >请选择心理健康状态</view>
+							<image :src="rimg" class="ilrmgr"></image>
+						</view>
+						
+					</uni-forms-item>
+				</picker>
+				<!-- <uni-forms-item label="心理健康状态"  name="health">
+					<view class="health flexcc">
+						<view class="flexc pl8 ml2" @click="heaidx=1">
+							<image :src="mooda" v-if="heaidx==1"></image>
+							<image :src="moodan" v-else></image>
+							愉悦
+						</view>
+						<view class="flexc pl8 ml2" @click="heaidx=2">
+							<image :src="moodb" v-if="heaidx==2"></image>
+							<image :src="moodbn" v-else></image>
+							难过
+						</view>
+						<view class="flexc pl8 ml2" @click="heaidx=3">
+							<image :src="moodc" v-if="heaidx==3"></image>
+							<image :src="moodcn" v-else></image>
+							生病
+						</view>
+					</view>
+				</uni-forms-item> -->
+				<uni-forms-item label="心理健康描述"  name="psychologicalDescription">
+					<view class="comboxl" :class="pagetype=='update'?'is_disabled':''">
+						<textarea placeholder="请输入心理健康描述详情" placeholder-style="color:#aaa;"  :disabled="pagetype=='update'"  v-model="datainfo.psychologicalDescription" :auto-height="autoHeight"  ></textarea>
+					</view>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">家庭信息</view>
+			<view class="fbox">
+				<uni-forms-item label="是否贫困"  name="isPoverty">
+					<uni-data-checkbox v-model="datainfo.isPoverty" :localdata="ynrange"></uni-data-checkbox>
+				</uni-forms-item>
+				<uni-forms-item label="是否留守儿童"  name="isLset">
+					<uni-data-checkbox v-model="datainfo.isLset" :localdata="ynrange"></uni-data-checkbox>
+				</uni-forms-item>
+				<uni-forms-item label="居住地址"  name="address" >
+					<view @click="getMapFn" class="flexc flex1">
+						<view class="flex1 f15 txr" :class="datainfo.address?'co16':'coa'">{{datainfo.address||'请选择居住地址'}}</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</view>
+				</uni-forms-item>
+				<!--  -->
+				<uni-forms-item label="父亲姓名"  name="fatherName">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.fatherName" placeholder="请输入父亲姓名">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="联系方式"  name="fatherTelephone">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.fatherTelephone" placeholder="请输入联系方式">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="母亲姓名"  name="motherName">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.motherName" placeholder="请输入母亲姓名">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="联系方式"  name="motherTelephone">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.motherTelephone" placeholder="请输入联系方式">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="紧急联系人"  name="emergencyContact">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.emergencyContact" placeholder="请输入紧急联系人姓名">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="紧急联系方式"  name="emergencyContactTelephone">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.emergencyContactTelephone" placeholder="请输入紧急联系方式">
+					</uni-easyinput>
+				</uni-forms-item>
+			</view>
+			<view class="fbtns">
+				<view class="rebtn" @click="getSubmit">确认</view>
+			</view>
+			
+	  </uni-forms>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	import {uploadmore,selectDictLabel} from '@/utils/common.js'
+	import {getDeptList,getselfList} from "@/api/mine/mine.js"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {getstuDetFn,getstuAddtFn,getstunoListFn,getstuPutFn} from "@/api/mine/files.js"
+  export default {
+	components:{},
+	data(){
+		return{
+			// adddj
+			addimg:require("@/mine/static/score/addd.png"),
+			mooda:require("@/mine/static/score/mooda.png"),
+			moodan:require("@/mine/static/score/moodan.png"),
+			moodb:require("@/mine/static/score/moodb.png"),
+			moodbn:require("@/mine/static/score/moodbn.png"),
+			moodc:require("@/mine/static/score/moodc.png"),
+			moodcn:require("@/mine/static/score/moodcn.png"),
+			delimg: require("@/static/images/del.png"),
+			rimg:require("@/mine/static/score/rimg.png"),
+			heaidx:1,
+			date:'',
+			baseUrl:'',
+			sexrange:[{"val": 1,"text":"男"},{"val":2,"text":"女"}],// 性别
+			ynrange:[{"value": 1,"text": "是"},{"value": 2,"text": "否"}],
+			zjfile:[],
+			mjfile:[],
+			autoHeight:true,
+			bjrange: [{"value": 1,"text": "有"	},{"value": 2,"text": "无"}],
+			rules: {
+			  name: {rules: [{required: true,errorMessage: '请选择姓名'}]},
+			  sex: {rules: [{required: true,errorMessage: '请选择性别'}]},
+			  // subjectClass: {rules: [{required: true,errorMessage: '请选择调课班级'}]},
+			  // subject: {rules: [{required: true,errorMessage: '请选择调课科目'}]},
+			  // beSubject: {rules: [{required: true,errorMessage: '请选择被调科目'}]},
+			  // week: {rules: [{required: true,errorMessage: '请选择时间(星期)'}]},
+			},
+			datainfo:{
+				 "studentId":"",//学生id
+				  "name":"",//姓名
+				  "sex":"",//性别(1:男,2:女)
+				  "age":"",//年龄
+				  "familyName":"",//民族
+				  "school":"",//学校(汉字)
+				  "studentNumber":"",//学号
+				  "idCard":"",//身份证号
+				  "height":"",//身高
+				  "weight":"",//体重
+				  "bloodType":"",//血型
+				  "politicalStatus":"",//政治面貌(字典值:political_outlook)
+				  "identificationPhoto":"",//证件照(地址)
+				  "entrancePermit":"",//门禁照(地址)
+				  "fatherName":"",//父亲
+				  "fatherTelephone":"",//父亲联系方式
+				  "motherName":"",//母亲
+				  "motherTelephone":"",//母亲联系方式
+				  "emergencyContact":"",//紧急
+				  "emergencyContactTelephone":"",//紧急联系方式
+				  "address":"",//居住地址
+				  "isNearsightedness":'',//近视,
+				  "psychologicalDescription":'',
+				  "isFarsightedness":'',//远视,
+				  "farsightedness":'',
+				  'health':'',
+				  "mind":'',
+				  "isMedicalHistory":'',
+				  "medicalDescription":'',
+				  "classId":'',
+				  "className":''
+				  
+			},
+			pagetype:'add',
+			stulist:'',
+			schoolval:[],
+			outlook:[],
+			isjinshi:[],
+			healthrange:[],
+			xlhealthrange:[],
+			bloodrange:[],
+			bloodidx:0,
+			sexidx:0,
+			lookidx:0,
+			schoolidx:0,
+			healthidx:0,
+			mindidx:0,
+			id:'',
+			address:{},
+			classlist:[],//班级
+			roles:'',
+			classidx:0,
+			nameidx:0,
+			studentlist:[],
+			schoolId:'',
+			stuflag:true
+		}
+	},
+	onUnload(){
+		uni.$off('refreshaddr')
+	},
+	onLoad: function(e) {
+		var that=this;
+		uni.$on('refreshaddr',(e) => {
+			var addr=JSON.parse(JSON.stringify(e))
+			this.datainfo.address=e.address
+			this.datainfo.longitude=e.lng
+			this.datainfo.latitude=e.lat
+		})
+		this.pagetype=e.type||'add';
+		this.baseUrl=baseUrl;
+		this.init()
+		this.getDeptListFn()
+		if(e.type=='update'){
+			this.id=e.id
+			this.getDataFn()
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			this.roles=roles;
+			if(roles=='parents'){
+				var newArr=this.$store.state.user.student;
+				if(newArr&&newArr.length){
+					if(newArr.length>1){
+						this.studentlist = newArr.map(v => {
+							return {
+								dictLabel:v.studentName,
+								dictValue: v.id,
+								classId:v.classId,
+								className:v.className
+							}
+						})
+					}else{
+						// 一个娃
+						this.datainfo.name=newArr[0].studentName
+						this.datainfo.studentId=newArr[0].id
+						this.datainfo.classId=newArr[0].classId
+						this.datainfo.className=newArr[0].className
+						this.stuflag=false;
+					}
+				}
+			}else if(roles=='teacher'){
+				var id=this.$store.state.user.schoolId;
+				this.schoolId=id;
+				this.getselfList(id)
+			}else{
+				this.schoolId=this.$store.state.user.deptId;
+				this.getselfList(0)
+			}
+		}
+	},
+	methods:{
+		getselfList(id){
+			var params={
+				parentId:id,
+			}
+			params['params[role]']=this.$store.state.user.choseroles
+			getselfList(params).then(res=>{
+				if(res.code==200){
+					var newArr=res.data;
+					if(newArr&&newArr.length){
+						this.classlist = newArr.map(v => {
+							return {
+								dictLabel: v.deptName,
+								dictValue: v.deptId,
+							}
+						})
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getMapFn(){
+			// #ifdef APP-PLUS
+			if(this.datainfo.address){
+				this.$tab.navigateTo('/mine/pages/files/maps?type=update&lng='+this.datainfo.longitude+'&lat='+this.datainfo.latitude+'&address='+this.datainfo.address)
+			}else{
+				this.$tab.navigateTo('/mine/pages/files/maps')
+			}
+			// #endif
+			// #ifndef APP-PLUS
+			if(this.datainfo.address){
+				this.$tab.navigateTo('/mine/pages/files/map?type=update&lng='+this.datainfo.longitude+'&lat='+this.datainfo.latitude+'&address='+this.datainfo.address)
+			}else{
+				this.$tab.navigateTo('/mine/pages/files/map')
+			}
+			
+			// #endif
+		},
+		getDataFn() {
+			getstuDetFn(this.id).then(res => {
+				if (res.code == 200) {
+					this.datainfo = res.data;
+					if(res.data.isNearsightedness){
+						this.datainfo.isNearsightedness=Number(res.data.isNearsightedness)
+					}
+					if(res.data.isLset){
+						this.datainfo.isLset=Number(res.data.isLset)
+					}
+					if(res.data.isPoverty){
+						this.datainfo.isPoverty=Number(res.data.isPoverty)
+					}
+					if(res.data.isMedicalHistory){
+						this.datainfo.isMedicalHistory=Number(res.data.isMedicalHistory)
+					}
+					if(res.data.identificationPhoto){
+						this.zjfile=res.data.identificationPhoto.split(',')
+					}else{
+						this.zjfile=[];
+					}
+					if(res.data.entrancePermit){
+						this.mjfile=res.data.entrancePermit.split(',')
+					}else{
+						this.mjfile=[];
+					}
+					if(res.data.sex){
+						this.sexidx=res.data.sex==1?0:1
+					}
+					// 政治面貌
+					if(res.data.politicalStatus){
+						for(var i=0;i<this.outlook.length;i++){
+							if(this.outlook[i].dictLabel==res.data.politicalStatus){
+								this.lookidx=Number(i)
+								break;
+							}
+						}
+					}
+					if(res.data.school){
+						for(var i=0;i<this.schoolval.length;i++){
+							if(this.schoolval[i].dictLabel==res.data.school){
+								this.schoolidx=Number(i)
+								break;
+							}
+						}
+					}
+					if(res.data.health){
+						for(var i=0;i<this.healthrange.length;i++){
+							if(this.healthrange[i].dictLabel==res.data.health){
+								this.healthidx=Number(i)
+								break;
+							}
+						}
+					}
+					if(res.data.mind){
+						for(var i=0;i<this.xlhealthrange.length;i++){
+							if(this.xlhealthrange[i].dictLabel==res.data.mind){
+								this.mindidx=Number(i)
+								break;
+							}
+						}
+					}
+					
+					
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		go(idCard) {
+			let sex = null;
+			let birth = null;
+			let myDate = new Date();
+			let month = myDate.getMonth() + 1;
+			let day = myDate.getDate();
+			let age = 0;
+							
+			if (idCard.length === 18) {
+			  age = myDate.getFullYear() - idCard.substring(6, 10) - 1;
+			  sex = idCard.substring(16, 17);
+			  birth = idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14);
+			  if (idCard.substring(10, 12) < month || idCard.substring(10, 12) === month && idCard.substring(12, 14) <= day)
+			    age++;
+							
+			}
+			if (idCard.length === 15) {
+			  age = myDate.getFullYear() - idCard.substring(6, 8) - 1901;
+			  sex = idCard.substring(13, 14);
+			  birth = "19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12);
+			  if (idCard.substring(8, 10) < month || idCard.substring(8, 10) === month && idCard.substring(10, 12) <= day)
+			    age++;
+			}			
+			if (sex % 2 === 0) sex = '2';
+			else sex = '1';
+			this.datainfo.sex = sex
+			this.datainfo.age = age
+			return {
+			  age,
+			  sex,
+			  birth
+			}
+		},
+		/* 上传后端获取身份证信息 */
+		getIdcardInfo(val) {
+			var idCard=this.datainfo.idCard;
+			if(!idCard){
+				return
+			}
+			// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
+			let _IDRe18 =/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+			let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+			// 校验身份证:
+			if (_IDRe18.test(idCard) || _IDre15.test(idCard)) {
+				this.go(idCard)		
+			} else {
+						
+			}
+		},
+		getClassFn(){
+			var that=this;
+			var roles=that.$store.state.user.choseroles;
+			that.roles=roles;
+			if(roles=='parents'){
+				this.$store.dispatch('GetInforoles').then(resd => {
+					if(resd.code==200){
+						var res=resd.data;
+						if(res.user&&res.user.parentsStudent&&res.user.parentsStudent.length){
+							that.stulist = res.user.parentsStudent
+						}
+					}
+				})
+			}
+		},
+		init(){
+			// 政治面貌
+			getDictionaryFn('political_outlook').then(res=>{
+				if(res.code==200){
+					this.outlook = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+			//近视
+			getDictionaryFn('isjinshi').then(res=>{
+				if(res.code==200){
+					this.isjinshi = res.data.map(v => {
+						return {
+							text: v.dictLabel,
+							value: v.dictValue
+						}
+					})
+				}
+			})
+			//健康状态 
+			getDictionaryFn('health_status').then(res=>{
+				if(res.code==200){
+					this.healthrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue:v.dictValue
+						}
+					})
+				}
+			})
+			//心理健康状态
+			getDictionaryFn('psychology').then(res=>{
+				if(res.code==200){
+					this.xlhealthrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+			// 血型
+			getDictionaryFn('blood_type').then(res=>{
+				if(res.code==200){
+					this.bloodrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		// 学校列表
+		getDeptListFn(){
+			var params={
+				parentId:0
+			}
+			getDeptList(0).then(res=>{
+				if(res.code==200){
+					this.schoolval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue:v.deptId
+						}
+					})
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getstunoListFn(){
+			var params={
+				classId:this.datainfo.classId
+			}
+			params['params[role]']=this.$store.state.user.choseroles
+			getstunoListFn(params).then(res=>{
+				if(res.code==200){
+					this.studentlist = res.rows.map(v => {
+						return {
+							dictLabel: v.studentName,
+							dictValue: v.id,
+							classId:v.classId
+						}
+					})
+				}
+			})
+		},
+		getSubmit(){
+			var that = this;
+			this.$refs.form.validate().then(res => {
+				var params = JSON.parse(JSON.stringify(this.datainfo))
+				if (this.pagetype == 'add') {
+					if(params.idCard){
+						let _IDRe18 =
+							/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+						let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+						// 校验身份证:
+						if (_IDRe18.test(params.idCard) || _IDre15.test(params.idCard)) {
+						}else{
+							this.$toast('请输入正确身份证号')
+							return
+						}
+					}
+					// 验证手机号
+					let regphone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
+					if(params.fatherTelephone&&!regphone.test(params.fatherTelephone)){
+						this.$toast('请输入正确的父亲联系方式')
+						return
+					}
+					if(params.motherTelephone&&!regphone.test(params.motherTelephone)){
+						this.$toast('请输入正确的母亲联系方式')
+						return
+					}
+					if(params.emergencyContactTelephone&&!regphone.test(params.emergencyContactTelephone)){
+						this.$toast('请输入正确的紧急联系方式')
+						return
+					}
+					getstuAddtFn(params).then(res => {
+						if (res.code == 200) {
+							that.$toast('新增成功')
+							setTimeout(function() {
+								uni.$emit('refreshdalist');
+								uni.navigateBack({
+									delta:1
+								})
+							}, 1500)
+						} else {
+							this.$toast(res.msg)
+						}
+					})
+				} else {
+					if(params.idCard){
+						let _IDRe18 =
+							/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+						let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+						// 校验身份证:
+						if (_IDRe18.test(params.idCard) || _IDre15.test(params.idCard)) {
+						}else{
+							this.$toast('请输入正确身份证号')
+							return
+						}
+					}
+					// 验证手机号
+					let regphone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
+					if(params.fatherTelephone&&!regphone.test(params.fatherTelephone)){
+						this.$toast('请输入正确的父亲联系方式')
+						return
+					}
+					if(params.motherTelephone&&!regphone.test(params.motherTelephone)){
+						this.$toast('请输入正确的母亲联系方式')
+						return
+					}
+					getstuPutFn(params).then(res => {
+						if (res.code == 200) {
+							that.$toast('修改成功')
+							setTimeout(function() {
+								uni.$emit('refreshdadetail');
+								uni.$emit('refreshdalist');
+								uni.navigateBack({
+									delta:1
+								})
+							}, 1500)
+						} else {
+							this.$toast(res.msg)
+						}
+					})
+				}
+			})
+		},
+		bindDateChange(e){
+			var idx=e.detail.value
+			this.datainfo.sex=this.sexrange[idx].val
+		},
+		bindDateChangea(e){
+			var idx=e.detail.value
+			this.datainfo.politicalStatus=this.outlook[idx].dictLabel
+		},
+		bindDateChangeb(e){
+			var idx=e.detail.value
+			this.datainfo.school=this.schoolval[idx].dictLabel
+		},
+		bindDateChangec(e){
+			var idx=e.detail.value
+			this.datainfo.health=this.healthrange[idx].dictLabel
+		},
+		bindDateChanged(e){
+			var idx=e.detail.value
+			this.datainfo.mind=this.xlhealthrange[idx].dictLabel
+		},
+		bindDateChangee(e){
+			var idx=e.detail.value
+			this.datainfo.className=this.classlist[idx].dictLabel;
+			this.datainfo.classId=this.classlist[idx].dictValue;
+			this.datainfo.name='';
+			this.datainfo.studentId='';
+			this.getstunoListFn()
+		},
+		bindDateChangef(e){
+			var idx=e.detail.value
+			this.datainfo.name=this.studentlist[idx].dictLabel
+			this.datainfo.studentId=this.studentlist[idx].dictValue
+		},
+		bindDateChangeg(e){
+			var idx=e.detail.value
+			this.datainfo.bloodType=this.bloodrange[idx].dictLabel
+			// this.datainfo.studentId=this.studentlist[idx].dictValue
+		},
+		// 查看照片
+		getPreview(iurl,idx) {
+			var newArr=[];
+			iurl.forEach(ite=>{
+				var ds=this.baseUrl+ite
+				newArr.push(ds)
+			})
+			uni.previewImage({
+				urls: newArr,
+				current:idx,
+				success: function(data) {
+					
+				},
+				fail: function(err) {
+					console.log(err.errMsg);
+				}
+			});
+		},
+		delimgFn(e,idx){
+			var that = this;
+			if(e=='zj'){
+				that.zjfile.splice(idx,1);
+				this.datainfo.identificationPhoto=that.zjfile.join(',')
+			}else{
+				that.mjfile.splice(idx,1);
+				this.datainfo.entrancePermit=that.mjfile.join(',')
+			}
+			
+		},
+		getphotoFn(e){
+			let that = this;
+			let file =[],count=9
+			if(e=='zj'){
+				file = that.zjfile;
+				count=9
+			}else{
+				file = that.mjfile;
+				count=9
+			}
+			if(file.length < count){
+				uni.chooseImage({
+					count: count - parseInt(file.length),
+					success:function(res){
+						let img= res.tempFilePaths;
+						if(img.length + file.length > count){
+							uni.showToast({
+								title: '最多上传'+count+'张图片',
+								icon: 'none',
+								duration: 2000
+							})
+						}else{
+							let imglen = res.tempFilePaths.length;
+							var fuwufile = [];
+							uploadmore('/common/upload',img,0,0,0,imglen,fuwufile,function(rs){
+								if(e=='zj'){
+									that.zjfile = that.zjfile.concat(rs);
+									that.datainfo.identificationPhoto=that.zjfile.join(',')
+								}else{
+									that.mjfile = that.mjfile.concat(rs);
+									that.datainfo.entrancePermit=that.mjfile.join(',')
+								}
+								// console.log(that.datainfo.image,85)
+							})	
+						}
+					}
+				});
+			}
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.addbox{padding: 24rpx 36rpx 180rpx;}
+.ftit{font-size: 30rpx;font-weight: 500;color: #666666;padding: 8rpx;margin-bottom: 16rpx;}
+.fbox{background: #FFFFFF;border-radius: 18rpx;padding: 12rpx 0;margin-bottom: 32rpx;
+	.addimg{width: 120rpx;height: 120rpx;}
+}
+.ilrmgr{width: 14rpx;height: 24rpx;margin-left: 20rpx;flex: 0 0 auto;}
+.addbtn{height: 98rpx;width: 100%;
+background: #1f57e6;
+border-radius: 48rpx;display: flex;align-items: center;justify-content: center;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;}
+.comboxl{min-height: 70rpx;padding:15rpx 0rpx;box-sizing: border-box;line-height: 40rpx;flex: 1;
+		textarea{width: 100%;font-size: 30rpx;color: #161616;text-align: right;}
+	}
+.imgs{display: flex;align-items: center;flex-wrap: wrap;justify-content: flex-end;
+	.photos{width: 120rpx;height: 120rpx;position: relative;margin: 0 0rpx 16rpx 16rpx;
+	// &:nth-child(3n){margin-left: 0;}
+	.rimg{width: 100%;height: 100%;}
+	.del{width: 36rpx;height: 36rpx;position: absolute;right: 0rpx;top: 0rpx;}
+	}
+}
+.is_disabled{background-color: #f7f6f6;min-height:70rpx;display: flex;align-items: center;justify-content: flex-end;color: #d5d5d5;
+	textarea{color: #d5d5d5;}
+}
+// 心理
+.health{display: flex;align-items: center;justify-content: flex-end;flex-wrap: wrap;flex: 1;
+	image{width: 36rpx;height: 36rpx;margin-right: 12rpx;font-size: 32rpx;color: #161616;flex:0 0 auto;}
+}
+
+.addbox /deep/ .uni-forms{flex: 1;}
+.addbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 30rpx;font-weight: bold;
+color: #161616;}
+.addbox /deep/ .uni-forms .uni-forms-item{margin-bottom: 0;padding: 4rpx 32rpx;
+	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+}
+.addbox /deep/  .uni-easyinput{height: 70rpx;}
+// .addbox /deep/  .uni-textarea-textarea{height: auto;}
+.addbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.addbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.addbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.addbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .addbox /deep/ .uni-forms-item__error{margin-top:-12rpx;left: auto;right: 0;}
+ .addbox /deep/ .uni-data-checklist .checklist-group .checklist-box{margin-right: 30rpx;}
+  .addbox /deep/ .uni-data-checklist .checklist-group{justify-content: flex-end;}
+</style>

+ 702 - 0
mine/pages/files/addteacher.vue

@@ -0,0 +1,702 @@
+<template>
+  <view class="addbox">
+	  <uni-forms ref="form" :rules="rules" :modelValue="datainfo">
+	  		  <!-- 家长 -->
+			<view class="ftit">基本信息</view>
+			<view class="fbox">
+				<picker range-key="dictLabel" v-if="roles!='teacher'&&pagetype=='add'" :range="classlist"  :value="classidx"  @change="bindDateChangeb">
+					<uni-forms-item name="className"  label="班级">
+						<view class="f15 flex1 txr co16" v-if="datainfo.className" >{{datainfo.className}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择班级</view>
+					</uni-forms-item>
+				</picker>
+				<picker range-key="dictLabel" :disabled="pagetype=='update'||!teaflag" :range="teacherlist"  :value="nameidx"  @change="bindDateChangef">
+					<uni-forms-item name="name" :disabled="pagetype=='update'||!teaflag" required  label="老师">
+						<view class="f15 flex1 txr co16" v-if="datainfo.name" >{{datainfo.name}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择老师</view>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="身份证号"  name="idCard">
+					<uni-easyinput :inputBorder="false" @blur="getIdcardInfo" v-model="datainfo.idCard" placeholder="请输入身份证号">
+					</uni-easyinput>
+				</uni-forms-item>
+				<!-- <uni-forms-item label="姓名"  name="name">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.name" placeholder="请输入姓名">
+					</uni-easyinput>
+				</uni-forms-item> -->
+				<picker range-key="text" :range="sexrange"  :value="sexidx"  @change="bindDateChange">
+					<uni-forms-item name="sex" required  label="性别">
+						<view class="f15 flex1 txr co16" v-if="datainfo.sex" >{{datainfo.sex==1?'男':'女'}}</view>
+						<view class="f15 flex1 txr coa" v-else >请选择性别</view>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="年龄"  name="age">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.age" placeholder="请输入年龄">
+					</uni-easyinput>
+				</uni-forms-item>
+				<picker range-key="dictLabel" :range="outlook"  :value="lookidx"  @change="bindDateChangea">
+					<uni-forms-item name="politicalStatus"  label="政治面貌">
+						<view class="f15 flex1 txr" :class="datainfo.politicalStatus?'co16':'coa'">{{datainfo.politicalStatus||'请选择政治面貌'}}</view>
+					</uni-forms-item>
+				</picker>
+				
+				<picker range-key="dictLabel" :range="zctitle"  :value="zcidx"  @change="bindDateChangec">
+					<uni-forms-item name="professional"  label="职称">
+						<view class="f15 flex1 txr" :class="datainfo.professional?'co16':'coa'">{{datainfo.professional||'请选择职称'}}</view>
+					</uni-forms-item>
+				</picker>
+				<uni-forms-item label="联系方式"  name="phone">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.phone" placeholder="请输入联系方式">
+					</uni-easyinput>
+				</uni-forms-item>
+				<uni-forms-item label="居住地址"  name="phone">
+					<view @click="getMapFn" class="flexc flex1">
+						<view class="flex1 f15 txr" :class="datainfo.address?'co16':'coa'">{{datainfo.address||'请选择居住地址'}}</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</view>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">职业信息</view>
+			<view class="fbox">
+				<!-- <uni-forms-item label="教龄"  name="height">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.height" placeholder="请输入教龄	">
+					</uni-easyinput>
+					<view class="f16 co16 ml6">年</view>
+				</uni-forms-item> -->
+				<picker  mode="date"  @change="bindDateChanged">
+					<uni-forms-item name="onBoardTime"  label="入职时间">
+						<view class="f15 flex1 txr" :class="datainfo.onBoardTime?'co16':'coa'">{{datainfo.onBoardTime||'请选择入职时间'}}</view>
+					</uni-forms-item>
+				</picker>
+				<picker  mode="date"  @change="bindDateChangee">
+					<uni-forms-item name="jobTime" required  label="参加工作时间">
+						<view class="f15 flex1 txr" :class="datainfo.jobTime?'co16':'coa'">{{datainfo.jobTime||'请选择参加工作时间'}}</view>
+					</uni-forms-item>
+				</picker>
+			</view>
+			<view class="ftit">照片信息</view>
+			<view class="fbox">
+				<uni-forms-item label="证件照"  name="identificationPhoto">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in zjfile" :key='index' @click="getPreview(zjfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('zj',index)" ></image>
+						</view>
+						<image :src="addimg" class="photos" v-if="zjfile.length<9" @click.stop="getphotoFn('zj')"></image>
+					</view>
+					
+				</uni-forms-item>
+				<uni-forms-item label="门禁照"  name="entrancePermit">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in mjfile" :key='index' @click="getPreview(mjfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('mj',index)" ></image>
+						</view>
+						<image :src="addimg" class="photos" v-if="mjfile.length<9" @click.stop="getphotoFn('mj')"></image>
+					</view>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">资质信息</view>
+			<view class="fbox">
+				<uni-forms-item label="毕业证明照"  name="identificationPhoto">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in byzmfile" :key='index' @click="getPreview(byzmfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('byzm',index)" ></image>
+						</view>
+						<image :src="addsimg" class="photos" v-if="byzmfile.length<9" @click.stop="getphotoFn('byzm')"></image>
+					</view>
+					
+				</uni-forms-item>
+				<uni-forms-item label="毕业证书照"  name="entrancePermit">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in byzsfile" :key='index' @click="getPreview(byzsfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('byzs',index)" ></image>
+						</view>
+						<image :src="addsimg" class="photos" v-if="byzsfile.length<9" @click.stop="getphotoFn('byzs')"></image>
+					</view>
+				</uni-forms-item>
+				<uni-forms-item label="教资证明照"  name="entrancePermit">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in jzzmfile" :key='index' @click="getPreview(jzzmfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('jzzm',index)" ></image>
+						</view>
+						<image :src="addsimg" class="photos" v-if="jzzmfile.length<9" @click.stop="getphotoFn('jzzm')"></image>
+					</view>
+				</uni-forms-item>
+				<uni-forms-item label="职称证明照"  name="entrancePermit">
+					<view class="flex1"></view>
+					<view class="imgs">
+						<view class="photos" v-for="(item,index) in zczmfile" :key='index' @click="getPreview(zczmfile,index)">
+							<image :src="baseUrl+item" class="addimg"></image>
+							<image :src="delimg" class="del" @click.stop="delimgFn('zczm',index)" ></image>
+						</view>
+						<image :src="addsimg" class="photos" v-if="zczmfile.length<9" @click.stop="getphotoFn('zczm')"></image>
+					</view>
+				</uni-forms-item>
+			</view>
+			<view class="ftit">其他信息</view>
+			<view class="fbox">
+				<uni-forms-item label="身高"  name="height">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.height" placeholder="请输入身高">
+					</uni-easyinput>
+					<view class="f16 co16 ml6">cm</view>
+				</uni-forms-item>
+				<uni-forms-item label="体重"  name="weight">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.weight" placeholder="请输入体重">
+					</uni-easyinput>
+					<view class="f16 co16 ml6">kg</view>
+				</uni-forms-item>
+				<picker range-key="dictLabel" :range="bloodrange"  :value="bloodidx"  @change="bindDateChangeg">
+					<uni-forms-item name="bloodType"  label="血型">
+						<view class="f15 flex1 txr" :class="datainfo.bloodType?'co16':'coa'">{{datainfo.bloodType||'请选择血型'}}</view>
+						<image :src="rimg" class="ilrmgr"></image>
+					</uni-forms-item>
+				</picker>
+				<!-- <uni-forms-item label="血型"  name="bloodType">
+					<uni-easyinput :inputBorder="false" v-model="datainfo.bloodType" placeholder="请输入血型">
+					</uni-easyinput>
+				</uni-forms-item> -->
+			</view>
+			<view class="fbtns">
+				<view class="rebtn" @click="getSubmit">确认</view>
+			</view>
+			
+	  </uni-forms>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	import {uploadmore,selectDictLabel} from '@/utils/common.js'
+	import {getDeptList} from "@/api/mine/mine.js"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {getteaDetFn,getteaAddtFn,getteaPutFn,getteanoListFn} from "@/api/mine/files.js"
+  export default {
+	components:{},
+	data(){
+		return{
+			// adddj
+			addimg:require("@/mine/static/score/addd.png"),
+			addsimg:require("@/mine/static/score/adddj.png"),
+			delimg: require("@/static/images/del.png"),
+			rimg:require("@/mine/static/score/rimg.png"),
+			date:'',
+			baseUrl:'',
+			sexrange:[{"val": 1,"text":"男"},{"val":2,"text":"女"}],// 性别
+			zjfile:[],
+			mjfile:[],
+			byzmfile:[],
+			byzsfile:[],
+			jzzmfile:[],
+			zczmfile:[],
+			autoHeight:true,
+			
+			rules: {
+			  name: {rules: [{required: true,errorMessage: '请选择老师'}]},
+			  sex: {rules: [{required: true,errorMessage: '请选择性别'}]},
+			  jobTime: {rules: [{required: true,errorMessage: '请选择参加工作时间'}]},
+			  // subject: {rules: [{required: true,errorMessage: '请选择调课科目'}]},
+			  // beSubject: {rules: [{required: true,errorMessage: '请选择被调科目'}]},
+			  // week: {rules: [{required: true,errorMessage: '请选择时间(星期)'}]},
+			},
+			datainfo:{
+				"teacherId":"",//学生id
+				"name":"",//姓名
+				"sex":"",//性别(1:男,2:女)
+				"age":"",//年龄
+				"school":"",//学校(汉字)
+				"studentNumber":"",//学号
+				"idCard":"",//身份证号
+				"height":"",//身高
+				"weight":"",//体重
+				"bloodType":"",//血型
+				"politicalStatus":"",//政治面貌(字典值:political_outlook)
+				"identificationPhoto":"",//证件照(地址)
+				"entrancePermit":"",//门禁照(地址)
+				"graduationPhoto":"",//毕业证明照(地址)
+				"degreePhoto":"",//学位证书照(地址)
+				"teachingPhoto":"",//教资证明照(地址)
+				"professionalPhoto":"",//职称证明照(地址)
+				"address":"",
+				'onBoardTime':'',//入职时间
+				'jobTime':'',//入职时间
+				'professional':'',//职称
+				"classId":'',
+				"className":''
+			},
+			pagetype:'add',
+			stulist:'',
+			schoolval:[],
+			outlook:[],
+			zctitle:[],
+			bloodrange:[],
+			zcidx:0,
+			bloodidx:0,
+			sexidx:0,
+			lookidx:0,
+			schoolidx:0,
+			classidx:0,
+			nameidx:0,
+			id:'',
+			schoolId:'',
+			classlist:[],
+			teacherlist:[],
+			teaflag:true,
+			roles:''
+		}
+	},
+	onLoad: function(e) {
+		uni.$on('refreshaddr',(e) => {
+			var addr=JSON.parse(JSON.stringify(e))
+			this.datainfo.address=e.address
+			this.datainfo.longitude=e.lng
+			this.datainfo.latitude=e.lat
+		})
+		this.pagetype=e.type||'add';
+		this.baseUrl=baseUrl;
+		this.init()
+		if(e.type=='update'){
+			this.id=e.id
+			this.getDataFn()
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			this.roles=roles;
+			if(roles=='parents'){
+			}else if(roles=='teacher'){
+				// 老师
+				this.datainfo.teacherId=this.$store.state.user.userId
+				this.datainfo.name=this.$store.state.user.name
+				this.datainfo.phone=this.$store.state.user.phonenumber
+				this.teaflag=false
+			}else{
+				this.schoolId=this.$store.state.user.deptId;
+				this.getclassListFn()
+			}
+		}
+	},
+	methods:{
+		getclassListFn(){
+			//  获取学校id
+			var id=this.schoolId;
+			getDeptList(id).then(res=>{
+				if(res.code==200){
+					var newArr=res.data;
+					if(newArr&&newArr.length){
+						this.classlist = newArr.map(v => {
+							return {
+								dictLabel: v.deptName,
+								dictValue: v.deptId,
+							}
+						})
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getteanoListFn(){
+			var params={
+				classId:this.datainfo.classId
+			}
+			params['params[role]']=this.$store.state.user.choseroles
+			getteanoListFn(params).then(res=>{
+				if(res.code==200){
+					this.teacherlist = res.rows.map(v => {
+						return {
+							dictLabel: v.teacherName,
+							dictValue: Number(v.teacherId),
+							classId:v.classId
+						}
+					})
+				}
+			})
+		},
+		go(idCard) {
+			let sex = null;
+			let birth = null;
+			let myDate = new Date();
+			let month = myDate.getMonth() + 1;
+			let day = myDate.getDate();
+			let age = 0;
+							
+			if (idCard.length === 18) {
+			  age = myDate.getFullYear() - idCard.substring(6, 10) - 1;
+			  sex = idCard.substring(16, 17);
+			  birth = idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14);
+			  if (idCard.substring(10, 12) < month || idCard.substring(10, 12) === month && idCard.substring(12, 14) <= day)
+			    age++;
+							
+			}
+			if (idCard.length === 15) {
+			  age = myDate.getFullYear() - idCard.substring(6, 8) - 1901;
+			  sex = idCard.substring(13, 14);
+			  birth = "19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12);
+			  if (idCard.substring(8, 10) < month || idCard.substring(8, 10) === month && idCard.substring(10, 12) <= day)
+			    age++;
+			}			
+			if (sex % 2 === 0) sex = '2';
+			else sex = '1';
+			this.datainfo.sex = sex
+			this.datainfo.age = age
+			return {
+			  age,
+			  sex,
+			  birth
+			}
+		},
+		/* 上传后端获取身份证信息 */
+		getIdcardInfo(val) {
+			var idCard=this.datainfo.idCard;
+			if(!idCard){
+				return
+			}
+			// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
+			let _IDRe18 =/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+			let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+			// 校验身份证:
+			if (_IDRe18.test(idCard) || _IDre15.test(idCard)) {
+				this.go(idCard)		
+			} else {
+						
+			}
+		},
+		getMapFn(){
+			// #ifdef APP-PLUS
+			this.$tab.navigateTo('/mine/pages/files/maps')
+			// #endif
+			// #ifndef APP-PLUS
+			this.$tab.navigateTo('/mine/pages/files/map')
+			// #endif
+		},
+		getDataFn() {
+			getteaDetFn(this.id).then(res => {
+				if (res.code == 200) {
+					this.datainfo = res.data;
+					if(res.data.identificationPhoto){
+						this.zjfile=res.data.identificationPhoto.split(',')
+					}else{
+						this.zjfile=[];
+					}
+					if(res.data.entrancePermit){
+						this.mjfile=res.data.entrancePermit.split(',')
+					}else{
+						this.mjfile=[];
+					}
+					if(res.data.graduationPhoto){
+						this.byzmfile=res.data.graduationPhoto.split(',')
+					}else{
+						this.byzmfile=[];
+					}
+					if(res.data.degreePhoto){
+						this.byzsfile=res.data.degreePhoto.split(',')
+					}else{
+						this.byzsfile=[];
+					}
+					if(res.data.teachingPhoto){
+						this.jzzmfile=res.data.teachingPhoto.split(',')
+					}else{
+						this.jzzmfile=[];
+					}
+					if(res.data.professionalPhoto){
+						this.zczmfile=res.data.professionalPhoto.split(',')
+					}else{
+						this.zczmfile=[];
+					}
+					if(res.data.sex){
+						this.sexidx=res.data.sex==1?0:1
+					}
+					this.datainfo.rzsh='123'
+					// 政治面貌
+					if(res.data.politicalStatus){
+						for(var i=0;i<this.outlook.length;i++){
+							if(this.outlook[i].dictLabel==res.data.politicalStatus){
+								this.lookidx=Number(i)
+								break;
+							}
+						}
+					}
+					// 职称
+					if(res.data.professional){
+						for(var i=0;i<this.zctitle.length;i++){
+							if(this.zctitle[i].dictLabel==res.data.professional){
+								this.zcidx=Number(i)
+								break;
+							}
+						}
+					}
+					// if(res.data.school){
+					// 	for(var i=0;i<this.schoolval.length;i++){
+					// 		if(this.schoolval[i].dictLabel==res.data.school){
+					// 			this.schoolidx=Number(i)
+					// 			break;
+					// 		}
+					// 	}
+					// }
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		init(){
+			// 政治面貌
+			getDictionaryFn('political_outlook').then(res=>{
+				if(res.code==200){
+					this.outlook = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+			// 职称
+			getDictionaryFn('title').then(res=>{
+				if(res.code==200){
+					this.zctitle = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+			// 血型
+			getDictionaryFn('blood_type').then(res=>{
+				if(res.code==200){
+					this.bloodrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		getSubmit(){
+			var that = this;
+			this.$refs.form.validate().then(res => {
+				var params = JSON.parse(JSON.stringify(this.datainfo))
+				if (this.pagetype == 'add') {
+					if(params.idCard){
+						let _IDRe18 =
+							/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+						let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+						// 校验身份证:
+						if (_IDRe18.test(params.idCard) || _IDre15.test(params.idCard)) {
+						}else{
+							this.$toast('请输入正确身份证号')
+							return
+						}
+					}
+					getteaAddtFn(params).then(res => {
+						if (res.code == 200) {
+							that.$toast('新增成功')
+							setTimeout(function() {
+								uni.$emit('refreshdalist');
+								uni.navigateBack({
+									delta:1
+								})
+							}, 1500)
+						} else {
+							this.$toast(res.msg)
+						}
+					})
+				} else {
+					getteaPutFn(params).then(res => {
+						if (res.code == 200) {
+							that.$toast('修改成功')
+							setTimeout(function() {
+								uni.$emit('refreshdadetail');
+								uni.$emit('refreshdalist');
+								uni.navigateBack({
+									delta:1
+								})
+							}, 1500)
+						} else {
+							this.$toast(res.msg)
+						}
+					})
+				}
+			})
+		},
+		bindDateChange(e){
+			var idx=e.detail.value
+			this.datainfo.sex=this.sexrange[idx].val
+		},
+		bindDateChangea(e){
+			var idx=e.detail.value
+			this.datainfo.politicalStatus=this.outlook[idx].dictLabel
+		},
+		bindDateChangec(e){
+			var idx=e.detail.value
+			this.datainfo.professional=this.zctitle[idx].dictLabel
+		},
+		bindDateChanged(e){
+			this.datainfo.onBoardTime=e.detail.value;
+		},
+		bindDateChangee(e){
+			this.datainfo.jobTime=e.detail.value;
+		},
+		
+		bindDateChangeb(e){
+			var idx=e.detail.value
+			this.datainfo.className=this.classlist[idx].dictLabel;
+			this.datainfo.classId=this.classlist[idx].dictValue;
+			this.datainfo.name='';
+			this.datainfo.teacherId='';
+			this.getteanoListFn()
+		},
+		bindDateChangef(e){
+			var idx=e.detail.value
+			this.datainfo.name=this.teacherlist[idx].dictLabel
+			this.datainfo.teacherId=this.teacherlist[idx].dictValue
+		},
+		bindDateChangeg(e){
+			var idx=e.detail.value
+			this.datainfo.bloodType=this.bloodrange[idx].dictLabel
+		},
+		// 查看照片
+		getPreview(iurl,idx) {
+			var newArr=[];
+			iurl.forEach(ite=>{
+				var ds=this.baseUrl+ite
+				newArr.push(ds)
+			})
+			uni.previewImage({
+				urls: newArr,
+				current:idx,
+				success: function(data) {
+					
+				},
+				fail: function(err) {
+					console.log(err.errMsg);
+				}
+			});
+		},
+		delimgFn(e,idx){
+			var that = this;
+			if(e=='zj'){
+				that.zjfile.splice(idx,1);
+				that.datainfo.identificationPhoto=that.zjfile.join(',')
+			}else if(e=='mj'){
+				that.mjfile.splice(idx,1);
+				that.datainfo.entrancePermit=that.mjfile.join(',')
+			}else if(e=='byzm'){
+				that.byzmfile.splice(idx,1);
+				that.datainfo.entrancePermit=that.byzmfile.join(',')
+			}else if(e=='byzs'){
+				that.byzsfile.splice(idx,1);
+				that.datainfo.entrancePermit=that.byzsfile.join(',')
+			}else if(e=='jzzm'){
+				that.jzzmfile.splice(idx,1);
+				that.datainfo.entrancePermit=that.jzzmfile.join(',')
+			}else if(e=='zczm'){
+				that.zczmfile.splice(idx,1);
+				that.datainfo.entrancePermit=that.zczmfile.join(',')
+			}
+			
+		},
+		getphotoFn(e){
+			let that = this;
+			let file =[],count=9
+			if(e=='zj'){
+				file = that.zjfile;
+				count=9
+			}else{
+				file = that.mjfile;
+				count=9
+			}
+			if(file.length < count){
+				uni.chooseImage({
+					count: count - parseInt(file.length),
+					success:function(res){
+						let img= res.tempFilePaths;
+						if(img.length + file.length > count){
+							uni.showToast({
+								title: '最多上传'+count+'张图片',
+								icon: 'none',
+								duration: 2000
+							})
+						}else{
+							let imglen = res.tempFilePaths.length;
+							var fuwufile = [];
+							uploadmore('/common/upload',img,0,0,0,imglen,fuwufile,function(rs){
+								if(e=='zj'){
+									that.zjfile = that.zjfile.concat(rs);
+									that.datainfo.identificationPhoto=that.zjfile.join(',')
+								}else if(e=='mj'){
+									that.mjfile = that.mjfile.concat(rs);
+									that.datainfo.entrancePermit=that.mjfile.join(',')
+								}else if(e=='byzm'){
+									that.byzmfile = that.byzmfile.concat(rs);
+									that.datainfo.graduationPhoto=that.byzmfile.join(',')
+								}else if(e=='byzs'){
+									that.byzsfile = that.byzsfile.concat(rs);
+									that.datainfo.degreePhoto=that.byzsfile.join(',')
+								}else if(e=='jzzm'){
+									that.jzzmfile = that.jzzmfile.concat(rs);
+									that.datainfo.teachingPhoto=that.jzzmfile.join(',')
+								}else if(e=='zczm'){
+									that.zczmfile = that.zczmfile.concat(rs);
+									that.datainfo.professionalPhoto=that.zczmfile.join(',')
+								}
+							})	
+						}
+					}
+				});
+			}
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.addbox{padding: 24rpx 36rpx 180rpx;}
+.ftit{font-size: 30rpx;font-weight: 500;color: #666666;padding: 8rpx;margin-bottom: 16rpx;}
+.fbox{background: #FFFFFF;border-radius: 18rpx;padding: 12rpx 0;margin-bottom: 32rpx;
+	.addimg{width: 120rpx;height: 120rpx;}
+	.ilrmgr{width: 14rpx;height: 24rpx;margin-left: 20rpx;flex: 0 0 auto;}
+}
+.addbtn{height: 98rpx;width: 100%;
+background: #1f57e6;
+border-radius: 48rpx;display: flex;align-items: center;justify-content: center;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;}
+.comboxl{min-height: 70rpx;padding:15rpx 0rpx;box-sizing: border-box;line-height: 40rpx;flex: 1;
+		textarea{width: 100%;font-size: 30rpx;color: #161616;text-align: right;}
+	}
+.imgs{display: flex;align-items: center;flex-wrap: wrap;justify-content: flex-end;
+	.photos{width: 120rpx;height: 120rpx;position: relative;margin: 0 0rpx 16rpx 16rpx;
+	// &:nth-child(3n){margin-left: 0;}
+	.rimg{width: 100%;height: 100%;}
+	.del{width: 36rpx;height: 36rpx;position: absolute;right: 0rpx;top: 0rpx;}
+	}
+}
+
+
+.addbox /deep/ .uni-forms{flex: 1;}
+.addbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.addbox /deep/ .uni-forms .uni-forms-item{margin-bottom: 0;padding: 4rpx 32rpx;
+	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+}
+.addbox /deep/  .uni-easyinput{height: 70rpx;}
+// .addbox /deep/  .uni-textarea-textarea{height: auto;}
+.addbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.addbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.addbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.addbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .addbox /deep/ .uni-forms-item__error{margin-top:-12rpx;left: auto;right: 0;}
+ .addbox /deep/ .uni-data-checklist .checklist-group .checklist-box{margin-right: 30rpx;}
+  .addbox /deep/ .uni-data-checklist .checklist-group{justify-content: flex-end;}
+</style>

+ 347 - 0
mine/pages/files/detail.vue

@@ -0,0 +1,347 @@
+<template>
+	<view class="det">
+		<uni-nav-bar left-icon="left" title="档案详情" :background-color="backgroundColor" :border="navborder" statusBar='true' fixed="true" @clickLeft='getBack'>
+			
+		</uni-nav-bar>
+		<view class="det_top"></view>
+		<view class="detbox">
+			<view class="det_list">
+				<image :src="bgimg" class="bgimg"></image>
+			 <view class="tit">基本信息</view>
+				<view class="list">
+				 <view class="ltit">姓名:</view>
+					<view class="ltxt">{{datainfo.name||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">身份证号:</view>
+					<view class="ltxt">{{datainfo.idCard||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">性别:</view>
+					<view class="ltxt">{{datainfo.sex=='1'?'男':'女'||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">年龄:</view>
+					<view class="ltxt">{{datainfo.age||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">民族:</view>
+					<view class="ltxt">{{datainfo.familyName||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">政治面貌:</view>
+					<view class="ltxt">{{datainfo.politicalStatus||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">学校:</view>
+					<view class="ltxt">{{datainfo.school||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">学号:</view>
+					<view class="ltxt">{{datainfo.studentNumber||""}}</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">
+					<view class="flex1">其他信息</view>
+					<view class="txt" @click="getHistory" v-if="checkPermi(['live:old:list'])">历史记录</view>
+				</view>
+				<view class="list">
+					<view class="ltit">身高:</view>
+					<view class="ltxt">{{datainfo.height||""}}cm</view>
+				</view>
+				<view class="list">
+					<view class="ltit">体重:</view>
+					<view class="ltxt">{{datainfo.weight||""}}kg</view>
+				</view>
+				<view class="list">
+					<view class="ltit">血型:</view>
+					<view class="ltxt">{{datainfo.bloodType||""}}</view>
+				</view>
+				<view class="list" style="align-items: center;">
+					<view class="f15 co6 flex0">更新时间:</view>
+					<view class="ltxt">{{datainfo.updateTime}}</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">
+					<view class="flex1">视力信息</view>
+				</view>
+				<view class="list">
+					<view class="ltit">是否近视:</view>
+					<view class="ltxt" v-if="datainfo.isNearsightedness">{{datainfo.isNearsightedness=='1'?'是':'否'}}</view>
+					<view class="ltxt" v-else></view>
+				</view>
+				<view class="list">
+					<view class="ltit">近视度数:</view>
+					<view class="ltxt">{{datainfo.degreeMyopia||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">是否远视:</view>
+					<view class="ltxt" v-if="datainfo.isFarsightedness">{{datainfo.isFarsightedness=='1'?'是':'否'}}</view>
+					<view class="ltxt" v-else></view>
+				</view>
+				<view class="list">
+					<view class="ltit">远视度数:</view>
+					<view class="ltxt">{{datainfo.farsightedness||""}}</view>
+				</view>
+				<view class="list" style="align-items: center;">
+					<view class="f15 co6 flex0">更新时间:</view>
+					<view class="ltxt">{{datainfo.updateTime||""}}</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">
+					<view class="flex1">健康信息</view>
+					<view class="txt" @click="getMind" v-if="checkPermi(['mind:old:list'])">历史记录</view>
+				</view>
+				<view class="list">
+					<view class="ltit">健康状态:</view>
+					<view class="ltxt">{{datainfo.health||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">有无过往病史:</view>
+					<view class="ltxt" v-if="datainfo.isMedicalHistory">{{datainfo.isMedicalHistory=='1'?'是':'否'}}</view>
+					<view class="ltxt" v-else></view>
+				</view>
+				<view class="list">
+					<view class="ltit">病史描述:</view>
+					<view class="ltxt">{{datainfo.medicalDescription||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">心理健康状态:</view>
+					<view class="ltxt">{{datainfo.mind||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">心理健康描述:</view>
+					<view class="ltxt">{{datainfo.psychologicalDescription||""}}</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">家庭信息</view>
+				<view class="list">
+					<view class="ltit">是否贫困:</view>
+					<view class="ltxt" v-if="datainfo.isPoverty">{{datainfo.isPoverty=='1'?'是':'否'}}</view>
+					<view class="ltxt" v-else></view>
+				</view>
+				<view class="list">
+					<view class="ltit">是否留守儿童:</view>
+					<view class="ltxt" v-if="datainfo.isLset">{{datainfo.isLset=='1'?'是':'否'}}</view>
+					<view class="ltxt" v-else></view>
+				</view>
+				<view class="list">
+					<view class="ltit">居住地址:</view>
+					<view class="ltxt">{{datainfo.address||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">父亲/电话:</view>
+					<view class="ltxt">{{datainfo.fatherName||""}}
+						<block v-if="datainfo.fatherName">/</block>
+						{{datainfo.fatherTelephone||""}}
+					</view>
+				</view>
+				<!-- <view class="list">
+					<view class="ltit">父亲联系方式:</view>
+					<view class="ltxt">{{datainfo.fatherTelephone||""}}</view>
+				</view> -->
+				<view class="list">
+					<view class="ltit">母亲/电话:</view>
+					<view class="ltxt">{{datainfo.motherName||""}}
+						<block v-if="datainfo.motherName">/</block>
+						{{datainfo.motherTelephone||""}}
+					</view>
+				</view>
+				<!-- <view class="list">
+					<view class="ltit">母亲联系方式:</view>
+					<view class="ltxt">{{datainfo.motherTelephone||""}}</view>
+				</view> -->
+				<view class="list">
+					<view class="ltit">紧急联系人/电话:</view>
+					<view class="ltxt">{{datainfo.emergencyContact||""}}
+						<block v-if="datainfo.emergencyContact">/</block>
+						{{datainfo.emergencyContactTelephone||""}}
+					</view>
+				</view>
+				<!-- <view class="list">
+					<view class="ltit">紧急联系方式:</view>
+					<view class="ltxt">{{datainfo.emergencyContactTelephone||""}}</view>
+				</view> -->
+			</view>
+			<view class="det_list">
+				<view class="tit">照片信息</view>
+				<view class="list flexcja mb15">
+					<view class="ltit">证件照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in zjfile" :key='index' @click="getPreview(zjfile,index)"></image>
+					</view>
+					
+				</view>
+				<view class="list flexcja">
+					<view class="ltit">门禁照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in mjfile" :key='index' @click="getPreview(mjfile,index)"></image>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view style="height: 170rpx;" v-if="checkPermi(['student:info:edit','student:info:remove'])"></view>
+		<view class="fbtn" v-if="checkPermi(['student:info:edit','student:info:remove'])">
+			<view class="rebtndel" @click="getDel" v-if="checkPermi(['student:info:remove'])">删除档案</view>
+			<view class="w13 flex0"></view>
+			<view class="rebtn" @click="getUpdate" v-if="checkPermi(['student:info:edit'])">修改档案</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+	import {getstuDetFn,getstuDelFn} from "@/api/mine/files.js"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	export default {
+		data() {
+			return {
+				bgimg: require("@/mine/static/score/bg.png"),
+				backgroundColor: "transparent",
+				navborder: false,
+				id: '',
+				datainfo: '',
+				baseUrl:'',
+				zjfile:[],
+				mjfile:[],
+				scrollTop:''
+			}
+		},
+		onUnload(){
+			uni.$off('refreshdadetail')
+		},
+		onLoad: function(e) {
+			uni.$on('refreshdadetail',(e) => {
+				this.getDataFn();
+			})
+			this.id = e.id;
+			this.baseUrl=baseUrl;
+			this.getDataFn()
+		},
+		onShow:function(){
+			var scrollTop=this.scrollTop;
+			if (scrollTop > 0) {
+				this.backgroundColor = '#c4defb'
+			} else {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 0
+				})
+				this.backgroundColor = 'transparent'
+			}
+		},
+		onPageScroll(e) {
+			var scrollTop = Number(e.scrollTop);
+			this.scrollTop=scrollTop
+			if (scrollTop > 0) {
+				this.backgroundColor = '#ffffff'
+			} else {
+				this.backgroundColor = 'transparent'
+			}
+		},
+		methods: {
+			checkPermi,checkRole,
+			getBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			getHistory(){
+				this.$tab.navigateTo('/mine/pages/files/history?id='+this.datainfo.studentId);	
+			},
+			getMind(){
+				this.$tab.navigateTo('/mine/pages/files/mindlist?type=da&id='+this.datainfo.studentId+'&name='+this.datainfo.name);
+			},
+			getDataFn() {
+				getstuDetFn(this.id).then(res => {
+					if (res.code == 200) {
+						this.datainfo = res.data;
+						if(res.data.identificationPhoto){
+							this.zjfile=res.data.identificationPhoto.split(',')
+						}else{
+							this.zjfile=[];
+						}
+						if(res.data.entrancePermit){
+							this.mjfile=res.data.entrancePermit.split(',')
+						}else{
+							this.mjfile=[];
+						}
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getUpdate(){
+				this.$tab.navigateTo('/mine/pages/files/addstudent?type=update&id='+this.id);	
+			},
+			getDel(){
+				var that=this;
+				this.$modal.confirm('确定删除该信息吗?').then(() => {
+				  getstuDelFn(that.id).then(res=>{
+					 if (res.code == 200) {
+					 	that.$toast('删除成功')
+						setTimeout(function(){
+							uni.$emit('refreshdalist');
+							uni.navigateBack({
+								delta:1
+							})
+						},1500)
+					 } else {
+					 	that.$toast(res.msg)
+					 } 
+				  })
+				})
+			},
+			// 查看照片
+			getPreview(iurl,idx) {
+				var newArr=[];
+				iurl.forEach(ite=>{
+					var ds=this.baseUrl+ite
+					newArr.push(ds)
+				})
+				uni.previewImage({
+					urls: newArr,
+					current:idx,
+					success: function(data) {
+						
+					},
+					fail: function(err) {
+						console.log(err.errMsg);
+					}
+				});
+			},
+		},
+
+	}
+</script>
+
+<style lang="scss" scoped>
+
+.det_top{width: 100%;height: 334rpx;background: linear-gradient(180deg, rgba(222,230,255,0.72) 28.000000000000004%, rgba(232,236,198,0) 100%);}
+.detbox{padding: 0 36rpx;margin-top: -180rpx;padding-bottom: 20rpx;
+	.det_list{background-color: #fff;border-radius: 10rpx;width: 100%;padding: 36rpx 48rpx;position: relative;margin-bottom: 24rpx;
+		.tit{font-size: 32rpx;font-weight: bold;color: #161616;position: relative;margin-bottom: 20rpx;display: flex;align-items: center;
+			.txt{font-size: 30rpx;font-weight: 500;
+color: #4775EA;}
+		&::before{width: 6rpx;height: 36rpx;background: #1f57e6;border-radius: 4rpx;content: '';position: absolute;left: -24rpx;top: 50%;margin-top: -18rpx;}
+		}
+		.list{
+			display: flex;align-items: flex-start;padding: 10rpx 0;
+			.ltit{flex: 0 0 auto;font-size: 30rpx;color: #161616;font-weight: bold;margin-right:4rpx;}
+			.ltxt{flex: 1;font-size: 30rpx;color: #666666;font-weight: 500;line-height: 40rpx;}
+			.imgs{display: flex;align-items: center;flex-wrap: wrap;justify-content: flex-end;}
+			.phoimg{width: 140rpx;height: 140rpx;margin: 0 0rpx 14rpx 14rpx;}
+		}
+		.bgimg{width: 188rpx;height: 160rpx;position: absolute;right: 46rpx;bottom: 54rpx;}
+	}
+}
+.fbtn{display: flex;align-items: center;position: fixed;left: 0;right: 0;bottom: 0;background-color: #f1f1f1;padding: 36rpx;
+		
+	}
+.det /deep/ .uni-navbar__placeholder{height: 0 !important;}
+</style>

+ 145 - 0
mine/pages/files/height.vue

@@ -0,0 +1,145 @@
+<template>
+  <view class="mind">
+	  <picker range-key="dictLabel" :disabled="daflag||studentlist.length<1" :range="studentlist"  :value="nameidx"  @change="bindDateChangea">
+	  		<view class="flexc mibox mb20">
+	  			<view class="tit" style="margin-bottom: 0;">人员</view>
+	  			<view class="f15 flex1 txr co16" v-if="name" >{{name}}</view>
+	  			<view class="f15 flex1 txr coa" v-else >请选择人员</view>
+	  			<image :src="rimg" class="rimg"></image>
+	  		</view>
+	  </picker>
+	  <view class='mibox flexc'>
+			<view class="tit">身高</view>
+			<input placeholder="请输入身高" v-model="height" type="number"/>
+	  		<view class="f16 co16 ml6">cm</view>
+		</view>
+		<view class='mibox flexc'>
+				<view class="tit">体重</view>
+				<input placeholder="请输入身高" v-model="weight" type="number"/>
+			<view class="f16 co16 ml6">kg</view>
+		</view>
+	  <view class="rebtn mt30" @click="getSubmit">确认</view>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {getliveAddFn} from "@/api/mine/files.js"
+  export default {
+	data(){
+		return{
+			rimg:require("@/mine/static/score/rimg.png"),
+			autoHeight:true,
+			height:'',
+			weight:'',
+			datainfo:{
+				
+			},
+			roles:'',
+			studentlist:[],
+			name:'',
+			nameidx:0,
+			studentId:'',
+			daflag:false,//档案修改
+		}
+	},
+	onLoad: function(e) {
+		if(e.type&&e.type=='daup'){
+			this.name=e.name;
+			this.studentId=e.id;
+			this.daflag=true;
+		}else{
+			//家长
+			var roles=this.$store.state.user.choseroles;
+			var newArr=this.$store.state.user.student;
+			if(newArr&&newArr.length){
+				if(newArr&&newArr.length>1){
+					this.studentlist = newArr.map(v => {
+						return {
+							dictLabel:v.studentName,
+							dictValue: v.id,
+						}
+					})
+				}else{
+					// 一个娃
+					this.name=newArr[0].studentName
+					this.studentId=newArr[0].id
+				}
+			}
+			
+		}
+		
+		
+	},
+	methods:{
+		bindDateChangea(e){
+			var idx=e.detail.value
+			this.name=this.studentlist[idx].dictLabel
+			this.studentId=this.studentlist[idx].dictValue
+		},
+		getSubmit(){
+			// 学生 id
+			var that=this;
+			var roles=this.$store.state.user.choseroles;
+			if(!this.studentId){
+				this.$toast('请选择人员')
+				return
+			}
+			if(!this.height&&!this.weight){
+				this.$toast('请至少输入身高或体重')
+				return
+			}
+			// 走修改
+			var params={
+				studentId:this.studentId,
+			}
+			if(this.height){
+				params.height=this.height
+			}
+			if(this.weight){
+				params.weight=this.weight
+			}
+			if(roles=='teacher'){
+				params.createType='2'
+			}else if(roles=='parents'){
+				params.createType='1'
+			}
+			getliveAddFn(params).then(res => {
+				if (res.code == 200) {
+					that.$toast('新增成功')
+					setTimeout(function() {
+						if(that.daflag){
+							uni.$emit('refreshdalist');
+							uni.redirectTo({
+								url:'/mine/pages/files/heightlist?type=da&id='+that.studentId+'&name='+that.name
+							})
+						}else{
+							uni.$emit('refreshlivelist');
+							uni.navigateBack({
+								delta:1
+							})
+						}
+						
+					}, 1500)
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.mind{
+	min-height: 100vh;background: #ffffff;padding: 80rpx 60rpx;
+	.mibox{
+		.tit{font-size: 32rpx;font-weight: 500;color: #161616;margin-bottom: 40rpx;}
+		textarea{border: 2rpx solid #FFB132;border-radius: 20rpx;width: 100%;min-height: 230rpx;padding:32rpx;box-sizing: border-box;}
+		.rimg{width: 14rpx;height: 24rpx;flex: 0 0 auto;margin-left: 12rpx;}
+		input{flex: 1;text-align: right;}
+	}
+}
+</style>

+ 215 - 0
mine/pages/files/heightlist.vue

@@ -0,0 +1,215 @@
+<template>
+  <view class="mind">
+	  <!-- tab栏 切孩子 -->
+	  <view class="top">
+	  		<view class="top_t" @click="getTab(ite.val)" :class="[tabval==ite.val?'act':'',daflag?'top_tda':'']"  v-for="(ite,idx) in studentlist" :key="idx">{{ite.tit}}<image :src="tapline" class="line"></image></view>
+	  </view>
+	  <view class="pt12">
+		  <xl-list :datype='datype' :datalist="list" :wtdt="wtdt" @getDel="getDel"></xl-list>
+	  </view>
+	  <view style="height: 100rpx;" v-if="checkPermi(['live:old:add'])&&!daflag"></view>
+	  <view class="mbtn" v-if="checkPermi(['live:old:add'])&&!daflag" @click="getAdd">更新身高体重状态</view>
+  </view>
+</template>
+
+<script>
+	import xlList from "@/mine/components/list/list.vue"
+	import {getliveListFn,getliveDelFn} from "@/api/mine/files.js"
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+  export default {
+	  components:{
+		  xlList
+	  },
+	data(){
+		return{
+			sucimg:require("@/mine/static/score/ncheck.png"),
+			tapline:require("@/static/images/hline.png"),
+			list:[],
+			datype:6,
+			pageSize: 10,
+			pageNum: 1,
+			reachflag: true,
+			wtdt: '',
+			tabval:'',
+			actidx:-1,
+			daflag:false,
+			studentlist:[]
+		}
+	},
+	onUnload() {
+		uni.$off('refreshlivelist')
+	},
+	onReachBottom() {
+		if (this.reachflag) {
+			this.pageNum++
+			this.getDataFn()
+		}
+	},
+	onLoad: function(e) {
+		uni.$on('refreshlivelist', (e) => {
+			this.reachflag = true;
+			this.pageNum = 1;
+			this.list = [];
+			this.getDataFn();
+		})
+		if(e.type&&e.type=='da'){
+			this.daflag=true;
+			this.tabval=e.id
+			this.studentlist=[{
+				tit:e.name,
+				val: e.id,
+			}]
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			var newArr=this.$store.state.user.student;
+			// console.log(newArr,1)
+			this.tabval=newArr[0].id
+			this.studentlist = newArr.map(v => {
+				return {
+					tit:v.studentName,
+					val: v.id,
+				}
+			})
+		}
+		this.getDataFn()
+	},
+	methods:{
+		checkPermi,checkRole,
+		getLook(e) {
+			if (this.actidx == e) {
+				this.actidx = -1
+			} else {
+				this.actidx = e;
+			}
+		},
+		toTree2(arr){
+			var list=this.list;
+			let newA = JSON.parse(JSON.stringify(arr));
+			if(list&&list.length){
+				list.forEach(ite=>{
+					for(var i =0;i<newA.length;i++){
+						if(ite.ayear === newA[i].ayear&&ite.amonth === newA[i].amonth){
+							ite.children.push(newA[i])
+						}else{
+							var obj={
+								ayear:newA[i].ayear,
+								amonth:newA[i].amonth,
+								check:true,
+								children:[]
+							}
+							obj.children.push(newA[i])
+							list.push(obj)
+						}
+					}
+				})
+				return list
+			}else{
+				var newArrs = [];
+				var larr=[]
+				const map = new Map();
+				newArrs = newA.filter(v => !map.has(v.ayear)&&!map.has(v.amonth) && map.set(v.ayear, 1)&& map.set(v.amonth, 1));
+				newArrs.forEach(ite=>{
+					var obj={
+						ayear:ite.ayear,
+						amonth:ite.amonth,
+						check:true
+					}
+					larr.push(obj)
+				})
+				larr.forEach(ite=>{
+					ite.children = newA.filter(e => {
+					    return ite.ayear === e.ayear&&ite.amonth === e.amonth
+					})
+				})
+				return larr
+			}
+		},
+		getAdd(){
+			this.$tab.navigateTo(`/mine/pages/files/height`)
+		},
+		getTab(idx){
+			this.tabval=idx;
+			this.list=[];
+			this.reachflag=true;
+			this.pageNum=1;
+			this.getDataFn();
+		},
+		getDel(id){
+			var that=this;
+			getliveDelFn(id).then(res=>{
+				if (res.code == 200) {
+					that.$toast('删除成功')
+						setTimeout(function(){
+							that.reachflag = true;
+							that.pageNum = 1;
+							that.list = [];
+							that.getDataFn();
+						},1500)
+				} else {
+					that.$toast(res.msg)
+				} 
+			})
+		},
+		getDataFn(a) {
+			var params = {
+				pageSize: this.pageSize,
+				pageNum: this.pageNum,
+				studentId:this.tabval
+			}
+			getliveListFn(params).then(res => {
+				if (res.code == 200) {
+					this.total = res.total;
+					if (res.rows.length < this.pageSize) {
+						this.reachflag = false
+						this.wtdt = '到底了~';
+					} else {
+						var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -1)
+						if (num < res.total) {
+							this.reachflag = true
+							this.wtdt = '上拉加载更多'
+						} else {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						}
+					}
+					// 数据处理
+					var newArr=res.rows;
+					if(newArr&&newArr.length){
+						var timeArr=[];
+						Object.keys(newArr).some((key) => {
+							var time=newArr[key].createTime.split(' ');
+							var a=time[0].split('-')
+							newArr[key].ayear=a[0];
+							newArr[key].amonth=a[1];
+						})
+						this.list=this.toTree2(newArr)
+					}else{
+						this.list=[]
+					}
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.mind{padding: 100rpx 36rpx 0rpx;min-height: 100vh;background-color: #ffffff;box-sizing: border-box;
+	.mbtn{position: fixed;left: 0;right: 0;bottom: 0;height: 100rpx;display: flex;align-items: center;justify-content: center;z-index: 2;background: #1f57e6;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;}
+	.top{height: 96rpx;border-bottom: 2rpx solid #E5E5E5;position: fixed;top: 0;left: 0;right: 0;overflow-x: scroll;display: flex;align-items: center;z-index: 1;background-color: #ffffff;
+		.top_t{position: relative;font-size: 30rpx;font-weight: 500;color: #AAAAAA;height: 94rpx;line-height: 94rpx;padding:0 20rpx;flex:1 0 auto;text-align: center;
+			&.act{color: #161616;font-weight: bold;
+				.line{display: block;}
+				// &::after{content: '';width: 42rpx;height: 10rpx;background: #1f57e6;border-radius: 6rpx;position: absolute;left: 50%;margin-left: -21rpx;bottom: 12rpx;}
+			}
+			&.top_tda{flex: 0 0 auto !important;padding: 0 40rpx;}
+			.line{width: 40rpx;height: 12rpx;position: absolute;left: 50%;margin-left: -20rpx;bottom: 16rpx;display: none;}
+		}
+	}
+}
+
+</style>

+ 248 - 0
mine/pages/files/history.vue

@@ -0,0 +1,248 @@
+<template>
+	<view class="container">
+		<!-- 多折线图 -->
+		<view class="tit">成长趋势</view>
+		<view class="aside_inner">
+			<view class="moreline_cavcans">
+				<qiun-data-charts type="mix" :ontouch="true" :opts="opts" :chartData="chartData"></qiun-data-charts>
+			</view>
+		</view>
+		<view class="tit mb16">历史详情</view>
+		<view class="table">
+			<zb-table
+			  :show-header="true"
+			  :columns="column2"
+			  :stripe="true"
+			  :fit="false"
+			  @rowClick="rowClick"
+			  @toggleRowSelection="toggleRowSelection"
+			  @toggleAllSelection="toggleAllSelection"  
+			  :data="hislist"></zb-table>
+		</view>
+	</view>
+</template>
+ 
+<script>
+	import qiunDataCharts from "@/mine/components/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue"
+	import zbTable from "@/mine/components/zb-table/zb-tables.vue"
+	import {column2} from '@/mine/components/zb-table/all.js'
+	import {getoldechFn,getliveListFn} from "@/api/mine/files.js"
+	export default {
+		components:{
+			zbTable,qiunDataCharts
+		},
+		data() {
+			return {
+				column2,
+				studentId:'',
+				hislist:[],
+				chartData: {},
+				categories: ["2016", "2017", "2018", "2019", ],
+				opts: {
+					color: ["#FFB132", "#419CFF",],
+					padding: [-10, 10, 30, 15],
+					dataLabel: false, //是否显示数据文案  true表示显示,false表示不显示
+					dataPointShape: false, //是否显示数据点数据图表
+					dataPointShapeType: 'solid', //图形标识点显示类型 solid实心 hollow空心
+					enableScroll: true,
+					legend: {
+						fontColor: '#363636',
+						fontSize: 12,
+						position: "top",
+						margin: 16,
+						padding: 5,
+						float: "center"
+					},
+					xAxis: {
+						disabled: false, //不绘制x轴
+						axisLine: false, //坐标轴线
+						axisLineColor: "#fff", //坐标轴线颜色
+						calibration: false, //刻度线
+						disableGrid: true, //不绘制网格线 
+						fontColor: "#474e5b", //刻度值字体颜色
+						fontSize: 14,
+						itemCount: 5,
+					},
+					yAxis: {
+						gridType: "dash", //横向网格样式  solid实线
+						axisLine: false, //坐标轴线是否显示
+						axisLineColor: '#fff', //坐标轴颜色
+						gridColor: 'rgba(86,94,107,0.4)', //网格颜色
+						dashLength: 3, //网格dash宽度
+						showTitle: true,
+						splitNumber: 4,
+						data: [{   //这里y轴分组   left是下标为0的第一组y数据在最左侧
+								position: "left",
+								axisLine: false, //坐标轴轴线是否显示
+								axisLineColor: '#fff', //坐标轴轴线颜色
+								fontColor: "#474e5b",
+								fontSize: 14,
+								disabled: false, //是否绘画y轴  true不 默认为false
+								min: 0, //y轴最小值
+								// max: 260, //y轴最大值   最大值来除以y轴显示的数量=每份的数量
+								// unit:'焦',//y轴刻度后面的单位
+								tofix: 2,
+								title: 'CM',
+								titleOffsetY: -6,
+								titleOffsetX: -6,
+							},
+							{//这里y轴分组   right是下标为1的第二组y数据在最右侧
+								position: "right",
+								axisLine: false, //坐标轴轴线是否显示
+								axisLineColor: '#fff', //坐标轴轴线颜色
+								fontColor: "#474e5b",
+								fontSize: 14,
+								disabled: false, //是否绘画y轴  true不 默认为false
+								min: 0, //y轴最小值
+								// max: 150, //y轴最大值   最大值来除以y轴显示的数量=每份的数量
+								// unit:'焦',//y轴刻度后面的单位
+								tofix: 2,
+								title: 'KG',
+								titleOffsetY: -6,
+								titleOffsetX: 10,
+							},
+						]
+					},
+ 
+					extra: {
+						tooltip: {
+							showArrow: true, //是否显示小三角
+							// showCategory:true,
+							gridColor: 'rgba(86,94,107,0.4)',
+							borderRadius: 6,
+							bgColor: "#546dfb",
+							gridType: 'dash', //分割线
+							dashLength: 3,
+							bgOpacity: 0.8,
+							labelBgColor: 'red',
+							fontColor: 'rgba(255, 255, 255, 0.8)'
+						},
+						line: {
+							type: "straight",
+							width: 2,
+							activeType: "hollow"
+						},
+						mix: {
+							line: {
+								width: 3,
+							}
+						}
+					}
+				}
+			};
+		},
+		onLoad(e) {
+			this.studentId=e.id;
+			this.getoldechFn()
+			this.getoldlistFn()
+		},
+		methods: {
+			getoldechFn(){
+				var params={
+					studentId:this.studentId
+				}
+				getoldechFn(params).then(res=>{
+					var x=res.data.X;
+					var newArr=[]
+					x.forEach((ite)=>{
+						var narr=ite.split('-')
+						ite=narr[1]+'/'+narr[2],
+						newArr.push(ite)
+					})
+					let nobj = {
+						categories: newArr,
+						series: [
+							{
+								name: "身高",
+								legendShape: 'circle',
+								type: "line",
+								data: res.data.Y1
+							},
+							{
+								name: "体重",
+								type: "line",
+								index: 1,//这个是重点  0代表第一组y轴坐标数据,1代表第二组y轴坐标数据
+								legendShape: 'circle',
+								data: res.data.Y2
+							},
+						],
+					};
+					this.chartData = JSON.parse(JSON.stringify(nobj));
+					// if(res.code==200){
+					// 	this.hislist=res.data
+					// }else{
+					// 	this.$toast(res.msg)
+					// }
+				})
+			},
+			getoldlistFn(){
+				var params={
+					studentId:this.studentId
+				}
+				getliveListFn(params).then(res=>{
+					if(res.code==200){
+						this.hislist=res.rows
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getServerData() {
+				//模拟从服务器获取数据时的延时
+				setTimeout(() => {
+					//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
+					let res = {
+						categories: this.categories,
+						series: [
+							{
+								name: "身高",
+								legendShape: 'circle',
+								type: "line",
+								data: [120, 150, 153, 185,]
+							},
+							{
+								name: "体重",
+								type: "line",
+								index: 1,//这个是重点  0代表第一组y轴坐标数据,1代表第二组y轴坐标数据
+								legendShape: 'circle',
+								data: [40, 45, 50, 46,]
+							},
+						],
+					};
+					this.chartData = JSON.parse(JSON.stringify(res));
+				}, 500);
+			},
+		},
+		created() {
+			// this.getServerData();
+		}
+	}
+</script>
+ 
+<style lang="scss" scoped>
+.zb-table /deep/ .zb-table-fixed{background: #F1F5FF !important;}
+.zb-table /deep/ .item-th{text-align: center !important;padding: 0 4rpx;background: #F1F5FF;text-align: center;border-bottom: none;}
+.zb-table /deep/ .item-td{text-align: center !important;padding: 0 4rpx;}
+.container{min-height: 100vh;background-color: #ffffff;}
+.tit{font-size: 32rpx;font-weight: bold;color: #161616;position: relative;display: flex;align-items: center;padding: 16rpx 60rpx;
+	&::before{width: 8rpx;height: 36rpx;background: #1f57e6;border-radius: 4rpx;content: '';position: absolute;left: 36rpx;top: 50%;margin-top: -18rpx;}
+	}
+.table{padding: 0 48rpx;}
+	.aside_inner {
+		width: 100%;
+ 
+		.moreline_title {
+			text-align: center;
+			color: #e6ebf1;
+			font-size: 32rpx;
+			padding-top: 50rpx;
+			font-weight: 500;
+		}
+ 
+		.moreline_cavcans {
+			width: 700rpx;
+			margin: 10rpx;
+			height: 440rpx;
+		}
+	}
+</style>

+ 284 - 0
mine/pages/files/leave.vue

@@ -0,0 +1,284 @@
+<template>
+  <view class="mind">
+	  <picker range-key="dictLabel" v-if="roles!='parents'" :disabled="daflag" :range="classlist"  :value="classidx"  @change="bindDateChangeb">
+	  		  <view class="flexc mibox mb20">
+	  			  <view class="tit" style="margin-bottom: 0;">班级</view>
+	  			  <view class="f15 flex1 txr co16" v-if="className" >{{className}}</view>
+	  			  <view class="f15 flex1 txr coa" v-else >请选择班级</view>
+	  			  <image :src="rimg" class="rimg"></image>
+	  		  </view>
+	  </picker>
+	  <picker range-key="dictLabel" :disabled="daflag||studentlist.length<1" :range="studentlist"  :value="nameidx"  @change="bindDateChangea">
+	  		  <view class="flexc mibox mb20">
+	  			  <view class="tit" style="margin-bottom: 0;">人员</view>
+	  			  <view class="f15 flex1 txr co16" v-if="name" >{{name}}</view>
+	  			  <view class="f15 flex1 txr coa" v-else >请选择人员</view>
+	  			  <image :src="rimg" class="rimg"></image>
+	  		  </view>
+	  </picker>
+	  <picker range-key="dictLabel" :disabled="daflag" :range="qjlxrange"  :value="qjlbidx"  @change="bindDateChanged">
+	  		  <view class="flexc mibox mb20">
+	  			  <view class="tit" style="margin-bottom: 0;">请假类别</view>
+	  			  <view class="f15 flex1 txr co16" v-if="category" >{{category}}</view>
+	  			  <view class="f15 flex1 txr coa" v-else >请选择请假类别</view>
+	  			  <image :src="rimg" class="rimg"></image>
+	  		  </view>
+	  </picker>
+	 <!-- <picker mode="time"   @change="bindDateChanged"> -->
+		  <view class="flexc mibox mb20">
+			  <view class="tit" style="margin-bottom: 0;">开始时间</view>
+			  <uni-datetime-picker :border="false" :hide-second='true' type="datetime" v-model="startTime" @change="changeLog" />
+			 <!-- <view class="f15 flex1 txr co16" v-if="starttime" >{{starttime}}</view>
+			  <view class="f15 flex1 txr coa" v-else >请选择开始时间</view> -->
+			  <image :src="rimg" class="rimg"></image>
+		  </view>
+		  <view class="flexc mibox mb20">
+		  			  <view class="tit" style="margin-bottom: 0;">结束时间</view>
+		  			  <uni-datetime-picker :border="false" :hide-second='true' type="datetime" v-model="endTime" @change="changeLog" />
+		  			 <!-- <view class="f15 flex1 txr co16" v-if="starttime" >{{starttime}}</view>
+		  			  <view class="f15 flex1 txr coa" v-else >请选择开始时间</view> -->
+		  			  <image :src="rimg" class="rimg"></image>
+		  </view>
+	  <!-- </picker> -->
+	  <view class='mibox'>
+		<view class="tit">详情描述</view>
+		<textarea placeholder="请输入详情描述内容……" v-model="reason" :auto-height="autoHeight"></textarea>
+	  </view>
+	  <view class="rebtn mt30" @click="getSubmit">确认</view>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {getDeptList} from "@/api/mine/mine.js"
+	import {getleaveAddFn,getstunoListFn} from "@/api/mine/files.js"
+  export default {
+	data(){
+		return{
+			rimg:require("@/mine/static/score/rimg.png"),
+			autoHeight:true,
+			qjlx:[],
+			
+			startTime:'',
+			endTime:'',
+			absenteeName:'',
+			qjlbidx:0,
+			category:'',//请假类别
+			categoryval:'',//请假类别
+			datainfo:{
+				
+			},
+			roles:'',
+			studentlist:[],
+			name:'',
+			nameidx:0,
+			classidx:0,
+			studentId:'',
+			classId:'',
+			className:'',
+			psychologicalDescription:'',
+			daflag:false,
+			qjlxrange:[],
+			reason:'',
+			classlist:[],//班级
+		}
+	},
+	onLoad: function(e) {
+		this.init();
+		if(e.type&&e.type=='daup'){
+			this.name=e.name;
+			this.studentId=e.id;
+			this.daflag=true;
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			this.roles=roles;
+			if(roles=='parents'){
+				var newArr=this.$store.state.user.student;
+				if(newArr&&newArr.length){
+					if(newArr.length>1){
+						this.studentlist = newArr.map(v => {
+							return {
+								dictLabel:v.studentName,
+								dictValue: v.id,
+								classId:v.classId
+							}
+						})
+					}else{
+						// 一个娃
+						this.name=newArr[0].studentName
+						this.studentId=newArr[0].id
+						this.classId=newArr[0].classId
+					}
+				}
+			}else if(roles=='teacher'){
+				var newArr=this.$store.state.user.teacherClass;
+				if(newArr&&newArr.length){
+					this.classlist = newArr.map(v => {
+						return {
+							dictLabel:v.className,
+							dictValue: v.classId,
+						}
+					})
+				}
+			}else{
+				var id=this.$store.state.user.deptId;
+				this.getclassListFn(id)
+			}
+			
+		}
+	},
+	methods:{
+		init(){
+			//心理健康状态
+			getDictionaryFn('qjlx').then(res=>{
+				if(res.code==200){
+					this.qjlxrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		changeLog(){
+			
+		},
+		getclassListFn(id){
+			getDeptList(id).then(res=>{
+				if(res.code==200){
+					var newArr=res.data;
+					if(newArr&&newArr.length){
+						this.classlist = newArr.map(v => {
+							return {
+								dictLabel: v.deptName,
+								dictValue: v.deptId,
+		
+							}
+						})
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		bindDateChangea(e){
+			var idx=e.detail.value
+			this.name=this.studentlist[idx].dictLabel
+			this.studentId=this.studentlist[idx].dictValue
+			this.classId=this.studentlist[idx].classId
+		},
+		bindDateChangeb(e){
+			var idx=e.detail.value
+			this.className=this.classlist[idx].dictLabel
+			this.classId=this.classlist[idx].dictValue
+			this.name='';
+			this.studentId='';
+			// 获取班级信息
+			this.getstunoListFn()
+		},
+		bindDateChanged(e){
+		 	var idx=e.detail.value
+		 	this.category=this.qjlxrange[idx].dictLabel
+		 	this.categoryval=this.qjlxrange[idx].dictValue
+		},
+		getstunoListFn(){
+			var params={
+				classId:this.classId
+			}
+			params['params[role]']=this.$store.state.user.choseroles
+			getstunoListFn(params).then(res=>{
+				if(res.code==200){
+					this.studentlist = res.rows.map(v => {
+						return {
+							dictLabel: v.studentName,
+							dictValue: v.id,
+							classId:v.classId
+						}
+					})
+				}
+			})
+		},
+		getSubmit(){
+			// 学生 id
+			var roles=this.$store.state.user.choseroles;
+			var that=this;
+			if(roles!="parents"){
+				if(!this.className){
+					this.$toast('请选择班级')
+					return
+				}
+			}
+			if(!this.studentId){
+				this.$toast('请选择人员')
+				return
+			}
+			if(!this.category){
+				this.$toast('请选择请假类别')
+				return
+			}
+			if(!this.startTime){
+				this.$toast('请选择开始时间')
+				return
+			}
+			if(!this.endTime){
+				this.$toast('请选择结束时间')
+				return
+			}
+			var params={
+				absenteeId:this.studentId,
+				category:this.categoryval,
+				reason:this.reason,
+				startTime:this.startTime+':00',
+				endTime:this.endTime+':00',
+				classId:this.classId,
+				absenteeName:this.name,
+			}
+			params['params[role]']=this.$store.state.user.choseroles
+			// if(roles=='teacher'){
+			// 	params.createType='2'
+			// }else if(roles=='parents'){
+			// 	params.createType='1'
+			// }
+			getleaveAddFn(params).then(res => {
+				if (res.code == 200) {
+					that.$toast('新增成功')
+					setTimeout(function() {
+						if(that.daflag){
+							uni.$emit('refreshleavelist');
+							uni.redirectTo({
+								url:'/mine/pages/files/leavelist?type=da&id='+that.studentId+'&name='+that.name
+							})
+						}else{
+							uni.$emit('refreshleavelist');
+							uni.navigateBack({
+								delta:1
+							})
+						}
+					}, 1500)
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.mind{
+	min-height: 100vh;background: #ffffff;padding: 80rpx 60rpx;
+	.mibox{
+		.tit{font-size: 32rpx;font-weight: 500;color: #161616;margin-bottom: 40rpx;}
+		textarea{border: 2rpx solid #FFB132;border-radius: 20rpx;width: 100%;min-height: 230rpx;padding:32rpx;box-sizing: border-box;}
+		.rimg{width: 14rpx;height: 24rpx;flex: 0 0 auto;margin-left: 12rpx;}
+	}
+}
+.mind /deep/ .uni-input-wrapper{text-align: right;font-size: 30rpx;}
+.mind /deep/ .uni-date__x-input{padding: 0;text-align: right;font-size: 30rpx;}
+.mind /deep/ .uni-date-x{padding: 0;}
+.mind /deep/ .uniui-calendar::before{display: none;}
+.mind /deep/ .uni-input-placeholder{color:#AAAAAA;font-size: 30rpx;}
+</style>

+ 281 - 0
mine/pages/files/leavelist.vue

@@ -0,0 +1,281 @@
+<template>
+  <view class="mind">
+	  <!-- tab栏 切孩子 -->
+	  <view class="top ">
+	  		<view class="top_t" @click="getTab(ite.val)" :class="[tabval==ite.val?'act':'',daflag?'top_tda':'']" v-for="(ite,idx) in tablist" :key="idx">{{ite.tit}}<image :src="tapline" class="line"></image></view>
+	  </view>
+	  <view class="pt12">
+		  <xl-list :datype='datype' :roles="roles" :qjlxrange="qjlxrange" :datalist="list" :wtdt="wtdt" @getDel="getDel"></xl-list>
+	  </view>
+	  <view style="height: 100rpx;" v-if="checkPermi(['system:leave:add'])"></view>
+	  <view class="mbtn" v-if="checkPermi(['system:leave:add'])" @click="getAdd">请假</view>
+  </view>
+</template>
+
+<script>
+	import xlList from "@/mine/components/list/list.vue"
+	import {getleaveListFn,getleaveDelFn} from "@/api/mine/files.js"
+	import {getDeptList} from "@/api/mine/mine.js"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+  export default {
+	  components:{
+		  xlList
+	  },
+	data(){
+		return{
+			sucimg:require("@/mine/static/score/ncheck.png"),
+			tapline:require("@/static/images/hline.png"),
+			list:[],
+			datype:7,
+			pageSize: 10,
+			pageNum: 1,
+			reachflag: true,
+			wtdt: '',
+			tabval:'',
+			actidx:-1,
+			daflag:false,
+			studentlist:[],
+			qjlxrange:[],
+			teacherClass:[],
+			tablist:[],
+			roles:'',
+		}
+	},
+	onUnload() {
+		uni.$off('refreshleavelist')
+	},
+	onReachBottom() {
+		if (this.reachflag) {
+			this.pageNum++
+			this.getDataFn()
+		}
+	},
+	onLoad: function(e) {
+		uni.$on('refreshleavelist', (e) => {
+			this.reachflag = true;
+			this.pageNum = 1;
+			this.list = [];
+			this.getDataFn();
+		})
+		if(e.type&&e.type=='da'){
+			this.daflag=true;
+			this.tabval=e.id
+			this.tablist=[{
+				tit:e.name,
+				val: e.id,
+			}]
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			this.roles=roles;
+			if(roles=='parents'){
+				var newArr=this.$store.state.user.student;
+				if(newArr&&newArr.length){
+					this.tabval=newArr[0].id
+					this.tablist = newArr.map(v => {
+						return {
+							tit:v.studentName,
+							val: v.id,
+						}
+					})
+				}
+				
+			}else if(roles=='teacher'){
+				// 选择班级
+				var newArr=this.$store.state.user.teacherClass;
+				if(newArr&&newArr.length){
+					this.tabval=newArr[0].classId
+					this.tablist = newArr.map(v => {
+						return {
+							tit:v.className,
+							val: v.classId,
+						}
+					})
+				}
+			}else{
+				var id=this.$store.state.user.deptId;
+				this.getclassListFn(id)
+			}	
+		}
+		this.init()
+		this.getDataFn()
+	},
+	methods:{
+		checkPermi,checkRole,
+		getclassListFn(id){
+			getDeptList(id).then(res=>{
+				if(res.code==200){
+					var newArr=res.data;
+					if(newArr&&newArr.length){
+						this.tabval=newArr[0].deptId
+						this.tablist = newArr.map(v => {
+							return {
+								tit: v.deptName,
+								val: v.deptId,
+
+							}
+						})
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		init(){
+			//心理健康状态
+			getDictionaryFn('qjlx').then(res=>{
+				if(res.code==200){
+					this.qjlxrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		getLook(e) {
+			if (this.actidx == e) {
+				this.actidx = -1
+			} else {
+				this.actidx = e;
+			}
+		},
+		toTree2(arr){
+			var list=this.list;
+			let newA = JSON.parse(JSON.stringify(arr));
+			if(list&&list.length){
+				list.forEach(ite=>{
+					for(var i =0;i<newA.length;i++){
+						if(ite.ayear === newA[i].ayear&&ite.amonth === newA[i].amonth){
+							ite.children.push(newA[i])
+						}else{
+							var obj={
+								ayear:newA[i].ayear,
+								amonth:newA[i].amonth,
+								check:true,
+								children:[]
+							}
+							obj.children.push(newA[i])
+							list.push(obj)
+						}
+					}
+				})
+				return list
+			}else{
+				var newArrs = [];
+				var larr=[]
+				const map = new Map();
+				newArrs = newA.filter(v => !map.has(v.ayear)&&!map.has(v.amonth) && map.set(v.ayear, 1)&& map.set(v.amonth, 1));
+				newArrs.forEach(ite=>{
+					var obj={
+						ayear:ite.ayear,
+						amonth:ite.amonth,
+						check:true
+					}
+					larr.push(obj)
+				})
+				larr.forEach(ite=>{
+					ite.children = newA.filter(e => {
+					    return ite.ayear === e.ayear&&ite.amonth === e.amonth
+					})
+				})
+				return larr
+			}
+		},
+		getAdd(){
+			this.$tab.navigateTo(`/mine/pages/files/leave`)
+		},
+		getTab(idx){
+			this.tabval=idx;
+			this.list=[];
+			this.reachflag=true;
+			this.pageNum=1;
+			this.getDataFn();
+		},
+		getDel(id){
+			var that=this;
+			getleaveDelFn(id).then(res=>{
+				if (res.code == 200) {
+					that.$toast('删除成功')
+						setTimeout(function(){
+							that.reachflag = true;
+							that.pageNum = 1;
+							that.list = [];
+							that.getDataFn();
+						},1500)
+				} else {
+					that.$toast(res.msg)
+				} 
+			})
+		},
+		getDataFn(a) {
+			var params = {
+				pageSize: this.pageSize,
+				pageNum: this.pageNum,
+			}
+			if(this.roles=='parents'){
+				params.absenteeId=this.tabval
+			}else{
+				params.classId=this.tabval
+			}
+			getleaveListFn(params).then(res => {
+				if (res.code == 200) {
+					this.total = res.total;
+					if (res.rows.length < this.pageSize) {
+						this.reachflag = false
+						this.wtdt = '到底了~';
+					} else {
+						var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -1)
+						if (num < res.total) {
+							this.reachflag = true
+							this.wtdt = '上拉加载更多'
+						} else {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						}
+					}
+					// 数据处理
+					var newArr=res.rows;
+					if(newArr&&newArr.length){
+						var timeArr=[];
+						Object.keys(newArr).some((key) => {
+							if(newArr[key].submitTime){
+								var time=newArr[key].submitTime.split(' ');
+								var a=time[0].split('-')
+								newArr[key].ayear=a[0];
+								newArr[key].amonth=a[1];
+							}
+							
+						})
+						this.list=this.toTree2(newArr)
+					}else{
+						this.list=[]
+					}
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.mind{padding: 100rpx 36rpx 0rpx;min-height: 100vh;background-color: #ffffff;box-sizing: border-box;
+	.mbtn{position: fixed;left: 0;right: 0;bottom: 0;height: 100rpx;display: flex;align-items: center;justify-content: center;z-index: 2;background: #1f57e6;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;}
+	.top{height: 96rpx;border-bottom: 2rpx solid #E5E5E5;position: fixed;top: 0;left: 0;right: 0;overflow-x: scroll;display: flex;align-items: center;z-index: 1;background-color: #ffffff;
+		.top_t{position: relative;font-size: 30rpx;font-weight: 500;color: #AAAAAA;height: 94rpx;line-height: 94rpx;padding:0 20rpx;flex:1 0 auto;text-align: center;
+			&.act{color: #161616;font-weight: bold;
+				.line{display: block;}
+				// &::after{content: '';width: 42rpx;height: 10rpx;background: #1f57e6;border-radius: 6rpx;position: absolute;left: 50%;margin-left: -21rpx;bottom: 12rpx;}
+			}
+			&.top_tda{flex: 0 0 auto !important;padding: 0 40rpx;}
+			.line{width: 40rpx;height: 12rpx;position: absolute;left: 50%;margin-left: -20rpx;bottom: 16rpx;display: none;}
+		}
+	}
+}
+
+</style>

+ 582 - 0
mine/pages/files/map.vue

@@ -0,0 +1,582 @@
+<template>
+	<view class="setbox">
+		<map
+			id="container"
+			class="map"
+			:latitude="center.lat"
+			:longitude="center.lng"
+			@poitap="onClcikImgMap"
+			@tap="onClcikImgMap"
+			:markers="covers"
+			scale="15"
+			:style="'width: 750rpx;height:' + mapheight + 'px;'"
+		></map>
+
+		<view class="maptop">
+			<view class="maptopflex">
+				<image :src="serimg" class="maptopimg"></image>
+				<input  class="maptopint" id="tipInputs" v-model="searchtxt"  @input="searchKeyword" placeholder="请输入地点进行查找" />
+			</view>
+			<!-- 地图联想 -->
+			<view class="addrSearch_list" >
+				<view class="addrSearch_item" v-for="(item, index) in searchList" :key="index" @click="handleAddrClick(item)" >
+					<view class="wrap_name">
+						<!-- #ifdef H5 -->
+						<text class="wrap_text">{{item.name.substring(0, item.name.indexOf(searchtxt))}}</text>
+							<text class="wrap_text" style="color: #2797FF;">{{searchtxt}}</text>
+							<text class="wrap_text">{{item.name.substring(item.name.indexOf(searchtxt) + searchtxt.length)}}</text>
+						<!-- #endif -->
+						<!-- #ifndef H5 -->
+						<rich-text :nodes="richNodes(item)"></rich-text>
+						<!-- #endif -->
+					</view>
+					<view class="wrap_addr">
+						<text class="wrap_addrs">{{ item.addr }}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="mapfot">
+			<view class="mapfott"><text class="mapfottit">标点位置</text></view>
+			<view class="mapfotx">
+				<image :src="adrimg" class="mapfotimg"></image>
+				<text class="mapfottxt" v-if="address">{{ address }}</text>
+			</view>
+			<view class="mapfotn" @click="getSureFn"><text class="mapfotntit">确定</text></view>
+		</view>
+	</view>
+</template>
+
+<script>
+import myAmapFun from '@/utils/initmap.js';
+import self from "@/utils/location.js"
+
+	export default{
+		data(){
+			return{
+				serimg:require("@/mine/static/score/serch.png"),
+				adrimg:require("@/mine/static/score/adress.png"),
+				mapimg:require("@/mine/static/score/map.png"),
+				// center:{
+				// 	lng:'117.211954',
+				// 	lat:'31.839676',
+				// },
+				center:{
+					lng:'',
+					lat:'',
+				},
+				mapflag:false,
+				// userId: this.$store.state.user.userId,
+				// deptId: this.$store.state.user.deptId,
+				address:'',
+				searchtxt:'',
+				type:'add',//新增还是修改,
+				placeSearchComponent:'',
+				autoCompleteComponent:'',
+				map:'',
+				covers: [{
+					id:0,
+					latitude: '',
+					longitude: '',
+					width:68,   //宽
+					height:68,   //高
+					iconPath: require("@/mine/static/score/map.png"),
+					anchor:{x: 0.5, y: 0.5}
+				}],
+				mapheight:0,
+				mapContext:"",
+				searchList:[],
+				focus:false,
+				location:'',
+				setflag:false,
+			}
+		},
+		onReady() {
+			this.getcreateMap()
+		},
+		onLoad(e) {
+			if(e.type=='update'){
+				this.type='update'
+				this.center.lng=e.lng;
+				this.center.lat=e.lat;
+				this.address=e.address;
+			}else{
+				if(e.address){
+					this.type='update'
+					this.center.lng=e.lng;
+					this.center.lat=e.lat;
+					this.address=e.address;
+				}else{
+					this.type='add';
+				}
+				
+			}
+			if(e.fromurl){
+				this.fromurl=e.fromurl
+			}
+		},
+		onShow() {
+			var that=this;
+			if(this.setflag){
+				this.setflag=false;
+				// #ifndef H5
+				this.getlocationadr()
+				// uni.getSetting({
+				// 	success(res) {
+				// 		if(res.authSetting['scope.userLocation'] != undefined){
+				// 			if (res.authSetting['scope.userLocation']) {
+				// 				// 已经授权,可以直接调用 getLocation 获取地理位置
+				// 				that.getlocation()
+				// 				that.setflag=false;
+				// 			} else {
+				// 				that.$modal.confirm('确定开启定位授权?').then(() => {
+				// 					that.setflag=true;
+				// 				  uni.openSetting({
+				// 				  	success(res2) {
+				// 				  		if (res2.authSetting['scope.userLocation']) {
+								  			
+				// 				  		}
+				// 				  	}
+				// 				  });
+				// 				})
+				// 			};
+				// 		}
+				// 	},
+				// 	fail(err) {
+				// 	},
+				// })
+				// #endif
+			}
+		},
+		mounted() {
+			var that=this;
+			this.getinfo();
+			if(this.type=='add'){
+				// #ifndef H5
+				this.getlocationadr()
+				// #endif
+			}else{				
+				var lng=this.center.lng;
+				var lat=this.center.lat;
+				that.covers = [];
+				that.covers = [{
+					id:1,
+					latitude: lat,
+					longitude: lng,
+					width:68,   //宽
+					height:68,   //高
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef MP-WEIXIN
+				that.getCity(lat,  lng)
+				// #endif
+			}
+		},
+		methods:{
+			// 获取定位
+			getlocationadr(){
+				var that=this;
+				self.getLocation(function(res){
+					if(res==-1){
+						that.setflag=true
+					}else{
+						that.center.lng=res.lng;
+						that.center.lat=res.lat;
+						that.address=res.address;
+						that.covers = [];
+						that.covers = [{
+							id:4,
+							width:68,   //宽
+							height:68,   //高
+							latitude: res.lat,
+							longitude: res.lng,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+						var newobj={
+							lng:res.lng,
+							lat:res.lat,
+							address:res.address
+						}
+						self.setUxLocation(newobj)
+					}	
+				})
+			},
+			getSureFn(){
+				var address={
+					address:this.address,
+					lng:this.center.lng,
+					lat:this.center.lat,
+				}
+				uni.$emit('refreshaddr',address);
+				uni.navigateBack({delta: 1});	
+			},
+			searchKeyword(){
+				var that=this;
+				if(this.searchtxt){
+					// #ifdef H5
+					AMap.plugin('AMap.PlaceSearch', function(){
+						let autoOptions = {
+							city:'全国',
+							citylimit: true,
+							pageIndex: 1,
+							pageSize: 20,
+						}
+						let placeSearch = new AMap.PlaceSearch(autoOptions);
+						placeSearch.search(that.searchtxt, function(status, result) {
+							// 搜索成功时,result即是对应的匹配数据
+							if (status === 'complete' && result.info === 'OK') {
+								let items = result.poiList.pois;
+								if(items.length > 0){
+									var pois = [];
+									for (let i in items) {
+										var obj = {
+											"name": items[i].name,
+											"addr": items[i].address,
+											"lng": items[i].location.lng,
+											"lat": items[i].location.lat
+										};
+										pois.push(obj);
+									}
+									that.searchList = pois;
+								}
+							}else{
+								that.searchList = [];
+							}
+						})
+					})
+					// #endif
+
+					// #ifndef H5
+					myAmapFun.getInputtips({
+						keywords: that.searchtxt,
+						city: '全国',
+						citylimit: true,
+						success: function(result){
+							console.log(result,124)
+							if(result.tips.length > 0){
+								let pois = [];
+								let items = result.tips;
+								for (let i in items) {
+									if(items[i].location&&items[i].location.length>0){
+										var lnglat = items[i].location.split(',');
+										var obj = {
+											"name": items[i].name,
+											"addr": items[i].district + items[i].address,
+											"lng": lnglat[0],
+											"lat": lnglat[1]
+										};
+										pois.push(obj);
+									}
+								}
+								that.searchList = pois;
+							}else{
+								that.searchList = [];
+							}
+						},
+						fail: function(info){
+							that.searchList = [];
+							console.log('fail-search', info)
+						}
+					})
+					// #endif
+				}
+			},
+			handleAddrClick(addr){
+				var that=this;
+				var lng=addr.lng;
+				var lat=addr.lat;
+				that.center.lng=lng;
+				that.center.lat=lat;
+				that.covers = [];
+				that.covers = [{
+					id:2,
+					width:68,   //宽
+					height:68,   //高
+					latitude: addr.lat,
+					longitude: addr.lng,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// that.address=addr.name || addr.addr;
+				that.address=addr.addr + addr.name;
+				that.searchList=[];
+				// #ifdef MP-WEIXIN
+				that.getCity(lat,  lng)
+				// #endif
+			},
+			richNodes(item){
+			return [{
+				children: [
+					{
+				type: 'text',
+				attrs: {
+				class:'wrap_text'
+				},
+				text: item.name.substring(0, item.name.indexOf(this.searchtxt))
+				},
+				{
+				type: 'text',
+				attrs: {
+				class:'wrap_texts'
+				},
+				text: this.searchtxt
+				},
+				{
+				type: 'text',
+				attrs: {
+				class:'wrap_text'
+				},
+				text: item.name.substring(item.name.indexOf(this.searchtxt) + this.searchtxt.length)
+				}
+				]
+			}]
+			},
+			// 获取当前屏幕信息
+			getinfo(){
+				var that=this;
+				uni.getSystemInfo({
+					success(e) {
+						that.mapheight=e.windowHeight;
+					},
+				})
+			},
+			getcreateMap(){
+				//mapId 就是你在 map 标签中定义的 id
+				this.mapContext = uni.createMapContext('container', this);
+			},
+			onClcikImgMap(e) {
+				var that=this;
+				var lng=e.detail.longitude;
+				var lat=e.detail.latitude;
+				that.center.lng=lng;
+				that.center.lat=lat;
+				that.covers = [];
+				that.covers = [{
+					id:3,
+					width:68,   //宽
+					height:68,   //高
+					latitude: e.detail.latitude,
+					longitude: e.detail.longitude,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef MP-WEIXIN
+				that.getCity(lat,  lng)
+				// #endif
+			},
+			//获取中心点
+			getCenterLanLat() {
+				var that = this;
+					this.mapContext.getCenterLocation({
+					  type: 'gcj02',
+					  success: res => {
+					    that.center.lng=res.longitude;
+					    that.center.lat=res.latitude;
+						that.covers = [];
+						that.covers = [{
+							id:4,
+							width:68,   //宽
+							height:68,   //高
+							latitude: e.detail.latitude,
+							longitude: e.detail.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+					    // #ifdef MP-WEIXIN
+						
+					    that.getCity(res.latitude,  res.longitude)
+					    // #endif
+					  },
+					  fail: err => {
+					    console.log('获取当前地图中心的经纬度2', err);
+					  },
+					});
+
+			},
+			getCity(latitude, longitude,idx) {
+				var that = this;
+				that.location = `${longitude},${latitude}`
+
+				myAmapFun.getRegeo({
+				//如果经纬度有问题会导致不进入回调方法,从而报错
+					location: that.location,
+					success: function(e) {
+						//成功回调
+						that.address='';
+						that.address = e[0].regeocodeData.formatted_address; //详细地址
+						// 存起来
+						if(idx&&idx==1){
+							var newobj={
+								lng:longitude,
+								lat:latitude,
+								address:that.address
+							}
+							self.setUxLocation(newobj)
+						}
+					},
+					fail: function(info) {
+						//失败回调
+						console.log(info)
+					}
+				})
+			},
+			// 获取定位
+			getlocation(){
+				var that = this;
+				uni.getLocation({
+					type: 'gcj02',
+					geocode: true,
+					success: function(res) {
+						that.center.lng=res.longitude;
+						that.center.lat=res.latitude;
+						that.covers = [];
+						that.covers = [{
+							id:4,
+							width:68,   //宽
+							height:68,   //高
+							latitude: res.latitude,
+							longitude: res.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+						// #ifdef MP-WEIXIN
+						that.getCity(res.latitude,  res.longitude,1)
+						// #endif
+						
+						// #ifdef H5
+						var adr= address.province+address.city+address.district+address.street+address.streetNum+address.poiName
+						// that.address=res.longitude
+						that.address=adr
+						// #endif
+
+					},
+					fail: function(red) {
+						uni.showToast({
+							title:"获取定位失败"
+						})
+					},
+				})
+			},
+			// 点击刷新方法
+			refresh(e){
+				this.getlocation();
+			},
+
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.maptop {
+	position: fixed;
+	left: 34rpx;
+	right: 34rpx;
+	top: 24rpx;
+}
+.maptopflex {
+	display: flex;
+	align-items: center;
+	padding: 0 32rpx;
+	box-sizing: border-box;
+	flex-direction: row;
+	width: 684rpx;
+	height: 84rpx;
+	background: #ffffff;
+	box-shadow: 0px 0px 12rpx 0px rgba(75, 75, 75, 0.35);
+	border-radius: 6rpx;
+	margin-bottom: 10rpx;
+}
+.maptopimg {
+	width: 36rpx;
+	height: 38rpx;
+	margin-right: 16rpx;
+}
+.maptopint {
+	font-size: 32rpx;
+	color: #666666;
+	flex: 1;
+	height: 84rpx;
+}
+.mapfot {
+	position: fixed;
+	left: 34rpx;
+	right: 34rpx;
+	bottom: 24rpx;
+	background: #fff;
+	box-shadow: 0px 0px 12rpx 0px rgba(75, 75, 75, 0.35);
+	border-radius: 6rpx;
+	padding: 40rpx 32rpx 32rpx;
+	min-height: 300rpx;
+}
+.mapfott {
+	margin-bottom: 28rpx;
+}
+.mapfottit {
+	font-size: 33rpx;
+	font-weight: bold;
+	color: #343434;
+}
+.mapfotx {
+	display: flex;
+	margin-bottom: 32rpx;
+	min-height: 70rpx;
+	flex-direction: row;
+}
+
+.mapfotimg {
+	width: 26rpx;
+	height: 28rpx;
+	flex: 0 0 auto;
+	margin-right: 12rpx;
+}
+.mapfottxt {
+	flex: 1;
+	font-size: 32rpx;
+	color: #343434;
+	line-height: 32rpx;
+}
+.mapfotn {
+	width: 618rpx;
+	height: 76rpx;
+	background: #1678ff;
+	border-radius: 6rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+.mapfotntit {
+	font-size: 34rpx;
+	color: #fff;
+}
+
+.addrSearch_item {
+	border-bottom: 2upx solid #f5f5f5;
+	padding: 4upx;
+	background: #ffffff;
+}
+.addrSearch_item .wrap_name {
+	display: flex;
+	flex-direction: row !important;
+}
+.wrap_text {
+	font-size: 34upx;
+	color: #151515;
+	line-height: 40upx;
+}
+.wrap_texts{
+	font-size: 34upx;
+	color: #2797FF;
+	line-height: 40upx;
+}
+.addrSearch_item .wrap_addr {
+	margin-top: 2upx;
+}
+.wrap_addrs {
+	font-size: 28upx;
+	color: #999;
+	line-height: 32upx;
+}
+</style>

+ 575 - 0
mine/pages/files/maps.nvue

@@ -0,0 +1,575 @@
+<template>
+	<view class="setbox">
+		<map
+			id="container"
+			class="map"
+			:latitude="center.lat"
+			:longitude="center.lng"
+			@poitap="onClcikImgMap"
+			@tap="onClcikImgMap"
+			:markers="covers"
+			scale="15"
+			:style="'width: 750rpx;height:' + mapheight + 'px;'"
+		></map>
+
+		<view class="maptop">
+			<view class="maptopflex">
+				<image :src="serimg" class="maptopimg"></image>
+				<input ref='input' class="maptopint" id="tipInputs" v-model="searchtxt" @blur="getBlur" @input="searchKeyword" placeholder="请输入地点进行查找" />
+			</view>
+			<!-- 地图联想 -->
+			<view class="addrSearch_list" >
+				<view class="addrSearch_item" v-for="(item, index) in searchList" :key="index" @click="handleAddrClick(item)" >
+					<view class="wrap_name">
+						<!-- #ifdef H5 -->
+						<text class="wrap_text">{{item.name.substring(0, item.name.indexOf(searchtxt))}}</text>
+							<text class="wrap_text" style="color: #2797FF;">{{searchtxt}}</text>
+							<text class="wrap_text">{{item.name.substring(item.name.indexOf(searchtxt) + searchtxt.length)}}</text>
+						<!-- #endif -->
+						<!-- #ifndef H5 -->
+						<rich-text :nodes="richNodes(item)"></rich-text>
+						<!-- #endif -->
+					</view>
+					<view class="wrap_addr">
+						<text class="wrap_addrs">{{ item.addr }}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="mapfot">
+			<view class="mapfott"><text class="mapfottit">标点位置</text></view>
+			<view class="mapfotx">
+				<image :src="adrimg" class="mapfotimg"></image>
+				<text class="mapfottxt" v-if="address">{{ address }}</text>
+			</view>
+			<view class="mapfotn" @click="getSureFn"><text class="mapfotntit">确定</text></view>
+		</view>
+	</view>
+</template>
+
+<script>
+import myAmapFun from '@/utils/initmap.js';
+import amapFile from '@/plugins/amap-wx.js';
+import self from "@/utils/location.js";
+// #ifdef APP-PLUS
+// var myAmapFun = new amapFile.AMapWX({
+// 	key: 'ccbe52b1ec5f66295fa4609c90a819b7',
+// 	batch: true
+// 	});
+// #endif
+	export default{
+		data(){
+			return{
+				serimg:require("@/mine/static/score/serch.png"),
+				adrimg:require("@/mine/static/score/adress.png"),
+				mapimg:require("@/mine/static/score/map.png"),
+				// center:{
+				// 	lng:'117.211954',
+				// 	lat:'31.839676',
+				// },
+				center:{
+					lng:'',
+					lat:'',
+				},
+				mapflag:false,
+				// userId: this.$store.state.user.userId,
+				// deptId: this.$store.state.user.deptId,
+				address:'',
+				searchtxt:'',
+				type:'add',//新增还是修改,
+				placeSearchComponent:'',
+				autoCompleteComponent:'',
+				map:'',
+				covers: [{
+					id:0,
+					latitude: '',
+					longitude: '',
+					width:68,   //宽
+					height:68,   //高
+					iconPath: require("@/mine/static/score/map.png"),
+					anchor:{x: 0.5, y: 0.5}
+				}],
+				mapheight:0,
+				mapContext:"",
+				searchList:[],
+				focus:false,
+				location:'',
+				setflag:false,
+			}
+		},
+		onReady() {
+			this.getcreateMap()
+		},
+		onShow() {
+			var that=this;
+			if(this.setflag){
+				this.setflag=false;
+				// #ifndef H5
+				this.getlocationadr()
+				// #endif
+			}
+		},
+		onLoad(e) {
+			if(e.type=='update'){
+				this.type='update'
+				this.center.lng=e.lng;
+				this.center.lat=e.lat;
+				this.address=e.address;
+			}else{
+				if(e.address){
+					this.type='update'
+					this.center.lng=e.lng;
+					this.center.lat=e.lat;
+					this.address=e.address;
+				}else{
+					this.type='add';
+				}
+				
+			}
+			if(e.fromurl){
+				this.fromurl=e.fromurl
+			}
+		},
+		mounted() {
+			var that=this;
+			this.getinfo();
+			if(this.type=='add'){
+				this.getlocationadr()
+			}else{				
+				var lng=this.center.lng;
+				var lat=this.center.lat;
+				that.covers = [];
+				that.covers = [{
+					id:1,
+					latitude: lat,
+					longitude: lng,
+					width:68,   //宽
+					height:68,   //高
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef APP
+				that.getCity(lat,  lng)
+				// #endif
+			}
+		},
+		methods:{
+			getBlur(){
+				
+			},
+			getSureFn(){
+				var address={
+					address:this.address,
+					lng:this.center.lng,
+					lat:this.center.lat,
+				}
+				uni.$emit('refreshaddr',address);
+				uni.navigateBack({delta: 1});	
+			},
+			getNextFn(){
+				var address={
+						address:this.address,
+						lng:this.center.lng,
+						lat:this.center.lat,
+					}
+					uni.$emit('refreshaddr',address);
+					uni.navigateBack({delta: 1});	
+			},
+			searchKeyword(){
+				var that=this;
+				if(this.searchtxt){
+					// #ifdef H5
+					AMap.plugin('AMap.PlaceSearch', function(){
+						let autoOptions = {
+							city:'全国',
+							citylimit: true,
+							pageIndex: 1,
+							pageSize: 20,
+						}
+						let placeSearch = new AMap.PlaceSearch(autoOptions);
+						placeSearch.search(that.searchtxt, function(status, result) {
+							// 搜索成功时,result即是对应的匹配数据
+							if (status === 'complete' && result.info === 'OK') {
+								let items = result.poiList.pois;
+								if(items.length > 0){
+									var pois = [];
+									for (let i in items) {
+										var obj = {
+											"name": items[i].name,
+											"addr": items[i].address,
+											"lng": items[i].location.lng,
+											"lat": items[i].location.lat
+										};
+										pois.push(obj);
+									}
+									that.searchList = pois;
+								}
+							}else{
+								that.searchList = [];
+							}
+						})
+					})
+					// #endif
+
+					// #ifndef H5
+					myAmapFun.getInputtips({
+						keywords: that.searchtxt,
+						city: '全国',
+						citylimit: true,
+						success: function(result){
+							if(result.tips.length > 0){
+								let pois = [];
+								let items = result.tips;
+								for (let i in items) {
+									if(items[i].location&&items[i].location.length>0){
+										var lnglat = items[i].location.split(',');
+										var obj = {
+											"name": items[i].name,
+											"addr": items[i].district + items[i].address,
+											"lng": lnglat[0],
+											"lat": lnglat[1]
+										};
+										pois.push(obj);
+									}
+								}
+								that.searchList = pois;
+							}else{
+								that.searchList = [];
+							}
+						},
+						fail: function(info){
+							that.searchList = [];
+							console.log('fail-search', info)
+						}
+					})
+					// #endif
+				}
+			},
+			handleAddrClick(addr){
+				var that=this;
+				var lng=addr.lng;
+				var lat=addr.lat;
+				that.center.lng=lng;
+				that.center.lat=lat;
+				that.covers = [];
+				that.covers = [{
+					id:2,
+					width:68,   //宽
+					height:68,   //高
+					latitude: addr.lat,
+					longitude: addr.lng,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef APP
+				that.address=addr.name || addr.addr;
+				that.searchList=[];
+				that.$refs.input.blur()
+				that.getCity(lat,  lng)
+				// #endif
+			},
+			richNodes(item){
+			return [{
+				children: [
+					{
+				type: 'text',
+				attrs: {
+				class:'wrap_text'
+				},
+				text: item.name.substring(0, item.name.indexOf(this.searchtxt))
+				},
+				{
+				type: 'text',
+				attrs: {
+				class:'wrap_texts'
+				},
+				text: this.searchtxt
+				},
+				{
+				type: 'text',
+				attrs: {
+				class:'wrap_text'
+				},
+				text: item.name.substring(item.name.indexOf(this.searchtxt) + this.searchtxt.length)
+				}
+				]
+			}]
+			},
+			// 获取当前屏幕信息
+			getinfo(){
+				var that=this;
+				uni.getSystemInfo({
+					success(e) {
+						that.mapheight=e.windowHeight;
+					},
+				})
+			},
+			getcreateMap(){
+				//mapId 就是你在 map 标签中定义的 id
+				this.mapContext = uni.createMapContext('container', this);
+			},
+			onClcikImgMap(e) {
+				var that=this;
+				var lng=e.detail.longitude;
+				var lat=e.detail.latitude;
+				that.center.lng=lng;
+				that.center.lat=lat;
+				that.covers = [];
+				that.covers = [{
+					id:3,
+					width:68,   //宽
+					height:68,   //高
+					latitude: e.detail.latitude,
+					longitude: e.detail.longitude,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef APP
+				that.getCity(lat,  lng)
+				// #endif
+			},
+			//获取中心点
+			getCenterLanLat() {
+				var that = this;
+					this.mapContext.getCenterLocation({
+					  type: 'gcj02',
+					  success: res => {
+					    that.center.lng=res.longitude;
+					    that.center.lat=res.latitude;
+						that.covers = [];
+						that.covers = [{
+							id:4,
+							width:68,   //宽
+							height:68,   //高
+							latitude: e.detail.latitude,
+							longitude: e.detail.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+					    // #ifdef APP
+						
+					    that.getCity(res.latitude,  res.longitude)
+					    // #endif
+					  },
+					  fail: err => {
+					    console.log('获取当前地图中心的经纬度2', err);
+					  },
+					});
+
+			},
+			getCity(latitude, longitude,idx) {
+				var that = this;
+				that.location = `${longitude},${latitude}`
+
+				myAmapFun.getRegeo({
+				//如果经纬度有问题会导致不进入回调方法,从而报错
+					location: that.location,
+					success: function(e) {
+						//成功回调
+						that.address='';
+						that.address = e[0].regeocodeData.formatted_address; //详细地址
+						// 存起来
+						if(idx&&idx==1){
+							var newobj={
+								lng:longitude,
+								lat:latitude,
+								address:that.address
+							}
+							self.setUxLocation(newobj)
+						}
+					},
+					fail: function(info) {
+						//失败回调
+						console.log(info)
+					}
+				})
+			},
+			// 获取定位
+			getlocationadr(){
+				var that=this;
+				self.getLocation(function(res){
+					if(res==-1){
+						that.setflag=true
+					}else{
+						that.center.lng=res.lng;
+						that.center.lat=res.lat;
+						that.address=res.address;
+						that.covers = [];
+						that.covers = [{
+							id:4,
+							width:68,   //宽
+							height:68,   //高
+							latitude: res.lat,
+							longitude: res.lng,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+						var newobj={
+							lng:res.lng,
+							lat:res.lat,
+							address:res.address
+						}
+						self.setUxLocation(newobj)
+					}	
+				})
+			},
+			getlocation(){
+				var that = this;
+				uni.getLocation({
+					type: 'gcj02',
+					geocode: true,
+					success: function(res) {
+						that.center.lng=res.longitude;
+						that.center.lat=res.latitude;
+						that.covers = [];
+						that.covers = [{
+							id:4,
+							width:68,   //宽
+							height:68,   //高
+							latitude: res.latitude,
+							longitude: res.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+						// #ifdef MP-WEIXIN
+						that.getCity(res.latitude,  res.longitude,1)
+						// #endif
+						
+						// #ifdef H5
+						var adr= address.province+address.city+address.district+address.street+address.streetNum+address.poiName
+						// that.address=res.longitude
+						that.address=adr
+						// #endif
+						// #ifdef APP
+						that.getCity(res.latitude,  res.longitude)
+						// #endif
+
+					},
+					fail: function(red) {
+						uni.showToast({
+							title:"获取定位失败"
+						})
+					},
+				})
+			},
+			// 点击刷新方法
+			refresh(e){
+				this.getlocation();
+			},
+
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.maptop {
+	position: fixed;
+	left: 34rpx;
+	right: 34rpx;
+	top: 24rpx;
+}
+.maptopflex {
+	display: flex;
+	align-items: center;
+	padding: 0 32rpx;
+	box-sizing: border-box;
+	flex-direction: row;
+	width: 684rpx;
+	height: 84rpx;
+	background: #ffffff;
+	box-shadow: 0px 0px 12rpx 0px rgba(75, 75, 75, 0.35);
+	border-radius: 6rpx;
+	margin-bottom: 10rpx;
+}
+.maptopimg {
+	width: 36rpx;
+	height: 38rpx;
+	margin-right: 16rpx;
+}
+.maptopint {
+	font-size: 32rpx;
+	color: #666666;
+	flex: 1;
+	height: 84rpx;
+}
+.mapfot {
+	position: fixed;
+	left: 34rpx;
+	right: 34rpx;
+	bottom: 24rpx;
+	background: #fff;
+	box-shadow: 0px 0px 12rpx 0px rgba(75, 75, 75, 0.35);
+	border-radius: 6rpx;
+	padding: 40rpx 32rpx 32rpx;
+	min-height: 300rpx;
+}
+.mapfott {
+	margin-bottom: 28rpx;
+}
+.mapfottit {
+	font-size: 33rpx;
+	font-weight: bold;
+	color: #343434;
+}
+.mapfotx {
+	display: flex;
+	margin-bottom: 32rpx;
+	min-height: 70rpx;
+	flex-direction: row;
+}
+
+.mapfotimg {
+	width: 26rpx;
+	height: 28rpx;
+	flex: 0 0 auto;
+	margin-right: 12rpx;
+}
+.mapfottxt {
+	flex: 1;
+	font-size: 32rpx;
+	color: #343434;
+	line-height: 32rpx;
+}
+.mapfotn {
+	width: 618rpx;
+	height: 76rpx;
+	background: #1678ff;
+	border-radius: 6rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+.mapfotntit {
+	font-size: 34rpx;
+	color: #fff;
+}
+
+.addrSearch_item {
+	border-bottom: 2upx solid #f5f5f5;
+	padding: 4upx;
+	background: #ffffff;
+}
+.addrSearch_item .wrap_name {
+	display: flex;
+	flex-direction: row !important;
+}
+.wrap_text {
+	font-size: 34upx;
+	color: #151515;
+	line-height: 40upx;
+}
+.wrap_texts{
+	font-size: 34upx;
+	color: #2797FF;
+	line-height: 40upx;
+}
+.addrSearch_item .wrap_addr {
+	margin-top: 2upx;
+}
+.wrap_addrs {
+	font-size: 28upx;
+	color: #999;
+	line-height: 32upx;
+}
+</style>

+ 158 - 0
mine/pages/files/mind.vue

@@ -0,0 +1,158 @@
+<template>
+  <view class="mind">
+	  <picker range-key="dictLabel" :disabled="daflag||studentlist.length<1" :range="studentlist"  :value="nameidx"  @change="bindDateChangea">
+	  		  <view class="flexc mibox mb20">
+	  			  <view class="tit" style="margin-bottom: 0;">人员</view>
+	  			  <view class="f15 flex1 txr co16" v-if="name" >{{name}}</view>
+	  			  <view class="f15 flex1 txr coa" v-else >请选择人员</view>
+	  			  <image :src="rimg" class="rimg"></image>
+	  		  </view>
+	  </picker>
+	  <picker range-key="dictLabel" :range="xlhealthrange"  :value="mindidx"  @change="bindDateChanged">
+		  <view class="flexc mibox mb20">
+			  <view class="tit" style="margin-bottom: 0;">心理健康状态</view>
+			  <view class="f15 flex1 txr co16" v-if="mind" >{{mind}}</view>
+			  <view class="f15 flex1 txr coa" v-else >请选择心理健康状态</view>
+			  <image :src="rimg" class="rimg"></image>
+		  </view>
+	  </picker>
+	  <view class='mibox'>
+		<view class="tit">心理健康描述</view>
+		<textarea placeholder="请输入心理健康描述详情…" v-model="psychologicalDescription" :auto-height="autoHeight"></textarea>
+	  </view>
+	  <view class="rebtn mt30" @click="getSubmit">确认</view>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {getmindAddFn} from "@/api/mine/files.js"
+  export default {
+	data(){
+		return{
+			rimg:require("@/mine/static/score/rimg.png"),
+			autoHeight:true,
+			xlhealthrange:[],
+			mindidx:0,
+			mind:'',
+			datainfo:{
+				
+			},
+			roles:'',
+			studentlist:[],
+			name:'',
+			nameidx:0,
+			studentId:'',
+			psychologicalDescription:'',
+			daflag:false,
+		}
+	},
+	onLoad: function(e) {
+		this.init();
+		if(e.type&&e.type=='daup'){
+			this.name=e.name;
+			this.studentId=e.id;
+			this.daflag=true;
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			var newArr=this.$store.state.user.student;
+			if(newArr&&newArr.length){
+				if(newArr&&newArr.length>1){
+					this.studentlist = newArr.map(v => {
+						return {
+							dictLabel:v.studentName,
+							dictValue: v.id,
+						}
+					})
+				}else{
+					// 一个娃
+					this.name=newArr[0].studentName
+					this.studentId=newArr[0].id
+				}
+			}
+			
+		}
+	},
+	methods:{
+		init(){
+			//心理健康状态
+			getDictionaryFn('psychology').then(res=>{
+				if(res.code==200){
+					this.xlhealthrange = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		bindDateChangea(e){
+			var idx=e.detail.value
+			this.name=this.studentlist[idx].dictLabel
+			this.studentId=this.studentlist[idx].dictValue
+		},
+		bindDateChanged(e){
+		 	var idx=e.detail.value
+		 	this.mind=this.xlhealthrange[idx].dictLabel
+		},
+		getSubmit(){
+			// 学生 id
+			var roles=this.$store.state.user.choseroles;
+			
+			var that=this;
+			if(!this.studentId){
+				this.$toast('请选择人员')
+				return
+			}
+			if(!this.mind){
+				this.$toast('请选择心理健康状态')
+				return
+			}
+			var params={
+				studentId:this.studentId,
+				mind:this.mind,
+				psychologicalDescription:this.psychologicalDescription
+			}
+			if(roles=='teacher'){
+				params.createType='2'
+			}else if(roles=='parents'){
+				params.createType='1'
+			}
+			getmindAddFn(params).then(res => {
+				if (res.code == 200) {
+					that.$toast('新增成功')
+					setTimeout(function() {
+						if(that.daflag){
+							uni.$emit('refreshdalist');
+							uni.redirectTo({
+								url:'/mine/pages/files/mindlist?type=da&id='+that.studentId+'&name='+that.name
+							})
+						}else{
+							uni.$emit('refreshmindlist');
+							uni.navigateBack({
+								delta:1
+							})
+						}
+					}, 1500)
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.mind{
+	min-height: 100vh;background: #ffffff;padding: 80rpx 60rpx;
+	.mibox{
+		.tit{font-size: 32rpx;font-weight: 500;color: #161616;margin-bottom: 40rpx;}
+		textarea{border: 2rpx solid #FFB132;border-radius: 20rpx;width: 100%;min-height: 230rpx;padding:32rpx;box-sizing: border-box;}
+		.rimg{width: 14rpx;height: 24rpx;flex: 0 0 auto;margin-left: 12rpx;}
+	}
+}
+</style>

+ 214 - 0
mine/pages/files/mindlist.vue

@@ -0,0 +1,214 @@
+<template>
+  <view class="mind">
+	  <!-- tab栏 切孩子 -->
+	  <view class="top ">
+	  		<view class="top_t" @click="getTab(ite.val)" :class="[tabval==ite.val?'act':'',daflag?'top_tda':'']" v-for="(ite,idx) in studentlist" :key="idx">{{ite.tit}}<image :src="tapline" class="line"></image></view>
+	  </view>
+	  <view class="pt12">
+		  <xl-list :datype='datype' :datalist="list" :wtdt="wtdt" @getDel="getDel"></xl-list>
+	  </view>
+	  <view style="height: 100rpx;" v-if="checkPermi(['mind:old:add'])&&!daflag"></view>
+	  <view class="mbtn" @click="getAdd" v-if="checkPermi(['mind:old:add'])&&!daflag">更新心理健康状态</view>
+  </view>
+</template>
+
+<script>
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+	import xlList from "@/mine/components/list/list.vue"
+	import {getmindListFn,getmindDelFn} from "@/api/mine/files.js"
+  export default {
+	  components:{
+		  xlList
+	  },
+	data(){
+		return{
+			sucimg:require("@/mine/static/score/ncheck.png"),
+			tapline:require("@/static/images/hline.png"),
+			list:[],
+			datype:5,
+			pageSize: 10,
+			pageNum: 1,
+			reachflag: true,
+			wtdt: '',
+			tabval:'',
+			actidx:-1,
+			daflag:false,
+			studentlist:[]
+		}
+	},
+	onUnload() {
+		uni.$off('refreshmindlist')
+	},
+	onReachBottom() {
+		if (this.reachflag) {
+			this.pageNum++
+			this.getDataFn()
+		}
+	},
+	onLoad: function(e) {
+		uni.$on('refreshmindlist', (e) => {
+			this.reachflag = true;
+			this.pageNum = 1;
+			this.list = [];
+			this.getDataFn();
+		})
+		if(e.type&&e.type=='da'){
+			this.daflag=true;
+			this.tabval=e.id
+			this.studentlist=[{
+				tit:e.name,
+				val: e.id,
+			}]
+		}else{
+			var roles=this.$store.state.user.choseroles;
+			var newArr=this.$store.state.user.student;
+			this.tabval=newArr[0].id
+			this.studentlist = newArr.map(v => {
+				return {
+					tit:v.studentName,
+					val: v.id,
+				}
+			})
+		}
+		this.getDataFn()
+	},
+	methods:{
+		checkPermi,checkRole,
+		getLook(e) {
+			if (this.actidx == e) {
+				this.actidx = -1
+			} else {
+				this.actidx = e;
+			}
+		},
+		getAdd(){
+			this.$tab.navigateTo(`/mine/pages/files/mind`)
+		},
+		getTab(idx){
+			this.tabval=idx;
+			this.list=[];
+			this.reachflag=true;
+			this.pageNum=1;
+			this.getDataFn();
+		},
+		getDel(id){
+			var that=this;
+			getmindDelFn(id).then(res=>{
+				if (res.code == 200) {
+					that.$toast('删除成功')
+						setTimeout(function(){
+							that.reachflag = true;
+							that.pageNum = 1;
+							that.list = [];
+							that.getDataFn();
+						},1500)
+				} else {
+					that.$toast(res.msg)
+				} 
+			})
+		},
+		toTree2(arr){
+			var list=this.list;
+			let newA = JSON.parse(JSON.stringify(arr));
+			if(list&&list.length){
+				list.forEach(ite=>{
+					for(var i =0;i<newA.length;i++){
+						if(ite.ayear === newA[i].ayear&&ite.amonth === newA[i].amonth){
+							ite.children.push(newA[i])
+						}else{
+							var obj={
+								ayear:newA[i].ayear,
+								amonth:newA[i].amonth,
+								check:true,
+								children:[]
+							}
+							obj.children.push(newA[i])
+							list.push(obj)
+						}
+					}
+				})
+				return list
+			}else{
+				var newArrs = [];
+				var larr=[]
+				const map = new Map();
+				newArrs = newA.filter(v => !map.has(v.ayear)&&!map.has(v.amonth) && map.set(v.ayear, 1)&& map.set(v.amonth, 1));
+				newArrs.forEach(ite=>{
+					var obj={
+						ayear:ite.ayear,
+						amonth:ite.amonth,
+						check:true
+					}
+					larr.push(obj)
+				})
+				larr.forEach(ite=>{
+					ite.children = newA.filter(e => {
+					    return ite.ayear === e.ayear&&ite.amonth === e.amonth
+					})
+				})
+				return larr
+			}
+		},
+		getDataFn(a) {
+			var params = {
+				pageSize: this.pageSize,
+				pageNum: this.pageNum,
+				studentId:this.tabval
+			}
+			getmindListFn(params).then(res => {
+				if (res.code == 200) {
+					this.total = res.total;
+					if (res.rows.length < this.pageSize) {
+						this.reachflag = false
+						this.wtdt = '到底了~';
+					} else {
+						var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -1)
+						if (num < res.total) {
+							this.reachflag = true
+							this.wtdt = '上拉加载更多'
+						} else {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						}
+					}
+					// 数据处理
+					var newArr=res.rows;
+					if(newArr&&newArr.length){
+						var timeArr=[];
+						Object.keys(newArr).some((key) => {
+							var time=newArr[key].createTime.split(' ');
+							var a=time[0].split('-')
+							newArr[key].ayear=a[0];
+							newArr[key].amonth=a[1];
+						})
+						this.list=this.toTree2(newArr)
+					}else{
+						this.list=[]
+					}
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.mind{padding: 100rpx 36rpx 0rpx;min-height: 100vh;background-color: #ffffff;box-sizing: border-box;
+	.mbtn{position: fixed;left: 0;right: 0;bottom: 0;height: 100rpx;display: flex;align-items: center;justify-content: center;z-index: 2;background: #1f57e6;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;}
+	.top{height: 96rpx;border-bottom: 2rpx solid #E5E5E5;position: fixed;top: 0;left: 0;right: 0;overflow-x: scroll;display: flex;align-items: center;z-index: 1;background-color: #ffffff;
+		.top_t{position: relative;font-size: 30rpx;font-weight: 500;color: #AAAAAA;height: 94rpx;line-height: 94rpx;padding:0 20rpx;flex:1 0 auto;text-align: center;
+			&.act{color: #161616;font-weight: bold;
+				.line{display: block;}
+				// &::after{content: '';width: 42rpx;height: 10rpx;background: #1f57e6;border-radius: 6rpx;position: absolute;left: 50%;margin-left: -21rpx;bottom: 12rpx;}
+			}
+			&.top_tda{flex: 0 0 auto !important;padding: 0 40rpx;}
+			.line{width: 40rpx;height: 12rpx;position: absolute;left: 50%;margin-left: -20rpx;bottom: 16rpx;display: none;}
+		}
+	}
+}
+
+</style>

+ 365 - 0
mine/pages/files/student.vue

@@ -0,0 +1,365 @@
+<template>
+	<view class="filebox">
+		<!-- 老师有 -->
+		<!-- 防溺水系统 -->
+		
+		<view class="fnbox flex0 bg2" v-if="joinflag">
+			<image :src="fziconb"></image>已加入防溺水计划
+		</view>
+		<view class="fnbox flex0 bg1" v-else @click="getJoinFn">
+			<image :src="fzicona"></image>加入防溺水计划
+		</view>
+		<view class="stutop" v-if="roles!='parents'">
+			<view class="search flexc mb12">
+				<image :src="searchimg" class="img"></image>
+				<input placeholder="输入学生姓名进行搜索" v-model="name" class="flex1 input" />
+				<view class="btn" @click="getSearch">搜索</view>
+			</view>
+			<view class="stutoa flexcj mb10">
+				<view class="stutoap">
+					<picker :value="classidx" range-key="className" :range="classlist" @change="bindDateChange">
+						<view class="flexc">
+							<view class=" f15 co16 f500">{{className||'请选择班级'}}</view>
+							<image :src="upimg"></image>
+						</view>
+					</picker>
+				</view>
+				<view class="stutoap">
+					<picker :value="isNearsidx" range-key="text" :range="ynrange" @change="bindDateChangea">
+						<view class="flexc">
+							<view class=" f15 co16 f500">{{isNearsightednessname||'近视/远视'}}</view>
+							<image :src="upimg"></image>
+						</view>
+					</picker>
+				</view>
+				<view class="stutoap">
+					<picker :value="isMedicalidx" range-key="text" :range="ywrange" @change="bindDateChangeb">
+						<view class="flexc">
+							<view class=" f15 co16 f500">{{isMedicalHistoryname||'有无病史'}}</view>
+							<image :src="upimg"></image>
+						</view>
+					</picker>
+				</view>
+			</view>
+			<view class="stutoar flex0">
+				当前班级学生共有<text>{{count.zs||0}}</text>名;其中男生<text>{{count.nan||0}}</text>名;女生<text>{{count.nv||0}}</text>名; 近视/远视<text>{{count.js||0}}</text>人;留守儿童<text>{{count.ls||0}}</text>人;家庭贫困<text>{{count.pk||0}}</text>人;
+			</view>
+		</view>
+		<view class="flex1 workbox">
+			<view class="workboxr">
+				<scroll-view scroll-y class="scroll-view"  lower-threshold="40" @scrolltolower="reach_btn">
+					<da-list :roles="roles" :datalist="list" :wtdt="wtdt" datype="1" @getDetail="getDetail" @getHeightFn="getHeightFn"></da-list>
+					<view style="height: 100rpx;"></view>
+				</scroll-view>
+			</view>
+		</view>
+		<!-- 家长 -->
+		<!-- v-if="checkPermi(['student:info:add'])" -->
+		<view class="addbtn" @click="getAdd" >添加
+			<block v-if="roles!='parents'">学生</block>
+			<block v-else>孩子</block>
+		档案</view>
+		<pop-up :type='type' :childrens="tablist" :classlist="classlist" @getChose="getChose" @getClose='getClose' @getJoin="getJoin"></pop-up>
+		
+	</view>
+</template>
+
+<script>
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+	import {getDeptList,getselfList} from "@/api/mine/mine.js"
+	import daList from "@/mine/components/list/list.vue"
+	import popUp from "@/mine/components/popup/popup.vue"
+	import {getstuListFn,getstuCountFn} from "@/api/mine/files.js"
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	export default {
+		data() {
+			return {
+				enter: require("@/mine/static/score/enter.png"),
+				searchimg: require("@/mine/static/score/search.png"),
+				upimg: require("@/mine/static/score/up.png"),
+				fzicona: require("@/mine/static/score/fzicona.png"),
+				fziconb: require("@/mine/static/score/fziconb.png"),
+				fziconc: require("@/mine/static/score/fziconc.png"),
+				fzicond: require("@/mine/static/score/fzicond.png"),
+				classlist: [],
+				ynrange:[{"value": 1,"text": "是"	},{"value": 2,"text": "否"}],
+				ywrange:[{"value": 1,"text": "有"	},{"value": 2,"text": "无"}],
+				list: [],
+				pageSize: 10,
+				pageNum: 1,
+				reachflag: true,
+				joinflag:false,
+				wtdt: '',
+				total: 0,
+				className: '',
+				name: '',
+				roles:this.$store.state.user.choseroles,
+				tablist:[],//家长孩子列表,
+				type:0,
+				isNearsightedness:'',
+				isNearsightednessname:'',
+				isMedicalHistory:'',
+				isMedicalHistoryname:'',
+				classidx:0,
+				isNearsidx:0,
+				isMedicalidx:0,
+				count:{},
+				schoolId:''
+			}
+		},
+		components: {
+			daList,popUp
+		},
+		onUnload() {
+			uni.$off('refreshdalist')
+		},
+		onLoad: function() {
+			uni.$on('refreshdalist', (e) => {
+				this.reachflag = true;
+				this.pageNum = 1;
+				this.list = [];
+				this.getDataFn();
+				this.getstuCountFn()
+			})
+			// 判断角色
+			var roles=this.$store.state.user.choseroles;
+			this.roles=roles;
+			if(roles=='parents'){
+				var newArr=this.$store.state.user.student;
+				if(newArr&&newArr.length){
+					// var newArr=res.user.parentsStudent;
+					this.tablist = newArr
+				}
+				this.getDataFn();
+			}else if(roles=='teacher'){
+				var id=this.$store.state.user.schoolId;
+				this.schoolId=id;
+				this.getselfList(id)
+			}else {
+				// 去拿班级部门
+				this.schoolId=this.$store.state.user.deptId;
+				this.getselfList(0)
+			}
+			uni.removeStorageSync('children')
+		},
+		methods: {
+			checkPermi,checkRole,
+			init(){
+				// 
+				getDictionaryFn('sys_subject').then(res=>{
+					if(res.code==200){
+						this.subject = res.data.map(v => {
+							return {
+								dictLabel: v.dictLabel,
+								dictValue: v.dictValue
+							}
+						})
+					}
+				})
+			},
+			getAdd() {
+				this.$tab.navigateTo('/mine/pages/files/addstudent?type=add')
+			},
+			getClose(){
+				this.type=0;
+			},
+			getJoinFn(){
+				this.type=8;
+			},
+			getJoin(){
+				this.type=0;	
+			},
+			getChose(e){
+				var obj={
+					studentId:e.id,
+					name:e.studentName,
+					school:e.schoolName,
+					idCard:e.studentNumber,
+					classId:e.classId
+				}
+				this.type=0;
+				uni.setStorageSync('children',JSON.stringify(obj))
+				this.$tab.navigateTo('/mine/pages/files/addstudent?type=add')
+			},
+			reach_btn() {
+				if (this.reachflag) {
+					this.pageNum++
+					this.getDataFn()
+				}
+			},
+			getselfList(id){
+				var params={
+					parentId:id,
+				}
+				params['params[role]']=this.$store.state.user.choseroles
+				getselfList(params).then(res=>{
+					if(res.code==200){
+						var newArr=res.data;
+						if(newArr&&newArr.length){
+							this.classId=newArr[0].deptId
+							this.className=newArr[0].deptName
+							this.classlist = newArr.map(v => {
+								return {
+									className: v.deptName,
+									classId: v.deptId,
+									schoolId: this.schoolId
+								}
+							})
+							this.getDataFn()
+							this.getstuCountFn()
+						}
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getstuCountFn(){
+				var params = {
+					classId: this.classId,
+				}
+				getstuCountFn(params).then(res=>{
+					if (res.code == 200) {
+						this.count=res.data
+					} else {
+						that.$toast(res.msg)
+					} 
+				})
+			},
+			getDataFn(a) {
+				var params = {
+					pageSize: this.pageSize,
+					pageNum: this.pageNum,
+				}
+				if (this.name) {
+					params.name = this.name
+				}
+				if (this.classId) {
+					params.classId = this.classId
+				}
+				if(this.isNearsightedness){
+					params.isNearsightedness = this.isNearsightedness
+				}
+				if(this.isMedicalHistory){
+					params.isMedicalHistory = this.isMedicalHistory
+				}
+				params['params[role]']=this.$store.state.user.choseroles
+				getstuListFn(params).then(res => {
+					if (res.code == 200) {
+						this.total = res.total;
+						var data=res.rows;
+						data.forEach((ite)=>{
+							if(ite.identificationPhoto&&ite.identificationPhoto.length>0){
+								var narr=ite.identificationPhoto.split(',')
+								ite.identificationPhoto=narr[0]
+							}
+						})
+						if (res.rows.length < this.pageSize) {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						} else {
+							var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -1)
+							if (num < res.total) {
+								this.reachflag = true
+								this.wtdt = '上拉加载更多'
+							} else {
+								this.reachflag = false
+								this.wtdt = '到底了~';
+							}
+						}
+						if (this.pageNum == 1) {
+							this.list = data;
+						} else {
+							this.list = this.list.concat(data)
+						}
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			bindDateChange(e) {
+				var idx = e.detail.value;
+				this.classId = this.classlist[idx].classId;
+				this.className = this.classlist[idx].className;
+				this.pageNum = 1;
+				this.list = [];
+				this.reachflag = true;
+				this.getDataFn()
+				this.getstuCountFn()
+			},
+			bindDateChangea(e){
+				var idx = e.detail.value;
+				this.isNearsightednessname = this.ynrange[idx].text;
+				this.isNearsightedness = this.ynrange[idx].value;
+				this.pageNum = 1;
+				this.list = [];
+				this.reachflag = true;
+				this.getDataFn()
+			},
+			bindDateChangeb(e){
+				var idx = e.detail.value;
+				this.isMedicalHistoryname = this.ynrange[idx].text;
+				this.isMedicalHistory = this.ynrange[idx].value;
+				this.pageNum = 1;
+				this.list = [];
+				this.reachflag = true;
+				this.getDataFn()
+			},
+			
+			getSearch() {
+				this.pageNum = 1;
+				this.list = [];
+				this.reachflag = true;
+				this.getDataFn()
+			},
+			getDetail(id) {
+				this.$tab.navigateTo('/mine/pages/files/detail?id=' + id)
+			},
+			getHeightFn(data){
+				var obj=JSON.parse(JSON.stringify(data))
+				if(obj.type=='height'){
+					this.$tab.navigateTo('/mine/pages/files/height?type=daup&name='+obj.name+'&id='+data.studentId)
+				}else if(obj.type=='mind'){
+					this.$tab.navigateTo('/mine/pages/files/mind?type=daup&name='+obj.name+'&id='+data.studentId)
+				}
+			}
+		},
+
+	}
+</script>
+
+<style lang="scss" scoped>
+.filebox{height: 100vh;background-color: #FFFFFF;display: flex;flex-direction: column;overflow: hidden;}
+.stutop{
+	padding: 28rpx 38rpx 0rpx;background-color: #FFFFFF;flex: 0 0 auto;
+}
+.fnbox{
+	width: 100%;height: 76rpx;display: flex;align-items: center;justify-content: center;font-size: 28rpx;font-weight: bold;
+	&.bg1{background: #FFF4EF;color: #FE4C0E;}
+	&.bg2{background:  #EEF3FE;color: #4775EA;}
+	image{width: 20rpx;height: 26rpx;margin-right: 12rpx;}
+}
+.stutoa{font-size: 28rpx;font-weight: bold;color: #666666;
+	text{color: #4775EA;padding: 0 8rpx;}
+	image{width: 22rpx;height: 12rpx;margin-left: 24rpx;}
+	.stutoap{flex: 1;padding: 16rpx 0;margin: 0 6rpx;}
+}
+.stutoar{font-size: 28rpx;font-weight: 500;color: #666666;
+	text{color: #4775EA;padding: 0 8rpx;font-weight: bold;}
+}
+.search{height: 80rpx;background: #F2F5FB;border-radius: 40rpx;padding-left: 40rpx;
+	.img{width: 30rpx;height: 32rpx;flex:0 0 auto;margin-right: 30rpx;}
+	.btn{width: 120rpx;height: 80rpx;background: #1f57e6;border-radius: 40rpx;font-size: 30rpx;font-weight: 500;
+color: #FFFFFF;text-align: center;line-height: 80rpx;flex:0 0 auto}
+	.input{font-size: 30rpx;color: #161616;line-height: 80rpx;}
+}
+
+.workbox{overflow: auto;
+	.workboxr{height: 100%;display: flex;}
+	.scroll-view{width: 100%;height: 100%;box-sizing: border-box;}
+}
+
+.addbtn{width:100%;
+height: 100rpx;
+background: #1f57e6;position: fixed;left: 0;right: 0;bottom: 0;z-index: 1;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;display: flex;align-items: center;justify-content: center;}
+</style>

+ 197 - 0
mine/pages/files/teacher.vue

@@ -0,0 +1,197 @@
+<template>
+  <view class="filebox">
+	  <!-- 老师有 -->
+	  <view class="stutop">
+		  <view class="search flexc">
+		  	<image :src="searchimg" class="img"></image>
+		  	<input placeholder="输入教职工姓名进行搜索" v-model="name" class="flex1 input"/>
+		  	<view class="btn" @click="getSearch">搜索</view>
+		  </view>
+		  <view class="stutoa flexcj mt12" v-if="choseroles=='school'">
+			 <!-- <view class="flex1">
+				  <picker :value="className" range-key="className" :range="classlist"  @change="bindDateChange" >
+				  	<view class="flexc">
+				  		<view class=" f15 co16 f500" >{{className||'请选择班级'}}</view>
+				  		<image :src="upimg"></image>
+				  	</view>
+				  </picker>
+			  </view> -->
+			  <view class="stutoar flex0">
+				  本校教职工共有<text>{{total}}</text>名
+			  </view>
+		  </view>
+	  </view>  
+	  <!-- 列表 -->
+	  <view class="flex1 workbox">
+	  	<view class="workboxr">
+	  		<scroll-view scroll-y class="scroll-view"  lower-threshold="40" @scrolltolower="reach_btn">
+	  			<da-list :datalist="list" :wtdt="wtdt" datype="2" @getDetail="getDetail"></da-list>
+	  			<view style="height: 100rpx;"></view>
+	  		</scroll-view>
+	  	</view>	
+	  </view>
+	  <view class="addbtn" @click="getAdd" v-if="checkPermi(['teacher:info:add'])">添加教职工档案</view>
+  </view>
+</template>
+
+<script>
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+	import daList from "@/mine/components/list/list.vue"
+	import {getteaListFn} from "@/api/mine/files.js"
+  export default {
+	data(){
+		return{
+			enter:require("@/mine/static/score/enter.png"),
+			searchimg: require("@/mine/static/score/search.png"),
+			upimg:require("@/mine/static/score/up.png"),
+			classlist:[],
+			list:[],
+			pageSize: 10,
+			pageNum: 1,
+			reachflag:true,
+			wtdt:'',
+			total:0,
+			className:'',
+			name:'',
+			choseroles:''
+		}
+	},
+	components:{
+		daList
+	},
+	onUnload(){
+		uni.$off('refreshdalist')
+	},
+	onLoad: function() {
+		uni.$on('refreshdalist',(e) => {
+			this.reachflag=true;
+			this.pageNum=1;
+			this.list=[];
+			this.getDataFn();
+		})
+		this.choseroles=this.$store.state.user.choseroles
+		this.getDataFn();
+	},
+	methods:{
+		checkPermi,checkRole,
+		reach_btn() {
+			if (this.reachflag) {
+				this.pageNum++
+				this.getDataFn()
+			}
+		},
+		getAdd(){
+			this.$tab.navigateTo('/mine/pages/files/addteacher?type=add')
+		},
+		init(){
+			// 职称
+			getDictionaryFn('political_outlook').then(res=>{
+				if(res.code==200){
+					this.outlook = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		getDataFn(a){
+			var params={
+				pageSize:this.pageSize,
+				pageNum: this.pageNum,
+			}
+			if(this.name){
+				params.name=this.name
+			}
+			// if(this.classId){
+			// 	params.classId=this.classId
+			// }
+			params['params[role]']=this.$store.state.user.choseroles
+			getteaListFn(params).then(res=>{
+				if(res.code==200){
+					this.total=res.total;
+					var data=res.rows;
+					data.forEach((ite)=>{
+						if(ite.identificationPhoto&&ite.identificationPhoto.length>0){
+							var narr=ite.identificationPhoto.split(',')
+							ite.identificationPhoto=narr[0]
+						}
+					})
+					if (res.rows.length < this.pageSize) {
+						this.reachflag = false
+						this.wtdt = '到底了~';
+					} else {
+						var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -	1)
+						if (num < res.total) {
+							this.reachflag = true
+							this.wtdt = '上拉加载更多'
+						} else {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						}
+					}
+					if (this.pageNum == 1) {
+						this.list = data;
+					} else {
+						this.list = this.list.concat(data)
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		bindDateChange(e){
+			var idx=e.detail.value;
+			this.classId=this.classlist[idx].classId;
+			this.className=this.classlist[idx].className;
+			this.pageNum=1;
+			this.list=[];
+			this.reachflag=true;
+			this.getDataFn()
+		},
+		getSearch(){
+			this.pageNum=1;
+			this.list=[];
+			this.reachflag=true;
+			this.getDataFn()
+		},
+		getDetail(id){
+			this.$tab.navigateTo('/mine/pages/files/teacherdetail?id='+id)
+		}
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.filebox{height: 100vh;background-color: #FFFFFF;display: flex;flex-direction: column;overflow: hidden;}
+.stutop{
+	padding: 28rpx 38rpx 2rpx;background-color: #FFFFFF;flex: 0 0 auto;
+}
+// 防溺水 心理健康, 记录体重每次信息 
+.stutoa{font-size: 28rpx;font-weight: bold;color: #666666;
+	text{color: #4775EA;padding: 0 8rpx;}
+	image{width: 22rpx;height: 12rpx;margin-left: 24rpx;}
+	.stutoap{flex: 1;padding: 16rpx 0;}
+}
+.stutoar{
+	text{color: #4775EA;padding: 0 8rpx;}
+}
+.search{height: 80rpx;background: #F2F5FB;border-radius: 40rpx;padding-left: 40rpx;
+	.img{width: 30rpx;height: 32rpx;flex:0 0 auto;margin-right: 30rpx;}
+	.btn{width: 120rpx;height: 80rpx;background: #1f57e6;border-radius: 40rpx;font-size: 30rpx;font-weight: 500;
+color: #FFFFFF;text-align: center;line-height: 80rpx;flex:0 0 auto}
+	.input{font-size: 30rpx;color: #161616;line-height: 80rpx;}
+}
+
+.workbox{overflow: auto;
+	.workboxr{height: 100%;display: flex;}
+	.scroll-view{width: 100%;height: 100%;box-sizing: border-box;}
+}
+
+.addbtn{width:100%;
+height: 100rpx;
+background: #1f57e6;position: fixed;left: 0;right: 0;bottom: 0;z-index: 1;font-size: 34rpx;font-weight: 500;
+color: #FFFFFF;display: flex;align-items: center;justify-content: center;}
+</style>

+ 280 - 0
mine/pages/files/teacherdetail.vue

@@ -0,0 +1,280 @@
+<template>
+	<view class="det">
+		<uni-nav-bar left-icon="left" title="档案详情" :background-color="backgroundColor" :border="navborder" statusBar='true' fixed="true" @clickLeft='getBack'>
+		</uni-nav-bar>
+		<view class="det_top"></view>
+		<view class="detbox">
+			<view class="det_list">
+				<image :src="bgimg" class="bgimg"></image>
+			 <view class="tit">基本信息</view>
+				<view class="list">
+				 <view class="ltit">姓名:</view>
+					<view class="ltxt">{{datainfo.name||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">身份证号:</view>
+					<view class="ltxt">{{datainfo.idCard||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">性别:</view>
+					<view class="ltxt">{{datainfo.sex=='1'?'男':'女'||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">年龄:</view>
+					<view class="ltxt">{{datainfo.age||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">政治面貌:</view>
+					<view class="ltxt">{{datainfo.politicalStatus||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">职称:</view>
+					<view class="ltxt">{{datainfo.professional||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">联系方式:</view>
+					<view class="ltxt">{{datainfo.phone||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">居住地址:</view>
+					<view class="ltxt">{{datainfo.address||""}}</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">职业信息</view>
+				<!-- <view class="list">
+					<view class="ltit">教龄:</view>
+					<view class="ltxt">{{datainfo.height||""}}年</view>
+				</view> -->
+				<view class="list">
+					<view class="ltit">入职时间:</view>
+					<view class="ltxt">{{datainfo.onBoardTime||""}}</view>
+				</view>
+				<view class="list">
+					<view class="ltit">参加工作时间:</view>
+					<view class="ltxt">{{datainfo.jobTime||""}}</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">照片信息</view>
+				<view class="list flexcja mb15">
+					<view class="ltit">证件照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in zjfile" :key='index' @click="getPreview(zjfile,index)"></image>
+					</view>
+					
+				</view>
+				<view class="list flexcja">
+					<view class="ltit">门禁照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in mjfile" :key='index' @click="getPreview(mjfile,index)"></image>
+					</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">资质信息</view>
+				<view class="list flexcja mb15">
+					<view class="ltit">毕业证明照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in byzmfile" :key='index' @click="getPreview(byzmfile,index)"></image>
+					</view>	
+				</view>
+				<view class="list flexcja">
+					<view class="ltit">毕业证书照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in byzsfile" :key='index' @click="getPreview(byzsfile,index)"></image>
+					</view>
+				</view>
+				<view class="list flexcja">
+					<view class="ltit">教资证明照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in jzzmfile" :key='index' @click="getPreview(jzzmfile,index)"></image>
+					</view>
+				</view>
+				<view class="list flexcja">
+					<view class="ltit">职称证明照:</view>
+					<view class="imgs">
+						<image :src="baseUrl+item" class="phoimg" v-for="(item,index) in zczmfile" :key='index' @click="getPreview(zczmfile,index)"></image>
+					</view>
+				</view>
+			</view>
+			<view class="det_list">
+				<view class="tit">其他信息</view>
+				<view class="list">
+					<view class="ltit">身高:</view>
+					<view class="ltxt">{{datainfo.height||""}}cm</view>
+				</view>
+				<view class="list">
+					<view class="ltit">体重:</view>
+					<view class="ltxt">{{datainfo.weight||""}}kg</view>
+				</view>
+				<view class="list">
+					<view class="ltit">血型:</view>
+					<view class="ltxt">{{datainfo.bloodType||""}}</view>
+				</view>
+			</view>
+			
+		</view>
+		<view style="height: 170rpx;" v-if="checkPermi(['teacher:info:edit','teacher:info:remove'])"></view>
+		<view class="fbtn" v-if="checkPermi(['teacher:info:edit','teacher:info:remove'])">
+			<view class="rebtndel" @click="getDel" v-if="checkPermi(['teacher:info:remove'])">删除档案</view>
+			<view class="w13 flex0"></view>
+			<view class="rebtn" @click="getUpdate" v-if="checkPermi(['teacher:info:edit'])">修改档案</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
+	import {getteaDetFn,getteaDelFn} from "@/api/mine/files.js"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	export default {
+		data() {
+			return {
+				bgimg: require("@/mine/static/score/bg.png"),
+				backgroundColor: "transparent",
+				navborder: false,
+				id: '',
+				datainfo: '',
+				baseUrl:'',
+				zjfile:[],
+				mjfile:[],
+				byzmfile:[],
+				byzsfile:[],
+				jzzmfile:[],
+				zczmfile:[],
+			}
+		},
+		onUnload(){
+			uni.$off('refreshdadetail')
+		},
+		onLoad: function(e) {
+			uni.$on('refreshdadetail',(e) => {
+				this.getDataFn();
+			})
+			this.id = e.id;
+			this.baseUrl=baseUrl;
+			this.getDataFn()
+		},
+		onPageScroll(e) {
+			var scrollTop = Number(e.scrollTop);
+			if (scrollTop > 0) {
+				this.backgroundColor = '#ffffff'
+			} else {
+				this.backgroundColor = 'transparent'
+			}
+		},
+		methods: {
+			checkPermi,checkRole,
+			getBack(){
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			getDataFn() {
+				getteaDetFn(this.id).then(res => {
+					if (res.code == 200) {
+						this.datainfo = res.data;
+						if(res.data.identificationPhoto){
+							this.zjfile=res.data.identificationPhoto.split(',')
+						}else{
+							this.zjfile=[];
+						}
+						if(res.data.entrancePermit){
+							this.mjfile=res.data.entrancePermit.split(',')
+						}else{
+							this.mjfile=[];
+						}
+						if(res.data.graduationPhoto){
+							this.byzmfile=res.data.graduationPhoto.split(',')
+						}else{
+							this.byzmfile=[];
+						}
+						if(res.data.degreePhoto){
+							this.byzsfile=res.data.degreePhoto.split(',')
+						}else{
+							this.byzsfile=[];
+						}
+						if(res.data.teachingPhoto){
+							this.jzzmfile=res.data.teachingPhoto.split(',')
+						}else{
+							this.jzzmfile=[];
+						}
+						if(res.data.professionalPhoto){
+							this.zczmfile=res.data.professionalPhoto.split(',')
+						}else{
+							this.zczmfile=[];
+						}
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getUpdate(){
+				this.$tab.navigateTo('/mine/pages/files/addteacher?type=update&id='+this.id);	
+			},
+			getDel(){
+				var that=this;
+				this.$modal.confirm('确定删除该信息吗?').then(() => {
+				  getteaDelFn(that.id).then(res=>{
+					 if (res.code == 200) {
+					 	that.$toast('删除成功')
+						setTimeout(function(){
+							uni.$emit('refreshdalist');
+							uni.navigateBack({
+								delta:1
+							})
+						},1500)
+					 } else {
+					 	that.$toast(res.msg)
+					 } 
+				  })
+				})
+			},
+			// 查看照片
+			getPreview(iurl,idx) {
+				var newArr=[];
+				iurl.forEach(ite=>{
+					var ds=this.baseUrl+ite
+					newArr.push(ds)
+				})
+				uni.previewImage({
+					urls: newArr,
+					current:idx,
+					success: function(data) {
+						
+					},
+					fail: function(err) {
+						console.log(err.errMsg);
+					}
+				});
+			},
+		},
+
+	}
+</script>
+
+<style lang="scss" scoped>
+
+.det_top{width: 100%;height: 334rpx;background: linear-gradient(180deg, rgba(222,230,255,0.72) 28.000000000000004%, rgba(232,236,198,0) 100%);}
+.detbox{padding: 0 36rpx;margin-top: -180rpx;padding-bottom: 20rpx;
+	.det_list{background-color: #fff;border-radius: 10rpx;width: 100%;padding: 36rpx 48rpx;position: relative;margin-bottom: 24rpx;
+		.tit{font-size: 32rpx;font-weight: bold;color: #161616;position: relative;margin-bottom: 20rpx;
+		&::before{width: 6rpx;height: 36rpx;background: #1f57e6;border-radius: 4rpx;content: '';position: absolute;left: -24rpx;top: 50%;margin-top: -18rpx;}
+		}
+		.list{
+			display: flex;align-items: flex-start;padding: 10rpx 0;
+			.ltit{flex: 0 0 auto;font-size: 30rpx;color: #161616;font-weight: bold;margin-right:4rpx;}
+			.ltxt{flex: 1;font-size: 30rpx;color: #666666;font-weight: 500;line-height: 40rpx;}
+			.imgs{display: flex;align-items: center;flex-wrap: wrap;justify-content: flex-end;}
+			.phoimg{width: 140rpx;height: 140rpx;margin: 0 0rpx 14rpx 14rpx;}
+		}
+		.bgimg{width: 188rpx;height: 160rpx;position: absolute;right: 46rpx;bottom: 54rpx;}
+	}
+}
+.fbtn{display: flex;align-items: center;position: fixed;left: 0;right: 0;bottom: 0;background-color: #f1f1f1;padding: 36rpx;
+		
+	}
+.det /deep/ .uni-navbar__placeholder{height: 0 !important;}
+</style>

+ 229 - 0
mine/pages/login/query.vue

@@ -0,0 +1,229 @@
+<template>
+  <view class="regbox pt80 " :style="froms=='login'?'':'background-color: #f5f5f5'">
+		
+		<block v-if="froms=='login'">
+			<image :src="sucimg" class="titimg"></image>
+			<view class="search">
+				<view class="f15 co16 fw mb10">手机号码</view>
+				<input placeholder="请输手机号码" v-model="phonenumber"/>
+			</view>
+			<view class="apllytxt"><text>*</text>请输入您注册时填写的手机号码进行查询</view>
+			<view class="rbtn mt40" @click="getQueryLogin">查询</view>
+		</block>
+		<pop-up :type='type' :regdat="regdat" @getregfn="getregfn" @getClose="getClose"></pop-up>
+		<view v-if="showflag||froms=='mine'" class="mt15">
+			<sh-list :datalist='list' :zhtype="zhtype"  @getUpdate="getUpdate" :froms="froms"></sh-list>
+		</view>
+		
+  </view>
+</template>
+
+<script>
+	import popUp from "@/components/popup/popup.vue"
+	import shList from "@/components/shlist/list.vue"
+	import {getqueryFn} from "@/api/mine/register.js"
+  export default {
+	data(){
+		return{
+			sucimg:require("@/mine/static/mine/success.png"),
+			type:0,
+			list:[],
+			zhtype:7,
+			froms:'login',
+			regdat:{},
+			phonenumber:'',
+			showflag:false
+		}
+	},
+	components:{popUp,shList},
+	onUnload(){
+		uni.$off('refreshstulist')
+	},
+	onLoad: function(e) {
+		uni.$on('refreshstulist', (e) => {
+			if(this.froms='mine'){
+				this.reachflag = true;
+				this.pageNum = 1;
+				this.list = [];
+				this.getQuery();
+			}
+		})
+		if(e.from&&e.from=='mine'){
+			this.froms=e.from;
+			this.getQuery();
+		}
+	},
+	methods:{
+		getUpdate(e){
+			// 个人中心才能去修改
+			var id=e.id;
+			var from=this.froms;
+			if(e.zctype=='school'){
+				this.$tab.navigateTo(`/mine/pages/mine/applyregister?type=update&id=${id}&from=${from}`)
+			}else if(e.zctype=='teacher'){
+				this.$tab.navigateTo(`/mine/pages/mine/applyteacher?type=update&id=${id}&from=${from}`)
+			}else if(e.zctype=='parents'){
+				this.$tab.navigateTo(`/mine/pages/mine/applyparent?type=update&id=${id}&from=${from}`)
+			}	
+		},
+		getQueryLogin(){
+			if(!this.phonenumber){
+				this.$toast('请输入手机号')
+				return
+			}
+			let regphone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
+			if(!regphone.test(this.phonenumber)){
+				this.$toast('请输入正确的手机号')
+				return
+			}
+			var params={
+				phonenumber:this.phonenumber
+			}
+			var that=this;
+			that.list=[];
+			 getqueryFn(params).then(res=>{
+				 if(res.code==200){
+					 var a,b,c,isPass;
+					 var dat=res.data;
+					 if(dat.parents||dat.school||dat.teacher){
+						Object.keys(dat).some((key) => {
+							 if(dat[key]&&dat[key].isPass){
+								if (dat[key].isPass == 2) {
+									a=1
+								}
+								if (dat[key].isPass == 3) {
+									b=1
+								}
+								if (dat[key].isPass == 1) {
+									c=1
+								}
+							 }
+						})
+						if(b){
+							//只要有一个拒绝  就展示列表
+							// 展示列表
+							var newArr=[];
+							 Object.keys(dat).some((key) => {
+								 if(key=='parents'){
+									 var nArr=dat[key].registerParentsStudentList;
+									 if(nArr&&nArr.length>0){
+										nArr.forEach(ite=>{
+											var newObja=ite;
+											newObja.zctype=key;
+											newArr.push(newObja)
+										}) 
+									 } 
+								 }else if(key=='school'){
+									 var newObjb=dat[key];
+									 if(newObjb.isPass){
+										newObjb.zctype=key;
+										newArr.push(newObjb) 
+									 } 
+								 }else if(key=='teacher'){
+									 var newObjc=dat[key];
+									 if(newObjc.isPass){
+										newObjc.zctype=key;
+										newArr.push(newObjc) 
+									 }   
+								 }
+							 })
+							 that.showflag=true;
+							 that.list=JSON.parse(JSON.stringify(newArr))	
+						}else if(a){
+							// 通过
+							var regdat={
+								tit:'注册成功',txt:'您提交的注册申请已通过 可前去登录',btn:'去登录',type:2
+							}
+							that.regdat=regdat;
+							that.type=4;	
+						}else if(c){
+							var regdat={
+								tit:'注册审核',txt:'您提交的注册申请待审核 请耐心等待',btn:'取消',type:1
+							}
+							that.regdat=regdat;
+							that.type=4;
+						}else{
+							this.$toast("您还未申请,请先去申请")
+						}
+					 }else{
+						this.$toast("您还未申请,请先去申请")
+					 }
+				 }
+				
+			 })
+		},
+		getQuery(){
+			var phonenumber=this.$store.state.user.phonenumber;
+			 var params={
+				phonenumber:phonenumber
+			 }
+			 var that=this;
+			 getqueryFn(params).then(res=>{
+				 if(res.code==200){
+					 that.typeflag=false;
+					 var a,b,c,isPass;
+					 var nobj=res.data;
+					 var newArr=[];
+					Object.keys(nobj).some((key) => {
+					 if(key=='parents'){
+						 if(nobj[key].isPass){
+							var nArr=nobj[key].registerParentsStudentList;
+							nArr.forEach(ite=>{
+								var newObja=ite;
+								newObja.zctype=key;
+								newArr.push(newObja)
+							}) 
+						 }
+						 
+					 }else if(key=='school'){
+						 if(nobj[key].isPass){
+							 var newObjb=nobj[key];
+							   newObjb.zctype=key;
+							 newArr.push(newObjb)
+						 }
+						 
+					 }else if(key=='teacher'){
+						 if(nobj[key].isPass){
+							var newObjc=nobj[key];
+							  newObjc.zctype=key;
+							newArr.push(newObjc) 
+						 } 
+					 }
+					 this.list=JSON.parse(JSON.stringify(newArr))
+				 })
+				 }
+				
+			 })
+			 
+		 },
+		 getLogin(){
+			  this.$tab.reLaunch(`/pages/login`)
+		 },
+		 getregfn(data){
+			if(data==2){
+		 		this.type = 0;
+		 		this.$tab.reLaunch(`/pages/login`)
+		 	}else{
+		 		this.type = 0
+		 	}
+		 },
+		 getClose(){
+			 this.type=0
+		 },
+		 getConfirm(){
+			 
+		 }
+	},
+  }
+</script>
+
+<style lang="scss" scoped>
+// .regbox{padding: 100rpx 86rpx;background-color: #f5f5f5;
+.regbox{padding:24rpx 36rpx;background-color: #ffffff;
+	.titimg{width: 210rpx;height: 210rpx;margin: 0 auto 28rpx;}
+	.search{
+		input{width: 100%;height: 80rpx;background: #FFFFFF;border: 2rpx solid #FFB132;border-radius: 36rpx;box-sizing: border-box;padding: 0rpx 40rpx;font-size: 30rpx;color: #161616;display: flex;align-items: center;}
+	}
+	.apllytxt{text-align: left;font-size: 26rpx;}
+}
+</style>

+ 209 - 0
mine/pages/login/register.vue

@@ -0,0 +1,209 @@
+<template>
+  <view>
+	  <view class="regbox">
+	  	  <view class="flex1">
+	  		  <image :src="headimg" class="headimg"></image>
+	  		  <image :src="mzimg" class="mzimg"></image>
+	  		  <view class="mt50">
+	  			  <!-- 注册学校账号 -->
+				  <view class="rbtn mb24" @click="getRegister">申请注册</view>
+				  <!-- <button  type="primary" class="rbtn mb24 mt50" open-type="getUserInfo" @getuserinfo="getuserinfo">
+				  	 <view class="rbtn mb24" >申请注册</view>
+				  </button> -->
+	  			 
+	  			<view class="rtxt" @click="getlogin">已有账号,去登录</view>
+	  		  </view>
+	  	  </view>
+		  
+	  	 <view class="apllytxt flex0" @click="getQuery" >已注册,去查询</view>
+	  </view>
+	  <phone-btn :type="typeflag" @getPhoneNumber='getPhoneNumber' @getClose="getClose"></phone-btn>
+	  <pop-up :type='type' :regdat="regdat" @getregfn="getregfn" @getClose="getClose"></pop-up>
+  </view>
+</template>
+
+<script>
+	import popUp from "@/components/popup/popup.vue"
+	import phoneBtn from "@/components/toptab/phonebtn.vue"
+	import {getweChatOpenid} from "@/api/login.js"
+	import {getqueryFn} from "@/api/mine/register.js"
+  export default {
+	  components:{
+		  phoneBtn,popUp
+	  },
+	data(){
+		return{
+			headimg:require('@/static/images/lricon.png'),
+			mzimg:require('@/mine/static/mine/mzicon.png'),
+			typeflag:false,
+			type:0,
+			wxInfo:{},
+			regdat:{},
+			typereg:'register'
+		}
+	},
+	onLoad: function() {
+		if(uni.getStorageSync('wxInfo')){
+			this.wxInfo=JSON.parse(JSON.stringify(uni.getStorageSync('wxInfo')))
+		}
+		uni.removeStorageSync('nopasslist')
+	},
+	methods:{
+		 getlogin(){
+			  this.$tab.reLaunch(`/pages/login`)
+		 },
+		 getClose() {
+		 	this.typeflag = false;
+			this.type=0;
+		 },
+		 getregfn(data){
+			 if(data==2){
+				this.type = 0;
+				this.$tab.reLaunch(`/pages/login`)
+			 }else{
+				this.type = 0
+			 }
+		 },
+		 getRegister(){
+			 this.$tab.navigateTo(`/mine/pages/mine/auth`)
+		 },
+		getPhoneNumber(data){
+			var that=this;
+			getweChatOpenid(data).then(res=>{
+				if(res.code==200){
+					that.typeflag=false;
+					that.wxInfo =res.data
+					uni.setStorageSync('wxInfo', JSON.parse(JSON.stringify(res.data)));
+					// 判断是从哪来的
+					if(that.typereg=='query'){
+						that.getQuery()
+					}else{
+						that.$tab.navigateTo(`/mine/pages/mine/auth`)
+					}
+					
+				}
+				
+			})
+		},
+		 async getuserinfo(e) {
+		 	const {iv,encryptedData} = e.detail
+		 	const {nickName, avatarUrl, ...userInfo} = e.detail.userInfo
+		 	
+		 	try{
+		 			uni.login({
+		            provider: 'weixin',
+		            success: (res) => {
+		                // 获取用户信息
+		 				if(res.code){
+		 					if(this.wxInfo.openId){
+								this.$tab.navigateTo(`/mine/pages/mine/auth`)
+							}else{
+								this.typeflag=true;
+								this.typereg="register"
+							}
+		 				}
+		            }
+		        })
+		 	} catch(e){
+		 		//TODO handle the exception
+		 	}
+		 },
+		 getQuery(){
+			 this.$tab.navigateTo('/mine/pages/login/query')
+			 return
+			 // 原来的获取授权
+			 if(!this.wxInfo.openId){
+				 // 授权
+				uni.getUserProfile({
+					desc: "获取你的昵称、头像、地区及性别",
+					success: (res) => {
+						if(!res.encryptedData || !res.iv){
+							return false;
+						}else{
+							this.typeflag=true;
+							this.typereg="query"
+							return
+						}
+					},
+					fail() {
+						
+					}
+				})
+				return
+			 }
+			 var params={
+				 phonenumber:''
+			 }
+			 var that=this;
+			 getqueryFn(params).then(res=>{
+				 if(res.code==200){
+					 that.typeflag=false;
+					 var a,b,c,isPass;
+					 var dat=res.data;
+					 if(dat.parents||dat.school||dat.teacher){
+						Object.keys(dat).some((key) => {
+							 if(dat[key]&&dat[key].isPass){
+								if (dat[key].isPass == 2) {
+									a=1
+								}
+								if (dat[key].isPass == 3) {
+									b=1
+								}
+								if (dat[key].isPass == 1) {
+									c=1
+								}
+							 }
+						})
+						// uni.setStorageSync("nopasslist",JSON.parse(JSON.stringify(dat)))
+						// that.$tab.navigateTo('/mine/pages/login/query')
+						// return
+						if(b){
+							//只要有一个拒绝  就展示列表
+							// var regdat={
+							// 	tit:'注册失败',txt:'您提交的注册申请未通过 请重新注册',btn:'去注册',type:3,
+							// }
+							// that.regdat=regdat;
+							// that.type=4;
+							// 走列表页面
+							uni.setStorageSync("nopasslist",JSON.parse(JSON.stringify(dat)))
+							that.$tab.navigateTo('/mine/pages/login/query')
+							
+						}else if(a){
+							// 通过
+							var regdat={
+								tit:'注册成功',txt:'您提交的注册申请已通过 可前去登录',btn:'去登录',type:2
+							}
+							that.regdat=regdat;
+							that.type=4;	
+						}else if(c){
+							var regdat={
+								tit:'注册审核',txt:'您提交的注册申请待审核 请耐心等待',btn:'取消',type:1
+							}
+							that.regdat=regdat;
+							that.type=4;
+						}else{
+							this.$toast("您还未申请,请先去申请")
+						}
+						// this.$tab.navigateTo(`/mine/pages/login/query?isPass=${isPass}`)
+						// console.log(a,b,c,isPass)
+					 }else{
+						this.$toast("您还未申请,请先去申请")
+					 }
+				 }
+				
+			 })
+			 
+		 }
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.regbox{padding: 160rpx 56rpx 100rpx;display: flex;flex-direction: column;}
+.headimg{width: 136rpx;height: 136rpx;margin:0 auto 36rpx;}
+.mzimg{width: 100rpx;height: 44rpx;margin: 0 auto ;}
+
+.rtxt{font-size: 32rpx;font-weight: 500;
+color: #4775EA;text-align: center;}
+</style>

+ 51 - 0
mine/pages/login/word.vue

@@ -0,0 +1,51 @@
+<template>
+  <view class="regbox pt80 ">
+		<image :src="wimg" class="titimg"></image>
+		<view class="search">
+			<view class="f15 co16 fw mb20">口令码</view>
+			<input placeholder="请输口令码" v-model="phonenumber"/>
+		</view>
+		<view class="apllytxt"><text>*</text>请输入老师发送的口令码进行班级绑定,建议直接复制 粘贴口令码,以避免输入错误</view>
+		<view class="rbtn mt20" @click="getQueryLogin">确认</view>
+		<pop-up :type='type' :regdat="regdat" @getregfn="getregfn" @getClose="getClose"></pop-up>
+  </view>
+</template>
+
+<script>
+	import popUp from "@/components/popup/popup.vue"
+	import {getqueryFn} from "@/api/mine/register.js"
+  export default {
+	data(){
+		return{
+			wimg:require("@/mine/static/score/word.png"),
+			type:0,
+			list:[],
+			zhtype:7,
+			regdat:{},
+			phonenumber:'',
+			showflag:false
+		}
+	},
+	components:{popUp},
+	onLoad: function(e) {
+		// uni.getClipboardData({
+		// 	success: function (res) {
+		// 		console.log(res.data);
+		// 	}
+		// });
+	},
+	methods:{
+	},
+  }
+</script>
+
+<style lang="scss" scoped>
+// .regbox{padding: 100rpx 86rpx;background-color: #f5f5f5;
+.regbox{padding:72rpx 80rpx;background-color: #ffffff;min-height: 100vh;box-sizing: border-box;
+	.titimg{width: 132rpx;height: 132rpx;margin: 0 auto 120rpx;}
+	.search{
+		input{width: 100%;height: 80rpx;background: #FFFFFF;border: 2rpx solid #FFB132;border-radius: 36rpx;box-sizing: border-box;padding: 0rpx 40rpx;font-size: 30rpx;color: #161616;display: flex;align-items: center;}
+	}
+	.apllytxt{text-align: left;font-size: 26rpx;margin-top: 52rpx;}
+}
+</style>

+ 254 - 0
mine/pages/mine/addclass.vue

@@ -0,0 +1,254 @@
+<template>
+    <view class="content">
+        <view class="user-box">
+        <m-tree
+            class="u-p-l-40"
+            ref="mtree"
+            :defaultProps="defaultProps"
+            :data="tree"
+            :divider="divider"
+            :edit="edit"
+            :unfold="true"
+			:className="className"
+			:njName="njName"
+            @node-click="nodeClick" 
+            @up-item="upNode" 
+            @down-item="downNode" 
+            @add-item="addNode" 
+            @edit-item="editNode" 
+            @delete-item="deleteNode"
+            @finger-action="fingerAction"
+            @long-press="longpressNode"></m-tree>
+        </view>
+    </view>
+</template>
+
+<script>
+	import {getDictionaryFn} from '@/api/mine/register.js'
+	import {getDeptListmine,getDeptaddFn,getDeptupdFn,getDeptdelFn,getDeptList } from "@/api/mine/mine.js"
+    export default {
+        data() {
+            return {
+                /* 
+                tree 数据
+                */
+                defaultProps: {
+                    id: 'deptId',             // 此项为id项的key
+                    children: 'children', // 此项为修改子集数据的key
+                    label: 'deptName' // 此项为修改显示数据的key
+                },
+                divider: false,
+                edit: true,
+				tree:[],
+				trees:[
+					{deptId: 0,deptName: "一年级",children:[{children: [],delFlag: "0",deptId: 132,deptName: "一年级一班",orderNum: 5,parentId: 0,status: "1"}]},
+					{deptId: 1,deptName: "二年级",children:[{children: [],delFlag: "0",deptId: 133,deptName: "二年级一班",orderNum: 5,parentId: 0,status: "1"}]},
+				],
+				className:[],
+				njName:[],
+            }
+        },
+		onLoad: function() {
+			this.getDeptListFn()
+			this.init()
+		},
+        methods: {
+			init(){
+				// 年级
+				getDictionaryFn('nj_name').then(res=>{
+					if(res.code==200){
+						this.njName = res.data.map(v => {
+							return {
+								dictLabel: v.dictLabel,
+								dictValue: v.dictValue
+							}
+						})
+					}
+				})
+				// 班级
+				getDictionaryFn('class_name').then(res=>{
+					if(res.code==200){
+						this.className = res.data.map(v => {
+							return {
+								dictLabel: v.dictLabel,
+								dictValue: v.dictValue
+							}
+						})
+					}
+				})
+			},
+			// 数据处理
+			 toTree2(arr){
+				let newA = JSON.parse(JSON.stringify(arr));
+				let data = newA.filter(item => {
+					item.children = newA.filter(e => {
+					    return item.deptId === e.parentId
+					  })
+					  return !item.parentId
+					})
+									
+					return data
+			},
+			getDeptListFn(){
+				var that=this;
+				var parentId=this.$store.state.user.deptId
+				getDeptListmine().then(res=>{
+					// 处理数据
+					if(res.code==200){
+						var newArr=this.toTree2(res.data);
+						var sArr=[]
+						Object.keys(newArr).some((key) => {
+							if (newArr[key].deptId == ('' + parentId)) {
+								newArr[key].isdel='1';
+								sArr[0]=newArr[key];
+								that.tree=sArr
+								return true;
+							}
+						})	
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+			},
+            //遍历id节点并删除
+            removeNodeData(datas, id){ //遍历树  获取id数组
+              for(var i in datas){
+                if(id===datas[i].id) {
+                    // datas.push(datas[i]);
+                    // console.log('要删除项目:', datas[i].id);
+                    datas.splice(i,1);
+                    break;
+                } else {
+                    if(datas[i].children){  //存在子节点就递归
+                      this.removeNodeData(datas[i].children, id);
+                    }
+                }
+              }
+            },
+            //遍历id节点添加子项
+            addNodeData(datas, id, nodedata){ //遍历树  获取id数组
+                var addflag = false;
+                if(id===0) {
+                    datas.unshift(nodedata);
+                    addflag=true;
+                } else {
+                    for(var i in datas){
+                        // console.log(JSON.stringify(datas[i]));
+                        if(id===datas[i].id) {
+                            // datas.push(datas[i]);
+                            // console.log('要增加项目:', datas[i].id, nodedata);
+                            datas[i].children.unshift(nodedata);
+                            addflag=true;
+                            break;
+                        } else {
+                            if(datas[i].children){  //存在子节点就递归
+                              this.addNodeData(datas[i].children, id, nodedata);
+                            }
+                        }
+                    }
+                }
+                return addflag;
+            },
+            //节点点击事件
+            nodeClick(e) {
+                // console.log('点击的项目', JSON.stringify(e));
+            },
+            //节点up按钮点击事件
+            upNode(e) {
+                const that = this;
+                console.log('upNode');
+                if(e.index!=0){
+                    // 根据自身需求,自行修改数据处理方法;
+
+                    // up上移操作,排序并更新tree中对应元素sort属性
+                    var data = {
+                        pnode: {}, 
+                        itemA: {id: e.items[e.index-1].id, sort: e.items[e.index].sort}, 
+                        itemB: {id: e.items[e.index].id, sort: e.items[e.index-1].sort},
+                    }
+                    that.$refs.mtree.treeSort(that.tree, e.item.pid, data); // 调用组件方法 排序sort 从小到大排序
+
+                }
+            },
+            //节点down按钮点击事件
+            downNode(e) { 
+                const that = this;
+                // console.log('downNode');
+                if(e.index != e.items.length-1){
+                    // 根据自身需求,自行修改数据处理方法;
+
+                    // down下移操作,排序并更新tree中对应元素sort属性
+                    var data = {
+                        pnode: {}, 
+                        itemA: {id: e.items[e.index+1].id, sort: e.items[e.index].sort}, 
+                        itemB: {id: e.items[e.index].id, sort: e.items[e.index+1].sort},
+                    }
+                    that.$refs.mtree.treeSort(that.tree, e.item.pid, data); // 调用组件方法 排序sort 从小到大排序
+                }
+            },
+            //节点新增按钮点击事件
+            addNode(e) {
+				
+				var params=JSON.parse(JSON.stringify(e))
+				getDeptaddFn(params).then(res=>{
+					if(res.code==200){
+						this.$toast('新增成功')
+						// 重置
+						uni.$emit('refreshdatalis');
+						this.getDeptListFn()
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+            },
+            //节点更新按钮点击事件
+            editNode(e) {
+				var params=JSON.parse(JSON.stringify(e))
+				getDeptupdFn(params).then(res=>{
+					if(res.code==200){
+						this.$toast('修改成功')
+						// 重置
+						uni.$emit('refreshdatalis');
+						this.getDeptListFn()
+					}else{
+						this.$toast(res.msg)
+					}
+				})   
+            },
+            //节点删除按钮点击事件
+            deleteNode(e) {
+				
+				var params=JSON.parse(JSON.stringify(e))
+				var deptId=params.deptId
+				getDeptdelFn(deptId).then(res=>{
+					if(res.code==200){
+						this.$toast('删除成功')
+						uni.$emit('refreshdatalis');
+						// 重置
+						this.getDeptListFn()
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+                // console.log('点击的项目delete', JSON.stringify(e));
+            },
+            //节点滑动
+            fingerAction(e) {
+                // console.log('节点滑动fingerAction', JSON.stringify(e));
+            },
+            //节点选线长按事件
+            longpressNode(e) {
+                console.log('长按的项目longpress', JSON.stringify(e));
+            }
+        }
+    }
+</script>
+
+<style lang="scss">
+page{
+    background-color: #ededed;
+}
+.user-box{
+    background-color: #fff;
+}
+</style>

+ 371 - 0
mine/pages/mine/applyparent.vue

@@ -0,0 +1,371 @@
+<template>
+	<view class="regbox flexdc">
+			<uni-forms ref="form" :rules="rulesup" :modelValue="datainfob">
+				<block v-if="froms!='addstu'">
+					<uni-forms-item label="姓名" required name="parentsName">
+						<uni-easyinput :inputBorder="false" v-model="datainfob.parentsName" placeholder="请输入您的姓名">
+						</uni-easyinput>
+						<view class="rimg"></view>
+					</uni-forms-item>
+					<uni-forms-item label="联系方式" required name="parentsPhone">
+						<uni-easyinput :inputBorder="false" v-model="datainfob.parentsPhone" placeholder="请输入您的联系方式">
+						</uni-easyinput>
+						<view class="rimg"></view>
+					</uni-forms-item>
+				</block>
+				
+
+				<!-- 单选 -->
+				<uni-forms-item label="学生姓名" required name="studentName">
+					<uni-easyinput :inputBorder="false" v-model="datainfob.studentName" placeholder="请输入学生姓名">
+					</uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+				<uni-forms-item label="学生身份证号" required name="studentNumber">
+					<uni-easyinput :inputBorder="false" type="number" v-model="datainfob.studentNumber"
+						placeholder="请输入学生身份证号"></uni-easyinput>
+					<view class="rimg"></view>
+				</uni-forms-item>
+				<picker range-key='dictLabel'  :value="xxindex" :range="schoolval" @change='bindDateChangea'>
+					<uni-forms-item label="学校" required name="schoolName">
+						<view class="f16  flex1 txr" :class="datainfob.schoolName?'co16':'coa'">
+							{{datainfob.schoolName||"请选择学校"}}</view>
+						<view class="rimg">
+							<image :src="rimg" class="rimgs"></image>
+						</view>
+					</uni-forms-item>
+				</picker>
+				<picker range-key='dictLabel'  :value="xkindex" :range="classval" @change='bindDateChangeb'>
+					<uni-forms-item label="班级" required name="className">
+						<view class="f16  flex1 txr" :class="datainfob.className?'co16':'coa'">
+							{{datainfob.className||"请选择班级"}}
+						</view>
+						<view class="rimg">
+							<image :src="rimg" class="rimgs"></image>
+						</view>
+					</uni-forms-item>
+				</picker>
+				<view class="line"></view>
+			</uni-forms>
+		<view class="mt26">
+			<view class="rbtn" @click="getSubmit">保存</view>
+			<view class="apllytxt f15" @click="gethome">稍后完善</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDeptList,
+		getDeptListminea
+	} from "@/api/mine/mine.js"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+	import {
+		getToken
+	} from '@/utils/auth'
+	import {
+		getstudentregFn,
+		getstudentdetFn,
+		getstudentputFn
+	} from "@/api/mine/register.js"
+	export default {
+		data() {
+			return {
+				rimg: require("@/static/images/rimg.png"),
+				wimg: require('@/static/images/read.png'),
+				delimg: require('@/static/images/del.png'),
+				addimg: require('@/static/images/add.png'),
+				tcdel: require('@/static/images/tcdel.png'),
+				cyvalue: '',
+				xxindex: 0,
+				bjindex: 0,
+				xkindex: 0,
+				rulebs: {
+					userName: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入姓名',
+						}]
+					},
+					userPhone: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入联系方式',
+						},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]
+					},
+					registerParentsStudentList: {
+						rules: [{
+							required: true,
+							errorMessage: '请填写学生信息',
+						}]
+					}
+				},
+				rulesup: {
+					parentsName: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入姓名',
+						}]
+					},
+					parentsPhone: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入联系方式',
+						},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]
+					},
+					studentName: {
+						rules: [{
+							required: true,
+							errorMessage: '请输入学生姓名',
+						}]
+					},
+					schoolName: {
+						rules: [{
+							required: true,
+							errorMessage: '请选择学校',
+						}]
+					},
+					className: {
+						rules: [{
+							required: true,
+							errorMessage: '请选择班级',
+						}]
+					},
+				},
+				datainfob: {
+					"userName": "",
+					"userPhone": "",
+					"schoolId": "",
+					"schoolName": "",
+					"classId": "",
+					"className": "",
+					"studentName": "",
+					"studentNumber": ""
+					// "registerParentsStudentList": [{
+						
+					// }]
+				},
+				classlist: [{
+					"schoolId": "",
+					"schoolName": "",
+					"classId": "",
+					"className": "",
+					"studentName": "",
+					"studentNumber": ""
+				}],
+				schoolval: [],
+				classval: [],
+				checkidx: -1,
+				id: '',
+				type: 'add', //页面类型 //添加学生
+				froms:'addstu'
+			}
+		},
+		onLoad: function(e) {
+			if(e.from){
+				this.froms=e.from||'addstu';
+			}
+			if (e.type&&e.type == 'update') {
+				this.id = e.id;
+				this.type = e.type;
+				this.getDataFn()
+			}
+			this.getDeptListFn();
+		},
+		methods: {
+			// 学校列表
+			getDeptListFn() {
+				var params = {
+					parentId: 0
+				}
+				getDeptList(0).then(res => {
+					if (res.code == 200) {
+						this.schoolval = res.data.map(v => {
+							return {
+								dictLabel: v.deptName,
+								dictValue: v.deptId,
+								tenantId:v.tenantId
+							}
+						})
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getDataFn() {
+				var params = {
+					id: this.id
+				}
+				getstudentdetFn(this.id).then(res => {
+					if (res.code == 200) {
+						this.datainfob = res.data;
+						var id=res.data.schoolId;
+						this.getclassListFn(id);
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			// 班级
+			getclassListFn(id) {
+				getDeptList(id).then(res => {
+					if (res.code == 200) {
+						this.classval = res.data.map(v => {
+							return {
+								dictLabel: v.deptName,
+								dictValue: v.deptId
+							}
+						})
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getAddFn() {
+				var obj = {
+					"schoolId": "",
+					"schoolName": "",
+					"classId": "",
+					"className": "",
+					"studentName": "",
+					"studentNumber": ""
+				}
+				this.classlist.push(obj);
+			},
+			getDel(idx) {
+				var that = this;
+				uni.showModal({
+					title: '确认删除',
+					content: "是否确认删除",
+					cancelText: '取消删除',
+					confirmText: '确认删除',
+					success: function(res) {
+						if (res.confirm) {
+							that.classlist.splice(idx, 1)
+						} else if (res.cancel) {
+							// console.log('用户点击取消');
+						}
+					}
+				});
+			},
+			getShow(idx) {
+				this.checkidx = idx;
+			},
+			// 选择学校
+			bindDateChangea(e) {
+				var val = e.detail.value;
+				var v = this.schoolval[val];
+				var id = v.dictValue;
+				if (this.datainfob.schoolId != id) {
+					this.datainfob.schoolName = v.dictLabel;
+					this.datainfob.tenantId = v.tenantId
+					this.datainfob.schoolId = id;
+					this.datainfob.className = '';
+					this.datainfob.classId = '';
+					this.getclassListFn(id);
+				}
+			},
+			// 班级
+			bindDateChangeb(e) {
+				var val = e.detail.value;
+				this.datainfob.className = this.classval[val].dictLabel
+				this.datainfob.classId = this.classval[val].dictValue
+			},
+			getSubmit() {
+				var that = this;
+				this.$refs.form.validate().then(res => {
+					var params = JSON.parse(JSON.stringify(this.datainfob))
+					if(!params.studentNumber){
+						this.$toast('请输入学生正确身份证号')
+						return
+					}
+					if(params.studentNumber){
+						let _IDRe18 =
+							/^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
+						let _IDre15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/
+						// 校验身份证:
+						if (_IDRe18.test(params.studentNumber) || _IDre15.test(params.studentNumber)) {
+						}else{
+							this.$toast('请输入学生'+ params.studentName + "正确身份证号")
+							return
+						}
+					}
+					
+					if (this.type == 'add') {
+						getstudentregFn(params).then(res => {
+							if (res.code == 200) {
+								that.$toast(res.msg)
+								setTimeout(function() {
+									uni.$emit('refreshstulist');
+									uni.navigateBack({
+										delta:1
+									})
+								}, 1500)
+							} else {
+								this.$toast(res.msg)
+							}
+						})
+					} else {
+						
+						getstudentputFn(params).then(res => {
+							if (res.code == 200) {
+								that.$toast(res.msg)
+								setTimeout(function() {
+									if(that.froms=='addstu'||that.froms=='mine'){
+										setTimeout(function() {
+											uni.$emit('refreshstulist');
+											uni.navigateBack({
+												delta:1
+											})
+										}, 1500)
+									}else{
+										that.$tab.redirectTo(`/mine/pages/mine/success`)
+									}
+								}, 1500)
+							} else {
+								this.$toast(res.msg)
+							}
+						})
+					}
+
+					// this.$tab.navigateTo(`/mine/pages/mine/success`)
+				})
+
+			},
+			gethome() {
+				this.$tab.reLaunch(`/pages/index/index`)
+			},
+		},
+
+	}
+</script>
+
+<style lang="scss" scoped>
+.regbox{padding: 50rpx 36rpx 80rpx;
+	.apllytxt{font-size:30rpx ;}
+	.line{width: 40rpx;height: 6rpx;background: #FFB132;margin: 60rpx auto 0;}
+	
+	.addbox{font-weight: 500;
+		image{width: 44rpx;height: 44rpx;margin-right: 24rpx;flex: 0 0 auto;}
+	}
+	
+	.delbox{width: 40rpx;height: 40rpx;position: absolute;right: 0;top: -40rpx;
+		image{
+			width: 36rpx;height: 36rpx;
+		}
+	}
+}
+.regbox /deep/ .uni-forms{flex: 1;}
+.regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.regbox /deep/ .uni-forms .uni-forms-item{padding: 28rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+}
+.regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+
+</style>

+ 313 - 0
mine/pages/mine/applyregister.vue

@@ -0,0 +1,313 @@
+<template>
+  <view class="regbox flexdc">
+	  <!-- 登录后不能修改学校 -->
+	 <!-- <uni-forms-item label="学校" required name="schoolName" v-if="from=='mine'">
+	  	<view class="f16  flex1 txr co16">{{variables.schoolName}}</view>
+	  	<view class="rimg">	</view>
+	  </uni-forms-item> -->
+	  <uni-forms  ref="form" :rules="rules" :modelValue="variables" >
+		<!-- <picker  range-key='dictLabel' :value="xxindex" :disabled="froms=='mine'" :range="schoolval" @change='bindDateChangea' >
+			<uni-forms-item label="学校" name="schoolName">
+				<view  class="f16  flex1 txr" :class="variables.schoolName?'co16':'coa'">{{variables.schoolName||'请选择学校'}}</view>
+			<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			</uni-forms-item>
+		</picker> -->
+		<view @click="getSchoolFn">
+			<uni-forms-item label="学校" name="schoolName">
+				<view  class="f16  flex1 txr" :class="variables.schoolName?'co16':'coa'">{{variables.schoolName||'请选择学校'}}</view>
+				<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			</uni-forms-item>
+		</view>
+		<uni-forms-item name="userName" required label="负责人姓名">
+			<uni-easyinput :inputBorder="false" :disabled="froms=='mine'" v-model="variables.userName" placeholder="请输入负责人姓名"></uni-easyinput>
+			<view class="rimg">	</view>
+		</uni-forms-item>
+	  	<uni-forms-item name="userPhone" required label="联系方式">
+	  		<uni-easyinput :inputBorder="false" :disabled="froms=='mine'" type="number" v-model="variables.userPhone" placeholder="请输入您的联系方式"></uni-easyinput>
+			<view class="rimg">	</view>
+	  	</uni-forms-item>
+		<view class="noborder">
+			<uni-forms-item name="registerSchoolFileList"  style='margin-bottom: 0;'>
+				<view class="flexc" style="width: 100%;">
+					<view class="f16 fw co16 flex0 ">上传资质</view>
+					<view class="infolist_a co47" ><lsj-upload
+						    ref="lsjUpload"
+						    childId="upload1"
+						    :width="width"
+						    :height="height"
+						    :option="option"
+						    :size="size"
+							:count="count"
+						    :formats="formats"
+						    :debug="debug"
+						    :instantly="instantly"
+						    @progress=""
+							@uploadEnd="onuploadEnd" >
+						        <view class="btn" :style="{width: width,height: height}">去上传</view>
+						</lsj-upload></view>
+					</view>
+			</uni-forms-item>
+			
+		</view>
+		
+		<view>
+			<view class="cldelistbf flexc"  v-for="(ite,idx) in filelist" :key='idx'>
+				<view class="flext f15 co16 flex1" @click="getDown(ite.url)">
+					<view class="imgl"><image :src="wimg" ></image></view>
+					<view class="tit">{{ite.name}}</view>
+				</view>
+				<!-- 删除 -->
+				<view class="delimg flex0" @click.stop="getDelFj(idx)">
+					<image :src="delimg" class="imgr"></image>
+				</view>
+			</view>
+		</view>
+		<view class="infolist_tit">注:须上传学校法人营业执照,或后期补传</view>
+		<view class="infolist_b"><text>*</text>请上传大小不超过<text>100MB</text>格式为<text>pdf</text>的文件</view>
+	  </uni-forms>
+	  <view>
+	  	<view class="rbtn" @click="getSubmit">提交</view>
+	  	 <view class="apllytxt"><text>*</text>请确认您提交的信息真实有效</view>
+	  </view>
+  </view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	import config from '@/config'
+	 const baseUrl = config.baseUrl
+	 const Clientid = config.Clientid
+	 import { getToken } from '@/utils/auth'
+	 import {getschoolregFn,getschoolDetFn,getschoolPutFn} from "@/api/mine/register.js"
+	 import {getDeptList} from "@/api/mine/mine.js"
+  export default {
+	data(){
+		return{
+			//附件
+			  option: {
+			        // 上传服务器地址,需要替换为你的接口地址
+			        url: baseUrl+'/common/upload', // 该地址非真实路径,需替换为你项目自己的接口地址
+			        // 上传附件的key
+			        name: 'file',
+			        // 根据你接口需求自定义请求头,默认不要写content-type,让浏览器自适配
+			        header: {
+			            // 示例参数可删除
+			            'Authorization':  'Bearer ' + getToken(),
+						'Clientid':  Clientid,
+			        },
+			        // 根据你接口需求自定义body参数
+			        formData: {
+						
+			        }
+			    },
+			// 选择文件后是否立即自动上传,true=选择后立即上传
+			instantly: true,
+			// 必传宽高且宽高应与slot宽高保持一致
+			width: '',
+			height: '44rpx',
+			// 限制允许上传的格式,空串=不限制,默认为空
+			formats: 'pdf',
+			// 文件上传大小限制
+			size: 100,
+			// 文件数量限制 默认10
+			count: 5,
+			// 文件回显列表
+			files: new Map(),
+			// 微信小程序Map对象for循环不显示,所以转成普通数组,不要问为什么,我也不知道
+			wxFiles: [],
+			// 是否打印日志
+			debug: false,
+			filelist:[], 
+			rimg:require("@/static/images/rimg.png"),
+			wimg:require('@/static/images/read.png'),
+			delimg:require('@/static/images/del.png'),
+			cyvalue:'',
+			cyindex:0,
+			cylist:[{label:'是',id:'Y'},{label:'否',id:'N'}],
+			variables:{
+				"schoolName": "",
+				"userName": "",
+				"userPhone": "",
+				"registerSchoolFileList": [],
+			},
+			rules: {
+			  schoolName: {rules: [{required: true,errorMessage: '请输入学校名称'}]},
+			  userName: {rules: [{required: true,errorMessage: '请输入负责人姓名'}]},
+			  userPhone: {rules: [{required: true,errorMessage: '请输入联系方式'},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]},
+			  // registerSchoolFileList: {rules: [{required: true,errorMessage: '请上传附件' } ]},
+			},
+			wxInfo:{},
+			schoolval: [],
+			xxindex:[],
+			id:'',
+			type:'add',//页面类型
+			froms:'',//入口
+			// procDefId:'flow_1se5q74i:17:32545',//流程定义id
+			// deploymentId:'32542',
+			// type:'',//0学校注册 1 家长  2 老师
+		}
+	},
+	onUnload(){
+		uni.$off('refreshschool')
+	},
+	onLoad: function(e) {
+		uni.$on('refreshschool', (e) => {
+			var schoolobj= e;
+			this.variables.schoolId=e.schoolNameId
+			this.variables.schoolName=e.schoolName
+		})
+		if(e.type&&e.type=='update'){
+			this.id=e.id;
+			this.froms=e.from||''
+			this.type=e.type;
+			this.getDataFn()
+		}
+		// if(uni.getStorageSync('wxInfo')){
+		// 	this.wxInfo=JSON.parse(JSON.stringify(uni.getStorageSync('wxInfo')))
+		// 	this.variables.userPhone=this.wxInfo.phoneNumber
+		// }
+		this.getDeptListFn();
+	},
+	methods:{
+		// 选择学校
+		bindDateChangea(e) {
+			var val = e.detail.value;
+			var v = this.schoolval[val];
+			this.variables.schoolName=v.dictLabel
+			this.variables.schoolId=v.dictValue
+		},
+		getSchoolFn(){
+			var v=this.variables
+			this.$tab.navigateTo(`/mine/pages/mine/school?id=`+v.schoolId+'&name='+v.schoolName)
+		},
+		getDataFn(){
+			getschoolDetFn(this.id).then(res=>{
+				if(res.code==200){
+					this.variables=res.data;
+					if(res.data.registerSchoolFileList&&res.data.registerSchoolFileList.length){
+						this.filelist=JSON.parse(JSON.stringify(res.data.registerSchoolFileList))
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		// 学校列表
+		getDeptListFn(){
+			var params={
+				parentId:0
+			}
+			getDeptList(0).then(res=>{
+				if(res.code==200){
+					this.schoolval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId
+						}
+					})
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getSubmit(){
+			var that=this;
+			this.$refs.form.validate().then(res => {
+				var params=JSON.parse(JSON.stringify(that.variables));
+				// params.openId=that.wxInfo.openId;
+				if(that.type=='add'){
+					getschoolregFn(params).then(res=>{
+						if(res.code==200){
+							that.$toast(res.msg)
+							setTimeout(function(){
+							that.$tab.redirectTo(`/mine/pages/mine/success`)	
+							},1500)
+						}else{
+							that.$toast(res.msg)
+						}
+					})
+				}else{
+					getschoolPutFn(params).then(res=>{
+						if(res.code==200){
+							// that.$toast('修改成功')
+							setTimeout(function(){
+							that.$tab.redirectTo(`/mine/pages/mine/success`)	
+							},1500)
+						}else{
+							that.$toast(res.msg)
+						}
+					})
+				}
+				
+			})
+			
+			
+		},
+		 onuploadEnd(item) {
+		 	var newobj={}
+		 	var responseText=JSON.parse(item.responseText)
+		 	// newobj.name=item.name;
+		 	newobj.name=responseText.originalFilename;
+		 	newobj.url=responseText.fileName;
+		 	this.filelist.push(newobj)
+		 		this.variables.registerSchoolFileList=JSON.parse(JSON.stringify(this.filelist))
+		 },
+		 getDelFj(idx){
+		 	this.filelist.splice(idx,1)
+		 		this.variables.registerSchoolFileList=JSON.parse(JSON.stringify(this.filelist))
+		 },
+		 getDown(e){
+		 	uni.showLoading({
+		 		title: '加载中'
+		 	});
+		 	var url=baseUrl+e;
+		 	uni.downloadFile({
+		 		url: url,//文件的下载路径
+		 		success(result) {
+		 				uni.hideLoading()
+		 			var filePath = result.tempFilePath;
+		 			   uni.openDocument({
+		 			     filePath: filePath,
+		 			     showMenu: true,
+		 			     success: function (res) {
+		 			     }
+		 			   });
+		 		},
+		 		fail(res) {uni.hideLoading()}
+		 	})
+		 },
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.infolist_a{height: 44rpx;flex: 1;text-align: right;font-size: 32rpx;}
+
+
+.cldelistbf {
+	padding: 20rpx 24rpx;
+		image{flex: 0 0 auto;}
+		.imgl{width: 40rpx;height: 40rpx;display: flex;align-items: center;justify-content: center;margin-right: 24rpx;
+			image{width: 40rpx;height: 34rpx;}
+		}
+		.imgr{width: 30rpx;height: 30rpx;margin-left: 24rpx;}
+		.tit{line-height: 40rpx;font-size: 32rpx;color: #161616;flex: 1;word-break: break-all;}
+	}
+.infolist_b{color: #aaaaaa;font-size: 26rpx;padding:0 24rpx;margin-top:10rpx;
+	text{word-break: break-all;margin: 0 4rpx;color: #ff0000;}
+}
+.infolist_tit{font-size: 26rpx;padding:0 24rpx;color: #ff0000;margin-top: 36rpx;}
+.regbox{padding: 50rpx 36rpx 80rpx;}
+.regbox /deep/ .uni-forms{flex: 1;}
+.regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.regbox /deep/ .uni-forms .uni-forms-item{padding: 36rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+}
+.regbox /deep/ .uni-forms .noborder  .uni-forms-item{margin-bottom: 0;border-bottom: 0;}
+.regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+</style>

+ 343 - 0
mine/pages/mine/applyteacher.vue

@@ -0,0 +1,343 @@
+<template>
+  <view class="regbox flexdc">
+	  <uni-forms ref="form" :rules="ruleas" :modelValue="datainfo">	
+		<picker  range-key='dictLabel' :value="xxindex" :range="schoolval" @change='bindDateChangea'>
+			<uni-forms-item label="学校" required name="schoolName">
+			<view  class="f16  flex1 txr" :class="datainfo.schoolName?'co16':'coa'">{{datainfo.schoolName||"请选择学校"}}
+			</view>
+			<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			</uni-forms-item>
+		 </picker>
+		 <uni-forms-item label="姓名" required name="userName">
+		 	<uni-easyinput :inputBorder="false" v-model="datainfo.userName" placeholder="请输入您的姓名"></uni-easyinput>
+		 	<view class="rimg"></view>
+		 </uni-forms-item>
+		 <uni-forms-item label="联系方式" required name="userPhone">
+		 	<uni-easyinput :inputBorder="false" v-model="datainfo.userPhone" placeholder="请输入您的联系方式"></uni-easyinput>
+		 	<view class="rimg"></view>
+		 </uni-forms-item>
+		 <!-- 单选 -->
+		 <view v-for="(ite,idx) in classlist" class="pr" :key="idx" @click="getShow(idx)">
+			 <view @click="getDel(idx)" class="delbox" v-if="idx!=0">
+				 <image :src="tcdel"></image>
+			 </view>
+			 <picker  range-key='dictLabel' :value="bjindex" :range="classval" @change='bindDateChangeb'>
+			 	<uni-forms-item label="班级" required name="className" @click="getClass">
+			 		<view  class="f16  flex1 txr" :class="ite.className?'co16':'coa'">{{ite.className||"请选择班级"}}
+			 		</view>
+			 		<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			 	</uni-forms-item>
+			 </picker>
+			 <picker  range-key='dictLabel' :value="xkindex" :range="subject" @change='bindDateChangec'>
+			 	<uni-forms-item label="学科" required name="discipline" >
+			 		<view  class="f16  flex1 txr" :class="ite.discipline?'co16':'coa'">{{ite.discipline||"请选择学科"}}
+			 		</view>
+			 		<view class="rimg"><image :src="rimg" class="rimgs"></image>	</view>
+			 	</uni-forms-item>
+			 </picker>
+			 <view class="line"></view>
+		 </view>
+		 
+		 <view class="addbox f17 co47 flexcc mt26" @click="getAddFn">
+		 	<image :src="addimg"></image>
+		 	新增班级信息
+		 </view>
+		 
+	  </uni-forms>
+	 
+	  <view class="mt26">
+	  	<view class="rbtn" @click="getSubmit">保存</view>
+	  	 <view class="apllytxt f15" @click="gethome">稍后完善</view>
+	  </view>
+  </view>
+</template>
+
+<script>
+	import {getDeptList,getDeptListminea} from "@/api/mine/mine.js"
+	import config from '@/config'
+	 const baseUrl = config.baseUrl
+	 import { getToken } from '@/utils/auth'
+	 import {getSystemType,getteacherregFn,getteacherputFn,getteacherdetFn} from "@/api/mine/register.js"
+	 import {gettenantList} from "@/api/login.js"
+  export default {
+	data(){
+		return{
+			rimg:require("@/static/images/rimg.png"),
+			wimg:require('@/static/images/read.png'),
+			delimg:require('@/static/images/del.png'),
+			addimg:require('@/static/images/add.png'),
+			tcdel:require('@/static/images/tcdel.png'),
+			cyvalue:'',
+			xxindex:0,
+			bjindex:0,
+			xkindex:0,
+			ruleas: {
+			  schoolName: {rules: [{required: true,errorMessage: '请输入学校名称'}]},
+			  userName: {rules: [{required: true,errorMessage: '请输入姓名',}]},
+			  userPhone: {rules: [{required: true,errorMessage: '请输入联系方式'},{pattern:"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",errorMessage: '请输入正确的联系方式'}]},
+			},
+			datainfo:{
+				  "schoolId": "",
+				  "schoolName":"",
+				  "userName":"",
+				  "userPhone":"",
+				  "registerTeacherClassList":[{
+				      "classId":"",
+				      "className":"",
+				      "discipline":""
+				}]
+			},
+			classlist:[{
+				      "classId":"",
+				      "className":"",
+				      "discipline":""
+				  }],
+			schoolval:[],
+			classval:[],
+			subject:[],//学科字典值
+			checkidx:-1,
+			id:'',
+			type:'add',//页面类型
+		}
+	},
+	onLoad: function(e) {
+		if(e.type&&e.type=='update'){
+			this.id=e.id;
+			this.type=e.type;
+			this.getDataFn()
+		}
+		// if(uni.getStorageSync('wxInfo')){
+		// 	this.wxInfo=JSON.parse(JSON.stringify(uni.getStorageSync('wxInfo')))
+		// 	this.datainfo.userPhone=this.wxInfo.phoneNumber
+		// 	this.datainfo.openId=this.wxInfo.openId
+		// }
+		this.getDeptListFn();
+		// this.init()
+	},
+	methods:{
+		getDataFn(){
+			getteacherdetFn(this.id).then(res=>{
+				if(res.code==200){
+					this.datainfo=res.data;
+					var id=res.data.schoolId;
+					this.getclassListFn(id);
+					var tenantId=res.data.tenantId;
+					this.getinit(tenantId)
+					if(res.data.registerTeacherClassList&&res.data.registerTeacherClassList.length>0){
+						this.classlist=res.data.registerTeacherClassList;
+					}else{
+						
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		// 学校列表
+		getDeptListFn(){
+			var params={
+				parentId:0
+			}
+			getDeptList(0).then(res=>{
+				if(res.code==200){
+					this.schoolval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId,
+							tenantId:v.tenantId
+						}
+					})
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		// 班级
+		getclassListFn(id){
+			getDeptList(id).then(res=>{
+				if(res.code==200){
+					this.classval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId
+						}
+					})
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getinit(id){
+			// 学科
+			var params={
+				dictType:'sys_subject',
+				tenantId:id
+			}
+			getSystemType(params).then(res=>{
+				if(res.code==200){
+					this.subject = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		getAddFn(){
+			var obj={
+				    "classId":"",
+				    "className":"",
+				    "discipline":""
+				}
+			this.classlist.push(obj);
+		},
+		getDel(idx){
+			var that=this;
+			uni.showModal({
+				title: '确认删除',
+				content: "是否确认删除",
+				cancelText: '取消删除',
+				confirmText: '确认删除',
+				success: function(res) {
+					if (res.confirm) {
+						that.classlist.splice(idx,1)
+					} else if (res.cancel) {
+						// console.log('用户点击取消');
+					}
+				}
+			});
+		},
+		getShow(idx){
+			this.checkidx=idx;
+		},
+		// 选择学校
+		bindDateChangea(e){
+			var val=e.detail.value;
+			var v=this.schoolval[val];
+			var id=v.dictValue;
+			if(this.datainfo.schoolId!=id){
+				this.datainfo.schoolName=v.dictLabel;
+				this.datainfo.schoolId=id;
+				this.datainfo.tenantId=v.tenantId;
+				this.getclassListFn(id);
+				this.getinit(v.tenantId)
+				var obj={"classId":"","className":"","discipline":""};
+				var newarr=[];
+				newarr.push(obj)
+				this.classlist=JSON.parse(JSON.stringify(newarr))
+			}
+			
+		},
+		// 班级
+		bindDateChangeb(e) {
+			var val=e.detail.value;
+			var idx=this.checkidx;
+			this.classlist[idx].className=this.classval[val].dictLabel
+			this.classlist[idx].classId=this.classval[val].dictValue
+		},
+		// 学科
+		bindDateChangec(e){
+			var val=e.detail.value;
+			var idx=this.checkidx;
+			this.classlist[idx].discipline=this.subject[val].dictLabel
+		},
+		getSubmit(){
+			var that=this;
+			this.$refs.form.validate().then(res => {
+				var list=this.classlist;
+				var newArr = [];
+				var a=0;
+				Object.keys(list).some((key) => {
+					// 去重
+					if (list[key].className && list[key].discipline) {
+						newArr.push(list[key])
+					} else if (list[key].className && !list[key].discipline) {
+						a=1;
+						this.$toast("请选择"+list[key].className+"的学科")
+						return
+					} else {
+						a=1;
+						this.$toast("请选择班级")
+						return
+					}
+				})
+				// 相同班级去重
+				var newArrs = [];
+				const map = new Map();
+				 newArrs = list.filter(v => !map.has(v.classId) && map.set(v.classId, 1));
+				if(newArrs.length<newArr.length){
+					this.$toast("请勿添加同一年级")
+					return
+				}
+				
+				if(a==1){
+					return
+				}
+				var params=JSON.parse(JSON.stringify(this.datainfo))
+				params.registerTeacherClassList=JSON.parse(JSON.stringify(newArr))
+				
+				if(this.type=='add'){
+					getteacherregFn(params).then(res=>{
+						if(res.code==200){
+							that.$toast(res.msg)
+							setTimeout(function(){
+							that.$tab.redirectTo(`/mine/pages/mine/success`)	
+							},1500)
+						}else{
+							this.$toast(res.msg)
+						}
+					})
+				}else{
+					getteacherputFn(params).then(res=>{
+						if(res.code==200){
+							that.$toast(res.msg)
+							setTimeout(function(){
+							that.$tab.redirectTo(`/mine/pages/mine/success`)	
+							},1500)
+						}else{
+							this.$toast(res.msg)
+						}
+					})
+				}
+				
+				// this.$tab.navigateTo(`/mine/pages/mine/success`)
+			})
+			
+		},
+		gethome(){
+			this.$tab.reLaunch(`/pages/index/index`)
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+
+.regbox{padding: 50rpx 36rpx 80rpx;
+	.apllytxt{font-size:30rpx ;}
+	.line{width: 40rpx;height: 6rpx;background: #FFB132;margin: 60rpx auto 0;}
+	
+	.addbox{font-weight: 500;
+		image{width: 44rpx;height: 44rpx;margin-right: 24rpx;flex: 0 0 auto;}
+	}
+	
+	.delbox{width: 40rpx;height: 40rpx;position: absolute;right: 0;top: -40rpx;
+		image{
+			width: 36rpx;height: 36rpx;
+		}
+	}
+}
+.regbox /deep/ .uni-forms{flex: 1;}
+.regbox /deep/ .uni-forms-item__label{flex: 0 0 auto;width: auto !important;font-size: 32rpx;font-weight: bold;
+color: #161616;}
+.regbox /deep/ .uni-forms .uni-forms-item{padding: 28rpx 24rpx 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-bottom: 0;
+	// &:nth-of-type(3){margin-bottom: 0;border-bottom: 0;}
+}
+.regbox /deep/ .uni-forms-item__content{display: flex;align-items: center;flex-direction: row;}
+.regbox /deep/ .uni-easyinput{flex: 1;text-align: right;}
+.regbox /deep/ .uni-easyinput__placeholder-class{font-size: 30rpx;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 30rpx;}
+ .regbox /deep/ .uni-forms-item__error{margin-top:20rpx;left: auto;right: 0;}
+</style>

+ 308 - 0
mine/pages/mine/auth.vue

@@ -0,0 +1,308 @@
+<template>
+	<view>
+		<!-- 角色 -->
+		<view class="regboxa" :style="loginflag?'min-height: 100vh;padding-bottom: 60rpx;':'height: 100vh;'">
+			<view class="reg_top">
+				<image :src="helimg" class="headimg"></image>
+				<view class="txt">请认证您的身份。</view>
+				<!-- 添加 -->
+				<block v-if="!loginflag">
+					<picker range-key="tit" :range="cardTypes"  :value="cardidx"  @change="bindDateChange">
+						<view class="lrlist">
+							<view class="label">身份</view>
+							<view  class="f16  flex1 txr" :class="cardType?'co16':'coa'">{{cardType||"请选择身份"}}</view>
+							<view class="rimg">
+								<image :src="rimg" class="rimgs"></image>
+							</view>
+						</view>
+					</picker>
+					<view class="lines"></view>
+				</block>
+			</view>
+			  
+			<view class="reg_fot">
+				
+			
+			  <block v-if="loginflag">
+				  <block v-for="(ite,idx) in roles" :key="idx">
+					<view class="rabox" @click="getSchoolApply(0,'school')" v-if="ite=='school'">
+						<image :src="mximg"></image>
+						<view @click.stop="gettip">
+							<uni-tooltip :content="xxtip">我是学校管理员<image :src="wimg" class="wicon" ></image></uni-tooltip>
+						</view>
+					</view>
+					<view class="rabox" @click="getSchoolApply(1,'teacher')" v-if="ite=='teacher'">
+						<image :src="mtimg" style="height: 200rpx;"></image>
+						<view @click.stop="gettip">
+							<uni-tooltip :content="lstip">我是老师<image :src="wimg" class="wicon" ></image></uni-tooltip>
+						</view>
+					</view>
+					<view class="rabox" @click="getSchoolApply(2,'parents')" v-if="ite=='parents'">
+						<image :src="mjimg" style="height: 212rpx;"></image>
+						<view @click.stop="gettip">
+							<uni-tooltip :content="jztip">我是家长<image :src="wimg" class="wicon" ></image></uni-tooltip>
+						</view>
+					</view>
+				  </block>
+				
+			  </block>
+			  <block v-else>
+				  <!-- <view class="rabox" @click="getSchoolApply(0)">
+				  		<image :src="mximg"></image>
+				  		<view @click.stop="gettip">
+				  			<uni-tooltip :content="xxtip">我是学校管理员<image :src="wimg" class="wicon" ></image></uni-tooltip>
+				  		</view>
+				  </view>
+				  <view class="rabox" @click="getSchoolApply(2)">
+				  		<image :src="mjimg" style="height: 212rpx;"></image>
+						<view @click.stop="gettip">
+							<uni-tooltip :content="jztip">我是家长<image :src="wimg" class="wicon" ></image></uni-tooltip>
+						</view>
+				  </view>
+				  <view class="rabox" @click="getSchoolApply(1)">
+				  		<image :src="mtimg" style="height: 200rpx;"></image>
+						<view @click.stop="gettip">
+							<uni-tooltip :content="lstip">我是老师<image :src="wimg" class="wicon" ></image></uni-tooltip>
+						</view>
+				  </view> -->
+				  	<block v-if="type==0"><apply-register :schoolval="schoolval" @getschoolregFn="getschoolregFn" :schoolobj="schoolobj"></apply-register></block>
+				  	<block v-if="type==1"><apply-teacher :schoolval="schoolval" :classvals="classval" :subject="subject" @getinit="getinit" @getclassListFn="getclassListFn" @getteacherregFn="getteacherregFn"></apply-teacher></block>
+					<block v-if="type==2"><apply-parent :classvals="classval" :schoolval="schoolval" @getclassListFn="getclassListFn" @getparentsregFn="getparentsregFn"></apply-parent></block>
+				  <!-- <view v-if="registerflag">
+				  </view> -->
+			  </block>
+			</view>
+			<view class="tips" v-if="loginflag">
+				<image :src="tipimg"></image>切换角色时,若不属于同一学校,请先退出后再登录
+			</view>
+		</view>
+		<!-- 注册信息 -->
+		
+	</view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	// import {getflowlistFn,getflowMyFn} from "@/api/mine/register.js"
+	import applyParent from "@/mine/components/login/applyparent.vue"
+	import applyTeacher from "@/mine/components/login/applyteacher.vue"
+	import applyRegister from "@/mine/components/login/applyregister.vue"
+	import { getToken } from '@/utils/auth'
+	import {getDeptList,getDeptListminea} from "@/api/mine/mine.js"
+	import {getparentsregFn,getschoolregFn,getSystemType,getteacherregFn} from "@/api/mine/register.js"
+  export default {
+	  components:{
+		  applyParent,applyTeacher,applyRegister
+	  },
+	data(){
+		return{
+			helimg:require("@/mine/static/mine/hello.png"), 
+			mjimg:require("@/mine/static/mine/mjicon.png"), 
+			mtimg:require("@/mine/static/mine/mticon.png"), 
+			mximg:require("@/mine/static/mine/mxgicon.png"),
+			wimg:require("@/mine/static/mine/shwicon.png"),
+			rimg: require("@/static/images/rimg.png"),
+			tipimg: require("@/mine/static/mine/tip.png"),
+			list:[],
+			loginflag:false,//是否登录
+			roles:'',
+			xxtip:'学校管理员身份',
+			lstip:'老师身份',
+			jztip:'学生家长身份',
+			registerflag:true,
+			schoolval:[],
+			type:-1,
+			cardType:'',
+			classval:[],
+			subject:[],
+			cardTypes:[{tit:'学校管理员',val:0},{tit:'老师',val:1},{tit:'学生家长',val:2},],
+			cardidx:0,
+			schoolobj:{}
+		}
+	},
+	onUnload(){
+		uni.$off('refreshschool')
+	},
+	onLoad: function(e) {
+		uni.$on('refreshschool', (e) => {
+			console.log(e,1)
+			this.schoolobj= e;
+		})
+		// this.init()
+		if (getToken()) {
+			// 判断切换还是新增
+			if(e.type&&e.type=='add'){
+				this.loginflag=false;
+				this.getDeptListFn();
+			}else{
+				// 判断有什么角色
+				var roles=this.$store.state.user.roles;
+				this.loginflag=true;
+				this.roles=roles;
+			}
+		} else {
+		  this.loginflag=false;
+		  this.getDeptListFn();
+		}
+	},
+	methods:{
+		gettip(){
+			
+		},
+		bindDateChange(e){
+			var idx=e.detail.value
+			this.type=this.cardTypes[idx].val;
+			this.cardType=this.cardTypes[idx].tit;
+			this.registerflag=true;
+		},
+		getinit(id){
+			// 学科
+			var params={
+				dictType:'sys_subject',
+				tenantId:id
+			}
+			getSystemType(params).then(res=>{
+				if(res.code==200){
+					this.subject = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		getclassListFn(id) {
+			getDeptList(id).then(res => {
+				if (res.code == 200) {
+					this.classval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId
+						}
+					})
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getparentsregFn(params){
+			var that=this;
+			getparentsregFn(params).then(res => {
+				if (res.code == 200) {
+					that.$toast(res.msg)
+					setTimeout(function() {
+						that.$tab.redirectTo(`/mine/pages/mine/success`)
+					}, 1500)
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getschoolregFn(params){
+			var that=this;
+			getschoolregFn(params).then(res=>{
+				if(res.code==200){
+					that.$toast(res.msg)
+					setTimeout(function(){
+					that.$tab.redirectTo(`/mine/pages/mine/success`)	
+					},1500)
+				}else{
+					that.$toast(res.msg)
+				}
+			})
+		},
+		getteacherregFn(params){
+			var that=this;
+			getteacherregFn(params).then(res=>{
+				if(res.code==200){
+					that.$toast(res.msg)
+					setTimeout(function(){
+					that.$tab.redirectTo(`/mine/pages/mine/success`)	
+					},1500)
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		// 学校列表
+		getDeptListFn() {
+			var params = {
+				parentId: 0
+			}
+			getDeptList(0).then(res => {
+				if (res.code == 200) {
+					this.schoolval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId,
+							tenantId:v.tenantId
+						}
+					})
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getSchoolApply(type,val){
+			var that=this;
+			if(this.loginflag){
+				var userroles=this.$store.state.user.userroles;
+				var a=0;
+				Object.keys(userroles).some((key) => {
+					if (userroles[key].roleKey == ('' + val)) {
+						that.$store.dispatch('checkRole', userroles[key]).then(() => {
+						  this.$tab.reLaunch('/pages/index/index') 
+						}).catch(() => {
+						 
+						})
+						return true;
+					}
+				})	
+			}else{
+				this.registerflag=true;
+				this.type=type;
+				// if(type==0){
+				// 	this.$tab.navigateTo(`/mine/pages/mine/applyregister`)
+				// }else if(type==1){
+				// 	this.$tab.navigateTo(`/mine/pages/mine/applyparent`)
+				// }else{
+				// 	this.$tab.navigateTo(`/mine/pages/mine/applyteacher`)
+				// }
+			}
+			
+		},
+
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.regboxa{background-color: #ffffff;box-sizing: border-box;padding:0 12rpx;display: flex;flex-direction: column;
+	.lines{width: 40rpx;height: 6rpx;background: #1f57e6;margin: 60rpx auto 0;}
+	.reg_top{padding: 40rpx 36rpx 0rpx;flex: 0 0 auto;}
+	.reg_fot{flex: 1;overflow: auto;}
+	.headimg{width: 126rpx;height: 28rpx;margin-bottom: 20rpx;}
+	.txt{font-size: 34rpx;color: #989898;}
+	.rabox{
+		display: flex;flex-direction: column;align-items: center;margin-top: 60rpx;
+		image{width: 200rpx;height: 202rpx;margin-bottom: 20rpx;}
+		view{font-size: 32rpx;color: #161616;display: flex;align-items: center;}
+		.wicon{width:30rpx;height: 30rpx;margin-left: 12rpx;margin-bottom: 0;}
+	}
+	.tips{font-size: 28rpx;color: #666666;display: flex;padding: 0 24rpx;margin-top: 30rpx;
+		image{width: 34rpx;height: 30rpx;margin-right: 14rpx;margin-top: 4rpx;}
+	}
+}
+.regboxa .rimg{flex: 0 0 auto;margin-left: 12rpx;display: flex;align-items: center;justify-content: center;width: 40rpx;height: 40rpx;}
+.regboxa .rimg image{width: 18rpx;height: 30rpx;}
+.regboxa /deep/ .uni-tooltip{display: flex;align-items: center;}
+.regboxa /deep/ .uni-tooltip-popup{top: 100%;right: 0;left: auto;padding: 12rpx 24rpx;}
+.lrlist{width: 100%;min-height: 100rpx;box-sizing: border-box;display: flex;align-items: center;margin-bottom: 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-top: 50rpx;padding: 0 20rpx;
+	.label{font-size: 32rpx;font-weight: bold;color: #161616;flex: 0 0 auto;margin-right: 48rpx;}
+	input{font-size: 30rpx;color: #161616;flex: 1;text-align: right;}
+	.input{font-size: 30rpx;color: #161616;}
+	.ilrmgr{width: 12rpx;height: 22rpx;}
+}
+</style>

+ 131 - 0
mine/pages/mine/exit.vue

@@ -0,0 +1,131 @@
+<template>
+	<view class="exit flexdc">
+		<view class="flex1">
+			<view class="bgf ptb6">
+				<view class="list flexcj">
+					<view class="f15 co16 fw5 flex0 mr10">头像</view>
+					<image v-if="avatar" @click.stop="handleToAvatar" :src="baseUrl+avatar" class="flex0 limg" mode="widthFix"></image>
+					<image v-else @click.stop="handleToAvatar" :src="avatarimg" class="flex0 limg" mode="widthFix"></image>
+				</view>
+				<view class="list flexcj">
+					<view class="f16 co16 fw5 flex0 mr10">账号</view>
+					<view class="f15 co16 fw5">{{name}}</view>
+				</view>
+				<view class="list flexcj">
+					<view class="f16 co16 fw5 flex0 mr10">手机</view>
+					<view class="f15 co16 fw5">{{phonenumber}}</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="flex0 ">
+			<!-- <view class="ebtn btn1">账号解绑</view> -->
+			<view class="ebtn btn2"  @click="handleLogout">退出登录</view>
+		</view>
+		<pop-up :type='type' :confdat="confdat" @getConfirm="getConfirm" @getClose="getClose"></pop-up>
+	</view>
+  <!-- <view class="setting-container" :style="{height: `${windowHeight}px`}">
+    <view class="menu-list">
+      <view class="list-cell list-cell-arrow" @click="handleToPwd">
+        <view class="menu-item-box">
+          <view class="iconfont icon-password menu-icon"></view>
+          <view>修改密码</view>
+        </view>
+      </view>
+      <view class="list-cell list-cell-arrow" @click="handleToUpgrade">
+        <view class="menu-item-box">
+          <view class="iconfont icon-refresh menu-icon"></view>
+          <view>检查更新</view>
+        </view>
+      </view>
+      <view class="list-cell list-cell-arrow" @click="handleCleanTmp">
+        <view class="menu-item-box">
+          <view class="iconfont icon-clean menu-icon"></view>
+          <view>清理缓存</view>
+        </view>
+      </view>
+    </view>
+    <view class="cu-list menu">
+      <view class="cu-item item-box">
+        <view class="content text-center" @click="handleLogout">
+          <text class="text-black">退出登录</text>
+        </view>
+      </view>
+    </view>
+  </view> -->
+</template>
+
+<script>
+	import popUp from "@/components/popup/popup.vue"
+	import config from '@/config'
+	const baseUrl = config.baseUrl
+  export default {
+    data() {
+      return {
+		user:{},
+        windowHeight: uni.getSystemInfoSync().windowHeight,
+		type:0,
+		name:this.$store.state.user.name,
+		phonenumber:this.$store.state.user.phonenumber,
+		confdat:{tit:'系统提示',txt:"确定注销并退出系统吗?",closetxt:'取消',suretxt:'确认'},
+		avatarimg:require("@/static/images/profile.png"),
+		baseUrl:'',
+      }
+    },
+	components:{
+		popUp
+	},
+	computed: {
+	  avatar() {
+	    return this.$store.state.user.avatar
+	  },
+	},
+	onLoad() {
+		this.baseUrl=baseUrl;
+	},
+    methods: {
+		getConfirm(){
+			this.$store.dispatch('LogOut').then(() => {
+			  this.$tab.reLaunch('/pages/index/index')
+			})
+		},
+		getClose(){
+			this.type=0
+		},
+      handleToPwd() {
+        this.$tab.navigateTo('/pages/mine/pwd/index')
+      },
+      handleToUpgrade() {
+        this.$modal.showToast('模块建设中~')
+      },
+      handleCleanTmp() {
+        this.$modal.showToast('模块建设中~')
+      },
+      handleLogout() {
+		  this.type=1
+        // this.$modal.confirm('确定注销并退出系统吗?').then(() => {
+        //   this.$store.dispatch('LogOut').then(() => {
+        //     this.$tab.reLaunch('/pages/index/index')
+        //   })
+        // })
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .page {
+    background-color: #f8f8f8;
+  }
+  .bgf{border-radius: 18rpx;}
+  .exit{padding: 40rpx 34rpx 80rpx;min-height: 100vh;box-sizing: border-box;
+	.list{padding: 24rpx 48rpx 24rpx 40rpx;}
+	.limg{width: 80rpx;height: 80rpx;border-radius: 50%;}
+	.ebtn{width: 100%;height: 98rpx;border-radius: 49rpx;text-align: center;line-height: 98rpx;font-size: 32rpx;font-weight: bold;color: #FFFEFE;margin-top: 30rpx;
+	&.btn1{border: 1px solid #DF0024;color: #DF0024;}
+	&.btn2{background: #1f57e6;;color: #FFFFFF;;}
+	}
+  }
+  
+
+</style>

+ 125 - 0
mine/pages/mine/limit.vue

@@ -0,0 +1,125 @@
+<template>
+  <view class="limit">
+	  <view class="list">
+		  <view class="ltit">是否接收重点人员告警</view>
+		  <view class="flex0" @click="checkflag=!checkflag">
+			  <image :src="check" v-if="checkflag"></image>
+			  <image :src="ncheck" v-else></image>
+			  
+		  </view>
+	  </view>
+	  <view class="list">
+	  		<view class="ltit">是否加入防溺水计划</view>
+	  		<view class="flex0" @click="getJoinFn">
+	  			<image :src="check" v-if="acheckflag"></image>
+	  			<image :src="ncheck" v-else></image> 
+	  		</view>
+	  </view>
+	  <pop-up :type='type' @getClose='getClose' @getJoin="getJoin" :classlist="classlist"></pop-up>
+  </view>
+</template>
+
+<script>
+	import {getDeptList} from "@/api/mine/mine.js"
+	// import tabSearch from "@/components/toptab/search.vue"
+	import popUp from "@/mine/components/popup/popup.vue"
+  export default {
+	  components:{
+	  	popUp
+	  },
+	data(){
+		return{
+			ncheck:require("@/mine/static/mine/ncheck.png"), 
+			check:require("@/mine/static/mine/check.png"),
+			checkflag:false,
+			acheckflag:false,
+			type:0,
+			classlist:[]
+		}
+	},
+	
+	onLoad: function() {
+		// 判断角色
+		var roles=this.$store.state.user.choseroles;
+		this.roles=roles;
+		if(roles=='parents'){
+			var newArr=this.$store.state.user.student;
+			if(newArr&&newArr.length){
+				// var newArr=res.user.parentsStudent;
+				this.tablist = newArr
+			}
+			this.getDataFn();
+		}else if(roles=='teacher'){
+			var newArr=this.$store.state.user.teacherClass;
+			if(newArr&&newArr.length){
+				this.classId=newArr[0].classId
+				this.className=newArr[0].className
+				this.classlist = newArr.map(v => {
+					return {
+						className: v.className,
+						classId: Number(v.classId),
+						schoolId: Number(v.schoolId)
+					}
+				})
+			}
+			// this.getstuCountFn();
+			this.getDataFn();
+		}else {
+			// 去拿班级部门
+			this.schoolId=this.$store.state.user.deptId;
+			this.getclassListFn()
+			// this.getDataFn();
+		}
+	},
+	methods:{
+		getDataFn(){
+			
+		},
+		getclassListFn(){
+			//  获取学校id
+			var id=this.schoolId;
+			getDeptList(id).then(res=>{
+				if(res.code==200){
+					var newArr=res.data;
+					if(newArr&&newArr.length){
+						this.classId=newArr[0].deptId
+						this.className=newArr[0].deptName
+						this.classlist = newArr.map(v => {
+							return {
+								className: v.deptName,
+								classId: Number(v.deptId),
+								schoolId: Number(id)
+							}
+						})
+						this.getDataFn()
+					}
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getJoinFn(){
+			this.acheckflag=!this.acheckflag;
+			if(this.acheckflag){
+				this.type=8
+			}
+		},
+		getClose(){
+			this.type=0;
+		},
+		getJoin(){
+			this.type=0;	
+		},
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.limit{padding: 40rpx 36rpx;
+	.list{display: flex;align-items: center;min-height:144rpx;background: #FFFFFF;border-radius: 18rpx;margin-bottom: 18rpx;padding:20rpx 48rpx;box-sizing: border-box;
+		.ltit{flex: 1;font-size: 30rpx;font-weight: 500;color: #161616;}
+		image{width: 90rpx;height: 50rpx;flex: 0 0 auto;}
+		}
+}
+</style>

+ 264 - 0
mine/pages/mine/roles.vue

@@ -0,0 +1,264 @@
+<template>
+	<view>
+		<!-- 角色 -->
+		<view class="regboxa" :style="loginflag?'min-height: 100vh;padding-bottom: 60rpx;':'height: 100vh;'">
+			<view class="reg_top">
+				<image :src="helimg" class="headimg"></image>
+				<view class="txt">请认证您的身份。</view>
+			</view>
+			  
+			<view class="reg_fot">
+				<view class="rabox" @click="getSchoolApply(0)">
+				  	<image :src="mximg"></image>
+				  	<view @click.stop="gettip">
+				  		<uni-tooltip :content="xxtip">我是学校管理员<image :src="wimg" class="wicon" ></image></uni-tooltip>
+				  	</view>
+				</view>
+				<view class="rabox" @click="getSchoolApply(1)">
+				  	<image :src="mtimg" style="height: 200rpx;"></image>
+					<view @click.stop="gettip">
+						<uni-tooltip :content="lstip">我是老师<image :src="wimg" class="wicon" ></image></uni-tooltip>
+					</view>
+				</view>
+				<view class="rabox" @click="getSchoolApply(2)">
+				  	<image :src="mjimg" style="height: 212rpx;"></image>
+					<view @click.stop="gettip">
+						<uni-tooltip :content="jztip">我是家长<image :src="wimg" class="wicon" ></image></uni-tooltip>
+					</view>
+				  </view>
+			  </block>
+			</view>
+			<view class="tips" v-if="loginflag">
+				<image :src="tipimg"></image>切换角色时,若不属于同一学校,请先退出后再登录
+			</view>
+		</view>
+		<!-- 注册信息 -->
+		
+	</view>
+</template>
+
+<script>
+	// import tabSearch from "@/components/toptab/search.vue"
+	// import {getflowlistFn,getflowMyFn} from "@/api/mine/register.js"
+	import applyParent from "@/mine/components/login/applyparent.vue"
+	import applyTeacher from "@/mine/components/login/applyteacher.vue"
+	import applyRegister from "@/mine/components/login/applyregister.vue"
+	import { getToken } from '@/utils/auth'
+	import {getDeptList,getDeptListminea} from "@/api/mine/mine.js"
+	import {getparentsregFn,getschoolregFn,getSystemType,getteacherregFn} from "@/api/mine/register.js"
+  export default {
+	  components:{
+		  applyParent,applyTeacher,applyRegister
+	  },
+	data(){
+		return{
+			helimg:require("@/mine/static/mine/hello.png"), 
+			mjimg:require("@/mine/static/mine/mjicon.png"), 
+			mtimg:require("@/mine/static/mine/mticon.png"), 
+			mximg:require("@/mine/static/mine/mxgicon.png"),
+			wimg:require("@/mine/static/mine/shwicon.png"),
+			rimg: require("@/static/images/rimg.png"),
+			tipimg: require("@/mine/static/mine/tip.png"),
+			list:[],
+			loginflag:false,//是否登录
+			roles:'',
+			xxtip:'学校管理员身份',
+			lstip:'老师身份',
+			jztip:'学生家长身份',
+			registerflag:true,
+			schoolval:[],
+			type:-1,
+			cardType:'',
+			classval:[],
+			subject:[],
+			cardTypes:[{tit:'学校管理员',val:0},{tit:'老师',val:1},{tit:'学生家长',val:2},],
+			cardidx:0,
+			schoolobj:{}
+		}
+	},
+	onUnload(){
+		uni.$off('refreshschool')
+	},
+	onLoad: function(e) {
+		uni.$on('refreshschool', (e) => {
+			console.log(e,1)
+			this.schoolobj= e;
+		})
+		// this.init()
+		// if (getToken()) {
+		// 	// 判断切换还是新增
+		// 	if(e.type&&e.type=='add'){
+		// 		this.loginflag=false;
+		// 		this.getDeptListFn();
+		// 	}else{
+		// 		// 判断有什么角色
+		// 		var roles=this.$store.state.user.roles;
+		// 		this.loginflag=true;
+		// 		this.roles=roles;
+		// 	}
+		// } else {
+		//   this.loginflag=false;
+		//   this.getDeptListFn();
+		// }
+	},
+	methods:{
+		gettip(){
+			
+		},
+		bindDateChange(e){
+			var idx=e.detail.value
+			this.type=this.cardTypes[idx].val;
+			this.cardType=this.cardTypes[idx].tit;
+			this.registerflag=true;
+		},
+		getinit(id){
+			// 学科
+			var params={
+				dictType:'sys_subject',
+				tenantId:id
+			}
+			getSystemType(params).then(res=>{
+				if(res.code==200){
+					this.subject = res.data.map(v => {
+						return {
+							dictLabel: v.dictLabel,
+							dictValue: v.dictValue
+						}
+					})
+				}
+			})
+		},
+		getclassListFn(id) {
+			getDeptList(id).then(res => {
+				if (res.code == 200) {
+					this.classval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId
+						}
+					})
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getparentsregFn(params){
+			var that=this;
+			getparentsregFn(params).then(res => {
+				if (res.code == 200) {
+					that.$toast(res.msg)
+					setTimeout(function() {
+						that.$tab.redirectTo(`/mine/pages/mine/success`)
+					}, 1500)
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getschoolregFn(params){
+			var that=this;
+			getschoolregFn(params).then(res=>{
+				if(res.code==200){
+					that.$toast(res.msg)
+					setTimeout(function(){
+					that.$tab.redirectTo(`/mine/pages/mine/success`)	
+					},1500)
+				}else{
+					that.$toast(res.msg)
+				}
+			})
+		},
+		getteacherregFn(params){
+			var that=this;
+			getteacherregFn(params).then(res=>{
+				if(res.code==200){
+					that.$toast(res.msg)
+					setTimeout(function(){
+					that.$tab.redirectTo(`/mine/pages/mine/success`)	
+					},1500)
+				}else{
+					this.$toast(res.msg)
+				}
+			})
+		},
+		// 学校列表
+		getDeptListFn() {
+			var params = {
+				parentId: 0
+			}
+			getDeptList(0).then(res => {
+				if (res.code == 200) {
+					this.schoolval = res.data.map(v => {
+						return {
+							dictLabel: v.deptName,
+							dictValue: v.deptId,
+							tenantId:v.tenantId
+						}
+					})
+				} else {
+					this.$toast(res.msg)
+				}
+			})
+		},
+		getSchoolApply(type,val){
+			var that=this;
+			if(this.loginflag){
+				var userroles=this.$store.state.user.userroles;
+				var a=0;
+				Object.keys(userroles).some((key) => {
+					if (userroles[key].roleKey == ('' + val)) {
+						that.$store.dispatch('checkRole', userroles[key]).then(() => {
+						  this.$tab.reLaunch('/pages/index/index') 
+						}).catch(() => {
+						 
+						})
+						return true;
+					}
+				})	
+			}else{
+				// this.registerflag=true;
+				// this.type=type;
+				if(type==0){
+					this.$tab.navigateTo(`/mine/pages/mine/applyregister`)
+				}else if(type==1){
+					this.$tab.navigateTo(`/mine/pages/mine/applyteacher`)
+				}else{
+					this.$tab.navigateTo(`/mine/pages/mine/applyparent`)
+				}
+			}
+			
+		},
+
+	},
+	
+  }
+</script>
+
+<style lang="scss" scoped>
+.regboxa{background-color: #ffffff;box-sizing: border-box;padding:0 12rpx;display: flex;flex-direction: column;
+	.lines{width: 40rpx;height: 6rpx;background: #1f57e6;margin: 60rpx auto 0;}
+	.reg_top{padding: 40rpx 36rpx 0rpx;flex: 0 0 auto;}
+	.reg_fot{flex: 1;overflow: auto;}
+	.headimg{width: 126rpx;height: 28rpx;margin-bottom: 20rpx;}
+	.txt{font-size: 34rpx;color: #989898;}
+	.rabox{
+		display: flex;flex-direction: column;align-items: center;margin-top: 60rpx;
+		image{width: 200rpx;height: 202rpx;margin-bottom: 20rpx;}
+		view{font-size: 32rpx;color: #161616;display: flex;align-items: center;}
+		.wicon{width:30rpx;height: 30rpx;margin-left: 12rpx;margin-bottom: 0;}
+	}
+	.tips{font-size: 28rpx;color: #666666;display: flex;padding: 0 24rpx;margin-top: 30rpx;
+		image{width: 34rpx;height: 30rpx;margin-right: 14rpx;margin-top: 4rpx;}
+	}
+}
+.regboxa .rimg{flex: 0 0 auto;margin-left: 12rpx;display: flex;align-items: center;justify-content: center;width: 40rpx;height: 40rpx;}
+.regboxa .rimg image{width: 18rpx;height: 30rpx;}
+.regboxa /deep/ .uni-tooltip{display: flex;align-items: center;}
+.regboxa /deep/ .uni-tooltip-popup{top: 100%;right: 0;left: auto;padding: 12rpx 24rpx;}
+.lrlist{width: 100%;min-height: 100rpx;box-sizing: border-box;display: flex;align-items: center;margin-bottom: 20rpx;border-bottom: 2rpx #C1C1C1 solid;margin-top: 50rpx;padding: 0 20rpx;
+	.label{font-size: 32rpx;font-weight: bold;color: #161616;flex: 0 0 auto;margin-right: 48rpx;}
+	input{font-size: 30rpx;color: #161616;flex: 1;text-align: right;}
+	.input{font-size: 30rpx;color: #161616;}
+	.ilrmgr{width: 12rpx;height: 22rpx;}
+}
+</style>

+ 162 - 0
mine/pages/mine/school.vue

@@ -0,0 +1,162 @@
+<template>
+	<view class="school">
+		<view class="sch_top">
+			<view class="search flexc">
+				<image :src="searchimg" class="img"></image>
+				<input placeholder="输入学校名称进行搜索" v-model="name" class="flex1 input" />
+				<view class="btn" @click="getSearch">搜索</view>
+			</view>
+		</view>
+		
+		  <view class="sch_list">
+		    <!-- 左侧通讯录 -->
+		    <scroll-view class="scroll-container" scroll-y="true" :scroll-into-view="toView" scroll-with-animation="true" @scroll="getScroll">
+		      <block v-if="addressBook">
+				  <!-- <view class="address-book" v-for="(item, index) in addressBook" :key="index" :id="item.id">
+				    <view class="address-book-index">{{ item.id }}</view>
+				    <view class="contact-container" :class="tabidx==item.zh_title?'act':''" v-for="(item, index) in item.data" :key="index" @click="getCheck(item.zh_title)">
+				      <view class="contact-detail-container" >
+				        <view class="contact-name">{{ item.zh_title }}</view>
+				      </view>
+				    </view>
+				  </view> -->
+				  <view class="address-book"  v-for="(item, key) in addressBook" :key="key" :id="key">
+				    <view class="address-book-index">{{ key }}</view>
+				    <view class="contact-container" :class="tabid==ite.schoolNameId?'act':''" v-for="(ite, index) in item" :key="index" @click="getCheck(ite)">
+				      <view class="contact-detail-container" >
+				        <view class="contact-name">{{ ite.schoolName }}</view>
+				      </view>
+				    </view>
+				  </view>
+			  </block>
+			  
+			  <block v-else>
+			  		<no-data ></no-data>
+			  </block>
+			  <view class="adr_zhan"></view>
+		    </scroll-view>
+		 
+		    <!-- 右侧字母导航条 -->
+		    <view class="letter-nav">
+		      <view class="item" v-for="(item, index) in indexList" :key="index" @click="toSelectIndex(item)">{{ item }}</view>
+		    </view>
+		  </view>
+		  <view class="sch_btn" @click="getSure">确认</view>
+	</view>
+</template>
+
+<script>
+	import {getschoolList} from "@/api/login.js"
+	import noData from "@/components/nodata/nodata.vue"
+	export default {
+		data(){
+		return {
+			searchimg: require("@/mine/static/score/search.png"),
+		    indexList: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',     'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
+		    toView: '',
+			tabid:-1,
+			name:'',
+			addressBook:[],
+			schoolName:'',
+		}
+		},
+		components:{
+			noData
+		},
+		onLoad(e) {
+			if(e.id){
+				this.tabid=e.id;
+				this.schoolName=e.name;
+			}
+			this.getDataFn()
+		},
+		methods: {
+			toSelectIndex(item){
+			    this.toView = item
+			},
+			getScroll(){
+				this.toView = ''
+			},
+			getCheck(e){
+				this.tabid=e.schoolNameId;
+				this.schoolName=e.schoolName
+			},
+			getSure(){
+				var obj={
+					schoolNameId:this.tabid,
+					schoolName:this.schoolName,
+				}
+				uni.$emit("refreshschool",obj)
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			getSearch(){
+				var params={
+					schoolName:this.name
+				}
+				this.addressBook=[];
+				getschoolList(params).then(res=>{
+					if(res.code==200){
+						this.addressBook=res.data
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getDataFn(){
+				getschoolList().then(res=>{
+					if(res.code==200){
+						this.addressBook=res.data
+					}else{
+						this.$toast(res.msg)
+					}
+				})
+			}
+
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+.sch_top{background-color: #FFFFFF;padding: 28rpx 36rpx;
+	.search{height: 80rpx;background: #F2F5FB;border-radius: 40rpx;padding-left: 40rpx;
+		.img{width: 30rpx;height: 32rpx;flex:0 0 auto;margin-right: 30rpx;}
+		.btn{width: 120rpx;height: 80rpx;background: #1f57e6;border-radius: 40rpx;font-size: 30rpx;font-weight: 500;
+color: #FFFFFF;text-align: center;line-height: 80rpx;flex:0 0 auto}
+		.input{font-size: 30rpx;color: #161616;line-height: 80rpx;}
+	}
+}
+.sch_btn{position: fixed;left: 0;right: 0;bottom: 0;height: 100rpx;background: #1f57e6;text-align: center;line-height: 100rpx;font-size: 32rpx;font-weight: 500;
+color: #FFFFFF;}
+.sch_list{margin-top: 24rpx;
+	.scroll-container{background-color: #FFFFFF;height: calc(100vh - 160rpx);}
+	.address-book{padding: 30rpx 90rpx 0 50rpx;
+		.address-book-index{font-size: 30rpx;font-weight: 500;color: #AAAAAA;margin-bottom: 12rpx;}
+		.contact-container{
+			padding:12rpx 0;font-size: 30rpx;font-weight: 500;color: #161616;
+			&.act{font-weight: bold;
+color: #4775EA;}
+		}
+	}
+	.adr_zhan{height: 120rpx;}
+}
+
+
+
+
+
+
+.letter-nav{
+	position: fixed;
+	right: 48rpx;
+	top: 180rpx;
+	bottom: 120rpx;
+	display: flex;flex-wrap: wrap;flex-direction: column;
+	.item{font-size: 26rpx;font-weight: 500;
+color: #AAAAAA;padding: 4rpx;}
+}
+
+
+</style>
+

Някои файлове не бяха показани, защото твърде много файлове са промени