Quellcode durchsuchen

梅隆全流程版本提交

xianwait vor 2 Jahren
Commit
9dedd671da
100 geänderte Dateien mit 27577 neuen und 0 gelöschten Zeilen
  1. 5 0
      .gitignore
  2. 0 0
      .tgitconfig
  3. 84 0
      App.vue
  4. 21 0
      LICENSE
  5. 90 0
      README.md
  6. 3 0
      common/api.js
  7. 0 0
      common/common.js
  8. 3 0
      common/config.js
  9. 68 0
      common/demo.scss
  10. 97 0
      common/graceChecker.js
  11. 352 0
      common/html-parser.js
  12. 7 0
      common/mixin.js
  13. 245 0
      common/permission.js
  14. 2 0
      common/props.js
  15. 136 0
      common/uni-nvue.css
  16. 1463 0
      common/uni.css
  17. 73 0
      common/util.js
  18. BIN
      components/.DS_Store
  19. 130 0
      components/classify-1/classify-1.vue
  20. 93 0
      components/falls-list/index.vue
  21. 185 0
      components/homelist/homelist.vue
  22. 108 0
      components/page-nav/page-nav.vue
  23. 380 0
      components/robby-image-upload/robby-image-upload.vue
  24. 1 0
      components/scroll-list/images.js
  25. 723 0
      components/scroll-list/scroll-list.vue
  26. 1386 0
      components/uqrcode/common/uqrcode.js
  27. 163 0
      components/uqrcode/uqrcode.vue
  28. 60 0
      components/zai-lattice/index.css
  29. 107 0
      components/zai-lattice/index.vue
  30. BIN
      components/zhoujessie-SideCategoryList/.DS_Store
  31. 60 0
      components/zhoujessie-SideCategoryList/READ_ME.md
  32. 292 0
      components/zhoujessie-SideCategoryList/category-list.vue
  33. 79 0
      components/zhoujessie-SideCategoryList/index-anchor.vue
  34. 268 0
      components/zhoujessie-SideCategoryList/index-list.vue
  35. 97 0
      main.js
  36. 161 0
      manifest.json
  37. 5 0
      package-lock.json
  38. 14 0
      package.json
  39. 4874 0
      pageA/address/data.js
  40. 103 0
      pageA/address/pickerAddress.vue
  41. 59 0
      pageA/card/activetion.vue
  42. 201 0
      pageA/card/addressList.vue
  43. 117 0
      pageA/card/addressMgt.vue
  44. 140 0
      pageA/card/amassScoreRecord.vue
  45. 140 0
      pageA/card/expense/details.vue
  46. 291 0
      pageA/card/expense/expenseCalendar.vue
  47. 59 0
      pageA/card/grant.vue
  48. 120 0
      pageA/card/index.vue
  49. 151 0
      pageA/card/orderProcess.vue
  50. 119 0
      pageA/club/apply.vue
  51. 156 0
      pageA/club/appoint.vue
  52. 583 0
      pageA/club/index.vue
  53. 181 0
      pageA/club/more.vue
  54. 113 0
      pageA/club/welfareList.vue
  55. 88 0
      pageA/components/dictSelect.vue
  56. 79 0
      pageA/components/input.vue
  57. 123 0
      pageA/components/show.vue
  58. 144 0
      pageA/integral/details.vue
  59. 377 0
      pageA/integral/expenseCalendar.vue
  60. 768 0
      pageA/integral/index.vue
  61. 490 0
      pageA/integral/list.vue
  62. 41 0
      pageA/integral/more.vue
  63. 53 0
      pageA/integral/ok.vue
  64. 238 0
      pageA/integral/shopcar.vue
  65. 189 0
      pageA/integral/shopcarTemporary.vue
  66. 190 0
      pageA/kq/kqList.vue
  67. 106 0
      pageA/login/css/main.css
  68. 170 0
      pageA/login/forget.vue
  69. 67 0
      pageA/login/login.vue
  70. 63 0
      pageA/login/register.vue
  71. 50 0
      pageA/login/selectOrg.vue
  72. 144 0
      pageA/msg/abList.vue
  73. 136 0
      pageA/msg/groupAb.vue
  74. 296 0
      pageA/msg/index.vue
  75. 134 0
      pageA/msg/subscription.vue
  76. 364 0
      pageA/msg/userMsgList.vue
  77. 172 0
      pageA/msg/visitingCard.vue
  78. 53 0
      pageA/notice/notice.vue
  79. 63 0
      pageA/officefile/index.vue
  80. 357 0
      pageA/psq/dayForm.vue
  81. 199 0
      pageA/psq/form.vue
  82. 77 0
      pageA/salary/salary.vue
  83. 24 0
      pageA/salary/salarySlip.vue
  84. BIN
      pageA/static/img/upload.png
  85. 36 0
      pageA/watch-login/css/icon.css
  86. 134 0
      pageA/watch-login/watch-button.vue
  87. 205 0
      pageA/watch-login/watch-input.vue
  88. 4874 0
      pageApp/address/data.js
  89. 103 0
      pageApp/address/pickerAddress.vue
  90. 131 0
      pageApp/administration/conference.vue
  91. 294 0
      pageApp/administration/inform.vue
  92. 586 0
      pageApp/administration/reserve.vue
  93. 212 0
      pageApp/administration/useCar.vue
  94. 254 0
      pageApp/administration/useSeal.vue
  95. 85 0
      pageApp/components/deptSelect.vue
  96. 79 0
      pageApp/components/dictSelect.vue
  97. 182 0
      pageApp/components/flowSubmit.vue
  98. 495 0
      pageApp/components/ge.vue
  99. 158 0
      pageApp/components/input.vue
  100. 126 0
      pageApp/components/list.vue

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+/node_modules
+/unpackage/release/apk
+/unpackage
+" " 
+" " 

+ 0 - 0
.tgitconfig


+ 84 - 0
App.vue

@@ -0,0 +1,84 @@
+<script>
+	export default {
+		onLoad() {
+			console.log("onLoad")
+		},
+		onLaunch() {
+			//更新提示
+			const updateManager = wx.getUpdateManager()
+			updateManager.onCheckForUpdate(function(res) {
+				// 请求完新版本信息的回调
+				// console.log(res.hasUpdate)
+				if (res.hasUpdate) {
+					updateManager.onUpdateReady(function(ress) {
+						updateManager.applyUpdate()
+						// console.log("===强制更新重启")
+					})
+				} else {
+					updateManager.onUpdateFailed(function() {
+						// 新版本下载失败
+					})
+				}
+			})
+		},
+		onShow: function() {
+			console.log('App Show')
+			uni.getSystemInfo({
+				success: (result) => {
+					// 获取手机系统的状态栏高度(不同手机的状态栏高度不同)  ( 不要使用uni-app官方文档的var(--status-bar-height) 官方这个是固定的20px  不对的 )
+					// console.log('当前手机的状态栏高度',result.statusBarHeight)
+					let statusBarHeight = result.statusBarHeight + 'px'
+					// 获取右侧胶囊的信息 单位px
+					const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
+					//bottom: 胶囊底部距离屏幕顶部的距离
+					//height: 胶囊高度
+					//left:   胶囊左侧距离屏幕左侧的距离
+					//right:  胶囊右侧距离屏幕左侧的距离
+					//top:    胶囊顶部距离屏幕顶部的距离
+					//width:  胶囊宽度
+					// console.log(menuButtonInfo.width, menuButtonInfo.height, menuButtonInfo.top)
+					// console.log('计算胶囊右侧距离屏幕右边距离', result.screenWidth - menuButtonInfo.right)
+					let menuWidth = menuButtonInfo.width + 40 + 'px'
+					let menuHeight = menuButtonInfo.height + 'px'
+					let menuBorderRadius = menuButtonInfo.height / 2 + 'px'
+					let menuRight = result.screenWidth - menuButtonInfo.right + 'px'
+					let menuTop = menuButtonInfo.top + 'px'
+					let contentTop = result.statusBarHeight + 44 + 'px'
+					let menuInfo = {
+						statusBarHeight: statusBarHeight, //状态栏高度----用来给自定义导航条页面的顶部导航条设计padding-top使用:目的留出系统的状态栏区域
+						menuWidth: menuWidth, //右侧的胶囊宽度--用来给自定义导航条页面的左侧胶囊设置使用
+						menuHeight: menuHeight, //右侧的胶囊高度--用来给自定义导航条页面的左侧胶囊设置使用
+						menuBorderRadius: menuBorderRadius, //一半的圆角--用来给自定义导航条页面的左侧胶囊设置使用
+						menuRight: menuRight, //右侧的胶囊距离右侧屏幕距离--用来给自定义导航条页面的左侧胶囊设置使用
+						menuTop: menuTop, //右侧的胶囊顶部距离屏幕顶部的距离--用来给自定义导航条页面的左侧胶囊设置使用
+						contentTop: contentTop, //内容区距离页面最上方的高度--用来给自定义导航条页面的内容区定位距离使用
+					}
+					uni.setStorageSync('menuInfo', menuInfo)
+				},
+				fail: (error) => {
+					console.log(error)
+				}
+			})
+		},
+		onHide: function() {
+			uni.hideTabBar()
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*每个页面公共css */
+	@import "@/uni_modules/uview-ui/index.scss";
+	@import "common/demo.scss";
+	@import './common/uni.css';
+
+	@font-face {
+		font-family: hsUniAppFont; //字体
+		src: url('static/font/SourceHanSansCN-Regular.otf'); //包路径
+	}
+
+	page {
+		font-family: hsUniAppFont;
+		letter-spacing: 2rpx;
+	}
+</style>

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 www.uviewui.com
+
+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.

+ 90 - 0
README.md

@@ -0,0 +1,90 @@
+<p align="center">
+    <img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
+</p>
+<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView 2.0</h3>
+<h3 align="center">多平台快速开发的UI框架</h3>
+
+[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
+[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
+[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues)
+[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com)
+[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases)
+[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
+
+## 说明
+
+uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
+
+## [官方文档:https://v2.uviewui.com](https://v2.uviewui.com)
+
+### 官方1群:1042987248(已满)
+### 官方2群:249718512(已满)
+### 官方3群:1129077272(已满)
+### 官方4群:1084514613(已满)
+### 官方5群:863820668(已满)
+### 官方6群:745721078(已满)
+### 官方7群:627867855(已满)
+### 官方8群:496409492(已满)
+### 官方9群:828504448(已满)
+### [点击加10群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
+
+## 特性
+
+- 全面兼容nvue,原生渲染,高性能
+- 兼容安卓,iOS,微信小程序,H5,QQ小程序,百度小程序,支付宝小程序,头条小程序
+- 60+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用
+- 众多贴心的JS利器,让您飞镖在手,召之即来,百步穿杨
+- 众多的常用页面和布局,让您专注逻辑,事半功倍
+- 详尽的文档支持,现代化的演示效果
+- 按需引入,精简打包体积
+
+
+## 预览
+
+您可以通过**微信**扫码,查看最佳的演示效果。
+<br>
+<br>
+<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
+
+
+## 链接
+
+- [官方文档](https://v2.uviewui.com/)
+- [更新日志](https://v2.uviewui.com/components/changelog.html)
+- [升级指南](https://v2.uviewui.com/components/changeGuide.html)
+- [关于我们](https://v2.uviewui.com/cooperation/about.html)
+
+## 交流反馈
+
+欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html)
+
+## 安装
+
+#### **下载地址** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
+
+## 快速上手
+
+请通过[官网安装文档](https://v2.uviewui.com/components/install.html)了解更详细的内容
+
+## 使用方法
+配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
+
+```html
+<template>
+	<u-button>按钮</u-button>
+</template>
+```
+
+请通过[快速上手](https://v2.uviewui.com/components/quickstart.html)了解更详细的内容
+
+
+## 捐赠uView的研发
+
+uView文档内容和框架源码全部开源免费,如果您认为uView帮到了您的开发工作,您可以捐赠uView的研发工作,捐赠无门槛,哪怕是一杯可乐也好(相信这比打赏主播更有意义)。
+
+<img src="https://uviewui.com/common/wechat.png" width="220" >
+<img style="margin-left: 100px;" src="https://uviewui.com/common/alipay.png" width="220" >
+
+## 版权信息
+uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
+

+ 3 - 0
common/api.js

@@ -0,0 +1,3 @@
+const { http } = uni.$u
+// 获取菜单
+export const fetchMenu = (params, config = {}) => http.post('/ebapi/public_api/index', params, config)

+ 0 - 0
common/common.js


+ 3 - 0
common/config.js

@@ -0,0 +1,3 @@
+module.exports = {
+    baseUrl: 'https://api.youzixy.com'
+}

+ 68 - 0
common/demo.scss

@@ -0,0 +1,68 @@
+.u-view {
+	padding: 40px 20px 0px 20px;
+	&__title {
+		font-size: 14px;
+		color: rgb(143, 156, 162);
+		margin-bottom: 10px;
+	}
+}
+.hs-hzl-count{	
+	text-align: center;
+	font-size: 20rpx;
+	font-weight: bold;
+	color: #FFFFFF;
+	background-color: #ff0000;
+	width: 35rpx;
+	height: 35rpx;
+	border-radius: 50%;
+	position: absolute;
+}
+.u-block{
+	padding: 14px;
+	&__section{
+		margin-bottom:10px;
+	}
+	&__title {
+		margin-top:10px;
+		font-size: 15px;
+		color: $u-content-color;
+		margin-bottom:10px;
+	}
+	&__flex{
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+	}
+}
+
+// 使用了cell组件的icon图片样式
+.u-cell-icon {
+	width: 36rpx;
+	height: 36rpx;
+	margin-right: 8rpx;
+}
+
+.u-page {
+	padding: 15px 15px 40px 15px;
+}
+
+.u-demo-block {
+	flex: 1;
+	margin-bottom: 13px;
+	
+	&__content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		// flex-direction: row!important;
+		// align-items: center;
+		// flex-wrap: wrap;
+	}
+	
+	&__title {
+		font-size: 14px;
+		color: rgb(143, 156, 162);
+		margin-bottom: 8px;
+	}
+}
+

+ 97 - 0
common/graceChecker.js

@@ -0,0 +1,97 @@
+/**
+数据验证(表单验证)
+来自 grace.hcoder.net 
+作者 hcoder 深海
+*/
+module.exports = {
+	error:'',
+	check : function (data, rule){
+		for(var i = 0; i < rule.length; i++){
+			if (!rule[i].checkType){return true;}
+			if (!rule[i].name) {return true;}
+			if (!rule[i].errorMsg) {return true;}
+			if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;}
+			switch (rule[i].checkType){
+				case 'string':
+					var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
+					if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
+				break;
+				case 'int':
+					var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
+					if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
+					break;
+				break;
+				case 'between':
+					if (!this.isNumber(data[rule[i].name])){
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'betweenD':
+					var reg = /^-?[1-9][0-9]?$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'betweenF': 
+					var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
+					if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;}
+					var minMax = rule[i].checkRule.split(',');
+					minMax[0] = Number(minMax[0]);
+					minMax[1] = Number(minMax[1]);
+					if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
+						this.error = rule[i].errorMsg;
+						return false;
+					}
+				break;
+				case 'same':
+					if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
+				break;
+				case 'notsame':
+					if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'email':
+					var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'phoneno':
+					var reg = /^1[0-9]{10,10}$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'zipcode':
+					var reg = /^[0-9]{6}$/;
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'reg':
+					var reg = new RegExp(rule[i].checkRule);
+					if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
+				break;
+				case 'in':
+					if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){
+						this.error = rule[i].errorMsg; return false;
+					}
+				break;
+				case 'notnull':
+					if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;}
+				break;
+			}
+		}
+		return true;
+	},
+	isNumber : function (checkVal){
+		var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
+		return reg.test(checkVal);
+	}
+}

+ 352 - 0
common/html-parser.js

@@ -0,0 +1,352 @@
+/*
+ * HTML5 Parser By Sam Blowes
+ *
+ * Designed for HTML5 documents
+ *
+ * Original code by John Resig (ejohn.org)
+ * http://ejohn.org/blog/pure-javascript-html-parser/
+ * Original code by Erik Arvidsson, Mozilla Public License
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+ *
+ * ----------------------------------------------------------------------------
+ * License
+ * ----------------------------------------------------------------------------
+ *
+ * This code is triple licensed using Apache Software License 2.0,
+ * Mozilla Public License or GNU Public License
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * 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
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Simple HTML Parser.
+ *
+ * The Initial Developer of the Original Code is Erik Arvidsson.
+ * Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
+ * Reserved.
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * ----------------------------------------------------------------------------
+ * Usage
+ * ----------------------------------------------------------------------------
+ *
+ * // Use like so:
+ * HTMLParser(htmlString, {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * });
+ *
+ * // or to get an XML string:
+ * HTMLtoXML(htmlString);
+ *
+ * // or to get an XML DOM Document
+ * HTMLtoDOM(htmlString);
+ *
+ * // or to inject into an existing document/DOM node
+ * HTMLtoDOM(htmlString, document);
+ * HTMLtoDOM(htmlString, document.body);
+ *
+ */
+// Regular Expressions for parsing tags and attributes
+var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
+var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
+var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
+
+var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
+// fixed by xxx 将 ins 标签从块级名单中移除
+
+var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
+
+var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
+// (and which close themselves)
+
+var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
+
+var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
+
+var special = makeMap('script,style');
+function HTMLParser(html, handler) {
+  var index;
+  var chars;
+  var match;
+  var stack = [];
+  var last = html;
+
+  stack.last = function () {
+    return this[this.length - 1];
+  };
+
+  while (html) {
+    chars = true; // Make sure we're not in a script or style element
+
+    if (!stack.last() || !special[stack.last()]) {
+      // Comment
+      if (html.indexOf('<!--') == 0) {
+        index = html.indexOf('-->');
+
+        if (index >= 0) {
+          if (handler.comment) {
+            handler.comment(html.substring(4, index));
+          }
+
+          html = html.substring(index + 3);
+          chars = false;
+        } // end tag
+
+      } else if (html.indexOf('</') == 0) {
+        match = html.match(endTag);
+
+        if (match) {
+          html = html.substring(match[0].length);
+          match[0].replace(endTag, parseEndTag);
+          chars = false;
+        } // start tag
+
+      } else if (html.indexOf('<') == 0) {
+        match = html.match(startTag);
+
+        if (match) {
+          html = html.substring(match[0].length);
+          match[0].replace(startTag, parseStartTag);
+          chars = false;
+        }
+      }
+
+      if (chars) {
+        index = html.indexOf('<');
+        var text = index < 0 ? html : html.substring(0, index);
+        html = index < 0 ? '' : html.substring(index);
+
+        if (handler.chars) {
+          handler.chars(text);
+        }
+      }
+    } else {
+      html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
+        text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
+
+        if (handler.chars) {
+          handler.chars(text);
+        }
+
+        return '';
+      });
+      parseEndTag('', stack.last());
+    }
+
+    if (html == last) {
+      throw 'Parse Error: ' + html;
+    }
+
+    last = html;
+  } // Clean up any remaining tags
+
+
+  parseEndTag();
+
+  function parseStartTag(tag, tagName, rest, unary) {
+    tagName = tagName.toLowerCase();
+
+    if (block[tagName]) {
+      while (stack.last() && inline[stack.last()]) {
+        parseEndTag('', stack.last());
+      }
+    }
+
+    if (closeSelf[tagName] && stack.last() == tagName) {
+      parseEndTag('', tagName);
+    }
+
+    unary = empty[tagName] || !!unary;
+
+    if (!unary) {
+      stack.push(tagName);
+    }
+
+    if (handler.start) {
+      var attrs = [];
+      rest.replace(attr, function (match, name) {
+        var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
+        attrs.push({
+          name: name,
+          value: value,
+          escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
+
+        });
+      });
+
+      if (handler.start) {
+        handler.start(tagName, attrs, unary);
+      }
+    }
+  }
+
+  function parseEndTag(tag, tagName) {
+    // If no tag name is provided, clean shop
+    if (!tagName) {
+      var pos = 0;
+    } // Find the closest opened tag of the same type
+    else {
+        for (var pos = stack.length - 1; pos >= 0; pos--) {
+          if (stack[pos] == tagName) {
+            break;
+          }
+        }
+      }
+
+    if (pos >= 0) {
+      // Close all the open elements, up the stack
+      for (var i = stack.length - 1; i >= pos; i--) {
+        if (handler.end) {
+          handler.end(stack[i]);
+        }
+      } // Remove the open elements from the stack
+
+
+      stack.length = pos;
+    }
+  }
+}
+
+function makeMap(str) {
+  var obj = {};
+  var items = str.split(',');
+
+  for (var i = 0; i < items.length; i++) {
+    obj[items[i]] = true;
+  }
+
+  return obj;
+}
+
+function removeDOCTYPE(html) {
+  return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
+}
+
+function parseAttrs(attrs) {
+  return attrs.reduce(function (pre, attr) {
+    var value = attr.value;
+    var name = attr.name;
+
+    if (pre[name]) {
+			pre[name] = pre[name] + " " + value;
+    } else {
+			pre[name] = value;
+    }
+
+    return pre;
+  }, {});
+}
+
+function parseHtml(html) {
+  html = removeDOCTYPE(html);
+  var stacks = [];
+  var results = {
+    node: 'root',
+    children: []
+  };
+  HTMLParser(html, {
+    start: function start(tag, attrs, unary) {
+      var node = {
+        name: tag
+      };
+
+      if (attrs.length !== 0) {
+        node.attrs = parseAttrs(attrs);
+      }
+
+      if (unary) {
+        var parent = stacks[0] || results;
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      } else {
+        stacks.unshift(node);
+      }
+    },
+    end: function end(tag) {
+      var node = stacks.shift();
+      if (node.name !== tag) console.error('invalid state: mismatch end tag');
+
+      if (stacks.length === 0) {
+        results.children.push(node);
+      } else {
+        var parent = stacks[0];
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      }
+    },
+    chars: function chars(text) {
+      var node = {
+        type: 'text',
+        text: text
+      };
+
+      if (stacks.length === 0) {
+        results.children.push(node);
+      } else {
+        var parent = stacks[0];
+
+        if (!parent.children) {
+          parent.children = [];
+        }
+
+        parent.children.push(node);
+      }
+    },
+    comment: function comment(text) {
+      var node = {
+        node: 'comment',
+        text: text
+      };
+      var parent = stacks[0];
+
+      if (!parent.children) {
+        parent.children = [];
+      }
+
+      parent.children.push(node);
+    }
+  });
+  return results.children;
+}
+
+export default parseHtml;

+ 7 - 0
common/mixin.js

@@ -0,0 +1,7 @@
+export default {
+    data() {
+        return {
+
+        }
+    }
+}

+ 245 - 0
common/permission.js

@@ -0,0 +1,245 @@
+/// null = 未请求,1 = 已允许,0 = 拒绝|受限, 2 = 系统未开启
+
+var isIOS
+
+function album() {
+    var result = 0;
+    var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
+    var authStatus = PHPhotoLibrary.authorizationStatus();
+    if (authStatus === 0) {
+        result = null;
+    } else if (authStatus == 3) {
+        result = 1;
+    } else {
+        result = 0;
+    }
+    plus.ios.deleteObject(PHPhotoLibrary);
+    return result;
+}
+
+function camera() {
+    var result = 0;
+    var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
+    var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
+    if (authStatus === 0) {
+        result = null;
+    } else if (authStatus == 3) {
+        result = 1;
+    } else {
+        result = 0;
+    }
+    plus.ios.deleteObject(AVCaptureDevice);
+    return result;
+}
+
+function location() {
+    var result = 0;
+    var cllocationManger = plus.ios.import("CLLocationManager");
+    var enable = cllocationManger.locationServicesEnabled();
+    var status = cllocationManger.authorizationStatus();
+    if (!enable) {
+        result = 2;
+    } else if (status === 0) {
+        result = null;
+    } else if (status === 3 || status === 4) {
+        result = 1;
+    } else {
+        result = 0;
+    }
+    plus.ios.deleteObject(cllocationManger);
+    return result;
+}
+
+function push() {
+    var result = 0;
+    var UIApplication = plus.ios.import("UIApplication");
+    var app = UIApplication.sharedApplication();
+    var enabledTypes = 0;
+    if (app.currentUserNotificationSettings) {
+        var settings = app.currentUserNotificationSettings();
+        enabledTypes = settings.plusGetAttribute("types");
+        if (enabledTypes == 0) {
+            result = 0;
+            console.log("推送权限没有开启");
+        } else {
+            result = 1;
+            console.log("已经开启推送功能!")
+        }
+        plus.ios.deleteObject(settings);
+    } else {
+        enabledTypes = app.enabledRemoteNotificationTypes();
+        if (enabledTypes == 0) {
+            result = 3;
+            console.log("推送权限没有开启!");
+        } else {
+            result = 4;
+            console.log("已经开启推送功能!")
+        }
+    }
+    plus.ios.deleteObject(app);
+    plus.ios.deleteObject(UIApplication);
+    return result;
+}
+
+function contact() {
+    var result = 0;
+    var CNContactStore = plus.ios.import("CNContactStore");
+    var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
+    if (cnAuthStatus === 0) {
+        result = null;
+    } else if (cnAuthStatus == 3) {
+        result = 1;
+    } else {
+        result = 0;
+    }
+    plus.ios.deleteObject(CNContactStore);
+    return result;
+}
+
+function record() {
+    var result = null;
+    var avaudiosession = plus.ios.import("AVAudioSession");
+    var avaudio = avaudiosession.sharedInstance();
+    var status = avaudio.recordPermission();
+    console.log("permissionStatus:" + status);
+    if (status === 1970168948) {
+        result = null;
+    } else if (status === 1735552628) {
+        result = 1;
+    } else {
+        result = 0;
+    }
+    plus.ios.deleteObject(avaudiosession);
+    return result;
+}
+
+function calendar() {
+    var result = null;
+    var EKEventStore = plus.ios.import("EKEventStore");
+    var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
+    if (ekAuthStatus == 3) {
+        result = 1;
+        console.log("日历权限已经开启");
+    } else {
+        console.log("日历权限没有开启");
+    }
+    plus.ios.deleteObject(EKEventStore);
+    return result;
+}
+
+function memo() {
+    var result = null;
+    var EKEventStore = plus.ios.import("EKEventStore");
+    var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
+    if (ekAuthStatus == 3) {
+        result = 1;
+        console.log("备忘录权限已经开启");
+    } else {
+        console.log("备忘录权限没有开启");
+    }
+    plus.ios.deleteObject(EKEventStore);
+    return result;
+}
+
+
+function requestIOS(permissionID) {
+    return new Promise((resolve, reject) => {
+        switch (permissionID) {
+            case "push":
+                resolve(push());
+                break;
+            case "location":
+                resolve(location());
+                break;
+            case "record":
+                resolve(record());
+                break;
+            case "camera":
+                resolve(camera());
+                break;
+            case "album":
+                resolve(album());
+                break;
+            case "contact":
+                resolve(contact());
+                break;
+            case "calendar":
+                resolve(calendar());
+                break;
+            case "memo":
+                resolve(memo());
+                break;
+            default:
+                resolve(0);
+                break;
+        }
+    });
+}
+
+function requestAndroid(permissionID) {
+    return new Promise((resolve, reject) => {
+        plus.android.requestPermissions(
+            [permissionID],
+            function(resultObj) {
+                var result = 0;
+                for (var i = 0; i < resultObj.granted.length; i++) {
+                    var grantedPermission = resultObj.granted[i];
+                    console.log('已获取的权限:' + grantedPermission);
+                    result = 1
+                }
+                for (var i = 0; i < resultObj.deniedPresent.length; i++) {
+                    var deniedPresentPermission = resultObj.deniedPresent[i];
+                    console.log('拒绝本次申请的权限:' + deniedPresentPermission);
+                    result = 0
+                }
+                for (var i = 0; i < resultObj.deniedAlways.length; i++) {
+                    var deniedAlwaysPermission = resultObj.deniedAlways[i];
+                    console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
+                    result = -1
+                }
+                resolve(result);
+            },
+            function(error) {
+                console.log('result error: ' + error.message)
+                resolve({
+                    code: error.code,
+                    message: error.message
+                });
+            }
+        );
+    });
+}
+
+function gotoAppPermissionSetting() {
+    if (permission.isIOS) {
+        var UIApplication = plus.ios.import("UIApplication");
+        var application2 = UIApplication.sharedApplication();
+        var NSURL2 = plus.ios.import("NSURL");
+        var setting2 = NSURL2.URLWithString("app-settings:");
+        application2.openURL(setting2);
+        plus.ios.deleteObject(setting2);
+        plus.ios.deleteObject(NSURL2);
+        plus.ios.deleteObject(application2);
+    } else {
+        var Intent = plus.android.importClass("android.content.Intent");
+        var Settings = plus.android.importClass("android.provider.Settings");
+        var Uri = plus.android.importClass("android.net.Uri");
+        var mainActivity = plus.android.runtimeMainActivity();
+        var intent = new Intent();
+        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+        var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
+        intent.setData(uri);
+        mainActivity.startActivity(intent);
+    }
+}
+
+const permission = {
+    get isIOS(){
+        return typeof isIOS === 'boolean' ? isIOS : (isIOS = uni.getSystemInfoSync().platform === 'ios')
+    },
+    requestIOS: requestIOS,
+    requestAndroid: requestAndroid,
+    gotoAppSetting: gotoAppPermissionSetting
+}
+
+module.exports = permission

+ 2 - 0
common/props.js

@@ -0,0 +1,2 @@
+uni.$u.props.gap.bgColor = '#f3f4f6'
+uni.$u.props.gap.height = '10'

+ 136 - 0
common/uni-nvue.css

@@ -0,0 +1,136 @@
+/* #ifndef APP-PLUS-NVUE */
+page {
+    min-height: 100%;
+    height: auto;
+}
+/* #endif */
+
+/* 解决头条小程序字体图标不显示问题,因为头条运行时自动插入了span标签,且有全局字体 */
+/* #ifdef MP-TOUTIAO */
+/* text :not(view) {
+    font-family: uniicons;
+} */
+/* #endif */
+
+.uni-icon {
+    font-family: uniicons;
+    font-weight: normal;
+}
+
+.uni-container {
+    padding: 15px;
+    background-color: #f8f8f8;
+}
+
+.uni-header-logo {
+	/* #ifdef H5 */
+	display: flex;
+	/* #endif */
+    padding: 15px 15px;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    margin-top: 10rpx;
+}
+
+.uni-header-image {
+    width: 80px;
+    height: 80px;
+}
+
+.uni-hello-text {
+    margin-bottom: 20px;
+}
+
+.hello-text {
+    color: #7A7E83;
+    font-size: 14px;
+    line-height: 20px;
+}
+
+.hello-link {
+    color: #7A7E83;
+    font-size: 14px;
+    line-height: 20px;
+}
+
+.uni-panel {
+    margin-bottom: 12px;
+}
+
+.uni-panel-h {
+	/* #ifdef H5 */
+	display: flex;
+	/* #endif */
+    background-color: #ffffff;
+    flex-direction: row !important;
+	/* justify-content: space-between !important; */
+    align-items: center !important;
+    padding: 12px;
+	/* #ifdef H5 */
+	cursor: pointer;
+	/* #endif */
+}
+/*
+.uni-panel-h:active {
+    background-color: #f8f8f8;
+}
+ */
+.uni-panel-h-on {
+    background-color: #f0f0f0;
+}
+
+.uni-panel-text {
+    flex: 1;
+    color: #000000;
+    font-size: 14px;
+    font-weight: normal;
+}
+
+.uni-panel-icon {
+    margin-left: 15px;
+    color: #999999;
+    font-size: 14px;
+    font-weight: normal;
+    transform: rotate(0deg);
+    transition-duration: 0s;
+    transition-property: transform;
+}
+
+.uni-panel-icon-on {
+    transform: rotate(180deg);
+}
+
+.uni-navigate-item {
+	/* #ifdef H5 */
+	display: flex;
+	/* #endif */
+    flex-direction: row;
+    align-items: center;
+    background-color: #FFFFFF;
+    border-top-style: solid;
+    border-top-color: #f0f0f0;
+    border-top-width: 1px;
+    padding: 12px;
+	/* #ifdef H5 */
+	cursor: pointer;
+	/* #endif */
+}
+
+.uni-navigate-item:active {
+    background-color: #f8f8f8;
+}
+
+.uni-navigate-text {
+    flex: 1;
+    color: #000000;
+    font-size: 14px;
+    font-weight: normal;
+}
+
+.uni-navigate-icon {
+    margin-left: 15px;
+    color: #999999;
+    font-size: 14px;
+    font-weight: normal;
+}

+ 1463 - 0
common/uni.css

@@ -0,0 +1,1463 @@
+@font-face {
+	font-family: uniicons;
+	font-weight: normal;
+	font-style: normal;
+	src: url('~@/static/uni.ttf') format('truetype');
+}
+
+/* #ifdef H5 */
+.fix-left-window {
+	padding-left: var(--window-left);
+}
+.pc-hide {
+	display: none !important;
+}
+/* #endif */
+
+/*通用 */
+
+view{
+	font-size:28rpx;
+	line-height:1.8;
+}
+progress, checkbox-group{
+	width: 100%;
+}
+form {
+	width: 100%;
+}
+.uni-flex {
+	display: flex;
+	flex-direction: row;
+}
+.uni-flex-item {
+	flex: 1;
+}
+.uni-row {
+	flex-direction: row;
+}
+.uni-column {
+	flex-direction: column;
+}
+.uni-link{
+	color:#576B95;
+	font-size:26rpx;
+}
+.uni-center{
+	text-align:center;
+}
+.uni-inline-item{
+	display: flex;
+	flex-direction: row;
+	align-items:center;
+}
+.uni-inline-item text{
+	margin-right: 20rpx;
+}
+.uni-inline-item text:last-child{
+	margin-right: 0rpx;
+	margin-left: 20rpx;
+}
+
+/* page */
+.uni-page-head{
+	padding:35rpx;
+	text-align: center;
+}
+.uni-page-head-title {
+	display: inline-block;
+	padding: 0 40rpx;
+	font-size: 30rpx;
+	height: 88rpx;
+	line-height: 88rpx;
+	color: #BEBEBE;
+	box-sizing: border-box;
+	border-bottom: 2rpx solid #D8D8D8;
+}
+.uni-page-body {
+	width: 100%;
+	padding:0 100px;
+	flex-grow: 1;
+	/* overflow-x: hidden; */
+}
+.uni-padding-wrap{
+	/* width:690rpx; */
+	padding:0 30rpx;
+}
+.uni-word {
+	text-align: center;
+	padding:200rpx 100rpx;
+}
+.uni-title {
+	font-size:30rpx;
+	font-weight:500;
+	padding:20rpx 0;
+	line-height:1.5;
+}
+.uni-text{
+	font-size:28rpx;
+}
+.uni-title text{
+	font-size:24rpx;
+	color:#888;
+}
+
+.uni-text-gray{
+	color: #ccc;
+}
+.uni-text-small {
+	font-size:24rpx;
+}
+.uni-common-mb{
+	margin-bottom:30rpx;
+}
+.uni-common-pb{
+	padding-bottom:30rpx;
+}
+.uni-common-pl{
+	padding-left:30rpx;
+}
+.uni-common-mt{
+	margin-top:30rpx;
+}
+/* 背景色 */
+.uni-bg-red{
+	background:#F76260; color:#FFF;
+}
+.uni-bg-green{
+	background:#09BB07; color:#FFF;
+}
+.uni-bg-blue{
+	background:#007AFF; color:#FFF;
+}
+/* 标题 */
+.uni-h1 {font-size: 80rpx; font-weight:700;}
+.uni-h2 {font-size: 60rpx; font-weight:700;}
+.uni-h3 {font-size: 48rpx; font-weight:700;}
+.uni-h4 {font-size: 36rpx; font-weight:700;}
+.uni-h5 {font-size: 28rpx; color: #8f8f94;}
+.uni-h6 {font-size: 24rpx; color: #8f8f94;}
+.uni-bold{font-weight:bold;}
+
+/* 文本溢出隐藏 */
+.uni-ellipsis {overflow: hidden; white-space: nowrap; text-overflow: ellipsis;}
+
+/* 竖向百分百按钮 */
+.uni-btn-v{
+	padding:10rpx 0;
+}
+.uni-btn-v button{margin:20rpx 0;}
+
+/* 表单 */
+.uni-form-item{
+	display:flex;
+	width:100%;
+	padding:10rpx 0;
+}
+.uni-form-item .title{
+	padding:10rpx 25rpx;
+}
+.uni-label {
+	width: 210rpx;
+	word-wrap: break-word;
+	word-break: break-all;
+	text-indent:20rpx;
+}
+.uni-input {
+	height: 50rpx;
+	padding: 15rpx 25rpx;
+	line-height:50rpx;
+	font-size:28rpx;
+	background:#FFF;
+	flex: 1;
+}
+radio-group, checkbox-group{
+	width:100%;
+}
+radio-group label, checkbox-group label{
+	padding-right:20rpx;
+}
+.uni-form-item .with-fun{
+	display:flex;
+	flex-wrap:nowrap;
+	background:#FFFFFF;
+}
+.uni-form-item .with-fun .uni-icon{
+	width:40px;
+	height:80rpx;
+	line-height:80rpx;
+	flex-shrink:0;
+}
+
+/* loadmore */
+.uni-loadmore{
+	height:80rpx;
+	line-height:80rpx;
+	text-align:center;
+	padding-bottom:30rpx;
+}
+/*数字角标*/
+.uni-badge,
+.uni-badge-default {
+	font-family: 'Helvetica Neue', Helvetica, sans-serif;
+	font-size: 12px;
+	line-height: 1;
+	display: inline-block;
+	padding: 3px 6px;
+	color: #333;
+	border-radius: 100px;
+	background-color: rgba(0, 0, 0, .15);
+}
+.uni-badge.uni-badge-inverted {
+	padding: 0 5px 0 0;
+	color: #929292;
+	background-color: transparent
+}
+.uni-badge-primary {
+	color: #fff;
+	background-color: #007aff
+}
+.uni-badge-blue.uni-badge-inverted,
+.uni-badge-primary.uni-badge-inverted {
+	color: #007aff;
+	background-color: transparent
+}
+.uni-badge-green,
+.uni-badge-success {
+	color: #fff;
+	background-color: #4cd964;
+}
+.uni-badge-green.uni-badge-inverted,
+.uni-badge-success.uni-badge-inverted {
+	color: #4cd964;
+	background-color: transparent
+}
+.uni-badge-warning,
+.uni-badge-yellow {
+	color: #fff;
+	background-color: #f0ad4e
+}
+.uni-badge-warning.uni-badge-inverted,
+.uni-badge-yellow.uni-badge-inverted {
+	color: #f0ad4e;
+	background-color: transparent
+}
+.uni-badge-danger,
+.uni-badge-red {
+	color: #fff;
+	background-color: #dd524d
+}
+.uni-badge-danger.uni-badge-inverted,
+.uni-badge-red.uni-badge-inverted {
+	color: #dd524d;
+	background-color: transparent
+}
+.uni-badge-purple,
+.uni-badge-royal {
+	color: #fff;
+	background-color: #8a6de9
+}
+.uni-badge-purple.uni-badge-inverted,
+.uni-badge-royal.uni-badge-inverted {
+	color: #8a6de9;
+	background-color: transparent
+}
+
+/*折叠面板 */
+.uni-collapse-content {
+	height: 0;
+	width: 100%;
+	overflow: hidden;
+}
+.uni-collapse-content.uni-active {
+	height: auto;
+}
+
+/*卡片视图 */
+.uni-card {
+	background: #fff;
+	border-radius: 8rpx;
+	margin:20rpx 0;
+	position: relative;
+	box-shadow: 0 2rpx 4rpx rgba(0, 0, 0, .3);
+}
+.uni-card-content {
+	font-size: 30rpx;
+}
+.uni-card-content.image-view{
+    width: 100%;
+    margin: 0;
+}
+.uni-card-content-inner {
+	position: relative;
+	padding: 30rpx;
+}
+.uni-card-footer,
+.uni-card-header {
+	position: relative;
+	display: flex;
+	min-height: 50rpx;
+	padding: 20rpx 30rpx;
+	justify-content: space-between;
+	align-items: center;
+}
+.uni-card-header {
+	font-size: 36rpx;
+}
+.uni-card-footer {
+	color: #6d6d72;
+}
+.uni-card-footer:before,
+.uni-card-header:after {
+	position: absolute;
+	top: 0;
+	right: 0;
+	left: 0;
+	height: 2rpx;
+	content: '';
+	-webkit-transform: scaleY(.5);
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+.uni-card-header:after {
+	top: auto;
+	bottom: 0;
+}
+.uni-card-media {
+	justify-content: flex-start;
+}
+.uni-card-media-logo {
+	height: 84rpx;
+	width: 84rpx;
+	margin-right: 20rpx;
+}
+.uni-card-media-body {
+	height: 84rpx;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	align-items: flex-start;
+}
+.uni-card-media-text-top {
+	line-height: 36rpx;
+	font-size: 34rpx;
+}
+.uni-card-media-text-bottom {
+	line-height: 30rpx;
+	font-size: 28rpx;
+	color: #8f8f94;
+}
+.uni-card-link {
+	color: #007AFF;
+}
+
+/* 列表 */
+.uni-list {
+	background-color: #FFFFFF;
+	position: relative;
+	width: 100%;
+	display: flex;
+	flex-direction: column;
+}
+.uni-list:after {
+	position: absolute;
+	z-index: 10;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	height: 1px;
+	content: '';
+	-webkit-transform: scaleY(.5);
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+.uni-list::before {
+	position: absolute;
+	z-index: 10;
+	right: 0;
+	top: 0;
+	left: 0;
+	height: 1px;
+	content: '';
+	-webkit-transform: scaleY(.5);
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+.uni-list-cell {
+	position: relative;
+	display: flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+}
+.uni-list-cell-hover {
+	background-color: #eee;
+}
+.uni-list-cell-pd {
+	padding: 22rpx 30rpx;
+}
+.uni-list-cell-left {
+    white-space: nowrap;
+	font-size:28rpx;
+	padding: 0 30rpx;
+}
+.uni-list-cell-db,
+.uni-list-cell-right {
+	flex: 1;
+}
+.uni-list-cell::after {
+	position: absolute;
+	z-index: 3;
+	right: 0;
+	bottom: 0;
+	left: 30rpx;
+	height: 1px;
+	content: '';
+	-webkit-transform: scaleY(.5);
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+.uni-list .uni-list-cell:last-child::after {
+	height: 0rpx;
+}
+.uni-list-cell-last.uni-list-cell::after {
+	height: 0rpx;
+}
+.uni-list-cell-divider {
+	position: relative;
+	display: flex;
+	color: #999;
+	background-color: #f7f7f7;
+	padding:15rpx 20rpx;
+}
+.uni-list-cell-divider::before {
+	position: absolute;
+	right: 0;
+	top: 0;
+	left: 0;
+	height: 1px;
+	content: '';
+	-webkit-transform: scaleY(.5);
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+.uni-list-cell-divider::after {
+	position: absolute;
+	right: 0;
+	bottom: 0;
+	left: 0rpx;
+	height: 1px;
+	content: '';
+	-webkit-transform: scaleY(.5);
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+.uni-list-cell-navigate {
+	font-size:30rpx;
+	padding: 22rpx 30rpx;
+	line-height: 48rpx;
+	position: relative;
+	display: flex;
+	box-sizing: border-box;
+	width: 100%;
+	flex: 1;
+	justify-content: space-between;
+	align-items: center;
+}
+.uni-list-cell-navigate {
+	padding-right: 36rpx;
+}
+.uni-navigate-badge {
+	padding-right: 50rpx;
+}
+.uni-list-cell-navigate.uni-navigate-right:after {
+	font-family: uniicons;
+	content: '\e583';
+	position: absolute;
+	right: 24rpx;
+	top: 50%;
+	color: #bbb;
+	-webkit-transform: translateY(-50%);
+	transform: translateY(-50%);
+}
+.uni-list-cell-navigate.uni-navigate-bottom:after {
+	font-family: uniicons;
+	content: '\e581';
+	position: absolute;
+	right: 24rpx;
+	top: 50%;
+	color: #bbb;
+	-webkit-transform: translateY(-50%);
+	transform: translateY(-50%);
+}
+.uni-list-cell-navigate.uni-navigate-bottom.uni-active::after {
+	font-family: uniicons;
+	content: '\e580';
+	position: absolute;
+	right: 24rpx;
+	top: 50%;
+	color: #bbb;
+	-webkit-transform: translateY(-50%);
+	transform: translateY(-50%);
+}
+.uni-collapse.uni-list-cell {
+	flex-direction: column;
+}
+.uni-list-cell-navigate.uni-active {
+	background: #eee;
+}
+.uni-list.uni-collapse {
+	box-sizing: border-box;
+	height: 0;
+	overflow: hidden;
+}
+.uni-collapse .uni-list-cell {
+	padding-left: 20rpx;
+}
+.uni-collapse .uni-list-cell::after {
+	left: 52rpx;
+}
+.uni-list.uni-active {
+	height: auto;
+}
+
+/* 三行列表 */
+.uni-triplex-row {
+	display: flex;
+	flex: 1;
+	width: 100%;
+	box-sizing: border-box;
+	flex-direction: row;
+	padding: 22rpx 30rpx;
+}
+.uni-triplex-right,
+.uni-triplex-left {
+	display: flex;
+	flex-direction: column;
+}
+.uni-triplex-left {
+	width: 84%;
+}
+.uni-triplex-left .uni-title{
+	padding:8rpx 0;
+}
+.uni-triplex-left .uni-text, .uni-triplex-left .uni-text-small{color:#999999;}
+.uni-triplex-right {
+	width: 16%;
+	text-align: right;
+}
+
+/* 图文列表 */
+.uni-media-list {
+	padding: 22rpx 30rpx;
+	box-sizing: border-box;
+	display: flex;
+	width: 100%;
+	flex-direction: row;
+}
+.uni-navigate-right.uni-media-list {
+	padding-right: 74rpx;
+}
+.uni-pull-right {
+	flex-direction: row-reverse;
+}
+.uni-pull-right>.uni-media-list-logo {
+	margin-right: 0rpx;
+	margin-left: 20rpx;
+}
+.uni-media-list-logo {
+	height: 84rpx;
+	width: 84rpx;
+	margin-right: 20rpx;
+}
+.uni-media-list-logo image {
+	height: 100%;
+	width: 100%;
+}
+.uni-media-list-body {
+	height: 84rpx;
+	display: flex;
+	flex: 1;
+	flex-direction: column;
+	justify-content: space-between;
+	align-items: flex-start;
+	overflow: hidden;
+}
+.uni-media-list-text-top {
+	width: 100%;
+	line-height: 36rpx;
+	font-size: 30rpx;
+}
+.uni-media-list-text-bottom {
+	width: 100%;
+	line-height: 30rpx;
+	font-size: 26rpx;
+	color: #8f8f94;
+}
+
+/* 九宫格 */
+.uni-grid-9 {
+	background: #f2f2f2;
+	width: 750rpx;
+	display: flex;
+	flex-direction: row;
+	flex-wrap: wrap;
+	border-top: 2rpx solid #eee;
+}
+.uni-grid-9-item {
+	width: 250rpx;
+	height: 200rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	border-bottom: 2rpx solid;
+	border-right: 2rpx solid;
+	border-color: #eee;
+	box-sizing: border-box;
+}
+.no-border-right {
+	border-right: none;
+}
+.uni-grid-9-image {
+	width: 100rpx;
+	height: 100rpx;
+}
+.uni-grid-9-text {
+	width: 250rpx;
+	line-height: 4rpx;
+	height: 40rpx;
+	text-align: center;
+	font-size: 30rpx;
+}
+.uni-grid-9-item-hover {
+	background: rgba(0, 0, 0, 0.1);
+}
+
+/* 上传 */
+.uni-uploader {
+	flex: 1;
+	flex-direction: column;
+}
+.uni-uploader-head {
+	display: flex;
+	flex-direction: row;
+	justify-content: space-between;
+}
+.uni-uploader-info {
+	color: #B2B2B2;
+}
+.uni-uploader-body {
+	margin-top: 16rpx;
+}
+.uni-uploader__files {
+	display: flex;
+	flex-direction: row;
+	flex-wrap: wrap;
+}
+.uni-uploader__file {
+	margin: 10rpx;
+	width: 210rpx;
+	height: 210rpx;
+}
+.uni-uploader__img {
+	display: block;
+	width: 210rpx;
+	height: 210rpx;
+}
+.uni-uploader__input-box {
+	position: relative;
+	margin:10rpx;
+	width: 208rpx;
+	height: 208rpx;
+	border: 2rpx solid #D9D9D9;
+}
+.uni-uploader__input-box:before,
+.uni-uploader__input-box:after {
+	content: " ";
+	position: absolute;
+	top: 50%;
+	left: 50%;
+	-webkit-transform: translate(-50%, -50%);
+	transform: translate(-50%, -50%);
+	background-color: #D9D9D9;
+}
+.uni-uploader__input-box:before {
+	width: 4rpx;
+	height: 79rpx;
+}
+.uni-uploader__input-box:after {
+	width: 79rpx;
+	height: 4rpx;
+}
+.uni-uploader__input-box:active {
+	border-color: #999999;
+}
+.uni-uploader__input-box:active:before,
+.uni-uploader__input-box:active:after {
+	background-color: #999999;
+}
+.uni-uploader__input {
+	position: absolute;
+	z-index: 1;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	opacity: 0;
+}
+
+/*问题反馈*/
+.feedback-title {
+	display: flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+	padding: 20rpx;
+	color: #8f8f94;
+	font-size: 28rpx;
+}
+.feedback-star-view.feedback-title {
+	justify-content: flex-start;
+	margin: 0;
+}
+.feedback-quick {
+	position: relative;
+	padding-right: 40rpx;
+}
+.feedback-quick:after {
+	font-family: uniicons;
+	font-size: 40rpx;
+	content: '\e581';
+	position: absolute;
+	right: 0;
+	top: 50%;
+	color: #bbb;
+	-webkit-transform: translateY(-50%);
+	transform: translateY(-50%);
+}
+.feedback-body {
+	background: #fff;
+}
+.feedback-textare {
+	height: 200rpx;
+	font-size: 34rpx;
+	line-height: 50rpx;
+	width: 100%;
+	box-sizing: border-box;
+	padding: 20rpx 30rpx 0;
+}
+.feedback-input {
+	font-size: 34rpx;
+	height: 50rpx;
+	min-height: 50rpx;
+	padding: 15rpx 20rpx;
+	line-height: 50rpx;
+}
+.feedback-uploader {
+	padding: 22rpx 20rpx;
+}
+.feedback-star {
+	font-family: uniicons;
+	font-size: 40rpx;
+	margin-left: 6rpx;
+}
+.feedback-star-view {
+	margin-left: 20rpx;
+}
+.feedback-star:after {
+	content: '\e408';
+}
+.feedback-star.active {
+	color: #FFB400;
+}
+.feedback-star.active:after {
+	content: '\e438';
+}
+.feedback-submit {
+	background: #007AFF;
+	color: #FFFFFF;
+	margin: 20rpx;
+}
+
+/* input group */
+.uni-input-group {
+	position: relative;
+	padding: 0;
+	border: 0;
+	background-color: #fff;
+}
+
+.uni-input-group:before {
+	position: absolute;
+	top: 0;
+	right: 0;
+	left: 0;
+	height: 2rpx;
+	content: '';
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+
+.uni-input-group:after {
+	position: absolute;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	height: 2rpx;
+	content: '';
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+
+.uni-input-row {
+	position: relative;
+	display: flex;
+	flex-direction: row;
+	font-size:28rpx;
+	padding: 22rpx 30rpx;
+	justify-content: space-between;
+}
+
+.uni-input-group .uni-input-row:after {
+	position: absolute;
+	right: 0;
+	bottom: 0;
+	left: 30rpx;
+	height: 2rpx;
+	content: '';
+	transform: scaleY(.5);
+	background-color: #c8c7cc;
+}
+
+.uni-input-row label {
+	line-height: 70rpx;
+}
+
+/* textarea */
+.uni-textarea{
+	width:100%;
+	background:#FFF;
+}
+.uni-textarea textarea{
+	width:96%;
+	padding:18rpx 2%;
+	line-height:1.6;
+	font-size:28rpx;
+	height:150rpx;
+}
+
+/* tab bar */
+.uni-tab-bar {
+	display: flex;
+	flex: 1;
+	flex-direction: column;
+	overflow: hidden;
+	height: 100%;
+}
+
+.uni-tab-bar .list {
+	width: 750rpx;
+	height: 100%;
+}
+
+.uni-swiper-tab {
+	width: 100%;
+	white-space: nowrap;
+	line-height: 100rpx;
+	height: 100rpx;
+	border-bottom: 1px solid #c8c7cc;
+}
+
+.swiper-tab-list {
+	font-size: 30rpx;
+	width: 150rpx;
+	display: inline-block;
+	text-align: center;
+	color: #555;
+}
+
+.uni-tab-bar .active {
+	color: #007AFF;
+}
+
+.uni-tab-bar .swiper-box {
+	flex: 1;
+	width: 100%;
+	height: calc(100% - 100rpx);
+}
+
+.uni-tab-bar-loading{
+	padding:20rpx 0;
+}
+
+/* comment */
+.uni-comment{padding:5rpx 0; display: flex; flex-grow:1; flex-direction: column;}
+.uni-comment-list{flex-wrap:nowrap; padding:10rpx 0; margin:10rpx 0; width:100%; display: flex;}
+.uni-comment-face{width:70rpx; height:70rpx; border-radius:100%; margin-right:20rpx; flex-shrink:0; overflow:hidden;}
+.uni-comment-face image{width:100%; border-radius:100%;}
+.uni-comment-body{width:100%;}
+.uni-comment-top{line-height:1.5em; justify-content:space-between;}
+.uni-comment-top text{color:#0A98D5; font-size:24rpx;}
+.uni-comment-date{line-height:38rpx; flex-direction:row; justify-content:space-between; display:flex !important; flex-grow:1;}
+.uni-comment-date view{color:#666666; font-size:24rpx; line-height:38rpx;}
+.uni-comment-content{line-height:1.6em; font-size:28rpx; padding:8rpx 0;}
+.uni-comment-replay-btn{background:#FFF; font-size:24rpx; line-height:28rpx; padding:5rpx 20rpx; border-radius:30rpx; color:#333 !important; margin:0 10rpx;}
+
+/* swiper msg */
+.uni-swiper-msg{width:100%; padding:12rpx 0; flex-wrap:nowrap; display:flex;}
+.uni-swiper-msg-icon{width:50rpx; margin-right:20rpx;}
+.uni-swiper-msg-icon image{width:100%; flex-shrink:0;}
+.uni-swiper-msg swiper{width:100%; height:50rpx;}
+.uni-swiper-msg swiper-item{line-height:50rpx;}
+
+/* product */
+.uni-product-list {
+    display: flex;
+    width: 100%;
+    flex-wrap: wrap;
+    flex-direction: row;
+}
+
+.uni-product {
+    padding: 20rpx;
+    display: flex;
+    flex-direction: column;
+}
+
+.image-view {
+    height: 330rpx;
+    width: 330rpx;
+	margin:12rpx 0;
+}
+
+.uni-product-image {
+    height: 330rpx;
+    width: 330rpx;
+}
+
+.uni-product-title {
+    width: 300rpx;
+    word-break: break-all;
+    display: -webkit-box;
+    overflow: hidden;
+	line-height:1.5;
+    text-overflow: ellipsis;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+}
+
+.uni-product-price {
+	margin-top:10rpx;
+    font-size: 28rpx;
+	line-height:1.5;
+    position: relative;
+}
+
+.uni-product-price-original {
+    color: #e80080;
+}
+
+.uni-product-price-favour {
+    color: #888888;
+    text-decoration: line-through;
+    margin-left: 10rpx;
+}
+
+.uni-product-tip {
+    position: absolute;
+    right: 10rpx;
+    background-color: #ff3333;
+    color: #ffffff;
+    padding: 0 10rpx;
+    border-radius: 5rpx;
+}
+
+/* timeline */
+.uni-timeline {
+		margin: 35rpx 0;
+		display: flex;
+		flex-direction: column;
+		position: relative;
+	}
+
+
+	.uni-timeline-item {
+		display: flex;
+		flex-direction: row;
+		position: relative;
+		padding-bottom: 20rpx;
+		box-sizing: border-box;
+		overflow: hidden;
+
+	}
+
+	.uni-timeline-item .uni-timeline-item-keynode {
+		width: 160rpx;
+		flex-shrink: 0;
+		box-sizing: border-box;
+		padding-right: 20rpx;
+		text-align: right;
+		line-height: 65rpx;
+	}
+
+	.uni-timeline-item .uni-timeline-item-divider {
+		flex-shrink: 0;
+		position: relative;
+		width: 30rpx;
+		height: 30rpx;
+		top: 15rpx;
+		border-radius: 50%;
+		background-color: #bbb;
+	}
+
+
+
+	.uni-timeline-item-divider::before,
+	.uni-timeline-item-divider::after {
+		position: absolute;
+		left: 15rpx;
+		width: 1rpx;
+		height: 100vh;
+		content: '';
+		background: inherit;
+	}
+
+	.uni-timeline-item-divider::before {
+		bottom: 100%;
+	}
+
+	.uni-timeline-item-divider::after {
+		top: 100%;
+	}
+
+
+	.uni-timeline-last-item .uni-timeline-item-divider:after {
+		display: none;
+	}
+
+	.uni-timeline-first-item .uni-timeline-item-divider:before {
+		display: none;
+	}
+
+	.uni-timeline-item .uni-timeline-item-content {
+		padding-left: 20rpx;
+	}
+
+	.uni-timeline-last-item .bottom-border::after{
+		display: none;
+	}
+
+	.uni-timeline-item-content .datetime{
+		color: #CCCCCC;
+	}
+
+	/* 自定义节点颜色 */
+	.uni-timeline-last-item .uni-timeline-item-divider{
+		background-color: #1AAD19;
+	}
+
+
+/* uni-icon */
+
+.uni-icon {
+	font-family: uniicons;
+	font-size: 24px;
+	font-weight: normal;
+	font-style: normal;
+	line-height: 1;
+	display: inline-block;
+	text-decoration: none;
+	-webkit-font-smoothing: antialiased;
+}
+
+.uni-icon.uni-active {
+	color: #007aff;
+}
+
+.uni-icon-contact:before {
+	content: '\e100';
+}
+
+.uni-icon-person:before {
+	content: '\e101';
+}
+
+.uni-icon-personadd:before {
+	content: '\e102';
+}
+
+.uni-icon-contact-filled:before {
+	content: '\e130';
+}
+
+.uni-icon-person-filled:before {
+	content: '\e131';
+}
+
+.uni-icon-personadd-filled:before {
+	content: '\e132';
+}
+
+.uni-icon-phone:before {
+	content: '\e200';
+}
+
+.uni-icon-email:before {
+	content: '\e201';
+}
+
+.uni-icon-chatbubble:before {
+	content: '\e202';
+}
+
+.uni-icon-chatboxes:before {
+	content: '\e203';
+}
+
+.uni-icon-phone-filled:before {
+	content: '\e230';
+}
+
+.uni-icon-email-filled:before {
+	content: '\e231';
+}
+
+.uni-icon-chatbubble-filled:before {
+	content: '\e232';
+}
+
+.uni-icon-chatboxes-filled:before {
+	content: '\e233';
+}
+
+.uni-icon-weibo:before {
+	content: '\e260';
+}
+
+.uni-icon-weixin:before {
+	content: '\e261';
+}
+
+.uni-icon-pengyouquan:before {
+	content: '\e262';
+}
+
+.uni-icon-chat:before {
+	content: '\e263';
+}
+
+.uni-icon-qq:before {
+	content: '\e264';
+}
+
+.uni-icon-videocam:before {
+	content: '\e300';
+}
+
+.uni-icon-camera:before {
+	content: '\e301';
+}
+
+.uni-icon-mic:before {
+	content: '\e302';
+}
+
+.uni-icon-location:before {
+	content: '\e303';
+}
+
+.uni-icon-mic-filled:before,
+.uni-icon-speech:before {
+	content: '\e332';
+}
+
+.uni-icon-location-filled:before {
+	content: '\e333';
+}
+
+.uni-icon-micoff:before {
+	content: '\e360';
+}
+
+.uni-icon-image:before {
+	content: '\e363';
+}
+
+.uni-icon-map:before {
+	content: '\e364';
+}
+
+.uni-icon-compose:before {
+	content: '\e400';
+}
+
+.uni-icon-trash:before {
+	content: '\e401';
+}
+
+.uni-icon-upload:before {
+	content: '\e402';
+}
+
+.uni-icon-download:before {
+	content: '\e403';
+}
+
+.uni-icon-close:before {
+	content: '\e404';
+}
+
+.uni-icon-redo:before {
+	content: '\e405';
+}
+
+.uni-icon-undo:before {
+	content: '\e406';
+}
+
+.uni-icon-refresh:before {
+	content: '\e407';
+}
+
+.uni-icon-star:before {
+	content: '\e408';
+}
+
+.uni-icon-plus:before {
+	content: '\e409';
+}
+
+.uni-icon-minus:before {
+	content: '\e410';
+}
+
+.uni-icon-circle:before,
+.uni-icon-checkbox:before {
+	content: '\e411';
+}
+
+.uni-icon-close-filled:before,
+.uni-icon-clear:before {
+	content: '\e434';
+}
+
+.uni-icon-refresh-filled:before {
+	content: '\e437';
+}
+
+.uni-icon-star-filled:before {
+	content: '\e438';
+}
+
+.uni-icon-plus-filled:before {
+	content: '\e439';
+}
+
+.uni-icon-minus-filled:before {
+	content: '\e440';
+}
+
+.uni-icon-circle-filled:before {
+	content: '\e441';
+}
+
+.uni-icon-checkbox-filled:before {
+	content: '\e442';
+}
+
+.uni-icon-closeempty:before {
+	content: '\e460';
+}
+
+.uni-icon-refreshempty:before {
+	content: '\e461';
+}
+
+.uni-icon-reload:before {
+	content: '\e462';
+}
+
+.uni-icon-starhalf:before {
+	content: '\e463';
+}
+
+.uni-icon-spinner:before {
+	content: '\e464';
+}
+
+.uni-icon-spinner-cycle:before {
+	content: '\e465';
+}
+
+.uni-icon-search:before {
+	content: '\e466';
+}
+
+.uni-icon-plusempty:before {
+	content: '\e468';
+}
+
+.uni-icon-forward:before {
+	content: '\e470';
+}
+
+.uni-icon-back:before,
+.uni-icon-left-nav:before {
+	content: '\e471';
+}
+
+.uni-icon-checkmarkempty:before {
+	content: '\e472';
+}
+
+.uni-icon-home:before {
+	content: '\e500';
+}
+
+.uni-icon-navigate:before {
+	content: '\e501';
+}
+
+.uni-icon-gear:before {
+	content: '\e502';
+}
+
+.uni-icon-paperplane:before {
+	content: '\e503';
+}
+
+.uni-icon-info:before {
+	content: '\e504';
+}
+
+.uni-icon-help:before {
+	content: '\e505';
+}
+
+.uni-icon-locked:before {
+	content: '\e506';
+}
+
+.uni-icon-more:before {
+	content: '\e507';
+}
+
+.uni-icon-flag:before {
+	content: '\e508';
+}
+
+.uni-icon-home-filled:before {
+	content: '\e530';
+}
+
+.uni-icon-gear-filled:before {
+	content: '\e532';
+}
+
+.uni-icon-info-filled:before {
+	content: '\e534';
+}
+
+.uni-icon-help-filled:before {
+	content: '\e535';
+}
+
+.uni-icon-more-filled:before {
+	content: '\e537';
+}
+
+.uni-icon-settings:before {
+	content: '\e560';
+}
+
+.uni-icon-list:before {
+	content: '\e562';
+}
+
+.uni-icon-bars:before {
+	content: '\e563';
+}
+
+.uni-icon-loop:before {
+	content: '\e565';
+}
+
+.uni-icon-paperclip:before {
+	content: '\e567';
+}
+
+.uni-icon-eye:before {
+	content: '\e568';
+}
+
+.uni-icon-arrowup:before {
+	content: '\e580';
+}
+
+.uni-icon-arrowdown:before {
+	content: '\e581';
+}
+
+.uni-icon-arrowleft:before {
+	content: '\e582';
+}
+
+.uni-icon-arrowright:before {
+	content: '\e583';
+}
+
+.uni-icon-arrowthinup:before {
+	content: '\e584';
+}
+
+.uni-icon-arrowthindown:before {
+	content: '\e585';
+}
+
+.uni-icon-arrowthinleft:before {
+	content: '\e586';
+}
+
+.uni-icon-arrowthinright:before {
+	content: '\e587';
+}
+
+.uni-icon-pulldown:before {
+	content: '\e588';
+}
+
+.uni-icon-scan:before {
+    content: "\e612";
+}
+
+/* 分界线 */
+.uni-divider{
+    height: 110rpx;
+    display: flex;
+    align-items:center;
+    justify-content: center;
+    position: relative;
+}
+.uni-divider__content{
+    font-size: 28rpx;
+    color: #999;
+    padding: 0 20rpx;
+    position: relative;
+    z-index: 101;
+    background: #F4F5F6;
+}
+.uni-divider__line{
+    background-color: #CCCCCC;
+    height: 1px;
+    width: 100%;
+    position: absolute;
+    z-index: 100;
+    top: 50%;
+    left: 0;
+    transform: translateY(50%);
+}
+
+.left-win-active text{
+	color: #007AFF !important;
+}

+ 73 - 0
common/util.js

@@ -0,0 +1,73 @@
+function formatTime(time) {
+	if (typeof time !== 'number' || time < 0) {
+		return time
+	}
+
+	var hour = parseInt(time / 3600)
+	time = time % 3600
+	var minute = parseInt(time / 60)
+	time = time % 60
+	var second = time
+
+	return ([hour, minute, second]).map(function (n) {
+		n = n.toString()
+		return n[1] ? n : '0' + n
+	}).join(':')
+}
+
+function formatLocation(longitude, latitude) {
+	if (typeof longitude === 'string' && typeof latitude === 'string') {
+		longitude = parseFloat(longitude)
+		latitude = parseFloat(latitude)
+	}
+
+	longitude = longitude.toFixed(2)
+	latitude = latitude.toFixed(2)
+
+	return {
+		longitude: longitude.toString().split('.'),
+		latitude: latitude.toString().split('.')
+	}
+}
+var dateUtils = {
+	UNITS: {
+		'年': 31557600000,
+		'月': 2629800000,
+		'天': 86400000,
+		'小时': 3600000,
+		'分钟': 60000,
+		'秒': 1000
+	},
+	humanize: function (milliseconds) {
+		var humanize = '';
+		for (var key in this.UNITS) {
+			if (milliseconds >= this.UNITS[key]) {
+				humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
+				break;
+			}
+		}
+		return humanize || '刚刚';
+	},
+	format: function (dateStr) {
+		var date = this.parse(dateStr)
+		var diff = Date.now() - date.getTime();
+		if (diff < this.UNITS['天']) {
+			return this.humanize(diff);
+		}
+		var _format = function (number) {
+			return (number < 10 ? ('0' + number) : number);
+		};
+		return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
+			_format(date.getHours()) + ':' + _format(date.getMinutes());
+	},
+	parse: function (str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
+		var a = str.split(/[^0-9]/);
+		return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
+	}
+};
+
+module.exports = {
+	formatTime: formatTime,
+	formatLocation: formatLocation,
+	dateUtils: dateUtils
+}

BIN
components/.DS_Store


+ 130 - 0
components/classify-1/classify-1.vue

@@ -0,0 +1,130 @@
+<template>
+	<view class="classify">
+		<view v-if="0 === list.length" style="margin: 0 auto;padding: 50rpx;color: #a8a8a8;">
+			暂无数据
+		</view>
+		<view class="classify-li" v-for="(item, index) in list" :key="index" @click="downLoad(item.link)">
+			<img class="classify-li__img" :src="url+item.imgPath" alt=""></img>
+			<view class="classify-li__text" >
+				{{item.text}}
+				<span v-if="item.count > 0 && item.count > 0" class="hs-hzl-app-count count">
+					{{item.count}}
+				</span>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	export default {
+		name: 'Classify1',
+		props: {
+			list: {
+				type: Array,
+				default: () => []
+			},
+			url: {
+				type: String,
+			}
+		},
+		data() {
+			return {
+				baseURL: uni.$BASE_URL
+			}
+		},
+		onLoad() {
+			this.$goto({
+				url: '../../pages/integral/index'
+			})
+		},
+		methods: {
+			// 打开自定义链接
+			openCustomLink(link = '') {
+				console.log(`link: ${link}`)
+			},
+			downLoad(item) {
+
+				if (item === '../../pageApp/hr/leave') {
+					uni.requestSubscribeMessage({
+						tmplIds: ['qgp7iG6xTRm4JewW8N46nXJT-E6xorFn2hZ2V7gD8wY'],
+						success(res) {}
+					})
+				}
+				if (item === '../../pageA/salary/salary') {
+					uni.requestSubscribeMessage({
+						tmplIds: ['SSsS8EV9dfv-CC7-w_JUKYnfEuWm6FiGL_eED8hf80Q'],
+						success(res) {}
+					})
+				}
+				if (item === '../../pageApp/my/MyApproval') {
+					uni.requestSubscribeMessage({
+						tmplIds: ['Toomi1XWGMzNxOCoPX1rRNj7gLuykgszEzUstXaAp9c'],
+						success(res) {}
+					})
+				}
+
+				//this.$router.push('/pageA/integral/index')
+				uni.removeStorageSync('approval')
+				if (0 < item.indexOf("../page")) {
+					uni.navigateTo({
+						url: item
+					})
+				} else
+				if (item) {
+					let url = encodeURIComponent(item)
+					uni.navigateTo({
+						url: '../../pages/home/myWebView?url=' + url
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.classify {
+		display: flex;
+		justify-content: flex-start;
+		flex-flow: row wrap;
+		padding: 14upx 24upx 8rpx;
+	
+		.classify-li {
+			flex: 0 0 20%;
+			position: relative;
+
+			&__img {
+				display: block;
+				width: 70upx;
+				height: 70upx;
+				margin: 0 auto;
+			}
+
+			&__text {
+				font-size: 24upx;
+				display: block;
+				color: #5a5a5a;
+				text-align: center;
+				margin: 8upx 8upx 14upx 0;
+			}
+		}
+	}
+
+	.hs-hzl-app-count {
+		text-align: center;
+		font-size: 20rpx;
+		font-weight: bold;
+		color: #FFFFFF;
+		background-color: #ff0000;
+		width: 35rpx;
+		height: 35rpx;
+		border-radius: 50%;
+		position: absolute;
+	}
+
+	.count {
+		bottom: 110rpx;
+		left: 70rpx;
+		padding: 0px 0 2rpx 2rpx;
+	}
+</style>

+ 93 - 0
components/falls-list/index.vue

@@ -0,0 +1,93 @@
+<template>
+	<view>
+		<view class="waterfall_left">
+			<view class="waterfall_list" v-for="(item,index) in goodsLeftList" :key="index">
+				<view class="waterfall_list_img">
+					<u-image :src="item.goods_main_pic" mode="widthFix" @load="considerPush"></u-image>
+				</view>
+				<view class="msg-box">
+					<view class="name single-omit">{{item.goods_name}}</view>
+					<view class="price-box flex-align-center">
+						<view class="unit"><text>¥</text>{{item.goods_sku.sku_sale_price}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="waterfall_right">
+			<view class="waterfall_list" v-for="(item,index) in goodsRightList" :key="index">
+				<view class="waterfall_list_img">
+					<u-image :src="item.goods_main_pic" mode="widthFix" @load="considerPush"></u-image>
+				</view>
+				<view class="msg-box">
+					<view class="name single-omit">{{item.goods_name}}</view>
+					<view class="price-box flex-align-center">
+						<view class="unit"><text>¥</text>{{item.goods_sku.sku_sale_price}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			list: {
+				type: Array,
+				required: true
+			},
+		},
+		data() {
+			return {
+				// 左侧商品列表
+				goodsLeftList: [],
+				// 右侧商品列表
+				goodsRightList: [],
+				// 组件数据备份
+				newList: [],
+			}
+		},
+		created() {
+			this.touchOff(); // 触发排列
+		},
+		mounted() {},
+		watch: {
+			list(newValue, oldValue) {
+				this.touchOff()
+			},
+		},
+		computed: {},
+		methods: {
+			// 触发重新排列
+			touchOff() {
+				this.newList = [...this.list];
+				this.goodsLeftList = [];
+				this.goodsRightList = [];
+				if (this.newList.length != 0) {
+					this.goodsLeftList.push(this.newList.shift()); //触发排列
+				}
+
+			},
+			// 计算排列
+			considerPush() {
+				if (this.newList.length == 0) return; //没有数据了
+				let leftH = 0,
+					rightH = 0; //左右高度
+				var query = uni.createSelectorQuery().in(this);
+				query.selectAll('.waterfall_left').boundingClientRect()
+				query.selectAll('.waterfall_right').boundingClientRect()
+				query.exec(res => {
+					leftH = res[0].length != 0 ? res[0][0].height : 0; //防止查询不到做个处理
+					rightH = res[1].length != 0 ? res[1][0].height : 0;
+					if (leftH == rightH || leftH < rightH) {
+						// 相等 || 左边小  
+						this.goodsLeftList.push(this.newList.shift());
+					} else {
+						// 右边小
+						this.goodsRightList.push(this.newList.shift());
+					}
+				});
+			},
+		}
+	}
+</script>

+ 185 - 0
components/homelist/homelist.vue

@@ -0,0 +1,185 @@
+<template>
+	<view style="background-color: #ffffff;">
+		<view style="background-color: #f4f4f4;">
+			<u-row>
+				<u-col span="10">
+					<view style="padding: 10rpx 15px;" class="font-jianju">
+						<u-text :text="title" size="18" color="rgb(55,186,189)"></u-text>
+					</view>
+				</u-col>
+				<u-col span="2">
+					<view @tap.stop="onClick">
+						<u-text v-if="limit !== 0" text="更多>>" color="rgb(83, 201, 255)"></u-text>
+					</view>
+				</u-col>
+			</u-row>
+		</view>
+		<view v-if="list.length === 0 || null === list || undefined === list"
+			style="text-align: center;padding: 50px 0;color: #5a5a5a;">
+			<view class="font-jianju">
+				暂无数据
+			</view>
+		</view>
+		<view v-if="1 === showType" v-for="(item, index) in list" :key="index">
+			<view v-if="limit == 0 || index < limit" @click="ononclick(1,item)"
+				style="border-bottom: 1rpx solid #cfcfcf;">
+				<view style="padding: 10rpx 40rpx;">
+					<u-row>
+						<u-col>
+							<view class="font-jianju">
+								<u-text :text="item.noticeTitle" size="14" color="#474747" mode="text">
+								</u-text>
+							</view>
+						</u-col>
+					</u-row>
+					<u-row>
+						<view style="padding-top: 3px;">
+							<view>
+								<view>
+									<u-text :text="item.createTime" color="#b1b1b1" size="12">
+									</u-text>
+								</view>
+							</view>
+						</view>
+					</u-row>
+				</view>
+			</view>
+		</view>
+		<view v-if="2 === showType" v-for="(item, index) in list" :key="index">
+			<view v-if="limit == 0 || index < limit" style="border-bottom: 1px solid #cfcfcf;padding: 0;"
+				@click="ononclick(2,item)">
+				<view style="padding: 10rpx 40rpx;">
+					<view class="uni-flex uni-row">
+						<view>
+							<img :src="url+item.imgPath"
+								style="border-radius: 5px;width: 198rpx; height: 150.5rpx ;border: 1px solid #f3f3f3;">
+							</img>
+						</view>
+						<view>
+							<view class="font-jianju" style="padding-left: 10px;height: 100%;width: 490rpx">
+								<u-text :text="item.text" mode="text" color="#6c6c6c" size="15">
+								</u-text>
+							</view>
+						</view>
+					</view>
+					<view>
+						<view
+							style="height: 5rpx;padding: 0;position: relative;bottom: 20rpx;text-align: right;color:#b1b1b1;">
+							<view style="font-size: 20rpx;">
+								{{item.updateTime}}
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<view v-if="3 === showType" v-for="(item, index) in list" :key="index">
+			<u-row style="border-bottom: 1px solid #cfcfcf;padding: 10rpx;">
+				<view>
+					<view style="padding: 0 5px 2px 5px;">
+						<u-text :text="item.text" mode="text" bold :lines="3" size="18">
+						</u-text>
+					</view>
+					<view style="padding: 0 5px;">
+						<img :src="url+item.imgPath" width="100%" height="100%"
+							style="border-radius: 5px;border: 1px solid #f3f3f3;">
+						</img>
+					</view>
+					<view style="padding: 0 5px;">
+						<u-text :text="item.updateTime" mode="text" color="#b1b1b1" size="14">
+						</u-text>
+					</view>
+				</view>
+				</u-col>
+			</u-row>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			list: {
+				type: Array,
+				default: () => []
+			},
+			url: {
+				type: String
+			},
+			title: {
+				type: String
+			},
+			showType: {
+				type: Number,
+				default: 0
+			},
+			limit: {
+				type: Number,
+				default: 0
+			}
+		},
+		name: "homelist",
+		data() {
+			return {
+				data: {},
+				show: false,
+				open: false,
+				baseURL: uni.$BASE_URL,
+				timeFormat: uni.$u.timeFormat
+			}
+		},
+		onLoad() {},
+		methods: {
+			ononclick(type, item) {
+				item.type = type
+				uni.setStorageSync("noticeData", item)
+				this.$goto("../../pageA/notice/notice")
+			},
+			// close() {
+			// 	uni.showTabBar({
+			// 		animation: true,
+			// 	})
+			// 	//this.$refs.popup[0].close()
+			// },
+			// dialogConfirm() {
+			// 	uni.showTabBar({
+			// 		animation: true,
+			// 	})
+			// },
+			onClick() {
+				const form = {
+					titile: this.title,
+					limit: 0,
+					showType: this.showType,
+					list: this.list
+				}
+				uni.setStorageSync("moreData", form)
+				this.$goto('../../pages/home/more')
+			},
+			// 打开自定义链接
+			openCustomLink(link = '') {
+				console.log(`link: ${link}`)
+				window.location.href = "https://" + link
+			},
+			downLoad(item) {
+				if (item) {
+					let url = encodeURIComponent(item)
+					uni.navigateTo({
+						url: '../../pages/home/myWebView?url=' + url
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	page {
+		padding: 0px;
+	}
+
+	.font-jianju {
+		letter-spacing: 5rpx;
+	}
+</style>

+ 108 - 0
components/page-nav/page-nav.vue

@@ -0,0 +1,108 @@
+<template>
+	<view class="nav-wrap">
+		<view class="nav-title">
+			<u--image :showLoading="true" src="https://cdn.uviewui.com/uview/common/logo.png" width="70px"
+				height="70px" />
+			<view class="nav-info">
+				<view class="nav-info__title" @tap="jumpToWx">
+					<text class="nav-info__title__text">uView 2.0</text>
+					<!-- #ifdef MP-WEIXIN -->
+					<!-- uni-app不支持text内部的text组件的tap事件,所以放到外部响应tap -->
+					<text class="nav-info__title__jump">查看1.x演示</text>
+					<!-- #endif -->
+				</view>
+				<text class="nav-slogan">多平台快速开发的UI框架</text>
+			</view>
+		</view>
+		<text class="nav-desc">{{desc}}</text>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			desc: String,
+			title: String,
+		},
+		methods: {
+			jumpToWx() {
+				// #ifdef MP-WEIXIN
+				uni.navigateToMiniProgram({
+					appId: 'wx3be833c4a263e0c2'
+				})
+				// #endif
+			}
+		},
+	}
+</script>
+
+<style lang="scss" scoped>
+	.nav-wrap {
+		padding: 15px;
+		position: relative;
+	}
+
+	.lang {
+		position: absolute;
+		top: 15px;
+		right: 15px;
+	}
+
+	.nav-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: flex-start;
+	}
+
+	.nav-info {
+		margin-left: 15px;
+		
+		&__title {
+			/* #ifndef APP-NVUE */
+			display: flex;
+			/* #endif */
+			flex-direction: row;
+			align-items: center;
+			
+			&__text {
+				/* #ifndef APP-NVUE */
+				display: flex;
+				/* #endif */
+				color: $u-main-color;
+				font-size: 25px;
+				font-weight: bold;
+				text-align: left;
+			}
+			
+			&__jump {
+				font-size: 12px;
+				color: $u-primary;
+				font-weight: normal;
+				margin-left: 20px;
+			}
+		}
+	}
+
+	.logo {
+		width: 70px;
+		height: 70px;
+		/* #ifndef APP-NVUE */
+		height: auto;
+		/* #endif */
+	}
+
+	.nav-slogan {
+		color: $u-tips-color;
+		font-size: 14px;
+	}
+
+	.nav-desc {
+		margin-top: 10px;
+		font-size: 14px;
+		color: $u-content-color;
+		line-height: 20px;
+	}
+</style>

+ 380 - 0
components/robby-image-upload/robby-image-upload.vue

@@ -0,0 +1,380 @@
+<template>
+	<view class="imageUploadContainer">
+		<view class="imageUploadList">
+			<view class="imageItem" v-bind:key="index" v-for="(path,index) in imageListData">
+				<image :src="path" :class="{'dragging':isDragging(index)}" draggable="true" @tap="previewImage" :data-index="index" @touchstart="start" @touchmove.stop.prevent="move" @touchend="stop"></image>
+				<view v-if="isShowDel" class="imageDel" @tap="deleteImage" :data-index="index">x</view>
+			</view>
+			<view v-if="isShowAdd" class="imageUpload" @tap="selectImage">+</view>
+		</view>
+		<image v-if="showMoveImage" class="moveImage" :style="{left:posMoveImageLeft, top:posMoveImageTop}" :src="moveImagePath"></image>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:'robby-image-upload',
+		props: ['value','enableDel','enableAdd','enableDrag','serverUrl','formData','header', 'limit','fileKeyName','showUploadProgress','serverUrlDeleteImage'],
+		data() {
+			return {
+				imageBasePos:{
+					x0: -1,
+					y0: -1,
+					w:-1,
+					h:-1,
+				},
+				showMoveImage: false,
+				moveImagePath: '',
+				moveLeft: 0,
+				moveTop: 0,
+				deltaLeft: 0,
+				deltaTop: 0,
+				dragIndex: null,
+				targetImageIndex: null,
+				imageList: [],
+				isDestroyed: false
+			}
+		}, 
+		mounted: function(){
+			this.imageList = this.value
+			
+			if(this.showUploadProgress === false){
+				this.showUploadProgress = false
+			}else{
+				this.showUploadProgress = true
+			}
+		},
+		destroyed: function(){
+			this.isDestroyed = true
+		},
+		computed:{
+			imageListData: function(){
+				if(this.value){
+					return this.value
+				}
+			},
+			posMoveImageLeft: function(){ 
+				return this.moveLeft + 'px'
+			},
+			posMoveImageTop: function(){
+				return this.moveTop + 'px'
+			},
+			isShowDel: function(){
+				if(this.enableDel === false){
+					return false
+				}else{
+					return true
+				}
+			},
+			isShowAdd: function(){
+				if(this.enableAdd === false){
+					return false
+				}
+				
+				if(this.limit && this.imageList.length >= this.limit){
+					return false
+				}
+				
+				return true
+			},
+			isDragable: function(){
+				if(this.enableDrag === false){
+					return false
+				}else{
+					return true
+				}
+			}
+		},
+		methods:{
+			selectImage: function(){
+				var _self = this
+				if(!_self.imageList){
+					_self.imageList = []
+				} 
+				
+				uni.chooseImage({
+					count: _self.limit ? (_self.limit - _self.imageList.length) : 999,
+					success: function(e){
+						var imagePathArr = e.tempFilePaths
+						
+						//如果设置了limit限制,在web上count参数无效,这里做判断控制选择的数量是否合要求
+						//在非微信小程序里,虽然可以选多张,但选择的结果会被截掉
+						//在app里,会自动做选择数量的限制
+						if(_self.limit){
+							var availableImageNumber = _self.limit - _self.imageList.length
+							if(availableImageNumber < imagePathArr.length){
+								uni.showToast({
+									title: '图片总数限制为'+_self.limit+'张,当前还可以选'+availableImageNumber+'张',
+									icon:'none',
+									mask: false,
+									duration: 2000
+								});
+								return
+							}
+						}
+						
+						//检查服务器地址是否设置,设置即表示图片要上传到服务器
+						if(_self.serverUrl){
+							uni.showToast({
+								title: '上传进度:0/' + imagePathArr.length,
+								icon: 'none',
+								mask: false
+							});
+							
+							var remoteIndexStart = _self.imageList.length - imagePathArr.length
+							var promiseWorkList = []
+							var keyname = (_self.fileKeyName ? _self.fileKeyName : 'upload-images')
+							var completeImages = 0
+							
+							for(let i=0; i<imagePathArr.length;i++){
+								promiseWorkList.push(new Promise((resolve, reject)=>{
+									let remoteUrlIndex = remoteIndexStart + i
+									uni.uploadFile({
+										url:_self.serverUrl,
+										fileType: 'image',
+										header: _self.header,
+										formData:_self.formData,
+										filePath: imagePathArr[i], 
+										name: keyname,
+										success: function(res){
+											if(res.statusCode === 200){
+												if(_self.isDestroyed){
+													return
+												}
+												
+												completeImages ++
+												
+												if(_self.showUploadProgress){
+													uni.showToast({
+														title: '上传进度:' + completeImages + '/' + imagePathArr.length,
+														icon: 'none',
+														mask: false,
+														duration: 500
+													});
+												}
+												console.log('success to upload image: ' + res.data)
+												resolve(res.data)
+											}else{
+												console.log('fail to upload image:'+res.data)
+												reject('fail to upload image:' + remoteUrlIndex)
+											}
+										},
+										fail: function(res){
+											console.log('fail to upload image:'+res)
+											reject('fail to upload image:' + remoteUrlIndex)
+										}
+									})
+								}))
+							}
+							Promise.all(promiseWorkList).then((result)=>{
+								if(_self.isDestroyed){
+									return
+								}
+								
+								for(let i=0; i<result.length;i++){
+									_self.imageList.push(result[i])
+								}
+								
+								_self.$emit('add', {
+									currentImages: imagePathArr,
+									allImages: _self.imageList
+								})
+								_self.$emit('input', _self.imageList)
+							})
+						}else{
+							for(let i=0; i<imagePathArr.length;i++){
+								_self.imageList.push(imagePathArr[i])
+							}
+							
+							_self.$emit('add', {
+								currentImages: imagePathArr,
+								allImages: _self.imageList
+							})
+							_self.$emit('input', _self.imageList)
+						}
+					}
+				})
+			},
+			deleteImage: function(e){
+				var imageIndex = e.currentTarget.dataset.index
+				var deletedImagePath = this.imageList[imageIndex]
+				this.imageList.splice(imageIndex, 1) 
+				
+				//检查删除图片的服务器地址是否设置,如果设置则调用API,在服务器端删除该图片
+				if(this.serverUrlDeleteImage){
+					uni.request({
+						url: this.serverUrlDeleteImage,
+						method: 'GET',
+						data: {
+							imagePath: deletedImagePath
+						},
+						success: res => {
+							console.log(res.data)
+						}
+					});
+				}
+				
+				this.$emit('delete',{
+					currentImage: deletedImagePath,
+					allImages: this.imageList
+				})
+				this.$emit('input', this.imageList)
+			},
+			previewImage: function(e){
+				var imageIndex = e.currentTarget.dataset.index
+				uni.previewImage({
+					current: this.imageList[imageIndex],
+					indicator: "number",
+					loop: "true",
+					urls:this.imageList
+				})
+			},
+			initImageBasePos: function(){
+				let paddingRate = 0.024
+				var _self = this
+				//计算图片基准位置
+				uni.getSystemInfo({
+					success: function(obj) {
+						let screenWidth = obj.screenWidth
+						let leftPadding = Math.ceil(paddingRate * screenWidth)
+						let imageWidth = Math.ceil((screenWidth - 2*leftPadding)/4)
+						
+						_self.imageBasePos.x0 = leftPadding
+						_self.imageBasePos.w = imageWidth
+						_self.imageBasePos.h = imageWidth
+					}
+				})
+			},
+			findOverlapImage: function(posX, posY){
+				let rows = Math.floor((posX-this.imageBasePos.x0)/this.imageBasePos.w)
+				let cols = Math.floor((posY-this.imageBasePos.y0)/this.imageBasePos.h)
+				let indx = cols*4 + rows
+				return indx
+			},
+			isDragging: function(indx){
+				return this.dragIndex === indx
+			},
+			start: function(e){
+				console.log(this.isDragable)
+				if(!this.isDragable){
+					return
+				}
+				this.dragIndex = e.currentTarget.dataset.index
+				this.moveImagePath = this.imageList[this.dragIndex]
+				this.showMoveImage = true
+				
+				//计算纵向图片基准位置
+				if(this.imageBasePos.y0 === -1){
+					this.initImageBasePos()
+					
+					let basePosY = Math.floor(this.dragIndex / 4) * this.imageBasePos.h
+					let currentImageOffsetTop = e.currentTarget.offsetTop
+					this.imageBasePos.y0 = currentImageOffsetTop - basePosY
+				}
+				
+				//设置选中图片当前左上角的坐标
+				this.moveLeft = e.target.offsetLeft
+				this.moveTop = e.target.offsetTop
+			},
+			move: function(e){
+				if(!this.isDragable){
+					return
+				}
+				const touch = e.touches[0]
+				this.targetImageIndex = this.findOverlapImage(touch.clientX, touch.clientY)
+				
+				//初始化deltaLeft/deltaTop
+				if(this.deltaLeft === 0){
+					this.deltaLeft = touch.clientX - this.moveLeft
+					this.deltaTop = touch.clientY - this.moveTop 
+				}
+				
+				//设置移动图片位置
+				this.moveLeft = touch.clientX - this.deltaLeft
+				this.moveTop = touch.clientY - this.deltaTop
+			},
+			stop: function(e){
+				if(!this.isDragable){
+					return
+				}
+				if(this.dragIndex !== null && this.targetImageIndex !== null){
+					if(this.targetImageIndex<0){
+						this.targetImageIndex = 0
+					}
+				
+					if(this.targetImageIndex>=this.imageList.length){
+						this.targetImageIndex = this.imageList.length-1
+					}
+					//交换图片
+					if(this.dragIndex !== this.targetImageIndex){
+						this.imageList[this.dragIndex] = this.imageList[this.targetImageIndex]
+						this.imageList[this.targetImageIndex] = this.moveImagePath
+					}
+				}
+				
+				this.dragIndex = null
+				this.targetImageIndex = null
+				this.deltaLeft = 0
+				this.deltaTop = 0
+				this.showMoveImage = false
+				
+				this.$emit('input', this.imageList)
+			}
+		}
+	}
+</script>
+
+<style>
+	.imageUploadContainer{
+		padding: 10upx 5upx;
+		margin: 10upx 5upx;
+	}
+	
+	.dragging{
+		transform: scale(1.2)
+	}
+	
+	.imageUploadList{
+		display: flex;
+		flex-wrap: wrap;
+	}
+	
+	.imageItem, .imageUpload{
+		width: 160upx;
+		height: 160upx;
+		margin: 10upx;
+	}
+	
+	.imageDel{
+		position: relative;
+		left: 120upx;
+		bottom: 165upx;
+		background-color: rgba(0,0,0,0.5);
+		width: 36upx;
+		text-align: center;
+		line-height: 35upx;
+		border-radius: 17upx;
+		color: white;
+		font-size: 30upx;
+		padding-bottom: 2upx;
+	}
+	
+	.imageItem image, .moveImage{
+		width: 160upx;
+		height: 160upx;
+		border-radius: 8upx;
+	}
+	
+	.imageUpload{
+		line-height: 130upx;
+		text-align: center;
+		font-size: 150upx;
+		color: #D9D9D9;
+		border: 1px solid #D9D9D9;
+		border-radius: 8upx;
+	}
+	
+	.moveImage{
+		position: absolute;
+	}
+</style>

Datei-Diff unterdrückt, da er zu groß ist
+ 1 - 0
components/scroll-list/images.js


+ 723 - 0
components/scroll-list/scroll-list.vue

@@ -0,0 +1,723 @@
+<template>
+	<view class="scroll-list-wrap" :style="[scrollListWrapStyle]">
+		<scroll-view class="scroll-view" :class="[elClass]" :style="[listWrapStyle]" scroll-y scroll-anchoring
+			enable-back-to-top :scroll-top="scrollTop" :lower-threshold="defaultOption.lowerThreshold"
+			@scroll="handleScroll" @touchend="handleTouchEnd" @touchmove.prevent.stop="handleTouchMove"
+			@touchstart="handleTouchStart" @scrolltolower="handleScrolltolower">
+			<view class="scroll-content" :style="[scrollContentStyle]">
+				<view class="pull-down-wrap">
+					<slot name="pulldown" v-if="$slots.pulldown"></slot>
+					<view class="refresh-view" :style="[refreshViewStyle]" v-else>
+						<view class="pull-down-animation" :class="{ refreshing: refreshing }"
+							:style="[pullDownAnimationStyle]"></view>
+						<text class="pull-down-text" :style="[pullDownTextStyle]">{{ refreshStateText }}</text>
+					</view>
+				</view>
+				<view class="empty-wrap" v-if="showEmpty">
+					<slot name="empty" v-if="$slots.empty"></slot>
+					<view class="empty-view" v-else>
+						<image class="empty-image" :src="defaultOption.emptyImage || images.empty" mode="aspectFit">
+						</image>
+						<text class="empty-text" :style="[emptyTextStyle]">{{ emptyText }}</text>
+					</view>
+				</view>
+				<view class="list-content">
+					<slot></slot>
+				</view>
+				<view class="pull-up-wrap" v-if="showPullUp">
+					<slot name="pullup" v-if="$slots.pullup"></slot>
+					<view class="load-view" v-else>
+						<view class="pull-up-animation" v-if="loading" :style="[pullUpAnimationStyle]"></view>
+						<text class="pull-up-text" :style="[pullUpTextStyle]">{{ loadStateText }}</text>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import images from './images.js';
+	export default {
+		name: 'scroll-list',
+		props: {
+			// 配置信息
+			option: {
+				type: Object,
+				default: () => ({})
+			}
+		},
+		data() {
+			return {
+				defaultOption: {
+					page: 1, // 分页
+					size: 5, // 分页大小
+					auto: false, // 自动加载
+					height: null, // 组件高度
+					disabled: false, // 禁用
+					background: '', // 背景颜色属性
+					emptyImage: '', // 空数据提示图片
+					offsetBottom: 0, // 底部高度补偿
+					pullDownSpeed: 0.5, // 下拉速率
+					lowerThreshold: 40, // 距离底部上拉加载距离
+					refresherThreshold: 80, // 距离顶部下拉刷新距离
+					refreshDelayed: 100, // 刷新延迟
+					refreshFinishDelayed: 100, // 刷新完成后的延迟
+					safeArea: false, // 是否开启安全区域适配
+					emptyTextColor: '#82848a', // 空提示文字颜色
+					loadTextColor: '#82848a', // 上拉加载文字颜色
+					loadIconColor: '#82848a', // 上拉加载图标颜色
+					refresherTextColor: '#82848a', // 下拉刷新文字颜色
+					refresherIconColor: '#82848a', // 下拉刷新图标颜色
+					emptyText: '暂无列表~', // 空数据提示文字
+					loadingText: '正在加载中~', // 加载中文字
+					loadFailText: '加载失败啦~', // 加载失败文字
+					noMoreText: '没有更多啦~', // 没有更多文字
+					refreshingText: '正在刷新~', // 正在刷新文字
+					refreshFailText: '刷新失败~', // 刷新失败文字
+					refreshSuccessText: '刷新成功~', // 刷新成功文字
+					pulldownText: '下拉刷新~', // 下拉中的文字
+					pulldownFinishText: '松开刷新~' // 下拉完成的文字
+				},
+				images, // 内置图片
+				elClass: '', // 组件动态class
+				windowInfo: {}, // 窗口信息
+				scrollTop: 0, // 距离顶部滚动高度
+				scrollViewTop: -1, // 滚动视图顶部位置
+				scrollViewHeight: 0, // 滚动视图高度
+				currentPage: 1, // 当前分页页码
+				currentSize: 5, // 当前分页大小
+				currentScrollTop: 0, // 当前滚动高度
+				emptyText: '暂无列表~',
+				loadStateText: '正在加载中~', // 加载状态文字
+				refreshStateText: '下拉刷新~', // 刷新状态文字
+				loadDisabled: false, // 是否禁用上拉加载
+				loading: false, // 是否加载中
+				refreshing: false, // 是否刷新中
+				refreshFinish: false, // 是否刷新完成
+				pulldowning: false, // 是否正在下拉
+				pullDownHeight: 0, // 下拉高度
+				showEmpty: false, // 是否显示空数据提示
+				showPullUp: false, // 是否显示上拉加载
+				showPullDown: false // 是否显示下拉刷新
+			};
+		},
+		methods: {
+			// 组件初始化
+			handleInit() {
+				// 合并配置
+				this.defaultOption = Object.assign(this.defaultOption, this.option);
+				this.showEmpty = !this.defaultOption.auto;
+				this.currentPage = this.defaultOption.page;
+				this.currentSize = this.defaultOption.size;
+				this.emptyText = this.defaultOption.emptyText;
+				this.loadStateText = this.defaultOption.loadingText;
+				this.refreshStateText = this.defaultOption.pulldownText;
+				// 计算高度
+				this.queryRect('.' + this.elClass).then(rect => {
+					// 设置组件顶部位置
+					this.scrollViewTop = rect.top;
+					// 判断是否自动加载
+					if (this.defaultOption.auto) this.load();
+				});
+			},
+			// 加载数据
+			load() {
+				if (this.defaultOption.disabled || this.loading || this.loadDisabled) return;
+				// 开启正在加载
+				this.loading = true;
+				// 设置正在加载状态文字
+				this.loadStateText = this.defaultOption.loadingText;
+				// 显示上拉加载
+				this.showPullUp = true;
+				// 分页参数
+				let paging = {
+					page: this.currentPage,
+					size: this.currentSize
+				};
+				// 触发load事件
+				this.$emit('load', paging);
+			},
+			// 加载成功
+			loadSuccess(data = {}) {
+				// 解构数据
+				const {
+					list,
+					total
+				} = data;
+				// 判断列表是否是数组
+				if (Array.isArray(list)) {
+					// 判断列表长度
+					if (list.length) {
+						// 判断列表长度和列表总数是否相同
+						if (list.length >= total) {
+							// 设置禁用上拉加载
+							this.loadDisabled = true;
+							// 加载状态文字
+							this.loadStateText = this.defaultOption.noMoreText;
+						} else {
+							// 关闭禁用上拉加载
+							this.loadDisabled = false;
+							// 设置分页参数
+							this.currentPage++;
+							// 加载状态为加载中
+							this.loadStateText = this.defaultOption.loadingText;
+							// 加载计算
+							this.loadCompute();
+						}
+						// 显示上拉加载
+						this.showPullUp = true;
+						// 隐藏空数据提示
+						this.showEmpty = false;
+					} else {
+						// 设置禁用上拉加载
+						this.loadDisabled = true;
+						// 隐藏上拉加载
+						this.showPullUp = false;
+						// 显示空数据提示
+						this.showEmpty = true;
+					}
+					// 关闭正在加载
+					this.loading = false;
+					this.showPullDown = false;
+					// 触发加载成功事件
+					this.$emit('loadSuccess', list);
+				} else {
+					// 不是数组类型当作加载失败处理
+					this.loadFail();
+					console.error('the list must be a array');
+				}
+			},
+			// 加载失败
+			loadFail() {
+				// 关闭正在加载
+				this.loading = false;
+				// 关闭空数据提示
+				this.showEmpty = false;
+				// 显示上拉加载
+				this.showPullUp = true;
+				// 加载状态为加载失败
+				this.loadStateText = this.defaultOption.loadFailText;
+				// 触发加载失败事件
+				this.$emit('loadFail');
+			},
+			// 刷新数据
+			refresh() {
+				// 如果是下拉刷新
+				if (this.pullDownHeight == this.defaultOption.refresherThreshold) {
+					// 关闭正在加载
+					this.loading = false;
+					// 隐藏上拉加载
+					this.showPullUp = false;
+				} else {
+					// 开启正在加载
+					this.loading = true;
+					// 隐藏空数据提示
+					this.showEmpty = false;
+					// 显示上拉加载
+					this.showPullUp = true;
+					// 设置正在刷新状态文字
+					this.loadStateText = this.defaultOption.refreshingText;
+				}
+				// 设置刷新未完成
+				this.refreshFinish = false;
+				// 开启正在刷新
+				this.refreshing = true;
+				// 设置正在刷新状态文字
+				this.refreshStateText = this.defaultOption.refreshingText;
+				// 设置分页参数
+				this.currentPage = 1;
+				this.currentSize = this.defaultOption.size;
+				let paging = {
+					page: this.currentPage,
+					size: this.currentSize
+				};
+				// 触发refresh事件
+				setTimeout(() => {
+					this.$emit('refresh', paging);
+				}, this.defaultOption.refreshDelayed);
+			},
+			// 刷新成功
+			refreshSuccess(data) {
+				// 解构数据
+				const {
+					list,
+					total
+				} = data;
+				// 判断列表是否是数组
+				if (Array.isArray(list)) {
+					// 判断列表长度
+					if (list.length) {
+						// 判断列表长度和列表总数是否相同
+						if (list.length >= total) {
+							// 设置禁用上拉加载
+							this.loadDisabled = true;
+							// 设置没有更多状态文字
+							this.loadStateText = this.defaultOption.noMoreText;
+						} else {
+							// 设置分页参数
+							this.currentPage++;
+							// 关闭禁用上拉加载
+							this.loadDisabled = false;
+							// 设置加载中状态文字
+							this.loadStateText = this.defaultOption.loadingText;
+							// 开启自动加载
+							this.defaultOption.auto = true;
+							// 加载计算
+							this.loadCompute();
+						}
+						// 关闭空数据提示
+						this.showEmpty = false;
+						// 显示上拉加载
+						this.showPullUp = true;
+					} else {
+						// 设置禁用上拉加载
+						this.loadDisabled = true;
+						// 隐藏上拉加载
+						this.showPullUp = false;
+						// 显示空数据提示
+						this.showEmpty = true;
+						// 设置没有更多状态文字
+						this.loadStateText = this.defaultOption.noMoreText;
+					}
+					// 关闭正在加载
+					this.loading = false;
+					// 设置刷新成功状态文字
+					this.refreshStateText = this.defaultOption.refreshSuccessText;
+					// 关闭正在刷新
+					this.refreshing = false;
+					// 关闭正在下拉
+					this.pulldowning = false;
+					// 触发刷新成功事件
+					this.$emit('refreshSuccess', list);
+					setTimeout(() => {
+						// 设置刷新完成
+						this.refreshFinish = true;
+						// 重置下拉高度
+						this.pullDownHeight = 0;
+						// 隐藏下拉刷新
+						this.showPullDown = false;
+						this.$emit('refreshSuccess');
+					}, this.defaultOption.refreshFinishDelayed);
+				} else {
+					// 不是数组类型当作刷新失败处理
+					this.refreshFail();
+					console.error('the list must be a array');
+				}
+			},
+			// 刷新失败
+			refreshFail() {
+				// 设置加载失败状态文字
+				this.loadStateText = this.defaultOption.refreshFailText;
+				// 设置刷新失败状态文字
+				this.refreshStateText = this.defaultOption.refreshFailText;
+				// 关闭正在加载
+				this.loading = false;
+				// 显示下拉加载
+				this.showPullUp = true;
+				// 关闭正在刷新
+				this.refreshing = false;
+				// 关闭正在下拉
+				this.pulldowning = false;
+				// 延迟执行刷新完成后状态
+				setTimeout(() => {
+					// 设置刷新完成
+					this.refreshFinish = true;
+					// 重置下拉高度
+					this.pullDownHeight = 0;
+					// 隐藏下拉刷新
+					this.showPullDown = false;
+					// 触发刷新失败事件
+					this.$emit('refreshError');
+				}, this.defaultOption.refreshFinishDelayed);
+			},
+			// 加载计算
+			loadCompute() {
+				// 判断是否自动加载
+				if (this.defaultOption.auto) {
+					// 延迟执行下否者可能会高度计算错误
+					setTimeout(() => {
+						this.$nextTick(() => {
+							this.queryRect('.list-content').then(rect => {
+								if (rect.height <= this.scrollViewHeight) {
+									this.load();
+								}
+							});
+						});
+					}, 100);
+				}
+			},
+			// 上拉触底事件
+			handleScrolltolower(e) {
+				console.log("触底加载")
+				this.option.page += 1
+				if (this.loadDisabled) return;
+				this.$emit('scrolltolower', e);
+				this.load();
+			},
+			// 滚动事件
+			handleScroll(event) {
+				this.currentScrollTop = event.detail.scrollTop;
+				this.$emit('scroll', event.detail);
+			},
+			// 触摸按下处理
+			handleTouchStart(event) {
+				if (this.defaultOption.disabled) return;
+				this.currentTouchStartY = event.touches[0].clientY;
+				this.$emit('touchStart', event);
+			},
+			// 触摸按下滑动处理
+			handleTouchMove(event) {
+				if (this.defaultOption.disabled || this.currentScrollTop) return;
+				if (event.touches[0].clientY >= this.currentTouchStartY) {
+					this.pulldowning = true;
+					this.showPullDown = true;
+					let pullDownDistance = (event.touches[0].clientY - this.currentTouchStartY) * this.defaultOption
+						.pullDownSpeed;
+					this.pullDownHeight = pullDownDistance > this.defaultOption.refresherThreshold ? this.defaultOption
+						.refresherThreshold : pullDownDistance;
+					this.refreshStateText =
+						this.pullDownHeight >= this.defaultOption.refresherThreshold ? this.defaultOption
+						.pulldownFinishText : this.defaultOption.pulldownText;
+					this.$emit('touchMove', event);
+				}
+			},
+			// 触摸松开处理
+			handleTouchEnd(event) {
+				if (this.defaultOption.disabled) return;
+				// 当下拉高度小于下拉阈值
+				if (this.pullDownHeight < this.defaultOption.refresherThreshold) {
+					// 关闭正在下拉
+					this.pulldowning = false;
+					// 重置下拉高度
+					this.pullDownHeight = 0;
+					// 隐藏下拉刷新
+					this.showPullDown = false;
+					// 触发下拉中断事件
+					this.$emit('refreshStop');
+				} else {
+					this.refresh();
+				}
+				// 触发下拉触摸松开事件
+				this.$emit('touchEnd', event);
+			},
+			// 更新组件
+			updateScrollView() {
+				if (this.defaultOption.height) {
+					this.scrollViewHeight = uni.upx2px(this.defaultOption.height);
+				} else {
+					this.scrollViewHeight = this.windowInfo.windowHeight - this.scrollViewTop;
+				}
+				this.scrollViewObserve();
+			},
+			// 监听列表高度变化
+			listContentObserve() {
+				this.disconnectObserve('_listContentObserve');
+				const listContentObserve = this.createIntersectionObserver({
+					thresholds: [0, 0.5, 1]
+				});
+				listContentObserve.relativeToViewport({
+					// #ifdef H5
+					top: -(this.windowInfo.windowTop + rect.top),
+					// #endif
+					// #ifndef H5
+					top: -rect.top
+					// #endif
+				});
+			},
+			// 监听组件位置变化
+			scrollViewObserve() {
+				this.disconnectObserve('_scrollViewObserve');
+				this.$nextTick(() => {
+					this.queryRect('.' + this.elClass).then(rect => {
+						const scrollViewObserve = this.createIntersectionObserver({
+							thresholds: [0, 0.5, 1]
+						});
+						scrollViewObserve.relativeToViewport({
+							// #ifdef H5
+							top: -(this.windowInfo.windowTop + rect.top),
+							// #endif
+							// #ifndef H5
+							top: -rect.top
+							// #endif
+						});
+						scrollViewObserve.observe('.' + this.elClass, position => {
+							// #ifdef H5
+							this.scrollViewTop = position.boundingClientRect.top - this.windowInfo
+								.windowTop;
+							// #endif
+							// #ifndef H5
+							this.scrollViewTop = position.boundingClientRect.top;
+							// #endif
+						});
+						this._scrollViewObserve = scrollViewObserve;
+					});
+				});
+			},
+			// 断开监听组件
+			disconnectObserve(observerName) {
+				const observer = this[observerName];
+				observer && observer.disconnect();
+			},
+			// 查询dom节点信息
+			queryRect(selector, all) {
+				return new Promise(resolve => {
+					uni.createSelectorQuery()
+						.in(this)[all ? 'selectAll' : 'select'](selector)
+						.boundingClientRect(rect => {
+							if (all && Array.isArray(rect) && rect.length) {
+								resolve(rect);
+							}
+							if (!all && rect) {
+								resolve(rect);
+							}
+						})
+						.exec();
+				});
+			},
+			// 16进制转RGB
+			hexToRgb(hex) {
+				const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+				hex = hex.replace(shorthandRegex, (m, r, g, b) => {
+					return r + r + g + g + b + b;
+				});
+				const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+				return result ? {
+						r: parseInt(result[1], 16),
+						g: parseInt(result[2], 16),
+						b: parseInt(result[3], 16)
+					} :
+					null;
+			}
+		},
+		computed: {
+			scrollListWrapStyle() {
+				let style = {};
+				style.background = this.defaultOption.background;
+				return style;
+			},
+			// 组件容器样式
+			listWrapStyle() {
+				let style = {};
+				const {
+					offsetBottom
+				} = this.defaultOption;
+				style.height = this.scrollViewHeight - uni.upx2px(offsetBottom) + 'px';
+				if (this.defaultOption.safeArea) style.paddingBottom = 'env(safe-area-inset-bottom) !important';
+				return style;
+			},
+			// 滚动内容样式
+			scrollContentStyle() {
+				const style = {};
+				const {
+					pullDownHeight,
+					pulldowning,
+					showPullDown
+				} = this;
+				style.transform = showPullDown ? `translateY(${pullDownHeight}px)` : `translateY(0px)`;
+				style.transition = pulldowning ? `transform 100ms ease-out` :
+					`transform 200ms cubic-bezier(0.19,1.64,0.42,0.72)`;
+				return style;
+			},
+			// 下拉刷新样式
+			refreshViewStyle() {
+				const style = {};
+				const {
+					showPullDown
+				} = this;
+				style.opacity = showPullDown ? 1 : 0;
+				return style;
+			},
+			// 下拉中动画样式
+			pullDownAnimationStyle() {
+				const style = {};
+				const {
+					refresherIconColor,
+					refresherThreshold
+				} = this.defaultOption;
+				const {
+					refreshing,
+					pullDownHeight
+				} = this;
+				const {
+					r,
+					g,
+					b
+				} = this.hexToRgb(refresherIconColor);
+				const rate = pullDownHeight / refresherThreshold;
+				style.borderColor = `rgba(${r},${g},${b},0.2)`;
+				style.borderTopColor = refresherIconColor;
+				if (!refreshing) {
+					style.transform = `rotate(${360 * rate}deg)`;
+					style.transition = 'transform 100ms linear';
+				}
+				return style;
+			},
+			pullDownTextStyle() {
+				const style = {};
+				const {
+					refresherTextColor
+				} = this.defaultOption;
+				style.color = refresherTextColor;
+				return style;
+			},
+			// 上拉中动画样式
+			pullUpAnimationStyle() {
+				const style = {};
+				const {
+					loadIconColor
+				} = this.defaultOption;
+				const {
+					r,
+					g,
+					b
+				} = this.hexToRgb(loadIconColor);
+				style.borderColor = `rgba(${r},${g},${b},0.2)`;
+				style.borderTopColor = loadIconColor;
+				return style;
+			},
+			// 上拉中文字样式
+			pullUpTextStyle() {
+				const style = {};
+				const {
+					loadTextColor
+				} = this.defaultOption;
+				style.color = loadTextColor;
+				return style;
+			},
+			// 空数据提示文字样式
+			emptyTextStyle() {
+				const style = {};
+				const {
+					emptyTextColor
+				} = this.defaultOption;
+				style.color = emptyTextColor;
+				return style;
+			}
+		},
+		watch: {
+			scrollViewTop(val) {
+				this.updateScrollView();
+			}
+		},
+		created() {
+			this.elClass = 'scroll-view-' + this._uid;
+			this.windowInfo = uni.getSystemInfoSync();
+		},
+		mounted() {
+			this.handleInit();
+		}
+	};
+</script>
+
+<style scoped lang="scss">
+	.scroll-list-wrap {
+		box-sizing: border-box;
+
+		.scroll-view {
+			position: relative;
+
+			.scroll-content {
+				height: 100%;
+				display: flex;
+				will-change: transform;
+				flex-direction: column;
+
+				.pull-down-wrap {
+					left: 0;
+					width: 100%;
+					display: flex;
+					padding: 30rpx 0;
+					position: absolute;
+					align-items: center;
+					justify-content: center;
+					transform: translateY(-100%);
+
+					.refresh-view {
+						display: flex;
+						justify-content: center;
+						align-items: center;
+
+						.pull-down-animation {
+							width: 32rpx;
+							height: 32rpx;
+							border-width: 4rpx;
+							border-style: solid;
+							border-radius: 50%;
+
+							&.refreshing {
+								animation: spin 0.5s linear infinite;
+							}
+
+							@keyframes spin {
+								to {
+									transform: rotate(360deg);
+								}
+							}
+						}
+
+						.pull-down-text {
+							margin-left: 10rpx;
+						}
+					}
+				}
+
+				.empty-wrap {
+					top: 0;
+					left: 0;
+					width: 100%;
+					height: 100%;
+					display: flex;
+					position: absolute;
+					align-items: center;
+					flex-direction: column;
+
+					.empty-view {
+						margin: auto;
+						display: flex;
+						align-items: center;
+						flex-direction: column;
+
+						.empty-image {
+							width: 200rpx;
+							height: 200rpx;
+						}
+
+						.empty-text {
+							color: #606266;
+							margin-top: 20rpx;
+						}
+					}
+				}
+
+				.list-content {}
+
+				.pull-up-wrap {
+					display: flex;
+					align-items: center;
+					justify-content: center;
+
+					.load-view {
+						padding: 20rpx 0;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+
+						.pull-up-animation {
+							width: 32rpx;
+							height: 32rpx;
+							border-width: 4rpx;
+							border-style: solid;
+							border-radius: 50%;
+							animation: spin 0.5s linear infinite;
+						}
+
+						.pull-up-text {
+							margin-left: 10rpx;
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 1386 - 0
components/uqrcode/common/uqrcode.js

@@ -0,0 +1,1386 @@
+//---------------------------------------------------------------------
+// github https://github.com/Sansnn/uQRCode
+// version 2.0.23
+//---------------------------------------------------------------------
+
+let uQRCode = {};
+
+(function() {
+  //---------------------------------------------------------------------
+  // QRCode for JavaScript
+  //
+  // Copyright (c) 2009 Kazuhiko Arase
+  //
+  // URL: http://www.d-project.com/
+  //
+  // Licensed under the MIT license:
+  //   http://www.opensource.org/licenses/mit-license.php
+  //
+  // The word "QR Code" is registered trademark of 
+  // DENSO WAVE INCORPORATED
+  //   http://www.denso-wave.com/qrcode/faqpatent-e.html
+  //
+  //---------------------------------------------------------------------
+
+  //---------------------------------------------------------------------
+  // QR8bitByte
+  //---------------------------------------------------------------------
+
+  function QR8bitByte(data) {
+    this.mode = QRMode.MODE_8BIT_BYTE;
+    this.data = data;
+  }
+
+  QR8bitByte.prototype = {
+
+    getLength: function(buffer) {
+      return this.data.length;
+    },
+
+    write: function(buffer) {
+      for (var i = 0; i < this.data.length; i++) {
+        // not JIS ...
+        buffer.put(this.data.charCodeAt(i), 8);
+      }
+    }
+  };
+
+  //---------------------------------------------------------------------
+  // QRCode
+  //---------------------------------------------------------------------
+
+  function QRCode(typeNumber, errorCorrectLevel) {
+    this.typeNumber = typeNumber;
+    this.errorCorrectLevel = errorCorrectLevel;
+    this.modules = null;
+    this.moduleCount = 0;
+    this.dataCache = null;
+    this.dataList = new Array();
+  }
+
+  QRCode.prototype = {
+
+    addData: function(data) {
+      var newData = new QR8bitByte(data);
+      this.dataList.push(newData);
+      this.dataCache = null;
+    },
+
+    isDark: function(row, col) {
+      if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
+        throw new Error(row + "," + col);
+      }
+      return this.modules[row][col];
+    },
+
+    getModuleCount: function() {
+      return this.moduleCount;
+    },
+
+    make: function() {
+      // Calculate automatically typeNumber if provided is < 1
+      if (this.typeNumber < 1) {
+        var typeNumber = 1;
+        for (typeNumber = 1; typeNumber < 40; typeNumber++) {
+          var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
+          var buffer = new QRBitBuffer();
+          var totalDataCount = 0;
+          for (var i = 0; i < rsBlocks.length; i++) {
+            totalDataCount += rsBlocks[i].dataCount;
+          }
+
+          for (var i = 0; i < this.dataList.length; i++) {
+            var data = this.dataList[i];
+            buffer.put(data.mode, 4);
+            buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+            data.write(buffer);
+          }
+          if (buffer.getLengthInBits() <= totalDataCount * 8)
+            break;
+        }
+        this.typeNumber = typeNumber;
+      }
+      this.makeImpl(false, this.getBestMaskPattern());
+    },
+
+    makeImpl: function(test, maskPattern) {
+
+      this.moduleCount = this.typeNumber * 4 + 17;
+      this.modules = new Array(this.moduleCount);
+
+      for (var row = 0; row < this.moduleCount; row++) {
+
+        this.modules[row] = new Array(this.moduleCount);
+
+        for (var col = 0; col < this.moduleCount; col++) {
+          this.modules[row][col] = null; //(col + row) % 3;
+        }
+      }
+
+      this.setupPositionProbePattern(0, 0);
+      this.setupPositionProbePattern(this.moduleCount - 7, 0);
+      this.setupPositionProbePattern(0, this.moduleCount - 7);
+      this.setupPositionAdjustPattern();
+      this.setupTimingPattern();
+      this.setupTypeInfo(test, maskPattern);
+
+      if (this.typeNumber >= 7) {
+        this.setupTypeNumber(test);
+      }
+
+      if (this.dataCache == null) {
+        this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
+      }
+
+      this.mapData(this.dataCache, maskPattern);
+    },
+
+    setupPositionProbePattern: function(row, col) {
+
+      for (var r = -1; r <= 7; r++) {
+
+        if (row + r <= -1 || this.moduleCount <= row + r) continue;
+
+        for (var c = -1; c <= 7; c++) {
+
+          if (col + c <= -1 || this.moduleCount <= col + c) continue;
+
+          if ((0 <= r && r <= 6 && (c == 0 || c == 6)) ||
+            (0 <= c && c <= 6 && (r == 0 || r == 6)) ||
+            (2 <= r && r <= 4 && 2 <= c && c <= 4)) {
+            this.modules[row + r][col + c] = true;
+          } else {
+            this.modules[row + r][col + c] = false;
+          }
+        }
+      }
+    },
+
+    getBestMaskPattern: function() {
+
+      var minLostPoint = 0;
+      var pattern = 0;
+
+      for (var i = 0; i < 8; i++) {
+
+        this.makeImpl(true, i);
+
+        var lostPoint = QRUtil.getLostPoint(this);
+
+        if (i == 0 || minLostPoint > lostPoint) {
+          minLostPoint = lostPoint;
+          pattern = i;
+        }
+      }
+
+      return pattern;
+    },
+
+    createMovieClip: function(target_mc, instance_name, depth) {
+
+      var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
+      var cs = 1;
+
+      this.make();
+
+      for (var row = 0; row < this.modules.length; row++) {
+
+        var y = row * cs;
+
+        for (var col = 0; col < this.modules[row].length; col++) {
+
+          var x = col * cs;
+          var dark = this.modules[row][col];
+
+          if (dark) {
+            qr_mc.beginFill(0, 100);
+            qr_mc.moveTo(x, y);
+            qr_mc.lineTo(x + cs, y);
+            qr_mc.lineTo(x + cs, y + cs);
+            qr_mc.lineTo(x, y + cs);
+            qr_mc.endFill();
+          }
+        }
+      }
+
+      return qr_mc;
+    },
+
+    setupTimingPattern: function() {
+
+      for (var r = 8; r < this.moduleCount - 8; r++) {
+        if (this.modules[r][6] != null) {
+          continue;
+        }
+        this.modules[r][6] = (r % 2 == 0);
+      }
+
+      for (var c = 8; c < this.moduleCount - 8; c++) {
+        if (this.modules[6][c] != null) {
+          continue;
+        }
+        this.modules[6][c] = (c % 2 == 0);
+      }
+    },
+
+    setupPositionAdjustPattern: function() {
+
+      var pos = QRUtil.getPatternPosition(this.typeNumber);
+
+      for (var i = 0; i < pos.length; i++) {
+
+        for (var j = 0; j < pos.length; j++) {
+
+          var row = pos[i];
+          var col = pos[j];
+
+          if (this.modules[row][col] != null) {
+            continue;
+          }
+
+          for (var r = -2; r <= 2; r++) {
+
+            for (var c = -2; c <= 2; c++) {
+
+              if (r == -2 || r == 2 || c == -2 || c == 2 ||
+                (r == 0 && c == 0)) {
+                this.modules[row + r][col + c] = true;
+              } else {
+                this.modules[row + r][col + c] = false;
+              }
+            }
+          }
+        }
+      }
+    },
+
+    setupTypeNumber: function(test) {
+
+      var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
+
+      for (var i = 0; i < 18; i++) {
+        var mod = (!test && ((bits >> i) & 1) == 1);
+        this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
+      }
+
+      for (var i = 0; i < 18; i++) {
+        var mod = (!test && ((bits >> i) & 1) == 1);
+        this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
+      }
+    },
+
+    setupTypeInfo: function(test, maskPattern) {
+
+      var data = (this.errorCorrectLevel << 3) | maskPattern;
+      var bits = QRUtil.getBCHTypeInfo(data);
+
+      // vertical		
+      for (var i = 0; i < 15; i++) {
+
+        var mod = (!test && ((bits >> i) & 1) == 1);
+
+        if (i < 6) {
+          this.modules[i][8] = mod;
+        } else if (i < 8) {
+          this.modules[i + 1][8] = mod;
+        } else {
+          this.modules[this.moduleCount - 15 + i][8] = mod;
+        }
+      }
+
+      // horizontal
+      for (var i = 0; i < 15; i++) {
+
+        var mod = (!test && ((bits >> i) & 1) == 1);
+
+        if (i < 8) {
+          this.modules[8][this.moduleCount - i - 1] = mod;
+        } else if (i < 9) {
+          this.modules[8][15 - i - 1 + 1] = mod;
+        } else {
+          this.modules[8][15 - i - 1] = mod;
+        }
+      }
+
+      // fixed module
+      this.modules[this.moduleCount - 8][8] = (!test);
+
+    },
+
+    mapData: function(data, maskPattern) {
+
+      var inc = -1;
+      var row = this.moduleCount - 1;
+      var bitIndex = 7;
+      var byteIndex = 0;
+
+      for (var col = this.moduleCount - 1; col > 0; col -= 2) {
+
+        if (col == 6) col--;
+
+        while (true) {
+
+          for (var c = 0; c < 2; c++) {
+
+            if (this.modules[row][col - c] == null) {
+
+              var dark = false;
+
+              if (byteIndex < data.length) {
+                dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
+              }
+
+              var mask = QRUtil.getMask(maskPattern, row, col - c);
+
+              if (mask) {
+                dark = !dark;
+              }
+
+              this.modules[row][col - c] = dark;
+              bitIndex--;
+
+              if (bitIndex == -1) {
+                byteIndex++;
+                bitIndex = 7;
+              }
+            }
+          }
+
+          row += inc;
+
+          if (row < 0 || this.moduleCount <= row) {
+            row -= inc;
+            inc = -inc;
+            break;
+          }
+        }
+      }
+
+    }
+
+  };
+
+  QRCode.PAD0 = 0xEC;
+  QRCode.PAD1 = 0x11;
+
+  QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
+
+    var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
+
+    var buffer = new QRBitBuffer();
+
+    for (var i = 0; i < dataList.length; i++) {
+      var data = dataList[i];
+      buffer.put(data.mode, 4);
+      buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+      data.write(buffer);
+    }
+
+    // calc num max data.
+    var totalDataCount = 0;
+    for (var i = 0; i < rsBlocks.length; i++) {
+      totalDataCount += rsBlocks[i].dataCount;
+    }
+
+    if (buffer.getLengthInBits() > totalDataCount * 8) {
+      throw new Error("code length overflow. (" +
+        buffer.getLengthInBits() +
+        ">" +
+        totalDataCount * 8 +
+        ")");
+    }
+
+    // end code
+    if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
+      buffer.put(0, 4);
+    }
+
+    // padding
+    while (buffer.getLengthInBits() % 8 != 0) {
+      buffer.putBit(false);
+    }
+
+    // padding
+    while (true) {
+
+      if (buffer.getLengthInBits() >= totalDataCount * 8) {
+        break;
+      }
+      buffer.put(QRCode.PAD0, 8);
+
+      if (buffer.getLengthInBits() >= totalDataCount * 8) {
+        break;
+      }
+      buffer.put(QRCode.PAD1, 8);
+    }
+
+    return QRCode.createBytes(buffer, rsBlocks);
+  }
+
+  QRCode.createBytes = function(buffer, rsBlocks) {
+
+    var offset = 0;
+
+    var maxDcCount = 0;
+    var maxEcCount = 0;
+
+    var dcdata = new Array(rsBlocks.length);
+    var ecdata = new Array(rsBlocks.length);
+
+    for (var r = 0; r < rsBlocks.length; r++) {
+
+      var dcCount = rsBlocks[r].dataCount;
+      var ecCount = rsBlocks[r].totalCount - dcCount;
+
+      maxDcCount = Math.max(maxDcCount, dcCount);
+      maxEcCount = Math.max(maxEcCount, ecCount);
+
+      dcdata[r] = new Array(dcCount);
+
+      for (var i = 0; i < dcdata[r].length; i++) {
+        dcdata[r][i] = 0xff & buffer.buffer[i + offset];
+      }
+      offset += dcCount;
+
+      var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
+      var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
+
+      var modPoly = rawPoly.mod(rsPoly);
+      ecdata[r] = new Array(rsPoly.getLength() - 1);
+      for (var i = 0; i < ecdata[r].length; i++) {
+        var modIndex = i + modPoly.getLength() - ecdata[r].length;
+        ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
+      }
+
+    }
+
+    var totalCodeCount = 0;
+    for (var i = 0; i < rsBlocks.length; i++) {
+      totalCodeCount += rsBlocks[i].totalCount;
+    }
+
+    var data = new Array(totalCodeCount);
+    var index = 0;
+
+    for (var i = 0; i < maxDcCount; i++) {
+      for (var r = 0; r < rsBlocks.length; r++) {
+        if (i < dcdata[r].length) {
+          data[index++] = dcdata[r][i];
+        }
+      }
+    }
+
+    for (var i = 0; i < maxEcCount; i++) {
+      for (var r = 0; r < rsBlocks.length; r++) {
+        if (i < ecdata[r].length) {
+          data[index++] = ecdata[r][i];
+        }
+      }
+    }
+
+    return data;
+
+  }
+
+  //---------------------------------------------------------------------
+  // QRMode
+  //---------------------------------------------------------------------
+
+  var QRMode = {
+    MODE_NUMBER: 1 << 0,
+    MODE_ALPHA_NUM: 1 << 1,
+    MODE_8BIT_BYTE: 1 << 2,
+    MODE_KANJI: 1 << 3
+  };
+
+  //---------------------------------------------------------------------
+  // QRErrorCorrectLevel
+  //---------------------------------------------------------------------
+
+  var QRErrorCorrectLevel = {
+    L: 1,
+    M: 0,
+    Q: 3,
+    H: 2
+  };
+
+  //---------------------------------------------------------------------
+  // QRMaskPattern
+  //---------------------------------------------------------------------
+
+  var QRMaskPattern = {
+    PATTERN000: 0,
+    PATTERN001: 1,
+    PATTERN010: 2,
+    PATTERN011: 3,
+    PATTERN100: 4,
+    PATTERN101: 5,
+    PATTERN110: 6,
+    PATTERN111: 7
+  };
+
+  //---------------------------------------------------------------------
+  // QRUtil
+  //---------------------------------------------------------------------
+
+  var QRUtil = {
+
+    PATTERN_POSITION_TABLE: [
+      [],
+      [6, 18],
+      [6, 22],
+      [6, 26],
+      [6, 30],
+      [6, 34],
+      [6, 22, 38],
+      [6, 24, 42],
+      [6, 26, 46],
+      [6, 28, 50],
+      [6, 30, 54],
+      [6, 32, 58],
+      [6, 34, 62],
+      [6, 26, 46, 66],
+      [6, 26, 48, 70],
+      [6, 26, 50, 74],
+      [6, 30, 54, 78],
+      [6, 30, 56, 82],
+      [6, 30, 58, 86],
+      [6, 34, 62, 90],
+      [6, 28, 50, 72, 94],
+      [6, 26, 50, 74, 98],
+      [6, 30, 54, 78, 102],
+      [6, 28, 54, 80, 106],
+      [6, 32, 58, 84, 110],
+      [6, 30, 58, 86, 114],
+      [6, 34, 62, 90, 118],
+      [6, 26, 50, 74, 98, 122],
+      [6, 30, 54, 78, 102, 126],
+      [6, 26, 52, 78, 104, 130],
+      [6, 30, 56, 82, 108, 134],
+      [6, 34, 60, 86, 112, 138],
+      [6, 30, 58, 86, 114, 142],
+      [6, 34, 62, 90, 118, 146],
+      [6, 30, 54, 78, 102, 126, 150],
+      [6, 24, 50, 76, 102, 128, 154],
+      [6, 28, 54, 80, 106, 132, 158],
+      [6, 32, 58, 84, 110, 136, 162],
+      [6, 26, 54, 82, 110, 138, 166],
+      [6, 30, 58, 86, 114, 142, 170]
+    ],
+
+    G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
+    G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
+    G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
+
+    getBCHTypeInfo: function(data) {
+      var d = data << 10;
+      while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
+        d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
+      }
+      return ((data << 10) | d) ^ QRUtil.G15_MASK;
+    },
+
+    getBCHTypeNumber: function(data) {
+      var d = data << 12;
+      while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
+        d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
+      }
+      return (data << 12) | d;
+    },
+
+    getBCHDigit: function(data) {
+
+      var digit = 0;
+
+      while (data != 0) {
+        digit++;
+        data >>>= 1;
+      }
+
+      return digit;
+    },
+
+    getPatternPosition: function(typeNumber) {
+      return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
+    },
+
+    getMask: function(maskPattern, i, j) {
+
+      switch (maskPattern) {
+
+        case QRMaskPattern.PATTERN000:
+          return (i + j) % 2 == 0;
+        case QRMaskPattern.PATTERN001:
+          return i % 2 == 0;
+        case QRMaskPattern.PATTERN010:
+          return j % 3 == 0;
+        case QRMaskPattern.PATTERN011:
+          return (i + j) % 3 == 0;
+        case QRMaskPattern.PATTERN100:
+          return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
+        case QRMaskPattern.PATTERN101:
+          return (i * j) % 2 + (i * j) % 3 == 0;
+        case QRMaskPattern.PATTERN110:
+          return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
+        case QRMaskPattern.PATTERN111:
+          return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
+
+        default:
+          throw new Error("bad maskPattern:" + maskPattern);
+      }
+    },
+
+    getErrorCorrectPolynomial: function(errorCorrectLength) {
+
+      var a = new QRPolynomial([1], 0);
+
+      for (var i = 0; i < errorCorrectLength; i++) {
+        a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
+      }
+
+      return a;
+    },
+
+    getLengthInBits: function(mode, type) {
+
+      if (1 <= type && type < 10) {
+
+        // 1 - 9
+
+        switch (mode) {
+          case QRMode.MODE_NUMBER:
+            return 10;
+          case QRMode.MODE_ALPHA_NUM:
+            return 9;
+          case QRMode.MODE_8BIT_BYTE:
+            return 8;
+          case QRMode.MODE_KANJI:
+            return 8;
+          default:
+            throw new Error("mode:" + mode);
+        }
+
+      } else if (type < 27) {
+
+        // 10 - 26
+
+        switch (mode) {
+          case QRMode.MODE_NUMBER:
+            return 12;
+          case QRMode.MODE_ALPHA_NUM:
+            return 11;
+          case QRMode.MODE_8BIT_BYTE:
+            return 16;
+          case QRMode.MODE_KANJI:
+            return 10;
+          default:
+            throw new Error("mode:" + mode);
+        }
+
+      } else if (type < 41) {
+
+        // 27 - 40
+
+        switch (mode) {
+          case QRMode.MODE_NUMBER:
+            return 14;
+          case QRMode.MODE_ALPHA_NUM:
+            return 13;
+          case QRMode.MODE_8BIT_BYTE:
+            return 16;
+          case QRMode.MODE_KANJI:
+            return 12;
+          default:
+            throw new Error("mode:" + mode);
+        }
+
+      } else {
+        throw new Error("type:" + type);
+      }
+    },
+
+    getLostPoint: function(qrCode) {
+
+      var moduleCount = qrCode.getModuleCount();
+
+      var lostPoint = 0;
+
+      // LEVEL1
+
+      for (var row = 0; row < moduleCount; row++) {
+
+        for (var col = 0; col < moduleCount; col++) {
+
+          var sameCount = 0;
+          var dark = qrCode.isDark(row, col);
+
+          for (var r = -1; r <= 1; r++) {
+
+            if (row + r < 0 || moduleCount <= row + r) {
+              continue;
+            }
+
+            for (var c = -1; c <= 1; c++) {
+
+              if (col + c < 0 || moduleCount <= col + c) {
+                continue;
+              }
+
+              if (r == 0 && c == 0) {
+                continue;
+              }
+
+              if (dark == qrCode.isDark(row + r, col + c)) {
+                sameCount++;
+              }
+            }
+          }
+
+          if (sameCount > 5) {
+            lostPoint += (3 + sameCount - 5);
+          }
+        }
+      }
+
+      // LEVEL2
+
+      for (var row = 0; row < moduleCount - 1; row++) {
+        for (var col = 0; col < moduleCount - 1; col++) {
+          var count = 0;
+          if (qrCode.isDark(row, col)) count++;
+          if (qrCode.isDark(row + 1, col)) count++;
+          if (qrCode.isDark(row, col + 1)) count++;
+          if (qrCode.isDark(row + 1, col + 1)) count++;
+          if (count == 0 || count == 4) {
+            lostPoint += 3;
+          }
+        }
+      }
+
+      // LEVEL3
+
+      for (var row = 0; row < moduleCount; row++) {
+        for (var col = 0; col < moduleCount - 6; col++) {
+          if (qrCode.isDark(row, col) &&
+            !qrCode.isDark(row, col + 1) &&
+            qrCode.isDark(row, col + 2) &&
+            qrCode.isDark(row, col + 3) &&
+            qrCode.isDark(row, col + 4) &&
+            !qrCode.isDark(row, col + 5) &&
+            qrCode.isDark(row, col + 6)) {
+            lostPoint += 40;
+          }
+        }
+      }
+
+      for (var col = 0; col < moduleCount; col++) {
+        for (var row = 0; row < moduleCount - 6; row++) {
+          if (qrCode.isDark(row, col) &&
+            !qrCode.isDark(row + 1, col) &&
+            qrCode.isDark(row + 2, col) &&
+            qrCode.isDark(row + 3, col) &&
+            qrCode.isDark(row + 4, col) &&
+            !qrCode.isDark(row + 5, col) &&
+            qrCode.isDark(row + 6, col)) {
+            lostPoint += 40;
+          }
+        }
+      }
+
+      // LEVEL4
+
+      var darkCount = 0;
+
+      for (var col = 0; col < moduleCount; col++) {
+        for (var row = 0; row < moduleCount; row++) {
+          if (qrCode.isDark(row, col)) {
+            darkCount++;
+          }
+        }
+      }
+
+      var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
+      lostPoint += ratio * 10;
+
+      return lostPoint;
+    }
+
+  };
+
+
+  //---------------------------------------------------------------------
+  // QRMath
+  //---------------------------------------------------------------------
+
+  var QRMath = {
+
+    glog: function(n) {
+
+      if (n < 1) {
+        throw new Error("glog(" + n + ")");
+      }
+
+      return QRMath.LOG_TABLE[n];
+    },
+
+    gexp: function(n) {
+
+      while (n < 0) {
+        n += 255;
+      }
+
+      while (n >= 256) {
+        n -= 255;
+      }
+
+      return QRMath.EXP_TABLE[n];
+    },
+
+    EXP_TABLE: new Array(256),
+
+    LOG_TABLE: new Array(256)
+
+  };
+
+  for (var i = 0; i < 8; i++) {
+    QRMath.EXP_TABLE[i] = 1 << i;
+  }
+  for (var i = 8; i < 256; i++) {
+    QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
+      QRMath.EXP_TABLE[i - 5] ^
+      QRMath.EXP_TABLE[i - 6] ^
+      QRMath.EXP_TABLE[i - 8];
+  }
+  for (var i = 0; i < 255; i++) {
+    QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
+  }
+
+  //---------------------------------------------------------------------
+  // QRPolynomial
+  //---------------------------------------------------------------------
+
+  function QRPolynomial(num, shift) {
+
+    if (num.length == undefined) {
+      throw new Error(num.length + "/" + shift);
+    }
+
+    var offset = 0;
+
+    while (offset < num.length && num[offset] == 0) {
+      offset++;
+    }
+
+    this.num = new Array(num.length - offset + shift);
+    for (var i = 0; i < num.length - offset; i++) {
+      this.num[i] = num[i + offset];
+    }
+  }
+
+  QRPolynomial.prototype = {
+
+    get: function(index) {
+      return this.num[index];
+    },
+
+    getLength: function() {
+      return this.num.length;
+    },
+
+    multiply: function(e) {
+
+      var num = new Array(this.getLength() + e.getLength() - 1);
+
+      for (var i = 0; i < this.getLength(); i++) {
+        for (var j = 0; j < e.getLength(); j++) {
+          num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
+        }
+      }
+
+      return new QRPolynomial(num, 0);
+    },
+
+    mod: function(e) {
+
+      if (this.getLength() - e.getLength() < 0) {
+        return this;
+      }
+
+      var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
+
+      var num = new Array(this.getLength());
+
+      for (var i = 0; i < this.getLength(); i++) {
+        num[i] = this.get(i);
+      }
+
+      for (var i = 0; i < e.getLength(); i++) {
+        num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
+      }
+
+      // recursive call
+      return new QRPolynomial(num, 0).mod(e);
+    }
+  };
+
+  //---------------------------------------------------------------------
+  // QRRSBlock
+  //---------------------------------------------------------------------
+
+  function QRRSBlock(totalCount, dataCount) {
+    this.totalCount = totalCount;
+    this.dataCount = dataCount;
+  }
+
+  QRRSBlock.RS_BLOCK_TABLE = [
+
+    // L
+    // M
+    // Q
+    // H
+
+    // 1
+    [1, 26, 19],
+    [1, 26, 16],
+    [1, 26, 13],
+    [1, 26, 9],
+
+    // 2
+    [1, 44, 34],
+    [1, 44, 28],
+    [1, 44, 22],
+    [1, 44, 16],
+
+    // 3
+    [1, 70, 55],
+    [1, 70, 44],
+    [2, 35, 17],
+    [2, 35, 13],
+
+    // 4		
+    [1, 100, 80],
+    [2, 50, 32],
+    [2, 50, 24],
+    [4, 25, 9],
+
+    // 5
+    [1, 134, 108],
+    [2, 67, 43],
+    [2, 33, 15, 2, 34, 16],
+    [2, 33, 11, 2, 34, 12],
+
+    // 6
+    [2, 86, 68],
+    [4, 43, 27],
+    [4, 43, 19],
+    [4, 43, 15],
+
+    // 7		
+    [2, 98, 78],
+    [4, 49, 31],
+    [2, 32, 14, 4, 33, 15],
+    [4, 39, 13, 1, 40, 14],
+
+    // 8
+    [2, 121, 97],
+    [2, 60, 38, 2, 61, 39],
+    [4, 40, 18, 2, 41, 19],
+    [4, 40, 14, 2, 41, 15],
+
+    // 9
+    [2, 146, 116],
+    [3, 58, 36, 2, 59, 37],
+    [4, 36, 16, 4, 37, 17],
+    [4, 36, 12, 4, 37, 13],
+
+    // 10		
+    [2, 86, 68, 2, 87, 69],
+    [4, 69, 43, 1, 70, 44],
+    [6, 43, 19, 2, 44, 20],
+    [6, 43, 15, 2, 44, 16],
+
+    // 11
+    [4, 101, 81],
+    [1, 80, 50, 4, 81, 51],
+    [4, 50, 22, 4, 51, 23],
+    [3, 36, 12, 8, 37, 13],
+
+    // 12
+    [2, 116, 92, 2, 117, 93],
+    [6, 58, 36, 2, 59, 37],
+    [4, 46, 20, 6, 47, 21],
+    [7, 42, 14, 4, 43, 15],
+
+    // 13
+    [4, 133, 107],
+    [8, 59, 37, 1, 60, 38],
+    [8, 44, 20, 4, 45, 21],
+    [12, 33, 11, 4, 34, 12],
+
+    // 14
+    [3, 145, 115, 1, 146, 116],
+    [4, 64, 40, 5, 65, 41],
+    [11, 36, 16, 5, 37, 17],
+    [11, 36, 12, 5, 37, 13],
+
+    // 15
+    [5, 109, 87, 1, 110, 88],
+    [5, 65, 41, 5, 66, 42],
+    [5, 54, 24, 7, 55, 25],
+    [11, 36, 12],
+
+    // 16
+    [5, 122, 98, 1, 123, 99],
+    [7, 73, 45, 3, 74, 46],
+    [15, 43, 19, 2, 44, 20],
+    [3, 45, 15, 13, 46, 16],
+
+    // 17
+    [1, 135, 107, 5, 136, 108],
+    [10, 74, 46, 1, 75, 47],
+    [1, 50, 22, 15, 51, 23],
+    [2, 42, 14, 17, 43, 15],
+
+    // 18
+    [5, 150, 120, 1, 151, 121],
+    [9, 69, 43, 4, 70, 44],
+    [17, 50, 22, 1, 51, 23],
+    [2, 42, 14, 19, 43, 15],
+
+    // 19
+    [3, 141, 113, 4, 142, 114],
+    [3, 70, 44, 11, 71, 45],
+    [17, 47, 21, 4, 48, 22],
+    [9, 39, 13, 16, 40, 14],
+
+    // 20
+    [3, 135, 107, 5, 136, 108],
+    [3, 67, 41, 13, 68, 42],
+    [15, 54, 24, 5, 55, 25],
+    [15, 43, 15, 10, 44, 16],
+
+    // 21
+    [4, 144, 116, 4, 145, 117],
+    [17, 68, 42],
+    [17, 50, 22, 6, 51, 23],
+    [19, 46, 16, 6, 47, 17],
+
+    // 22
+    [2, 139, 111, 7, 140, 112],
+    [17, 74, 46],
+    [7, 54, 24, 16, 55, 25],
+    [34, 37, 13],
+
+    // 23
+    [4, 151, 121, 5, 152, 122],
+    [4, 75, 47, 14, 76, 48],
+    [11, 54, 24, 14, 55, 25],
+    [16, 45, 15, 14, 46, 16],
+
+    // 24
+    [6, 147, 117, 4, 148, 118],
+    [6, 73, 45, 14, 74, 46],
+    [11, 54, 24, 16, 55, 25],
+    [30, 46, 16, 2, 47, 17],
+
+    // 25
+    [8, 132, 106, 4, 133, 107],
+    [8, 75, 47, 13, 76, 48],
+    [7, 54, 24, 22, 55, 25],
+    [22, 45, 15, 13, 46, 16],
+
+    // 26
+    [10, 142, 114, 2, 143, 115],
+    [19, 74, 46, 4, 75, 47],
+    [28, 50, 22, 6, 51, 23],
+    [33, 46, 16, 4, 47, 17],
+
+    // 27
+    [8, 152, 122, 4, 153, 123],
+    [22, 73, 45, 3, 74, 46],
+    [8, 53, 23, 26, 54, 24],
+    [12, 45, 15, 28, 46, 16],
+
+    // 28
+    [3, 147, 117, 10, 148, 118],
+    [3, 73, 45, 23, 74, 46],
+    [4, 54, 24, 31, 55, 25],
+    [11, 45, 15, 31, 46, 16],
+
+    // 29
+    [7, 146, 116, 7, 147, 117],
+    [21, 73, 45, 7, 74, 46],
+    [1, 53, 23, 37, 54, 24],
+    [19, 45, 15, 26, 46, 16],
+
+    // 30
+    [5, 145, 115, 10, 146, 116],
+    [19, 75, 47, 10, 76, 48],
+    [15, 54, 24, 25, 55, 25],
+    [23, 45, 15, 25, 46, 16],
+
+    // 31
+    [13, 145, 115, 3, 146, 116],
+    [2, 74, 46, 29, 75, 47],
+    [42, 54, 24, 1, 55, 25],
+    [23, 45, 15, 28, 46, 16],
+
+    // 32
+    [17, 145, 115],
+    [10, 74, 46, 23, 75, 47],
+    [10, 54, 24, 35, 55, 25],
+    [19, 45, 15, 35, 46, 16],
+
+    // 33
+    [17, 145, 115, 1, 146, 116],
+    [14, 74, 46, 21, 75, 47],
+    [29, 54, 24, 19, 55, 25],
+    [11, 45, 15, 46, 46, 16],
+
+    // 34
+    [13, 145, 115, 6, 146, 116],
+    [14, 74, 46, 23, 75, 47],
+    [44, 54, 24, 7, 55, 25],
+    [59, 46, 16, 1, 47, 17],
+
+    // 35
+    [12, 151, 121, 7, 152, 122],
+    [12, 75, 47, 26, 76, 48],
+    [39, 54, 24, 14, 55, 25],
+    [22, 45, 15, 41, 46, 16],
+
+    // 36
+    [6, 151, 121, 14, 152, 122],
+    [6, 75, 47, 34, 76, 48],
+    [46, 54, 24, 10, 55, 25],
+    [2, 45, 15, 64, 46, 16],
+
+    // 37
+    [17, 152, 122, 4, 153, 123],
+    [29, 74, 46, 14, 75, 47],
+    [49, 54, 24, 10, 55, 25],
+    [24, 45, 15, 46, 46, 16],
+
+    // 38
+    [4, 152, 122, 18, 153, 123],
+    [13, 74, 46, 32, 75, 47],
+    [48, 54, 24, 14, 55, 25],
+    [42, 45, 15, 32, 46, 16],
+
+    // 39
+    [20, 147, 117, 4, 148, 118],
+    [40, 75, 47, 7, 76, 48],
+    [43, 54, 24, 22, 55, 25],
+    [10, 45, 15, 67, 46, 16],
+
+    // 40
+    [19, 148, 118, 6, 149, 119],
+    [18, 75, 47, 31, 76, 48],
+    [34, 54, 24, 34, 55, 25],
+    [20, 45, 15, 61, 46, 16]
+  ];
+
+  QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
+
+    var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
+
+    if (rsBlock == undefined) {
+      throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" +
+        errorCorrectLevel);
+    }
+
+    var length = rsBlock.length / 3;
+
+    var list = new Array();
+
+    for (var i = 0; i < length; i++) {
+
+      var count = rsBlock[i * 3 + 0];
+      var totalCount = rsBlock[i * 3 + 1];
+      var dataCount = rsBlock[i * 3 + 2];
+
+      for (var j = 0; j < count; j++) {
+        list.push(new QRRSBlock(totalCount, dataCount));
+      }
+    }
+
+    return list;
+  }
+
+  QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
+
+    switch (errorCorrectLevel) {
+      case QRErrorCorrectLevel.L:
+        return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
+      case QRErrorCorrectLevel.M:
+        return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
+      case QRErrorCorrectLevel.Q:
+        return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
+      case QRErrorCorrectLevel.H:
+        return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
+      default:
+        return undefined;
+    }
+  }
+
+  //---------------------------------------------------------------------
+  // QRBitBuffer
+  //---------------------------------------------------------------------
+
+  function QRBitBuffer() {
+    this.buffer = new Array();
+    this.length = 0;
+  }
+
+  QRBitBuffer.prototype = {
+
+    get: function(index) {
+      var bufIndex = Math.floor(index / 8);
+      return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
+    },
+
+    put: function(num, length) {
+      for (var i = 0; i < length; i++) {
+        this.putBit(((num >>> (length - i - 1)) & 1) == 1);
+      }
+    },
+
+    getLengthInBits: function() {
+      return this.length;
+    },
+
+    putBit: function(bit) {
+
+      var bufIndex = Math.floor(this.length / 8);
+      if (this.buffer.length <= bufIndex) {
+        this.buffer.push(0);
+      }
+
+      if (bit) {
+        this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
+      }
+
+      this.length++;
+    }
+  };
+
+  //---------------------------------------------------------------------
+  // Support Chinese
+  //---------------------------------------------------------------------
+  function utf16To8(text) {
+    var result = '';
+    var c;
+    for (var i = 0; i < text.length; i++) {
+      c = text.charCodeAt(i);
+      if (c >= 0x0001 && c <= 0x007F) {
+        result += text.charAt(i);
+      } else if (c > 0x07FF) {
+        result += String.fromCharCode(0xE0 | c >> 12 & 0x0F);
+        result += String.fromCharCode(0x80 | c >> 6 & 0x3F);
+        result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+      } else {
+        result += String.fromCharCode(0xC0 | c >> 6 & 0x1F);
+        result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+      }
+    }
+    return result;
+  }
+
+  uQRCode = {
+    errorCorrectLevel: QRErrorCorrectLevel,
+
+    defaults: {
+      size: 354,
+      margin: 0,
+      backgroundColor: '#FFFFFF',
+      foregroundColor: '#000000',
+      fileType: 'png', // 'jpg', 'png'
+      errorCorrectLevel: QRErrorCorrectLevel.H,
+      typeNumber: -1
+    },
+
+    getModules: function(options) {
+      // options = Object.assign(this.defaults, options); // 不能用Object.assign,它会导致this.defaults被污染
+      options = {
+        ...this.defaults,
+        ...options
+      };
+      var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
+      qrcode.addData(utf16To8(options.text));
+      qrcode.make();
+      return qrcode.modules;
+    },
+
+    make: function(options, componentInstance) {
+      return new Promise((resolve, reject) => {
+        options = {
+          ...this.defaults,
+          ...options
+        }
+        if (!options.canvasId) {
+          throw new Error('uQRCode: Please set canvasId!');
+        }
+        var modules = this.getModules(options);
+        var tileW = (options.size - options.margin * 2) / modules.length;
+        var tileH = tileW;
+        var startTime = Date.now();
+
+        var ctx = uni.createCanvasContext(options.canvasId, componentInstance);
+        // ctx.draw(false); // 解决重复绘制,ctx.draw(true);调用过多导致真机卡顿、掉帧等问题
+        ctx.setFillStyle(options.backgroundColor);
+        ctx.fillRect(0, 0, options.size, options.size);
+        for (var row = 0; row < modules.length; row++) {
+          for (var col = 0; col < modules.length; col++) {
+            // 计算每一个小块的位置
+            var x = Math.round(col * tileW) + options.margin;
+            var y = Math.round(row * tileH) + options.margin;
+            var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
+            var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
+            var style = modules[row][col] ?
+              options.foregroundColor :
+              options.backgroundColor;
+            ctx.setFillStyle(style);
+            ctx.fillRect(x, y, w, h);
+            // ctx.draw(true);
+          }
+        }
+        
+        var drawDelay = options.drawDelay ? options.drawDelay : options.size * 2;
+        setTimeout(function() {
+          ctx.draw(false, function() {
+            // canvasToTempFilePath不加延时在微信小程序安卓端会混乱,所有问题主要就出现在这:canvasToTempFilePath,本来绘制是正确的,调用它的过程中,组件还是绘制状态,所以导致绘制异常,因为没有确保状态正常的回调方法,draw的回调也不行,所以加延时确保组件状态正常,再调用。
+            var drawTime = Date.now() - startTime;
+            var toFileDelay = options.toFileDelay ?
+              options.toFileDelay :
+              drawTime + // draw绘制耗费时间
+              (options.size * 2) + // 绘制大小的宽高,用来作为耗时参数
+              (modules.length * 2); // 矩阵信息,对应宽高,用来作为耗时参数
+            setTimeout(function() {
+              uni.canvasToTempFilePath({
+                canvasId: options.canvasId,
+                fileType: options.fileType,
+                width: options.size,
+                height: options.size,
+                destWidth: options.size,
+                destHeight: options.size,
+                success: function(res) {
+                  resolve(Object.assign(res, {
+                    time: Date.now() - startTime
+                  }));
+                },
+                fail: function(err) {
+                  reject(err);
+                }
+              }, componentInstance);
+            }, toFileDelay);
+          });
+        }, drawDelay);
+
+      });
+    }
+
+  }
+
+})();
+
+export default uQRCode;

+ 163 - 0
components/uqrcode/uqrcode.vue

@@ -0,0 +1,163 @@
+<template>
+	<view class="uqrcode">
+		<view v-if="options.mode === 'view'" class="uqrcode-view" :style="{
+      'width': `${options.size}px`, 
+      'height': `${options.size}px`,
+      'padding': `${options.margin}px`,
+      'background-color': options.backgroundColor
+      }">
+			<view class="uqrcode-view-row" v-for="(row, rowIndex) in modules.length" :key="rowIndex">
+				<view class="uqrcode-view-col" v-for="(col, colIndex) in modules.length" :key="colIndex" :style="{
+        	'width': `${colSize}px`,
+        	'height': `${colSize}px`,
+        	'background-color': modules[rowIndex][colIndex] ? options.foregroundColor : options.backgroundColor
+        	}">
+				</view>
+			</view>
+		</view>
+		<canvas v-else-if="options.mode === 'canvas'" class="uqrcode-canvas" :id="options.canvasId"
+			:canvas-id="options.canvasId" :style="{'width': `${options.size}px`, 'height': `${options.size}px`}" />
+	</view>
+</template>
+
+<script>
+	import uqrcode from './common/uqrcode'
+
+	export default {
+		name: 'uqrcode',
+		// props: {
+		//   mode: {
+		//     type: String,
+		//     default: 'view' // view|canvas
+		//   }
+		// },
+		data() {
+			return {
+				options: uqrcode.defaults,
+				modules: [],
+				result: {}
+			}
+		},
+		computed: {
+			colSize() {
+				return (this.options.size - this.options.margin * 2) / this.modules.length
+			}
+		},
+		methods: {
+			make(options) {
+				options = {
+					...this.options,
+					...options
+				}
+				if (!options.mode) {
+					options.mode = 'view'
+				}
+				if (!options.canvasId) {
+					options.canvasId = this.uuid()
+				}
+				this.options = options
+				if (options.mode === 'view') {
+					this.modules = uqrcode.getModules(options)
+				} else if (options.mode === 'canvas') {
+					return new Promise((resolve, reject) => {
+						uqrcode.make(options, this).then(res => {
+							this.result = res
+							resolve({
+								...res
+							})
+						}).catch(err => {
+							reject(err)
+						})
+					})
+				}
+			},
+			save() {
+				if (this.options.mode === 'view') {
+					uni.showToast({
+						icon: 'none',
+						title: 'view模式不支持保存,请提示用户使用截屏保存'
+					})
+				} else if (this.options.mode === 'canvas') {
+					// #ifdef H5
+					uni.showToast({
+						icon: 'none',
+						title: 'canvas H5不支持保存,请将二维码放置在image组件,再提示用户长按image保存'
+					})
+					// #endif
+					// #ifndef H5
+					uni.saveImageToPhotosAlbum({
+						filePath: this.result.tempFilePath,
+						success: (res) => {
+							uni.showToast({
+								icon: 'success',
+								title: '保存成功'
+							})
+						},
+						fail: (err) => {
+							uni.showToast({
+								icon: 'none',
+								title: JSON.stringify(err)
+							})
+						}
+					})
+					// #endif
+				}
+			},
+			uuid(len = 32, firstU = true, radix = null) {
+				let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
+				let uuid = [];
+				radix = radix || chars.length;
+
+				if (len) {
+					// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
+					for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
+				} else {
+					let r;
+					// rfc4122标准要求返回的uuid中,某些位为固定的字符
+					uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+					uuid[14] = '4';
+
+					for (let i = 0; i < 36; i++) {
+						if (!uuid[i]) {
+							r = 0 | Math.random() * 16;
+							uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+						}
+					}
+				}
+
+				// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
+				if (firstU) {
+					uuid.shift();
+					return 'u' + uuid.join('');
+				} else {
+					return uuid.join('');
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	.uqrcode-view {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uqrcode-view-row {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uqrcode-view-col {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		box-sizing: border-box;
+		/* #endif */
+	}
+</style>

+ 60 - 0
components/zai-lattice/index.css

@@ -0,0 +1,60 @@
+.zai-lattice-box {
+	width: 90%;
+	margin: 0 auto;
+	position: relative;
+	background: #a59ae2;
+	color: #fff;
+	border-radius: 30upx;
+	transition: background-color 3s;
+}
+
+.zai-lattice-box-shadow {
+	box-shadow: 0 4upx 30upx 0 #3c3556d9;
+}
+
+.zai-lattice-box .zai-lattice-box-p {
+	padding: 40upx;
+	position: relative;
+}
+
+.zai-lattice-box-p .zai-lattice-title {
+	color: #EFEEF2;
+	margin-top: 40upx;
+	font-size: 34upx;
+}
+
+.zai-lattice-box-p .zai-lattice-num {
+	margin-bottom: 30upx;
+}
+
+.zai-lattice-box-p .zai-lattice-num .zai-lattice-num-title {
+	font-weight: 600;
+	font-size: 52upx;
+}
+
+.zai-lattice-box-p .zai-lattice-num .zai-lattice-num-unit {
+	font-size: 34upx;
+	margin-left: 10upx;
+	color: #A1A0B5;
+}
+
+.zai-lattice-box-p .zai-lattice-icon {
+	color: #A1A0B5;
+	font-size: 66upx;
+	position: absolute;
+	right: 40upx;
+	bottom: 40upx;
+}
+
+.zai-lattice-box-p .zai-lattice-img {
+	position: absolute;
+	right: 40upx;
+	bottom: 40upx;
+	width: 66upx;
+	height: 66upx;
+}
+
+.zai-lattice-box-p .zai-lattice-img .zai-lattice-image {
+	width: 66upx;
+	height: 66upx;
+}

+ 107 - 0
components/zai-lattice/index.vue

@@ -0,0 +1,107 @@
+<template name="zai-lattice">
+	<view class="zai-lattice-box" :class="shadow?'zai-lattice-box-shadow':''" :style="{'background':backgroundColor}">
+		<view class="zai-lattice-box-p">
+			<progress :percent="progressPercent" class="zai-progress" active stroke-width="5" :backgroundColor="backgroundColor"
+				:activeColor="progressColor" />
+			<view class="zai-lattice-title" :style="{color:titleColor}">{{title}}</view>
+			<view class="zai-lattice-num">
+				<text class="zai-lattice-num-title" :style="{color:numColor}">{{num}}</text>
+				<text class="zai-lattice-num-unit" :style="{color:unitColor}">{{unit}}</text>
+			</view>
+			<view class="zai-lattice-icon" v-if="type=='icon'" :class="icon"
+				:style="{color:iconColor,'font-size':fontSize}"></view>
+			<view class="zai-lattice-img" v-if="type=='img'" :style="{width:fontSize,height:fontSize}"
+				@click="onClick()">
+				<image :src="src" mode="aspectFit" class="zai-lattice-image" :style="{width:fontSize,height:fontSize}">
+				</image>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "zai-lattice",
+		props: {
+			//背景颜色
+			backgroundColor: {
+				type: [String],
+				default: '#4F496C'
+			},
+			//是否开启阴影
+			shadow: Boolean,
+			//进度条颜色
+			progressColor: {
+				type: [String],
+				default: '#2086D8'
+			},
+			//进度条位置
+			progressPercent: {
+				type: [Number],
+				default: 0
+			},
+			//名称
+			title: String,
+			//数量
+			num: {
+				type: [Number, String],
+				default: 0
+			},
+			//单位
+			unit: String,
+			//字体图标
+			icon: String,
+			//图片地址
+			src: {
+				type: [String],
+				default: '../../static/img/control/close.png'
+			},
+			//图标颜色
+			iconColor: {
+				type: [String],
+				default: '#A1A0B5'
+			},
+			//单位颜色
+			unitColor: {
+				type: [String],
+				default: '#A1A0B5'
+			},
+			//数量颜色
+			numColor: {
+				type: [String],
+				default: '#ffffff'
+			},
+			//名称颜色
+			titleColor: {
+				type: [String],
+				default: '#EFEEF2'
+			},
+			//图标或图片大小
+			size: {
+				type: [Number, String],
+				default: 33
+			},
+			//图标类型
+			type: {
+				type: [String],
+				default: 'icon'
+			},
+		},
+		computed: {
+			fontSize() {
+				var size = Number(this.size)
+				size = isNaN(size) ? 33 : size
+				return `${size}px`
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style>
+	@import "./index.css";
+</style>

BIN
components/zhoujessie-SideCategoryList/.DS_Store


+ 60 - 0
components/zhoujessie-SideCategoryList/READ_ME.md

@@ -0,0 +1,60 @@
+### 版本号
+1.0.2
+
+### 描述
+侧边栏导航,类似于美团外卖商品列表页,支持右侧滚动时左侧对应到相应锚点,支持右侧滚动时对应锚点吸顶。
+
+### 使用方式
+```
+<!-- 例子:带banner的时候的设置 -->
+<view :style="[styleObj]"></view>
+<category-list :height="500" :offsetTop="offsetTop" :defaultActive="defaultActive"  :categoryList="categoryList" @categoryMainClick="categoryMainClick"
+ @categorySubClick="categorySubClick"></category-list>
+	 
+ <!-- 例子:组件占领整个页面的设置 -->
+<category-list :defaultActive="defaultActive" :categoryList="categoryList" @categoryMainClick="categoryMainClick"
+	@categorySubClick="categorySubClick"></category-list>
+```
+
+### 参数说明
+| 属性名 | 说明 | 类型 | 默认值 | 备注
+| ------ | ------ | ------ | ------ | ------ |
+| height | 当前列表的高度 | Number | 屏幕高度  | 单位:px |
+| sticky | 是否开启锚点自动吸顶 | Boolean | true | |
+| offsetTop | 锚点自动吸顶时与顶部的距离 | Number | 0 | 单位:px |
+| defaultActive | 默认选中的index值 | Number | 0 | |
+| zIndex | 锚点吸顶时的层级 | Number | 965 | |
+| categoryList | 列表 | Array | [] | 结构为[{name: 'xx', subCategoryList: []}] |
+| label | 内容列表中label对应的key名字 | String | 'name' | |
+| activeTextColor | 左侧选中时文字颜色 | String | '#2979ff' | |
+| activeBackgroundColor | 左侧选中时文字背景色 | String | '#eeeeee' | |
+| categoryMainClick | 选中左侧索引时触发 | Function |  | |
+| categorySubClick | 选中右侧内容项时触发 | Function |  | |
+
+### 注意事项
+1.方法`$getRect`为全局方法,用于查询节点信息,参考了 uView 的 `$uGetRect`,该方法可定义在入口文件。
+`getRect` 挂载到`Vue.prototype`上,因为这方法需要使用`in(this)`,所以无法把它独立成一个单独的文件导出。
+若项目中已引用uView库,则将该组件里使用的 `$getRect` 方法替换为 uView 对应方法`$uGetRect`即可。
+
+```
+// 入口文件 main.js
+Vue.prototype.$getRect = function(selector, all) {
+	return new Promise(resolve => {
+		uni.createSelectorQuery().
+		in(this)[all ? 'selectAll' : 'select'](selector)
+			.boundingClientRect(rect => {
+				if (all && Array.isArray(rect) && rect.length) {
+					resolve(rect)
+				}
+				if (!all && rect) {
+					resolve(rect)
+				}
+			})
+			.exec()
+	})
+}
+
+```
+2.`offset`字段中已做了适配浏览器的处理(顶部增加44px)。
+
+3.注意在微信小程序中,style的写法不支持vue官方文档,例如上面使用方式中 `style` 绑定 `styleObj`。

+ 292 - 0
components/zhoujessie-SideCategoryList/category-list.vue

@@ -0,0 +1,292 @@
+<template>
+	<view>
+		<view class="nav">
+			<!-- 左侧 -->
+			<view class="nav-left">
+				<scroll-view scroll-y scroll-with-animation :scrollTop="scrollLeftTop" :style="[{height: containerHeight + 'px'}]">
+					<!-- TODO: 可自行修改样式,绑定事件等 -->
+					<view class="nav-left-item" v-for="(item,index) in categoryList" @click="handleClickCate(item,index)" :key="index"
+					 :style="[index==activeIndex?activeStyle:null]">
+						{{item[label]}}
+					</view>
+				</scroll-view>
+			</view>
+
+			<!-- 右侧 -->
+			<view class="nav-right">
+				<scroll-view @scroll="scrollRight" :scroll-top="scrollTop" scroll-y :height="containerHeight" :style="[{height: containerHeight + 'px'}]"
+				 scroll-with-animation>
+					<index-list-component :sticky="sticky" :zIndex="zIndex" :offsetTop="stickyOffsetTop" @activeIndexChange="handleActiveIndexChange"
+					 ref="indexListRef" :defaultActiveIndex="defaultActive" :scrollTop="scrollRightTop" :index-list="indexList"
+					 @changeScrollTop="handleChangeScrollTop">
+						<view v-for="(item, index) in categoryList" :key="index">
+							<index-anchor :customStyle="{right: 'auto', left: 'auto'}" :index="item.name" />
+							<!-- TODO: 可自行修改样式,绑定事件等 -->
+							<view class="nav-right-item" v-for="(subItem, subItemIndex) in item.subCategoryList" :key="subItemIndex" @click="handleClickSub(subItem)">
+								<image class="item-img" mode="scaleToFill" :src="subItem[imgSrc]" />
+								<view class="item-label">{{subItem[label]}}</view>
+							</view>
+						</view>
+					</index-list-component>
+				</scroll-view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import IndexListComponent from './index-list.vue'
+	import IndexAnchor from './index-anchor.vue'
+	/**
+	 * categoryList 类目索引列表
+	 * @description 通过点击左侧索引到达右侧内容位置,参考了uView的<IndexList>所以列表组件
+	 * @tutorial 参考了 https://www.uviewui.com/components/indexList.html
+	 * @property {Number} height 当前列表的高度,若不设置默认为屏幕高度 
+	 * @property {Boolean} sticky 是否开启锚点自动吸顶(默认true)
+	 * @property {Number String} offsetTop 锚点自动吸顶时与顶部的距离(默认0)
+	 * @property {Number} defaultActive 默认选中的index值
+	 * @property {Number String} zIndex 锚点吸顶时的层级(默认965)
+	 * @property {Array} categoryList 内容列表,结构为 {name: 'xx', subCategoryList: []}
+	 * @property {String} label 内容列表中label对应的key名字,默认为 'name'
+	 * @property {String} activeTextColor 选中时文字颜色
+	 * @property {String} activeBackgroundColor 选中时背景色
+	 * @event {Function} categoryMainClick 选中左侧索引时触发
+	 * @event {Function} categorySubClick 选中右侧内容项时触发
+	 * @example <category-list :height="400" :defaultActive="2" :offsetTop="200" :categoryList="categoryList" :subCategoryList="subCategoryList" @categoryMainClick="categoryMainClick"
+		 @categorySubClick="categorySubClick"></category-list>
+	 */
+	export default {
+		name: "category",
+		data() {
+			return {
+				containerHeight: 0, // 记录height
+				scrollTop: 0,
+				scrollLeftTop: 0,
+				scrollRightTop: 0,
+				scrollHeight: 0,
+				activeStyle: {
+					color: this.activeTextColor,
+					backgroundColor: this.activeBackgroundColor
+				},
+				activeIndex: -1,
+				sideBarAnchorsRect: [],
+			}
+		},
+		props: {
+			height: {
+				type: Number,
+				default: 0
+			},
+			sticky: {
+				type: Boolean,
+				default: true
+			},
+			offsetTop: {
+				type: Number,
+				default: 0
+			},
+			zIndex: {
+				type: Number,
+				default: 965
+			},
+
+			defaultActive: {
+				type: Number,
+				default: 0
+			},
+			//主分类List
+			categoryList: {
+				type: Array,
+				default: () => {
+					return null;
+				}
+			},
+			activeTextColor: {
+				type: String,
+				default: '#2979ff'
+			},
+			activeBackgroundColor: {
+				type: String,
+				default: '#eee'
+			},
+			label: {
+				type: String,
+				default: 'name'
+			},
+			imgSrc: {
+				type: String,
+				default: 'logo'
+			},
+			//主分类点击事件
+			categoryMainClick: {},
+		},
+		computed: {
+			indexList() {
+				return this.categoryList.map((category) => category.name)
+			},
+			stickyOffsetTop() {
+				let offsetTop = this.offsetTop || 0
+				// #ifdef H5
+				offsetTop = offsetTop + 44;
+				// #endif
+				return offsetTop
+			}
+		},
+
+		methods: {
+			scroll(e) {
+				this.scrollHeight = e.detail.scrollHeight;
+			},
+			scrollRight(e) {
+				this.scrollRightTop = e.detail.scrollTop;
+			},
+			handleClickCate(category, index) {
+				this.$emit('categoryMainClick', category)
+				this.activeIndex = index;
+				// 滑动右侧列表到指定index位置
+				this.$refs.indexListRef.scrollToAnchor(index)
+			},
+			handleClickSub(subItem) {
+				this.$emit('categorySubClick', subItem)
+			},
+			handleChangeScrollTop(wraperScrollTop) {
+				this.scrollTop = wraperScrollTop
+			},
+			// 监听右侧滚动时index的变化
+			handleActiveIndexChange(index) {
+				if (this.activeIndex == index) return
+				this.activeIndex = index
+			},
+			// 获取side-bar中每项的rect
+			setSideBarAnchorsRect() {
+				const sideBarAnchorList = []
+				this.$getRect('.nav-left-item', true).then(rect => {
+					this.sideBarAnchorsRect = rect.map(item => {
+						return {
+							height: item.height,
+							top: item.top
+						}
+					})
+
+				});
+			},
+			scrollToLeftAnchor(index) {
+				const windowHeight = this.containerHeight
+				const halfWindowHeight = windowHeight / 2
+				let stickyOffsetTop = this.offsetTop
+				// // #ifdef H5
+				// stickyOffsetTop = this.offsetTop - 44;
+				// // #endif
+				// // #ifndef H5
+				// stickyOffsetTop = this.offsetTop;
+				// // #endif
+				const targetIndexTop = this.sideBarAnchorsRect[index] && (this.sideBarAnchorsRect[index].top - stickyOffsetTop)
+				if (targetIndexTop > halfWindowHeight) {
+					this.scrollLeftTop = targetIndexTop - halfWindowHeight
+				} else {
+					this.scrollLeftTop = 0
+				}
+			}
+		},
+		
+		mounted() {
+			this.activeIndex = this.defaultActive
+			uni.getSystemInfo({
+				success: res => {
+					const height = this.height
+					const windowHeight = res.windowHeight // 可使用窗口高度
+					if(height) {
+						// 限制containerHeight的值,避免传入的height值过大而出现滚动条
+						const remainHeight = windowHeight - this.stickyOffsetTop // 因设置了offsetTop后剩余的height值
+						if(height > remainHeight){
+							this.containerHeight = remainHeight
+						}else {
+							this.containerHeight = height
+						}
+					} else {
+						this.containerHeight = windowHeight
+					}
+				}
+			})
+			this.setSideBarAnchorsRect()
+		},
+		watch: {
+			activeIndex(newValue, oldValue) {
+				if (newValue != oldValue) {
+					// 滑动左侧列表到指定位置
+					this.scrollToLeftAnchor(newValue)
+				}
+			}
+		},
+		components: {
+			IndexAnchor,
+			IndexListComponent
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.nav {
+		display: flex;
+		width: 100%;
+	}
+
+	.nav-left {
+		width: 30%;
+	}
+
+	.nav-left-item {
+		height: 50px;
+		border-right: solid 1px #E0E0E0;
+		border-bottom: solid 1px #E0E0E0;
+		font-size: 14px;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.nav-right {
+		width: 70%;
+
+		.sub-title {
+			font-weight: bold;
+			font-size: 14px;
+		}
+	}
+
+	.nav-right-item {
+		text-align: center;
+		padding: 5px;
+		font-size: 13px;
+		display: flex;
+		margin-bottom: 10px;
+
+		.item-img {
+			width: 50px;
+			height: 50px;
+			margin-right: 10px;
+		}
+
+		.item-label {
+
+		}
+	}
+
+	.active {
+		color: #F24544;
+	}
+
+	.padding {
+		height: var(--status-bar-height);
+		width: 100%;
+		top: 0;
+		position: fixed;
+		background-color: #F24544;
+	}
+
+	.line {
+		height: 1px;
+		width: 100%;
+		background-color: #eee;
+	}
+</style>

+ 79 - 0
components/zhoujessie-SideCategoryList/index-anchor.vue

@@ -0,0 +1,79 @@
+<template>
+	<view class="u-index-anchor-wrapper" :style="[wrapperStyle]">
+		<view class="u-index-anchor" :class="[active ? 'u-index-anchor--active' : '']" :style="[customAnchorStyle]">
+			<slot v-if="useSlot" />
+			<block v-else>
+				<text>{{ index }}</text>
+			</block>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * indexAnchor 索引列表锚点
+	 * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用
+	 * @tutorial https://www.uviewui.com/components/indexList.html#indexanchor-props
+	 * @property {Boolean} use-slot 是否使用自定义内容的插槽(默认false)
+	 * @property {String Number} index 索引字符,如果定义了use-slot,此参数自动失效
+	 * @property {Object} custStyle 自定义样式,对象形式,如"{color: 'red'}"
+	 * @event {Function} default 锚点位置显示内容,默认为索引字符
+	 * @example <u-index-anchor :index="item" />
+	 */
+	export default {
+		name: "u-index-anchor",
+		props: {
+			useSlot: {
+				type: Boolean,
+				default: false
+			},
+			index: {
+				type: String,
+				default: ''
+			},
+			customStyle: {
+				type: Object,
+				default () {
+					return {}
+				}
+			}
+		},
+		data() {
+			return {
+				active: false,
+				wrapperStyle: {},
+				anchorStyle: {}
+			}
+		},
+		inject: ['UIndexList'],
+		mounted() {
+			this.UIndexList.children.push(this);
+			this.UIndexList.updateData();
+		},
+		computed: {
+			customAnchorStyle() {
+				return Object.assign(this.anchorStyle, this.customStyle);
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.u-index-anchor {
+		box-sizing: border-box;
+		padding: 14rpx 24rpx;
+		color: #606266;
+		width: 100%;
+		font-weight: 500;
+		font-size: 28rpx;
+		line-height: 1.2;
+		background-color: rgb(245, 245, 245);
+	}
+
+	.u-index-anchor--active {
+		right: 0;
+		left: 0;
+		color: #2979ff;
+		background-color: #fff;
+	}
+</style>

+ 268 - 0
components/zhoujessie-SideCategoryList/index-list.vue

@@ -0,0 +1,268 @@
+<template>
+	<view class="u-index-bar">
+		<slot />
+	</view>
+</template>
+
+<script>
+	/**
+	 * indexList 索引列表
+	 * @description 通过折叠面板收纳内容区域,搭配<u-index-anchor>使用
+	 * @tutorial https://www.uviewui.com/components/indexList.html#indexanchor-props
+	 * @property {Number String} scroll-top 当前滚动高度,自定义组件无法获得滚动条事件,所以依赖接入方传入
+	 * @property {Array} index-list 索引字符列表,数组(默认A-Z)
+	 * @property {Number String} z-index 锚点吸顶时的层级(默认965)
+	 * @property {Boolean} sticky 是否开启锚点自动吸顶(默认true)
+	 * @property {Number String} offset-top 锚点自动吸顶时与顶部的距离(默认0)
+	 * @property {String} highlight-color 锚点和右边索引字符高亮颜色(默认#2979ff)
+	 * @event {Function} select 选中右边索引字符时触发
+	 * @example <u-index-list :scrollTop="scrollTop"></u-index-list>
+	 */
+	export default {
+		name: "u-index-list",
+		props: {
+			defaultActiveIndex: {
+				type: Number,
+				default: 0
+			},
+			sticky: {
+				type: Boolean,
+				default: true
+			},
+			zIndex: {
+				type: [Number, String],
+			},
+			scrollTop: {
+				type: [Number, String],
+				default: 0,
+			},
+			offsetTop: {
+				type: [Number, String],
+				default: 0
+			},
+			activeColor: {
+				type: String,
+				default: '#2979ff'
+			}
+		},
+		created() {
+			this.stickyOffsetTop = 0
+			// #ifdef H5
+			this.stickyOffsetTop = this.offsetTop - 44;
+			// #endif
+			// #ifndef H5
+			this.stickyOffsetTop = this.offsetTop;
+			// #endif
+			// 只能在created生命周期定义children,如果在data定义,会因为在子组件中通过provide/inject
+			// 进行push时而导致的莫名其妙的错误
+			this.children = [];
+		},
+
+		provide() {
+			return {
+				UIndexList: this
+			}
+		},
+
+		data() {
+			const defaultActiveIndex = this.defaultActiveIndex
+			return {
+				isInit: true,
+				activeAnchorIndex: defaultActiveIndex,
+				height: 0,
+				top: 0,
+			}
+		},
+		watch: {
+			scrollTop(newValue) {
+				this.updateData()
+			}
+		},
+		methods: {
+			updateData() {
+				this.timer && clearTimeout(this.timer);
+				this.timer = setTimeout(() => {
+					this.setRect().then(() => {
+						this.onScroll();
+					});
+				}, 0);
+			},
+			setRect() {
+				return Promise.all([
+					this.setAnchorsRect(),
+					this.setListRect(),
+				]);
+			},
+			setAnchorsRect() {
+				const stickyOffsetTop = this.stickyOffsetTop
+				return Promise.all(this.children.map((anchor, index) => anchor
+					.$getRect('.u-index-anchor-wrapper')
+					.then((rect) => {
+						Object.assign(anchor, {
+							height: rect.height,
+							top: rect.top - stickyOffsetTop
+						});
+					})));
+			},
+			setListRect() {
+				return this.$getRect('.u-index-bar').then((rect) => {
+					// console.log('.u-index-bar.rect.top', rect.top + this.scrollTop - this.offsetTop)
+					Object.assign(this, {
+						height: rect.height,
+						top: rect.top + this.scrollTop
+					});
+				});
+			},
+			getActiveAnchorIndex() {
+				const {
+					children
+				} = this;
+				const {
+					sticky
+				} = this;
+				for (let i = this.children.length - 1; i >= 0; i--) {
+					const preAnchorHeight = i > 0 ? children[i - 1].height : 0;
+					const reachTop = sticky ? preAnchorHeight : 0;
+					if (reachTop >= children[i].top) {
+						// console.log(preAnchorHeight)
+						return i;
+					}
+				}
+				return 0;
+			},
+			onScroll() {
+				const {
+					children = []
+				} = this;
+				if (!children.length) {
+					return;
+				}
+				const {
+					sticky,
+					offsetTop,
+					scrollTop,
+					zIndex,
+					activeColor
+				} = this;
+				let active = -1
+				if (this.isInit && this.defaultActiveIndex) {
+					// 初始
+					this.isInit = false
+					active = this.defaultActiveIndex
+					this.scrollToAnchor(active)
+				} else {
+					active = this.getActiveAnchorIndex();
+				}
+				this.activeAnchorIndex = active;
+				this.$emit('activeIndexChange', active)
+				if (sticky) {
+					let isActiveAnchorSticky = false;
+					if (active !== -1) {
+						isActiveAnchorSticky =
+							children[active].top <= 0;
+					}
+					children.forEach((item, index) => {
+						if (index === active) {
+							let wrapperStyle = '';
+							let anchorStyle = {
+								color: `${activeColor}`
+							};
+							if (isActiveAnchorSticky) {
+								wrapperStyle = {
+									height: `${children[index].height}px`
+								};
+								anchorStyle = {
+									position: 'fixed',
+									top: `${offsetTop}px`,
+									zIndex: `${zIndex ? zIndex : this.zIndex}`,
+									color: `${activeColor}`
+								};
+							}
+							item.active = active;
+							item.wrapperStyle = wrapperStyle;
+							item.anchorStyle = anchorStyle;
+						} else if (index === active - 1) {
+							const currentAnchor = children[index];
+							const currentOffsetTop = currentAnchor.top;
+							const targetOffsetTop = index === children.length - 1 ?
+								this.top :
+								children[index + 1].top;
+							const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
+							const translateY = parentOffsetHeight - currentAnchor.height;
+							const anchorStyle = {
+								position: 'relative',
+								transform: `translate3d(0, ${translateY}px, 0)`,
+								zIndex: `${zIndex ? zIndex : this.zIndex}`,
+								color: `${activeColor}`
+							};
+							item.active = active;
+							item.anchorStyle = anchorStyle;
+						} else {
+							item.active = false;
+							item.anchorStyle = '';
+							item.wrapperStyle = '';
+						}
+					});
+				}
+			},
+			scrollToAnchor(index) {
+				if (this.scrollToAnchorIndex === index) {
+					return;
+				}
+				this.scrollToAnchorIndex = index;
+
+				const anchor = this.children && this.children[index];
+				if (anchor) {
+					this.$emit('changeScrollTop', anchor.top + this.scrollTop);
+				}
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	.u-index-bar {
+		position: relative
+	}
+
+	// .u-index-bar__sidebar {
+	// 	position: fixed;
+	// 	top: 50%;
+	// 	right: 0;
+	// 	display: flex;
+	// 	flex-direction: column;
+	// 	text-align: center;
+	// 	transform: translateY(-50%);
+	// 	user-select: none;
+	// 	z-index: 99;
+	// }
+
+	.u-index-bar__index {
+		font-weight: 500;
+		padding: 8rpx 18rpx;
+		font-size: 22rpx;
+		line-height: 1
+	}
+
+	.u-indexed-list-alert {
+		position: fixed;
+		width: 120rpx;
+		height: 120rpx;
+		right: 90rpx;
+		top: 50%;
+		margin-top: -60rpx;
+		border-radius: 24rpx;
+		font-size: 50rpx;
+		color: #fff;
+		background-color: rgba(0, 0, 0, 0.65);
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		padding: 0;
+		z-index: 9999999;
+	}
+
+	.u-indexed-list-alert text {
+		line-height: 50rpx;
+	}
+</style>

+ 97 - 0
main.js

@@ -0,0 +1,97 @@
+import Vue from 'vue'
+import App from './App'
+import store from './store'
+import WpTabbar from '@/pages/tabbar/wpTabbar'
+// 引入全局uView
+import uView from '@/uni_modules/uview-ui'
+import mixin from './common/mixin'
+import postSelect from 'pageApp/components/postSelect.vue'
+import deptSelect from 'pageApp/components/deptSelect.vue'
+import dictSelect from 'pageApp/components/dictSelect.vue'
+import input from 'pageApp/components/input.vue'
+import show from 'pageApp/components/show.vue'
+import flowSubmit from 'pageApp/components/flowSubmit.vue'
+import photo from 'pageApp/components/photo.vue'
+import wsRequest from 'util/webSocket/wsRequest.js'
+
+import {
+	httpRequest,
+	BASE_URL,
+	BASE_SOCKET_URL,
+	goto,
+	goTab,
+	goBack,
+	dateResult,
+	showModal,
+	getDicts,
+	dictTranslation,
+	getUrlType,
+	getConfigData,
+	getAllConfigData,
+	getAllDicts
+} from './util/request/api.js'
+Vue.component('wp-tabbar', WpTabbar);
+Vue.prototype.$httpRequest = httpRequest
+Vue.prototype.$BASE_URL = BASE_URL
+Vue.prototype.$BASE_SOCKET_URL = BASE_SOCKET_URL
+Vue.prototype.$goto = goto
+Vue.prototype.$goTab = goTab
+Vue.prototype.$goBack = goBack
+Vue.prototype.$dateResult = dateResult
+Vue.prototype.$showModal = showModal
+Vue.prototype.$getDicts = getDicts
+Vue.prototype.$getUrlType = getUrlType
+Vue.prototype.$dictTranslation = dictTranslation
+Vue.prototype.$getConfigData = getConfigData
+Vue.prototype.$getAllConfigData = getAllConfigData
+Vue.prototype.$getAllDicts = getAllDicts
+Vue.prototype.$wsConnection = new wsRequest(8000)
+
+// 入口文件 main.js
+Vue.prototype.$getRect = function(selector, all) {
+	return new Promise(resolve => {
+		uni.createSelectorQuery().
+		in(this)[all ? 'selectAll' : 'select'](selector)
+			.boundingClientRect(rect => {
+				if (all && Array.isArray(rect) && rect.length) {
+					resolve(rect)
+				}
+				if (!all && rect) {
+					resolve(rect)
+				}
+			})
+			.exec()
+	})
+}
+
+Vue.prototype.$store = store
+
+Vue.component('hs-post-select', postSelect)
+Vue.component('hs-dept-select', deptSelect)
+Vue.component('hs-dict-select', dictSelect)
+Vue.component('hs-input', input)
+Vue.component('hs-show', show)
+Vue.component('hs-flow-submit', flowSubmit)
+Vue.component('hs-photo', photo)
+
+Vue.config.productionTip = false
+
+App.mpType = 'app'
+Vue.use(uView)
+
+// #ifdef MP
+// 引入uView对小程序分享的mixin封装
+const mpShare = require('@/uni_modules/uview-ui/libs/mixin/mpShare.js')
+Vue.mixin(mpShare)
+// #endif
+Vue.mixin(mixin)
+
+const app = new Vue({
+	store,
+	...App
+})
+
+// 引入请求封装
+require('./util/request/index')(app)
+
+app.$mount()

+ 161 - 0
manifest.json

@@ -0,0 +1,161 @@
+{
+    "name" : "会助理",
+    "appid" : "__UNI__CCEB8E1",
+    "description" : "院务系统移动端-会助理APP",
+    "versionName" : "1.4.2.01",
+    "versionCode" : 27,
+    "transformPx" : false,
+    "app-plus" : {
+        //"popGesture" : "none",
+        "optimization" : {
+            "subPackages" : true
+        },
+        "safearea" : {
+            "background" : "#ffffff",
+            "bottom" : {
+                "offset" : "none"
+            }
+        },
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : false,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "modules" : {
+            "Webview-x5" : {},
+            "Push" : {},
+            "OAuth" : {}
+        },
+        "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.BLUETOOTH_PRIVILEGED\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ],
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a" ]
+            },
+            "ios" : {
+                "idfa" : false,
+                "privacyDescription" : {
+                    "NSPhotoLibraryUsageDescription" : "需要您的相册权限选择本地图片修改头像",
+                    "NSPhotoLibraryAddUsageDescription" : "保存到本地",
+                    "NSLocalNetworkUsageDescription" : "访问互联网"
+                }
+            },
+            "sdkConfigs" : {
+                "ad" : {
+                    "sigmob" : {}
+                },
+                "push" : {
+                    "unipush" : {
+                        "version" : "2",
+                        "offline" : false
+                    }
+                },
+                "oauth" : {
+                    "weixin" : {
+                        "appid" : "wxafec1ba2cf8721e3",
+                        "UniversalLinks" : ""
+                    }
+                },
+                "share" : {}
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "",
+                    "xhdpi" : "",
+                    "xxhdpi" : "",
+                    "xxxhdpi" : ""
+                },
+                "ios" : {}
+            },
+            "splashscreen" : {
+                "androidStyle" : "default",
+                "android" : {
+                    "hdpi" : "",
+                    "xhdpi" : "",
+                    "xxhdpi" : ""
+                },
+                "iosStyle" : "common"
+            }
+        }
+    },
+    "quickapp" : {},
+    "mp-weixin" : {
+        "appid" : "wxafec1ba2cf8721e3",
+        "setting" : {
+            "urlCheck" : true,
+            "es6" : false,
+            "minified" : true,
+            "postcss" : true
+        },
+        "optimization" : {
+            "subPackages" : true
+        },
+        "usingComponents" : true,
+        "permission" : {},
+        "unipush" : {
+            "enable" : false
+        }
+    },
+    "mp-alipay" : {
+        "usingComponents" : true,
+        "component2" : true
+    },
+    "mp-qq" : {
+        "optimization" : {
+            "subPackages" : true
+        },
+        "appid" : "15646153"
+    },
+    "mp-baidu" : {
+        "usingComponents" : true,
+        "appid" : ""
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true,
+        "appid" : ""
+    },
+    "h5" : {
+        "template" : "template.h5.html",
+        "router" : {
+            "mode" : "hash",
+            "base" : ""
+        },
+        "optimization" : {
+            "treeShaking" : {
+                "enable" : false
+            }
+        },
+        "title" : "uView UI",
+        "sdkConfigs" : {
+            "maps" : {}
+        },
+        "domain" : ""
+    },
+    "fallbackLocale" : "zh-Hans"
+}

+ 5 - 0
package-lock.json

@@ -0,0 +1,5 @@
+{
+	"name": "滚动列表【自动加载,上拉加载,下拉刷新,可自定义】",
+	"version": "1.1.0",
+	"lockfileVersion": 1
+}

+ 14 - 0
package.json

@@ -0,0 +1,14 @@
+{
+    "id": "scroll-list",
+    "name": "滚动列表【自动加载,上拉加载,下拉刷新,可自定义】",
+    "version": "1.1.0",
+    "description": "滚动列表【自动加载,上拉加载,下拉刷新,可自定义】",
+    "keywords": [
+        "自动加载",
+        "上拉加载",
+        "下拉刷新",
+        "可自定义",
+        "滚动"
+    ],
+    "dependencies": {}
+}

+ 4874 - 0
pageA/address/data.js

@@ -0,0 +1,4874 @@
+//data.js
+export default [{
+		"name": "北京市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"东城区",
+				"西城区",
+				"崇文区",
+				"宣武区",
+				"朝阳区",
+				"丰台区",
+				"石景山区",
+				"海淀区",
+				"门头沟区",
+				"房山区",
+				"通州区",
+				"顺义区",
+				"昌平区",
+				"大兴区",
+				"平谷区",
+				"怀柔区",
+				"密云县",
+				"延庆县"
+			]
+		}]
+	},
+	{
+		"name": "天津市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"和平区",
+				"河东区",
+				"河西区",
+				"南开区",
+				"河北区",
+				"红桥区",
+				"塘沽区",
+				"汉沽区",
+				"大港区",
+				"东丽区",
+				"西青区",
+				"津南区",
+				"北辰区",
+				"武清区",
+				"宝坻区",
+				"宁河县",
+				"静海县",
+				"蓟 县"
+			]
+		}]
+	},
+	{
+		"name": "河北省",
+		"city": [{
+				"name": "石家庄市",
+				"area": [
+					"长安区",
+					"桥东区",
+					"桥西区",
+					"新华区",
+					"郊 区",
+					"井陉矿区",
+					"井陉县",
+					"正定县",
+					"栾城县",
+					"行唐县",
+					"灵寿县",
+					"高邑县",
+					"深泽县",
+					"赞皇县",
+					"无极县",
+					"平山县",
+					"元氏县",
+					"赵 县",
+					"辛集市",
+					"藁",
+					"晋州市",
+					"新乐市",
+					"鹿泉市"
+				]
+			},
+			{
+				"name": "唐山市",
+				"area": [
+					"路南区",
+					"路北区",
+					"古冶区",
+					"开平区",
+					"新 区",
+					"丰润县",
+					"滦 县",
+					"滦南县",
+					"乐亭县",
+					"迁西县",
+					"玉田县",
+					"唐海县",
+					"遵化市",
+					"丰南市",
+					"迁安市"
+				]
+			},
+			{
+				"name": "秦皇岛市",
+				"area": [
+					"海港区",
+					"山海关区",
+					"北戴河区",
+					"青龙满族自治县",
+					"昌黎县",
+					"抚宁县",
+					"卢龙县"
+				]
+			},
+			{
+				"name": "邯郸市",
+				"area": [
+					"邯山区",
+					"丛台区",
+					"复兴区",
+					"峰峰矿区",
+					"邯郸县",
+					"临漳县",
+					"成安县",
+					"大名县",
+					"涉 县",
+					"磁 县",
+					"肥乡县",
+					"永年县",
+					"邱 县",
+					"鸡泽县",
+					"广平县",
+					"馆陶县",
+					"魏 县",
+					"曲周县",
+					"武安市"
+				]
+			},
+			{
+				"name": "邢台市",
+				"area": [
+					"桥东区",
+					"桥西区",
+					"邢台县",
+					"临城县",
+					"内丘县",
+					"柏乡县",
+					"隆尧县",
+					"任 县",
+					"南和县",
+					"宁晋县",
+					"巨鹿县",
+					"新河县",
+					"广宗县",
+					"平乡县",
+					"威 县",
+					"清河县",
+					"临西县",
+					"南宫市",
+					"沙河市"
+				]
+			},
+			{
+				"name": "保定市",
+				"area": [
+					"新市区",
+					"北市区",
+					"南市区",
+					"满城县",
+					"清苑县",
+					"涞水县",
+					"阜平县",
+					"徐水县",
+					"定兴县",
+					"唐 县",
+					"高阳县",
+					"容城县",
+					"涞源县",
+					"望都县",
+					"安新县",
+					"易 县",
+					"曲阳县",
+					"蠡 县",
+					"顺平县",
+					"博野",
+					"雄县",
+					"涿州市",
+					"定州市",
+					"安国市",
+					"高碑店市"
+				]
+			},
+			{
+				"name": "张家口",
+				"area": [
+					"桥东区",
+					"桥西区",
+					"宣化区",
+					"下花园区",
+					"宣化县",
+					"张北县",
+					"康保县",
+					"沽源县",
+					"尚义县",
+					"蔚 县",
+					"阳原县",
+					"怀安县",
+					"万全县",
+					"怀来县",
+					"涿鹿县",
+					"赤城县",
+					"崇礼县"
+				]
+			},
+			{
+				"name": "承德市",
+				"area": [
+					"双桥区",
+					"双滦区",
+					"鹰手营子矿区",
+					"承德县",
+					"兴隆县",
+					"平泉县",
+					"滦平县",
+					"隆化县",
+					"丰宁满族自治县",
+					"宽城满族自治县",
+					"围场满族蒙古族自治县"
+				]
+			},
+			{
+				"name": "沧州市",
+				"area": [
+					"新华区",
+					"运河区",
+					"沧 县",
+					"青 县",
+					"东光县",
+					"海兴县",
+					"盐山县",
+					"肃宁县",
+					"南皮县",
+					"吴桥县",
+					"献 县",
+					"孟村回族自治县",
+					"泊头市",
+					"任丘市",
+					"黄骅市",
+					"河间市"
+				]
+			},
+			{
+				"name": "廊坊市",
+				"area": [
+					"安次区",
+					"固安县",
+					"永清县",
+					"香河县",
+					"大城县",
+					"文安县",
+					"大厂回族自治县",
+					"霸州市",
+					"三河市"
+				]
+			},
+			{
+				"name": "衡水市",
+				"area": [
+					"桃城区",
+					"枣强县",
+					"武邑县",
+					"武强县",
+					"饶阳县",
+					"安平县",
+					"故城县",
+					"景 县",
+					"阜城县",
+					"冀州市",
+					"深州市"
+				]
+			}
+		]
+	},
+	{
+		"name": "山西省",
+		"city": [{
+				"name": "太原市",
+				"area": [
+					"小店区",
+					"迎泽区",
+					"杏花岭区",
+					"尖草坪区",
+					"万柏林区",
+					"晋源区",
+					"清徐县",
+					"阳曲县",
+					"娄烦县",
+					"古交市"
+				]
+			},
+			{
+				"name": "大同市",
+				"area": [
+					"城 区",
+					"矿 区",
+					"南郊区",
+					"新荣区",
+					"阳高县",
+					"天镇县",
+					"广灵县",
+					"灵丘县",
+					"浑源县",
+					"左云县",
+					"大同县"
+				]
+			},
+			{
+				"name": "阳泉市",
+				"area": [
+					"城 区",
+					"矿 区",
+					"郊 区",
+					"平定县",
+					"盂 县"
+				]
+			},
+			{
+				"name": "长治市",
+				"area": [
+					"城 区",
+					"郊 区",
+					"长治县",
+					"襄垣县",
+					"屯留县",
+					"平顺县",
+					"黎城县",
+					"壶关县",
+					"长子县",
+					"武乡县",
+					"沁 县",
+					"沁源县",
+					"潞城市"
+				]
+			},
+			{
+				"name": "晋城市",
+				"area": [
+					"城 区",
+					"沁水县",
+					"阳城县",
+					"陵川县",
+					"泽州县",
+					"高平市"
+				]
+			},
+			{
+				"name": "朔州市",
+				"area": [
+					"朔城区",
+					"平鲁区",
+					"山阴县",
+					"应 县",
+					"右玉县",
+					"怀仁县"
+				]
+			},
+			{
+				"name": "忻州市",
+				"area": [
+					"忻府区",
+					"原平市",
+					"定襄县",
+					"五台县",
+					"代 县",
+					"繁峙县",
+					"宁武县",
+					"静乐县",
+					"神池县",
+					"五寨县",
+					"岢岚县",
+					"河曲县",
+					"保德县",
+					"偏关县"
+				]
+			},
+			{
+				"name": "吕梁市",
+				"area": [
+					"离石区",
+					"孝义市",
+					"汾阳市",
+					"文水县",
+					"交城县",
+					"兴 县",
+					"临 县",
+					"柳林县",
+					"石楼县",
+					"岚 县",
+					"方山县",
+					"中阳县",
+					"交口县"
+				]
+			},
+			{
+				"name": "晋中市",
+				"area": [
+					"榆次市",
+					"介休市",
+					"榆社县",
+					"左权县",
+					"和顺县",
+					"昔阳县",
+					"寿阳县",
+					"太谷县",
+					"祁 县",
+					"平遥县",
+					"灵石县"
+				]
+			},
+			{
+				"name": "临汾市",
+				"area": [
+					"临汾市",
+					"侯马市",
+					"霍州市",
+					"曲沃县",
+					"翼城县",
+					"襄汾县",
+					"洪洞县",
+					"古 县",
+					"安泽县",
+					"浮山县",
+					"吉 县",
+					"乡宁县",
+					"蒲 县",
+					"大宁县",
+					"永和县",
+					"隰 县",
+					"汾西县"
+				]
+			},
+			{
+				"name": "运城市",
+				"area": [
+					"运城市",
+					"永济市",
+					"河津市",
+					"芮城县",
+					"临猗县",
+					"万荣县",
+					"新绛县",
+					"稷山县",
+					"闻喜县",
+					"夏 县",
+					"绛 县",
+					"平陆县",
+					"垣曲县"
+				]
+			}
+		]
+	},
+	{
+		"name": "内蒙古",
+		"city": [{
+				"name": "呼和浩特市",
+				"area": [
+					"新城区",
+					"回民区",
+					"玉泉区",
+					"郊 区",
+					"土默特左旗",
+					"托克托县",
+					"和林格尔县",
+					"清水河县",
+					"武川县"
+				]
+			},
+			{
+				"name": "包头市",
+				"area": [
+					"东河区",
+					"昆都伦区",
+					"青山区",
+					"石拐矿区",
+					"白云矿区",
+					"郊 区",
+					"土默特右旗",
+					"固阳县",
+					"达尔罕茂明安联合旗"
+				]
+			},
+			{
+				"name": "乌海市",
+				"area": [
+					"海勃湾区",
+					"海南区",
+					"乌达区"
+				]
+			},
+			{
+				"name": "赤峰市",
+				"area": [
+					"红山区",
+					"元宝山区",
+					"松山区",
+					"阿鲁科尔沁旗",
+					"巴林左旗",
+					"巴林右旗",
+					"林西县",
+					"克什克腾旗",
+					"翁牛特旗",
+					"喀喇沁旗",
+					"宁城县",
+					"敖汉旗"
+				]
+			},
+			{
+				"name": "呼伦贝尔市",
+				"area": [
+					"海拉尔市",
+					"满洲里市",
+					"扎兰屯市",
+					"牙克石市",
+					"根河市",
+					"额尔古纳市",
+					"阿荣旗",
+					"莫力达瓦达斡尔族自治旗",
+					"鄂伦春自治旗",
+					"鄂温克族自治旗",
+					"新巴尔虎右旗",
+					"新巴尔虎左旗",
+					"陈巴尔虎旗"
+				]
+			},
+			{
+				"name": "兴安盟",
+				"area": [
+					"乌兰浩特市",
+					"阿尔山市",
+					"科尔沁右翼前旗",
+					"科尔沁右翼中旗",
+					"扎赉特旗",
+					"突泉县"
+				]
+			},
+			{
+				"name": "通辽市",
+				"area": [
+					"科尔沁区",
+					"霍林郭勒市",
+					"科尔沁左翼中旗",
+					"科尔沁左翼后旗",
+					"开鲁县",
+					"库伦旗",
+					"奈曼旗",
+					"扎鲁特旗"
+				]
+			},
+			{
+				"name": "锡林郭勒盟",
+				"area": [
+					"二连浩特市",
+					"锡林浩特市",
+					"阿巴嘎旗",
+					"苏尼特左旗",
+					"苏尼特右旗",
+					"东乌珠穆沁旗",
+					"西乌珠穆沁旗",
+					"太仆寺旗",
+					"镶黄旗",
+					"正镶白旗",
+					"正蓝旗",
+					"多伦县"
+				]
+			},
+			{
+				"name": "乌兰察布盟",
+				"area": [
+					"集宁市",
+					"丰镇市",
+					"卓资县",
+					"化德县",
+					"商都县",
+					"兴和县",
+					"凉城县",
+					"察哈尔右翼前旗",
+					"察哈尔右翼中旗",
+					"察哈尔右翼后旗",
+					"四子王旗"
+				]
+			},
+			{
+				"name": "伊克昭盟",
+				"area": [
+					"东胜市",
+					"达拉特旗",
+					"准格尔旗",
+					"鄂托克前旗",
+					"鄂托克旗",
+					"杭锦旗",
+					"乌审旗",
+					"伊金霍洛旗"
+				]
+			},
+			{
+				"name": "巴彦淖尔盟",
+				"area": [
+					"临河市",
+					"五原县",
+					"磴口县",
+					"乌拉特前旗",
+					"乌拉特中旗",
+					"乌拉特后旗",
+					"杭锦后旗"
+				]
+			},
+			{
+				"name": "阿拉善盟",
+				"area": [
+					"阿拉善左旗",
+					"阿拉善右旗",
+					"额济纳旗"
+				]
+			}
+		]
+	},
+	{
+		"name": "辽宁省",
+		"city": [{
+				"name": "沈阳市",
+				"area": [
+					"沈河区",
+					"皇姑区",
+					"和平区",
+					"大东区",
+					"铁西区",
+					"苏家屯区",
+					"东陵区",
+					"于洪区",
+					"新民市",
+					"法库县",
+					"辽中县",
+					"康平县",
+					"新城子区"
+				]
+			},
+			{
+				"name": "大连市",
+				"area": [
+					"西岗区",
+					"中山区",
+					"沙河口区",
+					"甘井子区",
+					"旅顺口区",
+					"金州区",
+					"瓦房店市",
+					"普兰店市",
+					"庄河市",
+					"长海县"
+				]
+			},
+			{
+				"name": "鞍山市",
+				"area": [
+					"铁东区",
+					"铁西区",
+					"立山区",
+					"千山区",
+					"海城市",
+					"台安县",
+					"岫岩满族自治县"
+				]
+			},
+			{
+				"name": "抚顺市",
+				"area": [
+					"顺城区",
+					"新抚区",
+					"东洲区",
+					"望花区",
+					"抚顺县",
+					"清原满族自治县",
+					"新宾满族自治县"
+				]
+			},
+			{
+				"name": "本溪市",
+				"area": [
+					"平山区",
+					"明山区",
+					"溪湖区",
+					"南芬区",
+					"本溪满族自治县",
+					"桓仁满族自治县"
+				]
+			},
+			{
+				"name": "丹东市",
+				"area": [
+					"振兴区",
+					"元宝区",
+					"振安区",
+					"东港市",
+					"凤城市",
+					"宽甸满族自治县"
+				]
+			},
+			{
+				"name": "锦州市",
+				"area": [
+					"太和区",
+					"古塔区",
+					"凌河区",
+					"凌海市",
+					"黑山县",
+					"义县",
+					"北宁市"
+				]
+			},
+			{
+				"name": "营口市",
+				"area": [
+					"站前区",
+					"西市区",
+					"鲅鱼圈区",
+					"老边区",
+					"大石桥市",
+					"盖州市"
+				]
+			},
+			{
+				"name": "阜新市",
+				"area": [
+					"海州区",
+					"新邱区",
+					"太平区",
+					"清河门区",
+					"细河区",
+					"彰武县",
+					"阜新蒙古族自治县"
+				]
+			},
+			{
+				"name": "辽阳市",
+				"area": [
+					"白塔区",
+					"文圣区",
+					"宏伟区",
+					"太子河区",
+					"弓长岭区",
+					"灯塔市",
+					"辽阳县"
+				]
+			},
+			{
+				"name": "盘锦",
+				"area": [
+					"双台子区",
+					"兴隆台区",
+					"盘山县",
+					"大洼县"
+				]
+			},
+			{
+				"name": "铁岭市",
+				"area": [
+					"银州区",
+					"清河区",
+					"调兵山市",
+					"开原市",
+					"铁岭县",
+					"昌图县",
+					"西丰县"
+				]
+			},
+			{
+				"name": "朝阳市",
+				"area": [
+					"双塔区",
+					"龙城区",
+					"凌源市",
+					"北票市",
+					"朝阳县",
+					"建平县",
+					"喀喇沁左翼蒙古族自治县"
+				]
+			},
+			{
+				"name": "葫芦岛市",
+				"area": [
+					"龙港区",
+					"南票区",
+					"连山区",
+					"兴城市",
+					"绥中县",
+					"建昌县"
+				]
+			}
+		]
+	},
+	{
+		"name": "吉林省",
+		"city": [{
+				"name": "长春市",
+				"area": [
+					"朝阳区",
+					"宽城区",
+					"二道区",
+					"南关区",
+					"绿园区",
+					"双阳区",
+					"九台市",
+					"榆树市",
+					"德惠市",
+					"农安县"
+				]
+			},
+			{
+				"name": "吉林市",
+				"area": [
+					"船营区",
+					"昌邑区",
+					"龙潭区",
+					"丰满区",
+					"舒兰市",
+					"桦甸市",
+					"蛟河市",
+					"磐石市",
+					"永吉县"
+				]
+			},
+			{
+				"name": "四平",
+				"area": [
+					"铁西区",
+					"铁东区",
+					"公主岭市",
+					"双辽市",
+					"梨树县",
+					"伊通满族自治县"
+				]
+			},
+			{
+				"name": "辽源市",
+				"area": [
+					"龙山区",
+					"西安区",
+					"东辽县",
+					"东丰县"
+				]
+			},
+			{
+				"name": "通化市",
+				"area": [
+					"东昌区",
+					"二道江区",
+					"梅河口市",
+					"集安市",
+					"通化县",
+					"辉南县",
+					"柳河县"
+				]
+			},
+			{
+				"name": "白山市",
+				"area": [
+					"八道江区",
+					"江源区",
+					"临江市",
+					"靖宇县",
+					"抚松县",
+					"长白朝鲜族自治县"
+				]
+			},
+			{
+				"name": "松原市",
+				"area": [
+					"宁江区",
+					"乾安县",
+					"长岭县",
+					"扶余县",
+					"前郭尔罗斯蒙古族自治县"
+				]
+			},
+			{
+				"name": "白城市",
+				"area": [
+					"洮北区",
+					"大安市",
+					"洮南市",
+					"镇赉县",
+					"通榆县"
+				]
+			},
+			{
+				"name": "延边朝鲜族自治州",
+				"area": [
+					"延吉市",
+					"图们市",
+					"敦化市",
+					"龙井市",
+					"珲春市",
+					"和龙市",
+					"安图县",
+					"汪清县"
+				]
+			}
+		]
+	},
+	{
+		"name": "黑龙江省",
+		"city": [{
+				"name": "哈尔滨市",
+				"area": [
+					"松北区",
+					"道里区",
+					"南岗区",
+					"平房区",
+					"香坊区",
+					"道外区",
+					"呼兰区",
+					"阿城区",
+					"双城市",
+					"尚志市",
+					"五常市",
+					"宾县",
+					"方正县",
+					"通河县",
+					"巴彦县",
+					"延寿县",
+					"木兰县",
+					"依兰县"
+				]
+			},
+			{
+				"name": "齐齐哈尔市",
+				"area": [
+					"龙沙区",
+					"昂昂溪区",
+					"铁锋区",
+					"建华区",
+					"富拉尔基区",
+					"碾子山区",
+					"梅里斯达斡尔族区",
+					"讷河市",
+					"富裕县",
+					"拜泉县",
+					"甘南县",
+					"依安县",
+					"克山县",
+					"泰来县",
+					"克东县",
+					"龙江县"
+				]
+			},
+			{
+				"name": "鹤岗市",
+				"area": [
+					"兴山区",
+					"工农区",
+					"南山区",
+					"兴安区",
+					"向阳区",
+					"东山区",
+					"萝北县",
+					"绥滨县"
+				]
+			},
+			{
+				"name": "双鸭山",
+				"area": [
+					"尖山区",
+					"岭东区",
+					"四方台区",
+					"宝山区",
+					"集贤县",
+					"宝清县",
+					"友谊县",
+					"饶河县"
+				]
+			},
+			{
+				"name": "鸡西市",
+				"area": [
+					"鸡冠区",
+					"恒山区",
+					"城子河区",
+					"滴道区",
+					"梨树区",
+					"麻山区",
+					"密山市",
+					"虎林市",
+					"鸡东县"
+				]
+			},
+			{
+				"name": "大庆市",
+				"area": [
+					"萨尔图区",
+					"红岗区",
+					"龙凤区",
+					"让胡路区",
+					"大同区",
+					"林甸县",
+					"肇州县",
+					"肇源县",
+					"杜尔伯特蒙古族自治县"
+				]
+			},
+			{
+				"name": "伊春市",
+				"area": [
+					"伊春区",
+					"带岭区",
+					"南岔区",
+					"金山屯区",
+					"西林区",
+					"美溪区",
+					"乌马河区",
+					"翠峦区",
+					"友好区",
+					"上甘岭区",
+					"五营区",
+					"红星区",
+					"新青区",
+					"汤旺河区",
+					"乌伊岭区",
+					"铁力市",
+					"嘉荫县"
+				]
+			},
+			{
+				"name": "牡丹江市",
+				"area": [
+					"爱民区",
+					"东安区",
+					"阳明区",
+					"西安区",
+					"绥芬河市",
+					"宁安市",
+					"海林市",
+					"穆棱市",
+					"林口县",
+					"东宁县"
+				]
+			},
+			{
+				"name": "佳木斯市",
+				"area": [
+					"向阳区",
+					"前进区",
+					"东风区",
+					"郊区",
+					"同江市",
+					"富锦市",
+					"桦川县",
+					"抚远县",
+					"桦南县",
+					"汤原县"
+				]
+			},
+			{
+				"name": "七台河市",
+				"area": [
+					"桃山区",
+					"新兴区",
+					"茄子河区",
+					"勃利县"
+				]
+			},
+			{
+				"name": "黑河市",
+				"area": [
+					"爱辉区",
+					"北安市",
+					"五大连池市",
+					"逊克县",
+					"嫩江县",
+					"孙吴县"
+				]
+			},
+			{
+				"name": "绥化市",
+				"area": [
+					"北林区",
+					"安达市",
+					"肇东市",
+					"海伦市",
+					"绥棱县",
+					"兰西县",
+					"明水县",
+					"青冈县",
+					"庆安县",
+					"望奎县"
+				]
+			},
+			{
+				"name": "大兴安岭地区",
+				"area": [
+					"呼玛县",
+					"塔河县",
+					"漠河县",
+					"大兴安岭辖区"
+				]
+			}
+		]
+	},
+	{
+		"name": "上海市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"黄浦区",
+				"卢湾区",
+				"徐汇区",
+				"长宁区",
+				"静安区",
+				"普陀区",
+				"闸北区",
+				"虹口区",
+				"杨浦区",
+				"宝山区",
+				"闵行区",
+				"嘉定区",
+				"松江区",
+				"金山区",
+				"青浦区",
+				"南汇区",
+				"奉贤区",
+				"浦东新区",
+				"崇明县"
+			]
+		}]
+	},
+	{
+		"name": "江苏省",
+		"city": [{
+				"name": "南京市",
+				"area": [
+					"玄武区",
+					"白下区",
+					"秦淮区",
+					"建邺区",
+					"鼓楼区",
+					"下关区",
+					"栖霞区",
+					"雨花台区",
+					"浦口区",
+					"江宁区",
+					"六合区",
+					"溧水县",
+					"高淳县"
+				]
+			},
+			{
+				"name": "苏州市",
+				"area": [
+					"金阊区",
+					"平江区",
+					"沧浪区",
+					"虎丘区",
+					"吴中区",
+					"相城区",
+					"常熟市",
+					"张家港市",
+					"昆山市",
+					"吴江市",
+					"太仓市"
+				]
+			},
+			{
+				"name": "无锡市",
+				"area": [
+					"崇安区",
+					"南长区",
+					"北塘区",
+					"滨湖区",
+					"锡山区",
+					"惠山区",
+					"江阴市",
+					"宜兴市"
+				]
+			},
+			{
+				"name": "常州市",
+				"area": [
+					"钟楼区",
+					"天宁区",
+					"戚墅堰区",
+					"新北区",
+					"武进区",
+					"金坛市",
+					"溧阳市"
+				]
+			},
+			{
+				"name": "镇江市",
+				"area": [
+					"京口区",
+					"润州区",
+					"丹徒区",
+					"丹阳市",
+					"扬中市",
+					"句容市"
+				]
+			},
+			{
+				"name": "南通市",
+				"area": [
+					"崇川区",
+					"港闸区",
+					"通州市",
+					"如皋市",
+					"海门市",
+					"启东市",
+					"海安县",
+					"如东县"
+				]
+			},
+			{
+				"name": "泰州市",
+				"area": [
+					"海陵区",
+					"高港区",
+					"姜堰市",
+					"泰兴市",
+					"靖江市",
+					"兴化市"
+				]
+			},
+			{
+				"name": "扬州市",
+				"area": [
+					"广陵区",
+					"维扬区",
+					"邗江区",
+					"江都市",
+					"仪征市",
+					"高邮市",
+					"宝应县"
+				]
+			},
+			{
+				"name": "盐城市",
+				"area": [
+					"亭湖区",
+					"盐都区",
+					"大丰市",
+					"东台市",
+					"建湖县",
+					"射阳县",
+					"阜宁县",
+					"滨海县",
+					"响水县"
+				]
+			},
+			{
+				"name": "连云港市",
+				"area": [
+					"新浦区",
+					"海州区",
+					"连云区",
+					"东海县",
+					"灌云县",
+					"赣榆县",
+					"灌南县"
+				]
+			},
+			{
+				"name": "徐州市",
+				"area": [
+					"云龙区",
+					"鼓楼区",
+					"九里区",
+					"泉山区",
+					"贾汪区",
+					"邳州市",
+					"新沂市",
+					"铜山县",
+					"睢宁县",
+					"沛县",
+					"丰县"
+				]
+			},
+			{
+				"name": "淮安市",
+				"area": [
+					"清河区",
+					"清浦区",
+					"楚州区",
+					"淮阴区",
+					"涟水县",
+					"洪泽县",
+					"金湖县",
+					"盱眙县"
+				]
+			},
+			{
+				"name": "宿迁市",
+				"area": [
+					"宿城区",
+					"宿豫区",
+					"沭阳县",
+					"泗阳县",
+					"泗洪县"
+				]
+			}
+		]
+	},
+	{
+		"name": "浙江省",
+		"city": [{
+				"name": "杭州市",
+				"area": [
+					"拱墅区",
+					"西湖区",
+					"上城区",
+					"下城区",
+					"江干区",
+					"滨江区",
+					"余杭区",
+					"萧山区",
+					"建德市",
+					"富阳市",
+					"临安市",
+					"桐庐县",
+					"淳安县"
+				]
+			},
+			{
+				"name": "宁波市",
+				"area": [
+					"海曙区",
+					"江东区",
+					"江北区",
+					"镇海区",
+					"北仑区",
+					"鄞州区",
+					"余姚市",
+					"慈溪市",
+					"奉化市",
+					"宁海县",
+					"象山县"
+				]
+			},
+			{
+				"name": "温州市",
+				"area": [
+					"鹿城区",
+					"龙湾区",
+					"瓯海区",
+					"瑞安市",
+					"乐清市",
+					"永嘉县",
+					"洞头县",
+					"平阳县",
+					"苍南县",
+					"文成县",
+					"泰顺县"
+				]
+			},
+			{
+				"name": "嘉兴市",
+				"area": [
+					"秀城区",
+					"秀洲区",
+					"海宁市",
+					"平湖市",
+					"桐乡市",
+					"嘉善县",
+					"海盐县"
+				]
+			},
+			{
+				"name": "湖州市",
+				"area": [
+					"吴兴区",
+					"南浔区",
+					"长兴县",
+					"德清县",
+					"安吉县"
+				]
+			},
+			{
+				"name": "绍兴市",
+				"area": [
+					"越城区",
+					"诸暨市",
+					"上虞市",
+					"嵊州市",
+					"绍兴县",
+					"新昌县"
+				]
+			},
+			{
+				"name": "金华市",
+				"area": [
+					"婺城区",
+					"金东区",
+					"兰溪市",
+					"义乌市",
+					"东阳市",
+					"永康市",
+					"武义县",
+					"浦江县",
+					"磐安县"
+				]
+			},
+			{
+				"name": "衢州市",
+				"area": [
+					"柯城区",
+					"衢江区",
+					"江山市",
+					"龙游县",
+					"常山县",
+					"开化县"
+				]
+			},
+			{
+				"name": "舟山市",
+				"area": [
+					"定海区",
+					"普陀区",
+					"岱山县",
+					"嵊泗县"
+				]
+			},
+			{
+				"name": "台州市",
+				"area": [
+					"椒江区",
+					"黄岩区",
+					"路桥区",
+					"临海市",
+					"温岭市",
+					"玉环县",
+					"天台县",
+					"仙居县",
+					"三门县"
+				]
+			},
+			{
+				"name": "丽水市",
+				"area": [
+					"莲都区",
+					"龙泉市",
+					"缙云县",
+					"青田县",
+					"云和县",
+					"遂昌县",
+					"松阳县",
+					"庆元县",
+					"景宁畲族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "安徽省",
+		"city": [{
+				"name": "合肥市",
+				"area": [
+					"庐阳区",
+					"瑶海区",
+					"蜀山区",
+					"包河区",
+					"长丰县",
+					"肥东县",
+					"肥西县"
+				]
+			},
+			{
+				"name": "芜湖市",
+				"area": [
+					"镜湖区",
+					"弋江区",
+					"鸠江区",
+					"三山区",
+					"芜湖县",
+					"南陵县",
+					"繁昌县"
+				]
+			},
+			{
+				"name": "蚌埠市",
+				"area": [
+					"蚌山区",
+					"龙子湖区",
+					"禹会区",
+					"淮上区",
+					"怀远县",
+					"固镇县",
+					"五河县"
+				]
+			},
+			{
+				"name": "淮南市",
+				"area": [
+					"田家庵区",
+					"大通区",
+					"谢家集区",
+					"八公山区",
+					"潘集区",
+					"凤台县"
+				]
+			},
+			{
+				"name": "马鞍山市",
+				"area": [
+					"雨山区",
+					"花山区",
+					"金家庄区",
+					"当涂县"
+				]
+			},
+			{
+				"name": "淮北市",
+				"area": [
+					"相山区",
+					"杜集区",
+					"烈山区",
+					"濉溪县"
+				]
+			},
+			{
+				"name": "铜陵市",
+				"area": [
+					"铜官山区",
+					"狮子山区",
+					"郊区",
+					"铜陵县"
+				]
+			},
+			{
+				"name": "安庆市",
+				"area": [
+					"迎江区",
+					"大观区",
+					"宜秀区",
+					"桐城市",
+					"宿松县",
+					"枞阳县",
+					"太湖县",
+					"怀宁县",
+					"岳西县",
+					"望江县",
+					"潜山县"
+				]
+			},
+			{
+				"name": "黄山市",
+				"area": [
+					"屯溪区",
+					"黄山区",
+					"徽州区",
+					"休宁县",
+					"歙县",
+					"祁门县",
+					"黟县"
+				]
+			},
+			{
+				"name": "滁州市",
+				"area": [
+					"琅琊区",
+					"南谯区",
+					"天长市",
+					"明光市",
+					"全椒县",
+					"来安县",
+					"定远县",
+					"凤阳县"
+				]
+			},
+			{
+				"name": "阜阳市",
+				"area": [
+					"颍州区",
+					"颍东区",
+					"颍泉区",
+					"界首市",
+					"临泉县",
+					"颍上县",
+					"阜南县",
+					"太和县"
+				]
+			},
+			{
+				"name": "宿州市",
+				"area": [
+					"埇桥区",
+					"萧县",
+					"泗县",
+					"砀山县",
+					"灵璧县"
+				]
+			},
+			{
+				"name": "巢湖市",
+				"area": [
+					"居巢区",
+					"含山县",
+					"无为县",
+					"庐江县",
+					"和县"
+				]
+			},
+			{
+				"name": "六安市",
+				"area": [
+					"金安区",
+					"裕安区",
+					"寿县",
+					"霍山县",
+					"霍邱县",
+					"舒城县",
+					"金寨县"
+				]
+			},
+			{
+				"name": "亳州市",
+				"area": [
+					"谯城区",
+					"利辛县",
+					"涡阳县",
+					"蒙城县"
+				]
+			},
+			{
+				"name": "池州市",
+				"area": [
+					"贵池区",
+					"东至县",
+					"石台县",
+					"青阳县"
+				]
+			},
+			{
+				"name": "宣城市",
+				"area": [
+					"宣州区",
+					"宁国市",
+					"广德县",
+					"郎溪县",
+					"泾县",
+					"旌德县",
+					"绩溪县"
+				]
+			}
+		]
+	},
+	{
+		"name": "福建省",
+		"city": [{
+				"name": "福州市",
+				"area": [
+					"鼓楼区",
+					"台江区",
+					"仓山区",
+					"马尾区",
+					"晋安区",
+					"福清市",
+					"长乐市",
+					"闽侯县",
+					"闽清县",
+					"永泰县",
+					"连江县",
+					"罗源县",
+					"平潭县"
+				]
+			},
+			{
+				"name": "厦门市",
+				"area": [
+					"思明区",
+					"海沧区",
+					"湖里区",
+					"集美区",
+					"同安区",
+					"翔安区"
+				]
+			},
+			{
+				"name": "莆田市",
+				"area": [
+					"城厢区",
+					"涵江区",
+					"荔城区",
+					"秀屿区",
+					"仙游县"
+				]
+			},
+			{
+				"name": "三明市",
+				"area": [
+					"梅列区",
+					"三元区",
+					"永安市",
+					"明溪县",
+					"将乐县",
+					"大田县",
+					"宁化县",
+					"建宁县",
+					"沙县",
+					"尤溪县",
+					"清流县",
+					"泰宁县"
+				]
+			},
+			{
+				"name": "泉州市",
+				"area": [
+					"鲤城区",
+					"丰泽区",
+					"洛江区",
+					"泉港区",
+					"石狮市",
+					"晋江市",
+					"南安市",
+					"惠安县",
+					"永春县",
+					"安溪县",
+					"德化县",
+					"金门县"
+				]
+			},
+			{
+				"name": "漳州市",
+				"area": [
+					"芗城区",
+					"龙文区",
+					"龙海市",
+					"平和县",
+					"南靖县",
+					"诏安县",
+					"漳浦县",
+					"华安县",
+					"东山县",
+					"长泰县",
+					"云霄县"
+				]
+			},
+			{
+				"name": "南平市",
+				"area": [
+					"延平区",
+					"建瓯市",
+					"邵武市",
+					"武夷山市",
+					"建阳市",
+					"松溪县",
+					"光泽县",
+					"顺昌县",
+					"浦城县",
+					"政和县"
+				]
+			},
+			{
+				"name": "龙岩市",
+				"area": [
+					"新罗区",
+					"漳平市",
+					"长汀县",
+					"武平县",
+					"上杭县",
+					"永定县",
+					"连城县"
+				]
+			},
+			{
+				"name": "宁德市",
+				"area": [
+					"蕉城区",
+					"福安市",
+					"福鼎市",
+					"寿宁县",
+					"霞浦县",
+					"柘荣县",
+					"屏南县",
+					"古田县",
+					"周宁县"
+				]
+			}
+		]
+	},
+	{
+		"name": "江西省",
+		"city": [{
+				"name": "南昌市",
+				"area": [
+					"东湖区",
+					"西湖区",
+					"青云谱区",
+					"湾里区",
+					"青山湖区",
+					"新建县",
+					"南昌县",
+					"进贤县",
+					"安义县"
+				]
+			},
+			{
+				"name": "景德镇市",
+				"area": [
+					"珠山区",
+					"昌江区",
+					"乐平市",
+					"浮梁县"
+				]
+			},
+			{
+				"name": "萍乡市",
+				"area": [
+					"安源区",
+					"湘东区",
+					"莲花县",
+					"上栗县",
+					"芦溪县"
+				]
+			},
+			{
+				"name": "九江市",
+				"area": [
+					"浔阳区",
+					"庐山区",
+					"瑞昌市",
+					"九江县",
+					"星子县",
+					"武宁县",
+					"彭泽县",
+					"永修县",
+					"修水县",
+					"湖口县",
+					"德安县",
+					"都昌县"
+				]
+			},
+			{
+				"name": "新余市",
+				"area": [
+					"渝水区",
+					"分宜县"
+				]
+			},
+			{
+				"name": "鹰潭市",
+				"area": [
+					"月湖区",
+					"贵溪市",
+					"余江县"
+				]
+			},
+			{
+				"name": "赣州市",
+				"area": [
+					"章贡区",
+					"瑞金市",
+					"南康市",
+					"石城县",
+					"安远县",
+					"赣县",
+					"宁都县",
+					"寻乌县",
+					"兴国县",
+					"定南县",
+					"上犹县",
+					"于都县",
+					"龙南县",
+					"崇义县",
+					"信丰县",
+					"全南县",
+					"大余县",
+					"会昌县"
+				]
+			},
+			{
+				"name": "吉安市",
+				"area": [
+					"吉州区",
+					"青原区",
+					"井冈山市",
+					"吉安县",
+					"永丰县",
+					"永新县",
+					"新干县",
+					"泰和县",
+					"峡江县",
+					"遂川县",
+					"安福县",
+					"吉水县",
+					"万安县"
+				]
+			},
+			{
+				"name": "宜春市",
+				"area": [
+					"袁州区",
+					"丰城市",
+					"樟树市",
+					"高安市",
+					"铜鼓县",
+					"靖安县",
+					"宜丰县",
+					"奉新县",
+					"万载县",
+					"上高县"
+				]
+			},
+			{
+				"name": "抚州市",
+				"area": [
+					"临川区",
+					"南丰县",
+					"乐安县",
+					"金溪县",
+					"南城县",
+					"东乡县",
+					"资溪县",
+					"宜黄县",
+					"广昌县",
+					"黎川县",
+					"崇仁县"
+				]
+			},
+			{
+				"name": "上饶市",
+				"area": [
+					"信州区",
+					"德兴市",
+					"上饶县",
+					"广丰县",
+					"鄱阳县",
+					"婺源县",
+					"铅山县",
+					"余干县",
+					"横峰县",
+					"弋阳县",
+					"玉山县",
+					"万年县"
+				]
+			}
+		]
+	},
+	{
+		"name": "山东省",
+		"city": [{
+				"name": "济南市",
+				"area": [
+					"市中区",
+					"历下区",
+					"天桥区",
+					"槐荫区",
+					"历城区",
+					"长清区",
+					"章丘市",
+					"平阴县",
+					"济阳县",
+					"商河县"
+				]
+			},
+			{
+				"name": "青岛市",
+				"area": [
+					"市南区",
+					"市北区",
+					"城阳区",
+					"四方区",
+					"李沧区",
+					"黄岛区",
+					"崂山区",
+					"胶南市",
+					"胶州市",
+					"平度市",
+					"莱西市",
+					"即墨市"
+				]
+			},
+			{
+				"name": "淄博市",
+				"area": [
+					"张店区",
+					"临淄区",
+					"淄川区",
+					"博山区",
+					"周村区",
+					"桓台县",
+					"高青县",
+					"沂源县"
+				]
+			},
+			{
+				"name": "枣庄市",
+				"area": [
+					"市中区",
+					"山亭区",
+					"峄城区",
+					"台儿庄区",
+					"薛城区",
+					"滕州市"
+				]
+			},
+			{
+				"name": "东营市",
+				"area": [
+					"东营区",
+					"河口区",
+					"垦利县",
+					"广饶县",
+					"利津县"
+				]
+			},
+			{
+				"name": "烟台市",
+				"area": [
+					"芝罘区",
+					"福山区",
+					"牟平区",
+					"莱山区",
+					"龙口市",
+					"莱阳市",
+					"莱州市",
+					"招远市",
+					"蓬莱市",
+					"栖霞市",
+					"海阳市",
+					"长岛县"
+				]
+			},
+			{
+				"name": "潍坊市",
+				"area": [
+					"潍城区",
+					"寒亭区",
+					"坊子区",
+					"奎文区",
+					"青州市",
+					"诸城市",
+					"寿光市",
+					"安丘市",
+					"高密市",
+					"昌邑市",
+					"昌乐县",
+					"临朐县"
+				]
+			},
+			{
+				"name": "济宁市",
+				"area": [
+					"市中区",
+					"任城区",
+					"曲阜市",
+					"兖州市",
+					"邹城市",
+					"鱼台县",
+					"金乡县",
+					"嘉祥县",
+					"微山县",
+					"汶上县",
+					"泗水县",
+					"梁山县"
+				]
+			},
+			{
+				"name": "泰安市",
+				"area": [
+					"泰山区",
+					"岱岳区",
+					"新泰市",
+					"肥城市",
+					"宁阳县",
+					"东平县"
+				]
+			},
+			{
+				"name": "威海市",
+				"area": [
+					"环翠区",
+					"乳山市",
+					"文登市",
+					"荣成市"
+				]
+			},
+			{
+				"name": "日照市",
+				"area": [
+					"东港区",
+					"岚山区",
+					"五莲县",
+					"莒县"
+				]
+			},
+			{
+				"name": "莱芜市",
+				"area": [
+					"莱城区",
+					"钢城区"
+				]
+			},
+			{
+				"name": "临沂市",
+				"area": [
+					"兰山区",
+					"罗庄区",
+					"河东区",
+					"沂南县",
+					"郯城县",
+					"沂水县",
+					"苍山县",
+					"费县",
+					"平邑县",
+					"莒南县",
+					"蒙阴县",
+					"临沭县"
+				]
+			},
+			{
+				"name": "德州市",
+				"area": [
+					"德城区",
+					"乐陵市",
+					"禹城市",
+					"陵县",
+					"宁津县",
+					"齐河县",
+					"武城县",
+					"庆云县",
+					"平原县",
+					"夏津县",
+					"临邑县"
+				]
+			},
+			{
+				"name": "聊城市",
+				"area": [
+					"东昌府区",
+					"临清市",
+					"高唐县",
+					"阳谷县",
+					"茌平县",
+					"莘县",
+					"东阿县",
+					"冠县"
+				]
+			},
+			{
+				"name": "滨州市",
+				"area": [
+					"滨城区",
+					"邹平县",
+					"沾化县",
+					"惠民县",
+					"博兴县",
+					"阳信县",
+					"无棣县"
+				]
+			},
+			{
+				"name": "菏泽市",
+				"area": [
+					"牡丹区",
+					"鄄城县",
+					"单县",
+					"郓城县",
+					"曹县",
+					"定陶县",
+					"巨野县",
+					"东明县",
+					"成武县"
+				]
+			}
+		]
+	},
+	{
+		"name": "河南省",
+		"city": [{
+				"name": "郑州市",
+				"area": [
+					"中原区",
+					"金水区",
+					"二七区",
+					"管城回族区",
+					"上街区",
+					"惠济区",
+					"巩义市",
+					"新郑市",
+					"新密市",
+					"登封市",
+					"荥阳市",
+					"中牟县"
+				]
+			},
+			{
+				"name": "开封市",
+				"area": [
+					"鼓楼区",
+					"龙亭区",
+					"顺河回族区",
+					"禹王台区",
+					"金明区",
+					"开封县",
+					"尉氏县",
+					"兰考县",
+					"杞县",
+					"通许县"
+				]
+			},
+			{
+				"name": "洛阳市",
+				"area": [
+					"西工区",
+					"老城区",
+					"涧西区",
+					"瀍河回族区",
+					"洛龙区",
+					"吉利区",
+					"偃师市",
+					"孟津县",
+					"汝阳县",
+					"伊川县",
+					"洛宁县",
+					"嵩县",
+					"宜阳县",
+					"新安县",
+					"栾川县"
+				]
+			},
+			{
+				"name": "平顶山市",
+				"area": [
+					"新华区",
+					"卫东区",
+					"湛河区",
+					"石龙区",
+					"汝州市",
+					"舞钢市",
+					"宝丰县",
+					"叶县",
+					"郏县",
+					"鲁山县"
+				]
+			},
+			{
+				"name": "安阳市",
+				"area": [
+					"北关区",
+					"文峰区",
+					"殷都区",
+					"龙安区",
+					"林州市",
+					"安阳县",
+					"滑县",
+					"内黄县",
+					"汤阴县"
+				]
+			},
+			{
+				"name": "鹤壁市",
+				"area": [
+					"淇滨区",
+					"山城区",
+					"鹤山区",
+					"浚县",
+					"淇县"
+				]
+			},
+			{
+				"name": "新乡市",
+				"area": [
+					"卫滨区",
+					"红旗区",
+					"凤泉区",
+					"牧野区",
+					"卫辉市",
+					"辉县市",
+					"新乡县",
+					"获嘉县",
+					"原阳县",
+					"长垣县",
+					"封丘县",
+					"延津县"
+				]
+			},
+			{
+				"name": "焦作市",
+				"area": [
+					"解放区",
+					"中站区",
+					"马村区",
+					"山阳区",
+					"沁阳市",
+					"孟州市",
+					"修武县",
+					"温县",
+					"武陟县",
+					"博爱县"
+				]
+			},
+			{
+				"name": "濮阳市",
+				"area": [
+					"华龙区",
+					"濮阳县",
+					"南乐县",
+					"台前县",
+					"清丰县",
+					"范县"
+				]
+			},
+			{
+				"name": "许昌市",
+				"area": [
+					"魏都区",
+					"禹州市",
+					"长葛市",
+					"许昌县",
+					"鄢陵县",
+					"襄城县"
+				]
+			},
+			{
+				"name": "漯河市",
+				"area": [
+					"源汇区",
+					"郾城区",
+					"召陵区",
+					"临颍县",
+					"舞阳县"
+				]
+			},
+			{
+				"name": "三门峡市",
+				"area": [
+					"湖滨区",
+					"义马市",
+					"灵宝市",
+					"渑池县",
+					"卢氏县",
+					"陕县"
+				]
+			},
+			{
+				"name": "南阳市",
+				"area": [
+					"卧龙区",
+					"宛城区",
+					"邓州市",
+					"桐柏县",
+					"方城县",
+					"淅川县",
+					"镇平县",
+					"唐河县",
+					"南召县",
+					"内乡县",
+					"新野县",
+					"社旗县",
+					"西峡县"
+				]
+			},
+			{
+				"name": "商丘市",
+				"area": [
+					"梁园区",
+					"睢阳区",
+					"永城市",
+					"宁陵县",
+					"虞城县",
+					"民权县",
+					"夏邑县",
+					"柘城县",
+					"睢县"
+				]
+			},
+			{
+				"name": "信阳市",
+				"area": [
+					"浉河区",
+					"平桥区",
+					"潢川县",
+					"淮滨县",
+					"息县",
+					"新县",
+					"商城县",
+					"固始县",
+					"罗山县",
+					"光山县"
+				]
+			},
+			{
+				"name": "周口市",
+				"area": [
+					"川汇区",
+					"项城市",
+					"商水县",
+					"淮阳县",
+					"太康县",
+					"鹿邑县",
+					"西华县",
+					"扶沟县",
+					"沈丘县",
+					"郸城县"
+				]
+			},
+			{
+				"name": "驻马店市",
+				"area": [
+					"驿城区",
+					"确山县",
+					"新蔡县",
+					"上蔡县",
+					"西平县",
+					"泌阳县",
+					"平舆县",
+					"汝南县",
+					"遂平县",
+					"正阳县"
+				]
+			},
+			{
+				"name": "焦作市",
+				"area": [
+					"济源市"
+				]
+			}
+		]
+	},
+	{
+		"name": "湖北省",
+		"city": [{
+				"name": "武汉市",
+				"area": [
+					"江岸区",
+					"武昌区",
+					"江汉区",
+					"硚口区",
+					"汉阳区",
+					"青山区",
+					"洪山区",
+					"东西湖区",
+					"汉南区",
+					"蔡甸区",
+					"江夏区",
+					"黄陂区",
+					"新洲区"
+				]
+			},
+			{
+				"name": "黄石市",
+				"area": [
+					"黄石港区",
+					"西塞山区",
+					"下陆区",
+					"铁山区",
+					"大冶市",
+					"阳新县"
+				]
+			},
+			{
+				"name": "十堰市",
+				"area": [
+					"张湾区",
+					"茅箭区",
+					"丹江口市",
+					"郧县",
+					"竹山县",
+					"房县",
+					"郧西县",
+					"竹溪县"
+				]
+			},
+			{
+				"name": "荆州市",
+				"area": [
+					"沙市区",
+					"荆州区",
+					"洪湖市",
+					"石首市",
+					"松滋市",
+					"监利县",
+					"公安县",
+					"江陵县"
+				]
+			},
+			{
+				"name": "宜昌市",
+				"area": [
+					"西陵区",
+					"伍家岗区",
+					"点军区",
+					"猇亭区",
+					"夷陵区",
+					"宜都市",
+					"当阳市",
+					"枝江市",
+					"秭归县",
+					"远安县",
+					"兴山县",
+					"五峰土家族自治县",
+					"长阳土家族自治县"
+				]
+			},
+			{
+				"name": "襄樊市",
+				"area": [
+					"襄城区",
+					"樊城区",
+					"襄阳区",
+					"老河口市",
+					"枣阳市",
+					"宜城市",
+					"南漳县",
+					"谷城县",
+					"保康县"
+				]
+			},
+			{
+				"name": "鄂州市",
+				"area": [
+					"鄂城区",
+					"华容区",
+					"梁子湖区"
+				]
+			},
+			{
+				"name": "荆门市",
+				"area": [
+					"东宝区",
+					"掇刀区",
+					"钟祥市",
+					"京山县",
+					"沙洋县"
+				]
+			},
+			{
+				"name": "孝感市",
+				"area": [
+					"孝南区",
+					"应城市",
+					"安陆市",
+					"汉川市",
+					"云梦县",
+					"大悟县",
+					"孝昌县"
+				]
+			},
+			{
+				"name": "黄冈市",
+				"area": [
+					"黄州区",
+					"麻城市",
+					"武穴市",
+					"红安县",
+					"罗田县",
+					"浠水县",
+					"蕲春县",
+					"黄梅县",
+					"英山县",
+					"团风县"
+				]
+			},
+			{
+				"name": "咸宁市",
+				"area": [
+					"咸安区",
+					"赤壁市",
+					"嘉鱼县",
+					"通山县",
+					"崇阳县",
+					"通城县"
+				]
+			},
+			{
+				"name": "随州市",
+				"area": [
+					"曾都区",
+					"广水市"
+				]
+			},
+			{
+				"name": "恩施土家族苗族自治州",
+				"area": [
+					"恩施市",
+					"利川市",
+					"建始县",
+					"来凤县",
+					"巴东县",
+					"鹤峰县",
+					"宣恩县",
+					"咸丰县"
+				]
+			},
+			{
+				"name": "仙桃市",
+				"area": [
+					"仙桃"
+				]
+			},
+			{
+				"name": "天门市",
+				"area": [
+					"天门"
+				]
+			},
+			{
+				"name": "潜江市",
+				"area": [
+					"潜江"
+				]
+			},
+			{
+				"name": "神农架林区",
+				"area": [
+					"神农架林区"
+				]
+			}
+		]
+	},
+	{
+		"name": "湖南省",
+		"city": [{
+				"name": "长沙市",
+				"area": [
+					"岳麓区",
+					"芙蓉区",
+					"天心区",
+					"开福区",
+					"雨花区",
+					"浏阳市",
+					"长沙县",
+					"望城县",
+					"宁乡县"
+				]
+			},
+			{
+				"name": "株洲市",
+				"area": [
+					"天元区",
+					"荷塘区",
+					"芦淞区",
+					"石峰区",
+					"醴陵市",
+					"株洲县",
+					"炎陵县",
+					"茶陵县",
+					"攸县"
+				]
+			},
+			{
+				"name": "湘潭市",
+				"area": [
+					"岳塘区",
+					"雨湖区",
+					"湘乡市",
+					"韶山市",
+					"湘潭县"
+				]
+			},
+			{
+				"name": "衡阳市",
+				"area": [
+					"雁峰区",
+					"珠晖区",
+					"石鼓区",
+					"蒸湘区",
+					"南岳区",
+					"耒阳市",
+					"常宁市",
+					"衡阳县",
+					"衡东县",
+					"衡山县",
+					"衡南县",
+					"祁东县"
+				]
+			},
+			{
+				"name": "邵阳市",
+				"area": [
+					"双清区",
+					"大祥区",
+					"北塔区",
+					"武冈市",
+					"邵东县",
+					"洞口县",
+					"新邵县",
+					"绥宁县",
+					"新宁县",
+					"邵阳县",
+					"隆回县",
+					"城步苗族自治县"
+				]
+			},
+			{
+				"name": "岳阳市",
+				"area": [
+					"岳阳楼区",
+					"云溪区",
+					"君山区",
+					"临湘市",
+					"汨罗市",
+					"岳阳县",
+					"湘阴县",
+					"平江县",
+					"华容县"
+				]
+			},
+			{
+				"name": "常德市",
+				"area": [
+					"武陵区",
+					"鼎城区",
+					"津市市",
+					"澧县",
+					"临澧县",
+					"桃源县",
+					"汉寿县",
+					"安乡县",
+					"石门县"
+				]
+			},
+			{
+				"name": "张家界市",
+				"area": [
+					"永定区",
+					"武陵源区",
+					"慈利县",
+					"桑植县"
+				]
+			},
+			{
+				"name": "益阳市",
+				"area": [
+					"赫山区",
+					"资阳区",
+					"沅江市",
+					"桃江县",
+					"南县",
+					"安化县"
+				]
+			},
+			{
+				"name": "郴州市",
+				"area": [
+					"北湖区",
+					"苏仙区",
+					"资兴市",
+					"宜章县",
+					"汝城县",
+					"安仁县",
+					"嘉禾县",
+					"临武县",
+					"桂东县",
+					"永兴县",
+					"桂阳县"
+				]
+			},
+			{
+				"name": "永州市",
+				"area": [
+					"冷水滩区",
+					"零陵区",
+					"祁阳县",
+					"蓝山县",
+					"宁远县",
+					"新田县",
+					"东安县",
+					"江永县",
+					"道县",
+					"双牌县",
+					"江华瑶族自治县"
+				]
+			},
+			{
+				"name": "怀化市",
+				"area": [
+					"鹤城区",
+					"洪江市",
+					"会同县",
+					"沅陵县",
+					"辰溪县",
+					"溆浦县",
+					"中方县",
+					"新晃侗族自治县",
+					"芷江侗族自治县",
+					"通道侗族自治县",
+					"靖州苗族侗族自治县",
+					"麻阳苗族自治县"
+				]
+			},
+			{
+				"name": "娄底市",
+				"area": [
+					"娄星区",
+					"冷水江市",
+					"涟源市",
+					"新化县",
+					"双峰县"
+				]
+			},
+			{
+				"name": "湘西土家族苗族自治州",
+				"area": [
+					"吉首市",
+					"古丈县",
+					"龙山县",
+					"永顺县",
+					"凤凰县",
+					"泸溪县",
+					"保靖县",
+					"花垣县"
+				]
+			}
+		]
+	},
+	{
+		"name": "广东省",
+		"city": [{
+				"name": "广州市",
+				"area": [
+					"越秀区",
+					"荔湾区",
+					"海珠区",
+					"天河区",
+					"白云区",
+					"黄埔区",
+					"番禺区",
+					"花都区",
+					"南沙区",
+					"萝岗区",
+					"增城市",
+					"从化市"
+				]
+			},
+			{
+				"name": "深圳市",
+				"area": [
+					"福田区",
+					"罗湖区",
+					"南山区",
+					"宝安区",
+					"龙岗区",
+					"盐田区"
+				]
+			},
+			{
+				"name": "东莞市",
+				"area": [
+					"莞城",
+					"常平",
+					"塘厦",
+					"塘厦",
+					"塘厦"
+				]
+			},
+			{
+				"name": "中山市",
+				"area": [
+					"中山"
+				]
+			},
+			{
+				"name": "潮州市",
+				"area": [
+					"湘桥区",
+					"潮安县",
+					"饶平县"
+				]
+			},
+			{
+				"name": "揭阳市",
+				"area": [
+					"榕城区",
+					"揭东县",
+					"揭西县",
+					"惠来县",
+					"普宁市"
+				]
+			},
+			{
+				"name": "云浮市",
+				"area": [
+					"云城区",
+					"新兴县",
+					"郁南县",
+					"云安县",
+					"罗定市"
+				]
+			},
+			{
+				"name": "珠海市",
+				"area": [
+					"香洲区",
+					"斗门区",
+					"金湾区"
+				]
+			},
+			{
+				"name": "汕头市",
+				"area": [
+					"金平区",
+					"濠江区",
+					"龙湖区",
+					"潮阳区",
+					"潮南区",
+					"澄海区",
+					"南澳县"
+				]
+			},
+			{
+				"name": "韶关市",
+				"area": [
+					"浈江区",
+					"武江区",
+					"曲江区",
+					"乐昌市",
+					"南雄市",
+					"始兴县",
+					"仁化县",
+					"翁源县",
+					"新丰县",
+					"乳源瑶族自治县"
+				]
+			},
+			{
+				"name": "佛山市",
+				"area": [
+					"禅城区",
+					"南海区",
+					"顺德区",
+					"三水区",
+					"高明区"
+				]
+			},
+			{
+				"name": "江门市",
+				"area": [
+					"蓬江区",
+					"江海区",
+					"新会区",
+					"恩平市",
+					"台山市",
+					"开平市",
+					"鹤山市"
+				]
+			},
+			{
+				"name": "湛江市",
+				"area": [
+					"赤坎区",
+					"霞山区",
+					"坡头区",
+					"麻章区",
+					"吴川市",
+					"廉江市",
+					"雷州市",
+					"遂溪县",
+					"徐闻县"
+				]
+			},
+			{
+				"name": "茂名市",
+				"area": [
+					"茂南区",
+					"茂港区",
+					"化州市",
+					"信宜市",
+					"高州市",
+					"电白县"
+				]
+			},
+			{
+				"name": "肇庆市",
+				"area": [
+					"端州区",
+					"鼎湖区",
+					"高要市",
+					"四会市",
+					"广宁县",
+					"怀集县",
+					"封开县",
+					"德庆县"
+				]
+			},
+			{
+				"name": "惠州市",
+				"area": [
+					"惠城区",
+					"惠阳区",
+					"博罗县",
+					"惠东县",
+					"龙门县"
+				]
+			},
+			{
+				"name": "梅州市",
+				"area": [
+					"梅江区",
+					"兴宁市",
+					"梅县",
+					"大埔县",
+					"丰顺县",
+					"五华县",
+					"平远县",
+					"蕉岭县"
+				]
+			},
+			{
+				"name": "汕尾市",
+				"area": [
+					"城区",
+					"陆丰市",
+					"海丰县",
+					"陆河县"
+				]
+			},
+			{
+				"name": "河源市",
+				"area": [
+					"源城区",
+					"紫金县",
+					"龙川县",
+					"连平县",
+					"和平县",
+					"东源县"
+				]
+			},
+			{
+				"name": "阳江市",
+				"area": [
+					"江城区",
+					"阳春市",
+					"阳西县",
+					"阳东县"
+				]
+			},
+			{
+				"name": "清远市",
+				"area": [
+					"清城区",
+					"英德市",
+					"连州市",
+					"佛冈县",
+					"阳山县",
+					"清新县",
+					"连山壮族瑶族自治县",
+					"连南瑶族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "广西",
+		"city": [{
+				"name": "南宁市",
+				"area": [
+					"青秀区",
+					"兴宁区",
+					"西乡塘区",
+					"良庆区",
+					"江南区",
+					"邕宁区",
+					"武鸣县",
+					"隆安县",
+					"马山县",
+					"上林县",
+					"宾阳县",
+					"横县"
+				]
+			},
+			{
+				"name": "柳州市",
+				"area": [
+					"城中区",
+					"鱼峰区",
+					"柳北区",
+					"柳南区",
+					"柳江县",
+					"柳城县",
+					"鹿寨县",
+					"融安县",
+					"融水苗族自治县",
+					"三江侗族自治县"
+				]
+			},
+			{
+				"name": "桂林市",
+				"area": [
+					"象山区",
+					"秀峰区",
+					"叠彩区",
+					"七星区",
+					"雁山区",
+					"阳朔县",
+					"临桂县",
+					"灵川县",
+					"全州县",
+					"平乐县",
+					"兴安县",
+					"灌阳县",
+					"荔浦县",
+					"资源县",
+					"永福县",
+					"龙胜各族自治县",
+					"恭城瑶族自治县"
+				]
+			},
+			{
+				"name": "梧州市",
+				"area": [
+					"万秀区",
+					"蝶山区",
+					"长洲区",
+					"岑溪市",
+					"苍梧县",
+					"藤县",
+					"蒙山县"
+				]
+			},
+			{
+				"name": "北海市",
+				"area": [
+					"海城区",
+					"银海区",
+					"铁山港区",
+					"合浦县"
+				]
+			},
+			{
+				"name": "防城港市",
+				"area": [
+					"港口区",
+					"防城区",
+					"东兴市",
+					"上思县"
+				]
+			},
+			{
+				"name": "钦州市",
+				"area": [
+					"钦南区",
+					"钦北区",
+					"灵山县",
+					"浦北县"
+				]
+			},
+			{
+				"name": "贵港市",
+				"area": [
+					"港北区",
+					"港南区",
+					"覃塘区",
+					"桂平市",
+					"平南县"
+				]
+			},
+			{
+				"name": "玉林市",
+				"area": [
+					"玉州区",
+					"北流市",
+					"容县",
+					"陆川县",
+					"博白县",
+					"兴业县"
+				]
+			},
+			{
+				"name": "百色市",
+				"area": [
+					"右江区",
+					"凌云县",
+					"平果县",
+					"西林县",
+					"乐业县",
+					"德保县",
+					"田林县",
+					"田阳县",
+					"靖西县",
+					"田东县",
+					"那坡县",
+					"隆林各族自治县"
+				]
+			},
+			{
+				"name": "贺州市",
+				"area": [
+					"八步区",
+					"钟山县",
+					"昭平县",
+					"富川瑶族自治县"
+				]
+			},
+			{
+				"name": "河池市",
+				"area": [
+					"金城江区",
+					"宜州市",
+					"天峨县",
+					"凤山县",
+					"南丹县",
+					"东兰县",
+					"都安瑶族自治县",
+					"罗城仫佬族自治县",
+					"巴马瑶族自治县",
+					"环江毛南族自治县",
+					"大化瑶族自治县"
+				]
+			},
+			{
+				"name": "来宾市",
+				"area": [
+					"兴宾区",
+					"合山市",
+					"象州县",
+					"武宣县",
+					"忻城县",
+					"金秀瑶族自治县"
+				]
+			},
+			{
+				"name": "崇左市",
+				"area": [
+					"江州区",
+					"凭祥市",
+					"宁明县",
+					"扶绥县",
+					"龙州县",
+					"大新县",
+					"天等县"
+				]
+			}
+		]
+	},
+	{
+		"name": "海南省",
+		"city": [{
+				"name": "海口市",
+				"area": [
+					"龙华区",
+					"秀英区",
+					"琼山区",
+					"美兰区"
+				]
+			},
+			{
+				"name": "三亚市",
+				"area": [
+					"三亚市"
+				]
+			},
+			{
+				"name": "五指山市",
+				"area": [
+					"五指山"
+				]
+			},
+			{
+				"name": "琼海市",
+				"area": [
+					"琼海"
+				]
+			},
+			{
+				"name": "儋州市",
+				"area": [
+					"儋州"
+				]
+			},
+			{
+				"name": "文昌市",
+				"area": [
+					"文昌"
+				]
+			},
+			{
+				"name": "万宁市",
+				"area": [
+					"万宁"
+				]
+			},
+			{
+				"name": "东方市",
+				"area": [
+					"东方"
+				]
+			},
+			{
+				"name": "澄迈县",
+				"area": [
+					"澄迈县"
+				]
+			},
+			{
+				"name": "定安县",
+				"area": [
+					"定安县"
+				]
+			},
+			{
+				"name": "屯昌县",
+				"area": [
+					"屯昌县"
+				]
+			},
+			{
+				"name": "临高县",
+				"area": [
+					"临高县"
+				]
+			},
+			{
+				"name": "白沙黎族自治县",
+				"area": [
+					"白沙黎族自治县"
+				]
+			},
+			{
+				"name": "昌江黎族自治县",
+				"area": [
+					"昌江黎族自治县"
+				]
+			},
+			{
+				"name": "乐东黎族自治县",
+				"area": [
+					"乐东黎族自治县"
+				]
+			},
+			{
+				"name": "陵水黎族自治县",
+				"area": [
+					"陵水黎族自治县"
+				]
+			},
+			{
+				"name": "保亭黎族苗族自治县",
+				"area": [
+					"保亭黎族苗族自治县"
+				]
+			},
+			{
+				"name": "琼中黎族苗族自治县",
+				"area": [
+					"琼中黎族苗族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "重庆市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"渝中区",
+				"大渡口区",
+				"江北区",
+				"南岸区",
+				"北碚区",
+				"渝北区",
+				"巴南区",
+				"长寿区",
+				"双桥区",
+				"沙坪坝区",
+				"万盛区",
+				"万州区",
+				"涪陵区",
+				"黔江区",
+				"永川区",
+				"合川区",
+				"江津区",
+				"九龙坡区",
+				"南川区",
+				"綦江县",
+				"潼南县",
+				"荣昌县",
+				"璧山县",
+				"大足县",
+				"铜梁县",
+				"梁平县",
+				"开县",
+				"忠县",
+				"城口县",
+				"垫江县",
+				"武隆县",
+				"丰都县",
+				"奉节县",
+				"云阳县",
+				"巫溪县",
+				"巫山县",
+				"石柱土家族自治县",
+				"秀山土家族苗族自治县",
+				"酉阳土家族苗族自治县",
+				"彭水苗族土家族自治县"
+			]
+		}]
+	},
+	{
+		"name": "四川省",
+		"city": [{
+				"name": "成都市",
+				"area": [
+					"青羊区",
+					"锦江区",
+					"金牛区",
+					"武侯区",
+					"成华区",
+					"龙泉驿区",
+					"青白江区",
+					"新都区",
+					"温江区",
+					"都江堰市",
+					"彭州市",
+					"邛崃市",
+					"崇州市",
+					"金堂县",
+					"郫县",
+					"新津县",
+					"双流县",
+					"蒲江县",
+					"大邑县"
+				]
+			},
+			{
+				"name": "自贡市",
+				"area": [
+					"大安区",
+					"自流井区",
+					"贡井区",
+					"沿滩区",
+					"荣县",
+					"富顺县"
+				]
+			},
+			{
+				"name": "攀枝花市",
+				"area": [
+					"仁和区",
+					"米易县",
+					"盐边县",
+					"东区",
+					"西区"
+				]
+			},
+			{
+				"name": "泸州市",
+				"area": [
+					"江阳区",
+					"纳溪区",
+					"龙马潭区",
+					"泸县",
+					"合江县",
+					"叙永县",
+					"古蔺县"
+				]
+			},
+			{
+				"name": "德阳市",
+				"area": [
+					"旌阳区",
+					"广汉市",
+					"什邡市",
+					"绵竹市",
+					"罗江县",
+					"中江县"
+				]
+			},
+			{
+				"name": "绵阳市",
+				"area": [
+					"涪城区",
+					"游仙区",
+					"江油市",
+					"盐亭县",
+					"三台县",
+					"平武县",
+					"安县",
+					"梓潼县",
+					"北川羌族自治县"
+				]
+			},
+			{
+				"name": "广元市",
+				"area": [
+					"元坝区",
+					"朝天区",
+					"青川县",
+					"旺苍县",
+					"剑阁县",
+					"苍溪县",
+					"市中区"
+				]
+			},
+			{
+				"name": "遂宁市",
+				"area": [
+					"船山区",
+					"安居区",
+					"射洪县",
+					"蓬溪县",
+					"大英县"
+				]
+			},
+			{
+				"name": "内江市",
+				"area": [
+					"市中区",
+					"东兴区",
+					"资中县",
+					"隆昌县",
+					"威远县"
+				]
+			},
+			{
+				"name": "乐山市",
+				"area": [
+					"市中区",
+					"五通桥区",
+					"沙湾区",
+					"金口河区",
+					"峨眉山市",
+					"夹江县",
+					"井研县",
+					"犍为县",
+					"沐川县",
+					"马边彝族自治县",
+					"峨边彝族自治县"
+				]
+			},
+			{
+				"name": "南充",
+				"area": [
+					"顺庆区",
+					"高坪区",
+					"嘉陵区",
+					"阆中市",
+					"营山县",
+					"蓬安县",
+					"仪陇县",
+					"南部县",
+					"西充县"
+				]
+			},
+			{
+				"name": "眉山市",
+				"area": [
+					"东坡区",
+					"仁寿县",
+					"彭山县",
+					"洪雅县",
+					"丹棱县",
+					"青神县"
+				]
+			},
+			{
+				"name": "宜宾市",
+				"area": [
+					"翠屏区",
+					"宜宾县",
+					"兴文县",
+					"南溪县",
+					"珙县",
+					"长宁县",
+					"高县",
+					"江安县",
+					"筠连县",
+					"屏山县"
+				]
+			},
+			{
+				"name": "广安市",
+				"area": [
+					"广安区",
+					"华蓥市",
+					"岳池县",
+					"邻水县",
+					"武胜县"
+				]
+			},
+			{
+				"name": "达州市",
+				"area": [
+					"通川区",
+					"万源市",
+					"达县",
+					"渠县",
+					"宣汉县",
+					"开江县",
+					"大竹县"
+				]
+			},
+			{
+				"name": "雅安市",
+				"area": [
+					"雨城区",
+					"芦山县",
+					"石棉县",
+					"名山县",
+					"天全县",
+					"荥经县",
+					"宝兴县",
+					"汉源县"
+				]
+			},
+			{
+				"name": "巴中市",
+				"area": [
+					"巴州区",
+					"南江县",
+					"平昌县",
+					"通江县"
+				]
+			},
+			{
+				"name": "资阳市",
+				"area": [
+					"雁江区",
+					"简阳市",
+					"安岳县",
+					"乐至县"
+				]
+			},
+			{
+				"name": "阿坝藏族羌族自治州",
+				"area": [
+					"马尔康县",
+					"九寨沟县",
+					"红原县",
+					"汶川县",
+					"阿坝县",
+					"理县",
+					"若尔盖县",
+					"小金县",
+					"黑水县",
+					"金川县",
+					"松潘县",
+					"壤塘县",
+					"茂县"
+				]
+			},
+			{
+				"name": "甘孜藏族自治州",
+				"area": [
+					"康定县",
+					"丹巴县",
+					"炉霍县",
+					"九龙县",
+					"甘孜县",
+					"雅江县",
+					"新龙县",
+					"道孚县",
+					"白玉县",
+					"理塘县",
+					"德格县",
+					"乡城县",
+					"石渠县",
+					"稻城县",
+					"色达县",
+					"巴塘县",
+					"泸定县",
+					"得荣县"
+				]
+			},
+			{
+				"name": "凉山彝族自治州",
+				"area": [
+					"西昌市",
+					"美姑县",
+					"昭觉县",
+					"金阳县",
+					"甘洛县",
+					"布拖县",
+					"雷波县",
+					"普格县",
+					"宁南县",
+					"喜德县",
+					"会东县",
+					"越西县",
+					"会理县",
+					"盐源县",
+					"德昌县",
+					"冕宁县",
+					"木里藏族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "贵州省",
+		"city": [{
+				"name": "贵阳市",
+				"area": [
+					"南明区",
+					"云岩区",
+					"花溪区",
+					"乌当区",
+					"白云区",
+					"小河区",
+					"清镇市",
+					"开阳县",
+					"修文县",
+					"息烽县"
+				]
+			},
+			{
+				"name": "六盘水市",
+				"area": [
+					"钟山区",
+					"水城县",
+					"盘县",
+					"六枝特区"
+				]
+			},
+			{
+				"name": "遵义市",
+				"area": [
+					"红花岗区",
+					"汇川区",
+					"赤水市",
+					"仁怀市",
+					"遵义县",
+					"绥阳县",
+					"桐梓县",
+					"习水县",
+					"凤冈县",
+					"正安县",
+					"余庆县",
+					"湄潭县",
+					"道真仡佬族苗族自治县",
+					"务川仡佬族苗族自治县"
+				]
+			},
+			{
+				"name": "安顺市",
+				"area": [
+					"西秀区",
+					"普定县",
+					"平坝县",
+					"镇宁布依族苗族自治县",
+					"紫云苗族布依族自治县",
+					"关岭布依族苗族自治县"
+				]
+			},
+			{
+				"name": "铜仁地区",
+				"area": [
+					"铜仁市",
+					"德江县",
+					"江口县",
+					"思南县",
+					"石阡县",
+					"玉屏侗族自治县",
+					"松桃苗族自治县",
+					"印江土家族苗族自治县",
+					"沿河土家族自治县",
+					"万山特区"
+				]
+			},
+			{
+				"name": "毕节地区",
+				"area": [
+					"毕节市",
+					"黔西县",
+					"大方县",
+					"织金县",
+					"金沙县",
+					"赫章县",
+					"纳雍县",
+					"威宁彝族回族苗族自治县"
+				]
+			},
+			{
+				"name": "黔西南布依族苗族自治州",
+				"area": [
+					"兴义市",
+					"望谟县",
+					"兴仁县",
+					"普安县",
+					"册亨县",
+					"晴隆县",
+					"贞丰县",
+					"安龙县"
+				]
+			},
+			{
+				"name": "黔东南苗族侗族自治州",
+				"area": [
+					"凯里市",
+					"施秉县",
+					"从江县",
+					"锦屏县",
+					"镇远县",
+					"麻江县",
+					"台江县",
+					"天柱县",
+					"黄平县",
+					"榕江县",
+					"剑河县",
+					"三穗县",
+					"雷山县",
+					"黎平县",
+					"岑巩县",
+					"丹寨县"
+				]
+			},
+			{
+				"name": "黔南布依族苗族自治州",
+				"area": [
+					"都匀市",
+					"福泉市",
+					"贵定县",
+					"惠水县",
+					"罗甸县",
+					"瓮安县",
+					"荔波县",
+					"龙里县",
+					"平塘县",
+					"长顺县",
+					"独山县",
+					"三都水族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "云南省",
+		"city": [{
+				"name": "昆明市",
+				"area": [
+					"盘龙区",
+					"五华区",
+					"官渡区",
+					"西山区",
+					"东川区",
+					"安宁市",
+					"呈贡县",
+					"晋宁县",
+					"富民县",
+					"宜良县",
+					"嵩明县",
+					"石林彝族自治县",
+					"禄劝彝族苗族自治县",
+					"寻甸回族彝族自治县"
+				]
+			},
+			{
+				"name": "曲靖市",
+				"area": [
+					"麒麟区",
+					"宣威市",
+					"马龙县",
+					"沾益县",
+					"富源县",
+					"罗平县",
+					"师宗县",
+					"陆良县",
+					"会泽县"
+				]
+			},
+			{
+				"name": "玉溪市",
+				"area": [
+					"红塔区",
+					"江川县",
+					"澄江县",
+					"通海县",
+					"华宁县",
+					"易门县",
+					"峨山彝族自治县",
+					"新平彝族傣族自治县",
+					"元江哈尼族彝族傣族自治县"
+				]
+			},
+			{
+				"name": "保山市",
+				"area": [
+					"隆阳区",
+					"施甸县",
+					"腾冲县",
+					"龙陵县",
+					"昌宁县"
+				]
+			},
+			{
+				"name": "昭通市",
+				"area": [
+					"昭阳区",
+					"鲁甸县",
+					"巧家县",
+					"盐津县",
+					"大关县",
+					"永善县",
+					"绥江县",
+					"镇雄县",
+					"彝良县",
+					"威信县",
+					"水富县"
+				]
+			},
+			{
+				"name": "丽江市",
+				"area": [
+					"古城区",
+					"永胜县",
+					"华坪县",
+					"玉龙纳西族自治县",
+					"宁蒗彝族自治县"
+				]
+			},
+			{
+				"name": "普洱市",
+				"area": [
+					"思茅区",
+					"普洱哈尼族彝族自治县",
+					"墨江哈尼族自治县",
+					"景东彝族自治县",
+					"景谷傣族彝族自治县",
+					"镇沅彝族哈尼族拉祜族自治县",
+					"江城哈尼族彝族自治县",
+					"孟连傣族拉祜族佤族自治县",
+					"澜沧拉祜族自治县",
+					"西盟佤族自治县"
+				]
+			},
+			{
+				"name": "临沧市",
+				"area": [
+					"临翔区",
+					"凤庆县",
+					"云县",
+					"永德县",
+					"镇康县",
+					"双江拉祜族佤族布朗族傣族自治县",
+					"耿马傣族佤族自治县",
+					"沧源佤族自治县"
+				]
+			},
+			{
+				"name": "德宏傣族景颇族自治州",
+				"area": [
+					"潞西市",
+					"瑞丽市",
+					"梁河县",
+					"盈江县",
+					"陇川县"
+				]
+			},
+			{
+				"name": "怒江傈僳族自治州",
+				"area": [
+					"泸水县",
+					"福贡县",
+					"贡山独龙族怒族自治县",
+					"兰坪白族普米族自治县"
+				]
+			},
+			{
+				"name": "迪庆藏族自治州",
+				"area": [
+					"香格里拉县",
+					"德钦县",
+					"维西傈僳族自治县"
+				]
+			},
+			{
+				"name": "大理白族自治州",
+				"area": [
+					"大理市",
+					"祥云县",
+					"宾川县",
+					"弥渡县",
+					"永平县",
+					"云龙县",
+					"洱源县",
+					"剑川县",
+					"鹤庆县",
+					"漾濞彝族自治县",
+					"南涧彝族自治县",
+					"巍山彝族回族自治县"
+				]
+			},
+			{
+				"name": "楚雄彝族自治州",
+				"area": [
+					"楚雄市",
+					"双柏县",
+					"牟定县",
+					"南华县",
+					"姚安县",
+					"大姚县",
+					"永仁县",
+					"元谋县",
+					"武定县",
+					"禄丰县"
+				]
+			},
+			{
+				"name": "红河哈尼族彝族自治州",
+				"area": [
+					"蒙自县",
+					"个旧市",
+					"开远市",
+					"绿春县",
+					"建水县",
+					"石屏县",
+					"弥勒县",
+					"泸西县",
+					"元阳县",
+					"红河县",
+					"金平苗族瑶族傣族自治县",
+					"河口瑶族自治县",
+					"屏边苗族自治县"
+				]
+			},
+			{
+				"name": "文山壮族苗族自治州",
+				"area": [
+					"文山县",
+					"砚山县",
+					"西畴县",
+					"麻栗坡县",
+					"马关县",
+					"丘北县",
+					"广南县",
+					"富宁县"
+				]
+			},
+			{
+				"name": "西双版纳傣族自治州",
+				"area": [
+					"景洪市",
+					"勐海县",
+					"勐腊县"
+				]
+			}
+		]
+	},
+	{
+		"name": "西藏",
+		"city": [{
+				"name": "拉萨市",
+				"area": [
+					"城关区",
+					"林周县",
+					"当雄县",
+					"尼木县",
+					"曲水县",
+					"堆龙德庆县",
+					"达孜县",
+					"墨竹工卡县"
+				]
+			},
+			{
+				"name": "那曲地区",
+				"area": [
+					"那曲县",
+					"嘉黎县",
+					"比如县",
+					"聂荣县",
+					"安多县",
+					"申扎县",
+					"索县",
+					"班戈县",
+					"巴青县",
+					"尼玛县"
+				]
+			},
+			{
+				"name": "昌都地区",
+				"area": [
+					"昌都县",
+					"江达县",
+					"贡觉县",
+					"类乌齐县",
+					"丁青县",
+					"察雅县",
+					"八宿县",
+					"左贡县",
+					"芒康县",
+					"洛隆县",
+					"边坝县"
+				]
+			},
+			{
+				"name": "林芝地区",
+				"area": [
+					"林芝县",
+					"工布江达县",
+					"米林县",
+					"墨脱县",
+					"波密县",
+					"察隅县",
+					"朗县"
+				]
+			},
+			{
+				"name": "山南地区",
+				"area": [
+					"乃东县",
+					"扎囊县",
+					"贡嘎县",
+					"桑日县",
+					"琼结县",
+					"曲松县",
+					"措美县",
+					"洛扎县",
+					"加查县",
+					"隆子县",
+					"错那县",
+					"浪卡子县"
+				]
+			},
+			{
+				"name": "日喀则地区",
+				"area": [
+					"日喀则市",
+					"南木林县",
+					"江孜县",
+					"定日县",
+					"萨迦县",
+					"拉孜县",
+					"昂仁县",
+					"谢通门县",
+					"白朗县",
+					"仁布县",
+					"康马县",
+					"定结县",
+					"仲巴县",
+					"亚东县",
+					"吉隆县",
+					"聂拉木县",
+					"萨嘎县",
+					"岗巴县"
+				]
+			},
+			{
+				"name": "阿里地区",
+				"area": [
+					"噶尔县",
+					"普兰县",
+					"札达县",
+					"日土县",
+					"革吉县",
+					"改则县",
+					"措勤县"
+				]
+			}
+		]
+	},
+	{
+		"name": "陕西省",
+		"city": [{
+				"name": "西安市",
+				"area": [
+					"莲湖区",
+					"新城区",
+					"碑林区",
+					"雁塔区",
+					"灞桥区",
+					"未央区",
+					"阎良区",
+					"临潼区",
+					"长安区",
+					"高陵县",
+					"蓝田县",
+					"户县",
+					"周至县"
+				]
+			},
+			{
+				"name": "铜川市",
+				"area": [
+					"耀州区",
+					"王益区",
+					"印台区",
+					"宜君县"
+				]
+			},
+			{
+				"name": "宝鸡市",
+				"area": [
+					"渭滨区",
+					"金台区",
+					"陈仓区",
+					"岐山县",
+					"凤翔县",
+					"陇县",
+					"太白县",
+					"麟游县",
+					"扶风县",
+					"千阳县",
+					"眉县",
+					"凤县"
+				]
+			},
+			{
+				"name": "咸阳市",
+				"area": [
+					"秦都区",
+					"渭城区",
+					"杨陵区",
+					"兴平市",
+					"礼泉县",
+					"泾阳县",
+					"永寿县",
+					"三原县",
+					"彬县",
+					"旬邑县",
+					"长武县",
+					"乾县",
+					"武功县",
+					"淳化县"
+				]
+			},
+			{
+				"name": "渭南市",
+				"area": [
+					"临渭区",
+					"韩城市",
+					"华阴市",
+					"蒲城县",
+					"潼关县",
+					"白水县",
+					"澄城县",
+					"华县",
+					"合阳县",
+					"富平县",
+					"大荔县"
+				]
+			},
+			{
+				"name": "延安市",
+				"area": [
+					"宝塔区",
+					"安塞县",
+					"洛川县",
+					"子长县",
+					"黄陵县",
+					"延川县",
+					"富县",
+					"延长县",
+					"甘泉县",
+					"宜川县",
+					"志丹县",
+					"黄龙县",
+					"吴起县"
+				]
+			},
+			{
+				"name": "汉中市",
+				"area": [
+					"汉台区",
+					"留坝县",
+					"镇巴县",
+					"城固县",
+					"南郑县",
+					"洋县",
+					"宁强县",
+					"佛坪县",
+					"勉县",
+					"西乡县",
+					"略阳县"
+				]
+			},
+			{
+				"name": "榆林市",
+				"area": [
+					"榆阳区",
+					"清涧县",
+					"绥德县",
+					"神木县",
+					"佳县",
+					"府谷县",
+					"子洲县",
+					"靖边县",
+					"横山县",
+					"米脂县",
+					"吴堡县",
+					"定边县"
+				]
+			},
+			{
+				"name": "安康市",
+				"area": [
+					"汉滨区",
+					"紫阳县",
+					"岚皋县",
+					"旬阳县",
+					"镇坪县",
+					"平利县",
+					"石泉县",
+					"宁陕县",
+					"白河县",
+					"汉阴县"
+				]
+			},
+			{
+				"name": "商洛市",
+				"area": [
+					"商州区",
+					"镇安县",
+					"山阳县",
+					"洛南县",
+					"商南县",
+					"丹凤县",
+					"柞水县"
+				]
+			}
+		]
+	},
+	{
+		"name": "甘肃省",
+		"city": [{
+				"name": "兰州市",
+				"area": [
+					"城关区",
+					"七里河区",
+					"西固区",
+					"安宁区",
+					"红古区",
+					"永登县",
+					"皋兰县",
+					"榆中县"
+				]
+			},
+			{
+				"name": "嘉峪关市",
+				"area": [
+					"嘉峪关市"
+				]
+			},
+			{
+				"name": "金昌市",
+				"area": [
+					"金川区",
+					"永昌县"
+				]
+			},
+			{
+				"name": "白银市",
+				"area": [
+					"白银区",
+					"平川区",
+					"靖远县",
+					"会宁县",
+					"景泰县"
+				]
+			},
+			{
+				"name": "天水市",
+				"area": [
+					"清水县",
+					"秦安县",
+					"甘谷县",
+					"武山县",
+					"张家川回族自治县",
+					"北道区",
+					"秦城区"
+				]
+			},
+			{
+				"name": "武威市",
+				"area": [
+					"凉州区",
+					"民勤县",
+					"古浪县",
+					"天祝藏族自治县"
+				]
+			},
+			{
+				"name": "酒泉市",
+				"area": [
+					"肃州区",
+					"玉门市",
+					"敦煌市",
+					"金塔县",
+					"肃北蒙古族自治县",
+					"阿克塞哈萨克族自治县",
+					"安西县"
+				]
+			},
+			{
+				"name": "张掖市",
+				"area": [
+					"甘州区",
+					"民乐县",
+					"临泽县",
+					"高台县",
+					"山丹县",
+					"肃南裕固族自治县"
+				]
+			},
+			{
+				"name": "庆阳市",
+				"area": [
+					"西峰区",
+					"庆城县",
+					"环县",
+					"华池县",
+					"合水县",
+					"正宁县",
+					"宁县",
+					"镇原县"
+				]
+			},
+			{
+				"name": "平凉市",
+				"area": [
+					"崆峒区",
+					"泾川县",
+					"灵台县",
+					"崇信县",
+					"华亭县",
+					"庄浪县",
+					"静宁县"
+				]
+			},
+			{
+				"name": "定西市",
+				"area": [
+					"安定区",
+					"通渭县",
+					"临洮县",
+					"漳县",
+					"岷县",
+					"渭源县",
+					"陇西县"
+				]
+			},
+			{
+				"name": "陇南市",
+				"area": [
+					"武都区",
+					"成县",
+					"宕昌县",
+					"康县",
+					"文县",
+					"西和县",
+					"礼县",
+					"两当县",
+					"徽县"
+				]
+			},
+			{
+				"name": "临夏回族自治州",
+				"area": [
+					"临夏市",
+					"临夏县",
+					"康乐县",
+					"永靖县",
+					"广河县",
+					"和政县",
+					"东乡族自治县",
+					"积石山保安族东乡族撒拉族自治县"
+				]
+			},
+			{
+				"name": "甘南藏族自治州",
+				"area": [
+					"合作市",
+					"临潭县",
+					"卓尼县",
+					"舟曲县",
+					"迭部县",
+					"玛曲县",
+					"碌曲县",
+					"夏河县"
+				]
+			}
+		]
+	},
+	{
+		"name": "青海省",
+		"city": [{
+				"name": "西宁市",
+				"area": [
+					"城中区",
+					"城东区",
+					"城西区",
+					"城北区",
+					"湟源县",
+					"湟中县",
+					"大通回族土族自治县"
+				]
+			},
+			{
+				"name": "海东地区",
+				"area": [
+					"平安县",
+					"乐都县",
+					"民和回族土族自治县",
+					"互助土族自治县",
+					"化隆回族自治县",
+					"循化撒拉族自治县"
+				]
+			},
+			{
+				"name": "海北藏族自治州",
+				"area": [
+					"海晏县",
+					"祁连县",
+					"刚察县",
+					"门源回族自治县"
+				]
+			},
+			{
+				"name": "海南藏族自治州",
+				"area": [
+					"共和县",
+					"同德县",
+					"贵德县",
+					"兴海县",
+					"贵南县"
+				]
+			},
+			{
+				"name": "黄南藏族自治州",
+				"area": [
+					"同仁县",
+					"尖扎县",
+					"泽库县",
+					"河南蒙古族自治县"
+				]
+			},
+			{
+				"name": "果洛藏族自治州",
+				"area": [
+					"玛沁县",
+					"班玛县",
+					"甘德县",
+					"达日县",
+					"久治县",
+					"玛多县"
+				]
+			},
+			{
+				"name": "玉树藏族自治州",
+				"area": [
+					"玉树县",
+					"杂多县",
+					"称多县",
+					"治多县",
+					"囊谦县",
+					"曲麻莱县"
+				]
+			},
+			{
+				"name": "海西蒙古族藏族自治州",
+				"area": [
+					"德令哈市",
+					"格尔木市",
+					"乌兰县",
+					"都兰县",
+					"天峻县"
+				]
+			}
+		]
+	},
+	{
+		"name": "宁夏",
+		"city": [{
+				"name": "银川市",
+				"area": [
+					"兴庆区",
+					"西夏区",
+					"金凤区",
+					"灵武市",
+					"永宁县",
+					"贺兰县"
+				]
+			},
+			{
+				"name": "石嘴山市",
+				"area": [
+					"大武口区",
+					"惠农区",
+					"平罗县"
+				]
+			},
+			{
+				"name": "吴忠市",
+				"area": [
+					"利通区",
+					"青铜峡市",
+					"盐池县",
+					"同心县"
+				]
+			},
+			{
+				"name": "固原市",
+				"area": [
+					"原州区",
+					"西吉县",
+					"隆德县",
+					"泾源县",
+					"彭阳县"
+				]
+			},
+			{
+				"name": "中卫市",
+				"area": [
+					"沙坡头区",
+					"中宁县",
+					"海原县"
+				]
+			}
+		]
+	},
+	{
+		"name": "新疆",
+		"city": [{
+				"name": "乌鲁木齐市",
+				"area": [
+					"天山区",
+					"沙依巴克区",
+					"新市区",
+					"水磨沟区",
+					"头屯河区",
+					"达坂城区",
+					"东山区",
+					"乌鲁木齐县"
+				]
+			},
+			{
+				"name": "克拉玛依市",
+				"area": [
+					"克拉玛依区",
+					"独山子区",
+					"白碱滩区",
+					"乌尔禾区"
+				]
+			},
+			{
+				"name": "吐鲁番地区",
+				"area": [
+					"吐鲁番市",
+					"托克逊县",
+					"鄯善县"
+				]
+			},
+			{
+				"name": "哈密地区",
+				"area": [
+					"哈密市",
+					"伊吾县",
+					"巴里坤哈萨克自治县"
+				]
+			},
+			{
+				"name": "和田地区",
+				"area": [
+					"和田市",
+					"和田县",
+					"洛浦县",
+					"民丰县",
+					"皮山县",
+					"策勒县",
+					"于田县",
+					"墨玉县"
+				]
+			},
+			{
+				"name": "阿克苏地区",
+				"area": [
+					"阿克苏市",
+					"温宿县",
+					"沙雅县",
+					"拜城县",
+					"阿瓦提县",
+					"库车县",
+					"柯坪县",
+					"新和县",
+					"乌什县"
+				]
+			},
+			{
+				"name": "喀什地区",
+				"area": [
+					"喀什市",
+					"巴楚县",
+					"泽普县",
+					"伽师县",
+					"叶城县",
+					"岳普湖县",
+					"疏勒县",
+					"麦盖提县",
+					"英吉沙县",
+					"莎车县",
+					"疏附县",
+					"塔什库尔干塔吉克自治县"
+				]
+			},
+			{
+				"name": "克孜勒苏柯尔克孜自治州",
+				"area": [
+					"阿图什市",
+					"阿合奇县",
+					"乌恰县",
+					"阿克陶县"
+				]
+			},
+			{
+				"name": "巴音郭楞蒙古自治州",
+				"area": [
+					"库尔勒市",
+					"和静县",
+					"尉犁县",
+					"和硕县",
+					"且末县",
+					"博湖县",
+					"轮台县",
+					"若羌县",
+					"焉耆回族自治县"
+				]
+			},
+			{
+				"name": "昌吉回族自治州",
+				"area": [
+					"昌吉市",
+					"阜康市",
+					"奇台县",
+					"玛纳斯县",
+					"吉木萨尔县",
+					"呼图壁县",
+					"木垒哈萨克自治县",
+					"米泉市"
+				]
+			},
+			{
+				"name": "博尔塔拉蒙古自治州",
+				"area": [
+					"博乐市",
+					"精河县",
+					"温泉县"
+				]
+			},
+			{
+				"name": "石河子",
+				"area": [
+					"石河子"
+				]
+			},
+			{
+				"name": "阿拉尔",
+				"area": [
+					"阿拉尔"
+				]
+			},
+			{
+				"name": "图木舒克",
+				"area": [
+					"图木舒克"
+				]
+			},
+			{
+				"name": "五家渠",
+				"area": [
+					"五家渠"
+				]
+			},
+			{
+				"name": "伊犁哈萨克自治州",
+				"area": [
+					"伊宁市",
+					"奎屯市",
+					"伊宁县",
+					"特克斯县",
+					"尼勒克县",
+					"昭苏县",
+					"新源县",
+					"霍城县",
+					"巩留县",
+					"察布查尔锡伯自治县",
+					"塔城地区",
+					"阿勒泰地区"
+				]
+			}
+		]
+	},
+	{
+		"name": "台湾省",
+		"city": [{
+				"name": "台北市",
+				"area": [
+					"内湖区",
+					"南港区",
+					"中正区",
+					"万华区",
+					"大同区",
+					"中山区",
+					"松山区",
+					"大安区",
+					"信义区",
+					"文山区",
+					"士林区",
+					"北投区"
+				]
+			},
+			{
+				"name": "新北市",
+				"area": [
+					"板桥区",
+					"汐止区",
+					"新店区"
+				]
+			},
+			{
+				"name": "桃园市",
+				"area": [
+					"其他"
+				]
+			},
+			{
+				"name": "台中市",
+				"area": [
+					"其他"
+				]
+			},
+			{
+				"name": "台南市",
+				"area": [
+					"其他"
+				]
+			},
+			{
+				"name": "高雄市",
+				"area": [
+					"其他"
+				]
+			}
+		]
+	},
+	{
+		"name": "澳门",
+		"city": [{
+			"name": "澳门",
+			"area": [
+				"花地玛堂区",
+				"圣安多尼堂区",
+				"大堂区",
+				"望德堂区",
+				"风顺堂区",
+				"嘉模堂区",
+				"圣方济各堂区",
+				"路凼"
+			]
+		}]
+	},
+	{
+		"name": "香港",
+		"city": [{
+			"name": "香港",
+			"area": [
+				"深水埗区",
+				"油尖旺区",
+				"九龙城区",
+				"黄大仙区",
+				"观塘区",
+				"北区",
+				"大埔区",
+				"沙田区",
+				"西贡区",
+				"元朗区",
+				"屯门区",
+				"荃湾区",
+				"葵青区",
+				"离岛区",
+				"中西区",
+				"湾仔区",
+				"东区",
+				"南区"
+			]
+		}]
+	}
+]

+ 103 - 0
pageA/address/pickerAddress.vue

@@ -0,0 +1,103 @@
+<template>
+	<picker @change="bindPickerChange" @columnchange="columnchange" :range="array" range-key="name" :value="value"
+		mode="multiSelector">
+		<slot></slot>
+	</picker>
+</template>
+
+<script>
+	import AllAddress from './data.js'
+	let selectVal = ['', '', '']
+	export default {
+		data() {
+			return {
+				value: [0, 0, 0],
+				array: [],
+				index: 0
+			}
+		},
+		created() {
+			this.initSelect()
+		},
+		methods: {
+			// 初始化地址选项
+			initSelect() {
+				this.updateSourceDate() // 更新源数据
+					.updateAddressDate() // 更新结果数据
+					.$forceUpdate() // 触发双向绑定
+			},
+			// 地址控件改变控件
+			columnchange(d) {
+				this.updateSelectIndex(d.detail.column, d.detail.value) // 更新选择索引
+					.updateSourceDate() // 更新源数据
+					.updateAddressDate() // 更新结果数据
+					.$forceUpdate() // 触发双向绑定
+			},
+
+			/**
+			 * 更新源数据
+			 * */
+			updateSourceDate() {
+				this.array = []
+				this.array[0] = AllAddress.map(obj => {
+					return {
+						name: obj.name
+					}
+				})
+				this.array[1] = AllAddress[this.value[0]].city.map(obj => {
+					return {
+						name: obj.name
+					}
+				})
+				this.array[2] = AllAddress[this.value[0]].city[this.value[1]].area.map(obj => {
+					return {
+						name: obj
+					}
+				})
+				return this
+			},
+
+			/**
+			 * 更新索引
+			 * */
+			updateSelectIndex(column, value) {
+				let arr = JSON.parse(JSON.stringify(this.value))
+				arr[column] = value
+				if (column === 0) {
+					arr[1] = 0
+					arr[2] = 0
+				}
+				if (column === 1) {
+					arr[2] = 0
+				}
+				this.value = arr
+				return this
+			},
+
+			/**
+			 * 更新结果数据 
+			 * */
+			updateAddressDate() {
+				selectVal[0] = this.array[0][this.value[0]].name
+				selectVal[1] = this.array[1][this.value[1]].name
+				selectVal[2] = this.array[2][this.value[2]].name
+				return this
+			},
+
+			/**
+			 * 点击确定
+			 * */
+			bindPickerChange(e) {
+				this.$emit('change', {
+					index: this.value,
+					data: selectVal
+				})
+				return this
+			}
+
+		}
+	}
+</script>
+
+<style>
+</style>

+ 59 - 0
pageA/card/activetion.vue

@@ -0,0 +1,59 @@
+<template>
+	<view>
+		<view class="uni-form-item uni-column">
+			<view class="title" style="font-size: 40rpx;">卡号</view>
+			<input v-model="n" class="uni-input" :disabled="true" />
+		</view>
+		<view class="uni-form-item uni-column">
+			<view class="title" style="font-size: 40rpx;">激活码</view>
+			<input v-model="p" class="uni-input" focus placeholder="激活码" />
+		</view>
+		<view>
+			<view style="padding: 30rpx;">
+				<button @click="submit" type="primary">激活</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				n: uni.getStorageSync("rfiCard"),
+				p: ''
+			}
+		},
+		methods: {
+			async submit() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/activationRFI?n=' + this.n + "&p=" + this.p,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: '激活成功',
+						title: '提示',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						content: res.msg,
+						title: '提示',
+						showCancel: false
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 201 - 0
pageA/card/addressList.vue

@@ -0,0 +1,201 @@
+<template>
+	<view>
+		<scroll-list ref="list" :option="option" @load="load" @refresh="refresh" @loadSuccess="loadSuccess"
+			@scrolltolower="scrolltolower">
+			<view v-for="(item, index) in list" :key="index" @click="handleTest(item)">
+				<view class="infoBody">
+					<view>
+						<view style="border-bottom: 1px #b8b8b8 solid;">
+							<uni-row class="demo-uni-row">
+								<uni-col :span="12">
+									<view class="demo-uni-col dark"
+										style="font-size: 36rpx;margin: -20rpx 0 0 0;font-weight: bold;letter-spacing:5rpx;">
+										{{item.userName}}
+									</view>
+								</uni-col>
+								<uni-col :span="12">
+									<view class="demo-uni-col light" style="padding-bottom: 20rpx;">
+										{{item.phone}}
+									</view>
+								</uni-col>
+							</uni-row>
+						</view>
+						<uni-row class="demo-uni-row">
+							<uni-col>
+								<view class="demo-uni-col light" style="padding: 8rpx;color: #959595;">
+									<view v-if="item.provinces ">
+										{{item.provinces}}
+									</view>
+									<view v-if="item.detailedAddress">
+										{{ item.detailedAddress}}
+									</view>
+								</view>
+							</uni-col>
+						</uni-row>
+						<uni-row class="demo-uni-row">
+							<uni-col :span="13">
+								<view class="demo-uni-col light" style="color: #727272;">
+
+								</view>
+							</uni-col>
+							<uni-col :span="11">
+								<view class="demo-uni-col light" style="color: #727272;">
+
+								</view>
+							</uni-col>
+						</uni-row>
+					</view>
+				</view>
+			</view>
+		</scroll-list>
+		<view>
+			<view class="content" @click="plusAdd">
+				<!-- @touchstart="handleStart" @touchmove="handleMove" @touchend="handleEnd" -->
+				<view :style="{'transform':'translate3d('+0+'px,'+-80+'px,0)'}" class="touch">
+					<view style="font-size: 45rpx;">
+						+
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<style lang="scss">
+
+	.touch {
+		position: fixed;
+		right: 40rpx;
+		bottom: 60rpx;
+		width: 95rpx;
+		height: 95rpx;
+		/* 知识点
+		line-height是行高,针对的对象是文字,height针对的是容器,
+		也就是高度,当height和line-height值相同时会居中,
+		当line-height值小于height时文字向上移动,反之向下移动。
+		 */
+		line-height: 95rpx;
+		/* 文字垂直居中 */
+		text-align: center;
+		/* 水平居中 */
+		background-color: rgba(0, 0, 0, 0.6);
+		border-radius: 50%;
+		color: #fff;
+		font-size: 60rpx;
+		/* 去除标签点击事件高亮效果 */
+		-webkit-tap-highlight-color: transparent;
+		/* 使用transform: translate3d 处理性能高 GUP */
+	}
+
+	.page-wrap {}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 40rpx;
+		border-radius: 20rpx;
+		margin: 20rpx;
+		box-shadow: 0px 2px 10px #cccccc;
+	}
+
+	.content {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				userName: uni.getStorageSync("userInfo").nickName,
+				page: 1,
+				list: [],
+				total: 0,
+				clickType: 0
+			}
+		},
+		onLoad() {},
+		onShow() {
+			this.refresh({
+				page: 1,
+				size: 5
+			})
+		},
+		methods: {
+			plusAdd() {
+				uni.navigateTo({
+					url: 'addressMgt',
+					success() {
+						uni.removeStorageSync("addressData")
+					}
+				})
+			},
+			handleTest(item) {
+				if (uni.getStorageSync("clickType") === 0) {
+					uni.setStorageSync("addressData", item)
+					this.$goto('addressMgt')
+				} else {
+					uni.redirectTo({
+						url: '../../pages/integral/list',
+						success() {
+							uni.setStorageSync("addressData", item)
+							uni.setStorageSync("clickType", 1)
+						}
+					})
+				}
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/uadsList?userCode=' + uni.getStorageSync("userInfo").userName + '&pageNum=' +
+						paging.page +
+						'&pageSize=' + paging.size,
+					method: 'get',
+					urlType: 2
+				});
+				if (res.code === 200) {
+					setTimeout(() => {
+						if (paging.page === 1) {
+							//this.list = res.rows
+							this.total = res.total
+							this.$refs.list.loadSuccess({
+								list: res.rows,
+								total: this.total
+							});
+						} else if (paging.page > 1) {
+							for (var i = 0; i < res.rows.length; i++) {
+								this.list.push(res.rows[i])
+							}
+							this.$refs.list.loadSuccess({
+								list: this.list,
+								total: this.total
+							});
+						}
+					}, 300)
+				}
+			},
+			// 刷新刷剧
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {
+				console.log(e)
+			},
+			load(paging) {
+				console.log(2, paging)
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				console.log(3, list)
+				this.list = list
+			}
+		}
+	}
+</script>

+ 117 - 0
pageA/card/addressMgt.vue

@@ -0,0 +1,117 @@
+<template>
+	<view class="u-page">
+		<view class="u-demo-block">
+			<view class="u-demo-block__content">
+				<u--form labelPosition="left" :model="form" ref="form">
+					<u-form-item label="姓名" prop="userName" labelWidth="80" borderBottom>
+						<view class="content">
+							<u--input placeholder="姓名" v-model="form.userName" count></u--input>
+						</view>
+					</u-form-item>
+					<u-form-item label="手机号" prop="phone" labelWidth="80" borderBottom>
+						<view class="content">
+							<u--input placeholder="手机号" v-model="form.phone" count></u--input>
+						</view>
+					</u-form-item>
+					<u-form-item label="省市区" prop="provinces" labelWidth="80" borderBottom>
+						<view class="content">
+							<pickerAddress @change="change">
+								<view v-if="form.provinces">
+									{{form.provinces}}
+								</view>
+								<view v-else style="color: #c4c4c4;">
+									选择地址
+								</view>
+							</pickerAddress>
+						</view>
+					</u-form-item>
+					<u-form-item label="详细地址" prop="detailedAddress" labelWidth="80" borderBottom>
+						<u--textarea v-model="form.detailedAddress"></u--textarea>
+					</u-form-item>
+				</u--form>
+				<u-button :disabled="isDisabled" color="rgb(55,186,189)" text="提交" shape="circle" size="large"
+					@click="submit" customStyle="margin-top: 50px">
+				</u-button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import pickerAddress from '../address/pickerAddress.vue'
+	export default {
+		components: {
+			pickerAddress
+		},
+		data() {
+			return {
+				isDisabled: false,
+				form: {
+					userCode: uni.getStorageSync("setUserName"),
+					userName: '',
+					phone: '',
+					detailedAddress: '',
+					provinces: ''
+				}
+			}
+		},
+		onLoad() {},
+		onShow() {
+			if (uni.getStorageSync("addressData")) {
+				this.form = uni.getStorageSync("addressData")
+			}
+		},
+		methods: {
+			change(data) {
+				this.form.provinces = data.data.join('')
+			},
+			async submit() {
+				if (!this.form.userName) {
+					this.$showModal('请输入姓名')
+					 return
+				}
+				if (!this.form.phone) {
+					this.$showModal('请输入手机号') 
+					return
+				}
+				if (!this.form.provinces) {
+
+					this.$showModal('选择省市区')
+					 return
+				}
+				if (!this.form.detailedAddress) {
+
+					this.$showModal('请输入详细地址')
+					 return
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/saveAds',
+					method: 'post',
+					urlType: 2,
+					data: this.form
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: "保存成功",
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showToast({
+						duration: 2500,
+						title: res.msg,
+						icon: 'error',
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 140 - 0
pageA/card/amassScoreRecord.vue

@@ -0,0 +1,140 @@
+<template>
+	<view>
+		<scroll-list ref="list" :option="option" @load="load" @refresh="refresh" @loadSuccess="loadSuccess"
+			@scrolltolower="scrolltolower">
+			<view v-for="(item, index) in list" :key="index" @click="handleTest(item)">
+				<view class="infoBody">
+					<view>
+						<view style="border-bottom: 1px #b8b8b8 solid;">
+							<uni-row class="demo-uni-row">
+								<uni-col :span="20">
+									<view class="demo-uni-col dark"
+										style="font-size: 36rpx;margin: -20rpx 0 0 0;font-weight: bold;letter-spacing:5rpx;">
+										{{changeTypes [parseInt(item.changeType)-1] }}
+									</view>
+								</uni-col>
+								<uni-col :span="4">
+									<view v-if="item.changeType != '2'" class="demo-uni-col light"
+										style="color: rgb(55,186,189);margin-bottom: 10rpx;">
+										{{"+ "+item.amassScore}}
+									</view>
+									<view v-else class="demo-uni-col light"
+										style="color: rgb(55,186,189);margin-bottom: 10rpx;">
+										{{"- "+item.amassScore}}
+									</view>
+								</uni-col>
+							</uni-row>
+						</view>
+						<uni-row class="demo-uni-row">
+							<uni-col>
+								<view class="demo-uni-col light" style="padding: 8rpx;color: #b1b1b1;">
+								</view>
+							</uni-col>
+						</uni-row>
+						<uni-row class="demo-uni-row">
+							<uni-col :span="11">
+								<view class="demo-uni-col light" style="color: #727272;">
+									{{userName}}
+								</view>
+							</uni-col>
+							<uni-col :span="13">
+								<view class="demo-uni-col light" style="color: #727272;">
+									{{item.changeDate}}
+								</view>
+							</uni-col>
+						</uni-row>
+					</view>
+				</view>
+			</view>
+		</scroll-list>
+	</view>
+</template>
+<style lang="scss">
+	.page-wrap {}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 40rpx 40rpx 20rpx 40rpx;
+		border-radius: 20rpx;
+		margin: 20rpx;
+		box-shadow: 0px 2px 10px #cccccc;
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				userName: uni.getStorageSync("userInfo").nickName,
+				page: 1,
+				list: [],
+				total: 0,
+				changeTypes: ['使用积分卡', '兑换礼品', '退还', '平台操作']
+			}
+		},
+		onLoad() {},
+		onShow() {
+			this.refresh({
+				page: 1,
+				size: 5
+			})
+		},
+		methods: {
+			handleTest(item) {
+				item.pageType = 1
+				uni.setStorageSync("approval", item)
+				this.$goto('../ge/geApproval')
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/asl?uc=' + uni.getStorageSync("userInfo").userName + '&pageNum=' + paging.page +
+						'&pageSize=' + paging.size,
+					method: 'get',
+					urlType: 2
+				});
+				if (res.code === 200) {
+					setTimeout(() => {
+						if (paging.page === 1) {
+							//this.list = res.rows
+							this.total = res.total
+							this.$refs.list.loadSuccess({
+								list: res.rows,
+								total: this.total
+							});
+						} else if (paging.page > 1) {
+							for (var i = 0; i < res.rows.length; i++) {
+								this.list.push(res.rows[i])
+							}
+							this.$refs.list.loadSuccess({
+								list: this.list,
+								total: this.total
+							});
+						}
+					}, 300)
+				}
+			},
+			// 刷新刷剧
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {
+				console.log(e)
+			},
+			load(paging) {
+				console.log(2, paging)
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				console.log(3, list)
+				this.list = list
+			}
+		}
+	}
+</script>

+ 140 - 0
pageA/card/expense/details.vue

@@ -0,0 +1,140 @@
+<template>
+	<view>
+		<view class="view">
+			<!-- 			<view v-if="type === 0" class="listItemStyle">
+				<u-text text="查看订单进度" color="rgb(0, 170, 255)" size="20"></u-text>
+			</view> -->
+			<u-list @scrolltolower="scrolltolower">
+				<view v-if="dataList.length === 0" style="padding: 0 50px;">
+					<image style="margin: 0 auto; width: 100%;" src="../../../static/img/page/empty_view.png"></image>
+				</view>
+				<view class="listItemStyle">
+					<view style="padding: 10rpx;color: #848484;font-size: 30rpx;">
+						联系方式
+					</view>
+					<view style="padding: 5rpx 30rpx;color: #848484;">
+						<view v-if="order.userName && order.phone">
+							{{order.userName +" "+ order.phone}}
+						</view>
+					</view>
+					<view style="padding: 10rpx;color: #848484;font-size: 30rpx;">
+						收货地址
+					</view>
+					<view style="padding: 5rpx 30rpx;color: #848484;">
+						<view v-if="order.placeNumber">
+							{{order.placeNumber}}
+						</view>
+					</view>
+				</view>
+				<u-list-item v-for="(item, index) in dataList" :key="index">
+					<view v-if="item.amount !== 0 && item.amount" class="listItemStyle">
+						<u-row>
+							<u-col span="3">
+								<u--image :showLoading="true" shape="circle" :src="baseURL+item.pictrue" width="70px"
+									height="70px" style="margin: 10px;"></u--image>
+							</u-col>
+							<u-col span="7" style="margin-left: 5px;">
+								<view>
+									<u--text :text="item.name" size="20"></u--text>
+								</view>
+								<view style="margin-top: 10px;">
+									<u--text :text="'¥'+item.price" size="20"></u--text>
+								</view>
+							</u-col>
+							<u-col span="2">
+								<view>
+									<u--text :text="item.amount+'份'" size="25"></u--text>
+								</view>
+							</u-col>
+						</u-row>
+					</view>
+				</u-list-item>
+			</u-list>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				baseURL: this.$BASE_URL,
+				priceSum: 0.0,
+				dateShow: false,
+				data: {
+					organizationName: "",
+				},
+				order: uni.getStorageSync('order'),
+				from: {
+					orderNumber: '',
+					organizationCode: ''
+				},
+				dataList: [],
+				dataListNow: [],
+				type: uni.getStorageSync("tabType")
+			}
+		},
+		onLoad() {
+			this.submitOrder()
+		},
+		methods: {
+			toJDPage() {
+				this.$goto('../../../pageA/card/orderProcess')
+			},
+			async submitOrder() {
+				this.from.orderNumber = this.order.orderNumber
+				this.from.organizationCode = this.order.jgid
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getOrderDetail',
+					method: 'post',
+					data: this.from,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataList = res.rows
+				}
+			},
+			loadmore(data) {
+				for (var i = 0; i < data.length; i++) {
+					this.dataList.push(data[i])
+				}
+			},
+			result(time, mode) {
+				const timeFormat = uni.$u.timeFormat
+				switch (mode) {
+					case 'datetime':
+						return timeFormat(time, 'yyyy-mm-dd hh:MM')
+					case 'date':
+						return timeFormat(time, 'yyyy-mm-dd')
+					case 'year-month':
+						return timeFormat(time, 'yyyy-mm')
+					case 'time':
+						return time
+					default:
+						return ''
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	.view {
+		background-color: #ebebeb;
+		padding-top: 10px;
+	}
+
+	.listTermDate {
+		padding: 10px 0;
+	}
+
+	.listItemStyle {
+		margin: 5px 12px;
+		padding: 10px;
+		border-radius: 15px;
+		background-color: #fafafa;
+	}
+</style>

+ 291 - 0
pageA/card/expense/expenseCalendar.vue

@@ -0,0 +1,291 @@
+<template>
+	<view>
+		<view>
+			<view>
+				<u-list @scrolltolower="scrolltolower">
+					<!-- <view class="listTermDate">
+						 <u-cell-group>
+								<u-cell :title="from.date" arrow-direction="down" @click="dateShow = true" isLink></u-cell>
+							</u-cell-group> 
+						<view>
+							<u-datetime-picker :show="dateShow" closeOnClickOverlay v-model="from.date" mode="date"
+								@cancel="dateShow = false" @confirm="submitDate" :formatter="formatter"
+								@change="change">
+							</u-datetime-picker>
+						</view>
+					</view> -->
+					<view class="hand">
+						<u-row>
+							<u-col span="8">
+								<view class="orgTop">
+									<uni-row>
+										<uni-col :span="10">
+											<u--text text="所属机构" size="22" bold color="#619f8a"></u--text>
+										</uni-col>
+										<uni-col :span="24">
+											<u--text :text="from.organizationName" size="22" bold color="#757575">
+											</u--text>
+										</uni-col>
+									</uni-row>
+								</view>
+							</u-col>
+							<!--<u-col span="4">
+										<view>
+											<u-button class="sxButton" size="normal" loadingMode="circle" color="#65c1aa">统计查看
+											</u-button>
+										</view>
+									</u-col> -->
+						</u-row>
+					</view>
+					<view v-if="indexList.length === 0" style="padding: 0 50px;">
+						<image style="margin: 0 auto; width: 100%;" src="../../../static/img/page/empty_view.png">
+						</image>
+					</view>
+					<view v-for="(item, index) in indexList" :key="index">
+						<view :data-index="index" class="order-item">
+							<view class="listItemStyle">
+								<u-row>
+									<u-col span="3">
+										<view class="orderFoodStyle orderFoodType0">
+											{{item.statusText}}
+										</view>
+									</u-col>
+									<u-col span="5" class="orderFoodStyle orderFoodType">
+										<view style="font-size: 26rpx;">
+											订单:{{item.orderNumber}}
+										</view>
+									</u-col>
+									<u-col span="4" textAlign="right">
+										<view class="moneyText">
+											{{"- "+item.orderTotal+""}}
+										</view>
+									</u-col>
+								</u-row>
+								<u-row>
+									<u-col span="5" class="orderTimeText">{{item.paytime}}</u-col>
+									<u-col span="1" class="orderTimeText">
+									</u-col>
+									<u-col span="2" class="orderTimeText">
+										<view style="color: #1787ff;font-size: 34rpx;" @click="toJDPage(item)">
+											进度
+										</view>
+									</u-col>
+									<u-col span="3" class="orderTimeText">
+										<view style="color: #1787ff;font-size: 34rpx;" @click="getDetails(item)">
+											详情
+										</view>
+									</u-col>
+									<u-col span="2" class="orderTimeText">
+										<view v-if="item.isNews === '1'"
+											style="font-size: 22rpx;color: rgb(55,186,189);" @click="toJDPage(item)">
+											新消息
+										</view>
+									</u-col>
+								</u-row>
+							</view>
+						</view>
+					</view>
+				</u-list>
+				<u-modal :show="modalContent1.show" :title="modalContent1.title" :showCancelButton="true"
+					confirmColor="#53a591" @confirm="backSubmit()" @cancel="modalContent1.show = false">
+					{{modalContent1.content}}
+				</u-modal>
+				<u-modal :show="modalContent2.show" :title="modalContent2.title" :content='modalContent2.content'
+					confirmColor="#53a591" @confirm="modalContent2.show = false">
+				</u-modal>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				type: uni.getStorageSync("tabType"),
+				dateShow: false,
+				data: {},
+				from: {
+					organizationName: ''
+				},
+				indexList: [],
+				modalContent1: {
+					show: false,
+					title: '提示',
+					content: '确认退单吗?'
+				},
+				modalContent2: {
+					show: false,
+					title: '提示',
+					content: ''
+				},
+				//列表数据(
+				indexList: [],
+				//左滑默认宽度
+				startX: 0,
+				startY: 0,
+				delBtnWidth: 90,
+				pageNum: 1,
+				pageSize: 10,
+				total: 1
+			}
+		},
+		onLoad() {
+			this.getExpenseCalendarList()
+		},
+		onShow() {
+			this.getExpenseCalendarList()
+		},
+		onHide() {
+			this.getExpenseCalendarList()
+		},
+		methods: {
+			toJDPage(item) {
+				uni.setStorageSync('order', item)
+				this.$goto('../orderProcess')
+			},
+			getDetails(item) {
+				uni.setStorageSync('order', item)
+				this.$goto('details')
+			},
+			async getExpenseCalendarList() {
+				if (this.indexList.length >= this.total) {
+					return;
+				}
+				const orgInfo = uni.getStorageSync("orgInfo")
+				this.from.organizationName = orgInfo.organizationName
+				this.from.userName = uni.getStorageSync('userInfo').userName
+				this.from.organizationCode = orgInfo.organizationCode
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getOrder?' + "pageNum=" + this.pageNum + "&" + "pageSize=" + this.pageSize,
+					method: 'post',
+					data: this.from,
+					urlType: 2
+				});
+				if (res.code === 200) {
+					this.total = res.total
+					this.loadmore(res.rows)
+				}
+			},
+			change(e) {
+				//this.changeDate = this.result(e.value, e.mode)
+			},
+			scrolltolower() {
+				this.pageNum++;
+				this.getExpenseCalendarList()
+			},
+			loadmore(data) {
+				if (data.length === 0) {
+					return;
+				}
+				for (var i = 0; i < data.length; i++) {
+					this.indexList.push(data[i])
+				}
+			},
+			formatter(type, value) {
+				if (type === 'year') {
+					return `${value}年`
+				}
+				if (type === 'month') {
+					return `${value}月`
+				}
+				if (type === 'day') {
+					return `${value}日`
+				}
+				return value
+			},
+			//删除方法
+			delData(item) {
+				this.modalContent1.show = true;
+				uni.setStorageSync("orderNumber", item.orderNumber)
+				//关闭侧边滑动
+				item.right = 0
+			}
+		}
+	}
+</script>
+
+<style>
+
+	.hand {
+		margin-top: 2px;
+		padding: 5%;
+		border-radius: 10px 10px 0 0;
+		background: linear-gradient(to bottom right, #85c1bf, #f1fef9);
+	}
+
+	.orgTop {
+		margin-bottom: 5px;
+	}
+
+	.sxButton {
+		width: 100px;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+	}
+
+	.order-item {
+		position: relative;
+	}
+
+	.remove {
+		width: 100px;
+		height: 100%;
+		background-color: #57aa8e;
+		color: white;
+		position: absolute;
+		top: 0;
+		right: -100px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 18px;
+	}
+
+	.listTermDate {
+		padding: 10px 0;
+	}
+
+	.listItemStyle {
+		background-color: #ffffff;
+		padding: 15px;
+		border: 1px solid #d8d8d8;
+		margin: 10rpx;
+	}
+
+	.orderFoodStyle {
+		font-size: 20px;
+	}
+
+	.orderFoodType {
+		color: #000000;
+	}
+
+	.orderFoodType0 {
+		color: #1787ff;
+	}
+
+	.orderFoodType1 {
+		color: #da0000;
+	}
+
+	.orderFoodType2 {
+		color: #00af00;
+	}
+
+	.moneyText {
+		font-size: 26rpx;
+		color: #b30000;
+	}
+
+	.orderTimeText {
+		position: relative;
+		top: 5px;
+		color: #bebebe;
+		font-size: 16px;
+	}
+</style>

+ 59 - 0
pageA/card/grant.vue

@@ -0,0 +1,59 @@
+<template>
+	<view>
+		<view class="uni-form-item uni-column">
+			<view class="title" style="font-size: 40rpx;">卡号</view>
+			<input v-model="n" class="uni-input" :disabled="true" />
+		</view>
+		<view class="uni-form-item uni-column">
+			<view class="title" style="font-size: 40rpx;">激活码</view>
+			<input v-model="p" class="uni-input" focus placeholder="激活码" />
+		</view>
+		<view>
+			<view style="padding: 30rpx;">
+				<button @click="submit" type="primary">激活</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				n: uni.getStorageSync("rfiCard"),
+				p: ''
+			}
+		},
+		methods: {
+			async submit() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/activationRFI?n=' + this.n + "&p=" + this.p,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: '激活成功',
+						title: '提示',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showToast({
+						duration: 2500,
+						title: res.msg,
+						icon: 'error',
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 120 - 0
pageA/card/index.vue

@@ -0,0 +1,120 @@
+<template>
+	<view>
+		<u-cell-group>
+			<!-- 			<u-cell icon="rmb-circle" title="积分余额" value="">
+				<u--text slot="right-icon" :text="acTitle" color="rgb(55,186,189)"></u--text>
+				<u--text slot="right-icon" :text="amassScore" color="rgb(55,186,189)"></u--text>
+			</u-cell> -->
+			<!-- <u-cell icon="calendar" title="积分订单" @click="toExpenseCalendarPage" :isLink="true"></u-cell> -->
+			<u-cell icon="scan" title="积分卡激活" :isLink="true" @click="takeMeal"></u-cell>
+			<!-- <u-cell icon="tags" title="积分卡发放" :isLink="true" @click="grantMeal"></u-cell> -->
+			<u-cell icon="map" title="收件地址" :isLink="true" @click="toAddressMgtPage"></u-cell>
+			<u-cell icon="clock" title="积分历史" :isLink="true" @click="toAmassScoreRecordPage"></u-cell>
+		</u-cell-group>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				acTitle: '',
+				amassScore: 0
+			}
+		},
+		onLoad() {
+			this.acTitle = uni.getStorageSync('orgInfo').organizationName.substring(0, 1) + ":"
+			this.getDataAmassScore()
+		},
+		methods: {
+
+			toExpenseCalendarPage() {
+				uni.navigateTo({
+					url: "expense/expenseCalendar"
+				})
+			},
+			toAmassScoreRecordPage() {
+				this.$goto('amassScoreRecord')
+			},
+			takeMeal() {
+				var that = this;
+				uni.scanCode({
+					scanType: ['qrCode'],
+					success: function(res) {
+						// uni.showModal({
+						// 	content: JSON.stringify(res),
+						// })
+						if (res.result) {
+							uni.setStorageSync("rfiCard", res.result)
+						}
+						if (res.result.indexOf("type") !== -1) {
+							if (JSON.parse(res.result).data) {
+								uni.setStorageSync("rfiCard", JSON.parse(res.result).data)
+							}
+						}
+						that.$goto('activetion');
+					},
+					fail: function(a) {},
+					complete: function(b) {}
+				})
+			},
+			grantMeal() {
+				var that = this;
+				uni.scanCode({
+					scanType: ['qrCode'],
+					success: function(res) {
+						uni.setStorageSync("rfiCard", res.result)
+						that.grantUpLoad(res)
+					},
+					fail: function(a) {},
+					complete: function(b) {}
+				})
+			},
+			toAddressMgtPage() {
+				uni.setStorageSync("clickType", 0)
+				this.$goto('addressList')
+			},
+			async grantUpLoad(data) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/scg?cn=' + data.result + "&on=" + uni.getStorageSync("orgInfo")
+						.organizationName,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.$showModal("发放成功")
+				} else {
+					uni.showToast({
+						duration: 2500,
+						title: res.msg,
+						icon: 'error',
+					});
+				}
+			},
+			async getDataAmassScore(data) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/ac?uc=' + uni.getStorageSync("setUserName"),
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.amassScore = res.data
+				} else {
+					uni.showToast({
+						duration: 2500,
+						title: res.msg,
+						icon: 'error',
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 151 - 0
pageA/card/orderProcess.vue

@@ -0,0 +1,151 @@
+this.$getUrlType()<template>
+	<view>
+		<view style="padding: 30rpx;">
+			<view style="font-size: 30rpx;color: #b8b8b8;">
+				下单备注:
+			</view>
+			<view style="font-size: 40rpx;color: #9d9d9d;padding: 0 20rpx;">
+				<view v-if="data.remark">
+					{{data.remark}}
+				</view>
+				<view v-else>
+					无
+				</view>
+			</view>
+		</view>
+		<view style="padding: 30rpx;overflow: auto; height:650rpx;">
+			<uni-steps :options="list" :active="active" direction="column" active-color="rgb(55,186,189)" />
+			<view v-if="data.statusText === '已回收'">
+				<button style="width: 600rpx;" @click="backOd">退单</button>
+			</view>
+			<view v-if="data.statusText === '已下单'">
+				<button style="width: 600rpx;" @click="backOd">退单</button>
+			</view>
+		</view>
+		<view v-if="data.statusText !== '已完成'" style="padding: 0 30rpx 30rpx 30rpx;background-color: #f5f5f5;">
+			<view style="color: #9a9a9a;padding: 10rpx;">
+				问题反馈
+			</view>
+			<view style="margin-bottom: 40rpx;">
+				<u-textarea v-model="form.processDesc" border></u-textarea>
+			</view>
+			<u-button text="发送" color="rgb(55,186,189)" @click="clientSubmit"></u-button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				form: {
+					orderNo: uni.getStorageSync("order").orderNumber,
+					userCode: uni.getStorageSync("setUserName"),
+					processDesc: '',
+				},
+				list: [],
+				data: uni.getStorageSync("order"),
+				active: 0
+			}
+		},
+		onLoad() {
+			this.getList()
+			this.newsToOne()
+		},
+		onShow() {
+			this.newsToOne()
+		},
+		methods: {
+			async backOd() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/backOd?on=' + this.data.orderNumber,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.data.statusText = '已完成'
+					uni.redirectTo({
+						url: '../../pages/user/index',
+						success() {
+							uni.showModal({
+								title: "提示",
+								content: "积分已退还,订单结束",
+								showCancel: false,
+								confirmColor: 'rgb(55,186,189)'
+							})
+						}
+					})
+				}
+			},
+			async clientSubmit() {
+				if (!this.form.processDesc) {
+					this.$showModal("请填写反馈")
+					return
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/clientSubmit',
+					method: 'post',
+					data: this.form,
+					urlType: 2
+				});
+				if (res.code === 200) {
+					this.form.processDesc = ''
+					this.getList()
+				}
+			},
+			async newsToOne() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/nto?on=' + this.data.orderNumber,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+			},
+			async getList() {
+				this.list = []
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/opl?uc=' + uni.getStorageSync("userInfo").userName + "&on=" + this.data
+						.orderNumber,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					let data = res.data
+					for (var i = 0; i < data.length; i++) {
+						if (data[i].processStatus) {
+							this.list.push({
+								title: data[i].processStatus + " : " + data[i].processDesc,
+								desc: data[i].processDate
+							})
+						} else {
+							this.list.push({
+								title: data[i].processDesc,
+								desc: data[i].processDate
+							})
+						}
+						if (data[i].processDate) {
+							this.active = i
+						}
+					}
+				} else {
+					uni.showToast({
+						duration: 2500,
+						title: res.msg,
+						icon: 'error',
+					});
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 119 - 0
pageA/club/apply.vue

@@ -0,0 +1,119 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc">
+				<hsInput label="用户编号" v-model="form.userCode" :disabled="true" />
+			</view>
+			<view class="desc">
+				<hsInput label="领取人" v-model="form.userName" :disabled="true" />
+			</view>
+			<view class="desc">
+				<hsDictSelect label="地点" dictKey="welfare_apply_addr" v-model="form.address" :disabled="isDisabled" />
+			</view>
+		</view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="submit" color="rgb(55,186,189)" text="报名">
+						</u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import hsDictSelect from "../components/dictSelect.vue"
+	import hsInput from "../components/input.vue"
+	export default {
+		components: {
+			hsDictSelect,
+			hsInput
+		},
+		data() {
+			return {
+				isDisabled: false,
+				defaultDept: '',
+				form: {
+					userCode: null,
+					userName: null,
+					address: null,
+					id: uni.getStorageSync("applyInfo").id,
+					source: uni.getStorageSync("applyInfo").source
+				}
+			}
+		},
+		onLoad() {
+			this.getApplyData()
+			this.form.userCode = uni.getStorageSync("userInfo").userName
+			this.form.userName = uni.getStorageSync("userInfo").nickName
+		},
+		methods: {
+			async submit() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/sumbitWelfare',
+					method: 'post',
+					data: this.form,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.$showModal("报名成功")
+				} else {
+					this.$showModal(res.msg)
+				}
+			},
+			getApplyData() {
+				this.$httpRequest({
+					url: '/app/getApplyData?id=' + uni.getStorageSync("applyInfo").id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				}).then(res => {
+					res = res.data
+					if (res.code === 200) {
+						if (res.data.nowStatus === '2') {
+							this.form.address = res.data.address
+							this.isDisabled = true
+							this.$showModal("您已完成报名")
+						}
+					} else {
+
+					}
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 156 - 0
pageA/club/appoint.vue

@@ -0,0 +1,156 @@
+<template>
+	<view>
+		<scroll-list ref="list" :option="option" @load="load" @refresh="refresh" @loadSuccess="loadSuccess"
+			@scrolltolower="scrolltolower">
+
+			<view style="text-align: center;border: 1rpx solid #cecece;color: #9c9c9c;">
+				<uni-row>
+					<uni-col :span="20">
+						<uni-row>
+							<uni-col :span="16">活动名</uni-col>
+							<uni-col :span="8">活动类型</uni-col>
+						</uni-row>
+					</uni-col>
+					<uni-col :span="4">
+						操作
+					</uni-col>
+				</uni-row>
+			</view>
+			<view v-for="(item, index) in list" :key="index">
+				<view
+					style="text-align: center;border: 1rpx solid #cecece;color: #747474;padding: 20rpx 0;font-size: 50rpx;">
+					<uni-row>
+						<uni-col :span="20">
+							<view @click="handleTest(item)">
+								<uni-row>
+									<uni-col :span="16">{{item.eventName}}</uni-col>
+									<uni-col :span="8">{{item.eventType}}</uni-col>
+								</uni-row>
+								<view
+									style="font-size: 20rpx;color: #a2a2a2;text-align: left;padding: 15rpx 0 0 25rpx;">
+									预约时间:{{item.createTime}}
+								</view>
+							</view>
+						</uni-col>
+						<uni-col :span="4">
+							<view class="yyButton" style="margin:20rpx 5rpx 0;border: 1rpx solid rgb(10, 185, 156);
+										color: rgb(10, 185, 156);font-size: 22rpx; padding:  5rpx;
+										 border-radius: 10rpx;" @click="back(item)">
+								取消预约
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+			</view>
+		</scroll-list>
+	</view>
+</template>
+<style lang="scss" scoped>
+	.page-wrap {}
+
+	.yyButton:active {
+		background-color: #dedede;
+	}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 20rpx 0;
+		font-size: 30px;
+		margin: 2rpx;
+		box-shadow: 0px 2px 5px #e5e5e5;
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				page: 1,
+				list: [],
+				scrollList: [],
+				total: 0
+			}
+		},
+		onLoad() {
+
+		},
+		onShow() {
+			this.$refs.list.refresh()
+		},
+		methods: {
+			async back(item) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/backEventOrder?id=' + item.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.taskList({
+						page: 1,
+						size: 5
+					})
+					this.$showModal("取消成功")
+				} else {
+					this.$showModal(res.msg)
+				}
+			},
+			handleTest(item) {
+				setTimeout(() => {
+					this.list = []
+				}, 1000)
+				uni.setStorageSync("eventId", item.eventId)
+				uni.setStorageSync("isUpload", 1)
+				uni.navigateTo({
+					url: "more"
+				})
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/eventOrders?pageNum=' + paging.page + '&pageSize=' + paging.size,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (paging.page === 1) {
+						this.scrollList = res.rows
+						this.total = res.total
+						this.$refs.list.loadSuccess({
+							list: res.rows,
+							total: this.total
+						});
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							this.scrollList.push(res.rows[i])
+						}
+						this.$refs.list.loadSuccess({
+							list: this.scrollList,
+							total: this.total
+						});
+					}
+				}
+			},
+			// 刷新刷剧
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {
+				console.log(e)
+			},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>

+ 583 - 0
pageA/club/index.vue

@@ -0,0 +1,583 @@
+<template>
+	<view>
+		<view v-if="noticeStatus">
+			<u-notice-bar :text="noticeText"></u-notice-bar>
+		</view>
+		<u-sticky>
+			<view>
+				<!-- @click="oneTypeClick(item,index)" -->
+				<scroll-view class="scroll-view_H_MY" :scroll-x="true" @scroll="scroll">
+					<view :class="index=== oneTypeActive ? 'scroll-view-item_H_MY-active':''"
+						v-for="(item,index) in ['活动']" class="scroll-view-item_H_MY">
+						{{item}}
+					</view>
+				</scroll-view>
+			</view>
+		</u-sticky>
+		<view style="display: flex;flex-flow: row wrap;">
+			<view style="width: 20%; text-align: center;background-color: #f0f0f0;">
+				<scroll-view scroll-y scroll-with-animation :scrollTop="scrollLeftTop"
+					:style="[{height: containerHeight + 'px'}]">
+					<view :class="index === twoTypeActive ? 'giftTypeItem-active':''" @click="twoTypeClick(item,index)"
+						v-for="(item,index) in clubsData" class="giftTypeItem">
+						{{item.projectName}}
+					</view>
+				</scroll-view>
+			</view>
+			<view style="width: 80%;background-color: #ffffff;text-align:center;">
+				<scroll-view scroll-y scroll-with-animation :scrollTop="scrollLeftTop" :lower-threshold="110"
+					@scrolltolower="refreshGift" :style="[{height: containerHeight + 'px'}]">
+					<view class="foodBody">
+						<view style="width: 48%;">
+							<view v-if="index %2 === 0" class="goodsItem" v-for="(item, index) in list" :key="index">
+								<view @click="toMorePage(item)">
+									<img class="cuisineImg" width="100%" height="100%" :src=" baseURL+item.eventImgUrl"
+										mode="widthFix" radius="5"></img>
+									<view class="goodsName">{{item.eventPlace}}</view>
+									<view style="text-align: left;">
+										<view>
+											<uni-row>
+												<uni-col span="4">
+													<view style="font-size: 18rpx;">
+														地点
+													</view>
+												</uni-col>
+												<uni-col span="20">
+													<view style="font-size: 20rpx;">
+														{{item.eventPlaceSite}}
+													</view>
+												</uni-col>
+											</uni-row>
+										</view>
+										<view style="font-size: 20rpx;">
+											开始:{{item.eventStartTime}}
+										</view>
+										<view style="font-size: 20rpx;">
+											结束:{{item.eventEndTime}}
+										</view>
+									</view>
+									<view class="goodsPrice">
+										<u-row>
+											<u-col span="6">
+												<view
+													:style="{'font-size': '12px','color': item.alreadyHave === 0 ? 'rgb(10, 185, 156)':'rgb(0, 0, 0)'}">
+													{{'已报:'+item.alreadyHave}}
+												</view>
+											</u-col>
+											<u-col span="6" textAlign="right">
+												<view style="font-size: 12px;color: rgb(0, 0, 0)">
+													{{'剩余:'+(item.limitNum - item.alreadyHave)}}
+												</view>
+											</u-col>
+										</u-row>
+									</view>
+
+								</view>
+								<view class="gwxx">
+								</view>
+								<view class="gwxx">
+									<!-- <view style="display: flex;flex-wrap: wrap-reverse;padding: 0 10rpx;"> -->
+									<view style="text-align: center;">
+										<view class="yyButton" style="border: 1rpx solid rgb(10, 185, 156);
+													color: rgb(10, 185, 156);font-size: 22rpx; padding: 5rpx 15rpx;
+													 border-radius: 10rpx;" @click="addGoods(item)">
+											预约
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+						<view style="width: 48%;">
+							<view v-if="index %2 !== 0" class="goodsItem" v-for="(item, index) in list" :key="index">
+								<view @click="toMorePage(item)">
+									<img class="cuisineImg" width="100%" height="100%" :src=" baseURL+item.eventImgUrl"
+										mode="widthFix" radius="5"></img>
+									<view class="goodsName">{{item.eventPlace}}</view>
+									<view style="text-align: left;">
+										<view>
+											<uni-row>
+												<uni-col span="4">
+													<view style="font-size: 18rpx;">
+														地点
+													</view>
+												</uni-col>
+												<uni-col span="20">
+													<view style="font-size: 20rpx;">
+														{{item.eventPlaceSite}}
+													</view>
+												</uni-col>
+											</uni-row>
+										</view>
+										<view style="font-size: 18rpx;">
+											开始:{{item.eventStartTime}}
+										</view>
+										<view style="font-size: 18rpx;">
+											结束:{{item.eventEndTime}}
+										</view>
+									</view>
+									<view class="goodsPrice">
+										<u-row>
+											<u-col span="6">
+												<view
+													:style="{'font-size': '12px','color': item.alreadyHave === 0 ? 'rgb(10, 185, 156)':'rgb(0, 0, 0)'}">
+													{{'已报:'+item.alreadyHave}}
+												</view>
+											</u-col>
+											<u-col span="6" textAlign="right">
+												<view style="font-size: 12px;color: rgb(0, 0, 0)">
+													{{'剩余:'+(item.limitNum - item.alreadyHave)}}
+												</view>
+											</u-col>
+										</u-row>
+									</view>
+								</view>
+								<view class="gwxx">
+								</view>
+								<view class="gwxx">
+									<view style="text-align: center;">
+										<view class="yyButton" style="border: 1rpx solid rgb(10, 185, 156);
+													color: rgb(10, 185, 156);font-size: 22rpx; padding: 5rpx 15rpx;
+													 border-radius: 10rpx;" @click="addGoods(item)">
+											预约
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+					<u-loadmore :status="status" />
+				</scroll-view>
+			</view>
+		</view>
+		<view class="content">
+			<!-- @touchstart="handleStart" @touchmove="handleMove" @touchend="handleEnd" -->
+			<view :style="{'transform':'translate3d('+0+'px,'+-180+'px,0)'}" class="touch">
+				<view @click="confirm1">
+					<view style="margin-left: 25rpx;">
+						<uni-row>
+							预约
+						</uni-row>
+						<uni-row>
+							记录
+						</uni-row>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- <wp-tabbar pagePath="/pages/integral/index" :type="type"></wp-tabbar> -->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				containerHeight: 0,
+				stickyOffsetTop: 20,
+				scrollLeftTop: 0,
+				height: 0,
+				option: {
+					page: 1,
+					size: 10,
+					auto: true
+				},
+				noticeText: '',
+				page: 1,
+				oneTypeActive: 0,
+				twoTypeActive: 0,
+				list: [],
+				clubsData: [],
+				total: 0,
+				from: {
+					consumerType: uni.getStorageSync("userInfo").userType,
+					jgid: uni.getStorageSync("orgInfo").organizationCode,
+					organizationCode: uni.getStorageSync("orgInfo").organizationCode
+				},
+				gwcType: 0,
+				scrollTop: 0,
+				gwcNum: 0,
+				xMove: 0,
+				yMove: -80,
+				baseURL: this.$BASE_URL,
+				loading: false,
+				oName: uni.getStorageSync("orgInfo").organizationName,
+				maxNum: 0,
+				timeStop: 0,
+				goodsList: [],
+				gwcGoodsList: [],
+				menuData: {},
+				status: 'loadmore',
+				//上滑列表锁 避免多次上滑导致出错
+				loadingLock: 0,
+				noticeStatus: false
+			}
+		},
+		mounted() {
+			uni.removeStorageSync('shopData')
+			this.getClubs()
+			this.getNoticeStatus()
+			this.getNotice()
+			let that = this
+			uni.getSystemInfo({
+				success: res => {
+					console.log(res)
+					const height = that.height
+					const windowHeight = res.windowHeight // 可使用窗口高度
+					if (windowHeight) {
+						// 限制containerHeight的值,避免传入的height值过大而出现滚动条
+
+						that.containerHeight = windowHeight
+					}
+				}
+			})
+		},
+		onShow() {
+			this.getClubs()
+		},
+		onPullDownRefresh() {},
+		onReachBottom() {},
+		methods: {
+			// 上滑
+			refreshGift() {
+				if (this.total === this.list.length) {
+					this.status = 'nomore'
+					return
+				}
+				if (this.loadingLock === 0) {
+					++this.option.page
+					this.taskList(this.option)
+				}
+			},
+			twoTypeClick(type, index) {
+				this.list = []
+				this.twoTypeActive = index
+				this.option.page = 1
+				this.option.size = 10
+				this.option.associationsInfoId = type.id
+				this.taskList(this.option)
+			},
+			toMorePage(item) {
+				uni.setStorageSync("eventId", item.id)
+				uni.setStorageSync("isUpload", 0)
+				uni.navigateTo({
+					url: "more"
+				})
+			},
+			async getClubs() {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/clubs',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.clubsData = res.data;
+					this.option.page = 1
+					this.option.size = 10
+					this.option.associationsInfoId = this.clubsData[0].id
+					this.taskList(this.option)
+				}
+			},
+			async getNoticeStatus() {
+				this.$getConfigData('club_notice_open').then(res => {
+					if (res.code === 200) {
+						this.noticeStatus = res.msg !== "false"
+						if (this.noticeStatus) {
+							this.containerHeight -= 75
+						} else {
+							this.containerHeight -= 40
+						}
+					}
+				})
+			},
+			async addGoods(data) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/eventOrder?eventId=' + data.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						showCancel: false,
+						content: '预约成功'
+					})
+					this.taskList(this.option)
+				} else {
+					this.$showModal(res.msg)
+				}
+			},
+
+			async getNotice() {
+				this.$getConfigData('club_notice').then(res => {
+					this.noticeText = res.msg
+				})
+			},
+			async taskList(paging) {
+				this.loadingLock = 1
+				this.status = 'loading'
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/events?pageNum=' + paging.page + '&pageSize=' + paging.size +
+						"&associationsInfoId=" + paging.associationsInfoId,
+					method: 'get',
+					isNotErrorMsg: true,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (paging.page === 1) {
+						this.total = res.total
+						this.list = res.rows
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							this.list.push(res.rows[i])
+						}
+					}
+					this.loadingLock = 0
+					if (this.total === this.list.length) {
+						this.status = 'nomore'
+					} else {
+						this.status = 'loadmore'
+					}
+				}
+			},
+			scroll: function(e) {
+				this.old.scrollTop = e.detail.scrollTop
+			},
+			confirm1(e) {
+				uni.setStorageSync('orderType', 1)
+				uni.navigateTo({
+					url: 'appoint'
+				})
+			},
+			// 刷新刷剧
+			refresh() {
+				this.taskList(this.option)
+			},
+			scrolltolower(e) {},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.foodBody {
+		padding-top: 10rpx;
+		padding-left: 10rpx;
+		display: flex;
+		flex-flow: row wrap;
+		justify-content: center;
+		border-radius: 30rpx;
+	}
+
+	.gwxx {
+		padding-top: 10rpx;
+	}
+
+	.scroll-view_H_MY {
+		white-space: nowrap;
+		width: 100%;
+		letter-spacing: 10rpx;
+		// padding: 20rpx;
+		background-color: rgb(255, 255, 255);
+		// background: linear-gradient(to bottom right, rgb(47, 203, 198), rgb(127, 241, 209));
+	}
+
+	.scroll-view-item_H_MY {
+		color: #8c8c8c;
+		height: 35px;
+		width: 33.4%;
+		font-size: 30rpx;
+		display: inline-flex; // item的外层定义成行内元素才可进行滚动 inline-block / inline-flex 均可
+		flex-direction: column;
+		align-items: center;
+		border-right: 1rpx #f3f3f3 solid;
+	}
+
+	.scroll-view-item_H_MY-active {
+		// background-color: rgb(153, 241, 224);
+		border-bottom: 5rpx rgb(96, 182, 158) solid;
+	}
+
+	.giftTypeItem {
+		color: #8c8c8c;
+		padding: 20rpx 10rpx;
+		font-size: 25rpx;
+		letter-spacing: 5rpx;
+		background-color: #f0f0f0;
+		border-bottom: 1rpx #f3f3f3 solid;
+	}
+
+	.giftTypeItem-active {
+		background-color: #ffffff;
+	}
+
+	.isNumNull {
+		color: #FF0000;
+	}
+	
+	.addGwc:active {
+		color: #ffffff;
+	}
+
+	.yyButton:active {
+		background-color: #dedede;
+	}
+	
+	
+	.content {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+	
+	.touch {
+		position: fixed;
+		right: -5rpx;
+		bottom: 60rpx;
+		width: 105rpx;
+		height: 105rpx;
+		padding: 5rpx;
+		background-color: rgb(10, 185, 156);
+		border-top-left-radius: 50%;
+		border-bottom-left-radius: 50%;
+		color: #fff;
+		font-size: 50rpx;
+		/* 去除标签点击事件高亮效果 */
+		-webkit-tap-highlight-color: transparent;
+		/* 使用transform: translate3d 处理性能高 GUP */
+	}
+
+
+	#button_div {
+		position: fixed;
+		bottom: var(--window-bottom);
+	}
+
+	.mybackColor {
+		background-color: #8c8c8c;
+	}
+
+
+
+	.shopHand {
+		font-weight: bold;
+		font-size: 20px;
+		height: 20%;
+		padding: 10% 0 10px 10px;
+		margin-bottom: 5px;
+		//background: linear-gradient(to bottom right, #85c1bf, #f1fef9);
+		//background: rgb(55,186,189);
+		background: #9ED6CF;
+	}
+
+	.cuisineImg {
+		border-radius: 10px;
+		max-height: 600rpx;
+		height: auto;
+		width: auto;
+		padding: 0rpx 5rpx 2rpx;
+	}
+
+	.doFoodConfigView {
+		width: 93%;
+		margin: 0 auto;
+		margin-top: 5px;
+		padding: 2% 5px;
+		background-color: #ffffff;
+		border-radius: 10px;
+		border: 1px solid #d3d3d3;
+	}
+
+
+	.gwcNum {
+		width: 15px;
+		top: 17px;
+		left: 21px;
+		position: relative;
+	}
+
+	/* 商品列表 */
+	.goodsContent {
+		width: 100%;
+		margin: 0 auto;
+		flex-direction: column;
+		background: #f3f3f3;
+		display: flex;
+		justify-content: center;
+	}
+
+	.goodsItem {
+		width: 280rpx;
+		background: #FFFFFF;
+		// border-radius: 10px;
+		padding: 10rpx 0;
+		// margin: 5rpx;
+		// border: 1px solid #ebebeb;
+	}
+
+	.goodsName {
+		font-size: 24rpx;
+		color: #2e2e2e;
+		padding: 10rpx 20rpx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+
+	.goodsPrice {
+		color: #ffac29;
+		font-size: 24rpx;
+		padding: 0 5rpx;
+	}
+
+
+	.addFood {
+		margin-left: 20rpx;
+		color: #8c8c8c;
+	}
+
+	.minus {
+		width: 26px;
+		height: 26px;
+		background-color: #efefef;
+		border-width: 1px;
+		border-color: #c6c6c6;
+		border-top-left-radius: 100px;
+		border-top-right-radius: 100px;
+		border-bottom-left-radius: 100px;
+		border-bottom-right-radius: 100px;
+		@include flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.input {
+		padding: 0;
+	}
+
+	.plus {
+		width: 20px;
+		height: 20px;
+		background-color: #FF0000;
+		border-radius: 50%;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+</style>

+ 181 - 0
pageA/club/more.vue

@@ -0,0 +1,181 @@
+<template>
+	<view>
+		<view style="padding: 8rpx;">
+			<span style="font-size:40rpx; font-weight: bold">
+				活动详情
+			</span>
+			<hs-show label="活动类别" :data="data.eventType" labelSize="6" valueSize="18"></hs-show>
+			<hs-show label="名称" :data="data.eventName" labelSize="4" valueSize="20"></hs-show>
+			<hs-show label="地点" :data="data.eventPlaceSite" labelSize="4" valueSize="20"></hs-show>
+			<hs-show label="社团群组" :data="data.clubName" labelSize="6" valueSize="18"></hs-show>
+			<hs-show label="活动开始时间" :data="data.eventStartTime" labelSize="8" valueSize="16"></hs-show>
+			<hs-show label="活动结束时间" :data="data.eventEndTime" labelSize="8" valueSize="16"></hs-show>
+			<hs-show label="人数限制" :data="data.limitNum"></hs-show>
+		</view>
+		<view style="padding: 8rpx;">
+			<span style="font-size:40rpx; font-weight: bold">
+				场地详情
+			</span>
+			<view v-html="data.placeMore" style="padding: 10rpx;">
+			</view>
+		</view>
+		<view style="padding: 8rpx;">
+			<uni-row>
+				<uni-col :span="6">
+					<span style="font-size:40rpx; font-weight: bold">
+						活动风采
+					</span>
+				</uni-col>
+				<uni-col :span="18">
+				</uni-col>
+			</uni-row>
+			<view style="padding: 30rpx;" v-if="!disabled">
+				<view>
+					<u-upload @afterRead="afterRead" @delete="deletePic" name="1" multiple :maxCount="999"
+						uploadIcon="plus-circle">
+						<image src="../static/img/upload.png" mode="widthFix" style="width: 150px;height: auto;">
+						</image>
+					</u-upload>
+				</view>
+				<view style="margin: 30rpx 0;overflow-y: auto;">
+					<u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="1" multiple
+						:maxCount="999" width="120" height="120" uploadIcon="plus-circle" disabled>
+					</u-upload>
+				</view>
+			</view>
+			<view v-else v-html="imgData" style="padding: 5rpx;">
+
+			</view>
+		</view>
+		<view style="height: 40rpx;">
+		</view>
+	</view>
+</template>
+
+<script>
+	import hsShow from "../components/show.vue"
+	export default {
+		components: {
+			hsShow
+		},
+		data() {
+			return {
+				id: uni.getStorageSync("eventId"),
+				data: {},
+				scrollTop: 0,
+				imgData: '',
+				imgHTML1: '<p><img src="',
+				imgHTML2: '" style="max-width:100%;height:auto;"></p>',
+				fileList: [],
+				disabled: false
+			}
+		},
+		onLoad() {
+			if (uni.getStorageSync("isUpload") === 0) {
+				this.disabled = true
+			} else {
+				this.disabled = false
+			}
+		},
+		onShow() {
+			this.submitMore()
+			this.getMein()
+		},
+		onPageScroll(e) {
+			this.scrollTop = e.scrollTop
+		},
+		methods: {
+			async submitMore() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/more?eventId=' + this.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.data = res.data
+					this.data.placeMore = this.data.placeMore.replace(/<img/g,
+						"<img style='max-width:100%;height:auto;'");
+					// this.data.mien = this.data.mien.replace(/<img/g,
+					// 	"<img style='max-width:100%;height:auto;'");
+				}
+			},
+			getMein() {
+				this.$httpRequest({
+					url: '/app/eventsImg?eventId=' + this.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				}).then(res => {
+					if (res.data.code === 200) {
+						this.fileList = res.data.data
+						this.fileList.forEach(item => {
+							this.imgData += this.imgHTML1 + item.url + this.imgHTML2
+						})
+					}
+				})
+			},
+			// 新增图片
+			async afterRead(event) {
+				// 当设置 mutiple 为 true 时, file 为数组格式,否则为对象格式
+				let lists = [].concat(event.file)
+				let fileListLen
+				if (this.fileList) {
+					fileListLen = this.fileList.length
+				} else {
+					this.fileList = []
+					fileListLen = 0
+				}
+				lists.map((item) => {
+					this.fileList.push({
+						...item,
+						status: 'uploading',
+						message: '上传中'
+					})
+				})
+				for (let i = 0; i < lists.length; i++) {
+					const result = await this.uploadFilePromise(lists[i].url)
+					let item = this.fileList[fileListLen]
+					this.fileList.splice(fileListLen, 1, result)
+					fileListLen++
+				}
+				// uni.setStorageSync("listImg", this.fileList)
+				console.log(this.fileList)
+			},
+			// 删除图片
+			deletePic(event) {
+				this.fileList.splice(event.index, 1)
+			},
+			uploadFilePromise(url) {
+				return new Promise((resolve, reject) => {
+
+					let header = {
+						"Authorization": "Bearer " + uni.getStorageSync('token'),
+						"eventId": this.id
+					}
+					let a = uni.uploadFile({
+						url: this.$BASE_URL + '/app/eventImg/upload', // 仅为示例,非真实的接口地址
+						filePath: url,
+						name: 'file',
+						header: header,
+						success: (res) => {
+							// console.log(JSON.parse(res.data).url);
+							setTimeout(() => {
+								resolve(JSON.parse(res.data))
+							}, 1000)
+						}
+					});
+				})
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	image {
+		padding: 0;
+		margin: 0;
+		/* max-width: 100%;
+		height: auto; */
+	}
+</style>

+ 113 - 0
pageA/club/welfareList.vue

@@ -0,0 +1,113 @@
+<template>
+	<view>
+		<scroll-list ref="list" :option="option" @load="load" @refresh="refresh" @loadSuccess="loadSuccess"
+			@scrolltolower="scrolltolower">
+			<view v-for="(item, index) in list" :key="index">
+				<view
+					style="border: 1rpx solid #cecece;color: #747474;padding: 20rpx ;font-size: 50rpx;">
+					<uni-row>
+						<uni-col :span="20">
+							<view @click="handleTest(item)">
+								{{item.source}}
+							</view>
+						</uni-col>
+						<!-- <uni-col :span="4">
+							<view class="yyButton" style="margin:20rpx 5rpx 0;border: 1rpx solid rgb(10, 185, 156);
+										color: rgb(10, 185, 156);font-size: 22rpx; padding:  5rpx;
+										 border-radius: 10rpx;" @click="back(item)">
+								取消预约
+							</view>
+						</uni-col> -->
+					</uni-row>
+				</view>
+			</view>
+		</scroll-list>
+	</view>
+</template>
+<style lang="scss" scoped>
+	.page-wrap {}
+
+	.yyButton:active {
+		background-color: #dedede;
+	}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 20rpx 0;
+		font-size: 30px;
+		margin: 2rpx;
+		box-shadow: 0px 2px 5px #e5e5e5;
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				page: 1,
+				list: [],
+				scrollList: [],
+				total: 0
+			}
+		},
+		onLoad() {
+
+		},
+		onShow() {
+			this.$refs.list.refresh()
+		},
+		methods: {
+			handleTest(item) {
+				uni.setStorageSync("applyInfo", item)
+				uni.navigateTo({
+					url: "apply"
+				})
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/welfareOrders?pageNum=' + paging.page + '&pageSize=' + paging.size,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (paging.page === 1) {
+						this.scrollList = res.rows
+						this.total = res.total
+						this.$refs.list.loadSuccess({
+							list: res.rows,
+							total: this.total
+						});
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							this.scrollList.push(res.rows[i])
+						}
+						this.$refs.list.loadSuccess({
+							list: this.scrollList,
+							total: this.total
+						});
+					}
+				}
+			},
+			// 刷新刷剧
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {
+				console.log(e)
+			},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>

+ 88 - 0
pageA/components/dictSelect.vue

@@ -0,0 +1,88 @@
+<template>
+	<view class="desc">
+		<uni-row>
+			<uni-col :span="5">
+				<view class="desc" style="font-size: 25rpx;">
+					{{label}}
+				</view>
+			</uni-col>
+			<uni-col :span="19">
+				<view class="pickerView">
+					<picker @change="bindPickerChange" :value="index" :range="data" range-key="dictLabel"
+						:disabled="disabled">
+						<view class="pickerText" v-if="data && data.length>0 && index !== undefined">
+							{{ data[index].dictLabel }}
+						</view>
+						<view class="pickerText" v-else>
+							待 选 择
+						</view>
+					</picker>
+				</view>
+			</uni-col>
+		</uni-row>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'hs-post-select',
+		props: {
+			value: {
+				Type: String,
+				default: null
+			},
+			label: {
+				Type: String,
+				default: '岗位'
+			},
+			dictKey: {
+				Type: String,
+				default: null
+			},
+			disabled: false,
+		},
+		data() {
+			return {
+				data: [],
+				index: undefined
+			}
+		},
+		watch: {
+			value() {
+				for (var i = 0; i < this.data.length; i++) {
+					if (this.data[i].dictValue === this.value) {
+						this.index = i
+					}
+				}
+			}
+		},
+		mounted() {
+			this.data = uni.getStorageSync(this.dictKey)
+		},
+		methods: {
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+				this.$emit('input', this.data[this.index].dictValue)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+</style>

+ 79 - 0
pageA/components/input.vue

@@ -0,0 +1,79 @@
+<template>
+	<view class="desc">
+		<uni-row>
+			<uni-col :span="labelSize">
+				<view class="desc" style="font-size: 25rpx;">
+					{{label}}
+				</view>
+			</uni-col>
+			<uni-col :span="inputSpan">
+				<view>
+					<uni-easyinput v-if="!textarea" primaryColor="#37babd" v-model="value" @input="input"
+						:disabled="disabled">
+					</uni-easyinput>
+					<uni-easyinput v-if="textarea" type="textarea" primaryColor="#37babd" v-model="value" @input="input"
+						:disabled="disabled">
+					</uni-easyinput>
+				</view>
+			</uni-col>
+		</uni-row>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'hs-input',
+		props: {
+			value: {
+				Type: String,
+				default: null
+			},
+			label: {
+				Type: String,
+				default: ''
+			},
+			labelSize: {
+				Type: Number,
+				default: 5
+			},
+			inputSpan: {
+				Type: Number,
+				default: 19
+			},
+			disabled: false,
+			textarea: false
+		},
+		data() {
+			return {
+
+			}
+		},
+		mounted() {
+
+		},
+		methods: {
+			input: function(e) {
+				this.$emit('input', this.value)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+</style>

+ 123 - 0
pageA/components/show.vue

@@ -0,0 +1,123 @@
+<template>
+	<view>
+		<view v-if="mode === 'text'">
+			<uni-row>
+				<uni-col :span="labelSize">
+					<view class="desc">
+						{{label}}
+					</view>
+				</uni-col>
+				<uni-col :span="valueSize">
+					<view class="desc" style="text-align: right;" v-if="data !== '' && data !== null && data !== undefined">
+						{{data}}
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<view v-if="mode === 'time'">
+			<uni-row>
+				<uni-col :span="labelSize">
+					<view class="desc">
+						{{label}}
+					</view>
+				</uni-col>
+				<uni-col :span="valueSize">
+					<view class="desc" v-if="data !== '' && data !== null && data !== undefined">
+						{{$dateResult(data,'date')}}
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<view v-if="mode === 'dict'">
+			<uni-row>
+				<uni-col :span="labelSize">
+					<view class="desc">
+						{{label}}
+					</view>
+				</uni-col>
+				<uni-col :span="valueSize">
+					<view class="desc">
+						{{dictLabel}}
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<view v-if="mode === 'dept'">
+			<uni-row>
+				<uni-col :span="labelSize">
+					<view class="desc">
+						{{label}}
+					</view>
+				</uni-col>
+				<uni-col :span="valueSize">
+					<view class="desc">
+						{{$dictTranslation(data,'deptData','dept')}}
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<view v-if="mode === 'post'">
+			<uni-row>
+				<uni-col :span="labelSize">
+					<view class="desc">
+						{{label}}
+					</view>
+				</uni-col>
+				<uni-col :span="valueSize">
+					<view class="desc">
+						{{$dictTranslation(data,'postsData','post')}}
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<u-gap height="10" bgColor="#f7f7f7"></u-gap>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			label: {
+				type: String,
+				default: ''
+			},
+			labelSize: {
+				type: Number,
+				default: 6
+			},
+			valueSize: {
+				type: Number,
+				default: 18
+			},
+			data: {
+				type: String,
+				default: ''
+			},
+			mode: {
+				type: String,
+				default: 'text'
+			},
+			dictKey: {
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				dictLabel: ''
+			}
+		},
+		mounted() {
+			if (this.mode === 'dict') {
+				this.dictLabel = this.$dictTranslation(this.data, this.dictKey, 'dict')
+			}
+		}
+	}
+</script>
+
+<style>
+	.desc {
+		padding: 10rpx 30rpx;
+		color: #818181;
+	}
+</style>

+ 144 - 0
pageA/integral/details.vue

@@ -0,0 +1,144 @@
+<template>
+	<view>
+		<view class="view">
+			<!-- 			<view v-if="type === 0" class="listItemStyle">
+				<u-text text="查看订单进度" color="rgb(0, 170, 255)" size="20"></u-text>
+			</view> -->
+			<u-list @scrolltolower="scrolltolower">
+				<view v-if="dataList.length === 0" style="padding: 0 50px;">
+					<image style="margin: 0 auto; width: 100%;" src="../../../static/img/page/empty_view.png"></image>
+				</view>
+				<view class="listItemStyle">
+					<view style="padding: 10rpx;color: #848484;font-size: 30rpx;">
+						联系方式
+					</view>
+					<view style="padding: 5rpx 30rpx;color: #848484;">
+						<view v-if="order.userName && order.phone">
+							{{order.userName +" "+ order.phone}}
+						</view>
+					</view>
+					<view style="padding: 10rpx;color: #848484;font-size: 30rpx;">
+						领取地点
+					</view>
+					<view style="padding: 5rpx 30rpx;color: #848484;">
+						<view v-if="order.placeNumber">
+							{{order.placeNumber}}
+						</view>
+					</view>
+				</view>
+				<u-list-item v-for="(item, index) in dataList" :key="index">
+					<view v-if="item.amount !== 0 && item.amount" class="listItemStyle">
+						<u-row>
+							<u-col span="3">
+								<u--image :showLoading="true" shape="circle" :src="baseURL+item.pictrue" width="70px"
+									height="70px" style="margin: 10px;"></u--image>
+							</u-col>
+							<u-col span="7" style="margin-left: 5px;">
+								<view>
+									<u--text :text="item.name" size="20"></u--text>
+								</view>
+								<view v-if="item.eventTime"
+									style="text-align: left;color: #ffaf25;font-size: 22rpx;margin-top: 10rpx;">
+									{{"预计 "+item.eventTime+" 可领取"}}
+								</view>
+								<view style="margin-top: 10px;">
+									<u-icon name="integral" :label="item.price"></u-icon>
+								</view>
+							</u-col>
+							<u-col span="2">
+								<view>
+									<u--text :text="'x'+item.amount" size="25"></u--text>
+								</view>
+							</u-col>
+						</u-row>
+					</view>
+				</u-list-item>
+			</u-list>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				baseURL: this.$BASE_URL,
+				priceSum: 0.0,
+				dateShow: false,
+				data: {
+					organizationName: "",
+				},
+				order: uni.getStorageSync('order'),
+				from: {
+					orderNumber: '',
+					organizationCode: ''
+				},
+				dataList: [],
+				dataListNow: [],
+				type: uni.getStorageSync("tabType")
+			}
+		},
+		onLoad() {
+			this.submitOrder()
+		},
+		methods: {
+			toJDPage() {
+				this.$goto('../../../pageA/card/orderProcess')
+			},
+			async submitOrder() {
+				this.from.orderNumber = this.order.orderNumber
+				this.from.organizationCode = this.order.jgid
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getGiftOrderDetail',
+					method: 'post',
+					data: this.from,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataList = res.rows
+				}
+			},
+			loadmore(data) {
+				for (var i = 0; i < data.length; i++) {
+					this.dataList.push(data[i])
+				}
+			},
+			result(time, mode) {
+				const timeFormat = uni.$u.timeFormat
+				switch (mode) {
+					case 'datetime':
+						return timeFormat(time, 'yyyy-mm-dd hh:MM')
+					case 'date':
+						return timeFormat(time, 'yyyy-mm-dd')
+					case 'year-month':
+						return timeFormat(time, 'yyyy-mm')
+					case 'time':
+						return time
+					default:
+						return ''
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	.view {
+		background-color: #ebebeb;
+		padding-top: 10px;
+	}
+
+	.listTermDate {
+		padding: 10px 0;
+	}
+
+	.listItemStyle {
+		margin: 5px 12px;
+		padding: 10px;
+		border-radius: 15px;
+		background-color: #fafafa;
+	}
+</style>

+ 377 - 0
pageA/integral/expenseCalendar.vue

@@ -0,0 +1,377 @@
+<template>
+	<view>
+		<view>
+			<view>
+				<u-list @scrolltolower="scrolltolower">
+					<!-- <view class="listTermDate">
+						 <u-cell-group>
+								<u-cell :title="from.date" arrow-direction="down" @click="dateShow = true" isLink></u-cell>
+							</u-cell-group> 
+						<view>
+							<u-datetime-picker :show="dateShow" closeOnClickOverlay v-model="from.date" mode="date"
+								@cancel="dateShow = false" @confirm="submitDate" :formatter="formatter"
+								@change="change">
+							</u-datetime-picker>
+						</view>
+					</view> -->
+					<view class="hand">
+						<u-row>
+							<u-col span="8">
+								<view class="orgTop">
+									<uni-row>
+										<uni-col :span="10">
+											<u--text text="所属机构" size="22" bold color="#619f8a"></u--text>
+										</uni-col>
+										<uni-col :span="24">
+											<u--text :text="from.organizationName" size="22" bold color="#757575">
+											</u--text>
+										</uni-col>
+									</uni-row>
+								</view>
+							</u-col>
+							<!--<u-col span="4">
+										<view>
+											<u-button class="sxButton" size="normal" loadingMode="circle" color="#65c1aa">统计查看
+											</u-button>
+										</view>
+									</u-col> -->
+						</u-row>
+					</view>
+					<view v-if="indexList.length === 0" style="padding: 0 50px;">
+						<image style="margin: 0 auto; width: 100%;" src="../../../static/img/page/empty_view.png">
+						</image>
+					</view>
+					<view v-for="(item, index) in indexList" :key="index">
+						<view :data-index="index" class="order-item" @touchstart="drawStart" @touchmove="drawMove"
+							@touchend="drawEnd" :style="'right:'+item.right+'px'">
+							<view class="listItemStyle">
+								<u-row>
+									<u-col span="3">
+										<view class="orderFoodStyle orderFoodType0">
+											{{item.statusText}}
+										</view>
+									</u-col>
+									<u-col span="5" class="orderFoodStyle orderFoodType">
+										<view style="font-size: 24rpx;">
+											订单:{{item.orderNumber}}
+										</view>
+									</u-col>
+									<u-col span="4" textAlign="right">
+										<view class="moneyText">
+											{{"- "+item.orderTotal+""}}
+										</view>
+									</u-col>
+								</u-row>
+								<u-row>
+									<u-col span="7" class="orderTimeText">{{item.paytime}}</u-col>
+									<!-- <u-col span="2" class="orderTimeText">
+										<view style="color: #1787ff;font-size: 34rpx;" @click="toJDPage(item)">
+											进度
+										</view>
+									</u-col> -->
+									<u-col span="3" class="orderTimeText">
+										<view style="color: #1787ff;font-size: 34rpx;" @click="getDetails(item)">
+											详情
+										</view>
+									</u-col>
+									<u-col span="2" class="orderTimeText">
+										<view v-if="item.isNews === '1'"
+											style="font-size: 22rpx;color: rgb(55,186,189);" @click="toJDPage(item)">
+											新消息
+										</view>
+									</u-col>
+								</u-row>
+							</view>
+							<view class="remove" @click="delData(item)">退 单
+							</view>
+						</view>
+					</view>
+				</u-list>
+				<u-modal :show="modalContent1.show" :title="modalContent1.title" :showCancelButton="true"
+					confirmColor="#53a591" @confirm="toBack()" @cancel="modalContent1.show = false">
+					{{modalContent1.content}}
+				</u-modal>
+				<u-modal :show="modalContent2.show" :title="modalContent2.title" :content='modalContent2.content'
+					confirmColor="#53a591" @confirm="modalContent2.show = false">
+				</u-modal>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				type: uni.getStorageSync("tabType"),
+				dateShow: false,
+				data: {},
+				from: {
+					organizationName: ''
+				},
+				indexList: [],
+				modalContent1: {
+					show: false,
+					title: '提示',
+					content: '确认退单吗?'
+				},
+				modalContent2: {
+					show: false,
+					title: '提示',
+					content: ''
+				},
+				//列表数据(
+				indexList: [],
+				//左滑默认宽度
+				startX: 0,
+				startY: 0,
+				delBtnWidth: 90,
+				pageNum: 1,
+				pageSize: 10,
+				total: 1
+			}
+		},
+		onLoad() {
+
+		},
+		onShow() {
+			this.getExpenseCalendarList()
+		},
+		onHide() {
+			this.getExpenseCalendarList()
+		},
+		onUnload: function() {
+			console.log("-----onUnload------>");
+		},
+		methods: {
+			toJDPage(item) {
+				uni.setStorageSync('order', item)
+				this.$goto('../orderProcess')
+			},
+			getDetails(item) {
+				uni.setStorageSync('order', item)
+				this.$goto('details')
+			},
+			async getExpenseCalendarList() {
+				if (this.indexList.length >= this.total) {
+					return;
+				}
+				const orgInfo = uni.getStorageSync("orgInfo")
+				this.from.organizationName = orgInfo.organizationName
+				this.from.userName = uni.getStorageSync('userInfo').userName
+				this.from.organizationCode = orgInfo.organizationCode
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getOrder2?' + "pageNum=" + this.pageNum + "&" + "pageSize=" + this.pageSize,
+					method: 'post',
+					data: this.from,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.total = res.total
+					this.loadmore(res.rows)
+				}
+			},
+			async toBack(item) {
+				this.modalContent1.show = false;
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/giftBack?orderId=' + uni.getStorageSync("orderNumber"),
+					method: 'get',
+					data: this.from,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.$showModal('退单成功')
+					uni.redirectTo({
+						url: 'expenseCalendar'
+					});
+				} else {
+					this.modalContent2.content = res.msg
+					this.modalContent2.show = true
+				}
+			},
+			change(e) {
+				//this.changeDate = this.result(e.value, e.mode)
+			},
+			scrolltolower() {
+				this.pageNum++;
+				this.getExpenseCalendarList()
+			},
+			loadmore(data) {
+				if (data.length === 0) {
+					return;
+				}
+				for (var i = 0; i < data.length; i++) {
+					this.indexList.push(data[i])
+				}
+			},
+			formatter(type, value) {
+				if (type === 'year') {
+					return `${value}年`
+				}
+				if (type === 'month') {
+					return `${value}月`
+				}
+				if (type === 'day') {
+					return `${value}日`
+				}
+				return value
+			},
+			//开始触摸滑动
+			drawStart(e) {
+				var touch = e.touches[0];
+				this.startX = touch.clientX;
+				this.startY = touch.clientY;
+			},
+			//触摸滑动
+			drawMove(e) {
+				for (var index in this.indexList) {
+					this.$set(this.indexList[index], 'right', 0);
+				}
+				var item = this.indexList[e.currentTarget.dataset.index];
+				if (item.zfbz === 2) {
+					return;
+				}
+				if (item.zfbz === 3) {
+					return;
+				}
+				var touch = e.touches[0];
+				//防止快速滑动影响动画效果
+				//上滑
+				if (e.touches[0].clientY - this.startY > 100) {
+					return;
+				}
+				//下滑
+				if (this.startY - e.touches[0].clientY > 100) {
+					return;
+				}
+				var disX = this.startX - touch.clientX;
+				if (disX >= 0) {
+					if (disX > this.delBtnWidth) {
+						disX = this.delBtnWidth;
+					}
+					this.$set(this.indexList[e.currentTarget.dataset.index], 'right', disX);
+				} else {
+					this.$set(this.indexList[e.currentTarget.dataset.index], 'right', 0);
+				}
+			},
+			//触摸滑动结束
+			drawEnd(e) {
+				var item = this.indexList[e.currentTarget.dataset.index];
+				//如果滑动距离超过65默认展开按钮
+				if (item.right >= 65) {
+					item.right = this.delBtnWidth;
+					return;
+				}
+				//赋值动画初始距离
+				var dhWidth = item.right;
+				//每隔 3 毫秒 减少 2px动画距离 实现动画效果
+				var dhStop = setInterval(() => {
+					//console.log(item.right)
+					dhWidth -= 2;
+					//当动画距离已经为0或小于零 默认列表距离为0
+					if (dhWidth <= 0) {
+						item.right = 0;
+						//清除本次定时器
+						clearInterval(dhStop)
+						return;
+					}
+					item.right = dhWidth;
+				}, 3);
+			},
+			//删除方法
+			delData(item) {
+				this.modalContent1.show = true;
+				uni.setStorageSync("orderNumber", item.orderId)
+				//关闭侧边滑动
+				item.right = 0
+			}
+		}
+	}
+</script>
+
+<style>
+	.hand {
+		margin-top: 2px;
+		padding: 20rpx;
+		border-radius: 10px 10px 0 0;
+		background: linear-gradient(to bottom right, #85c1bf, #f1fef9);
+	}
+
+	.orgTop {
+		margin-bottom: 5px;
+	}
+
+	.sxButton {
+		width: 100px;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+	}
+
+	.order-item {
+		position: relative;
+	}
+
+	.remove {
+		width: 100px;
+		height: 100%;
+		background-color: #57aa8e;
+		color: white;
+		position: absolute;
+		top: 0;
+		right: -100px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-size: 18px;
+	}
+
+	.listTermDate {
+		padding: 10px 0;
+	}
+
+	.listItemStyle {
+		background-color: #ffffff;
+		padding: 15px;
+		border: 1px solid #d8d8d8;
+		margin: 10rpx;
+	}
+
+	.orderFoodStyle {
+		font-size: 20px;
+	}
+
+	.orderFoodType {
+		color: #000000;
+	}
+
+	.orderFoodType0 {
+		color: #1787ff;
+	}
+
+	.orderFoodType1 {
+		color: #da0000;
+	}
+
+	.orderFoodType2 {
+		color: #00af00;
+	}
+
+	.moneyText {
+		font-size: 26rpx;
+		color: #b30000;
+	}
+
+	.orderTimeText {
+		position: relative;
+		top: 5px;
+		color: #bebebe;
+		font-size: 24rpx;
+	}
+</style>

+ 768 - 0
pageA/integral/index.vue

@@ -0,0 +1,768 @@
+<template>
+	<view>
+		<view v-if="noticeStatus">
+			<u-notice-bar :text="noticeText"></u-notice-bar>
+		</view>
+		<u-sticky>
+			<view>
+				<scroll-view class="scroll-view_H_MY" :scroll-x="true" @scroll="scroll">
+					<view :class="index=== oneTypeActive ? 'scroll-view-item_H_MY-active':''"
+						@click="oneTypeClick(item,index)" v-for="(item,index) in giftTypeList"
+						class="scroll-view-item_H_MY">
+						{{item.giftTypeName}}
+					</view>
+				</scroll-view>
+			</view>
+		</u-sticky>
+		<view style="display: flex;flex-flow: row wrap;">
+			<view style="width: 20%; text-align: center;background-color: #f0f0f0;">
+				<scroll-view scroll-y scroll-with-animation :scrollTop="scrollLeftTop"
+					:style="[{height: containerHeight + 'px'}]">
+					<view :class="index === twoTypeActive ? 'giftTypeItem-active':''" @click="twoTypeClick(item,index)"
+						v-for="(item,index) in giftTypeList[oneTypeActive].children" class="giftTypeItem">
+						{{item.giftTypeName}}
+					</view>
+				</scroll-view>
+			</view>
+			<view style="width: 80%;background-color: #ffffff;text-align:center;">
+				<scroll-view scroll-y scroll-with-animation :scrollTop="scrollLeftTop" :lower-threshold="110"
+					@scrolltolower="refreshGift" :style="[{height: containerHeight + 'px'}]">
+					<view class="foodBody">
+						<view style="width: 48%;">
+							<view v-if="index %2 === 0" class="goodsItem" v-for="(item, index) in list" :key="index">
+								<img @click="toMorePage(item)" class="cuisineImg" width="100%" height="100%"
+									:src=" baseURL+item.giftPictrue" mode="widthFix" radius="5"></img>
+								<view @click="toMorePage(item)" class="goodsName">{{item.giftName}}</view>
+								<view class="goodsPrice" @click="toMorePage(item)">
+									<u-row>
+										<u-col span="6">
+											<u-icon name="integral" :label="item.giftPrice"
+												labelColor="rgb(10, 185, 156)" color="rgb(10, 185, 156)"
+												labelSize="12.5"></u-icon>
+										</u-col>
+										<u-col span="6" textAlign="right">
+											<view
+												:style="{'font-size': '12px','color': item.amount === 0 ? '#ffac29':'rgb(0, 0, 0)'}">
+												{{'库存:'+item.amount}}
+											</view>
+										</u-col>
+									</u-row>
+								</view>
+								<view class="gwxx">
+								</view>
+								<view class="gwxx">
+									<view style="display: flex;flex-wrap: wrap-reverse;padding: 0 20rpx;">
+										<view style="border: 1rpx solid rgb(10, 185, 156);
+													color: rgb(10, 185, 156);font-size: 22rpx; padding: 5rpx 15rpx;
+													 border-radius: 10rpx;" @click="addGoods(item)">
+											加入购物车
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+						<view style="width: 48%;">
+							<view v-if="index %2 !== 0" class="goodsItem" v-for="(item, index) in list" :key="index">
+								<img @click="toMorePage(item)" class="cuisineImg" width="100%" height="100%"
+									:src=" baseURL+item.giftPictrue" mode="widthFix" radius="5"></img>
+								<view @click="toMorePage(item)" class="goodsName">{{item.giftName}}</view>
+								<view class="goodsPrice" @click="toMorePage(item)">
+									<u-row>
+										<u-col span="6">
+											<u-icon name="integral" :label="item.giftPrice"
+												labelColor="rgb(10, 185, 156)" color="rgb(10, 185, 156)"
+												labelSize="12.5"></u-icon>
+										</u-col>
+										<u-col span="6" textAlign="right">
+											<view
+												:style="{'font-size': '12px','color': item.amount === 0 ? '#ffac29':'rgb(0, 0, 0)'}">
+												{{'库存:'+item.amount}}
+											</view>
+										</u-col>
+									</u-row>
+								</view>
+								<view class="gwxx">
+									<view style="display: flex;flex-wrap: wrap-reverse;padding: 0 20rpx;">
+										<view style="border: 1rpx solid rgb(10, 185, 156);
+													color: rgb(10, 185, 156);font-size: 22rpx; padding: 5rpx 15rpx;
+													 border-radius: 10rpx;" @click="addGoods(item)">
+											加入购物车
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+					<u-loadmore :status="status" />
+				</scroll-view>
+			</view>
+		</view>
+		<view class="content">
+			<!-- @touchstart="handleStart" @touchmove="handleMove" @touchend="handleEnd" -->
+			<view :style="{'transform':'translate3d('+0+'px,'+-80+'px,0)'}" class="touch">
+				<view @click="confirm1">
+					<view :style="gwcNum === 0 ? 'background-color:#c5c5c5;':'background-color:#e93c45;'" style="position: absolute;top:-30rpx; right: 0;
+					color: #ffffff;font-size: 30rpx;border-radius: 50%;width: 55rpx;height: 55rpx;">
+						{{gwcNum}}
+					</view>
+					<u-icon name="shopping-cart" size="50" class="gwc" color="#ffffff">
+					</u-icon>
+				</view>
+			</view>
+		</view>
+		<!-- <wp-tabbar pagePath="/pages/integral/index" :type="type"></wp-tabbar> -->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				containerHeight: 0,
+				stickyOffsetTop: 20,
+				scrollLeftTop: 0,
+				height: 0,
+				option: {
+					page: 1,
+					size: 10,
+					auto: true
+				},
+				noticeText: '',
+				page: 1,
+				oneTypeActive: 0,
+				twoTypeActive: 0,
+				list: [],
+				giftTypeList: [],
+				total: 0,
+				from: {
+					consumerType: uni.getStorageSync("userInfo").userType,
+					jgid: uni.getStorageSync("orgInfo").organizationCode,
+					organizationCode: uni.getStorageSync("orgInfo").organizationCode
+				},
+				gwcType: 0,
+				scrollTop: 0,
+				gwcNum: 0,
+				xMove: 0,
+				yMove: -80,
+				baseURL: this.$BASE_URL,
+				loading: false,
+				oName: uni.getStorageSync("orgInfo").organizationName,
+				maxNum: 0,
+				timeStop: 0,
+				goodsList: [],
+				gwcGoodsList: [],
+				menuData: {},
+				status: 'loadmore',
+				//兑换物品下拉列表锁 避免多次下拉导致出错
+				loadingLock: 0,
+				noticeStatus: false
+			}
+		},
+		mounted() {
+			uni.removeStorageSync('shopData')
+			// this.load(this.option)
+			this.getNoticeStatus()
+			this.getSCN()
+			this.giftType()
+			this.getNotice()
+			let that = this
+			uni.getSystemInfo({
+				success: res => {
+					console.log(res)
+					const height = that.height
+					const windowHeight = res.windowHeight // 可使用窗口高度
+					if (windowHeight) {
+						// 限制containerHeight的值,避免传入的height值过大而出现滚动条
+						// 	const remainHeight = windowHeight - that.stickyOffsetTop // 因设置了offsetTop后剩余的height值
+						// 	if (height > remainHeight) {
+						// 		this.containerHeight = remainHeight
+						// 	} else {
+						// 		this.containerHeight = height
+						// 	}
+						// } else {
+						that.containerHeight = windowHeight
+					}
+				}
+			})
+		},
+		onShow() {
+
+		},
+		onPullDownRefresh() {},
+		onReachBottom() {},
+		methods: {
+			refreshGift() {
+				if (this.total === this.list.length) {
+					this.status = 'nomore'
+					return
+				}
+				if (this.loadingLock === 0) {
+					++this.option.page
+					this.taskList(this.option)
+				}
+			},
+			oneTypeClick(type, index) {
+				this.list = []
+				this.oneTypeActive = index
+				this.gwcType = index
+				uni.removeStorageSync('shopData')
+				this.gwcGoodsList = []
+				if (this.gwcType === 0) {
+					this.getSCN()
+				} else if (this.gwcType === 1) {
+					this.gwcNum = 0
+				}
+				this.twoTypeActive = 0
+				this.option.page = 1
+				this.option.size = 10
+				if (type.giftTypeNo) {
+					this.option.giftType = 2
+				} else {
+					this.option.giftType = 1
+				}
+				this.option.giftTypeCode = type.children[0].id
+				this.taskList(this.option)
+			},
+			twoTypeClick(type, index) {
+				this.list = []
+				this.twoTypeActive = index
+				this.option.page = 1
+				this.option.size = 10
+				if (type.giftTypeNo) {
+					this.option.giftType = 2
+				} else {
+					this.option.giftType = 1
+				}
+				this.option.giftTypeCode = type.id
+				this.taskList(this.option)
+			},
+			myIsNaN(value) {
+				return typeof value === 'number' && !isNaN(value)
+			},
+			changeNum(value) {
+				this.setGwcNum()
+			},
+			toMorePage(item) {
+				uni.setStorageSync("giftContent", item.giftContent)
+				uni.navigateTo({
+					url: "../../pages/integral/more"
+				})
+			},
+			async giftType() {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/giftType',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.giftTypeList = res.data;
+					this.option.page = 1
+					this.option.size = 10
+					this.option.giftType = 1
+					this.option.giftTypeCode = res.data[0].children[0].id
+					this.taskList(this.option)
+				}
+			},
+			async getNoticeStatus() {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getNoticeStatus',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.noticeStatus = res.msg !== "false"
+					if (this.noticeStatus) {
+						this.containerHeight -= 75
+					} else {
+						this.containerHeight -= 40
+					}
+				}
+			},
+			async addGoods(data) {
+				let form = {
+					amount: data.amount,
+					giftId: data.giftId,
+					giftName: data.giftName,
+					giftNumber: data.giftNumber,
+					giftPictrue: data.giftPictrue,
+					giftPrice: data.giftPrice,
+					num: data.num,
+					plusOrMinus: 0
+				}
+				if (this.gwcType === 0) {
+					form.eventId = data.eventId
+					form.eventName = data.eventName
+					form.eventTime = data.eventTime
+					// 发送请求
+					const {
+						data: res
+					} = await this.$httpRequest({
+						url: '/app/addShopCar',
+						method: 'post',
+						data: form,
+						urlType: this.$getUrlType()
+					});
+					if (res.code === 200) {
+						uni.showToast({
+							duration: 1500,
+							title: '添加成功'
+						})
+						this.getSCN()
+					} else {
+						this.$showModal(res.msg)
+					}
+				} else
+				if (this.gwcType >= 1) {
+					let count = 0
+					let gift = form
+					if (gift.num < gift.amount) {
+						if (this.gwcGoodsList.length > 0) {
+							for (let i = 0; i < this.gwcGoodsList.length; i++) {
+								if (this.gwcGoodsList[i].giftId === data.giftId) {
+									this.gwcGoodsList[i].num += 1
+									count = 1
+									break;
+								}
+							}
+						}
+						if (count === 0) {
+							gift.num += 1
+							this.gwcGoodsList.push(gift)
+						}
+						this.gwcNum = this.gwcGoodsList.length
+						uni.setStorageSync('shopData', this.gwcGoodsList)
+						uni.showToast({
+							duration: 1500,
+							title: '添加成功'
+						})
+					} else {
+						this.$showModal("库存不足")
+					}
+				}
+			},
+
+			async getNotice() {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getNotice',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.noticeText = res.msg
+				}
+			},
+			async getSCN() {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getSCN',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.gwcNum = res.data
+				}
+			},
+			async taskList(paging) {
+				this.loadingLock = 1
+				this.status = 'loading'
+				this.from.giftType = paging.giftType
+				this.from.giftTypeCode = paging.giftTypeCode
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getGift?pageNum=' + paging.page + '&pageSize=' + paging.size,
+					method: 'post',
+					data: this.from,
+					isNotErrorMsg: true,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (paging.page === 1) {
+						this.total = res.total
+						this.list = res.rows
+						this.list.forEach(item => {
+							item.num = 0
+						})
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							res.rows[i].num = 0
+							this.list.push(res.rows[i])
+						}
+					}
+					this.loadingLock = 0
+					if (this.total === this.list.length) {
+						this.status = 'nomore'
+					} else {
+						this.status = 'loadmore'
+					}
+				}
+			},
+			setGwcNum() {
+				console.log("setGwcNum")
+				let count = 0
+				const goodsListInfo = this.list;
+				for (var i = 0; i < goodsListInfo.length; i++) {
+					if (goodsListInfo[i].num) {
+						let num = parseInt(goodsListInfo[i].num)
+						let amount = parseInt(goodsListInfo[i].amount)
+						if (amount < num) {
+							goodsListInfo[i].num = amount
+							num = amount
+						}
+						count += num
+					}
+				}
+				this.gwcNum = count
+			},
+			toShopListPage() {
+				if (0 === this.gwcNum) {
+					this.showToast({
+						duration: 1500,
+						message: "请选择商品"
+					});
+					return;
+				}
+				this.show1 = true;
+			},
+			addToCart(type, gift) {
+				if (type === 0 && gift.num === 0) {
+					return
+				}
+				if (gift.amount === 0) {
+					this.showToast({
+						duration: 500,
+						message: "库存不足"
+					});
+					return
+				}
+				if (type === 1) {
+					if (gift.num) {
+						if (gift.amount <= gift.num) {
+							this.showToast({
+								duration: 500,
+								message: "库存已达最大数量"
+							});
+							return
+						}
+						gift.num += 1
+					} else {
+						gift.num = 1
+					}
+				} else {
+					gift.num -= 1
+				}
+				let that = this
+				setTimeout(() => {
+					that.setGwcNum()
+				}, 100)
+			},
+			scroll: function(e) {
+				this.old.scrollTop = e.detail.scrollTop
+			},
+			confirm1(e) {
+				if (this.gwcType === 0) {
+					uni.setStorageSync('orderType', 1)
+					uni.navigateTo({
+						url: '../../pageA/integral/shopcar'
+					})
+				} else
+				if (this.gwcType === 1) {
+					uni.setStorageSync('orderType', 2)
+					uni.navigateTo({
+						url: '../../pageA/integral/shopcarTemporary'
+					})
+				}
+			},
+			showToast(params) {
+				this.$refs.uToast.show({
+					...params,
+					complete() {}
+				})
+			},
+			handleStart(ev) {
+				// console.log('start',ev);
+				// 记录一开始手指按下的坐标
+				var touch = ev.changedTouches[0];
+				startPoint.x = touch.pageX;
+				startPoint.y = touch.pageY;
+			},
+			handleMove(ev) {
+				// console.log('move',ev);
+				// 防止页面高度很大,出现滚动条,不能移动-默认拖动滚动条事件
+				ev.preventDefault();
+
+				isTouchMove = true;
+
+				var touch = ev.changedTouches[0];
+				var diffPonit = {}; // 存放差值
+				var movePonit = {
+					// 记录移动的距离
+					x: 0,
+					y: 0
+				};
+				diffPonit.x = touch.pageX - startPoint.x;
+				diffPonit.y = touch.pageY - startPoint.y;
+				// 移动的距离 = 差值 + 当前坐标点
+				movePonit.x = diffPonit.x + curPoint.x;
+				movePonit.y = diffPonit.y + curPoint.y;
+				this.move(movePonit.x, movePonit.y);
+			},
+			handleEnd(ev) {
+				// console.log('end', ev);
+				if (!isTouchMove) return;
+				//  更新坐标原点
+				var touch = ev.changedTouches[0];
+				curPoint.x += touch.pageX - startPoint.x;
+				curPoint.y += touch.pageY - startPoint.y;
+				// 重置
+				isTouchMove = false;
+			},
+			move(x, y) {
+				x = x || 0; // 没有传就是0
+				y = y || 0;
+				this.xMove = x;
+				this.yMove = y;
+				// translate3d	(tx,ty,tz)	在X轴偏移tx,在Y轴偏移ty,在Z轴偏移tz,单位px
+			},
+			// 刷新刷剧
+			refresh() {
+				this.option.page = 1
+				this.option.size = 10
+				this.option.giftType = 1
+				this.taskList(this.option)
+			},
+			scrolltolower(e) {},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	.foodBody {
+		padding-top: 10rpx;
+		padding-left: 10rpx;
+		display: flex;
+		flex-flow: row wrap;
+		justify-content: center;
+		border-radius: 30rpx;
+	}
+	
+	.gwxx {
+		padding-top: 10rpx;
+	}
+	
+	.scroll-view_H_MY {
+		white-space: nowrap;
+		width: 100%;
+		letter-spacing: 10rpx;
+		// padding: 20rpx;
+		background-color: rgb(255, 255, 255);
+		// background: linear-gradient(to bottom right, rgb(47, 203, 198), rgb(127, 241, 209));
+	}
+	
+	.scroll-view-item_H_MY {
+		color: #8c8c8c;
+		height: 35px;
+		width: 33.4%;
+		font-size: 30rpx;
+		display: inline-flex; // item的外层定义成行内元素才可进行滚动 inline-block / inline-flex 均可
+		flex-direction: column;
+		align-items: center;
+		border-right: 1rpx #f3f3f3 solid;
+	}
+	
+	.scroll-view-item_H_MY-active {
+		// background-color: rgb(153, 241, 224);
+		border-bottom: 5rpx rgb(96, 182, 158) solid;
+	}
+	
+	.giftTypeItem {
+		color: #8c8c8c;
+		padding: 20rpx 10rpx;
+		font-size: 25rpx;
+		letter-spacing: 5rpx;
+		background-color: #f0f0f0;
+		border-bottom: 1rpx #f3f3f3 solid;
+	}
+	
+	.giftTypeItem-active {
+		background-color: #ffffff;
+	}
+	
+	.isNumNull {
+		color: #FF0000;
+	}
+	
+	.content {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+	
+	.addGwc:active {
+		color: #ffffff;
+	}
+	
+	.touch {
+		position: fixed;
+		right: 40rpx;
+		bottom: 60rpx;
+		width: 95rpx;
+		height: 95rpx;
+		/* 知识点
+		line-height是行高,针对的对象是文字,height针对的是容器,
+		也就是高度,当height和line-height值相同时会居中,
+		当line-height值小于height时文字向上移动,反之向下移动。
+		 */
+		line-height: 95rpx;
+		/* 文字垂直居中 */
+		text-align: center;
+		/* 水平居中 */
+		background-color: rgba(0, 0, 0, 0.6);
+		border-radius: 50%;
+		color: #fff;
+		font-size: 60rpx;
+		/* 去除标签点击事件高亮效果 */
+		-webkit-tap-highlight-color: transparent;
+		/* 使用transform: translate3d 处理性能高 GUP */
+	}
+	
+	
+	#button_div {
+		position: fixed;
+		bottom: var(--window-bottom);
+	}
+	
+	.mybackColor {
+		background-color: #8c8c8c;
+	}
+	
+	
+	
+	.shopHand {
+		font-weight: bold;
+		font-size: 20px;
+		height: 20%;
+		padding: 10% 0 10px 10px;
+		margin-bottom: 5px;
+		//background: linear-gradient(to bottom right, #85c1bf, #f1fef9);
+		//background: rgb(55,186,189);
+		background: #9ED6CF;
+	}
+	
+	.cuisineImg {
+		border-radius: 10px;
+		max-height: 600rpx;
+		height: auto;
+		width: auto;
+		padding: 0rpx 5rpx 2rpx;
+	}
+	
+	.doFoodConfigView {
+		width: 93%;
+		margin: 0 auto;
+		margin-top: 5px;
+		padding: 2% 5px;
+		background-color: #ffffff;
+		border-radius: 10px;
+		border: 1px solid #d3d3d3;
+	}
+	
+	
+	.gwcNum {
+		width: 15px;
+		top: 17px;
+		left: 21px;
+		position: relative;
+	}
+	
+	/* 商品列表 */
+	.goodsContent {
+		width: 100%;
+		margin: 0 auto;
+		flex-direction: column;
+		background: #f3f3f3;
+		display: flex;
+		justify-content: center;
+	}
+	
+	.goodsItem {
+		width: 280rpx;
+		background: #FFFFFF;
+		// border-radius: 10px;
+		padding: 10rpx 0;
+		// margin: 5rpx;
+		// border: 1px solid #ebebeb;
+	}
+
+	.goodsName {
+		font-size: 24rpx;
+		color: #2e2e2e;
+		padding: 10rpx 20rpx;
+		overflow: hidden;
+		text-overflow: ellipsis;
+		display: -webkit-box;
+		-webkit-line-clamp: 2;
+		-webkit-box-orient: vertical;
+	}
+
+	.goodsPrice {
+		color: #ffac29;
+		font-size: 24rpx;
+		padding: 0 15rpx;
+	}
+
+
+	.addFood {
+		margin-left: 20rpx;
+		color: #8c8c8c;
+	}
+
+	.minus {
+		width: 26px;
+		height: 26px;
+		background-color: #efefef;
+		border-width: 1px;
+		border-color: #c6c6c6;
+		border-top-left-radius: 100px;
+		border-top-right-radius: 100px;
+		border-bottom-left-radius: 100px;
+		border-bottom-right-radius: 100px;
+		@include flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.input {
+		padding: 0;
+	}
+
+	.plus {
+		width: 20px;
+		height: 20px;
+		background-color: #FF0000;
+		border-radius: 50%;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+</style>

+ 490 - 0
pageA/integral/list.vue

@@ -0,0 +1,490 @@
+<template>
+	<view>
+		<view class="view">
+			<view class="hand">
+				<uni-row>
+					<uni-col :span="6">
+						<u--text text="所属机构" size="16" bold color="#619f8a"></u--text>
+					</uni-col>
+					<uni-col :span="18">
+						<u--text :text="data.organizationName" size="16" color="#757575">
+						</u--text>
+					</uni-col>
+				</uni-row>
+				<view style="color: #696969;margin-top: 20rpx;">
+					<uni-row>
+						<uni-col :span="7">
+							<u--text text="领取地点" size="16" bold color="#619f8a"></u--text>
+						</uni-col>
+						<uni-col :span="12">
+							<view>
+								<view style="padding: 0 20rpx;">
+									<picker @change="bindPickerChange" :value="index" :range="placeData"
+										range-key="placeName">
+										<view style="font-size: 40rpx;color: #848484;">
+											<u--text :iconStyle="{color: '#757575',fontSize:'40rpx'}"
+												suffixIcon="arrow-down" :text="placeData[index].placeName"
+												color="#757575" size="16"></u--text>
+										</view>
+									</picker>
+								</view>
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+				<view class="uni-list" style="margin-top: 30rpx;">
+					<view class="uni-list-cell">
+						<view class="uni-list-cell-db">
+							<view class="uni-input" style="color: #535353;font-size: 25rpx;">
+								下单备注:
+							</view>
+						</view>
+					</view>
+					<view class="uni-list-cell">
+						<view class="uni-list-cell-db">
+							<u--textarea v-model="remark"></u--textarea>
+						</view>
+					</view>
+				</view>
+			</view>
+			<u-list @scrolltolower="scrolltolower">
+				<view v-if="!shopDataNow">
+					<image style="margin: 0 auto; width: 100%;" src="../../static/img/page/empty_view.png"></image>
+				</view>
+				<u-list-item v-for="(item, index) in shopDataNow" :key="index">
+					<view v-if="item.num !== 0 && item.num" class="listItemStyle">
+						<u-row>
+							<u-col span="3">
+								<u--image :showLoading="true" shape="circle" :src="baseURL+item.giftPictrue"
+									width="70px" height="70px" style="margin: 10px;"></u--image>
+							</u-col>
+							<u-col span="9" class="">
+								<view>
+									{{item.giftName}}
+								</view>
+								<view v-if="item.eventTime"
+									style="text-align: left;color: #ffaf25;font-size: 22rpx;margin-top: 10rpx;">
+									{{item.eventTime+" 可领取"}}
+								</view>
+								<u-row>
+									<u-col span="10">
+										<view style="margin-top: 3px;">
+											<u-icon name="integral" :label="item.giftPrice"></u-icon>
+										</view>
+									</u-col>
+									<u-col span="2">
+										<view style="margin-top: 3px;">
+											x {{parseInt(item.num)}}
+										</view>
+									</u-col>
+								</u-row>
+							</u-col>
+							<!-- <u-col span="1" class="numberStyler">
+								<view style="padding: 15rpx;">
+									<u-button icon="minus" size="mini" color="#e93c45" @click="addToCart(0,item)">
+									</u-button>
+								</view>
+								<view style="padding: 15rpx;">
+									<u-button icon="plus" size="mini" color="rgb(10, 185, 156)"
+										@click="addToCart(1,item)">
+									</u-button>
+								</view>
+							</u-col> -->
+							<!-- <u-col span="1">
+								<u-button @click="addToCart(0,item)" icon="trash" size="30" color="#d23226">
+								</u-button>
+							</u-col> -->
+						</u-row>
+					</view>
+				</u-list-item>
+			</u-list>
+			<view style="margin-bottom: 220rpx;"></view>
+		</view>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="7">
+						<view class="sum_price_view">
+							<span>合计:</span>
+							<u-row>
+								<u-col span="3">
+									<u-icon name="integral" color="#aa0000" size="30"></u-icon>
+								</u-col>
+								<u-col span="9">
+									<view style="margin-left: 20rpx;color:#aa0000;font-size: 40rpx;">
+										{{priceSum}}
+									</view>
+								</u-col>
+							</u-row>
+						</view>
+					</u-col>
+					<u-col span="5">
+						<u-button class="btnDoPay" shape="circle" @click="toOKPage" :disabled="isDisabled"
+							color="linear-gradient(to bottom right, #79a7a4, #88d8a1)" text="确认支付"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				ghAddrSrc: '',
+				index: 0,
+				baseURL: this.$BASE_URL,
+				priceSum: 0.0,
+				dateShow: false,
+				data: {
+					organizationName: "",
+				},
+				jcd: [],
+				from: {
+					userNumber: '',
+					phone: '',
+					jgid: '',
+					paytime: '',
+					orderTotal: 0,
+					hsGifts: [],
+					remark: '',
+					placeNumber: ''
+				},
+				isDisabled: false,
+				placeData: [],
+				shopData: [],
+				shopDataNow: [],
+				addressData: uni.getStorageSync("addressData"),
+				remark: ''
+			}
+		},
+		onBackPress() {
+			uni.removeStorageSync('shopData')
+			this.priceSum = 0.0
+		},
+		onShow() {
+			this.shopDataNow = []
+			this.data.organizationName = uni.getStorageSync("orgInfo").organizationName
+			//清空价格总数
+			this.priceSum = 0;
+			//获取瀑布流中所有菜品数据
+			const data = uni.getStorageSync('shopData')
+			for (var i = 0; i < data.length; i++) {
+				if (data[i].num) {
+					//计算单个菜品的总价格
+					const total = data[i].num * data[i].giftPrice
+					data[i].total = total
+					//传入 购物数据当前集合 
+					this.shopDataNow.push(data[i])
+					//计算页面显示的总价格
+					this.priceSum = parseFloat(this.priceSum) + (data[i].num * parseFloat(data[i].giftPrice)) + ''
+				}
+			}
+			//获取菜品查询数据
+			const cuisinesData = uni.getStorageSync("cuisinesData")
+			//获取用户信息
+			const user = uni.getStorageSync('userInfo');
+		},
+		onLoad() {
+			this.getGiftReceivePlace()
+			// this.getAddress()
+		},
+		onshow() {
+			this.getAddress()
+		},
+		methods: {
+			toAddressListPage() {
+				uni.redirectTo({
+					url: '../../pageA/card/addressList',
+					success() {
+						uni.setStorageSync("clickType", 1)
+					}
+				})
+			},
+			async getGiftReceivePlace() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getGiftReceivePlace',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.placeData = res.data
+				} else {
+					uni.showModal({
+						title: "系统提醒",
+						showCancel: false,
+						content: res.msg,
+					});
+				}
+			},
+			async getAddress() {
+				if (uni.getStorageSync("addressData")) {
+					this.addressData = uni.getStorageSync("addressData")
+					return
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/uadsList?userCode=' + uni.getStorageSync('userInfo').userName,
+					method: 'get',
+					urlType: 2
+				});
+				if (res.code === 200) {
+					this.addressData = res.rows[0]
+				} else {
+					uni.showToast({
+						duration: 2500,
+						title: res.msg,
+						icon: 'error',
+					});
+				}
+			},
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+			},
+			addToCartOLD(type, food) {
+				food.num -= 1
+				this.priceSum = parseFloat(this.priceSum) - parseFloat(food.giftPrice)
+				let coyp = []
+				this.shopDataNow.forEach(item => {
+					if (item.num != 0) {
+						coyp.push(item)
+					}
+				})
+				this.shopDataNow = coyp
+			},
+			addToCart(type, gift) {
+				if (type === 0 && gift.num === 0) {
+					return
+				}
+				if (gift.amount === 0) {
+					uni.showToast({
+						duration: 500,
+						title: "库存不足",
+						icon: 'error'
+					});
+					return
+				}
+				if (type === 1) {
+					if (gift.num) {
+						if (gift.amount <= gift.num) {
+							uni.showToast({
+								duration: 500,
+								title: "库存已达最大数量",
+								icon: 'error'
+							});
+							return
+						}
+						gift.num += 1
+					} else {
+						gift.num = 1
+					}
+					this.priceSum = parseFloat(this.priceSum) + gift.giftPrice + ''
+				} else {
+					gift.num -= 1
+					this.priceSum = parseFloat(this.priceSum) - gift.giftPrice + ''
+				}
+				// let that = this
+				// setTimeout(() => {
+				// 	that.setGwcNum()
+				// }, 100)
+			},
+			toOKPage() {
+				this.isDisabled = true
+				let that = this
+				uni.requestSubscribeMessage({
+					tmplIds: ['kVkzFr0kqRMg_bHA9WPE8SU-udtMh452g0GRE2a03qU'],
+					success(res) {
+						that.submitOrder()
+					},
+					fail() {
+						that.submitOrder()
+					}
+				})
+			},
+			async submitOrder() {
+				uni.showLoading({
+					title: '加载中',
+					mask: true
+				})
+				const data = this.shopDataNow
+				for (var i = 0; i < data.length; i++) {
+					if (data[i].num) {
+						data[i].amount = data[i].num
+					}
+				}
+				let userInfo = uni.getStorageSync('userInfo')
+				this.from = {
+					userNumber: userInfo.userName,
+					userName: userInfo.nickName,
+					phone: userInfo.phonenumber,
+					jgid: uni.getStorageSync("orgInfo").organizationCode,
+					paytime: '',
+					orderType: uni.getStorageSync('orderType'),
+					orderTotal: this.priceSum,
+					hsGifts: this.shopDataNow,
+					remark: this.remark,
+					placeNumber: this.placeData[this.index].placeName
+				}
+				if (this.priceSum === 0) {
+					uni.showToast({
+						duration: 1500,
+						icon: 'none',
+						title: "没有需要兑换的物品"
+
+					});
+					return
+				}
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/giftOrder',
+					method: 'post',
+					data: this.from,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.priceSum = 0.0;
+					setTimeout(() => {
+						uni.hideLoading()
+						this.isDisabled = false
+						uni.navigateTo({
+							url: 'ok'
+						})
+					}, 1000)
+				} else {
+					uni.hideLoading()
+					uni.showToast({
+						duration: 1500,
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			},
+			submitDate() {},
+			scrolltolower() {
+				//this.getRechargeHistoryList()
+			},
+			loadmore(data) {
+				for (var i = 0; i < data.length; i++) {
+					this.indexList.push(data[i])
+				}
+			},
+			result(time, mode) {
+				const timeFormat = uni.$u.timeFormat
+				switch (mode) {
+					case 'datetime':
+						return timeFormat(time, 'yyyy-mm-dd hh:MM')
+					case 'date':
+						return timeFormat(time, 'yyyy-mm-dd')
+					case 'year-month':
+						return timeFormat(time, 'yyyy-mm')
+					case 'time':
+						return time
+					default:
+						return ''
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.view {
+		background-color: #ebebeb;
+		padding-top: 10px;
+	}
+
+	.hand {
+		padding: 5%;
+		margin: 0 5px 5px 5px;
+		border-radius: 15px;
+		background: linear-gradient(to bottom right, #97dad8, #f1fef9);
+	}
+
+	.orgTop {
+		margin-bottom: 5px;
+	}
+
+	.sxButton {
+		width: 100px;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+	}
+
+	.listTermDate {
+		padding: 10px 0;
+	}
+
+	.listItemStyle {
+		margin: 5px 12px;
+		padding: 5px;
+		border-radius: 15px;
+		background-color: #fafafa;
+	}
+
+	.minus {
+		width: 22px;
+		height: 22px;
+		background-color: #efefef;
+		border-width: 1px;
+		border-color: #c6c6c6;
+		border-radius: 100px;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.input {
+		padding: 0;
+	}
+
+	.plus {
+		width: 22px;
+		height: 22px;
+		background-color: #FF0000;
+		border-radius: 50%;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+
+	.numberStyler {
+		position: relative;
+		left: -10px;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 80px;
+		background-color: #ffffff;
+		z-index: 9999;
+	}
+
+	.sum_price_num_style {
+		font-size: 30px;
+		color: #d83024;
+	}
+
+	.sum_price_view {
+		margin-left: 10px;
+		display: flex;
+		justify-content: unset;
+		align-items: baseline;
+	}
+
+	.btnDoPay {
+		width: 100%;
+	}
+</style>

+ 41 - 0
pageA/integral/more.vue

@@ -0,0 +1,41 @@
+<template>
+	<view>
+		<view v-html="data">
+			<view class="back-top-box">
+				<u-back-top :scroll-top="scrollTop"></u-back-top>
+			</view>
+		</view>
+		<view style="height: 40rpx;"></view>
+		<!--    回到顶部-->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: uni.getStorageSync("giftContent"),
+				scrollTop: 0
+			}
+		},
+		onShow() {
+			if (this.data) {
+				this.data = this.data.replace(/<img/g,
+					"<img style='max-width:100%;height:auto;'");
+			}
+		},
+		onPageScroll(e) {
+			this.scrollTop = e.scrollTop
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style scoped>
+	image {
+		padding: 0;
+		margin: 0;
+	}
+</style>

+ 53 - 0
pageA/integral/ok.vue

@@ -0,0 +1,53 @@
+<template>
+	<view>
+		<view class="okView">
+			<u-icon name="checkbox-mark" color="rgb(55,186,189)" size="260rpx"></u-icon>
+			<view style="font-size: 35rpx;font-weight: bold;">下 单 成 功</view>
+		</view>
+		<view style="height: 350rpx; text-align: center;padding:40rpx 0 ;color: #848484;">
+			请前往 我的 → 兑换记录 查看
+		</view>
+		<view style="width:300rpx; color: #000000; border-radius: 5px; margin:0 auto">
+			<u-button icon="reload" color="rgb(55,186,189)" @click="toHomePage()" text="返回主页"></u-button>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			toHomePage() {
+				uni.reLaunch({
+					url: '../../pages/home/index'
+				})
+			}
+			// uni.requestSubscribeMessage({
+			// 	tmplIds: ['ekI5ueMK83FprLjYmRWIy4mfS3kWl6RHh3JT4DtLiN8'],
+			// 	success(res) {
+			//	}
+			// })
+
+		}
+	}
+</script>
+
+<style>
+	.okView {
+		background-color: #f0f0f0;
+		border-radius: 20px;
+		padding: 60rpx;
+		height: 300rpx;
+		width: 50%;
+		margin: 0 auto;
+		margin-top: 20%;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+
+	}
+</style>

+ 238 - 0
pageA/integral/shopcar.vue

@@ -0,0 +1,238 @@
+<template>
+	<view>
+		<view style="padding: 10rpx 20rpx;">
+			<view v-if="!shopDataNow">
+				<image style="margin: 0 auto; width: 100%;" src="../../static/img/page/empty_view.png"></image>
+			</view>
+			<u-checkbox-group v-model="checkgroup" placement="column" @change="checkChange">
+				<view v-for="(item, index) in shopDataNow" :key="index">
+					<view v-if="item.num !== 0 && item.num" class="listItemStyle">
+						<u-row>
+							<u-col span="2">
+								<view style="margin: 15rpx 10rpx 0 10rpx;">
+									<u-checkbox activeColor="#53a591" :customStyle="{marginBottom: '8px'}" :name="item">
+									</u-checkbox>
+								</view>
+							</u-col>
+							<u-col span="3">
+								<u--image :showLoading="true" shape="circle" :src="baseURL+item.giftPictrue"
+									width="80px" height="80px" style="margin: 10rpx "></u--image>
+							</u-col>
+							<u-col span="7">
+								<view style="">
+									{{item.giftName}}
+								</view>
+								<view style="text-align: left;color: #ffaf25;font-size: 22rpx;margin-top: 10rpx;">
+									{{item.eventTime+" 可领取"}}
+								</view>
+								<u-row>
+									<u-col span="6">
+										<view style="margin-top: 10rpx;">
+											<u-icon name="integral" :label="item.giftPrice"></u-icon>
+										</view>
+									</u-col>
+									<u-col span="6">
+										<view style="margin-top: 30rpx;">
+											<u-row>
+												<u-col span="4">
+													<view style="padding: 5rpx;">
+														<u-button icon="minus" size="mini" plain="ture"
+															:disabled="buttonIsUse" @click="minusGoods(item)">
+														</u-button>
+													</view>
+												</u-col>
+												<u-col span="4">
+													<view style="text-align: center;">
+														{{parseInt(item.num)}}
+													</view>
+												</u-col>
+												<u-col span="4">
+													<view style="padding: 5rpx;">
+														<u-button icon="plus" size="mini" plain="ture"
+															:disabled="buttonIsUse" @click="addGoods(item)">
+														</u-button>
+													</view>
+												</u-col>
+											</u-row>
+										</view>
+									</u-col>
+								</u-row>
+							</u-col>
+						</u-row>
+					</view>
+				</view>
+
+			</u-checkbox-group>
+		</view>
+		<view style="margin-bottom: 150rpx;"></view>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button class="btnDoPay" shape="circle" @click="toOKPage"
+							color="linear-gradient(to bottom right, #79a7a4, #88d8a1)" text="确认下单"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				status: 'loadmore',
+				baseURL: this.$BASE_URL,
+				list: 15,
+				page: 0,
+				shopDataNow: [],
+				gwcId: '',
+				buttonIsUse: false,
+				checkgroup: ''
+			}
+		},
+		onLoad() {
+			this.getGWC()
+			uni.removeStorageSync('shopData')
+		},
+		onReachBottom() {
+			if (this.page >= 3) return;
+			this.status = 'loading';
+			this.page = ++this.page;
+			setTimeout(() => {
+				this.list += 10;
+				if (this.page >= 3) this.status = 'nomore';
+				else this.status = 'loading';
+			}, 2000)
+		},
+		methods: {
+			checkChange(detail) {
+				if (detail.length === 0) {
+					this.buttonIsUse = false
+				} else {
+					this.buttonIsUse = true
+					uni.setStorageSync('shopData', detail)
+				}
+			},
+			async getGWC() {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getUsc',
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.shopDataNow = res.data
+				} else {
+					uni.showToast({
+						duration: 1000,
+						title: res.msg,
+						icon: 'none'
+					})
+				}
+				uni.stopPullDownRefresh()
+			},
+			async minusGoods(data) {
+				data.plusOrMinus = 1
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/addShopCar',
+					method: 'post',
+					data: data,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.getGWC()
+				} else {
+					this.$showModal(res.msg)
+				}
+			},
+			async addGoods(data) {
+				data.plusOrMinus = 0
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/addShopCar',
+					method: 'post',
+					data: data,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.getGWC()
+				} else {
+					this.$showModal(res.msg)
+				}
+			},
+			toOKPage() {
+				let that = this
+				uni.requestSubscribeMessage({
+					tmplIds: ['-57EtxA5K6MUpKbvQwHblrKldu5j1tG6-JlYZNpIZ04'],
+					success(res) {
+						let data = uni.getStorageSync('shopData')
+						if (data && data.length > 0) {
+							for (var i = 0; i < data.length; i++) {
+								for (var j = 0; j < data.length - 1; j++) {
+									if (data[i].eventId !== data[j + 1].eventId) {
+										that.$showModal("不同活动商品不能同时下单")
+										return;
+									}
+								}
+							}
+							uni.navigateTo({
+								url: 'list'
+							})
+						} else {
+							uni.showToast({
+								duration: 1500,
+								title: '请选择至少一个物品',
+								icon: 'none'
+							})
+						}
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.listItemStyle {
+		height: 100%;
+		margin: 10rpx 0;
+		padding: 20rpx 15rpx;
+		border-radius: 15px;
+		background-color: #ffffff;
+		border: 1rpx solid #eeeeee;
+	}
+
+	.wrap {
+		padding: 24rpx;
+	}
+
+	.item {
+		padding: 24rpx 0;
+		color: $u-content-color;
+		font-size: 28rpx;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+		z-index: 9999;
+	}
+
+	.btnDoPay {
+		width: 100%;
+	}
+</style>

+ 189 - 0
pageA/integral/shopcarTemporary.vue

@@ -0,0 +1,189 @@
+<template>
+	<view>
+		<view style="padding: 10rpx 20rpx;">
+			<view v-if="!shopDataNow">
+				<image style="margin: 0 auto; width: 100%;" src="../../static/img/page/empty_view.png"></image>
+			</view>
+			<u-checkbox-group v-model="checkgroup" placement="column" @change="checkChange">
+				<view v-for="(item, index) in shopDataNow" :key="index">
+					<view v-if="item.num !== 0 && item.num" class="listItemStyle">
+						<u-row>
+							<u-col span="2">
+								<view style="margin: 15rpx 10rpx 0 10rpx;">
+									<u-checkbox activeColor="#53a591" :customStyle="{marginBottom: '8px'}" :name="item">
+									</u-checkbox>
+								</view>
+							</u-col>
+							<u-col span="3">
+								<u--image :showLoading="true" shape="circle" :src="baseURL+item.giftPictrue"
+									width="80px" height="80px" style="margin: 10rpx "></u--image>
+							</u-col>
+							<u-col span="7">
+								<view style="">
+									{{item.giftName}}
+								</view>
+								<u-row>
+									<u-col span="6">
+										<view style="margin-top: 10rpx;">
+											<u-icon name="integral" :label="item.giftPrice"></u-icon>
+										</view>
+									</u-col>
+									<u-col span="6">
+										<view style="margin-top: 30rpx;">
+											<u-row>
+												<u-col span="4">
+													<view style="padding: 5rpx;">
+														<u-button icon="minus" size="mini" plain="ture"
+															:disabled="buttonIsUse" @click="minusGoods(index,item)">
+														</u-button>
+													</view>
+												</u-col>
+												<u-col span="4">
+													<view style="text-align: center;">
+														{{parseInt(item.num)}}
+													</view>
+												</u-col>
+												<u-col span="4">
+													<view style="padding: 5rpx;">
+														<u-button icon="plus" size="mini" plain="ture"
+															:disabled="buttonIsUse" @click="addGoods(item)">
+														</u-button>
+													</view>
+												</u-col>
+											</u-row>
+										</view>
+									</u-col>
+								</u-row>
+							</u-col>
+						</u-row>
+					</view>
+				</view>
+
+			</u-checkbox-group>
+		</view>
+		<view style="margin-bottom: 150rpx;"></view>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button class="btnDoPay" shape="circle" @click="toOKPage"
+							color="linear-gradient(to bottom right, #79a7a4, #88d8a1)" text="确认下单"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				status: 'loadmore',
+				baseURL: this.$BASE_URL,
+				list: 15,
+				page: 0,
+				shopDataNow: [],
+				gwcId: '',
+				buttonIsUse: false,
+				checkgroup: ''
+			}
+		},
+		onLoad() {
+			this.getGWC()
+		},
+		onReachBottom() {
+			if (this.page >= 3) return;
+			this.status = 'loading';
+			this.page = ++this.page;
+			setTimeout(() => {
+				this.list += 10;
+				if (this.page >= 3) this.status = 'nomore';
+				else this.status = 'loading';
+			}, 2000)
+		},
+		methods: {
+			checkChange(detail) {
+				if (detail.length === 0) {
+					this.buttonIsUse = false
+				} else {
+					this.buttonIsUse = true
+					uni.setStorageSync('shopData', detail)
+				}
+			},
+			getGWC() {
+				this.shopDataNow = uni.getStorageSync('shopData')
+				uni.removeStorageSync('shopData')
+				uni.stopPullDownRefresh()
+			},
+			async minusGoods(index, data) {
+				if (data.num === 1) {
+					this.shopDataNow.splice(index, 1)
+				} else {
+					data.num -= 1
+				}
+			},
+			async addGoods(data) {
+				if (data.num < data.amount) {
+					data.num += 1
+				}
+			},
+			toOKPage() {
+				let that = this
+				uni.requestSubscribeMessage({
+					tmplIds: ['-57EtxA5K6MUpKbvQwHblrKldu5j1tG6-JlYZNpIZ04'],
+					success(res) {
+						let data = uni.getStorageSync('shopData')
+						if (data && data.length > 0) {
+							uni.navigateTo({
+								url: 'list'
+							})
+						} else {
+							uni.showToast({
+								duration: 1500,
+								title: '请选择至少一个物品',
+								icon: 'none'
+							})
+						}
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.listItemStyle {
+		height: 100%;
+		margin: 10rpx 0;
+		padding: 20rpx 15rpx;
+		border-radius: 15px;
+		background-color: #ffffff;
+		border: 1rpx solid #eeeeee;
+	}
+
+	.wrap {
+		padding: 24rpx;
+	}
+
+	.item {
+		padding: 24rpx 0;
+		color: $u-content-color;
+		font-size: 28rpx;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+		z-index: 9999;
+	}
+
+	.btnDoPay {
+		width: 100%;
+	}
+</style>

+ 190 - 0
pageA/kq/kqList.vue

@@ -0,0 +1,190 @@
+<template>
+	<view>
+		<scroll-list ref="list" :option="option" @load="load" @refresh="refresh" @loadSuccess="loadSuccess"
+			@scrolltolower="scrolltolower">
+			<view v-for="(item, index) in list" :key="index" @click="handleTest(item)">
+				<view class="infoBody">
+					<view>
+						<view style="border-bottom: 1px #b8b8b8 solid;">
+							<uni-row class="demo-uni-row">
+								<uni-col :span="20">
+									<view class="demo-uni-col dark"
+										style="font-size: 36rpx;margin: -20rpx 0 0 0;font-weight: bold;letter-spacing:5rpx;color: #616161;">
+										2023-04-26
+									</view>
+								</uni-col>
+								<uni-col v-if="item.msgIsRead === '0'" :span="4">
+									<view class="demo-uni-col light"
+										style="color: rgb(55,186,189);margin-bottom: 10rpx;">
+									上班打卡
+									</view>
+								</uni-col>
+							</uni-row>
+						</view>
+						<uni-row class="demo-uni-row">
+							<uni-col :span="12">
+								<view class="demo-uni-col light" style="padding: 26rpx;color: #b1b1b1;">
+								</view>
+							</uni-col>
+						</uni-row>
+						<uni-row class="demo-uni-row">
+							<uni-col :span="12">
+								<view class="demo-uni-col light" style="color: #b1b1b1;">
+									{{"申请人:"+item.formData.apply_user_name}}
+								</view>
+							</uni-col>
+							<uni-col :span="12">
+								<view class="demo-uni-col light" style="color: #b1b1b1;">
+									{{item.createTime}}
+								</view>
+							</uni-col>
+						</uni-row>
+					</view>
+				</view>
+			</view>
+		</scroll-list>
+	</view>
+</template>
+<style lang="scss" scoped>
+	// page {
+	// 	background-color: #f3f3f3;
+	// }
+
+	.page-wrap {}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 40rpx;
+		border-radius: 20rpx;
+		margin: 20rpx;
+		box-shadow: 0px 2px 10px #cccccc;
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				page: 1,
+				list: [],
+				scrollList: [],
+				total: 0,
+				actions: [],
+				file_approval_flow_run_key: '',
+				biz_leave_flow_run_key: '',
+				reserve_consuming_flow_run_key: '',
+				personnel_hire_approval_flow_run_key: '',
+				personnel_dimission_approval_flow_run_key: ''
+			}
+		},
+		onLoad() {
+			this.file_approval_flow_run_key = uni.getStorageSync('file_approval_flow_run_key')
+			this.biz_leave_flow_run_key = uni.getStorageSync('biz_leave_flow_run_key')
+			this.reserve_consuming_flow_run_key = uni.getStorageSync('reserve_consuming_flow_run_key')
+			this.reserve_return_flow_run_key = uni.getStorageSync('reserve_return_flow_run_key')
+			this.reserve_register_flow_run_key = uni.getStorageSync('reserve_register_flow_run_key')
+			this.personnel_hire_approval_flow_run_key = uni.getStorageSync('personnel_hire_approval_flow_run_key')
+			this.personnel_dimission_approval_flow_run_key = uni.getStorageSync(
+				'personnel_dimission_approval_flow_run_key')
+		},
+		onShow() {
+			this.$refs.list.refresh()
+		},
+		methods: {
+			handleTest(item) {
+				item.pageType = 4
+				uni.setStorageSync("approval", item)
+				this.readL(item.taskId)
+				if (item.examplesId === this.file_approval_flow_run_key) {
+					this.$goto('../ge/geNewsApproval')
+				} else if (item.examplesId === this.biz_leave_flow_run_key) {
+					this.$goto('../ge/geApproval')
+				} else if (item.examplesId === this.reserve_register_flow_run_key) {
+					this.$goto('../ge/geReserveApproval')
+				} else if (item.examplesId === this.reserve_consuming_flow_run_key) {
+					this.$goto('../ge/geReserveApproval')
+				} else if (item.examplesId === this.reserve_return_flow_run_key) {
+					this.$goto('../ge/geReserveApproval')
+				} else if (item.examplesId === this.personnel_hire_approval_flow_run_key) {
+					this.$goto('../ge/geEntry')
+				} else if (item.examplesId === this.personnel_dimission_approval_flow_run_key) {
+					this.$goto('../ge/geDimission')
+				} else if (item.examplesId === uni.getStorageSync('interview_record_approval_flow_run_key')) {
+					this.$goto('../ge/geInterview')
+				} else if (item.examplesId === uni.getStorageSync('instant_notice_approval_flow_run_key')) {
+					this.$goto('../ge/geNotice')
+				} else if (item.examplesId === uni.getStorageSync('shift_official_approval_flow_run_key')) {
+					this.$goto('../ge/geShiftOfficial')
+				} else if (item.examplesId === uni.getStorageSync('use_seal_approval_flow_run_key')) {
+					this.$goto('../ge/geUseSeal')
+				} else if (item.examplesId === uni.getStorageSync('device_repairs_approval_flow_run_key')) {
+					this.$goto('../ge/geDeviceRepairs')
+				} else if (item.examplesId === uni.getStorageSync('device_scrap_approval_flow_run_key')) {
+					this.$goto('../ge/geDeviceScrap')
+				}else if (item.examplesId === uni.getStorageSync('purchase_approval_flow_run_key')) {
+					this.$goto('../ge/gePurchase')
+				}
+
+				this.list = []
+			},
+			async readL(id) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/rt?taskId=' + id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+
+				}
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/ccRecord?pageNum=' + paging.page + '&pageSize=' + paging.size,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					for (var i = 0; i < res.rows.length; i++) {
+						res.rows[i].formData = JSON.parse(res.rows[i].formData)
+					}
+					if (paging.page === 1) {
+						this.scrollList = res.rows
+						this.total = res.total
+						this.$refs.list.loadSuccess({
+							list: res.rows,
+							total: this.total
+						});
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							this.scrollList.push(res.rows[i])
+						}
+						this.$refs.list.loadSuccess({
+							list: this.scrollList,
+							total: this.total
+						});
+					}
+				}
+			},
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>

+ 106 - 0
pageA/login/css/main.css

@@ -0,0 +1,106 @@
+.content {
+	display: flex;
+	flex-direction: column;
+	justify-content: center;
+	margin-top: 128rpx;
+}
+
+/* 头部 logo */
+.header {
+	width: 161rpx;
+	height: 171rpx;
+	box-shadow: 0rpx 0rpx 60rpx 0rpx rgba(0, 0, 0, 0.1);
+	border-radius: 50%;
+	background-color: #f4f4f4;
+	margin-top: 328rpx;
+	margin-bottom: 72rpx;
+	margin-left: auto;
+	margin-right: auto;
+}
+
+.header image {
+	width: 168rpx;
+	height: 168rpx;
+	border-radius: 10%;
+}
+
+/* 主体 */
+.main {
+	display: flex;
+	flex-direction: column;
+	padding-left: 70rpx;
+	padding-right: 70rpx;
+}
+
+.tips {
+	color: #999999;
+	font-size: 28rpx;
+	margin-top: 64rpx;
+	margin-left: 48rpx;
+}
+
+/* 登录按钮 */
+.wbutton {
+	margin-top: 96rpx;
+}
+
+/* 其他登录方式 */
+.other_login {
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+	margin-top: 256rpx;
+	text-align: center;
+}
+
+.login_icon {
+	border: none;
+	font-size: 64rpx;
+	margin: 0 64rpx 0 64rpx;
+	color: rgba(0, 0, 0, 0.7)
+}
+
+.wechat_color {
+	color: #83DC42;
+}
+
+.weibo_color {
+	color: #F9221D;
+}
+
+.github_color {
+	color: #24292E;
+}
+
+/* 底部 */
+.footer {
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+	font-size: 28rpx;
+	margin-top: 64rpx;
+	color: rgba(0, 0, 0, 0.7);
+	text-align: center;
+	height: 40rpx;
+	line-height: 40rpx;
+}
+
+.footer text {
+	font-size: 24rpx;
+	margin-left: 15rpx;
+	margin-right: 15rpx;
+}
+
+
+.uni-fixed-bottom {
+	width: 100%;
+	bottom: 0upx;
+	padding: 0upx;
+	position: fixed;
+	background: #FFFFFF;
+	transform: translateZ(0);
+	bottom: env(safe-area-inset-bottom);
+	bottom: constant(safe-area-inset-bottom);
+}

+ 170 - 0
pageA/login/forget.vue

@@ -0,0 +1,170 @@
+<template>
+	<view>
+
+		<view class="content">
+			<!-- 主体 -->
+			<view class="main">
+				<view class="tips">若你忘记了密码,可在此重置为:123456。</view>
+				<wInput v-model="phoneData" type="text" maxlength="11" placeholder="请输入手机号码"></wInput>
+				<wInput v-model="userName" type="text" maxlength="11" placeholder="请输入姓名" isShowPass></wInput>
+			</view>
+
+			<wButton bgColor="linear-gradient(to bottom right, rgb(55,186,189), #94e2c4)" class="wbutton" text="重置密码"
+				:rotate="isRotate" @click.native="startReset()"></wButton>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	let _this;
+	import wInput from '../watch-login/watch-input.vue' //input
+	import wButton from '../watch-login/watch-button.vue' //button
+	export default {
+		data() {
+			return {
+				phoneData: "", //电话
+				userName: "", //姓名
+				verCode: "", //验证码
+				isRotate: false, //是否加载旋转
+			}
+		},
+		components: {
+			wInput,
+			wButton
+		},
+		mounted() {
+			_this = this;
+		},
+		methods: {
+			async startReset(e) {
+				//登录
+				if (this.isRotate) {
+					//判断是否加载中,避免重复点击请求
+					return false;
+				}
+				if (this.phoneData.length == "") {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '手机号不能为空'
+					});
+					return;
+				}
+				if (!/^1[3|4|5|6|7|8|9][0-9]\d{4,8}$/.test(this.phoneData)) {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '手机号不正确'
+					});
+					return
+				}
+				if (this.userName.length == "") {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '姓名不能为空'
+					});
+					return;
+				}
+				_this.isRotate = true
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/resetPwd?un=' + this.userName + "&phone=" + this.phoneData,
+					method: 'get',
+					urlType: 1,
+					isNotToken: true
+				})
+				_this.isRotate = false;
+				if (res.code == 200) {
+					_this.isRotate = false
+					uni.showToast({
+						icon: 'ok',
+						position: 'bottom',
+						title: '已重置为默认密码'
+					});
+					this.$goto('login');
+				} else {
+					uni.showToast({
+						icon: 'error',
+						position: 'bottom',
+						title: '手机号与姓名不匹配'
+					});
+				}
+				_this.isRotate = false;
+			},
+			getVerCode() {
+				//获取验证码
+				if (_this.phoneData.length != 11) {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '手机号不正确'
+					});
+					return false;
+				}
+				console.log("获取验证码")
+				this.$refs.runCode.$emit('runCode'); //触发倒计时(一般用于请求成功验证码后调用)
+				uni.showToast({
+					icon: 'none',
+					position: 'bottom',
+					title: '模拟倒计时触发'
+				});
+
+				setTimeout(function() {
+					_this.$refs.runCode.$emit('runCode', 0); //假装模拟下需要 终止倒计时
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '模拟倒计时终止'
+					});
+				}, 3000)
+			},
+			startRePass() {
+				//重置密码
+				if (this.isRotate) {
+					//判断是否加载中,避免重复点击请求
+					return false;
+				}
+				if (this.phoneData.length != 11) {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '手机号不正确'
+					});
+					return false;
+				}
+				if (this.passData.length < 6) {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '密码不正确'
+					});
+					return false;
+				}
+				if (this.verCode.length != 4) {
+					uni.showToast({
+						icon: 'none',
+						position: 'bottom',
+						title: '验证码不正确'
+					});
+					return false;
+				}
+				console.log("重置密码成功")
+				_this.isRotate = true
+				setTimeout(function() {
+					_this.isRotate = false
+				}, 3000)
+
+
+			}
+		}
+	}
+</script>
+
+<style>
+	@import url("../watch-login/css/icon.css");
+	@import url("./css/main.css");
+</style>

Datei-Diff unterdrückt, da er zu groß ist
+ 67 - 0
pageA/login/login.vue


Datei-Diff unterdrückt, da er zu groß ist
+ 63 - 0
pageA/login/register.vue


Datei-Diff unterdrückt, da er zu groß ist
+ 50 - 0
pageA/login/selectOrg.vue


+ 144 - 0
pageA/msg/abList.vue

@@ -0,0 +1,144 @@
+<template>
+	<view>
+		<view class="qu" v-for="qu in data">
+			<view class="tip">
+				<text>{{qu.title}}</text>
+			</view>
+			<view class="row uni-flex uni-row" v-for="friend in qu.children"  @click="toVisitingCard(friend)">
+				<view class="row_logo">
+					<image :src="BaseUrl+friend.imgSrc"></image>
+				</view>
+				<view class="flex-item" style="padding: 10rpx 0;">
+					<u-text :text="friend.name" size="20" color="#787878"></u-text>
+					<!-- <u-text mode="phone" :text="friend.phone" size="15" call="true"></u-text> -->
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: [],
+				BaseUrl: this.$BASE_URL
+			}
+		},
+		onLoad() {
+			this.getabData()
+		},
+		onShow() {
+			this.getabData()
+		},
+		methods: {
+			toVisitingCard(friend) {
+				uni.setStorageSync('data', friend)
+				uni.navigateTo({
+					url: '/pageA/msg/visitingCard'
+				})
+			},
+			async getabData() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/ci/ab?un=' + uni.getStorageSync("deptId"),
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.data = res.data
+				} else {
+					this.data = []
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: #f8f8f8;
+	}
+
+	.row {
+		background: white;
+		display: flex;
+		width: 100%;
+		height: 100rpx;
+		border-bottom: 1px solid #eeeeee;
+
+		.row_logo {
+			width: 20%;
+			display: flex;
+			align-items: center;
+
+			image {
+				width: 50px;
+				height: 50px;
+				margin: auto;
+				border-radius: 5px;
+			}
+		}
+
+		.row_left {
+			height: 100%;
+			width: 40%;
+			display: flex;
+			align-items: center;
+
+			border: {
+				bottom: 1px solid #DDDDDD;
+			}
+
+			text {
+				font-size: 16px;
+				font-family: 'syht';
+				display: block;
+			}
+
+		}
+
+		.row_right {
+			height: 100%;
+			width: 40%;
+			display: flex;
+			align-items: center;
+
+			border: {
+				bottom: 1px solid #DDDDDD;
+			}
+
+			text {
+				font-size: 16px;
+				font-family: 'syht';
+				display: block;
+			}
+
+		}
+
+
+
+	}
+
+	.row:last-child {
+		.row_right {
+			border: 0;
+		}
+	}
+
+	.qu {
+		.tip {
+			margin: 3px 0;
+			font-size: 14px;
+			font-family: 'syht';
+
+			text {
+				margin-left: 13px;
+			}
+		}
+	}
+</style>

+ 136 - 0
pageA/msg/groupAb.vue

@@ -0,0 +1,136 @@
+<template>
+	<view>
+		<view class="qu" v-for="qu in data">
+			<view class="tip">
+				<text>{{qu.title}}</text>
+			</view>
+			<view class="row uni-flex uni-row" v-for="friend in qu.children">
+				<view class="row_logo">
+					<image :src="BaseUrl+friend.imgSrc"></image>
+				</view>
+				<view class="flex-item">
+					<u-text :text="friend.name" size="18" bold></u-text>
+					<u-text mode="phone" :text="friend.phone" size="15" call="true"></u-text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: []
+			}
+		},
+		onLoad() {
+			this.getabData()
+		},
+		onShow() {
+			this.getabData()
+		},
+		methods: {
+			async getabData() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/ci/gab?data=' + uni.getStorageSync("groupUserCode"),
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.data = res.data
+				} else {
+					this.data = []
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: #EEEEEE;
+	}
+
+	.row {
+		background: white;
+		display: flex;
+		width: 100%;
+		height: 60px;
+
+		.row_logo {
+			width: 20%;
+			display: flex;
+			align-items: center;
+
+			image {
+				width: 50px;
+				height: 50px;
+				margin: auto;
+				border-radius: 5px;
+			}
+		}
+
+		.row_left {
+			height: 100%;
+			width: 40%;
+			display: flex;
+			align-items: center;
+
+			border: {
+				bottom: 1px solid #DDDDDD;
+			}
+
+			text {
+				font-size: 16px;
+				font-family: 'syht';
+				display: block;
+			}
+
+		}
+
+		.row_right {
+			height: 100%;
+			width: 40%;
+			display: flex;
+			align-items: center;
+
+			border: {
+				bottom: 1px solid #DDDDDD;
+			}
+
+			text {
+				font-size: 16px;
+				font-family: 'syht';
+				display: block;
+			}
+
+		}
+
+
+
+	}
+
+	.row:last-child {
+		.row_right {
+			border: 0;
+		}
+	}
+
+	.qu {
+		.tip {
+			margin: 3px 0;
+			font-size: 14px;
+			font-family: 'syht';
+
+			text {
+				margin-left: 13px;
+			}
+		}
+	}
+</style>

+ 296 - 0
pageA/msg/index.vue

@@ -0,0 +1,296 @@
+<template>
+	<view class="top">
+		<view style="margin: 20px 15px 15px 15px; border: 1px solid #a4a4a4;border-radius: 10px;">
+			<u--input v-model="text" placeholder="姓名 / 手机号" prefixIcon="search"
+				prefixIconStyle="font-size: 22px;color: #909399" @focus="searchFocus" @blur="searchBlur"
+				@input="doSearch()">
+			</u--input>
+		</view>
+		<view v-if="showSearch">
+			<u-row v-for="item in groupList" customStyle="margin: 5px 0" @click="toGroupAbPage(item.groupMember)">
+				<u-col span="2">
+					<view class="demo-layout bg-purple-light">
+						<image src="../../static/img/msg/gzqz.png" style="margin-left: 10px;width: 50px;height: 50px;">
+						</image>
+					</view>
+				</u-col>
+				<u-col span="9">
+					<view class="demo-layout bg-purple">
+						<u-text :text="item.groupName" size="14"></u-text>
+					</view>
+				</u-col>
+			</u-row>
+		</view>
+		<view v-if="showSearch">
+			<view style="color: #a4a4a4;padding: 5px;background-color: #ffffff;">部门分类</view>
+			<uni-list v-for="item in bmList">
+				<uni-list-item :clickable="true" @click="toAbListPage(item.deptId)" :title="item.deptName" />
+			</uni-list>
+		</view>
+		<view v-if="!showSearch" style="border-top: 1px solid #eeeeee;">
+			<view class="row uni-flex uni-row" v-for="friend in result">
+				<view style="padding: 5rpx 0 0 20rpx" @click="toVisitingCard(friend)">
+					<u-text :text="friend.name+' '+friend.phone" size="18" color="#a5a5a5"></u-text>
+				</view>
+			</view>
+			<view style="height: 40px;">
+
+			</view>
+		</view>
+		<view style="height: 40px;">
+
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				text: '',
+				result: [],
+				data: [],
+				showSearch: true,
+				BaseUrl: this.$BASE_URL,
+				list: [],
+				qiyes: [{
+						id: 1,
+						name: '中山大学',
+						src: '../../static/img/tab-icon/me-active.png'
+					},
+					{
+						id: 2,
+						name: '阿里巴巴',
+						src: '../../static/img/tab-icon/me-active.png'
+					}
+				],
+				stars: [{
+						id: 1,
+						name: '1',
+						src: '../../static/img/tab-icon/me-active.png'
+					},
+					{
+						id: 2,
+						name: '2',
+						src: '../../static/img/tab-icon/me-active.png'
+					}
+				],
+				friends: [],
+				bmList: [],
+				groupList: [],
+				isSearch: false,
+				searchCount: 0
+			}
+		},
+		onLoad() {
+			this.getBmData()
+		},
+		onShow() {
+			this.getBmData()
+			this.getabData()
+			this.getGcData()
+		},
+		methods: {
+			toVisitingCard(friend) {
+				console.log(this.result)
+				uni.setStorageSync('data', friend)
+				uni.navigateTo({
+					url: '/pageA/msg/visitingCard'
+				})
+			},
+			doSearch(value) {
+				let that = this
+				let count = this.searchCount++
+				if (value) {
+					this.result = []
+					this.data.forEach(i => {
+						if (that.isSearch) {
+							// setTimeout(() => {
+							i.children.forEach(t => {
+								if (that.isSearch) {
+									var tc = t
+									if (that.isZhOrNumber(value) === 'ZH') {
+										if (tc.name.indexOf(value) != -1) {
+											that.result.push(tc)
+										}
+									} else if (that.isZhOrNumber(value) === 'NUM') {
+										if (value.length >= 2) {
+											let zzbds = new RegExp("^" + value + "[0-9]+")
+											if (zzbds.test(tc.phone)) {
+												that.result.push(tc)
+											}
+										} else {
+											this.result = []
+										}
+									}
+								}
+							})
+							// }, 10)
+						}
+					})
+				}
+			},
+			isZhOrNumber(str) {
+				//验证是否是汉字
+				var pattern = new RegExp("[\u4E00-\u9FA5]+");
+				if (pattern.test(str)) {
+					return 'ZH'
+				}
+				//验证是否是数字
+				var pattern3 = new RegExp("[0-9]+");
+				if (pattern3.test(str)) {
+					return 'NUM'
+				}
+			},
+			searchFocus() {
+				this.showSearch = false
+				this.isSearch = true
+				this.result = []
+			},
+			searchBlur() {
+				this.isSearch = false
+				this.text = null
+				this.showSearch = true
+			},
+			toAbListPage(deptId) {
+				uni.setStorageSync("deptId", deptId)
+				this.$goto("abList")
+			},
+			toGroupAbPage(data) {
+				uni.setStorageSync("groupUserCode", data)
+				this.$goto("groupAb")
+			},
+			bindClick(e) {
+				console.log('点击item,返回数据' + JSON.stringify(e))
+			},
+			async getGcData() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/ci/gl?un=' + uni.getStorageSync('userInfo').userName,
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.groupList = res.data
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+				}
+			},
+			async getBmData() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/ci/abDepts?un=' + uni.getStorageSync('userInfo').userName + "&oc=" + uni
+						.getStorageSync("orgInfo").organizationCode,
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.bmList = res.data
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+				}
+			},
+			async getabData() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/ci/ab?un=all',
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.data = res.data
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	page {
+		background: #fefefe;
+	}
+
+	.row {
+		background: white;
+		display: flex;
+		width: 100%;
+		height: 80rpx;
+		border-bottom: 1px solid #eeeeee;
+
+		.row_logo {
+			width: 20%;
+			display: flex;
+			align-items: center;
+
+			image {
+				width: 80px;
+				height: 80px;
+				margin: auto;
+				border-radius: 5px;
+			}
+		}
+
+		.row_left {
+			height: 100%;
+			width: 40%;
+			display: flex;
+			align-items: center;
+
+			border: {
+				bottom: 1px solid #DDDDDD;
+			}
+
+			text {
+				font-size: 16px;
+				font-family: 'syht';
+				display: block;
+			}
+
+		}
+
+		.row_right {
+			height: 100%;
+			width: 40%;
+			display: flex;
+			align-items: center;
+
+			border: {
+				bottom: 1px solid #DDDDDD;
+			}
+
+			text {
+				font-size: 16px;
+				font-family: 'syht';
+				display: block;
+			}
+
+		}
+
+
+
+	}
+
+	.row:last-child {
+		.row_right {
+			border: 0;
+		}
+	}
+
+	.qu {
+		.tip {
+			margin: 3px 0;
+			font-size: 14px;
+			font-family: 'syht';
+
+			text {
+				margin-left: 13px;
+			}
+		}
+	}
+</style>

+ 134 - 0
pageA/msg/subscription.vue

@@ -0,0 +1,134 @@
+<template>
+	<!--  消息订阅组件 -->
+	<view class="message_subscription">
+		<button @click="judgementMessageSwitch()"
+			style="margin: 20px;background-color: rgb(55,186,189);">消息订阅测试</button>
+		<button @click="getUser()" style="margin: 20px;background-color: rgb(55,186,189);">获取用户信息</button>
+		<button @click="login()" style="margin: 20px;background-color: rgb(55,186,189);">使用微信登录</button>
+		<u-popup v-model="showOpenSettingDialog" mode="center" width="520rpx" :mask-close-able="false" height="300rpx"
+			border-radius="18">
+			<div class="mock-dialog">
+				<div class="mock-dialog-content">
+					<div class="mock-dialog-title">提示</div>
+					<div class="mock-dialog-text">
+						{{tipsContent}}
+					</div>
+				</div>
+				<div class="mock-dialog-button">
+					<div class="color-gray" @click="dontOpenSetting">{{buttonCancelText}}</div>
+					<div class="color-blue" @click="openSetting">{{buttonConfirmText}}</div>
+				</div>
+			</div>
+		</u-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'messageSubscription',
+		components: {},
+		data() {
+			return {
+				showOpenSettingDialog: false, // 授权询问弹框,uview
+				tipsContent: '为了及时获取订单状态,您是否想接收订单状态的消息提醒?', // 弹框提示内容,
+				buttonConfirmText: '去开启消息提醒',
+				buttonCancelText: '不需要提醒',
+				tmplId: []
+			}
+		},
+		methods: {
+			// 判断消息订阅总开关是否打开
+			judgementMessageSwitch(flag) {
+				let that = this
+				uni.getSetting({
+					withSubscriptions: true,
+					success(res) {
+						console.log(res)
+						if (!res.subscriptionsSetting.mainSwitch) { // 订阅消息的总开关,如果是关着的,引导用户去打开
+							that.showOpenSettingDialog = true
+						} else { // 如果开着,则继续向下打开弹窗,获取用户授权
+							that.messageSubscription()
+						}
+
+					},
+					fail() {
+						that.messageSubscription() // 如果失败,则继续向下打开弹窗,获取用户授权
+					}
+				})
+			},
+
+			// 弹窗点订阅,开启消息订阅提醒
+			openSetting() {
+				if (this.buttonConfirmText == '确定') {
+					this.messageSubscription()
+					return
+				}
+
+				var that = this
+				uni.openSetting({
+					withSubscriptions: true,
+					complete(res) {
+						uni.getSetting({
+							withSubscriptions: true,
+							success(res) {
+								if (res.subscriptionsSetting.mainSwitch) { // 订阅消息的总开关,如果是开着的
+									that.tipsContent = '再次点击确定,弹出可订阅列表进行订阅'
+									that.buttonCancelText = '取消'
+									that.buttonConfirmText = '确定'
+								} else {
+									that.showOpenSettingDialog = false;
+								}
+							}
+						})
+					}
+				})
+			},
+			getUser() {
+				uni.getUserProfile({
+					desc: "获取你的昵称、头像信息", //必填项,声明获取用户个人信息后的用途,不超过30个字符
+					success: (res) => {
+						const userInfo = res.userInfo;
+						console.log("用户基本信息", userInfo);
+					},
+					fail: (res) => {
+						//拒绝授权
+						wx.showToast({
+							title: "获取失败",
+							icon: "error",
+							duration: 2000,
+						});
+						return;
+					},
+				});
+
+			},
+			// 弹窗点不订阅
+			dontOpenSetting() {
+				this.showOpenSettingDialog = false;
+			},
+
+			// 订阅申请弹出,只允许点击弹出
+			messageSubscription() {
+				this.tipsContent = '为了及时掌握订单状态,您是否想接收订单状态的消息提醒?' // 弹框提示内容,
+				this.buttonConfirmText = '去开启消息提醒'
+				this.buttonCancelText = '不需要提醒'
+				let that = this
+				that.showOpenSettingDialog = false;
+				let tmplId = ['2nFR6OXrC7d6w3ZkqaLsKjXYBQB3k78xzRvQoPacfKA']
+				// let tmplId = ['qgp7iG6xTRm4JewW8N46nXJT-E6xorFn2hZ2V7gD8wY']
+				// 'Toomi1XWGMzNxOCoPX1rRNj7gLuykgszEzUstXaAp9c', 'CdLBnE4unNbHlQikYoGHehagWZAK8gSGu52QCbAesLIQUE'
+				// 模板ID,去小程序后台管理开一个,写进数组里,官方文档也有介绍
+				uni.requestSubscribeMessage({
+					tmplIds: tmplId,
+					success(res) {
+						console.log("success", res)
+						// if (res['qgp7iG6xTRm4JewW8N46nXJT-E6xorFn2hZ2V7gD8wY'] == 'accept') {
+						console.log('订阅成功');
+						// }
+					}
+				})
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped></style>

+ 364 - 0
pageA/msg/userMsgList.vue

@@ -0,0 +1,364 @@
+<template>
+	<view>
+		<!-- paddingTop不生效可换成marginTop -->
+		<view class="tab_title" :style="{ paddingTop: statusBarHeight}">
+			<!-- 左上角自定义样式 -->
+			<view class="menu_btn flex-betwee box-sizing"
+				:style="{ position: 'fixed', top: menuTop, left: menuRight, width: menuWidth, height: menuHeight, borderRadius: menuBorderRadius}">
+				<!-- <image class="logo" src="/static/logo.png" @click="goStepPage"></image> -->
+				<uni-row>
+					<uni-col :span="8">
+						<view @click="leftBack">
+							<u-icon name="arrow-left" size="30" color="rgb(138, 138, 138)">
+							</u-icon>
+						</view>
+					</uni-col>
+					<uni-col :span="16">
+						<view class="tit" @click="confirm">全部已读</view>
+					</uni-col>
+				</uni-row>
+			</view>
+		</view>
+		<scroll-list :style="{ paddingTop: statusBarHeight}" ref="list" :option="option" @load="load" @refresh="refresh"
+			@loadSuccess="loadSuccess" @scrolltolower="scrolltolower">
+			<view v-for="(item, index) in list" :key="index" @click="handleTest(item)">
+				<view class="infoBody">
+					<view>
+						<view style="border-bottom: 1px #b8b8b8 solid;">
+							<uni-row class="demo-uni-row">
+								<uni-col :span="19">
+									<view class="demo-uni-col dark"
+										style="font-size: 36rpx;margin: -20rpx 0 0 0;font-weight: bold;letter-spacing:5rpx;">
+										{{item.msgTitle}}
+									</view>
+								</uni-col>
+								<uni-col v-if="item.msgIsRead === '0'" :span="5">
+									<view class="demo-uni-col light"
+										style="color: rgb(55,186,189);margin-bottom: 10rpx;">
+										点击查看
+									</view>
+								</uni-col>
+							</uni-row>
+						</view>
+						<uni-row class="demo-uni-row">
+							<uni-col>
+								<view class="demo-uni-col light" style="padding: 36rpx;color: #676767;">
+									<view v-html="item.msgContent"></view>
+								</view>
+							</uni-col>
+						</uni-row>
+						<uni-row class="demo-uni-row">
+							<uni-col :span="24">
+								<view class="demo-uni-col light" style="color: #727272;">
+									{{item.createTime}}
+								</view>
+							</uni-col>
+						</uni-row>
+					</view>
+				</view>
+			</view>
+		</scroll-list>
+	</view>
+</template>
+<style lang="scss">
+	.page-wrap {}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 40rpx;
+		border-radius: 20rpx;
+		margin: 20rpx;
+		box-shadow: 0px 2px 10px #cccccc;
+	}
+
+	.tit {
+		margin: 0 10rpx;
+		text-align: center;
+		color: #999999;
+		border: 1px #cccccc solid;
+		border-radius: 20rpx;
+	}
+
+	.tit:active {
+		background: #d4d4d4;
+	}
+
+	.box-sizing {
+		box-sizing: border-box;
+	}
+
+	.index-page {
+		width: 100vw;
+		height: calc(100vh - 64px); // 解决页面无内容时上下滚动问题 高度默认44px + padding-top 20px
+		// padding: 32rpx;
+
+		.tab_title {
+			width: 100%;
+			height: 44px !important; //这个是固定的44px(所有小程序顶部高度都是 = 44px + 手机系统状态栏高度)
+			line-height: 44px;
+			text-align: center;
+			// background-color: #d00;
+			background-color: #f8f8f8 !important;
+			position: fixed;
+			top: 0;
+			z-index: 9999;
+			color: #000;
+			font-weight: 500;
+
+			.menu_btn {
+				width: 414rpx !important;
+				// background-color: #ffffff; //这个是小程序默认的标题栏背景色
+				overflow: hidden;
+
+			}
+		}
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				msgTypes: uni.getStorageSync('app_msg_type'),
+				page: 1,
+				list: [],
+				scrollList: [],
+				total: 0,
+				status: '',
+				tabType: uni.getStorageSync('tabType'),
+				file_approval_flow_run_key: '',
+				biz_leave_flow_run_key: '',
+				reserve_consuming_flow_run_key: '',
+				reserve_return_flow_run_key: '',
+				reserve_register_flow_run_key: '',
+				personnel_hire_approval_flow_run_key: '',
+				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight, //状态栏的高度(可以设置为顶部导航条的padding-top)
+				menuWidth: uni.getStorageSync('menuInfo').menuWidth,
+				menuHeight: uni.getStorageSync('menuInfo').menuHeight,
+				menuBorderRadius: uni.getStorageSync('menuInfo').menuBorderRadius,
+				menuRight: uni.getStorageSync('menuInfo').menuRight,
+				menuTop: uni.getStorageSync('menuInfo').menuTop,
+				contentTop: uni.getStorageSync('menuInfo').contentTop
+
+			}
+		},
+		onLoad() {
+			this.file_approval_flow_run_key = uni.getStorageSync('file_approval_flow_run_key')
+			this.biz_leave_flow_run_key = uni.getStorageSync('biz_leave_flow_run_key')
+			this.reserve_consuming_flow_run_key = uni.getStorageSync('reserve_consuming_flow_run_key')
+			this.reserve_return_flow_run_key = uni.getStorageSync('reserve_return_flow_run_key')
+			this.reserve_register_flow_run_key = uni.getStorageSync('reserve_register_flow_run_key')
+			this.personnel_hire_approval_flow_run_key = uni.getStorageSync('personnel_hire_approval_flow_run_key')
+			this.personnel_dimission_approval_flow_run_key = uni.getStorageSync(
+				'personnel_dimission_approval_flow_run_key')
+		},
+		onShow() {
+			this.$refs.list.refresh()
+		},
+		methods: {
+			leftBack() {
+				uni.navigateBack()
+			},
+			confirm() {
+				this.$httpRequest({
+					url: '/app/doAllRead',
+					method: 'get',
+					urlType: this.$getUrlType()
+				}).then(res => {
+					this.$refs.list.refresh()
+				})
+			},
+			handleTest(item) {
+				this.readTask(item)
+				if (this.tabType === 2) {
+					if (item.msgType === '1') {
+						this.orderInfo(item.remark, 1, '1')
+					}
+					if (item.msgType === '2') {
+						this.orderInfo(item.remark, 1, '2')
+					}
+					if (item.msgType === '3') {
+						uni.navigateTo({
+							url: "../salary/salary"
+						})
+					}
+				} else if (this.tabType === 3) {
+					if (item.msgType) {
+						if (item.msgType === '1') {
+							this.gtdToId(item.remark, 1, '1')
+						}
+						if (item.msgType === '2') {
+							uni.switchTab({
+								url: "/pages/orderFood/index"
+							})
+						}
+						if (item.msgType === '3') {
+							uni.navigateTo({
+								url: "../salary/salary"
+							})
+						}
+						if (item.msgType === '4') {
+							this.gtdToId(item.remark, 3, '4')
+						}
+						if (item.msgType === '5') {
+							this.gtdToId(item.remark, 1, '5')
+						}
+						if (item.msgType === '6') {
+							this.orderInfo(item.remark, 1, '6')
+						}
+						if (item.msgType === '7') {
+							this.gtdToId(item.remark, 3, '7')
+						}
+					}
+				}
+			},
+			async gtdToId(id, pageType, msgType) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/gtdToId?taskId=' + id + '&type=' + msgType,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (res.data[0]) {
+						res.data[0].pageType = pageType
+						uni.setStorageSync("approval", res.data[0])
+						if (res.data[0].examplesId === this.file_approval_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geNewsApproval"
+							})
+						} else if (res.data[0].examplesId === this.biz_leave_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geApproval"
+							})
+						} else if (res.data[0].examplesId === this.reserve_consuming_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geReserveApproval"
+							})
+						} else if (res.data[0].examplesId === this.reserve_return_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geReserveApproval"
+							})
+						} else if (res.data[0].examplesId === this.reserve_register_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geReserveApproval"
+							})
+						} else if (res.data[0].examplesId === this.personnel_hire_approval_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geEntry"
+							})
+						} else if (res.data[0].examplesId === this.personnel_dimission_approval_flow_run_key) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geDimission"
+							})
+						} else if (res.data[0].examplesId === uni.getStorageSync(
+								'device_repairs_approval_flow_run_key')) {
+							uni.navigateTo({
+								url: "../../pageApp/ge/geDeviceRepairs"
+							})
+						}
+						uni.hideLoading({
+							mask: true
+						})
+					}
+				}
+			},
+			async orderInfo(id, pageType, msgType) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/orderInfo?on=' + id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (res.data) {
+						uni.setStorageSync("order", res.data)
+						if (msgType === '1') {
+							uni.navigateTo({
+								url: "../card/expense/details"
+							})
+						} else if (msgType === '2') {
+							uni.navigateTo({
+								url: "../card/orderProcess"
+							})
+						} else if (msgType === '6') {
+							uni.navigateTo({
+								url: "../integral/details"
+							})
+						}
+						uni.hideLoading({
+							mask: true
+						})
+					}
+				}
+			},
+			async readTask(item) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/rm?id=' + item.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					let msgData = uni.getStorageSync("msgData")
+					if (msgData) {
+						if (msgData["m" + item.msgType] > 0) {
+							--msgData["m" + item.msgType];
+							uni.setStorageSync("msgData", msgData)
+						}
+					}
+				}
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/gum?pageNum=' + paging.page + '&pageSize=' + paging.size,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (paging.page === 1) {
+						this.scrollList = res.rows
+						this.total = res.total
+						this.$refs.list.loadSuccess({
+							list: res.rows,
+							total: this.total
+						});
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							this.scrollList.push(res.rows[i])
+						}
+						this.$refs.list.loadSuccess({
+							list: this.scrollList,
+							total: this.total
+						});
+					}
+				}
+			},
+			// 刷新刷剧
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {
+
+			},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>

+ 172 - 0
pageA/msg/visitingCard.vue

@@ -0,0 +1,172 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="20">
+						<view class="desc">
+							头像
+						</view>
+					</uni-col>
+					<uni-col :span="4">
+						<view>
+							<view class="desc">
+								<image v-if="data.imgSrc" class="desc_img" :src="BaseUrl+data.imgSrc"></image>
+								<view v-else class="desc_img img_alt_text">无</view>
+							</view>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc">
+							姓名
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="desc descContent">
+							<u-text :text="data.userName" size="18" color="#a3a3a3"></u-text>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc">
+							部门
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="desc descContent">
+							<u-text :text="data.department" size="18" color="#a3a3a3"></u-text>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc">
+							岗位
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="desc descContent">
+							<u-text :text="data.post" size="18" color="#a3a3a3"></u-text>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc">
+							手机号
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="desc">
+							<u-text mode="phone" :text="data.phone" size="18" call="true" color="#45a5ff"></u-text>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc">
+							座机号
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="desc descContent">
+							<u-text :text="data.seatNo" size="18" color="#a3a3a3"></u-text>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc item_border">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc">
+							邮箱
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="desc descContent">
+							<u-text mode="text" :text="data.email" size="18" color="#a3a3a3" align="right"></u-text>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: {},
+				BaseUrl: this.$BASE_URL
+			}
+		},
+		onLoad() {},
+		onShow() {
+			this.getVisitingCard()
+		},
+		methods: {
+			async getVisitingCard() {
+				console.log(uni.getStorageSync('data'))
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/getOpfInfo?opfUserPhone=' + uni.getStorageSync('data').phone,
+					method: 'get'
+				})
+				if (res.code == 200) {
+					this.data = res.data
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+				}
+			}
+		}
+	}
+</script>
+<style>
+	.desc {
+		padding: 15rpx 5rpx;
+		font-size: 35rpx;
+		color: #838383;
+	}
+
+	.descContent {
+		color: #a3a3a3;
+		text-align: right;
+	}
+
+	.item_border {
+		border-bottom: 1px solid #eeeeee;
+	}
+
+	.desc_img {
+		width: 100rpx;
+		height: 100rpx;
+		border: 2rpx solid #dadada;
+		border-radius: 20rpx;
+	}
+
+	.img_alt_text {
+		color: #dadada;
+		line-height: 95rpx;
+		font-size: 35rpx;
+		align-items: center;
+	}
+</style>

+ 53 - 0
pageA/notice/notice.vue

@@ -0,0 +1,53 @@
+<template>
+	<view>
+		<view style="padding: 10px;margin: 0 auto;">{{$dateResult(item.createTime, 'datetime')}}</view>
+		<view v-if="data.type === 1" style="padding: 10px 15px 0;" v-html="data.noticeContent"></view>
+		<view v-if="data.type === 2" style="padding: 10px 15px 0;" v-html="data.link"></view>
+		<view style="height: 40rpx;"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: uni.getStorageSync("noticeData")
+			}
+		},
+		onShow() {
+			console.log(this.data)
+			if (this.data.noticeContent) {
+				this.data.noticeContent = this.data.noticeContent.replace(/<img/g,
+					"<img style='max-width:100%;height:auto;'");
+			}
+			if (this.data.link) {
+				this.data.link = this.data.link.replace(/<img/g,
+					"<img style='max-width:100%;height:auto;'");
+			}
+			if (this.data.noticeTitle) {
+				uni.setNavigationBarTitle({
+					title: this.data.noticeTitle
+				})
+			}
+			if (this.data.text) {
+				uni.setNavigationBarTitle({
+					title: this.data.text
+				})
+			}
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.product-content {
+		width: 95%;
+		padding: 20rpx 20rpx 0 20px;
+	}
+
+	page {
+		font-size: 30rpx;
+	}
+</style>

+ 63 - 0
pageA/officefile/index.vue

@@ -0,0 +1,63 @@
+<template>
+	<view>
+		<button @click="previewFile">预览文件</button>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			previewFile() {
+				uni.showLoading({
+					title: '加载中'
+				})
+
+				uni.downloadFile({
+					url: "http://114.115.142.166:8087/down/0OR9jtcjJHMj.xlsx", //后端返回的文件地址
+					filePath: wx.env.USER_DATA_PATH + '/gwy.xls',
+					// filePath: wx.env.USER_DATA_PATH + '/' + item.name + '.' + item.value.split('.')[item.value.split('.').length - 1],
+					success: function(res) {
+						if (res.statusCode === 200) {
+							uni.openDocument({
+								showMenu: true,
+								filePath: res.filePath,
+								success: function(res) {
+									console.log(res, '打开文件成功')
+								},
+								fail: (err) => {
+									uni.showToast({
+										title: '打开文件失败请重试',
+										icon: 'none'
+									})
+								}
+							})
+						} else {
+							uni.showToast({
+								title: '打开文件失败请重试',
+								icon: 'none'
+							})
+						}
+						uni.hideLoading()
+					},
+					fail: (err) => {
+						uni.hideLoading()
+						uni.showToast({
+							title: '加载失败请重试',
+							icon: "none"
+						})
+					}
+				})
+
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 357 - 0
pageA/psq/dayForm.vue

@@ -0,0 +1,357 @@
+<template>
+	<view class="wrapper" style="padding: 30px">
+		<div class="header">
+			<div>
+				<h2 v-if="!isOffDuty">每日上岗</h2>
+			</div>
+			<div style="position: absolute;padding: 5px 20px;font-size: 15px;color: rgba(0,0,0,0.39);
+      right: 10px;top:10px;border: 1px solid rgba(0,0,0,0.39);border-radius: 10px">
+				<span>{{form.orgName}}</span>
+			</div>
+		</div>
+		<view class="main">
+			<view>
+				<text class="u-block__title" style="font-size: 18px;">{{1+'.'+text[0].label}}</text>
+				<view class="u-demo-block__content" style="padding: 15px;">
+					<view class="u-page__radio-item">
+						<u-radio-group v-model="form.queResults[0]" placement="column" activeColor="#73a6a4">
+							<u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in text[0].resultList"
+								:key="item.id" :label="item.value" :name="item.value" size="25">
+							</u-radio>
+						</u-radio-group>
+					</view>
+				</view>
+				<view>
+				</view>
+				<view class="uni-list" v-if="form.queResults[0] === '是'">
+					<view class="uni-list-cell">
+						<view class="uni-list-cell-left">
+							<span style="font-size: 16px;color: #acacac;">
+								开始时间:
+							</span>
+						</view>
+						<view class="uni-list-cell-db">
+							<view class="example-body">
+								<uni-datetime-picker type="datetime" :border="false" :clear-icon="false"
+									return-type="timestamp" :start="Date.now()" v-model="form.vacateStartTime" />
+							</view>
+							<!-- <picker mode="date" :value="form.vacateStartTime" :start="startDate" :end="endDate"
+								@change="bindStartDateChange">
+								<view class="uni-input">{{form.vacateStartTime}}</view>
+							</picker> -->
+						</view>
+					</view>
+					<view class="uni-list-cell">
+						<view class="uni-list-cell-left">
+							<span style="font-size: 16px;color: #acacac;">
+								结束时间:
+							</span>
+						</view>
+						<view class="uni-list-cell-db">
+							<view class="example-body">
+								<uni-datetime-picker type="datetime" :border="false" :clear-icon="false"
+									return-type="timestamp" :start="Date.now()" v-model="form.vacateEndTime" />
+							</view>
+							<!-- <picker mode="date" :value="form.vacateEndTime" :start="startDate" :end="endDate"
+								@change="bindEndDateChange">
+								<view class="uni-input">{{form.vacateEndTime}}</view>
+							</picker> -->
+						</view>
+					</view>
+				</view>
+			</view>
+			<view>
+				<text class="u-block__title" style="font-size: 18px;">{{1+'.'+text[1 ].label}}</text>
+				<view class="u-demo-block__content" style="padding: 15px;">
+					<view class="u-page__radio-item">
+						<u-radio-group v-model="form.queResults[1]" placement="column" activeColor="#73a6a4">
+							<u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in text[1].resultList"
+								:key="item.id" :label="item.value" :name="item.value" size="25">
+							</u-radio>
+						</u-radio-group>
+					</view>
+				</view>
+			</view>
+			<view>
+				<text class="u-block__title" style="font-size: 18px;">{{1+'.'+text[2].label}}</text>
+				<view class="u-demo-block__content" style="padding: 15px;">
+					<view class="u-page__radio-item">
+						<u-radio-group v-model="form.queResults[2]" placement="column" activeColor="#73a6a4">
+							<u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in text[2].resultList"
+								:key="item.id" :label="item.value" :name="item.value" size="25">
+							</u-radio>
+						</u-radio-group>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<u-button v-if="!isOffDuty" type="success" @click="submit" color="#73a6a4" :disabled="disabled">
+				上班提交
+			</u-button>
+			<view v-if="isOffDuty" style="">
+				<u-text text="说明:"></u-text>
+				<view style="border: 1px solid #d5d5d5; margin:5px 0 50px 0;">
+					<u-textarea v-model="form.remark" placeholder="请输入内容" count></u-textarea>
+				</view>
+				<u-button style="font-size: 24px;" type="success" @click="submit" color="#73a6a4" :disabled="disabled">
+					下班打卡
+				</u-button>
+			</view>
+		</view>
+		<view class="uni-fixed-bottom">
+			<div style="margin-bottom: 5px;">
+				<u-row>
+					<u-col span="5">
+						<u-text text="技术支持:会山科技" color="#cacaca">
+						</u-text>
+					</u-col>
+					<u-col span="2">
+						<div></div>
+					</u-col>
+					<u-col span="5">
+						<u-text text="hs@willalp.com" color="#cacaca">
+						</u-text>
+					</u-col>
+				</u-row>
+			</div>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "form",
+		data() {
+			const currentDate = this.getDate({
+				format: true
+			})
+			return {
+				text: [{
+					"id": "1509390250483634177",
+					"label": "是否请假",
+					"prop": "queResultText1",
+					"resultList": [{
+							"value": "是",
+							"id": "1"
+						},
+						{
+							"value": "否",
+							"id": "2"
+						}
+					]
+				}, {
+					"id": "1519272021753278466",
+					"label": "是否晚班",
+					"prop": "queResultText2",
+					"resultList": [{
+							"value": "是",
+							"id": "1"
+						},
+						{
+							"value": "否",
+							"id": "2"
+						}
+					]
+				}, {
+					"id": "1523961554814062594",
+					"label": "是否被管控",
+					"prop": "queResultText3",
+					"resultList": [{
+							"value": "是",
+							"id": "1"
+						},
+						{
+							"value": "否",
+							"id": "2"
+						}
+					]
+				}],
+				queDbList: [],
+				disabled: false,
+				isOffDuty: false,
+				form: {
+					userName: '',
+					userNo: '',
+					orgNo: '',
+					orgName: '',
+					clockInType: 0,
+					vacateStartTime: '',
+					vacateEndTime: '',
+					remark: '',
+					queResults: [],
+					ques: []
+				}
+			}
+		},
+		computed: {
+			startDate() {
+				return this.getDate('start');
+			},
+			endDate() {
+				return this.getDate('end');
+			}
+		},
+		onLoad() {
+			const userInfo = uni.getStorageSync('userInfo');
+			const orgInfo = uni.getStorageSync('orgInfo');
+			this.form.userName = userInfo.nickName
+			this.form.userNo = userInfo.userName
+			this.form.orgNo = orgInfo.organizationCode
+			this.form.orgName = orgInfo.organizationName
+			//是否打卡
+			this.isClockingIn()
+		},
+		created() {
+			this.getList()
+		},
+		methods: {
+			bindStartDateChange: function(e) {
+				this.form.vacateStartTime = e.detail.value
+			},
+			bindEndDateChange: function(e) {
+				this.form.vacateEndTime = e.detail.value
+			},
+			getDate(type) {
+				const date = new Date();
+				let year = date.getFullYear();
+				let month = date.getMonth() + 1;
+				let day = date.getDate();
+
+				if (type === 'start') {
+					year = year - 60;
+				} else if (type === 'end') {
+					year = year + 2;
+				}
+				month = month > 9 ? month : '0' + month;
+				day = day > 9 ? day : '0' + day;
+				return `${year}-${month}-${day}`;
+			},
+			async getQueList() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/yq/list?queGroupId=' + 2,
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.queDbList = res.data
+					this.queDbList.forEach(q => {
+						this.form.ques.push(q.id)
+					})
+				} else {
+
+				}
+			},
+			async save() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					method: 'POST',
+					url: '/api/ci/clocking/in',
+					data: this.form
+				})
+				if (res.code == 200) {
+					uni.showToast({
+						title: res.msg,
+						icon: 'success'
+					})
+					setTimeout(() => {
+						location.reload()
+					}, 1000)
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: "none"
+					})
+				}
+			},
+			async isClockingIn() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					method: 'POST',
+					url: '/api/ci/clocking/info',
+					data: this.form
+				})
+				if (res.code == 200) {
+					if (undefined !== res.data) {
+						console.log("not null")
+						this.isOffDuty = true
+						this.form.clockInType = 5
+					}
+				} else {
+
+				}
+			},
+			getList() {
+				this.getQueList();
+			},
+			submit() {
+				this.disabled = true
+				console.log(this.form.vacateStartTime)
+				if (this.form.vacateStartTime > this.form.vacateEndTime) {
+					uni.showToast({
+						title: '结束时间小于开始时间',
+						icon: 'none'
+					})
+					this.disabled = false
+					return;
+				}
+				this.save()
+				setTimeout(() => {
+					this.disabled = false
+				}, 2000)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.wrapper {
+		display: flex;
+		flex-direction: column;
+		min-height: 100%;
+	}
+
+	.header {
+		flex: 0;
+		margin-top: 20px;
+	}
+
+	.main {
+		flex: 1;
+		margin: 20px 0;
+	}
+
+	.footer {
+		flex: 0;
+	}
+
+
+	.uni-fixed-bottom {
+		width: 100%;
+		bottom: 0upx;
+		padding: 0upx;
+		position: fixed;
+		background: #FFFFFF;
+		transform: translateZ(0);
+		bottom: env(safe-area-inset-bottom);
+		bottom: constant(safe-area-inset-bottom);
+	}
+
+	.u-page {
+		&__style {
+			font-size: 16px;
+			color: rgb(96, 98, 102);
+			margin-bottom: 20rpx;
+			font-weight: bold;
+		}
+
+		&__title {
+			font-size: 16px;
+			color: rgb(96, 98, 102);
+			margin-bottom: 20rpx;
+		}
+	}
+</style>

+ 199 - 0
pageA/psq/form.vue

@@ -0,0 +1,199 @@
+<template>
+	<view class="wrapper" style="padding: 30px">
+		<div class="header">
+			<div>
+				<h2>防疫调查登记问卷</h2>
+			</div>
+			<div style="position: absolute;padding: 5px 20px;font-size: 15px;color: rgba(0,0,0,0.39);
+      right: 10px;top:10px;border: 1px solid rgba(0,0,0,0.39);border-radius: 10px">
+				<span>{{form.orgName}}</span>
+			</div>
+		</div>
+		<view class="main">
+			<view v-for="(item,index) in queDbList">
+				<text class="u-block__title" style="font-size: 18px;">{{index+1+"."+item.label}}</text>
+				<view class="u-demo-block__content" style="padding: 15px;">
+					<view class="u-page__radio-item">
+						<u-radio-group v-model="form.queResults[index]" placement="column" activeColor="#73a6a4">
+							<u-radio :customStyle="{marginBottom: '8px'}" v-for="item in item.resultList"
+								:key="item.id" :label="item.value" :name="item.value" size="25">
+							</u-radio>
+						</u-radio-group>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view>
+			<u-button type="success" @click="submit" color="#73a6a4" :disabled="disabled">提交</u-button>
+		</view>
+		<view class="uni-fixed-bottom">
+			<div style="margin-bottom: 5px;">
+				<u-row>
+					<u-col span="5">
+						<u-text text="技术支持:会山科技" color="#cacaca">
+						</u-text>
+					</u-col>
+					<u-col span="2">
+						<div></div>
+					</u-col>
+					<u-col span="5">
+						<u-text text="hs@willalp.com" color="#cacaca">
+						</u-text>
+					</u-col>
+				</u-row>
+			</div>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "form",
+		data() {
+			return {
+				queDbList: [],
+				disabled: false,
+				form: {
+					userName: '',
+					userNo: '',
+					orgNo: '',
+					orgName: '',
+					queResults: ['', '', '', '', '', '', ''],
+					ques: []
+				},
+			}
+		},
+		onLoad() {
+			const userInfo = uni.getStorageSync('userInfo');
+			const orgInfo = uni.getStorageSync('orgInfo');
+			this.form.userName = userInfo.nickName
+			this.form.userNo = userInfo.userName
+			this.form.orgNo = orgInfo.organizationCode
+			this.form.orgName = orgInfo.organizationName
+		},
+		created() {
+			this.getList()
+		},
+		methods: {
+			async getQueList() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/yq/list?queGroupId=' + 1,
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.queDbList = res.data
+					this.queDbList.forEach(q => {
+						this.form.ques.push(q.id)
+					})
+				} else {
+
+				}
+			},
+			async save() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					method: 'POST',
+					url: '/api/yq/save',
+					data: this.form
+				})
+				if (res.code == 200) {
+					uni.showToast({
+						title: res.msg,
+						icon: 'success'
+					})
+					setTimeout(() => {
+						location.reload()
+					}, 1000)
+				} else {
+
+				}
+			},
+			getList() {
+				this.getQueList();
+			},
+			submit() {
+				this.disabled = true
+				var message = "";
+				var isOk = false;
+				// var myreg =
+				// 	/^(((13[0-9]{1})|(14[0-9]{1})|(17[0-9]{1})|(15[0-3]{1})|(15[4-9]{1})|(18[0-9]{1})|(199))+\d{8})$/;
+				// if (phone == '') {
+				// 	// console.log("手机号码不能为空");
+				// 	message = "手机号码不能为空!";
+				// 	isOk = true;
+				// } else if (phone.length !== 11) {
+				// 	//console.log("请输入11位手机号码!");
+				// 	message = "请输入11位手机号码!";
+				// 	isOk = true;
+				// } else if (!myreg.test(phone)) {
+				// 	//console.log("请输入有效的手机号码!");
+				// 	message = "请输入有效的手机号码!";
+				// 	isOk = true;
+				// }
+				if (isOk) {
+					uni.showToast({
+						title: message,
+						icon: 'error'
+					})
+					return;
+				}
+				this.save()
+				setTimeout(() => {
+					this.disabled = false
+				}, 2000)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.wrapper {
+		display: flex;
+		flex-direction: column;
+		min-height: 100%;
+	}
+
+	.header {
+		flex: 0;
+		margin-top: 20px;
+	}
+
+	.main {
+		flex: 1;
+		margin: 20px 0;
+	}
+
+	.footer {
+		flex: 0;
+	}
+
+
+	.uni-fixed-bottom {
+		width: 100%;
+		bottom: 0upx;
+		padding: 0upx;
+		position: fixed;
+		background: #FFFFFF;
+		transform: translateZ(0);
+		bottom: env(safe-area-inset-bottom);
+		bottom: constant(safe-area-inset-bottom);
+	}
+
+	.u-page {
+		&__style {
+			font-size: 16px;
+			color: rgb(96, 98, 102);
+			margin-bottom: 20rpx;
+			font-weight: bold;
+		}
+
+		&__title {
+			font-size: 16px;
+			color: rgb(96, 98, 102);
+			margin-bottom: 20rpx;
+		}
+	}
+</style>

+ 77 - 0
pageA/salary/salary.vue

@@ -0,0 +1,77 @@
+<template>
+	<view>
+		<view v-if="null === data || undefined === data" style="text-align: center;padding: 50px 0;">
+			<view>
+				暂无数据
+			</view>
+		</view>
+		<uni-list v-for="item in data">
+			<uni-list-item :clickable="true" @click="toSlipPage(item.data)" :title="item.date"
+				:note="'收入:'+item.fsalary+' 元'" />
+		</uni-list>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: {}
+			}
+		},
+		onLoad() {
+			this.getSalarySlip()
+		},
+		onShow() {
+			this.getSalarySlip()
+		},
+		methods: {
+			toSlipPage(data) {
+				uni.setStorageSync("salarySlipData", data)
+				this.$goto("salarySlip")
+			},
+			async getSalarySlip() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/api/ci/sl/?un=' + uni.getStorageSync("setUserName") + "&oc=" + uni
+						.getStorageSync("orgInfo").organizationCode,
+					method: 'get',
+				})
+				if (res.code == 200) {
+					this.data = res.data
+				} else {
+
+				}
+			},
+			dateResult(time, mode) {
+				const timeFormat = uni.$u.timeFormat
+				switch (mode) {
+					case 'datetime':
+						return timeFormat(time, 'yyyy-mm-dd hh:MM:ss')
+					case 'date':
+						return timeFormat(time, 'yyyy-mm-dd')
+					case 'year-month':
+						return timeFormat(time, 'yyyy-mm')
+					case 'time':
+						return time
+					default:
+						return ''
+				}
+			}
+		}
+	}
+</script>
+
+<style>
+	page {
+		padding: 5rpx;
+	}
+
+	.listBody {}
+
+	.mylist {
+		padding: 5px;
+		border-bottom: 1px solid #ababab;
+	}
+</style>

+ 24 - 0
pageA/salary/salarySlip.vue

@@ -0,0 +1,24 @@
+<template>
+	<view>
+		<uni-list v-for="item in data" style="font-size: 40px;">
+			<uni-list-item :title="item.title" :note="item.value"></uni-list-item>
+		</uni-list>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				data: uni.getStorageSync("salarySlipData")
+			}
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style>
+
+</style>

BIN
pageA/static/img/upload.png


Datei-Diff unterdrückt, da er zu groß ist
+ 36 - 0
pageA/watch-login/css/icon.css


+ 134 - 0
pageA/watch-login/watch-button.vue

@@ -0,0 +1,134 @@
+<template>
+	<view>
+		<!-- 按钮 -->
+		<button 
+			:class="['buttonBorder',!_rotate?'dlbutton':'dlbutton_loading']" 
+			:style="{'background':bgColor, 'color': fontColor}"
+            
+			@click="$emit('click', $event)"
+			@contact="$emit('contact', $event)"
+			@error="$emit('error', $event)"
+			@getphonenumber="$emit('getphonenumber', $event)"
+			@getuserinfo="$emit('getuserinfo', $event)"
+			@launchapp="$emit('launchapp', $event)"
+			@longtap="$emit('longtap', $event)"
+			@opensetting="$emit('opensetting', $event)"
+			@touchcancel="$emit('touchcancel', $event)"
+			@touchend="$emit('touchend', $event)"
+			@touchmove="$emit('touchmove', $event)"
+			@touchstart="$emit('touchstart', $event)"
+		>
+			<view :class="_rotate?'rotate_loop':''">
+				<text v-if="_rotate" class="cuIcon cuIcon-loading1 "></text>
+				<view v-if="!_rotate"><slot name="text">{{ text }}</slot></view>
+			</view>
+		</button>
+	</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			text: String, //显示文本
+			rotate:{
+				//是否启动加载
+				type: [Boolean,String],
+				default: false,
+			}, 
+			bgColor:{
+				//按钮背景颜色
+				type: String,
+				default: "linear-gradient(to right, rgba(0,0,0,0.7), rgba(0,0,0,0.6))",
+			},
+			fontColor:{
+				//按钮字体颜色
+				type: String,
+				default: "#FFFFFF",
+			},
+		},
+		computed:{
+			_rotate() {
+				//处理值
+				return String(this.rotate) !== 'false'
+			},
+		}
+	}
+</script>
+
+<style>
+	@import url("./css/icon.css");
+	
+	button{
+		outline: none;  /* 或者 outline: 0 */
+	}
+	button:after {  
+	    border: none;  
+	}
+	button:focus{
+		outline: none;  /* 或者 outline: 0 */
+	}
+	
+	.dlbutton {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		color: #FFFFFF;
+		font-size: 30rpx;
+		white-space:nowrap;
+		overflow: hidden;
+		width:601rpx;
+		height:100rpx;
+		background:linear-gradient(to right, rgba(0,0,0,0.7), rgba(0,0,0,0.6));
+		box-shadow:0rpx 0rpx 13rpx 0rpx rgba(164,217,228,0.4);
+		border-radius:2.5rem;
+		margin-top: 0rpx;
+	}
+	.dlbutton_loading {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		color: #FFFFFF;
+		font-size: 30rpx;
+		width:100rpx;
+		height:100rpx;
+		background:linear-gradient(to right, rgba(0,0,0,0.7), rgba(0,0,0,0.6));
+		box-shadow:0rpx 0rpx 13rpx 0rpx rgba(164,217,228,0.4);
+		border-radius:2.5rem;
+		margin-top: 0rpx;
+	}
+	.buttonBorder{
+	    border: none ;
+	    border-radius: 2.5rem ;
+	    -webkit-box-shadow: 0 0 60rpx 0 rgba(0,0,0,.2) ;
+	    box-shadow: 0 0 60rpx 0 rgba(0,0,0,.2) ;
+	    -webkit-transition: all 0.4s cubic-bezier(.57,.19,.51,.95);
+	    -moz-transition: all 0.4s cubic-bezier(.57,.19,.51,.95);
+	    -ms-transition: all 0.4s cubic-bezier(.57,.19,.51,.95);
+	    -o-transition: all 0.4s cubic-bezier(.57,.19,.51,.95);
+	    transition: all 0.4s cubic-bezier(.57,.19,.51,.95);
+	}
+	
+	/* 旋转动画 */
+	.rotate_loop{
+		-webkit-transition-property: -webkit-transform;
+	    -webkit-transition-duration: 1s;
+	    -moz-transition-property: -moz-transform;
+	    -moz-transition-duration: 1s;
+	    -webkit-animation: rotate 1s linear infinite;
+	    -moz-animation: rotate 1s linear infinite;
+	    -o-animation: rotate 1s linear infinite;
+	    animation: rotate 1s linear infinite;
+	}
+	@-webkit-keyframes rotate{from{-webkit-transform: rotate(0deg)}
+	    to{-webkit-transform: rotate(360deg)}
+	}
+	@-moz-keyframes rotate{from{-moz-transform: rotate(0deg)}
+	    to{-moz-transform: rotate(359deg)}
+	}
+	@-o-keyframes rotate{from{-o-transform: rotate(0deg)}
+	    to{-o-transform: rotate(359deg)}
+	}
+	@keyframes rotate{from{transform: rotate(0deg)}
+	    to{transform: rotate(359deg)}
+	}
+</style>

+ 205 - 0
pageA/watch-login/watch-input.vue

@@ -0,0 +1,205 @@
+<template>
+	<view class="main-list oBorder" @click="$emit('click', $event)">
+		<!-- 文本框 -->
+		<input class="main-input" :value="value" :type="_type" :focus="_focus" :maxlength="maxlength"
+			:placeholder="placeholder" :password="type==='password'&&!showPassword" :disabled="isDisabled"
+			@input="$emit('input', $event.detail.value)" @blur="$emit('blur', $event)" @focus="$emit('focus', $event)"
+			@longpress="$emit('longpress', $event)" @confirm="$emit('confirm', $event)"
+			@longtap="$emit('longtap', $event)" @touchcancel="$emit('touchcancel', $event)"
+			@touchend="$emit('touchend', $event)" @touchmove="$emit('touchmove', $event)"
+			@touchstart="$emit('touchstart', $event)" />
+		<!-- 是否可见密码 -->
+		<image v-if="_isShowPass&&type==='password'&&!_isShowCode" class="img cuIcon"
+			:class="showPassword?'cuIcon-attention':'cuIcon-attentionforbid'" @tap="showPass"></image>
+		<!-- 倒计时 -->
+		<view v-if="_isShowCode&&!_isShowPass" :class="['vercode',{'vercode-run': second>0}]" @click="setCode">
+			{{ getVerCodeSecond }}
+		</view>
+
+	</view>
+</template>
+
+<script>
+	let _this, countDown;
+	export default {
+		data() {
+			return {
+				showPassword: false, //是否显示明文
+				second: 0, //倒计时
+				isRunCode: false, //是否开始倒计时
+			}
+		},
+		props: {
+			type: String, //类型
+			value: String, //值
+			placeholder: String, //框内提示
+			maxlength: {
+				//最大长度
+				type: [Number, String],
+				default: 20,
+			},
+			isDisabled: false,
+			isShowPass: {
+				//是否显示密码图标(二选一)
+				type: [Boolean, String],
+				default: false,
+			},
+			isShowCode: {
+				//是否显示获取验证码(二选一)
+				type: [Boolean, String],
+				default: false,
+			},
+			codeText: {
+				type: String,
+				default: "获取验证码",
+			},
+			setTime: {
+				//倒计时时间设置
+				type: [Number, String],
+				default: 60,
+			},
+			focus: {
+				//是否聚焦  
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		model: {
+			prop: 'value',
+			event: 'input'
+		},
+		mounted() {
+			_this = this
+			//准备触发
+			this.$on('runCode', (val) => {
+				this.runCode(val);
+			});
+			clearInterval(countDown); //先清理一次循环,避免缓存
+		},
+		methods: {
+			showPass() {
+				//是否显示密码
+				this.showPassword = !this.showPassword
+			},
+			setCode() {
+				//设置获取验证码的事件
+				if (this.isRunCode) {
+					//判断是否开始倒计时,避免重复点击
+					return false;
+				}
+				this.$emit('setCode')
+			},
+			runCode(val) {
+				//开始倒计时
+				if (String(val) == "0") {
+
+					//判断是否需要终止循环
+					this.second = 0; //初始倒计时
+					clearInterval(countDown); //清理循环
+					this.isRunCode = false; //关闭循环状态
+					return false;
+				}
+				if (this.isRunCode) {
+					//判断是否开始倒计时,避免重复点击
+					return false;
+				}
+				this.isRunCode = true
+				this.second = this._setTime //倒数秒数
+
+				let _this = this;
+				countDown = setInterval(function() {
+					_this.second--
+					if (_this.second == 0) {
+						_this.isRunCode = false
+						clearInterval(countDown)
+					}
+				}, 1000)
+			}
+		},
+		computed: {
+			_type() {
+				//处理值
+				const type = this.type
+				return type == 'password' ? 'text' : type
+			},
+			_isShowPass() {
+				//处理值
+				return String(this.isShowPass) !== 'false'
+			},
+			_isShowCode() {
+				//处理值
+				return String(this.isShowCode) !== 'false'
+			},
+			_setTime() {
+				//处理值
+				const setTime = Number(this.setTime)
+				return setTime > 0 ? setTime : 60
+			},
+			_focus() {
+				//处理值  
+				return String(this.focus) !== 'false'
+			},
+			getVerCodeSecond() {
+				//验证码倒计时计算
+				if (this.second <= 0) {
+					return this.codeText;
+				} else {
+					if (this.second < 10) {
+						return '0' + this.second;
+					} else {
+						return this.second;
+					}
+				}
+
+			}
+		}
+	}
+</script>
+
+<style>
+	@import url("./css/icon.css");
+
+	.main-list {
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+		/* height: 36rpx; */
+		/* Input 高度 */
+		color: #333333;
+		padding: 40rpx 32rpx;
+		margin: 32rpx 0;
+	}
+
+	.img {
+		width: 32rpx;
+		height: 52rpx;
+		font-size: 32rpx;
+	}
+
+	.main-input {
+		flex: 1;
+		text-align: left;
+		font-size: 28rpx;
+		/* line-height: 100rpx; */
+		padding-right: 10rpx;
+		margin-left: 20rpx;
+	}
+
+	.vercode {
+		color: rgba(0, 0, 0, 0.7);
+		font-size: 24rpx;
+		/* line-height: 100rpx; */
+	}
+
+	.vercode-run {
+		color: rgba(0, 0, 0, 0.4) !important;
+	}
+
+	.oBorder {
+		border: none;
+		border-radius: 2.5rem;
+		-webkit-box-shadow: 0 0 60rpx 0 rgba(43, 86, 112, .1);
+		box-shadow: 0 0 60rpx 0 rgba(43, 86, 112, .1);
+	}
+</style>

+ 4874 - 0
pageApp/address/data.js

@@ -0,0 +1,4874 @@
+//data.js
+export default [{
+		"name": "北京市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"东城区",
+				"西城区",
+				"崇文区",
+				"宣武区",
+				"朝阳区",
+				"丰台区",
+				"石景山区",
+				"海淀区",
+				"门头沟区",
+				"房山区",
+				"通州区",
+				"顺义区",
+				"昌平区",
+				"大兴区",
+				"平谷区",
+				"怀柔区",
+				"密云县",
+				"延庆县"
+			]
+		}]
+	},
+	{
+		"name": "天津市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"和平区",
+				"河东区",
+				"河西区",
+				"南开区",
+				"河北区",
+				"红桥区",
+				"塘沽区",
+				"汉沽区",
+				"大港区",
+				"东丽区",
+				"西青区",
+				"津南区",
+				"北辰区",
+				"武清区",
+				"宝坻区",
+				"宁河县",
+				"静海县",
+				"蓟 县"
+			]
+		}]
+	},
+	{
+		"name": "河北省",
+		"city": [{
+				"name": "石家庄市",
+				"area": [
+					"长安区",
+					"桥东区",
+					"桥西区",
+					"新华区",
+					"郊 区",
+					"井陉矿区",
+					"井陉县",
+					"正定县",
+					"栾城县",
+					"行唐县",
+					"灵寿县",
+					"高邑县",
+					"深泽县",
+					"赞皇县",
+					"无极县",
+					"平山县",
+					"元氏县",
+					"赵 县",
+					"辛集市",
+					"藁",
+					"晋州市",
+					"新乐市",
+					"鹿泉市"
+				]
+			},
+			{
+				"name": "唐山市",
+				"area": [
+					"路南区",
+					"路北区",
+					"古冶区",
+					"开平区",
+					"新 区",
+					"丰润县",
+					"滦 县",
+					"滦南县",
+					"乐亭县",
+					"迁西县",
+					"玉田县",
+					"唐海县",
+					"遵化市",
+					"丰南市",
+					"迁安市"
+				]
+			},
+			{
+				"name": "秦皇岛市",
+				"area": [
+					"海港区",
+					"山海关区",
+					"北戴河区",
+					"青龙满族自治县",
+					"昌黎县",
+					"抚宁县",
+					"卢龙县"
+				]
+			},
+			{
+				"name": "邯郸市",
+				"area": [
+					"邯山区",
+					"丛台区",
+					"复兴区",
+					"峰峰矿区",
+					"邯郸县",
+					"临漳县",
+					"成安县",
+					"大名县",
+					"涉 县",
+					"磁 县",
+					"肥乡县",
+					"永年县",
+					"邱 县",
+					"鸡泽县",
+					"广平县",
+					"馆陶县",
+					"魏 县",
+					"曲周县",
+					"武安市"
+				]
+			},
+			{
+				"name": "邢台市",
+				"area": [
+					"桥东区",
+					"桥西区",
+					"邢台县",
+					"临城县",
+					"内丘县",
+					"柏乡县",
+					"隆尧县",
+					"任 县",
+					"南和县",
+					"宁晋县",
+					"巨鹿县",
+					"新河县",
+					"广宗县",
+					"平乡县",
+					"威 县",
+					"清河县",
+					"临西县",
+					"南宫市",
+					"沙河市"
+				]
+			},
+			{
+				"name": "保定市",
+				"area": [
+					"新市区",
+					"北市区",
+					"南市区",
+					"满城县",
+					"清苑县",
+					"涞水县",
+					"阜平县",
+					"徐水县",
+					"定兴县",
+					"唐 县",
+					"高阳县",
+					"容城县",
+					"涞源县",
+					"望都县",
+					"安新县",
+					"易 县",
+					"曲阳县",
+					"蠡 县",
+					"顺平县",
+					"博野",
+					"雄县",
+					"涿州市",
+					"定州市",
+					"安国市",
+					"高碑店市"
+				]
+			},
+			{
+				"name": "张家口",
+				"area": [
+					"桥东区",
+					"桥西区",
+					"宣化区",
+					"下花园区",
+					"宣化县",
+					"张北县",
+					"康保县",
+					"沽源县",
+					"尚义县",
+					"蔚 县",
+					"阳原县",
+					"怀安县",
+					"万全县",
+					"怀来县",
+					"涿鹿县",
+					"赤城县",
+					"崇礼县"
+				]
+			},
+			{
+				"name": "承德市",
+				"area": [
+					"双桥区",
+					"双滦区",
+					"鹰手营子矿区",
+					"承德县",
+					"兴隆县",
+					"平泉县",
+					"滦平县",
+					"隆化县",
+					"丰宁满族自治县",
+					"宽城满族自治县",
+					"围场满族蒙古族自治县"
+				]
+			},
+			{
+				"name": "沧州市",
+				"area": [
+					"新华区",
+					"运河区",
+					"沧 县",
+					"青 县",
+					"东光县",
+					"海兴县",
+					"盐山县",
+					"肃宁县",
+					"南皮县",
+					"吴桥县",
+					"献 县",
+					"孟村回族自治县",
+					"泊头市",
+					"任丘市",
+					"黄骅市",
+					"河间市"
+				]
+			},
+			{
+				"name": "廊坊市",
+				"area": [
+					"安次区",
+					"固安县",
+					"永清县",
+					"香河县",
+					"大城县",
+					"文安县",
+					"大厂回族自治县",
+					"霸州市",
+					"三河市"
+				]
+			},
+			{
+				"name": "衡水市",
+				"area": [
+					"桃城区",
+					"枣强县",
+					"武邑县",
+					"武强县",
+					"饶阳县",
+					"安平县",
+					"故城县",
+					"景 县",
+					"阜城县",
+					"冀州市",
+					"深州市"
+				]
+			}
+		]
+	},
+	{
+		"name": "山西省",
+		"city": [{
+				"name": "太原市",
+				"area": [
+					"小店区",
+					"迎泽区",
+					"杏花岭区",
+					"尖草坪区",
+					"万柏林区",
+					"晋源区",
+					"清徐县",
+					"阳曲县",
+					"娄烦县",
+					"古交市"
+				]
+			},
+			{
+				"name": "大同市",
+				"area": [
+					"城 区",
+					"矿 区",
+					"南郊区",
+					"新荣区",
+					"阳高县",
+					"天镇县",
+					"广灵县",
+					"灵丘县",
+					"浑源县",
+					"左云县",
+					"大同县"
+				]
+			},
+			{
+				"name": "阳泉市",
+				"area": [
+					"城 区",
+					"矿 区",
+					"郊 区",
+					"平定县",
+					"盂 县"
+				]
+			},
+			{
+				"name": "长治市",
+				"area": [
+					"城 区",
+					"郊 区",
+					"长治县",
+					"襄垣县",
+					"屯留县",
+					"平顺县",
+					"黎城县",
+					"壶关县",
+					"长子县",
+					"武乡县",
+					"沁 县",
+					"沁源县",
+					"潞城市"
+				]
+			},
+			{
+				"name": "晋城市",
+				"area": [
+					"城 区",
+					"沁水县",
+					"阳城县",
+					"陵川县",
+					"泽州县",
+					"高平市"
+				]
+			},
+			{
+				"name": "朔州市",
+				"area": [
+					"朔城区",
+					"平鲁区",
+					"山阴县",
+					"应 县",
+					"右玉县",
+					"怀仁县"
+				]
+			},
+			{
+				"name": "忻州市",
+				"area": [
+					"忻府区",
+					"原平市",
+					"定襄县",
+					"五台县",
+					"代 县",
+					"繁峙县",
+					"宁武县",
+					"静乐县",
+					"神池县",
+					"五寨县",
+					"岢岚县",
+					"河曲县",
+					"保德县",
+					"偏关县"
+				]
+			},
+			{
+				"name": "吕梁市",
+				"area": [
+					"离石区",
+					"孝义市",
+					"汾阳市",
+					"文水县",
+					"交城县",
+					"兴 县",
+					"临 县",
+					"柳林县",
+					"石楼县",
+					"岚 县",
+					"方山县",
+					"中阳县",
+					"交口县"
+				]
+			},
+			{
+				"name": "晋中市",
+				"area": [
+					"榆次市",
+					"介休市",
+					"榆社县",
+					"左权县",
+					"和顺县",
+					"昔阳县",
+					"寿阳县",
+					"太谷县",
+					"祁 县",
+					"平遥县",
+					"灵石县"
+				]
+			},
+			{
+				"name": "临汾市",
+				"area": [
+					"临汾市",
+					"侯马市",
+					"霍州市",
+					"曲沃县",
+					"翼城县",
+					"襄汾县",
+					"洪洞县",
+					"古 县",
+					"安泽县",
+					"浮山县",
+					"吉 县",
+					"乡宁县",
+					"蒲 县",
+					"大宁县",
+					"永和县",
+					"隰 县",
+					"汾西县"
+				]
+			},
+			{
+				"name": "运城市",
+				"area": [
+					"运城市",
+					"永济市",
+					"河津市",
+					"芮城县",
+					"临猗县",
+					"万荣县",
+					"新绛县",
+					"稷山县",
+					"闻喜县",
+					"夏 县",
+					"绛 县",
+					"平陆县",
+					"垣曲县"
+				]
+			}
+		]
+	},
+	{
+		"name": "内蒙古",
+		"city": [{
+				"name": "呼和浩特市",
+				"area": [
+					"新城区",
+					"回民区",
+					"玉泉区",
+					"郊 区",
+					"土默特左旗",
+					"托克托县",
+					"和林格尔县",
+					"清水河县",
+					"武川县"
+				]
+			},
+			{
+				"name": "包头市",
+				"area": [
+					"东河区",
+					"昆都伦区",
+					"青山区",
+					"石拐矿区",
+					"白云矿区",
+					"郊 区",
+					"土默特右旗",
+					"固阳县",
+					"达尔罕茂明安联合旗"
+				]
+			},
+			{
+				"name": "乌海市",
+				"area": [
+					"海勃湾区",
+					"海南区",
+					"乌达区"
+				]
+			},
+			{
+				"name": "赤峰市",
+				"area": [
+					"红山区",
+					"元宝山区",
+					"松山区",
+					"阿鲁科尔沁旗",
+					"巴林左旗",
+					"巴林右旗",
+					"林西县",
+					"克什克腾旗",
+					"翁牛特旗",
+					"喀喇沁旗",
+					"宁城县",
+					"敖汉旗"
+				]
+			},
+			{
+				"name": "呼伦贝尔市",
+				"area": [
+					"海拉尔市",
+					"满洲里市",
+					"扎兰屯市",
+					"牙克石市",
+					"根河市",
+					"额尔古纳市",
+					"阿荣旗",
+					"莫力达瓦达斡尔族自治旗",
+					"鄂伦春自治旗",
+					"鄂温克族自治旗",
+					"新巴尔虎右旗",
+					"新巴尔虎左旗",
+					"陈巴尔虎旗"
+				]
+			},
+			{
+				"name": "兴安盟",
+				"area": [
+					"乌兰浩特市",
+					"阿尔山市",
+					"科尔沁右翼前旗",
+					"科尔沁右翼中旗",
+					"扎赉特旗",
+					"突泉县"
+				]
+			},
+			{
+				"name": "通辽市",
+				"area": [
+					"科尔沁区",
+					"霍林郭勒市",
+					"科尔沁左翼中旗",
+					"科尔沁左翼后旗",
+					"开鲁县",
+					"库伦旗",
+					"奈曼旗",
+					"扎鲁特旗"
+				]
+			},
+			{
+				"name": "锡林郭勒盟",
+				"area": [
+					"二连浩特市",
+					"锡林浩特市",
+					"阿巴嘎旗",
+					"苏尼特左旗",
+					"苏尼特右旗",
+					"东乌珠穆沁旗",
+					"西乌珠穆沁旗",
+					"太仆寺旗",
+					"镶黄旗",
+					"正镶白旗",
+					"正蓝旗",
+					"多伦县"
+				]
+			},
+			{
+				"name": "乌兰察布盟",
+				"area": [
+					"集宁市",
+					"丰镇市",
+					"卓资县",
+					"化德县",
+					"商都县",
+					"兴和县",
+					"凉城县",
+					"察哈尔右翼前旗",
+					"察哈尔右翼中旗",
+					"察哈尔右翼后旗",
+					"四子王旗"
+				]
+			},
+			{
+				"name": "伊克昭盟",
+				"area": [
+					"东胜市",
+					"达拉特旗",
+					"准格尔旗",
+					"鄂托克前旗",
+					"鄂托克旗",
+					"杭锦旗",
+					"乌审旗",
+					"伊金霍洛旗"
+				]
+			},
+			{
+				"name": "巴彦淖尔盟",
+				"area": [
+					"临河市",
+					"五原县",
+					"磴口县",
+					"乌拉特前旗",
+					"乌拉特中旗",
+					"乌拉特后旗",
+					"杭锦后旗"
+				]
+			},
+			{
+				"name": "阿拉善盟",
+				"area": [
+					"阿拉善左旗",
+					"阿拉善右旗",
+					"额济纳旗"
+				]
+			}
+		]
+	},
+	{
+		"name": "辽宁省",
+		"city": [{
+				"name": "沈阳市",
+				"area": [
+					"沈河区",
+					"皇姑区",
+					"和平区",
+					"大东区",
+					"铁西区",
+					"苏家屯区",
+					"东陵区",
+					"于洪区",
+					"新民市",
+					"法库县",
+					"辽中县",
+					"康平县",
+					"新城子区"
+				]
+			},
+			{
+				"name": "大连市",
+				"area": [
+					"西岗区",
+					"中山区",
+					"沙河口区",
+					"甘井子区",
+					"旅顺口区",
+					"金州区",
+					"瓦房店市",
+					"普兰店市",
+					"庄河市",
+					"长海县"
+				]
+			},
+			{
+				"name": "鞍山市",
+				"area": [
+					"铁东区",
+					"铁西区",
+					"立山区",
+					"千山区",
+					"海城市",
+					"台安县",
+					"岫岩满族自治县"
+				]
+			},
+			{
+				"name": "抚顺市",
+				"area": [
+					"顺城区",
+					"新抚区",
+					"东洲区",
+					"望花区",
+					"抚顺县",
+					"清原满族自治县",
+					"新宾满族自治县"
+				]
+			},
+			{
+				"name": "本溪市",
+				"area": [
+					"平山区",
+					"明山区",
+					"溪湖区",
+					"南芬区",
+					"本溪满族自治县",
+					"桓仁满族自治县"
+				]
+			},
+			{
+				"name": "丹东市",
+				"area": [
+					"振兴区",
+					"元宝区",
+					"振安区",
+					"东港市",
+					"凤城市",
+					"宽甸满族自治县"
+				]
+			},
+			{
+				"name": "锦州市",
+				"area": [
+					"太和区",
+					"古塔区",
+					"凌河区",
+					"凌海市",
+					"黑山县",
+					"义县",
+					"北宁市"
+				]
+			},
+			{
+				"name": "营口市",
+				"area": [
+					"站前区",
+					"西市区",
+					"鲅鱼圈区",
+					"老边区",
+					"大石桥市",
+					"盖州市"
+				]
+			},
+			{
+				"name": "阜新市",
+				"area": [
+					"海州区",
+					"新邱区",
+					"太平区",
+					"清河门区",
+					"细河区",
+					"彰武县",
+					"阜新蒙古族自治县"
+				]
+			},
+			{
+				"name": "辽阳市",
+				"area": [
+					"白塔区",
+					"文圣区",
+					"宏伟区",
+					"太子河区",
+					"弓长岭区",
+					"灯塔市",
+					"辽阳县"
+				]
+			},
+			{
+				"name": "盘锦",
+				"area": [
+					"双台子区",
+					"兴隆台区",
+					"盘山县",
+					"大洼县"
+				]
+			},
+			{
+				"name": "铁岭市",
+				"area": [
+					"银州区",
+					"清河区",
+					"调兵山市",
+					"开原市",
+					"铁岭县",
+					"昌图县",
+					"西丰县"
+				]
+			},
+			{
+				"name": "朝阳市",
+				"area": [
+					"双塔区",
+					"龙城区",
+					"凌源市",
+					"北票市",
+					"朝阳县",
+					"建平县",
+					"喀喇沁左翼蒙古族自治县"
+				]
+			},
+			{
+				"name": "葫芦岛市",
+				"area": [
+					"龙港区",
+					"南票区",
+					"连山区",
+					"兴城市",
+					"绥中县",
+					"建昌县"
+				]
+			}
+		]
+	},
+	{
+		"name": "吉林省",
+		"city": [{
+				"name": "长春市",
+				"area": [
+					"朝阳区",
+					"宽城区",
+					"二道区",
+					"南关区",
+					"绿园区",
+					"双阳区",
+					"九台市",
+					"榆树市",
+					"德惠市",
+					"农安县"
+				]
+			},
+			{
+				"name": "吉林市",
+				"area": [
+					"船营区",
+					"昌邑区",
+					"龙潭区",
+					"丰满区",
+					"舒兰市",
+					"桦甸市",
+					"蛟河市",
+					"磐石市",
+					"永吉县"
+				]
+			},
+			{
+				"name": "四平",
+				"area": [
+					"铁西区",
+					"铁东区",
+					"公主岭市",
+					"双辽市",
+					"梨树县",
+					"伊通满族自治县"
+				]
+			},
+			{
+				"name": "辽源市",
+				"area": [
+					"龙山区",
+					"西安区",
+					"东辽县",
+					"东丰县"
+				]
+			},
+			{
+				"name": "通化市",
+				"area": [
+					"东昌区",
+					"二道江区",
+					"梅河口市",
+					"集安市",
+					"通化县",
+					"辉南县",
+					"柳河县"
+				]
+			},
+			{
+				"name": "白山市",
+				"area": [
+					"八道江区",
+					"江源区",
+					"临江市",
+					"靖宇县",
+					"抚松县",
+					"长白朝鲜族自治县"
+				]
+			},
+			{
+				"name": "松原市",
+				"area": [
+					"宁江区",
+					"乾安县",
+					"长岭县",
+					"扶余县",
+					"前郭尔罗斯蒙古族自治县"
+				]
+			},
+			{
+				"name": "白城市",
+				"area": [
+					"洮北区",
+					"大安市",
+					"洮南市",
+					"镇赉县",
+					"通榆县"
+				]
+			},
+			{
+				"name": "延边朝鲜族自治州",
+				"area": [
+					"延吉市",
+					"图们市",
+					"敦化市",
+					"龙井市",
+					"珲春市",
+					"和龙市",
+					"安图县",
+					"汪清县"
+				]
+			}
+		]
+	},
+	{
+		"name": "黑龙江省",
+		"city": [{
+				"name": "哈尔滨市",
+				"area": [
+					"松北区",
+					"道里区",
+					"南岗区",
+					"平房区",
+					"香坊区",
+					"道外区",
+					"呼兰区",
+					"阿城区",
+					"双城市",
+					"尚志市",
+					"五常市",
+					"宾县",
+					"方正县",
+					"通河县",
+					"巴彦县",
+					"延寿县",
+					"木兰县",
+					"依兰县"
+				]
+			},
+			{
+				"name": "齐齐哈尔市",
+				"area": [
+					"龙沙区",
+					"昂昂溪区",
+					"铁锋区",
+					"建华区",
+					"富拉尔基区",
+					"碾子山区",
+					"梅里斯达斡尔族区",
+					"讷河市",
+					"富裕县",
+					"拜泉县",
+					"甘南县",
+					"依安县",
+					"克山县",
+					"泰来县",
+					"克东县",
+					"龙江县"
+				]
+			},
+			{
+				"name": "鹤岗市",
+				"area": [
+					"兴山区",
+					"工农区",
+					"南山区",
+					"兴安区",
+					"向阳区",
+					"东山区",
+					"萝北县",
+					"绥滨县"
+				]
+			},
+			{
+				"name": "双鸭山",
+				"area": [
+					"尖山区",
+					"岭东区",
+					"四方台区",
+					"宝山区",
+					"集贤县",
+					"宝清县",
+					"友谊县",
+					"饶河县"
+				]
+			},
+			{
+				"name": "鸡西市",
+				"area": [
+					"鸡冠区",
+					"恒山区",
+					"城子河区",
+					"滴道区",
+					"梨树区",
+					"麻山区",
+					"密山市",
+					"虎林市",
+					"鸡东县"
+				]
+			},
+			{
+				"name": "大庆市",
+				"area": [
+					"萨尔图区",
+					"红岗区",
+					"龙凤区",
+					"让胡路区",
+					"大同区",
+					"林甸县",
+					"肇州县",
+					"肇源县",
+					"杜尔伯特蒙古族自治县"
+				]
+			},
+			{
+				"name": "伊春市",
+				"area": [
+					"伊春区",
+					"带岭区",
+					"南岔区",
+					"金山屯区",
+					"西林区",
+					"美溪区",
+					"乌马河区",
+					"翠峦区",
+					"友好区",
+					"上甘岭区",
+					"五营区",
+					"红星区",
+					"新青区",
+					"汤旺河区",
+					"乌伊岭区",
+					"铁力市",
+					"嘉荫县"
+				]
+			},
+			{
+				"name": "牡丹江市",
+				"area": [
+					"爱民区",
+					"东安区",
+					"阳明区",
+					"西安区",
+					"绥芬河市",
+					"宁安市",
+					"海林市",
+					"穆棱市",
+					"林口县",
+					"东宁县"
+				]
+			},
+			{
+				"name": "佳木斯市",
+				"area": [
+					"向阳区",
+					"前进区",
+					"东风区",
+					"郊区",
+					"同江市",
+					"富锦市",
+					"桦川县",
+					"抚远县",
+					"桦南县",
+					"汤原县"
+				]
+			},
+			{
+				"name": "七台河市",
+				"area": [
+					"桃山区",
+					"新兴区",
+					"茄子河区",
+					"勃利县"
+				]
+			},
+			{
+				"name": "黑河市",
+				"area": [
+					"爱辉区",
+					"北安市",
+					"五大连池市",
+					"逊克县",
+					"嫩江县",
+					"孙吴县"
+				]
+			},
+			{
+				"name": "绥化市",
+				"area": [
+					"北林区",
+					"安达市",
+					"肇东市",
+					"海伦市",
+					"绥棱县",
+					"兰西县",
+					"明水县",
+					"青冈县",
+					"庆安县",
+					"望奎县"
+				]
+			},
+			{
+				"name": "大兴安岭地区",
+				"area": [
+					"呼玛县",
+					"塔河县",
+					"漠河县",
+					"大兴安岭辖区"
+				]
+			}
+		]
+	},
+	{
+		"name": "上海市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"黄浦区",
+				"卢湾区",
+				"徐汇区",
+				"长宁区",
+				"静安区",
+				"普陀区",
+				"闸北区",
+				"虹口区",
+				"杨浦区",
+				"宝山区",
+				"闵行区",
+				"嘉定区",
+				"松江区",
+				"金山区",
+				"青浦区",
+				"南汇区",
+				"奉贤区",
+				"浦东新区",
+				"崇明县"
+			]
+		}]
+	},
+	{
+		"name": "江苏省",
+		"city": [{
+				"name": "南京市",
+				"area": [
+					"玄武区",
+					"白下区",
+					"秦淮区",
+					"建邺区",
+					"鼓楼区",
+					"下关区",
+					"栖霞区",
+					"雨花台区",
+					"浦口区",
+					"江宁区",
+					"六合区",
+					"溧水县",
+					"高淳县"
+				]
+			},
+			{
+				"name": "苏州市",
+				"area": [
+					"金阊区",
+					"平江区",
+					"沧浪区",
+					"虎丘区",
+					"吴中区",
+					"相城区",
+					"常熟市",
+					"张家港市",
+					"昆山市",
+					"吴江市",
+					"太仓市"
+				]
+			},
+			{
+				"name": "无锡市",
+				"area": [
+					"崇安区",
+					"南长区",
+					"北塘区",
+					"滨湖区",
+					"锡山区",
+					"惠山区",
+					"江阴市",
+					"宜兴市"
+				]
+			},
+			{
+				"name": "常州市",
+				"area": [
+					"钟楼区",
+					"天宁区",
+					"戚墅堰区",
+					"新北区",
+					"武进区",
+					"金坛市",
+					"溧阳市"
+				]
+			},
+			{
+				"name": "镇江市",
+				"area": [
+					"京口区",
+					"润州区",
+					"丹徒区",
+					"丹阳市",
+					"扬中市",
+					"句容市"
+				]
+			},
+			{
+				"name": "南通市",
+				"area": [
+					"崇川区",
+					"港闸区",
+					"通州市",
+					"如皋市",
+					"海门市",
+					"启东市",
+					"海安县",
+					"如东县"
+				]
+			},
+			{
+				"name": "泰州市",
+				"area": [
+					"海陵区",
+					"高港区",
+					"姜堰市",
+					"泰兴市",
+					"靖江市",
+					"兴化市"
+				]
+			},
+			{
+				"name": "扬州市",
+				"area": [
+					"广陵区",
+					"维扬区",
+					"邗江区",
+					"江都市",
+					"仪征市",
+					"高邮市",
+					"宝应县"
+				]
+			},
+			{
+				"name": "盐城市",
+				"area": [
+					"亭湖区",
+					"盐都区",
+					"大丰市",
+					"东台市",
+					"建湖县",
+					"射阳县",
+					"阜宁县",
+					"滨海县",
+					"响水县"
+				]
+			},
+			{
+				"name": "连云港市",
+				"area": [
+					"新浦区",
+					"海州区",
+					"连云区",
+					"东海县",
+					"灌云县",
+					"赣榆县",
+					"灌南县"
+				]
+			},
+			{
+				"name": "徐州市",
+				"area": [
+					"云龙区",
+					"鼓楼区",
+					"九里区",
+					"泉山区",
+					"贾汪区",
+					"邳州市",
+					"新沂市",
+					"铜山县",
+					"睢宁县",
+					"沛县",
+					"丰县"
+				]
+			},
+			{
+				"name": "淮安市",
+				"area": [
+					"清河区",
+					"清浦区",
+					"楚州区",
+					"淮阴区",
+					"涟水县",
+					"洪泽县",
+					"金湖县",
+					"盱眙县"
+				]
+			},
+			{
+				"name": "宿迁市",
+				"area": [
+					"宿城区",
+					"宿豫区",
+					"沭阳县",
+					"泗阳县",
+					"泗洪县"
+				]
+			}
+		]
+	},
+	{
+		"name": "浙江省",
+		"city": [{
+				"name": "杭州市",
+				"area": [
+					"拱墅区",
+					"西湖区",
+					"上城区",
+					"下城区",
+					"江干区",
+					"滨江区",
+					"余杭区",
+					"萧山区",
+					"建德市",
+					"富阳市",
+					"临安市",
+					"桐庐县",
+					"淳安县"
+				]
+			},
+			{
+				"name": "宁波市",
+				"area": [
+					"海曙区",
+					"江东区",
+					"江北区",
+					"镇海区",
+					"北仑区",
+					"鄞州区",
+					"余姚市",
+					"慈溪市",
+					"奉化市",
+					"宁海县",
+					"象山县"
+				]
+			},
+			{
+				"name": "温州市",
+				"area": [
+					"鹿城区",
+					"龙湾区",
+					"瓯海区",
+					"瑞安市",
+					"乐清市",
+					"永嘉县",
+					"洞头县",
+					"平阳县",
+					"苍南县",
+					"文成县",
+					"泰顺县"
+				]
+			},
+			{
+				"name": "嘉兴市",
+				"area": [
+					"秀城区",
+					"秀洲区",
+					"海宁市",
+					"平湖市",
+					"桐乡市",
+					"嘉善县",
+					"海盐县"
+				]
+			},
+			{
+				"name": "湖州市",
+				"area": [
+					"吴兴区",
+					"南浔区",
+					"长兴县",
+					"德清县",
+					"安吉县"
+				]
+			},
+			{
+				"name": "绍兴市",
+				"area": [
+					"越城区",
+					"诸暨市",
+					"上虞市",
+					"嵊州市",
+					"绍兴县",
+					"新昌县"
+				]
+			},
+			{
+				"name": "金华市",
+				"area": [
+					"婺城区",
+					"金东区",
+					"兰溪市",
+					"义乌市",
+					"东阳市",
+					"永康市",
+					"武义县",
+					"浦江县",
+					"磐安县"
+				]
+			},
+			{
+				"name": "衢州市",
+				"area": [
+					"柯城区",
+					"衢江区",
+					"江山市",
+					"龙游县",
+					"常山县",
+					"开化县"
+				]
+			},
+			{
+				"name": "舟山市",
+				"area": [
+					"定海区",
+					"普陀区",
+					"岱山县",
+					"嵊泗县"
+				]
+			},
+			{
+				"name": "台州市",
+				"area": [
+					"椒江区",
+					"黄岩区",
+					"路桥区",
+					"临海市",
+					"温岭市",
+					"玉环县",
+					"天台县",
+					"仙居县",
+					"三门县"
+				]
+			},
+			{
+				"name": "丽水市",
+				"area": [
+					"莲都区",
+					"龙泉市",
+					"缙云县",
+					"青田县",
+					"云和县",
+					"遂昌县",
+					"松阳县",
+					"庆元县",
+					"景宁畲族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "安徽省",
+		"city": [{
+				"name": "合肥市",
+				"area": [
+					"庐阳区",
+					"瑶海区",
+					"蜀山区",
+					"包河区",
+					"长丰县",
+					"肥东县",
+					"肥西县"
+				]
+			},
+			{
+				"name": "芜湖市",
+				"area": [
+					"镜湖区",
+					"弋江区",
+					"鸠江区",
+					"三山区",
+					"芜湖县",
+					"南陵县",
+					"繁昌县"
+				]
+			},
+			{
+				"name": "蚌埠市",
+				"area": [
+					"蚌山区",
+					"龙子湖区",
+					"禹会区",
+					"淮上区",
+					"怀远县",
+					"固镇县",
+					"五河县"
+				]
+			},
+			{
+				"name": "淮南市",
+				"area": [
+					"田家庵区",
+					"大通区",
+					"谢家集区",
+					"八公山区",
+					"潘集区",
+					"凤台县"
+				]
+			},
+			{
+				"name": "马鞍山市",
+				"area": [
+					"雨山区",
+					"花山区",
+					"金家庄区",
+					"当涂县"
+				]
+			},
+			{
+				"name": "淮北市",
+				"area": [
+					"相山区",
+					"杜集区",
+					"烈山区",
+					"濉溪县"
+				]
+			},
+			{
+				"name": "铜陵市",
+				"area": [
+					"铜官山区",
+					"狮子山区",
+					"郊区",
+					"铜陵县"
+				]
+			},
+			{
+				"name": "安庆市",
+				"area": [
+					"迎江区",
+					"大观区",
+					"宜秀区",
+					"桐城市",
+					"宿松县",
+					"枞阳县",
+					"太湖县",
+					"怀宁县",
+					"岳西县",
+					"望江县",
+					"潜山县"
+				]
+			},
+			{
+				"name": "黄山市",
+				"area": [
+					"屯溪区",
+					"黄山区",
+					"徽州区",
+					"休宁县",
+					"歙县",
+					"祁门县",
+					"黟县"
+				]
+			},
+			{
+				"name": "滁州市",
+				"area": [
+					"琅琊区",
+					"南谯区",
+					"天长市",
+					"明光市",
+					"全椒县",
+					"来安县",
+					"定远县",
+					"凤阳县"
+				]
+			},
+			{
+				"name": "阜阳市",
+				"area": [
+					"颍州区",
+					"颍东区",
+					"颍泉区",
+					"界首市",
+					"临泉县",
+					"颍上县",
+					"阜南县",
+					"太和县"
+				]
+			},
+			{
+				"name": "宿州市",
+				"area": [
+					"埇桥区",
+					"萧县",
+					"泗县",
+					"砀山县",
+					"灵璧县"
+				]
+			},
+			{
+				"name": "巢湖市",
+				"area": [
+					"居巢区",
+					"含山县",
+					"无为县",
+					"庐江县",
+					"和县"
+				]
+			},
+			{
+				"name": "六安市",
+				"area": [
+					"金安区",
+					"裕安区",
+					"寿县",
+					"霍山县",
+					"霍邱县",
+					"舒城县",
+					"金寨县"
+				]
+			},
+			{
+				"name": "亳州市",
+				"area": [
+					"谯城区",
+					"利辛县",
+					"涡阳县",
+					"蒙城县"
+				]
+			},
+			{
+				"name": "池州市",
+				"area": [
+					"贵池区",
+					"东至县",
+					"石台县",
+					"青阳县"
+				]
+			},
+			{
+				"name": "宣城市",
+				"area": [
+					"宣州区",
+					"宁国市",
+					"广德县",
+					"郎溪县",
+					"泾县",
+					"旌德县",
+					"绩溪县"
+				]
+			}
+		]
+	},
+	{
+		"name": "福建省",
+		"city": [{
+				"name": "福州市",
+				"area": [
+					"鼓楼区",
+					"台江区",
+					"仓山区",
+					"马尾区",
+					"晋安区",
+					"福清市",
+					"长乐市",
+					"闽侯县",
+					"闽清县",
+					"永泰县",
+					"连江县",
+					"罗源县",
+					"平潭县"
+				]
+			},
+			{
+				"name": "厦门市",
+				"area": [
+					"思明区",
+					"海沧区",
+					"湖里区",
+					"集美区",
+					"同安区",
+					"翔安区"
+				]
+			},
+			{
+				"name": "莆田市",
+				"area": [
+					"城厢区",
+					"涵江区",
+					"荔城区",
+					"秀屿区",
+					"仙游县"
+				]
+			},
+			{
+				"name": "三明市",
+				"area": [
+					"梅列区",
+					"三元区",
+					"永安市",
+					"明溪县",
+					"将乐县",
+					"大田县",
+					"宁化县",
+					"建宁县",
+					"沙县",
+					"尤溪县",
+					"清流县",
+					"泰宁县"
+				]
+			},
+			{
+				"name": "泉州市",
+				"area": [
+					"鲤城区",
+					"丰泽区",
+					"洛江区",
+					"泉港区",
+					"石狮市",
+					"晋江市",
+					"南安市",
+					"惠安县",
+					"永春县",
+					"安溪县",
+					"德化县",
+					"金门县"
+				]
+			},
+			{
+				"name": "漳州市",
+				"area": [
+					"芗城区",
+					"龙文区",
+					"龙海市",
+					"平和县",
+					"南靖县",
+					"诏安县",
+					"漳浦县",
+					"华安县",
+					"东山县",
+					"长泰县",
+					"云霄县"
+				]
+			},
+			{
+				"name": "南平市",
+				"area": [
+					"延平区",
+					"建瓯市",
+					"邵武市",
+					"武夷山市",
+					"建阳市",
+					"松溪县",
+					"光泽县",
+					"顺昌县",
+					"浦城县",
+					"政和县"
+				]
+			},
+			{
+				"name": "龙岩市",
+				"area": [
+					"新罗区",
+					"漳平市",
+					"长汀县",
+					"武平县",
+					"上杭县",
+					"永定县",
+					"连城县"
+				]
+			},
+			{
+				"name": "宁德市",
+				"area": [
+					"蕉城区",
+					"福安市",
+					"福鼎市",
+					"寿宁县",
+					"霞浦县",
+					"柘荣县",
+					"屏南县",
+					"古田县",
+					"周宁县"
+				]
+			}
+		]
+	},
+	{
+		"name": "江西省",
+		"city": [{
+				"name": "南昌市",
+				"area": [
+					"东湖区",
+					"西湖区",
+					"青云谱区",
+					"湾里区",
+					"青山湖区",
+					"新建县",
+					"南昌县",
+					"进贤县",
+					"安义县"
+				]
+			},
+			{
+				"name": "景德镇市",
+				"area": [
+					"珠山区",
+					"昌江区",
+					"乐平市",
+					"浮梁县"
+				]
+			},
+			{
+				"name": "萍乡市",
+				"area": [
+					"安源区",
+					"湘东区",
+					"莲花县",
+					"上栗县",
+					"芦溪县"
+				]
+			},
+			{
+				"name": "九江市",
+				"area": [
+					"浔阳区",
+					"庐山区",
+					"瑞昌市",
+					"九江县",
+					"星子县",
+					"武宁县",
+					"彭泽县",
+					"永修县",
+					"修水县",
+					"湖口县",
+					"德安县",
+					"都昌县"
+				]
+			},
+			{
+				"name": "新余市",
+				"area": [
+					"渝水区",
+					"分宜县"
+				]
+			},
+			{
+				"name": "鹰潭市",
+				"area": [
+					"月湖区",
+					"贵溪市",
+					"余江县"
+				]
+			},
+			{
+				"name": "赣州市",
+				"area": [
+					"章贡区",
+					"瑞金市",
+					"南康市",
+					"石城县",
+					"安远县",
+					"赣县",
+					"宁都县",
+					"寻乌县",
+					"兴国县",
+					"定南县",
+					"上犹县",
+					"于都县",
+					"龙南县",
+					"崇义县",
+					"信丰县",
+					"全南县",
+					"大余县",
+					"会昌县"
+				]
+			},
+			{
+				"name": "吉安市",
+				"area": [
+					"吉州区",
+					"青原区",
+					"井冈山市",
+					"吉安县",
+					"永丰县",
+					"永新县",
+					"新干县",
+					"泰和县",
+					"峡江县",
+					"遂川县",
+					"安福县",
+					"吉水县",
+					"万安县"
+				]
+			},
+			{
+				"name": "宜春市",
+				"area": [
+					"袁州区",
+					"丰城市",
+					"樟树市",
+					"高安市",
+					"铜鼓县",
+					"靖安县",
+					"宜丰县",
+					"奉新县",
+					"万载县",
+					"上高县"
+				]
+			},
+			{
+				"name": "抚州市",
+				"area": [
+					"临川区",
+					"南丰县",
+					"乐安县",
+					"金溪县",
+					"南城县",
+					"东乡县",
+					"资溪县",
+					"宜黄县",
+					"广昌县",
+					"黎川县",
+					"崇仁县"
+				]
+			},
+			{
+				"name": "上饶市",
+				"area": [
+					"信州区",
+					"德兴市",
+					"上饶县",
+					"广丰县",
+					"鄱阳县",
+					"婺源县",
+					"铅山县",
+					"余干县",
+					"横峰县",
+					"弋阳县",
+					"玉山县",
+					"万年县"
+				]
+			}
+		]
+	},
+	{
+		"name": "山东省",
+		"city": [{
+				"name": "济南市",
+				"area": [
+					"市中区",
+					"历下区",
+					"天桥区",
+					"槐荫区",
+					"历城区",
+					"长清区",
+					"章丘市",
+					"平阴县",
+					"济阳县",
+					"商河县"
+				]
+			},
+			{
+				"name": "青岛市",
+				"area": [
+					"市南区",
+					"市北区",
+					"城阳区",
+					"四方区",
+					"李沧区",
+					"黄岛区",
+					"崂山区",
+					"胶南市",
+					"胶州市",
+					"平度市",
+					"莱西市",
+					"即墨市"
+				]
+			},
+			{
+				"name": "淄博市",
+				"area": [
+					"张店区",
+					"临淄区",
+					"淄川区",
+					"博山区",
+					"周村区",
+					"桓台县",
+					"高青县",
+					"沂源县"
+				]
+			},
+			{
+				"name": "枣庄市",
+				"area": [
+					"市中区",
+					"山亭区",
+					"峄城区",
+					"台儿庄区",
+					"薛城区",
+					"滕州市"
+				]
+			},
+			{
+				"name": "东营市",
+				"area": [
+					"东营区",
+					"河口区",
+					"垦利县",
+					"广饶县",
+					"利津县"
+				]
+			},
+			{
+				"name": "烟台市",
+				"area": [
+					"芝罘区",
+					"福山区",
+					"牟平区",
+					"莱山区",
+					"龙口市",
+					"莱阳市",
+					"莱州市",
+					"招远市",
+					"蓬莱市",
+					"栖霞市",
+					"海阳市",
+					"长岛县"
+				]
+			},
+			{
+				"name": "潍坊市",
+				"area": [
+					"潍城区",
+					"寒亭区",
+					"坊子区",
+					"奎文区",
+					"青州市",
+					"诸城市",
+					"寿光市",
+					"安丘市",
+					"高密市",
+					"昌邑市",
+					"昌乐县",
+					"临朐县"
+				]
+			},
+			{
+				"name": "济宁市",
+				"area": [
+					"市中区",
+					"任城区",
+					"曲阜市",
+					"兖州市",
+					"邹城市",
+					"鱼台县",
+					"金乡县",
+					"嘉祥县",
+					"微山县",
+					"汶上县",
+					"泗水县",
+					"梁山县"
+				]
+			},
+			{
+				"name": "泰安市",
+				"area": [
+					"泰山区",
+					"岱岳区",
+					"新泰市",
+					"肥城市",
+					"宁阳县",
+					"东平县"
+				]
+			},
+			{
+				"name": "威海市",
+				"area": [
+					"环翠区",
+					"乳山市",
+					"文登市",
+					"荣成市"
+				]
+			},
+			{
+				"name": "日照市",
+				"area": [
+					"东港区",
+					"岚山区",
+					"五莲县",
+					"莒县"
+				]
+			},
+			{
+				"name": "莱芜市",
+				"area": [
+					"莱城区",
+					"钢城区"
+				]
+			},
+			{
+				"name": "临沂市",
+				"area": [
+					"兰山区",
+					"罗庄区",
+					"河东区",
+					"沂南县",
+					"郯城县",
+					"沂水县",
+					"苍山县",
+					"费县",
+					"平邑县",
+					"莒南县",
+					"蒙阴县",
+					"临沭县"
+				]
+			},
+			{
+				"name": "德州市",
+				"area": [
+					"德城区",
+					"乐陵市",
+					"禹城市",
+					"陵县",
+					"宁津县",
+					"齐河县",
+					"武城县",
+					"庆云县",
+					"平原县",
+					"夏津县",
+					"临邑县"
+				]
+			},
+			{
+				"name": "聊城市",
+				"area": [
+					"东昌府区",
+					"临清市",
+					"高唐县",
+					"阳谷县",
+					"茌平县",
+					"莘县",
+					"东阿县",
+					"冠县"
+				]
+			},
+			{
+				"name": "滨州市",
+				"area": [
+					"滨城区",
+					"邹平县",
+					"沾化县",
+					"惠民县",
+					"博兴县",
+					"阳信县",
+					"无棣县"
+				]
+			},
+			{
+				"name": "菏泽市",
+				"area": [
+					"牡丹区",
+					"鄄城县",
+					"单县",
+					"郓城县",
+					"曹县",
+					"定陶县",
+					"巨野县",
+					"东明县",
+					"成武县"
+				]
+			}
+		]
+	},
+	{
+		"name": "河南省",
+		"city": [{
+				"name": "郑州市",
+				"area": [
+					"中原区",
+					"金水区",
+					"二七区",
+					"管城回族区",
+					"上街区",
+					"惠济区",
+					"巩义市",
+					"新郑市",
+					"新密市",
+					"登封市",
+					"荥阳市",
+					"中牟县"
+				]
+			},
+			{
+				"name": "开封市",
+				"area": [
+					"鼓楼区",
+					"龙亭区",
+					"顺河回族区",
+					"禹王台区",
+					"金明区",
+					"开封县",
+					"尉氏县",
+					"兰考县",
+					"杞县",
+					"通许县"
+				]
+			},
+			{
+				"name": "洛阳市",
+				"area": [
+					"西工区",
+					"老城区",
+					"涧西区",
+					"瀍河回族区",
+					"洛龙区",
+					"吉利区",
+					"偃师市",
+					"孟津县",
+					"汝阳县",
+					"伊川县",
+					"洛宁县",
+					"嵩县",
+					"宜阳县",
+					"新安县",
+					"栾川县"
+				]
+			},
+			{
+				"name": "平顶山市",
+				"area": [
+					"新华区",
+					"卫东区",
+					"湛河区",
+					"石龙区",
+					"汝州市",
+					"舞钢市",
+					"宝丰县",
+					"叶县",
+					"郏县",
+					"鲁山县"
+				]
+			},
+			{
+				"name": "安阳市",
+				"area": [
+					"北关区",
+					"文峰区",
+					"殷都区",
+					"龙安区",
+					"林州市",
+					"安阳县",
+					"滑县",
+					"内黄县",
+					"汤阴县"
+				]
+			},
+			{
+				"name": "鹤壁市",
+				"area": [
+					"淇滨区",
+					"山城区",
+					"鹤山区",
+					"浚县",
+					"淇县"
+				]
+			},
+			{
+				"name": "新乡市",
+				"area": [
+					"卫滨区",
+					"红旗区",
+					"凤泉区",
+					"牧野区",
+					"卫辉市",
+					"辉县市",
+					"新乡县",
+					"获嘉县",
+					"原阳县",
+					"长垣县",
+					"封丘县",
+					"延津县"
+				]
+			},
+			{
+				"name": "焦作市",
+				"area": [
+					"解放区",
+					"中站区",
+					"马村区",
+					"山阳区",
+					"沁阳市",
+					"孟州市",
+					"修武县",
+					"温县",
+					"武陟县",
+					"博爱县"
+				]
+			},
+			{
+				"name": "濮阳市",
+				"area": [
+					"华龙区",
+					"濮阳县",
+					"南乐县",
+					"台前县",
+					"清丰县",
+					"范县"
+				]
+			},
+			{
+				"name": "许昌市",
+				"area": [
+					"魏都区",
+					"禹州市",
+					"长葛市",
+					"许昌县",
+					"鄢陵县",
+					"襄城县"
+				]
+			},
+			{
+				"name": "漯河市",
+				"area": [
+					"源汇区",
+					"郾城区",
+					"召陵区",
+					"临颍县",
+					"舞阳县"
+				]
+			},
+			{
+				"name": "三门峡市",
+				"area": [
+					"湖滨区",
+					"义马市",
+					"灵宝市",
+					"渑池县",
+					"卢氏县",
+					"陕县"
+				]
+			},
+			{
+				"name": "南阳市",
+				"area": [
+					"卧龙区",
+					"宛城区",
+					"邓州市",
+					"桐柏县",
+					"方城县",
+					"淅川县",
+					"镇平县",
+					"唐河县",
+					"南召县",
+					"内乡县",
+					"新野县",
+					"社旗县",
+					"西峡县"
+				]
+			},
+			{
+				"name": "商丘市",
+				"area": [
+					"梁园区",
+					"睢阳区",
+					"永城市",
+					"宁陵县",
+					"虞城县",
+					"民权县",
+					"夏邑县",
+					"柘城县",
+					"睢县"
+				]
+			},
+			{
+				"name": "信阳市",
+				"area": [
+					"浉河区",
+					"平桥区",
+					"潢川县",
+					"淮滨县",
+					"息县",
+					"新县",
+					"商城县",
+					"固始县",
+					"罗山县",
+					"光山县"
+				]
+			},
+			{
+				"name": "周口市",
+				"area": [
+					"川汇区",
+					"项城市",
+					"商水县",
+					"淮阳县",
+					"太康县",
+					"鹿邑县",
+					"西华县",
+					"扶沟县",
+					"沈丘县",
+					"郸城县"
+				]
+			},
+			{
+				"name": "驻马店市",
+				"area": [
+					"驿城区",
+					"确山县",
+					"新蔡县",
+					"上蔡县",
+					"西平县",
+					"泌阳县",
+					"平舆县",
+					"汝南县",
+					"遂平县",
+					"正阳县"
+				]
+			},
+			{
+				"name": "焦作市",
+				"area": [
+					"济源市"
+				]
+			}
+		]
+	},
+	{
+		"name": "湖北省",
+		"city": [{
+				"name": "武汉市",
+				"area": [
+					"江岸区",
+					"武昌区",
+					"江汉区",
+					"硚口区",
+					"汉阳区",
+					"青山区",
+					"洪山区",
+					"东西湖区",
+					"汉南区",
+					"蔡甸区",
+					"江夏区",
+					"黄陂区",
+					"新洲区"
+				]
+			},
+			{
+				"name": "黄石市",
+				"area": [
+					"黄石港区",
+					"西塞山区",
+					"下陆区",
+					"铁山区",
+					"大冶市",
+					"阳新县"
+				]
+			},
+			{
+				"name": "十堰市",
+				"area": [
+					"张湾区",
+					"茅箭区",
+					"丹江口市",
+					"郧县",
+					"竹山县",
+					"房县",
+					"郧西县",
+					"竹溪县"
+				]
+			},
+			{
+				"name": "荆州市",
+				"area": [
+					"沙市区",
+					"荆州区",
+					"洪湖市",
+					"石首市",
+					"松滋市",
+					"监利县",
+					"公安县",
+					"江陵县"
+				]
+			},
+			{
+				"name": "宜昌市",
+				"area": [
+					"西陵区",
+					"伍家岗区",
+					"点军区",
+					"猇亭区",
+					"夷陵区",
+					"宜都市",
+					"当阳市",
+					"枝江市",
+					"秭归县",
+					"远安县",
+					"兴山县",
+					"五峰土家族自治县",
+					"长阳土家族自治县"
+				]
+			},
+			{
+				"name": "襄樊市",
+				"area": [
+					"襄城区",
+					"樊城区",
+					"襄阳区",
+					"老河口市",
+					"枣阳市",
+					"宜城市",
+					"南漳县",
+					"谷城县",
+					"保康县"
+				]
+			},
+			{
+				"name": "鄂州市",
+				"area": [
+					"鄂城区",
+					"华容区",
+					"梁子湖区"
+				]
+			},
+			{
+				"name": "荆门市",
+				"area": [
+					"东宝区",
+					"掇刀区",
+					"钟祥市",
+					"京山县",
+					"沙洋县"
+				]
+			},
+			{
+				"name": "孝感市",
+				"area": [
+					"孝南区",
+					"应城市",
+					"安陆市",
+					"汉川市",
+					"云梦县",
+					"大悟县",
+					"孝昌县"
+				]
+			},
+			{
+				"name": "黄冈市",
+				"area": [
+					"黄州区",
+					"麻城市",
+					"武穴市",
+					"红安县",
+					"罗田县",
+					"浠水县",
+					"蕲春县",
+					"黄梅县",
+					"英山县",
+					"团风县"
+				]
+			},
+			{
+				"name": "咸宁市",
+				"area": [
+					"咸安区",
+					"赤壁市",
+					"嘉鱼县",
+					"通山县",
+					"崇阳县",
+					"通城县"
+				]
+			},
+			{
+				"name": "随州市",
+				"area": [
+					"曾都区",
+					"广水市"
+				]
+			},
+			{
+				"name": "恩施土家族苗族自治州",
+				"area": [
+					"恩施市",
+					"利川市",
+					"建始县",
+					"来凤县",
+					"巴东县",
+					"鹤峰县",
+					"宣恩县",
+					"咸丰县"
+				]
+			},
+			{
+				"name": "仙桃市",
+				"area": [
+					"仙桃"
+				]
+			},
+			{
+				"name": "天门市",
+				"area": [
+					"天门"
+				]
+			},
+			{
+				"name": "潜江市",
+				"area": [
+					"潜江"
+				]
+			},
+			{
+				"name": "神农架林区",
+				"area": [
+					"神农架林区"
+				]
+			}
+		]
+	},
+	{
+		"name": "湖南省",
+		"city": [{
+				"name": "长沙市",
+				"area": [
+					"岳麓区",
+					"芙蓉区",
+					"天心区",
+					"开福区",
+					"雨花区",
+					"浏阳市",
+					"长沙县",
+					"望城县",
+					"宁乡县"
+				]
+			},
+			{
+				"name": "株洲市",
+				"area": [
+					"天元区",
+					"荷塘区",
+					"芦淞区",
+					"石峰区",
+					"醴陵市",
+					"株洲县",
+					"炎陵县",
+					"茶陵县",
+					"攸县"
+				]
+			},
+			{
+				"name": "湘潭市",
+				"area": [
+					"岳塘区",
+					"雨湖区",
+					"湘乡市",
+					"韶山市",
+					"湘潭县"
+				]
+			},
+			{
+				"name": "衡阳市",
+				"area": [
+					"雁峰区",
+					"珠晖区",
+					"石鼓区",
+					"蒸湘区",
+					"南岳区",
+					"耒阳市",
+					"常宁市",
+					"衡阳县",
+					"衡东县",
+					"衡山县",
+					"衡南县",
+					"祁东县"
+				]
+			},
+			{
+				"name": "邵阳市",
+				"area": [
+					"双清区",
+					"大祥区",
+					"北塔区",
+					"武冈市",
+					"邵东县",
+					"洞口县",
+					"新邵县",
+					"绥宁县",
+					"新宁县",
+					"邵阳县",
+					"隆回县",
+					"城步苗族自治县"
+				]
+			},
+			{
+				"name": "岳阳市",
+				"area": [
+					"岳阳楼区",
+					"云溪区",
+					"君山区",
+					"临湘市",
+					"汨罗市",
+					"岳阳县",
+					"湘阴县",
+					"平江县",
+					"华容县"
+				]
+			},
+			{
+				"name": "常德市",
+				"area": [
+					"武陵区",
+					"鼎城区",
+					"津市市",
+					"澧县",
+					"临澧县",
+					"桃源县",
+					"汉寿县",
+					"安乡县",
+					"石门县"
+				]
+			},
+			{
+				"name": "张家界市",
+				"area": [
+					"永定区",
+					"武陵源区",
+					"慈利县",
+					"桑植县"
+				]
+			},
+			{
+				"name": "益阳市",
+				"area": [
+					"赫山区",
+					"资阳区",
+					"沅江市",
+					"桃江县",
+					"南县",
+					"安化县"
+				]
+			},
+			{
+				"name": "郴州市",
+				"area": [
+					"北湖区",
+					"苏仙区",
+					"资兴市",
+					"宜章县",
+					"汝城县",
+					"安仁县",
+					"嘉禾县",
+					"临武县",
+					"桂东县",
+					"永兴县",
+					"桂阳县"
+				]
+			},
+			{
+				"name": "永州市",
+				"area": [
+					"冷水滩区",
+					"零陵区",
+					"祁阳县",
+					"蓝山县",
+					"宁远县",
+					"新田县",
+					"东安县",
+					"江永县",
+					"道县",
+					"双牌县",
+					"江华瑶族自治县"
+				]
+			},
+			{
+				"name": "怀化市",
+				"area": [
+					"鹤城区",
+					"洪江市",
+					"会同县",
+					"沅陵县",
+					"辰溪县",
+					"溆浦县",
+					"中方县",
+					"新晃侗族自治县",
+					"芷江侗族自治县",
+					"通道侗族自治县",
+					"靖州苗族侗族自治县",
+					"麻阳苗族自治县"
+				]
+			},
+			{
+				"name": "娄底市",
+				"area": [
+					"娄星区",
+					"冷水江市",
+					"涟源市",
+					"新化县",
+					"双峰县"
+				]
+			},
+			{
+				"name": "湘西土家族苗族自治州",
+				"area": [
+					"吉首市",
+					"古丈县",
+					"龙山县",
+					"永顺县",
+					"凤凰县",
+					"泸溪县",
+					"保靖县",
+					"花垣县"
+				]
+			}
+		]
+	},
+	{
+		"name": "广东省",
+		"city": [{
+				"name": "广州市",
+				"area": [
+					"越秀区",
+					"荔湾区",
+					"海珠区",
+					"天河区",
+					"白云区",
+					"黄埔区",
+					"番禺区",
+					"花都区",
+					"南沙区",
+					"萝岗区",
+					"增城市",
+					"从化市"
+				]
+			},
+			{
+				"name": "深圳市",
+				"area": [
+					"福田区",
+					"罗湖区",
+					"南山区",
+					"宝安区",
+					"龙岗区",
+					"盐田区"
+				]
+			},
+			{
+				"name": "东莞市",
+				"area": [
+					"莞城",
+					"常平",
+					"塘厦",
+					"塘厦",
+					"塘厦"
+				]
+			},
+			{
+				"name": "中山市",
+				"area": [
+					"中山"
+				]
+			},
+			{
+				"name": "潮州市",
+				"area": [
+					"湘桥区",
+					"潮安县",
+					"饶平县"
+				]
+			},
+			{
+				"name": "揭阳市",
+				"area": [
+					"榕城区",
+					"揭东县",
+					"揭西县",
+					"惠来县",
+					"普宁市"
+				]
+			},
+			{
+				"name": "云浮市",
+				"area": [
+					"云城区",
+					"新兴县",
+					"郁南县",
+					"云安县",
+					"罗定市"
+				]
+			},
+			{
+				"name": "珠海市",
+				"area": [
+					"香洲区",
+					"斗门区",
+					"金湾区"
+				]
+			},
+			{
+				"name": "汕头市",
+				"area": [
+					"金平区",
+					"濠江区",
+					"龙湖区",
+					"潮阳区",
+					"潮南区",
+					"澄海区",
+					"南澳县"
+				]
+			},
+			{
+				"name": "韶关市",
+				"area": [
+					"浈江区",
+					"武江区",
+					"曲江区",
+					"乐昌市",
+					"南雄市",
+					"始兴县",
+					"仁化县",
+					"翁源县",
+					"新丰县",
+					"乳源瑶族自治县"
+				]
+			},
+			{
+				"name": "佛山市",
+				"area": [
+					"禅城区",
+					"南海区",
+					"顺德区",
+					"三水区",
+					"高明区"
+				]
+			},
+			{
+				"name": "江门市",
+				"area": [
+					"蓬江区",
+					"江海区",
+					"新会区",
+					"恩平市",
+					"台山市",
+					"开平市",
+					"鹤山市"
+				]
+			},
+			{
+				"name": "湛江市",
+				"area": [
+					"赤坎区",
+					"霞山区",
+					"坡头区",
+					"麻章区",
+					"吴川市",
+					"廉江市",
+					"雷州市",
+					"遂溪县",
+					"徐闻县"
+				]
+			},
+			{
+				"name": "茂名市",
+				"area": [
+					"茂南区",
+					"茂港区",
+					"化州市",
+					"信宜市",
+					"高州市",
+					"电白县"
+				]
+			},
+			{
+				"name": "肇庆市",
+				"area": [
+					"端州区",
+					"鼎湖区",
+					"高要市",
+					"四会市",
+					"广宁县",
+					"怀集县",
+					"封开县",
+					"德庆县"
+				]
+			},
+			{
+				"name": "惠州市",
+				"area": [
+					"惠城区",
+					"惠阳区",
+					"博罗县",
+					"惠东县",
+					"龙门县"
+				]
+			},
+			{
+				"name": "梅州市",
+				"area": [
+					"梅江区",
+					"兴宁市",
+					"梅县",
+					"大埔县",
+					"丰顺县",
+					"五华县",
+					"平远县",
+					"蕉岭县"
+				]
+			},
+			{
+				"name": "汕尾市",
+				"area": [
+					"城区",
+					"陆丰市",
+					"海丰县",
+					"陆河县"
+				]
+			},
+			{
+				"name": "河源市",
+				"area": [
+					"源城区",
+					"紫金县",
+					"龙川县",
+					"连平县",
+					"和平县",
+					"东源县"
+				]
+			},
+			{
+				"name": "阳江市",
+				"area": [
+					"江城区",
+					"阳春市",
+					"阳西县",
+					"阳东县"
+				]
+			},
+			{
+				"name": "清远市",
+				"area": [
+					"清城区",
+					"英德市",
+					"连州市",
+					"佛冈县",
+					"阳山县",
+					"清新县",
+					"连山壮族瑶族自治县",
+					"连南瑶族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "广西",
+		"city": [{
+				"name": "南宁市",
+				"area": [
+					"青秀区",
+					"兴宁区",
+					"西乡塘区",
+					"良庆区",
+					"江南区",
+					"邕宁区",
+					"武鸣县",
+					"隆安县",
+					"马山县",
+					"上林县",
+					"宾阳县",
+					"横县"
+				]
+			},
+			{
+				"name": "柳州市",
+				"area": [
+					"城中区",
+					"鱼峰区",
+					"柳北区",
+					"柳南区",
+					"柳江县",
+					"柳城县",
+					"鹿寨县",
+					"融安县",
+					"融水苗族自治县",
+					"三江侗族自治县"
+				]
+			},
+			{
+				"name": "桂林市",
+				"area": [
+					"象山区",
+					"秀峰区",
+					"叠彩区",
+					"七星区",
+					"雁山区",
+					"阳朔县",
+					"临桂县",
+					"灵川县",
+					"全州县",
+					"平乐县",
+					"兴安县",
+					"灌阳县",
+					"荔浦县",
+					"资源县",
+					"永福县",
+					"龙胜各族自治县",
+					"恭城瑶族自治县"
+				]
+			},
+			{
+				"name": "梧州市",
+				"area": [
+					"万秀区",
+					"蝶山区",
+					"长洲区",
+					"岑溪市",
+					"苍梧县",
+					"藤县",
+					"蒙山县"
+				]
+			},
+			{
+				"name": "北海市",
+				"area": [
+					"海城区",
+					"银海区",
+					"铁山港区",
+					"合浦县"
+				]
+			},
+			{
+				"name": "防城港市",
+				"area": [
+					"港口区",
+					"防城区",
+					"东兴市",
+					"上思县"
+				]
+			},
+			{
+				"name": "钦州市",
+				"area": [
+					"钦南区",
+					"钦北区",
+					"灵山县",
+					"浦北县"
+				]
+			},
+			{
+				"name": "贵港市",
+				"area": [
+					"港北区",
+					"港南区",
+					"覃塘区",
+					"桂平市",
+					"平南县"
+				]
+			},
+			{
+				"name": "玉林市",
+				"area": [
+					"玉州区",
+					"北流市",
+					"容县",
+					"陆川县",
+					"博白县",
+					"兴业县"
+				]
+			},
+			{
+				"name": "百色市",
+				"area": [
+					"右江区",
+					"凌云县",
+					"平果县",
+					"西林县",
+					"乐业县",
+					"德保县",
+					"田林县",
+					"田阳县",
+					"靖西县",
+					"田东县",
+					"那坡县",
+					"隆林各族自治县"
+				]
+			},
+			{
+				"name": "贺州市",
+				"area": [
+					"八步区",
+					"钟山县",
+					"昭平县",
+					"富川瑶族自治县"
+				]
+			},
+			{
+				"name": "河池市",
+				"area": [
+					"金城江区",
+					"宜州市",
+					"天峨县",
+					"凤山县",
+					"南丹县",
+					"东兰县",
+					"都安瑶族自治县",
+					"罗城仫佬族自治县",
+					"巴马瑶族自治县",
+					"环江毛南族自治县",
+					"大化瑶族自治县"
+				]
+			},
+			{
+				"name": "来宾市",
+				"area": [
+					"兴宾区",
+					"合山市",
+					"象州县",
+					"武宣县",
+					"忻城县",
+					"金秀瑶族自治县"
+				]
+			},
+			{
+				"name": "崇左市",
+				"area": [
+					"江州区",
+					"凭祥市",
+					"宁明县",
+					"扶绥县",
+					"龙州县",
+					"大新县",
+					"天等县"
+				]
+			}
+		]
+	},
+	{
+		"name": "海南省",
+		"city": [{
+				"name": "海口市",
+				"area": [
+					"龙华区",
+					"秀英区",
+					"琼山区",
+					"美兰区"
+				]
+			},
+			{
+				"name": "三亚市",
+				"area": [
+					"三亚市"
+				]
+			},
+			{
+				"name": "五指山市",
+				"area": [
+					"五指山"
+				]
+			},
+			{
+				"name": "琼海市",
+				"area": [
+					"琼海"
+				]
+			},
+			{
+				"name": "儋州市",
+				"area": [
+					"儋州"
+				]
+			},
+			{
+				"name": "文昌市",
+				"area": [
+					"文昌"
+				]
+			},
+			{
+				"name": "万宁市",
+				"area": [
+					"万宁"
+				]
+			},
+			{
+				"name": "东方市",
+				"area": [
+					"东方"
+				]
+			},
+			{
+				"name": "澄迈县",
+				"area": [
+					"澄迈县"
+				]
+			},
+			{
+				"name": "定安县",
+				"area": [
+					"定安县"
+				]
+			},
+			{
+				"name": "屯昌县",
+				"area": [
+					"屯昌县"
+				]
+			},
+			{
+				"name": "临高县",
+				"area": [
+					"临高县"
+				]
+			},
+			{
+				"name": "白沙黎族自治县",
+				"area": [
+					"白沙黎族自治县"
+				]
+			},
+			{
+				"name": "昌江黎族自治县",
+				"area": [
+					"昌江黎族自治县"
+				]
+			},
+			{
+				"name": "乐东黎族自治县",
+				"area": [
+					"乐东黎族自治县"
+				]
+			},
+			{
+				"name": "陵水黎族自治县",
+				"area": [
+					"陵水黎族自治县"
+				]
+			},
+			{
+				"name": "保亭黎族苗族自治县",
+				"area": [
+					"保亭黎族苗族自治县"
+				]
+			},
+			{
+				"name": "琼中黎族苗族自治县",
+				"area": [
+					"琼中黎族苗族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "重庆市",
+		"city": [{
+			"name": "直辖市",
+			"area": [
+				"渝中区",
+				"大渡口区",
+				"江北区",
+				"南岸区",
+				"北碚区",
+				"渝北区",
+				"巴南区",
+				"长寿区",
+				"双桥区",
+				"沙坪坝区",
+				"万盛区",
+				"万州区",
+				"涪陵区",
+				"黔江区",
+				"永川区",
+				"合川区",
+				"江津区",
+				"九龙坡区",
+				"南川区",
+				"綦江县",
+				"潼南县",
+				"荣昌县",
+				"璧山县",
+				"大足县",
+				"铜梁县",
+				"梁平县",
+				"开县",
+				"忠县",
+				"城口县",
+				"垫江县",
+				"武隆县",
+				"丰都县",
+				"奉节县",
+				"云阳县",
+				"巫溪县",
+				"巫山县",
+				"石柱土家族自治县",
+				"秀山土家族苗族自治县",
+				"酉阳土家族苗族自治县",
+				"彭水苗族土家族自治县"
+			]
+		}]
+	},
+	{
+		"name": "四川省",
+		"city": [{
+				"name": "成都市",
+				"area": [
+					"青羊区",
+					"锦江区",
+					"金牛区",
+					"武侯区",
+					"成华区",
+					"龙泉驿区",
+					"青白江区",
+					"新都区",
+					"温江区",
+					"都江堰市",
+					"彭州市",
+					"邛崃市",
+					"崇州市",
+					"金堂县",
+					"郫县",
+					"新津县",
+					"双流县",
+					"蒲江县",
+					"大邑县"
+				]
+			},
+			{
+				"name": "自贡市",
+				"area": [
+					"大安区",
+					"自流井区",
+					"贡井区",
+					"沿滩区",
+					"荣县",
+					"富顺县"
+				]
+			},
+			{
+				"name": "攀枝花市",
+				"area": [
+					"仁和区",
+					"米易县",
+					"盐边县",
+					"东区",
+					"西区"
+				]
+			},
+			{
+				"name": "泸州市",
+				"area": [
+					"江阳区",
+					"纳溪区",
+					"龙马潭区",
+					"泸县",
+					"合江县",
+					"叙永县",
+					"古蔺县"
+				]
+			},
+			{
+				"name": "德阳市",
+				"area": [
+					"旌阳区",
+					"广汉市",
+					"什邡市",
+					"绵竹市",
+					"罗江县",
+					"中江县"
+				]
+			},
+			{
+				"name": "绵阳市",
+				"area": [
+					"涪城区",
+					"游仙区",
+					"江油市",
+					"盐亭县",
+					"三台县",
+					"平武县",
+					"安县",
+					"梓潼县",
+					"北川羌族自治县"
+				]
+			},
+			{
+				"name": "广元市",
+				"area": [
+					"元坝区",
+					"朝天区",
+					"青川县",
+					"旺苍县",
+					"剑阁县",
+					"苍溪县",
+					"市中区"
+				]
+			},
+			{
+				"name": "遂宁市",
+				"area": [
+					"船山区",
+					"安居区",
+					"射洪县",
+					"蓬溪县",
+					"大英县"
+				]
+			},
+			{
+				"name": "内江市",
+				"area": [
+					"市中区",
+					"东兴区",
+					"资中县",
+					"隆昌县",
+					"威远县"
+				]
+			},
+			{
+				"name": "乐山市",
+				"area": [
+					"市中区",
+					"五通桥区",
+					"沙湾区",
+					"金口河区",
+					"峨眉山市",
+					"夹江县",
+					"井研县",
+					"犍为县",
+					"沐川县",
+					"马边彝族自治县",
+					"峨边彝族自治县"
+				]
+			},
+			{
+				"name": "南充",
+				"area": [
+					"顺庆区",
+					"高坪区",
+					"嘉陵区",
+					"阆中市",
+					"营山县",
+					"蓬安县",
+					"仪陇县",
+					"南部县",
+					"西充县"
+				]
+			},
+			{
+				"name": "眉山市",
+				"area": [
+					"东坡区",
+					"仁寿县",
+					"彭山县",
+					"洪雅县",
+					"丹棱县",
+					"青神县"
+				]
+			},
+			{
+				"name": "宜宾市",
+				"area": [
+					"翠屏区",
+					"宜宾县",
+					"兴文县",
+					"南溪县",
+					"珙县",
+					"长宁县",
+					"高县",
+					"江安县",
+					"筠连县",
+					"屏山县"
+				]
+			},
+			{
+				"name": "广安市",
+				"area": [
+					"广安区",
+					"华蓥市",
+					"岳池县",
+					"邻水县",
+					"武胜县"
+				]
+			},
+			{
+				"name": "达州市",
+				"area": [
+					"通川区",
+					"万源市",
+					"达县",
+					"渠县",
+					"宣汉县",
+					"开江县",
+					"大竹县"
+				]
+			},
+			{
+				"name": "雅安市",
+				"area": [
+					"雨城区",
+					"芦山县",
+					"石棉县",
+					"名山县",
+					"天全县",
+					"荥经县",
+					"宝兴县",
+					"汉源县"
+				]
+			},
+			{
+				"name": "巴中市",
+				"area": [
+					"巴州区",
+					"南江县",
+					"平昌县",
+					"通江县"
+				]
+			},
+			{
+				"name": "资阳市",
+				"area": [
+					"雁江区",
+					"简阳市",
+					"安岳县",
+					"乐至县"
+				]
+			},
+			{
+				"name": "阿坝藏族羌族自治州",
+				"area": [
+					"马尔康县",
+					"九寨沟县",
+					"红原县",
+					"汶川县",
+					"阿坝县",
+					"理县",
+					"若尔盖县",
+					"小金县",
+					"黑水县",
+					"金川县",
+					"松潘县",
+					"壤塘县",
+					"茂县"
+				]
+			},
+			{
+				"name": "甘孜藏族自治州",
+				"area": [
+					"康定县",
+					"丹巴县",
+					"炉霍县",
+					"九龙县",
+					"甘孜县",
+					"雅江县",
+					"新龙县",
+					"道孚县",
+					"白玉县",
+					"理塘县",
+					"德格县",
+					"乡城县",
+					"石渠县",
+					"稻城县",
+					"色达县",
+					"巴塘县",
+					"泸定县",
+					"得荣县"
+				]
+			},
+			{
+				"name": "凉山彝族自治州",
+				"area": [
+					"西昌市",
+					"美姑县",
+					"昭觉县",
+					"金阳县",
+					"甘洛县",
+					"布拖县",
+					"雷波县",
+					"普格县",
+					"宁南县",
+					"喜德县",
+					"会东县",
+					"越西县",
+					"会理县",
+					"盐源县",
+					"德昌县",
+					"冕宁县",
+					"木里藏族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "贵州省",
+		"city": [{
+				"name": "贵阳市",
+				"area": [
+					"南明区",
+					"云岩区",
+					"花溪区",
+					"乌当区",
+					"白云区",
+					"小河区",
+					"清镇市",
+					"开阳县",
+					"修文县",
+					"息烽县"
+				]
+			},
+			{
+				"name": "六盘水市",
+				"area": [
+					"钟山区",
+					"水城县",
+					"盘县",
+					"六枝特区"
+				]
+			},
+			{
+				"name": "遵义市",
+				"area": [
+					"红花岗区",
+					"汇川区",
+					"赤水市",
+					"仁怀市",
+					"遵义县",
+					"绥阳县",
+					"桐梓县",
+					"习水县",
+					"凤冈县",
+					"正安县",
+					"余庆县",
+					"湄潭县",
+					"道真仡佬族苗族自治县",
+					"务川仡佬族苗族自治县"
+				]
+			},
+			{
+				"name": "安顺市",
+				"area": [
+					"西秀区",
+					"普定县",
+					"平坝县",
+					"镇宁布依族苗族自治县",
+					"紫云苗族布依族自治县",
+					"关岭布依族苗族自治县"
+				]
+			},
+			{
+				"name": "铜仁地区",
+				"area": [
+					"铜仁市",
+					"德江县",
+					"江口县",
+					"思南县",
+					"石阡县",
+					"玉屏侗族自治县",
+					"松桃苗族自治县",
+					"印江土家族苗族自治县",
+					"沿河土家族自治县",
+					"万山特区"
+				]
+			},
+			{
+				"name": "毕节地区",
+				"area": [
+					"毕节市",
+					"黔西县",
+					"大方县",
+					"织金县",
+					"金沙县",
+					"赫章县",
+					"纳雍县",
+					"威宁彝族回族苗族自治县"
+				]
+			},
+			{
+				"name": "黔西南布依族苗族自治州",
+				"area": [
+					"兴义市",
+					"望谟县",
+					"兴仁县",
+					"普安县",
+					"册亨县",
+					"晴隆县",
+					"贞丰县",
+					"安龙县"
+				]
+			},
+			{
+				"name": "黔东南苗族侗族自治州",
+				"area": [
+					"凯里市",
+					"施秉县",
+					"从江县",
+					"锦屏县",
+					"镇远县",
+					"麻江县",
+					"台江县",
+					"天柱县",
+					"黄平县",
+					"榕江县",
+					"剑河县",
+					"三穗县",
+					"雷山县",
+					"黎平县",
+					"岑巩县",
+					"丹寨县"
+				]
+			},
+			{
+				"name": "黔南布依族苗族自治州",
+				"area": [
+					"都匀市",
+					"福泉市",
+					"贵定县",
+					"惠水县",
+					"罗甸县",
+					"瓮安县",
+					"荔波县",
+					"龙里县",
+					"平塘县",
+					"长顺县",
+					"独山县",
+					"三都水族自治县"
+				]
+			}
+		]
+	},
+	{
+		"name": "云南省",
+		"city": [{
+				"name": "昆明市",
+				"area": [
+					"盘龙区",
+					"五华区",
+					"官渡区",
+					"西山区",
+					"东川区",
+					"安宁市",
+					"呈贡县",
+					"晋宁县",
+					"富民县",
+					"宜良县",
+					"嵩明县",
+					"石林彝族自治县",
+					"禄劝彝族苗族自治县",
+					"寻甸回族彝族自治县"
+				]
+			},
+			{
+				"name": "曲靖市",
+				"area": [
+					"麒麟区",
+					"宣威市",
+					"马龙县",
+					"沾益县",
+					"富源县",
+					"罗平县",
+					"师宗县",
+					"陆良县",
+					"会泽县"
+				]
+			},
+			{
+				"name": "玉溪市",
+				"area": [
+					"红塔区",
+					"江川县",
+					"澄江县",
+					"通海县",
+					"华宁县",
+					"易门县",
+					"峨山彝族自治县",
+					"新平彝族傣族自治县",
+					"元江哈尼族彝族傣族自治县"
+				]
+			},
+			{
+				"name": "保山市",
+				"area": [
+					"隆阳区",
+					"施甸县",
+					"腾冲县",
+					"龙陵县",
+					"昌宁县"
+				]
+			},
+			{
+				"name": "昭通市",
+				"area": [
+					"昭阳区",
+					"鲁甸县",
+					"巧家县",
+					"盐津县",
+					"大关县",
+					"永善县",
+					"绥江县",
+					"镇雄县",
+					"彝良县",
+					"威信县",
+					"水富县"
+				]
+			},
+			{
+				"name": "丽江市",
+				"area": [
+					"古城区",
+					"永胜县",
+					"华坪县",
+					"玉龙纳西族自治县",
+					"宁蒗彝族自治县"
+				]
+			},
+			{
+				"name": "普洱市",
+				"area": [
+					"思茅区",
+					"普洱哈尼族彝族自治县",
+					"墨江哈尼族自治县",
+					"景东彝族自治县",
+					"景谷傣族彝族自治县",
+					"镇沅彝族哈尼族拉祜族自治县",
+					"江城哈尼族彝族自治县",
+					"孟连傣族拉祜族佤族自治县",
+					"澜沧拉祜族自治县",
+					"西盟佤族自治县"
+				]
+			},
+			{
+				"name": "临沧市",
+				"area": [
+					"临翔区",
+					"凤庆县",
+					"云县",
+					"永德县",
+					"镇康县",
+					"双江拉祜族佤族布朗族傣族自治县",
+					"耿马傣族佤族自治县",
+					"沧源佤族自治县"
+				]
+			},
+			{
+				"name": "德宏傣族景颇族自治州",
+				"area": [
+					"潞西市",
+					"瑞丽市",
+					"梁河县",
+					"盈江县",
+					"陇川县"
+				]
+			},
+			{
+				"name": "怒江傈僳族自治州",
+				"area": [
+					"泸水县",
+					"福贡县",
+					"贡山独龙族怒族自治县",
+					"兰坪白族普米族自治县"
+				]
+			},
+			{
+				"name": "迪庆藏族自治州",
+				"area": [
+					"香格里拉县",
+					"德钦县",
+					"维西傈僳族自治县"
+				]
+			},
+			{
+				"name": "大理白族自治州",
+				"area": [
+					"大理市",
+					"祥云县",
+					"宾川县",
+					"弥渡县",
+					"永平县",
+					"云龙县",
+					"洱源县",
+					"剑川县",
+					"鹤庆县",
+					"漾濞彝族自治县",
+					"南涧彝族自治县",
+					"巍山彝族回族自治县"
+				]
+			},
+			{
+				"name": "楚雄彝族自治州",
+				"area": [
+					"楚雄市",
+					"双柏县",
+					"牟定县",
+					"南华县",
+					"姚安县",
+					"大姚县",
+					"永仁县",
+					"元谋县",
+					"武定县",
+					"禄丰县"
+				]
+			},
+			{
+				"name": "红河哈尼族彝族自治州",
+				"area": [
+					"蒙自县",
+					"个旧市",
+					"开远市",
+					"绿春县",
+					"建水县",
+					"石屏县",
+					"弥勒县",
+					"泸西县",
+					"元阳县",
+					"红河县",
+					"金平苗族瑶族傣族自治县",
+					"河口瑶族自治县",
+					"屏边苗族自治县"
+				]
+			},
+			{
+				"name": "文山壮族苗族自治州",
+				"area": [
+					"文山县",
+					"砚山县",
+					"西畴县",
+					"麻栗坡县",
+					"马关县",
+					"丘北县",
+					"广南县",
+					"富宁县"
+				]
+			},
+			{
+				"name": "西双版纳傣族自治州",
+				"area": [
+					"景洪市",
+					"勐海县",
+					"勐腊县"
+				]
+			}
+		]
+	},
+	{
+		"name": "西藏",
+		"city": [{
+				"name": "拉萨市",
+				"area": [
+					"城关区",
+					"林周县",
+					"当雄县",
+					"尼木县",
+					"曲水县",
+					"堆龙德庆县",
+					"达孜县",
+					"墨竹工卡县"
+				]
+			},
+			{
+				"name": "那曲地区",
+				"area": [
+					"那曲县",
+					"嘉黎县",
+					"比如县",
+					"聂荣县",
+					"安多县",
+					"申扎县",
+					"索县",
+					"班戈县",
+					"巴青县",
+					"尼玛县"
+				]
+			},
+			{
+				"name": "昌都地区",
+				"area": [
+					"昌都县",
+					"江达县",
+					"贡觉县",
+					"类乌齐县",
+					"丁青县",
+					"察雅县",
+					"八宿县",
+					"左贡县",
+					"芒康县",
+					"洛隆县",
+					"边坝县"
+				]
+			},
+			{
+				"name": "林芝地区",
+				"area": [
+					"林芝县",
+					"工布江达县",
+					"米林县",
+					"墨脱县",
+					"波密县",
+					"察隅县",
+					"朗县"
+				]
+			},
+			{
+				"name": "山南地区",
+				"area": [
+					"乃东县",
+					"扎囊县",
+					"贡嘎县",
+					"桑日县",
+					"琼结县",
+					"曲松县",
+					"措美县",
+					"洛扎县",
+					"加查县",
+					"隆子县",
+					"错那县",
+					"浪卡子县"
+				]
+			},
+			{
+				"name": "日喀则地区",
+				"area": [
+					"日喀则市",
+					"南木林县",
+					"江孜县",
+					"定日县",
+					"萨迦县",
+					"拉孜县",
+					"昂仁县",
+					"谢通门县",
+					"白朗县",
+					"仁布县",
+					"康马县",
+					"定结县",
+					"仲巴县",
+					"亚东县",
+					"吉隆县",
+					"聂拉木县",
+					"萨嘎县",
+					"岗巴县"
+				]
+			},
+			{
+				"name": "阿里地区",
+				"area": [
+					"噶尔县",
+					"普兰县",
+					"札达县",
+					"日土县",
+					"革吉县",
+					"改则县",
+					"措勤县"
+				]
+			}
+		]
+	},
+	{
+		"name": "陕西省",
+		"city": [{
+				"name": "西安市",
+				"area": [
+					"莲湖区",
+					"新城区",
+					"碑林区",
+					"雁塔区",
+					"灞桥区",
+					"未央区",
+					"阎良区",
+					"临潼区",
+					"长安区",
+					"高陵县",
+					"蓝田县",
+					"户县",
+					"周至县"
+				]
+			},
+			{
+				"name": "铜川市",
+				"area": [
+					"耀州区",
+					"王益区",
+					"印台区",
+					"宜君县"
+				]
+			},
+			{
+				"name": "宝鸡市",
+				"area": [
+					"渭滨区",
+					"金台区",
+					"陈仓区",
+					"岐山县",
+					"凤翔县",
+					"陇县",
+					"太白县",
+					"麟游县",
+					"扶风县",
+					"千阳县",
+					"眉县",
+					"凤县"
+				]
+			},
+			{
+				"name": "咸阳市",
+				"area": [
+					"秦都区",
+					"渭城区",
+					"杨陵区",
+					"兴平市",
+					"礼泉县",
+					"泾阳县",
+					"永寿县",
+					"三原县",
+					"彬县",
+					"旬邑县",
+					"长武县",
+					"乾县",
+					"武功县",
+					"淳化县"
+				]
+			},
+			{
+				"name": "渭南市",
+				"area": [
+					"临渭区",
+					"韩城市",
+					"华阴市",
+					"蒲城县",
+					"潼关县",
+					"白水县",
+					"澄城县",
+					"华县",
+					"合阳县",
+					"富平县",
+					"大荔县"
+				]
+			},
+			{
+				"name": "延安市",
+				"area": [
+					"宝塔区",
+					"安塞县",
+					"洛川县",
+					"子长县",
+					"黄陵县",
+					"延川县",
+					"富县",
+					"延长县",
+					"甘泉县",
+					"宜川县",
+					"志丹县",
+					"黄龙县",
+					"吴起县"
+				]
+			},
+			{
+				"name": "汉中市",
+				"area": [
+					"汉台区",
+					"留坝县",
+					"镇巴县",
+					"城固县",
+					"南郑县",
+					"洋县",
+					"宁强县",
+					"佛坪县",
+					"勉县",
+					"西乡县",
+					"略阳县"
+				]
+			},
+			{
+				"name": "榆林市",
+				"area": [
+					"榆阳区",
+					"清涧县",
+					"绥德县",
+					"神木县",
+					"佳县",
+					"府谷县",
+					"子洲县",
+					"靖边县",
+					"横山县",
+					"米脂县",
+					"吴堡县",
+					"定边县"
+				]
+			},
+			{
+				"name": "安康市",
+				"area": [
+					"汉滨区",
+					"紫阳县",
+					"岚皋县",
+					"旬阳县",
+					"镇坪县",
+					"平利县",
+					"石泉县",
+					"宁陕县",
+					"白河县",
+					"汉阴县"
+				]
+			},
+			{
+				"name": "商洛市",
+				"area": [
+					"商州区",
+					"镇安县",
+					"山阳县",
+					"洛南县",
+					"商南县",
+					"丹凤县",
+					"柞水县"
+				]
+			}
+		]
+	},
+	{
+		"name": "甘肃省",
+		"city": [{
+				"name": "兰州市",
+				"area": [
+					"城关区",
+					"七里河区",
+					"西固区",
+					"安宁区",
+					"红古区",
+					"永登县",
+					"皋兰县",
+					"榆中县"
+				]
+			},
+			{
+				"name": "嘉峪关市",
+				"area": [
+					"嘉峪关市"
+				]
+			},
+			{
+				"name": "金昌市",
+				"area": [
+					"金川区",
+					"永昌县"
+				]
+			},
+			{
+				"name": "白银市",
+				"area": [
+					"白银区",
+					"平川区",
+					"靖远县",
+					"会宁县",
+					"景泰县"
+				]
+			},
+			{
+				"name": "天水市",
+				"area": [
+					"清水县",
+					"秦安县",
+					"甘谷县",
+					"武山县",
+					"张家川回族自治县",
+					"北道区",
+					"秦城区"
+				]
+			},
+			{
+				"name": "武威市",
+				"area": [
+					"凉州区",
+					"民勤县",
+					"古浪县",
+					"天祝藏族自治县"
+				]
+			},
+			{
+				"name": "酒泉市",
+				"area": [
+					"肃州区",
+					"玉门市",
+					"敦煌市",
+					"金塔县",
+					"肃北蒙古族自治县",
+					"阿克塞哈萨克族自治县",
+					"安西县"
+				]
+			},
+			{
+				"name": "张掖市",
+				"area": [
+					"甘州区",
+					"民乐县",
+					"临泽县",
+					"高台县",
+					"山丹县",
+					"肃南裕固族自治县"
+				]
+			},
+			{
+				"name": "庆阳市",
+				"area": [
+					"西峰区",
+					"庆城县",
+					"环县",
+					"华池县",
+					"合水县",
+					"正宁县",
+					"宁县",
+					"镇原县"
+				]
+			},
+			{
+				"name": "平凉市",
+				"area": [
+					"崆峒区",
+					"泾川县",
+					"灵台县",
+					"崇信县",
+					"华亭县",
+					"庄浪县",
+					"静宁县"
+				]
+			},
+			{
+				"name": "定西市",
+				"area": [
+					"安定区",
+					"通渭县",
+					"临洮县",
+					"漳县",
+					"岷县",
+					"渭源县",
+					"陇西县"
+				]
+			},
+			{
+				"name": "陇南市",
+				"area": [
+					"武都区",
+					"成县",
+					"宕昌县",
+					"康县",
+					"文县",
+					"西和县",
+					"礼县",
+					"两当县",
+					"徽县"
+				]
+			},
+			{
+				"name": "临夏回族自治州",
+				"area": [
+					"临夏市",
+					"临夏县",
+					"康乐县",
+					"永靖县",
+					"广河县",
+					"和政县",
+					"东乡族自治县",
+					"积石山保安族东乡族撒拉族自治县"
+				]
+			},
+			{
+				"name": "甘南藏族自治州",
+				"area": [
+					"合作市",
+					"临潭县",
+					"卓尼县",
+					"舟曲县",
+					"迭部县",
+					"玛曲县",
+					"碌曲县",
+					"夏河县"
+				]
+			}
+		]
+	},
+	{
+		"name": "青海省",
+		"city": [{
+				"name": "西宁市",
+				"area": [
+					"城中区",
+					"城东区",
+					"城西区",
+					"城北区",
+					"湟源县",
+					"湟中县",
+					"大通回族土族自治县"
+				]
+			},
+			{
+				"name": "海东地区",
+				"area": [
+					"平安县",
+					"乐都县",
+					"民和回族土族自治县",
+					"互助土族自治县",
+					"化隆回族自治县",
+					"循化撒拉族自治县"
+				]
+			},
+			{
+				"name": "海北藏族自治州",
+				"area": [
+					"海晏县",
+					"祁连县",
+					"刚察县",
+					"门源回族自治县"
+				]
+			},
+			{
+				"name": "海南藏族自治州",
+				"area": [
+					"共和县",
+					"同德县",
+					"贵德县",
+					"兴海县",
+					"贵南县"
+				]
+			},
+			{
+				"name": "黄南藏族自治州",
+				"area": [
+					"同仁县",
+					"尖扎县",
+					"泽库县",
+					"河南蒙古族自治县"
+				]
+			},
+			{
+				"name": "果洛藏族自治州",
+				"area": [
+					"玛沁县",
+					"班玛县",
+					"甘德县",
+					"达日县",
+					"久治县",
+					"玛多县"
+				]
+			},
+			{
+				"name": "玉树藏族自治州",
+				"area": [
+					"玉树县",
+					"杂多县",
+					"称多县",
+					"治多县",
+					"囊谦县",
+					"曲麻莱县"
+				]
+			},
+			{
+				"name": "海西蒙古族藏族自治州",
+				"area": [
+					"德令哈市",
+					"格尔木市",
+					"乌兰县",
+					"都兰县",
+					"天峻县"
+				]
+			}
+		]
+	},
+	{
+		"name": "宁夏",
+		"city": [{
+				"name": "银川市",
+				"area": [
+					"兴庆区",
+					"西夏区",
+					"金凤区",
+					"灵武市",
+					"永宁县",
+					"贺兰县"
+				]
+			},
+			{
+				"name": "石嘴山市",
+				"area": [
+					"大武口区",
+					"惠农区",
+					"平罗县"
+				]
+			},
+			{
+				"name": "吴忠市",
+				"area": [
+					"利通区",
+					"青铜峡市",
+					"盐池县",
+					"同心县"
+				]
+			},
+			{
+				"name": "固原市",
+				"area": [
+					"原州区",
+					"西吉县",
+					"隆德县",
+					"泾源县",
+					"彭阳县"
+				]
+			},
+			{
+				"name": "中卫市",
+				"area": [
+					"沙坡头区",
+					"中宁县",
+					"海原县"
+				]
+			}
+		]
+	},
+	{
+		"name": "新疆",
+		"city": [{
+				"name": "乌鲁木齐市",
+				"area": [
+					"天山区",
+					"沙依巴克区",
+					"新市区",
+					"水磨沟区",
+					"头屯河区",
+					"达坂城区",
+					"东山区",
+					"乌鲁木齐县"
+				]
+			},
+			{
+				"name": "克拉玛依市",
+				"area": [
+					"克拉玛依区",
+					"独山子区",
+					"白碱滩区",
+					"乌尔禾区"
+				]
+			},
+			{
+				"name": "吐鲁番地区",
+				"area": [
+					"吐鲁番市",
+					"托克逊县",
+					"鄯善县"
+				]
+			},
+			{
+				"name": "哈密地区",
+				"area": [
+					"哈密市",
+					"伊吾县",
+					"巴里坤哈萨克自治县"
+				]
+			},
+			{
+				"name": "和田地区",
+				"area": [
+					"和田市",
+					"和田县",
+					"洛浦县",
+					"民丰县",
+					"皮山县",
+					"策勒县",
+					"于田县",
+					"墨玉县"
+				]
+			},
+			{
+				"name": "阿克苏地区",
+				"area": [
+					"阿克苏市",
+					"温宿县",
+					"沙雅县",
+					"拜城县",
+					"阿瓦提县",
+					"库车县",
+					"柯坪县",
+					"新和县",
+					"乌什县"
+				]
+			},
+			{
+				"name": "喀什地区",
+				"area": [
+					"喀什市",
+					"巴楚县",
+					"泽普县",
+					"伽师县",
+					"叶城县",
+					"岳普湖县",
+					"疏勒县",
+					"麦盖提县",
+					"英吉沙县",
+					"莎车县",
+					"疏附县",
+					"塔什库尔干塔吉克自治县"
+				]
+			},
+			{
+				"name": "克孜勒苏柯尔克孜自治州",
+				"area": [
+					"阿图什市",
+					"阿合奇县",
+					"乌恰县",
+					"阿克陶县"
+				]
+			},
+			{
+				"name": "巴音郭楞蒙古自治州",
+				"area": [
+					"库尔勒市",
+					"和静县",
+					"尉犁县",
+					"和硕县",
+					"且末县",
+					"博湖县",
+					"轮台县",
+					"若羌县",
+					"焉耆回族自治县"
+				]
+			},
+			{
+				"name": "昌吉回族自治州",
+				"area": [
+					"昌吉市",
+					"阜康市",
+					"奇台县",
+					"玛纳斯县",
+					"吉木萨尔县",
+					"呼图壁县",
+					"木垒哈萨克自治县",
+					"米泉市"
+				]
+			},
+			{
+				"name": "博尔塔拉蒙古自治州",
+				"area": [
+					"博乐市",
+					"精河县",
+					"温泉县"
+				]
+			},
+			{
+				"name": "石河子",
+				"area": [
+					"石河子"
+				]
+			},
+			{
+				"name": "阿拉尔",
+				"area": [
+					"阿拉尔"
+				]
+			},
+			{
+				"name": "图木舒克",
+				"area": [
+					"图木舒克"
+				]
+			},
+			{
+				"name": "五家渠",
+				"area": [
+					"五家渠"
+				]
+			},
+			{
+				"name": "伊犁哈萨克自治州",
+				"area": [
+					"伊宁市",
+					"奎屯市",
+					"伊宁县",
+					"特克斯县",
+					"尼勒克县",
+					"昭苏县",
+					"新源县",
+					"霍城县",
+					"巩留县",
+					"察布查尔锡伯自治县",
+					"塔城地区",
+					"阿勒泰地区"
+				]
+			}
+		]
+	},
+	{
+		"name": "台湾省",
+		"city": [{
+				"name": "台北市",
+				"area": [
+					"内湖区",
+					"南港区",
+					"中正区",
+					"万华区",
+					"大同区",
+					"中山区",
+					"松山区",
+					"大安区",
+					"信义区",
+					"文山区",
+					"士林区",
+					"北投区"
+				]
+			},
+			{
+				"name": "新北市",
+				"area": [
+					"板桥区",
+					"汐止区",
+					"新店区"
+				]
+			},
+			{
+				"name": "桃园市",
+				"area": [
+					"其他"
+				]
+			},
+			{
+				"name": "台中市",
+				"area": [
+					"其他"
+				]
+			},
+			{
+				"name": "台南市",
+				"area": [
+					"其他"
+				]
+			},
+			{
+				"name": "高雄市",
+				"area": [
+					"其他"
+				]
+			}
+		]
+	},
+	{
+		"name": "澳门",
+		"city": [{
+			"name": "澳门",
+			"area": [
+				"花地玛堂区",
+				"圣安多尼堂区",
+				"大堂区",
+				"望德堂区",
+				"风顺堂区",
+				"嘉模堂区",
+				"圣方济各堂区",
+				"路凼"
+			]
+		}]
+	},
+	{
+		"name": "香港",
+		"city": [{
+			"name": "香港",
+			"area": [
+				"深水埗区",
+				"油尖旺区",
+				"九龙城区",
+				"黄大仙区",
+				"观塘区",
+				"北区",
+				"大埔区",
+				"沙田区",
+				"西贡区",
+				"元朗区",
+				"屯门区",
+				"荃湾区",
+				"葵青区",
+				"离岛区",
+				"中西区",
+				"湾仔区",
+				"东区",
+				"南区"
+			]
+		}]
+	}
+]

+ 103 - 0
pageApp/address/pickerAddress.vue

@@ -0,0 +1,103 @@
+<template>
+	<picker @change="bindPickerChange" @columnchange="columnchange" :range="array" range-key="name" :value="value"
+		mode="multiSelector">
+		<slot></slot>
+	</picker>
+</template>
+
+<script>
+	import AllAddress from './data.js'
+	let selectVal = ['', '', '']
+	export default {
+		data() {
+			return {
+				value: [0, 0, 0],
+				array: [],
+				index: 0
+			}
+		},
+		created() {
+			this.initSelect()
+		},
+		methods: {
+			// 初始化地址选项
+			initSelect() {
+				this.updateSourceDate() // 更新源数据
+					.updateAddressDate() // 更新结果数据
+					.$forceUpdate() // 触发双向绑定
+			},
+			// 地址控件改变控件
+			columnchange(d) {
+				this.updateSelectIndex(d.detail.column, d.detail.value) // 更新选择索引
+					.updateSourceDate() // 更新源数据
+					.updateAddressDate() // 更新结果数据
+					.$forceUpdate() // 触发双向绑定
+			},
+
+			/**
+			 * 更新源数据
+			 * */
+			updateSourceDate() {
+				this.array = []
+				this.array[0] = AllAddress.map(obj => {
+					return {
+						name: obj.name
+					}
+				})
+				this.array[1] = AllAddress[this.value[0]].city.map(obj => {
+					return {
+						name: obj.name
+					}
+				})
+				this.array[2] = AllAddress[this.value[0]].city[this.value[1]].area.map(obj => {
+					return {
+						name: obj
+					}
+				})
+				return this
+			},
+
+			/**
+			 * 更新索引
+			 * */
+			updateSelectIndex(column, value) {
+				let arr = JSON.parse(JSON.stringify(this.value))
+				arr[column] = value
+				if (column === 0) {
+					arr[1] = 0
+					arr[2] = 0
+				}
+				if (column === 1) {
+					arr[2] = 0
+				}
+				this.value = arr
+				return this
+			},
+
+			/**
+			 * 更新结果数据 
+			 * */
+			updateAddressDate() {
+				selectVal[0] = this.array[0][this.value[0]].name
+				selectVal[1] = this.array[1][this.value[1]].name
+				selectVal[2] = this.array[2][this.value[2]].name
+				return this
+			},
+
+			/**
+			 * 点击确定
+			 * */
+			bindPickerChange(e) {
+				this.$emit('change', {
+					index: this.value,
+					data: selectVal
+				})
+				return this
+			}
+
+		}
+	}
+</script>
+
+<style scoped>
+</style>

+ 131 - 0
pageApp/administration/conference.vue

@@ -0,0 +1,131 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							会议名称
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					会议议题:
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.totalTime">
+					</uni-easyinput>
+				</view>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					会议参加人员:
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.totalTime">
+					</uni-easyinput>
+				</view>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							会议时间
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.leaveStartTime"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							会议室
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					会议室备注:
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.totalTime">
+					</uni-easyinput>
+				</view>
+			</view>
+		</view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="submit"
+							color="rgb(55,186,189)" text="提交"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				isDisabled: false,
+				index: 0,
+				wpTypes: ['办公用品','固定资产','低值易耗品','广告印刷品','其他']
+			}
+		},
+		methods: {
+			submit() {
+
+			},
+			onchange(e) {
+				setTimeout(() => {
+
+				}, 200)
+			},
+			maskClick(e) {},
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 15rpx 5rpx;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 294 - 0
pageApp/administration/inform.vue

@@ -0,0 +1,294 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							标题
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.noticeTitle">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							发起人
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.noticeUsers" disabled>
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							接收人
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<picker @change="deptBindPickerChange" :value="deptConfig.deptIndex"
+								:range="deptConfig.deptDatas" range-key="deptName">
+								<view class="pickerText"
+									v-if="deptConfig.deptDatas && deptConfig.deptDatas.length>0 && deptConfig.deptIndex !== undefined">
+									{{ deptConfig.deptDatas[deptConfig.deptIndex].deptName }}
+								</view>
+								<view class="pickerText" v-else>
+									{{defaultDept}}
+								</view>
+							</picker>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					通知内容
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.contentOfNotice">
+					</uni-easyinput>
+				</view>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					备注
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.remark">
+					</uni-easyinput>
+				</view>
+			</view>
+		</view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="submit"
+							color="rgb(55,186,189)" text="提交"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+		<!-- 下一步选择人员弹窗 -->
+		<uni-popup ref="popup" background-color="#fff">
+			<view style="height: 800rpx;">
+				<view class="desc">
+					<uni-row>
+						<uni-col :span="10">
+							<view style="font-size: 40rpx;color: rgb(145, 145, 145);">
+							</view>
+						</uni-col>
+						<uni-col :span="11">
+							<view style="font-size: 40rpx;color: rgb(98, 98, 98);">
+								下一步
+							</view>
+						</uni-col>
+						<uni-col :span="3">
+							<view @click="submitPass" style="font-size: 40rpx;color: rgb(55,186,189);">
+								确认
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+				<view>
+					<!--  -->
+					<uni-row>
+						<uni-col>
+							<view style="padding: 15rpx 20rpx;">
+								<uni-data-picker ref="picker" placeholder="请选择" :popup-title="selectTitle"
+									:localdata="dataTree" v-model="hxForm.candidate" @change="nextApprovalChange">
+								</uni-data-picker>
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				isDisabled: false,
+				selectTitle: '',
+				hxForm: {},
+				pageType: '',
+				searchGoodsName: '',
+				dataTree: [],
+				form: {
+					goodsId: '',
+					goodsName: '',
+					amount: 1,
+					unit: '',
+					remark: ''
+				},
+				org_dept_parent_id: '',
+				index: 0,
+				defaultDept: ''
+			}
+		},
+		onLoad() {
+			//申请人初始化
+			this.form.applyUserName = uni.getStorageSync("userInfo").nickName
+		},
+		methods: {
+			change(e) {
+				console.log(e);
+			},
+			radioChange: function(evt) {
+				this.form.remark = evt.detail.value
+			},
+			async submit() {
+				this.isDisabled = true
+				setTimeout(() => {
+					this.isDisabled = false
+				}, 1000)
+				// if (!this.form.applyDepartment) {
+				// 	this.isDisabled = false
+				// 	uni.showModal({
+				// 		content: '请选择所属部门',
+				// 		title: '提交失败',
+				// 		showCancel: false
+				// 	})
+				// 	return
+				// }
+				// if (!this.form.goodsName) {
+				// 	this.isDisabled = false
+				// 	uni.showModal({
+				// 		content: '请选择物资',
+				// 		title: '提交失败',
+				// 		showCancel: false
+				// 	})
+				// 	return
+				// }
+				// if (!this.form.amount) {
+				// 	this.isDisabled = false
+				// 	uni.showModal({
+				// 		content: '请填写数量',
+				// 		title: '提交失败',
+				// 		showCancel: false
+				// 	})
+				// 	return
+				// }
+				// if (!this.form.applyReason) {
+				// 	this.isDisabled = false
+				// 	uni.showModal({
+				// 		content: '请选择领用类型',
+				// 		title: '提交失败',
+				// 		showCancel: false
+				// 	})
+				// 	return
+				// }
+				//统一写入参数
+				this.form.applyUserId = uni.getStorageSync('setUserName')
+				this.form.applyUserName = uni.getStorageSync('userInfo').nickName
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/submitApply/instantNotice',
+					method: 'post',
+					data: this.form,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataTree = res.data.tree
+					this.hxForm.taskId = res.data.taskId
+					this.$refs.popup.open('bottom')
+					this.selectTitle = "请选择" + this.dataTree[0].text
+					this.isDisabled = false
+				} else {
+					this.$showModal(res.msg)
+				}
+				this.isDisabled = false
+			},
+			async submitPass() {
+				if (!this.hxForm.candidate) {
+					uni.showModal({
+						content: '请选择' + this.dataTree[0].text,
+						title: '提交失败',
+						showCancel: false,
+					})
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/task/submit/candidate?taskId=' + this.hxForm.taskId +
+						'&candidate=' + this.hxForm.candidate + '&applyUserName=' + this.hxForm.applyUserName,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: '已提交给审批人员',
+						title: '提交成功',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						content: res.msg,
+						title: '提交失败',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				}
+			},
+			nextApprovalChange(e) {
+				// console.log('onchange:', e.detail.value[1].text);
+				this.hxForm.applyUserName = e.detail.value[1].text
+				this.hxForm.candidate = e.detail.value[1].value
+			},
+			maskClick(e) {}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 586 - 0
pageApp/administration/reserve.vue

@@ -0,0 +1,586 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							申请人
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.applyUserName" disabled>
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							申请部门
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<picker @change="deptBindPickerChange" :value="deptConfig.deptIndex"
+								:range="deptConfig.deptDatas" range-key="deptName">
+								<view class="pickerText"
+									v-if="deptConfig.deptDatas && deptConfig.deptDatas.length>0 && deptConfig.deptIndex !== undefined">
+									{{ deptConfig.deptDatas[deptConfig.deptIndex].deptName }}
+								</view>
+								<view class="pickerText" v-else>
+									{{defaultDept}}
+								</view>
+							</picker>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc" v-if="pageType === 'dj'">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							登记类型
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<picker @change="accessBindPickerChange" :value="accessStorageType.index"
+								:range="accessStorageType.data" range-key="dictLabel">
+								<view class="pickerText"
+									v-if="accessStorageType.data && accessStorageType.data.length>0 && accessStorageType.index !== undefined">
+									{{ accessStorageType.data[accessStorageType.index].dictLabel }}
+								</view>
+								<view class="pickerText" v-else>
+									待 选 择
+								</view>
+							</picker>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc" v-if="pageType === 'ly'">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							领用类型
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<picker @change="dictBindPickerChange" :value="outStorageType.index"
+								:range="outStorageType.data" range-key="dictLabel">
+								<view class="pickerText"
+									v-if="outStorageType.data && outStorageType.data.length>0 && outStorageType.index !== undefined">
+									{{ outStorageType.data[outStorageType.index].dictLabel }}
+								</view>
+								<view class="pickerText" v-else>
+									待 选 择
+								</view>
+							</picker>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc" v-if="pageType === 'gh'">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							物品状态
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<radio-group @change="radioChange">
+								<uni-col :span="12" v-for="(item, index) in radiolist1">
+									<label :key="item.value">
+										<radio color="rgb(55,186,189)" :value="item.value" :checked="index === current">
+											{{item.value}}
+										</radio>
+									</label>
+								</uni-col>
+							</radio-group>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							物资类型
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<picker @change="oneBindPickerChange" :value="typeData.oneTypeIndex"
+								:range="typeData.oneType" range-key="goodsTypeName">
+								<view class="pickerText"
+									v-if="typeData.oneType && typeData.oneType.length>0 && typeData.oneTypeIndex !== undefined">
+									{{ typeData.oneType[typeData.oneTypeIndex].goodsTypeName }}
+								</view>
+								<view class="pickerText" v-else>
+									待 选 择
+								</view>
+							</picker>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							具体分类
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<picker @change="twoBindPickerChange" :value="typeData.twoTypeIndex"
+								:range="typeData.twoType" range-key="goodsTypeName"
+								:disabled="typeData.twoTypeDisabled">
+								<view class="pickerText"
+									v-if="typeData.twoType && typeData.twoType.length>0 && typeData.oneTypeIndex !== undefined">
+									{{ typeData.twoType[typeData.twoTypeIndex].goodsTypeName }}
+								</view>
+								<view class="pickerText" v-else @click="isTwoTypeShowModal()">
+									待 选 择
+								</view>
+							</picker>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							物资名称
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView pickerText">
+							<view @click="openGoodsPopup" class="pickerText" v-if="form.goodsName">
+								{{form.goodsName}}
+							</view>
+							<view @click="openGoodsPopup" class="pickerText" v-else>
+								待 选 择
+							</view>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							单位
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view class="pickerView">
+							<view class="pickerText" v-if="form.unit">
+								{{form.unit}}
+							</view>
+							<view class="pickerText" v-else>
+								暂无
+							</view>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;" v-if="pageType === 'dj'">
+							登记数量
+						</view>
+						<view class="desc" style="font-size: 25rpx;" v-if="pageType === 'ly'">
+							申请数量
+						</view>
+						<view class="desc" style="font-size: 25rpx;" v-if="pageType === 'gh'">
+							归还数量
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<u-number-box v-model="form.amount"></u-number-box>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc" v-if="pageType === 'ly'">
+				<view class="desc" style="font-size: 25rpx;">
+					备注:
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.remark">
+					</uni-easyinput>
+				</view>
+			</view>
+		</view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="submit"
+							color="rgb(55,186,189)" text="提交"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+		<!-- 物资选择弹窗 -->
+		<uni-popup ref="goodsPopup" background-color="#fff">
+			<view style="height: 800rpx;">
+				<view style="padding: 30rpx;">
+					<u-search v-model="searchGoodsName" :show-action="false" placeholder="快捷搜索"
+						@change="getAppGoodsData(typeData.twoType[typeData.twoTypeIndex].id)"></u-search>
+				</view>
+				<view style="padding: 5rpx;">
+					<uni-list v-for="item in goodsData">
+						<uni-list-item :clickable="true" @click="goodsToSubmiut(item)" :title="item.name" />
+					</uni-list>
+				</view>
+			</view>
+		</uni-popup>
+		<!-- 下一步选择人员弹窗 -->
+		<uni-popup ref="popup" background-color="#fff">
+			<view style="height: 800rpx;">
+				<view class="desc">
+					<uni-row>
+						<uni-col :span="10">
+							<view style="font-size: 40rpx;color: rgb(145, 145, 145);">
+							</view>
+						</uni-col>
+						<uni-col :span="11">
+							<view style="font-size: 40rpx;color: rgb(98, 98, 98);">
+								下一步
+							</view>
+						</uni-col>
+						<uni-col :span="3">
+							<view @click="submitPass" style="font-size: 40rpx;color: rgb(55,186,189);">
+								确认
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+				<view>
+					<!--  -->
+					<uni-row>
+						<uni-col>
+							<view style="padding: 15rpx 20rpx;">
+								<uni-data-picker ref="picker" placeholder="请选择" :popup-title="selectTitle"
+									:localdata="dataTree" v-model="hxForm.candidate" @change="nextApprovalChange">
+								</uni-data-picker>
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				isDisabled: false,
+				selectTitle: '',
+				form: {
+					goodsId: '',
+					goodsName: '',
+					amount: 1,
+					unit: '',
+					remark: ''
+				},
+				org_dept_parent_id: '',
+				searchGoodsName: '',
+				hxForm: {},
+				dataTree: [],
+				index: 0,
+				defaultDept: '',
+				reserve_type: [],
+				goodsData: [],
+				deptConfig: {
+					deptDatas: [],
+					deptIndex: undefined
+				},
+				current: 0,
+				radiolist1: [{
+					value: '正常'
+				}, {
+					value: '异常'
+				}, {
+					value: '损坏'
+				}],
+				typeData: {
+					oneTypeIndex: undefined,
+					oneType: [],
+					twoTypeIndex: undefined,
+					twoType: [],
+					twoTypeDisabled: true
+				},
+				outStorageType: {
+					index: undefined,
+					data: []
+				},
+				accessStorageType: {
+					index: undefined,
+					data: []
+				},
+				pageType: ''
+			}
+		},
+		onLoad() {
+			this.pageType = this.$root.$mp.query.pageType
+			let title = ''
+			switch (this.pageType) {
+				case "dj":
+					title = '物资登记'
+					this.accessStorageType.data = uni.getStorageSync('access_stroage_type')
+					this.form.recordType = 1
+					break
+				case "ly":
+					title = '物资领用'
+					this.outStorageType.data = uni.getStorageSync('out_storage_type')
+					this.form.recordType = 2
+					break
+				case "gh":
+					title = '物资归还'
+					this.form.recordType = 3
+					this.form.applyReason = 5
+					this.form.remark = '正常'
+					break
+			}
+			uni.setNavigationBarTitle({
+				title: title
+			})
+			//物资一级分类初始化
+			this.getAppGoodsTypeData('')
+			//机构信息初始化
+			this.deptConfig.deptDatas = uni.getStorageSync('deptData')
+			//申请人初始化
+			this.form.applyUserName = uni.getStorageSync("userInfo").nickName
+			//翻译默认部门
+			let department = uni.getStorageSync('files').department
+			this.defaultDept = this.$dictTranslation(department, 'deptData', 'dept')
+			this.form.applyDepartment = department
+		},
+		methods: {
+			openGoodsPopup() {
+				if (!this.typeData.twoTypeDisabled) {
+					this.$refs.goodsPopup.open('bottom')
+				} else {
+					this.$showModal('请先选择具体分类')
+				}
+			},
+			isTwoTypeShowModal() {
+				if (this.typeData.twoTypeDisabled) {
+					this.$showModal('请先选择物资类型')
+				}
+			},
+			change(e) {
+				console.log(e);
+			},
+			radioChange: function(evt) {
+				this.form.remark = evt.detail.value
+			},
+			async submit() {
+				this.isDisabled = true
+				setTimeout(() => {
+					this.isDisabled = false
+				}, 1000)
+				if (!this.form.applyDepartment) {
+					this.isDisabled = false
+					uni.showModal({
+						content: '请选择所属部门',
+						title: '提交失败',
+						showCancel: false
+					})
+					return
+				}
+				if (!this.form.goodsName) {
+					this.isDisabled = false
+					uni.showModal({
+						content: '请选择物资',
+						title: '提交失败',
+						showCancel: false
+					})
+					return
+				}
+				if (!this.form.amount) {
+					this.isDisabled = false
+					uni.showModal({
+						content: '请填写数量',
+						title: '提交失败',
+						showCancel: false
+					})
+					return
+				}
+				if (!this.form.applyReason) {
+					this.isDisabled = false
+					uni.showModal({
+						content: '请选择领用类型',
+						title: '提交失败',
+						showCancel: false
+					})
+					return
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/submitApply/rcr',
+					method: 'post',
+					data: this.form
+				});
+				if (res.code === 200) {
+					this.dataTree = res.data.tree
+					this.hxForm.taskId = res.data.taskId
+					this.$refs.popup.open('bottom')
+					this.selectTitle = "请选择" + this.dataTree[0].text
+					this.isDisabled = false
+				} else {
+					this.$showModal(res.msg)
+				}
+				this.isDisabled = false
+			},
+			async submitPass() {
+				if (!this.hxForm.candidate) {
+					uni.showModal({
+						content: '请选择' + this.dataTree[0].text,
+						title: '提交失败',
+						showCancel: false,
+					})
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/task/submit/candidate?taskId=' + this.hxForm.taskId +
+						'&candidate=' + this.hxForm.candidate + '&applyUserName=' + this.hxForm.applyUserName,
+					method: 'get',
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: '已提交给审批人员',
+						title: '提交成功',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						content: res.msg,
+						title: '提交失败',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				}
+			},
+			nextApprovalChange(e) {
+				// console.log('onchange:', e.detail.value[1].text);
+				this.hxForm.applyUserName = e.detail.value[1].text
+				this.hxForm.candidate = e.detail.value[1].value
+			},
+			//获取物资一级/二级类型
+			async getAppGoodsTypeData(type) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/goodsType?type=' + type,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (type) {
+						this.typeData.twoType = res.data
+						this.getAppGoodsData(this.typeData.twoType[0].id)
+					} else {
+						this.typeData.oneType = res.data
+						this.getAppGoodsTypeData(this.typeData.oneType[0].id)
+					}
+				}
+			},
+			//获取物资信息/查询物资信息
+			async getAppGoodsData(type) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/goodses?type=' + type + '&name=' + this.searchGoodsName,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.goodsData = res.data
+				}
+			},
+			//选择物资form赋值
+			goodsToSubmiut(item) {
+				this.form.goodsName = item.name
+				this.form.goodsId = item.id
+				this.form.unit = item.unit
+				this.$refs.goodsPopup.close()
+			},
+			maskClick(e) {},
+
+			//选择框赋值区
+			oneBindPickerChange: function(e) {
+				this.typeData.oneTypeIndex = e.detail.value
+				this.getAppGoodsTypeData(this.typeData.oneType[this.typeData.oneTypeIndex].id)
+				this.typeData.twoTypeIndex = 0
+				this.typeData.twoTypeDisabled = false
+				this.form.goodsName = ''
+			},
+			twoBindPickerChange: function(e) {
+				this.typeData.twoTypeIndex = e.detail.value
+				this.form.goodsName = ''
+			},
+			deptBindPickerChange: function(e) {
+				this.deptConfig.deptIndex = e.detail.value
+				this.form.applyDepartment = this.deptConfig.deptDatas[this.deptConfig.deptIndex].deptId
+			},
+			dictBindPickerChange: function(e) {
+				this.outStorageType.index = e.detail.value
+				this.form.applyReason = this.outStorageType.data[this.outStorageType.index].dictValue
+			},
+			accessBindPickerChange: function(e) {
+				this.accessStorageType.index = e.detail.value
+				this.form.applyReason = this.accessStorageType.data[this.accessStorageType.index].dictValue
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 212 - 0
pageApp/administration/useCar.vue

@@ -0,0 +1,212 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							申请人
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							申请部门
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							申请时间
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.leaveStartTime"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					申请事由:
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.totalTime">
+					</uni-easyinput>
+				</view>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							乘车人数
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							车型车号
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							始发地
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							目的地
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-easyinput primaryColor="#37babd" v-model="form.totalTime">
+							</uni-easyinput>
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							出发时间
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.leaveStartTime"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							归还时间
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.leaveStartTime"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<view class="desc" style="font-size: 25rpx;">
+					申请用途:
+				</view>
+				<view>
+					<uni-easyinput type="textarea" primaryColor="#37babd" v-model="form.totalTime">
+					</uni-easyinput>
+				</view>
+			</view>
+		</view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="submit"
+							color="rgb(55,186,189)" text="提交"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				isDisabled: false,
+				index: 0,
+				wpTypes: ['办公用品', '固定资产', '低值易耗品', '广告印刷品', '其他']
+			}
+		},
+		methods: {
+			submit() {
+
+			},
+			onchange(e) {
+				setTimeout(() => {
+
+				}, 200)
+			},
+			maskClick(e) {},
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 15rpx 5rpx;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 254 - 0
pageApp/administration/useSeal.vue

@@ -0,0 +1,254 @@
+<template>
+	<view>
+		<view style="padding:5rpx 20rpx 45rpx 20rpx;">
+			<view class="desc">
+				<hs-input label="申请人" v-model="form.name" :disabled="true" />
+			</view>
+			<view class="desc">
+				<hs-dept-select label="部门" v-model="form.department" :autofill="true" />
+			</view>
+			<view class="desc">
+				<hs-dict-select label="使用形式" dictKey="hzl_seal_use_type" v-model="form.usA" />
+			</view>
+			<view class="desc">
+				<hs-dict-select label="印章类型" dictKey="seal_type" v-model="form.usB" />
+			</view>
+			<view class="desc">
+				<hs-dict-select label="使用地点" dictKey="hzl_seal_use_address" v-model="form.usE" />
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="6">
+						<view class="desc" style="font-size: 25rpx;">
+							用印开始时间
+						</view>
+					</uni-col>
+					<uni-col :span="18">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.usF"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="6">
+						<view class="desc" style="font-size: 25rpx;">
+							用印结束时间
+						</view>
+					</uni-col>
+					<uni-col :span="18">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.usD"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<uni-row>
+					<uni-col :span="5">
+						<view class="desc" style="font-size: 25rpx;">
+							归还时间
+						</view>
+					</uni-col>
+					<uni-col :span="19">
+						<view>
+							<uni-datetime-picker type="date" :clear-icon="false" v-model="form.usJ"
+								@maskClick="maskClick" @change="onchange()" />
+						</view>
+					</uni-col>
+				</uni-row>
+			</view>
+			<view class="desc">
+				<hs-dict-select label="文件类型" dictKey="hzl_file_type" v-model="form.soG" />
+			</view>
+			<view class="desc">
+				<hs-input label="文件名称" v-model="form.soH" model="textarea" />
+			</view>
+			<view class="desc">
+				<hs-input label="文件份数" v-model="form.soI" />
+			</view>
+			<view class="desc">
+				<hs-input label="申请原因" v-model="form.conclusion" model="textarea" />
+			</view>
+		</view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="submit"
+							color="rgb(55,186,189)" text="提交"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+		<!-- 下一步选择人员弹窗 -->
+		<uni-popup ref="popup" background-color="#fff">
+			<view style="height: 800rpx;">
+				<view class="desc">
+					<uni-row>
+						<uni-col :span="10">
+							<view style="font-size: 40rpx;color: rgb(145, 145, 145);">
+							</view>
+						</uni-col>
+						<uni-col :span="11">
+							<view style="font-size: 40rpx;color: rgb(98, 98, 98);">
+								下一步
+							</view>
+						</uni-col>
+						<uni-col :span="3">
+							<view @click="submitPass" style="font-size: 40rpx;color: rgb(55,186,189);">
+								确认
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+				<view>
+					<!--  -->
+					<uni-row>
+						<uni-col>
+							<view style="padding: 15rpx 20rpx;">
+								<uni-data-picker ref="picker" placeholder="请选择" :popup-title="selectTitle"
+									:localdata="dataTree" v-model="hxForm.candidate" @change="nextApprovalChange">
+								</uni-data-picker>
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				isDisabled: false,
+				selectTitle: '',
+				hxForm: {},
+				pageType: '',
+				searchGoodsName: '',
+				dataTree: [],
+				index: 0,
+				sealTypes: ['公章', '合同专用章', '财务专用章', '携带外出办公', '其他'],
+				deptConfig: {
+					deptDatas: [],
+					deptIndex: uni.getStorageSync('deptData'),
+				},
+				defaultDept: '',
+				form: {}
+			}
+		},
+		onLoad() {
+			//申请人初始化
+			this.form.name = uni.getStorageSync("userInfo").nickName
+		},
+		methods: {
+			async submit() {
+				this.isDisabled = true
+				setTimeout(() => {
+					this.isDisabled = false
+				}, 1000)
+				//统一写入参数
+				this.form.applyUserId = uni.getStorageSync('setUserName')
+				this.form.applyUserName = uni.getStorageSync('userInfo').nickName
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/submitApply/useSeal',
+					method: 'post',
+					data: this.form,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataTree = res.data.tree
+					this.hxForm.taskId = res.data.taskId
+					this.$refs.popup.open('bottom')
+					this.selectTitle = "请选择" + this.dataTree[0].text
+					this.isDisabled = false
+				} else {
+					this.$showModal(res.msg)
+				}
+				this.isDisabled = false
+			},
+			async submitPass() {
+				if (!this.hxForm.candidate) {
+					uni.showModal({
+						content: '请选择' + this.dataTree[0].text,
+						title: '提交失败',
+						showCancel: false,
+					})
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/task/submit/candidate?taskId=' + this.hxForm.taskId +
+						'&candidate=' + this.hxForm.candidate + '&applyUserName=' + this.hxForm.applyUserName,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: '已提交给审批人员',
+						title: '提交成功',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						content: res.msg,
+						title: '提交失败',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				}
+			},
+			nextApprovalChange(e) {
+				// console.log('onchange:', e.detail.value[1].text);
+				this.hxForm.applyUserName = e.detail.value[1].text
+				this.hxForm.candidate = e.detail.value[1].value
+			},
+			maskClick(e) {},
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 85 - 0
pageApp/components/deptSelect.vue

@@ -0,0 +1,85 @@
+<template>
+	<view class="desc">
+		<uni-row>
+			<uni-col :span="5">
+				<view class="desc" style="font-size: 25rpx;">
+					{{label}}
+				</view>
+			</uni-col>
+			<uni-col :span="19">
+				<view class="pickerView">
+					<picker @change="deptBindPickerChange" :value="deptConfig.deptIndex" :range="deptConfig.deptDatas"
+						range-key="deptName">
+						<view class="pickerText"
+							v-if="deptConfig.deptDatas && deptConfig.deptDatas.length>0 && deptConfig.deptIndex !== undefined">
+							{{ deptConfig.deptDatas[deptConfig.deptIndex].deptName }}
+						</view>
+						<view class="pickerText" v-else>
+							{{defaultDept}}
+						</view>
+					</picker>
+				</view>
+			</uni-col>
+		</uni-row>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'hs-dept-select',
+		props: {
+			value: {
+				Type: String,
+				default: null
+			},
+			label: {
+				Type: String,
+				default: '岗位'
+			},
+			autofill: false
+		},
+		data() {
+			return {
+				defaultDept: '待 选 择',
+				deptConfig: {
+					deptDatas: uni.getStorageSync('deptData'),
+					deptIndex: undefined
+				},
+			}
+		},
+		mounted() {
+			if (this.autofill) {
+				//翻译默认部门
+				let department = uni.getStorageSync('files').department
+				this.defaultDept = this.$dictTranslation(department, 'deptData', 'dept')
+				this.$emit('input', department)
+			}
+		},
+		methods: {
+			deptBindPickerChange: function(e) {
+				this.deptConfig.deptIndex = e.detail.value
+				this.$emit('input', this.deptConfig.deptDatas[this.deptConfig.deptIndex].deptId)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 15rpx 0 15rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		margin-right: 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+</style>

+ 79 - 0
pageApp/components/dictSelect.vue

@@ -0,0 +1,79 @@
+<template>
+	<view class="desc">
+		<uni-row>
+			<uni-col :span="5">
+				<view class="desc" style="font-size: 25rpx;">
+					{{label}}
+				</view>
+			</uni-col>
+			<uni-col :span="19">
+				<view class="pickerView">
+					<picker @change="bindPickerChange" :value="index" :range="data" range-key="dictLabel">
+						<view class="pickerText" v-if="data && data.length>0 && index !== undefined">
+							{{ data[index].dictLabel }}
+						</view>
+						<view class="pickerText" v-else>
+							待 选 择
+						</view>
+					</picker>
+				</view>
+			</uni-col>
+		</uni-row>
+	</view>
+</template>
+
+<script>
+	// 
+	export default {
+		name: 'hs-post-select',
+		props: {
+			value: {
+				Type: String,
+				default: null
+			},
+			label: {
+				Type: String,
+				default: '岗位'
+			},
+			dictKey: {
+				Type: String,
+				default: null
+			},
+		},
+		data() {
+			return {
+				data: [],
+				index: undefined
+			}
+		},
+		mounted() {
+			this.data = uni.getStorageSync(this.dictKey)
+		},
+		methods: {
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+				this.$emit('input', this.data[this.index].dictValue)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 15rpx 0 15rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		margin-right: 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+</style>

+ 182 - 0
pageApp/components/flowSubmit.vue

@@ -0,0 +1,182 @@
+<template>
+	<view>
+		<u-gap height="70" bgColor="#ffffff"></u-gap>
+		<view class="bottim_view">
+			<view>
+				<u-row>
+					<u-col span="11">
+						<u-button :disabled="isDisabled" class="btnDoPay" shape="circle" @click="verify"
+							color="rgb(55,186,189)" text="提交"></u-button>
+					</u-col>
+				</u-row>
+			</view>
+		</view>
+		<!-- 下一步选择人员弹窗 -->
+		<uni-popup ref="popup" background-color="#fff">
+			<view style="height: 800rpx;">
+				<view class="desc">
+					<uni-row>
+						<uni-col :span="10">
+							<view style="font-size: 40rpx;color: rgb(145, 145, 145);">
+							</view>
+						</uni-col>
+						<uni-col :span="11">
+							<view style="font-size: 40rpx;color: rgb(98, 98, 98);">
+								下一步
+							</view>
+						</uni-col>
+						<uni-col :span="3">
+							<view @click="submitPass" style="font-size: 40rpx;color: rgb(55,186,189);">
+								确认
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+				<view>
+					<!--  -->
+					<uni-row>
+						<uni-col>
+							<view style="padding: 15rpx 20rpx;">
+								<uni-data-picker ref="picker" placeholder="请选择" :popup-title="selectTitle"
+									:localdata="dataTree" v-model="hxForm.candidate" @change="nextApprovalChange">
+								</uni-data-picker>
+							</view>
+						</uni-col>
+					</uni-row>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			api: {
+				type: String,
+				default: null
+			},
+			data: {}
+		},
+		data() {
+			return {
+				isDisabled: false,
+				selectTitle: '',
+				hxForm: {},
+				pageType: '',
+				searchGoodsName: '',
+				dataTree: [],
+				index: 0,
+				defaultDept: '',
+				form: {}
+			}
+		},
+		onLoad() {
+
+		},
+		methods: {
+			/**字段验证方法*/
+			verify() {
+				this.$emit('verify')
+			},
+			async submit() {
+				this.isDisabled = true
+				setTimeout(() => {
+					this.isDisabled = false
+				}, 1000)
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/submitApply/' + this.api,
+					method: 'post',
+					data: this.data,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataTree = res.data.tree
+					this.hxForm.taskId = res.data.taskId
+					this.$refs.popup.open('bottom')
+					this.selectTitle = "请选择" + this.dataTree[0].text
+					this.isDisabled = false
+				} else {
+					this.$showModal(res.msg)
+				}
+				this.isDisabled = false
+			},
+			async submitPass() {
+				if (!this.hxForm.candidate) {
+					uni.showModal({
+						content: '请选择' + this.dataTree[0].text,
+						title: '提交失败',
+						showCancel: false,
+					})
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/task/submit/candidate?taskId=' + this.hxForm.taskId +
+						'&candidate=' + this.hxForm.candidate + '&applyUserName=' + this.hxForm.applyUserName,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						content: '已提交给审批人员',
+						title: '提交成功',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						content: res.msg,
+						title: '提交失败',
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				}
+			},
+			nextApprovalChange(e) {
+				// console.log('onchange:', e.detail.value[1].text);
+				this.hxForm.applyUserName = e.detail.value[1].text
+				this.hxForm.candidate = e.detail.value[1].value
+			},
+			maskClick(e) {},
+			bindPickerChange: function(e) {
+				this.index = e.detail.value
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 5rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+
+	.bottim_view {
+		padding: 5px 20px 30px;
+		position: fixed;
+		left: 0px;
+		bottom: 0px;
+		width: 100%;
+		height: 40px;
+		background-color: #ffffff;
+	}
+</style>

+ 495 - 0
pageApp/components/ge.vue

@@ -0,0 +1,495 @@
+<template>
+	<view class="geHeight">
+		<view>
+			<u-gap height="10" bgColor="#f5f5f5"></u-gap>
+			<view v-if="data.pageType === 1">
+				<view class="desc" style="color: #bababa;">
+					批注:
+				</view>
+				<view class="desc">
+					<!-- <u--textarea v-model="pz" border="bottom"></u--textarea> -->
+					<uni-easyinput type="textarea" v-model="pz" primaryColor="rgb(55,186,189)" :inputBorder="false">
+					</uni-easyinput>
+				</view>
+			</view>
+			<u-gap height="10" bgColor="#f5f5f5"></u-gap>
+			<view class="desc">
+				<view>
+					<uni-steps :options="list1" :active="active" direction="column" active-color="rgb(55,186,189)" />
+				</view>
+			</view>
+		</view>
+		<view v-if="data.pageType == 3" class="bomButtonBody" style="height: 10%;">
+			<uni-row v-if="list1 && list1.length === 1">
+				<uni-col>
+					<view class="desc">
+						<u-button :disabled="isDisabled" color="rgb(55,186,189)" shape="circle" size="large"
+							@click="revoke">撤销
+						</u-button>
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<u-gap height="110"></u-gap>
+		<view v-if="data.pageType === 1 && zindeButtion === 1 && data.isEnd === '0'" class="bomButtonBody"
+			style="position: fixed;bottom: 0">
+			<uni-row>
+				<uni-col :span="8">
+					<view class="desc">
+						<u-button color="rgb(55,186,189)" shape="circle" size="large"
+							@click="passTrue('同意','RESULT_TRUE','bottom')">同意
+						</u-button>
+					</view>
+				</uni-col>
+				<uni-col :span="8">
+					<view class="desc">
+						<u-button color="rgb(188, 188, 188)" shape="circle" size="large"
+							@click="passTrue('驳回','RESULT_FALSE','bottom')">驳回</u-button>
+					</view>
+				</uni-col>
+				<uni-col :span="8">
+					<view class="desc">
+						<u-button color="rgb(136, 188, 160)" shape="circle" size="large"
+							@click="passTrue('驳回','RESULT_CASE_OF','bottom')">转交</u-button>
+					</view>
+				</uni-col>
+			</uni-row>
+		</view>
+		<view>
+			<!-- 普通弹窗 -->
+			<uni-popup ref="popup" background-color="#fff" @change="propChange">
+				<view class="popup-content" :class="{ 'popup-height': type === 'left' || type === 'right' }">
+					<view class="desc">
+						<uni-row>
+							<uni-col :span="8">
+								<view style="font-size: 40rpx;color: rgb(145, 145, 145);">
+								</view>
+							</uni-col>
+							<uni-col :span="13">
+								<view style="font-size: 40rpx;color: rgb(98, 98, 98);">
+									{{nextTitle}}
+								</view>
+							</uni-col>
+							<uni-col :span="3">
+								<view @click="submitPass" style="font-size: 40rpx;color: rgb(55,186,189);">
+									确认
+								</view>
+							</uni-col>
+						</uni-row>
+					</view>
+					<view class="desc">
+						<uni-row>
+							<uni-col>
+								<view class="desc">
+									<uni-data-picker ref="picker" placeholder="请选择" :popup-title="selectTitle"
+										:localdata="dataTree" v-model="nextUserName" @change="nextApprovalChange">
+									</uni-data-picker>
+								</view>
+							</uni-col>
+						</uni-row>
+					</view>
+				</view>
+			</uni-popup>
+		</view>
+		<view>
+			<!-- 驳回选择弹窗 -->
+			<uni-popup ref="popup2" background-color="#fff" @change="propChange">
+				<view style="height: 800rpx;">
+					<view class="desc">
+						<view style="text-align: center;font-size: 30rpx;color: rgb(98, 98, 98);">
+							驳回至以下任意流程
+						</view>
+					</view>
+					<view style="padding: 20rpx 10rpx;">
+						<uni-list v-for="item in rejectHistoryData">
+							<uni-list-item :clickable="true" @click="rejectSubmit(item)" :title="item.comment" />
+						</uni-list>
+					</view>
+				</view>
+			</uni-popup>
+		</view>
+	</view>
+</template>
+
+<script>
+	/**
+	 * 会山科技-会助理 审批操作功能组件
+	 * */
+	export default {
+		data() {
+			return {
+				baseUrl: this.$BASE_URL,
+				data: uni.getStorageSync("approval"),
+				form: {
+					nextApproval: '',
+					nextUserName: '',
+					pz: ''
+				},
+				dataTree: [],
+				queryParams: {},
+				historyData: [],
+				rejectHistoryData: [],
+				active: 0,
+				list1: [],
+				isDisabled: false,
+				actions: [],
+				type: 'center',
+				zindeButtion: 1,
+				selectTitle: '',
+				nextTitle: ''
+			}
+		},
+		mounted() {
+			uni.showLoading({
+				title: '正在加载'
+			})
+			if (this.data.baseName && this.data.pageType === 1) {
+				uni.setNavigationBarTitle({
+					title: this.data.baseName
+				})
+			}
+			this.getHouXuanZu()
+			this.getListHistory()
+			this.readTask()
+			uni.hideLoading()
+		},
+		methods: {
+			nextApprovalChange(e) {
+				let nextUser = e.detail.value[1]
+				this.form.nextUserName = e.detail.value[1].text
+				this.form.nextApproval = e.detail.value[1].value
+			},
+			propChange(e) {
+				if (e.show) {
+					this.zindeButtion = 0
+				} else {
+					this.zindeButtion = 1
+				}
+			},
+			rejectSubmit(item) {
+				this.form.rejectBaseId = item.baseId
+				this.form.nextApproval = item.operator
+				this.submitPass()
+			},
+			async revoke() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/revoke?taskId=' + this.data.taskId,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.showModal({
+						title: "撤销成功",
+						icon: "OK",
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						title: "撤销失败",
+						content: res.msg,
+						showCancel: false,
+						success() {
+							uni.navigateBack()
+						}
+					})
+				}
+			},
+			previewFile(fileUrl) {
+				uni.showLoading({
+					title: '加载中'
+				})
+				uni.downloadFile({
+					url: fileUrl, //后端返回的文件地址
+					// filePath: wx.env.USER_DATA_PATH + '/' + item.name + '.' + item.value.split('.')[item.value.split('.').length - 1],
+					success: function(res) {
+						if (res.statusCode === 200) {
+							uni.openDocument({
+								showMenu: true,
+								filePath: res.tempFilePath,
+								success: function(res) {
+									console.log(res, '打开文件成功')
+								},
+								fail: (err) => {
+									uni.showToast({
+										title: '打开文件失败请重试',
+										icon: 'none'
+									})
+								}
+							})
+						} else {
+							uni.showToast({
+								title: '打开文件失败请重试',
+								icon: 'none'
+							})
+						}
+						uni.hideLoading()
+					},
+					fail: (err) => {
+						uni.hideLoading()
+						uni.showToast({
+							title: '加载失败请重试',
+							icon: "none"
+						})
+					}
+				})
+			},
+			async readTask() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/rt?taskId=' + this.data.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+
+				}
+			},
+			async getHouXuanZu() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/pL?groupId=' + this.data.baseGroupId + '&baseId=' + this.data.baseId,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataTree = res.data
+				}
+				uni.hideLoading()
+			},
+			async getRejectListHistory() {
+				uni.showLoading({
+					title: '加载中',
+					mask: true
+				})
+				let id = this.data.taskId ? this.data.taskId : this.data.id
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/reject/ctr?taskId=' + id,
+					method: 'get',
+					data: this.queryParams,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (res.data.length == 0) {
+						this.submitPass()
+						return
+					}
+					this.$refs.popup2.open('bottom')
+					this.rejectHistoryData = res.data
+					uni.hideLoading()
+				}
+			},
+			async getListHistory() {
+				let id = this.data.taskId ? this.data.taskId : this.data.id
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/ctr?taskId=' + id,
+					method: 'get',
+					data: this.queryParams,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.historyData = res.data
+					if (0 != this.historyData.length) {
+						for (var i = 0; i < this.historyData.length; i++) {
+							this.list1.push({
+								title: this.historyData[i].comment,
+								desc: this.historyData[i].createTime
+							})
+						}
+					} else {
+						this.list1.push({
+							title: "待审批"
+						})
+					}
+					if (this.historyData[this.historyData.length - 1] && !(this.historyData[this.historyData
+							.length - 1].comment === "自动结束")) {
+						this.list1.push({
+							title: "待审批"
+						})
+					}
+					this.active = this.list1.length - 1
+					uni.hideLoading()
+				}
+			},
+			dataForm(comment, pass) {
+				this.form = {
+					comment: this.form.pz ? this.form.pz : comment,
+					result: pass,
+					baseId: this.data.baseId,
+					taskId: this.data.id,
+					formData: this.data.formData
+				}
+			},
+			passTrue(comment, pass, type) {
+				this.dataForm(comment, pass)
+				if (pass === 'RESULT_TRUE' && this.data.isCandidate == "1") {
+					this.submitPass()
+					return
+				}
+				if (pass === 'RESULT_FALSE') {
+					this.getRejectListHistory()
+					return
+				}
+				if (pass === 'RESULT_CASE_OF') {
+					this.getCurrentHouXuanZu()
+					this.selectTitle = '请选择转交人'
+					this.nextTitle = '请选择转交人'
+					this.$refs.popup.open(type)
+					return
+				}
+				this.nextTitle = '下一步审批人'
+				this.type = type
+				// open 方法传入参数 等同在 uni-popup 组件上绑定 type属性
+				this.$refs.popup.open(type)
+			},
+			async getCurrentHouXuanZu() {
+				uni.showLoading({
+					title: '加载中',
+					mask: true
+				})
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/currentPL?groupId=' + this.data.baseGroupId + '&baseId=' + this.data.baseId,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.dataTree = res.data
+					uni.hideLoading()
+				}
+			},
+			async submitPass() {
+				uni.showLoading({
+					mask: true,
+					title: '正在提交',
+				})
+				if (this.form.result !== 'RESULT_FALSE' && this.data.isCandidate == "0") {
+					if (!this.form.nextApproval) {
+						uni.hideLoading()
+						uni.showModal({
+							content: '请选择批准人',
+							title: '提交失败',
+							showCancel: false
+						})
+						return
+					}
+				}
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/nextStep',
+					method: 'post',
+					data: this.form,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					uni.hideLoading()
+					uni.showModal({
+						title: "提交成功",
+						icon: "OK",
+						showCancel: false,
+						success() {
+							uni.navigateTo({
+								url: "../../pages/app/index"
+							})
+							uni.navigateBack()
+						}
+					})
+				} else {
+					uni.showModal({
+						title: "提交失败",
+						icon: "ERROR",
+						showCancel: false,
+						content: res.msg
+					})
+				}
+				uni.hideLoading()
+			},
+			dateFormat(time) {
+				let date = new Date(time);
+				let year = date.getFullYear();
+				// 在日期格式中,月份是从0开始的,因此要加0,使用三元表达式在小于10的前面加0,以达到格式统一  如 09:11:05
+				let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
+				let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
+				let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
+				let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
+				let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
+				// 拼接
+				// return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
+				return year + "/" + month + "/" + day;
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 30rpx;
+	}
+
+	.u-page {
+		&__button-item {
+			margin: 0 15px 5px 0;
+		}
+	}
+
+	.u-demo-block__content {
+		flex-direction: row;
+		flex-wrap: wrap;
+		align-items: center;
+	}
+
+
+	.popup-content {
+		height: 800rpx;
+	}
+
+
+	.geHeight {
+		height: 100%;
+		position: relative;
+	}
+
+	.bomButtonBody {
+		border-top: 5rpx #f7f7f7 solid;
+		padding: 30rpx 0 50rpx 0;
+		width: 100%;
+	}
+
+	.status-btn {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		height: 92rpx;
+		margin: 30rpx;
+		background-color: #007AFF;
+	}
+
+	.example-body {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		padding: 15px;
+		flex-direction: row;
+	}
+
+	.check-btn {
+		display: flex;
+		justify-content: space-between;
+		margin-bottom: 10px;
+	}
+</style>

+ 158 - 0
pageApp/components/input.vue

@@ -0,0 +1,158 @@
+<template>
+	<view class="desc">
+		<uni-row>
+			<uni-col :span="labelSize">
+				<view class="desc" style="font-size: 25rpx;">
+					{{label}}
+				</view>
+			</uni-col>
+			<uni-col :span="inputSpan">
+				<view style="padding: 0 10rpx 0 0;">
+					<uni-easyinput v-if="model === 'input'" primaryColor="#37babd" v-model="val" @input="input"
+						:disabled="disabled">
+					</uni-easyinput>
+					<uni-datetime-picker v-if="model === 'date'" type="date" :clear-icon="false" v-model="val"
+						:disabled="disabled" />
+					<view v-if="model === 'search'" class="pickerView pickerText">
+						<view @click="openSearch" class="pickerText" v-if="val">
+							{{val}}
+						</view>
+						<view @click="openSearch" class="pickerText" v-else>
+							待 选 择
+						</view>
+					</view>
+					<u-number-box v-if="model === 'number'" v-model="val" @change="changeNumber"></u-number-box>
+				</view>
+			</uni-col>
+			<uni-col :span="2" v-if="unit">
+				<view style="padding: 10rpx 5rpx 0 2rpx;color: #818181;font-size: 20rpx;">
+					{{unit}}
+				</view>
+			</uni-col>
+		</uni-row>
+		<view class="desc">
+			<uni-easyinput v-if="model === 'textarea'" type="textarea" primaryColor="#37babd" v-model="val"
+				@input="input" :disabled="disabled">
+			</uni-easyinput>
+		</view>
+		<uni-popup ref="searchPopup" background-color="#fff">
+			<view style="height: 800rpx;">
+				<view style="padding: 30rpx;">
+					<u-search v-model="searchText" :show-action="false" placeholder="快捷搜索" @change="getSearchApiData()">
+					</u-search>
+				</view>
+				<view style="padding: 5rpx;">
+					<uni-list v-for="item in searchData">
+						<uni-list-item :clickable="true" @click="dataToValue(item)" :title="item[searchLabelKey]" />
+					</uni-list>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'hs-input',
+		props: {
+			value: {
+				Type: String,
+				default: null
+			},
+			label: {
+				Type: String,
+				default: ''
+			},
+			unit: {
+				Type: String,
+				default: ''
+			},
+			model: {
+				Type: String,
+				default: 'input'
+			},
+			labelSize: {
+				Type: Number,
+				default: 5
+			},
+			inputSpan: {
+				Type: Number,
+				default: 19
+			},
+			searchLabelKey: {
+				Type: String,
+				default: 'name'
+			},
+			searchApi: {
+				Type: String,
+				default: null
+			},
+			disabled: false
+		},
+		data() {
+			return {
+				val: '',
+				searchText: ''
+			}
+		},
+		watch: {
+			value(newVal) {
+				this.val = newVal
+			},
+			modelValue(newVal) {
+				this.val = newVal
+			}
+		},
+		mounted() {
+
+		},
+		methods: {
+			input: function(e) {
+				this.$emit('input', this.val)
+			},
+			openSearch() {
+				console.log('click ---> Test')
+				this.$refs.searchPopup.open('bottom')
+			},
+			changeNumber(e) {
+				this.$emit('change', this.val)
+			},
+			//获取/查询 信息
+			async getSearchApiData() {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/' + this.searchApi + this.searchText,
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.searchData = res.data
+				}
+			},
+			//选择赋值给value
+			dataToValue(item) {
+				this.$emit('input', item[this.searchLabelKey])
+				this.$refs.searchPopup.close()
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.desc {
+		padding: 10rpx 15rpx 0 15rpx;
+		color: #818181;
+		font-size: 20rpx;
+	}
+
+	.pickerView {
+		// align-items: flex-end;
+		padding: 10rpx 20rpx;
+		border: 1rpx #eeeeee solid;
+	}
+
+	.pickerText {
+		font-size: 26rpx;
+		color: #b1b1b1;
+	}
+</style>

+ 126 - 0
pageApp/components/list.vue

@@ -0,0 +1,126 @@
+<template>
+	<view>
+		<scroll-list ref="list" :option="option" @load="load" @refresh="refresh" @loadSuccess="loadSuccess"
+			@scrolltolower="scrolltolower">
+
+			<view v-for="(item, index) in list" :key="index">
+
+			</view>
+		</scroll-list>
+	</view>
+</template>
+<style lang="scss" scoped>
+	.page-wrap {}
+
+	.yyButton:active {
+		background-color: #dedede;
+	}
+
+	.infoBody {
+		background-color: #ffffff;
+		padding: 20rpx 0;
+		font-size: 30px;
+		margin: 2rpx;
+		box-shadow: 0px 2px 5px #e5e5e5;
+	}
+</style>
+<script>
+	export default {
+		props: {
+			apiUrl: {
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				option: {
+					page: 1,
+					size: 5,
+					auto: true
+				},
+				page: 1,
+				list: [],
+				scrollList: [],
+				total: 0
+			}
+		},
+		onLoad() {
+
+		},
+		onShow() {
+			this.$refs.list.refresh()
+		},
+		methods: {
+			async back(item) {
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: '/app/backEventOrder?id=' + item.id,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					this.taskList({
+						page: 1,
+						size: 5
+					})
+					this.$showModal("取消成功")
+				} else {
+					this.$showModal(res.msg)
+				}
+			},
+			handleTest(item) {
+				setTimeout(() => {
+					this.list = []
+				}, 1000)
+				uni.setStorageSync("eventId", item.eventId)
+				uni.setStorageSync("isUpload", 1)
+				uni.navigateTo({
+					url: "more"
+				})
+			},
+			async taskList(paging) {
+				// 发送请求
+				const {
+					data: res
+				} = await this.$httpRequest({
+					url: this.apiUrl + '?pageNum=' + paging.page + '&pageSize=' + paging.size,
+					method: 'get',
+					urlType: this.$getUrlType()
+				});
+				if (res.code === 200) {
+					if (paging.page === 1) {
+						this.scrollList = res.rows
+						this.total = res.total
+						this.$refs.list.loadSuccess({
+							list: res.rows,
+							total: this.total
+						});
+					} else if (paging.page > 1) {
+						for (var i = 0; i < res.rows.length; i++) {
+							this.scrollList.push(res.rows[i])
+						}
+						this.$refs.list.loadSuccess({
+							list: this.scrollList,
+							total: this.total
+						});
+					}
+				}
+			},
+			// 刷新刷剧
+			refresh(paging) {
+				this.taskList(paging)
+			},
+			scrolltolower(e) {
+				console.log(e)
+			},
+			load(paging) {
+				this.taskList(paging)
+			},
+			loadSuccess(list) {
+				this.list = list
+			}
+		}
+	}
+</script>

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.