hwq 2 年之前
父节点
当前提交
09bb0aa841
共有 100 个文件被更改,包括 10949 次插入0 次删除
  1. 3 0
      .gitignore
  2. 288 0
      App.vue
  3. 272 0
      api/user.js
  4. 37 0
      api/wx.js
  5. 18 0
      components/empty/empty.vue
  6. 1355 0
      components/wangding-pickerAddress/data.js
  7. 103 0
      components/wangding-pickerAddress/wangding-pickerAddress.vue
  8. 18 0
      config/app.js
  9. 32 0
      config/cache.js
  10. 39 0
      libs/log.js
  11. 84 0
      libs/login.js
  12. 253 0
      libs/wechat.js
  13. 44 0
      main.js
  14. 203 0
      manifest.json
  15. 19 0
      package.json
  16. 24 0
      pages.json
  17. 97 0
      pages/user/user.vue
  18. 147 0
      plugin/image-tools/index.js
  19. 0 0
      plugin/jweixin-module/index.js
  20. 242 0
      static/css/cmy.css
  21. 47 0
      store/index.js
  22. 34 0
      store/model/shop.js
  23. 68 0
      store/model/user.js
  24. 47 0
      uni.scss
  25. 18 0
      uni_modules/ksp-cropper/changelog.md
  26. 971 0
      uni_modules/ksp-cropper/components/ksp-cropper/ksp-cropper.vue
  27. 84 0
      uni_modules/ksp-cropper/package.json
  28. 73 0
      uni_modules/ksp-cropper/readme.md
  29. 22 0
      uni_modules/uni-icons/changelog.md
  30. 1169 0
      uni_modules/uni-icons/components/uni-icons/icons.js
  31. 96 0
      uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  32. 663 0
      uni_modules/uni-icons/components/uni-icons/uniicons.css
  33. 二进制
      uni_modules/uni-icons/components/uni-icons/uniicons.ttf
  34. 86 0
      uni_modules/uni-icons/package.json
  35. 8 0
      uni_modules/uni-icons/readme.md
  36. 19 0
      uni_modules/uni-load-more/changelog.md
  37. 5 0
      uni_modules/uni-load-more/components/uni-load-more/i18n/en.json
  38. 8 0
      uni_modules/uni-load-more/components/uni-load-more/i18n/index.js
  39. 5 0
      uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
  40. 5 0
      uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
  41. 112 0
      uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
  42. 86 0
      uni_modules/uni-load-more/package.json
  43. 14 0
      uni_modules/uni-load-more/readme.md
  44. 16 0
      uni_modules/uni-notice-bar/changelog.md
  45. 395 0
      uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue
  46. 90 0
      uni_modules/uni-notice-bar/package.json
  47. 13 0
      uni_modules/uni-notice-bar/readme.md
  48. 25 0
      uni_modules/uni-number-box/changelog.md
  49. 221 0
      uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue
  50. 85 0
      uni_modules/uni-number-box/package.json
  51. 13 0
      uni_modules/uni-number-box/readme.md
  52. 56 0
      uni_modules/uni-popup/changelog.md
  53. 45 0
      uni_modules/uni-popup/components/uni-popup-dialog/keypress.js
  54. 271 0
      uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue
  55. 143 0
      uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue
  56. 187 0
      uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue
  57. 7 0
      uni_modules/uni-popup/components/uni-popup/i18n/en.json
  58. 8 0
      uni_modules/uni-popup/components/uni-popup/i18n/index.js
  59. 7 0
      uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json
  60. 7 0
      uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json
  61. 45 0
      uni_modules/uni-popup/components/uni-popup/keypress.js
  62. 26 0
      uni_modules/uni-popup/components/uni-popup/popup.js
  63. 475 0
      uni_modules/uni-popup/components/uni-popup/uni-popup.vue
  64. 90 0
      uni_modules/uni-popup/package.json
  65. 17 0
      uni_modules/uni-popup/readme.md
  66. 25 0
      uni_modules/uni-rate/changelog.md
  67. 361 0
      uni_modules/uni-rate/components/uni-rate/uni-rate.vue
  68. 88 0
      uni_modules/uni-rate/package.json
  69. 12 0
      uni_modules/uni-rate/readme.md
  70. 8 0
      uni_modules/uni-scss/changelog.md
  71. 1 0
      uni_modules/uni-scss/index.scss
  72. 82 0
      uni_modules/uni-scss/package.json
  73. 4 0
      uni_modules/uni-scss/readme.md
  74. 7 0
      uni_modules/uni-scss/styles/index.scss
  75. 3 0
      uni_modules/uni-scss/styles/setting/_border.scss
  76. 66 0
      uni_modules/uni-scss/styles/setting/_color.scss
  77. 55 0
      uni_modules/uni-scss/styles/setting/_radius.scss
  78. 56 0
      uni_modules/uni-scss/styles/setting/_space.scss
  79. 167 0
      uni_modules/uni-scss/styles/setting/_styles.scss
  80. 24 0
      uni_modules/uni-scss/styles/setting/_text.scss
  81. 146 0
      uni_modules/uni-scss/styles/setting/_variables.scss
  82. 19 0
      uni_modules/uni-scss/styles/tools/functions.scss
  83. 31 0
      uni_modules/uni-scss/theme.scss
  84. 62 0
      uni_modules/uni-scss/variables.scss
  85. 20 0
      uni_modules/uni-transition/changelog.md
  86. 128 0
      uni_modules/uni-transition/components/uni-transition/createAnimation.js
  87. 277 0
      uni_modules/uni-transition/components/uni-transition/uni-transition.vue
  88. 87 0
      uni_modules/uni-transition/package.json
  89. 11 0
      uni_modules/uni-transition/readme.md
  90. 1 0
      unpackage/cache/.storyboard
  91. 二进制
      unpackage/cache/apk/__UNI__F0EBD91_cm.apk
  92. 1 0
      unpackage/cache/apk/apkurl
  93. 0 0
      unpackage/cache/apk/cmManifestCache.json
  94. 30 0
      unpackage/cache/appleConfig.ini
  95. 3 0
      unpackage/cache/certdata
  96. 3 0
      unpackage/cache/certdataios
  97. 11 0
      unpackage/cache/ipa/apple-app-site-association
  98. 二进制
      unpackage/cache/wgt/__UNI__F0EBD91/.manifest/google-keystore.keystore
  99. 二进制
      unpackage/cache/wgt/__UNI__F0EBD91/.manifest/icon-android-hdpi.png
  100. 二进制
      unpackage/cache/wgt/__UNI__F0EBD91/.manifest/icon-android-xhdpi.png

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+.DS_Store
+unpackage/dist
+.hbuilderx

+ 288 - 0
App.vue

@@ -0,0 +1,288 @@
+<script>
+/**
+ * vuex管理登陆状态,具体可以参考官方登陆模板示例
+ */
+import { mapMutations } from 'vuex';
+// #ifdef H5
+import { weixindata, setRouter } from './utils/wxAuthorized';
+// #endif
+// #ifdef APP-PLUS
+import { getUpApp } from './utils/upApp.js';
+// #endif
+export default {
+	data() {
+		return {
+			/* 保存微信信息 */
+			appData: {}
+		};
+	},
+	methods: {
+		...mapMutations('user', ['setUserInfo', 'login', 'hasLogin']),
+		...mapMutations('shop', ['setShopInfo','setShopAction']),
+		...mapMutations(['setFirstUse'])
+	},
+	onLaunch: function(urlObj) {
+		console.log('开始升级');
+		const obj = this;
+		// 加载缓存中的用户信息
+		const userInfo = uni.getStorageSync('userInfo') || '';
+		// 判断是否拥有用户信息
+		if (userInfo.uid) {
+			//更新登陆状态
+			uni.getStorage({
+				key: 'userInfo',
+				success: res => {
+					obj.setUserInfo(res.data);
+					obj.login();
+				}
+			});
+		}
+		// 获取当前位置附近商店数据
+		const shopDetail = uni.getStorageSync('shopDetail') ||'';
+		if(shopDetail){
+			uni.getStorage({
+				key: 'shopDetail',
+				success: res => {
+					obj.setShopInfo(res.data);
+				}
+			});
+		}
+		// 获取商家用户数据
+		const shopDetailAction = uni.getStorageSync('shopDetailAction') ||'';
+		if(shopDetailAction){
+			uni.getStorage({
+				key: 'shopDetailAction',
+				success: res => {
+					obj.setShopAction(res.data);
+				}
+			});
+		}
+		// 获取是否已经在如果引导图
+		const guideMap = uni.getStorageSync('guideMap') ||false;
+		// 判断是否已经加载过数据
+		if(guideMap){
+			this.setFirstUse(true)
+		}
+		// #ifdef H5
+		// 保存路由对象
+		setRouter(this.$router);
+		//判断是否已经缓存浏览器
+		let bool = uni.getStorageSync('weichatBrowser') || '';
+		if (bool === '') {
+			//判断是否为微信浏览
+			bool = navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger';
+			// 保存当前是否为微信内核浏览器
+			uni.setStorageSync('weichatBrowser', bool);
+		}
+		if (bool) {
+			// 加载微信信息
+			weixindata();
+		}
+		// #endif
+		// #ifdef APP-PLUS
+		// 判断是否升级
+		getUpApp();
+		// 获取当前运行系统
+		let system = uni.getStorageSync('platform') || '';
+		if (!system) {
+			uni.setStorage({
+				key: 'platform',
+				data: uni.getSystemInfoSync().platform
+			});
+		}
+		// #endif
+	},
+	onShow: function() {
+		// 加载拦截
+		// console.log('App Show');
+	},
+	onHide: function() {
+		// console.log('App Hide');
+	}
+};
+</script>
+
+<style lang="scss">
+/*全局公共样式和字体图标*/
+@import '/static/css/cmy.css';
+view,
+scroll-view,
+swiper,
+swiper-item,
+cover-view,
+cover-image,
+icon,
+text,
+rich-text,
+progress,
+button,
+checkbox,
+form,
+input,
+label,
+radio,
+slider,
+switch,
+textarea,
+navigator,
+audio,
+camera,
+image,
+video {
+	box-sizing: border-box;
+}
+/* 骨架屏替代方案 */
+.Skeleton {
+	background: #f3f3f3;
+	padding: 20rpx 0;
+	border-radius: 8rpx;
+}
+
+/* 图片载入替代方案 */
+.image-wrapper {
+	font-size: 0;
+	background: #f3f3f3;
+	border-radius: 4px;
+	image {
+		width: 100%;
+		height: 100%;
+		transition: 0.6s;
+		opacity: 0;
+		&.loaded {
+			opacity: 1;
+		}
+	}
+}
+
+// 设置富文本中图片最大宽度
+uni-rich-text img {
+	max-width: 100% !important;
+}
+/*边框*/
+.b-b:after,
+.b-t:after {
+	position: absolute;
+	z-index: 3;
+	left: 0;
+	right: 0;
+	height: 0;
+	content: '';
+	transform: scaleY(0.5);
+	border-bottom: 1px solid $border-color-base;
+}
+
+.b-b:after {
+	bottom: 0;
+}
+
+.b-t:after {
+	top: 0;
+}
+
+/* input 样式 */
+.input-placeholder {
+	color: #999999;
+}
+
+.placeholder {
+	color: #999999;
+}
+// 边距样式
+@for $i from 1 to 5 {
+	.margin-l-#{$i * 10} {
+		margin-left: $i * 10rpx !important;
+	}
+	.margin-r-#{$i * 10} {
+		margin-right: $i * 10rpx !important;
+	}
+	.margin-t-#{$i * 10} {
+		margin-top: $i * 10rpx !important;
+	}
+	.margin-b-#{$i * 10} {
+		margin-bottom: $i * 10rpx !important;
+	}
+	.margin-#{$i * 10} {
+		margin: $i * 10rpx !important;
+	}
+	.margin-v-#{$i * 10} {
+		margin-top: $i * 10rpx !important;
+		margin-bottom: $i * 10rpx !important;
+	}
+	.margin-c-#{$i * 10} {
+		margin-left: $i * 10rpx !important;
+		margin-right: $i * 10rpx !important;
+	}
+	.padding-l-#{$i * 10} {
+		padding-left: $i * 10rpx !important;
+	}
+	.padding-r-#{$i * 10} {
+		padding-right: $i * 10rpx !important;
+	}
+	.padding-t-#{$i * 10} {
+		padding-top: $i * 10rpx !important;
+	}
+	.padding-b-#{$i * 10} {
+		padding-bottom: $i * 10rpx !important;
+	}
+	.padding-#{$i * 10} {
+		padding: $i * 10rpx !important;
+	}
+	.padding-v-#{$i * 10} {
+		padding-top: $i * 10rpx !important;
+		padding-bottom: $i * 10rpx !important;
+	}
+	.padding-c-#{$i * 10} {
+		padding-left: $i * 10rpx !important;
+		padding-right: $i * 10rpx !important;
+	}
+}
+// 字体大小
+.font-size-sm {
+	font-size: $font-sm;
+}
+.font-size-base {
+	font-size: $font-base;
+}
+.font-size-lg {
+	font-size: $font-lg;
+}
+// 字体颜色
+.font-color-yellow {
+	color: $color-yellow !important;
+}
+.font-color-gray {
+	color: $color-gray !important;
+}
+.font-color-red {
+	color: $color-red !important;
+}
+.font-color-greed {
+	color: $color-green !important;
+}
+// 边框颜色
+.border-color-yellow {
+	border: 1rpx solid $color-yellow;
+}
+// 基础按钮
+.base-buttom {
+	background-color: $color-green;
+	font-size: 32rpx;
+	padding: 30rpx;
+	color: #FFFFFF;
+	margin: 0 50rpx;
+	border-radius: 100rpx;
+	margin-top: 100rpx;
+	text-align: center;
+	z-index: 95;
+}
+// 修改默认背景颜色
+uni-page-wrapper {
+	background-color: $page-color-base;
+}
+page {
+	background-color: $page-color-base;
+	// 设置默认字体
+	font-family: PingFang SC, STHeitiSC-Light, Helvetica-Light, arial, sans-serif, Droid Sans Fallback;
+	min-height: 100%;
+}
+</style>

+ 272 - 0
api/user.js

@@ -0,0 +1,272 @@
+import request from '@/utils/request'
+
+// 订单统计信息
+export function orderData(data) {
+	return request({
+		url: '/api/order/data',
+		method: 'get',
+		data
+	});
+}
+// 实名认证
+export function real_name(data) {
+	return request({
+		url: '/api/real_name',
+		method: 'post',
+		data
+	});
+}
+
+// 获取用户信息
+export function getUserInfo(data) {
+	return request({
+		url: '/api/userinfo',
+		method: 'get',
+		data
+	});
+}
+// 个人中心页数据
+export function getUser(data) {
+	return request({
+		url: '/api/user',
+		method: 'get',
+		data
+	});
+}
+
+// 用户分享图
+export function spreadBanner(data) {
+	return request({
+		url: '/api/spread/banner',
+		method: 'get',
+		data
+	});
+}
+
+// 获取地址列表
+export function getAddressList(data) {
+	return request({
+		url: '/api/address/list',
+		method: 'get',
+		data
+	});
+}
+// 修改地址
+export function addressEdit(data) {
+	return request({
+		url: '/api/address/edit',
+		method: 'post',
+		data
+	});
+}
+// 删除地址
+export function addressDel(data) {
+	return request({
+		url: '/api/address/del',
+		method: 'post',
+		data
+	});
+}
+// 设为默认地址
+export function setAddressDefault(data) {
+	return request({
+		url: '/api/address/default/set',
+		method: 'post',
+		data
+	});
+}
+// 购物车列表
+export function getCartList(data) {
+	return request({
+		url: '/api/cart/list',
+		method: 'get',
+		data
+	});
+}
+
+// 修改购物车数量
+export function getCartNum(data) {
+	return request({
+		url: '/api/cart/num',
+		method: 'post',
+		data
+	});
+}
+//删除购物车
+export function cartDel(data) {
+	return request({
+		url: '/api/cart/del',
+		method: 'post',
+		data
+	});
+}
+//获取收藏夹列表
+export function getcollectList(data) {
+	return request({
+		url: '/api/collect/user',
+		method: 'get',
+		data
+	});
+}
+// 取消收藏
+export function delcollect(data) {
+	return request({
+		url: '/api/collect/del',
+		method: 'post',
+		data
+	});
+}
+// 获取我的团队
+export function spreadPeople(data) {
+	return request({
+		url: '/api/spread/people',
+		method: 'post',
+		data
+	});
+}
+// 获取我的所有车辆包含被授权车辆
+export function mycar(data) {
+	return request({
+		url: '/api/car/mycar',
+		method: 'get',
+		data
+	});
+}
+// 获取我的车辆
+export function carList(data) {
+	return request({
+		url: '/api/car/lst',
+		method: 'get',
+		data
+	});
+}
+// 获取授权车辆
+export function get_touid_car(data) {
+	return request({
+		url: '/api/car/get_touid_car',
+		method: 'post',
+		data
+	});
+}
+// 获取车辆详情
+export function getCarInfo(data) {
+	return request({
+		url: '/api/car/info',
+		method: 'get',
+		data
+	});
+}
+// 获取车辆行程记录列表
+export function car_record(data) {
+	return request({
+		url: '/api/car/car_record',
+		method: 'post',
+		data
+	});
+}
+// 获取车辆行程记录详细
+export function record_info(data) {
+	return request({
+		url: '/api/car/record_info',
+		method: 'get',
+		data
+	});
+}
+// 车锁开关
+export function car_switch(data) {
+	return request({
+		url: '/api/car/car_switch',
+		method: 'post',
+		data
+	});
+}
+
+// 车辆授权
+export function add_auth_car(data) {
+	return request({
+		url: '/api/car/add_auth_car',
+		method: 'post',
+		data
+	});
+}
+// 删除授权
+export function del_auth_car(data) {
+	return request({
+		url: '/api/car/del_auth_car',
+		method: 'post',
+		data
+	});
+}
+
+// 车辆授权列表
+export function get_auth(data) {
+	return request({
+		url: '/api/car/get_auth',
+		method: 'post',
+		data
+	});
+}
+
+// 车辆报修
+export function create_question(data) {
+	return request({
+		url: '/api/car/create_question',
+		method: 'post',
+		data
+	});
+}
+
+// 车辆报修详情
+export function question_info(data) {
+	return request({
+		url: '/api/car/question_info',
+		method: 'post',
+		data
+	});
+}
+
+// 车辆报修历史
+export function question(data) {
+	return request({
+		url: '/api/car/question',
+		method: 'post',
+		data
+	});
+}
+// 车辆报修评价
+export function question_score(data) {
+	return request({
+		url: '/api/car/question_score',
+		method: 'post',
+		data
+	});
+}
+
+// 撤销报修
+export function cancel_question(data) {
+	return request({
+		url: '/api/car/cancel_question',
+		method: 'get',
+		data
+	});
+}
+
+// 提前还款
+export function prepayment(data) {
+	return request({
+		url: '/api/car/prepayment',
+		method: 'post',
+		data
+	});
+}
+
+
+// 提前还款
+export function getcar_status(data) {
+	return request({
+		url: '/api/car/getcar_status',
+		method: 'get',
+		data
+	});
+}
+

+ 37 - 0
api/wx.js

@@ -0,0 +1,37 @@
+import request from '@/utils/request'
+// 微信分享信息
+export function share(data) {
+	return request({
+		url: '/api/share',
+		method: 'get',
+		data
+	});
+}
+// #ifdef H5
+//微信配置
+export function wechatConfig(data) {
+	return request({
+		url: '/api/wechat/config',
+		method: 'get',
+		data
+	});
+}
+// 微信code地址
+export function wechatAuth(data) {
+	return request({
+		url: '/api/wechat/auth',
+		method: 'get',
+		data
+	});
+}
+// #endif
+// #ifdef MP-WEIXIN
+// 微信code地址
+export function wechatMpAuth(data) {
+	return request({
+		url: '/api/wechat/mp_auth',
+		method: 'post',
+		data
+	});
+}
+// #endif

文件差异内容过多而无法显示
+ 18 - 0
components/empty/empty.vue


+ 1355 - 0
components/wangding-pickerAddress/data.js

@@ -0,0 +1,1355 @@
+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": "直辖县",
+		"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": "福建",
+	"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": "湖南",
+	"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": "重庆",
+	"city": [{
+		"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": "云南",
+	"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": "香港",
+	"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": "南海岛",
+		"area": ["东沙群岛", "南沙群岛"]
+	}, {
+		"name": "苗栗县",
+		"area": ["头屋乡", "西湖乡", "苑里镇", "造桥乡", "竹南镇", "卓兰镇", "大湖乡", "公馆乡", "后龙镇", "苗栗市", "南庄乡", "三湾乡", "三义乡",
+			"狮潭乡", "泰安乡", "铜锣乡", "通霄镇", "头份市"
+		]
+	}, {
+		"name": "嘉义市",
+		"area": ["东区", "西区"]
+	}, {
+		"name": "嘉义县",
+		"area": ["阿里山乡", "布袋镇", "大林镇", "大埔乡", "东石乡", "番路乡", "六脚乡", "鹿草乡", "梅山乡", "民雄乡", "朴子市", "水上乡", "太保市",
+			"溪口乡", "新港乡", "义竹乡", "中埔乡", "竹崎乡"
+		]
+	}, {
+		"name": "新竹市",
+		"area": ["东区", "北区"]
+	}, {
+		"name": "新竹县",
+		"area": ["峨眉乡", "关西镇", "横山乡", "湖口乡", "尖石乡", "芎林乡", "五峰乡", "新丰乡", "新埔镇", "竹北市", "竹东镇", "宝山乡", "北埔乡"]
+	}, {
+		"name": "花莲县",
+		"area": ["卓溪乡", "丰滨乡", "凤林镇", "富里乡", "光復乡", "花莲市", "吉安乡", "瑞穗乡", "寿丰乡", "万荣乡", "新城乡", "秀林乡", "玉里镇"]
+	}, {
+		"name": "高雄市",
+		"area": ["阿莲区", "大寮区", "大社区", "大树区", "凤山区", "冈山区", "鼓山区", "湖内区", "甲仙区", "苓雅区", "林园区", "六龟区", "路竹区",
+			"茂林区", "美浓区", "弥陀区", "那玛夏区", "楠梓区", "内门区", "鸟松区"
+		]
+	}, {
+		"name": "基隆市",
+		"area": ["安乐区", "暖暖区", "七堵区", "仁爱区", "信义区", "中山区", "中正区"]
+	}, {
+		"name": "金门县",
+		"area": ["金城镇", "金湖镇", "金宁乡", "金沙镇", "烈屿乡", "乌坵乡"]
+	}, {
+		"name": "连江县",
+		"area": ["北竿乡", "东引乡", "莒光乡", "南竿乡"]
+	}, {
+		"name": "云林县",
+		"area": ["褒忠乡", "北港镇", "莿桐乡", "大埤乡", "东势乡", "斗六市", "斗南镇", "二崙乡", "古坑乡", "虎尾镇", "口湖乡", "林内乡", "崙背乡",
+			"麦寮乡", "水林乡", "四湖乡", "臺西乡", "土库镇", "西螺镇", "元长乡"
+		]
+	}]
+}]

+ 103 - 0
components/wangding-pickerAddress/wangding-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>

+ 18 - 0
config/app.js

@@ -0,0 +1,18 @@
+module.exports = {
+	// 请求域名 格式: https://您的域名
+	
+	HTTP_REQUEST_URL:'http://base.liuniu946.com',
+
+	
+	
+	// #ifdef H5
+	// HTTP_REQUEST_URL: window.location.protocol+"//"+window.location.host,
+	// #endif
+	HEADER:{
+		'content-type': 'application/json'
+	},
+	// 回话密钥名称 请勿修改此配置
+	TOKENNAME: 'Authori-zation',
+	// 缓存时间 0 永久
+	EXPIRE:0,
+};

+ 32 - 0
config/cache.js

@@ -0,0 +1,32 @@
+module.exports = {
+	//token
+	LOGIN_STATUS: 'LOGIN_STATUS_TOKEN',
+	// uid
+	UID:'UID',
+	//�û�
+	USER_INFO: 'USER_INFO',
+	//token�����¼�
+	EXPIRES_TIME: 'EXPIRES_TIME',
+	//�Ƿ���Ȩ
+	WX_AUTH: 'WX_AUTH',
+	//���ں���Ȩcode
+	STATE_KEY: 'wx_authorize_state',
+	//�û�����
+	LOGINTYPE: 'loginType',
+	//���ں���ת����
+	BACK_URL: 'login_back_url',
+	// ����code
+	STATE_R_KEY: 'roution_authorize_state',
+	//��ȨlogoС����
+	LOGO_URL: 'LOGO_URL',
+	//模板缓存
+	SUBSCRIBE_MESSAGE: 'SUBSCRIBE_MESSAGE',
+
+	TIPS_KEY: 'TIPS_KEY',
+
+	SPREAD: 'spread',
+	//缓存经度
+	CACHE_LONGITUDE: 'LONGITUDE',
+	//缓存纬度
+	CACHE_LATITUDE: 'LATITUDE',
+}

+ 39 - 0
libs/log.js

@@ -0,0 +1,39 @@
+
+const logLength=100;//缓存存储上限
+const name = 'log';//缓存名字
+export function addLog (data,content='') {
+	let log = uni.getStorageSync(name)||[];
+	log.unshift({
+		title:data,
+		content:content
+	});
+	uni.setStorageSync(name,log);
+	initLog(log);
+}
+
+
+export function delLog () {
+	return uni.setStorageSync(name,'');
+}
+
+export function getLog () {
+	return uni.getStorageSync(name);
+}
+
+export function initLog (log) {
+	if(log.length>logLength){
+		const newarr = log.slice(log.length-logLength);
+		uni.setStorageSync(name,newarr);
+	}
+}
+export function showLog (log) {
+	
+	let str = '';
+	uni.getStorageSync(name).forEach((e) => {
+		str+=e.title+':'+JSON.stringify(e.content)
+	})
+	uni.showModal({
+		title:"日志",
+		content:str
+	})
+}

+ 84 - 0
libs/login.js

@@ -0,0 +1,84 @@
+import store from "../store";
+import Cache from '../utils/cache';
+// #ifdef H5 || APP-PLUS
+import {
+	isWeixin
+} from "../utils";
+import auth from './wechat';
+// #endif
+
+import {
+	LOGIN_STATUS,
+	USER_INFO,
+	EXPIRES_TIME,
+	STATE_R_KEY
+} from './../config/cache';
+
+function prePage() {
+	let pages = getCurrentPages();
+	let prePage = pages[pages.length - 2];
+	// #ifdef H5
+	return prePage;
+	// #endif
+	return prePage.$vm;
+}
+
+export function toLogin(push, pathLogin) {
+	// store.commit("LOGOUT");
+	let path = prePage();
+	if (path) {
+		path = path.router;
+		if (path == undefined) {
+			path = location.pathname;
+		}
+	}
+	// #ifdef H5
+	else {
+		path = location.pathname;
+	}
+	// #endif
+
+	if (!pathLogin)
+		pathLogin = '/page/users/login/index'
+	Cache.set('login_back_url', path);
+	// #ifdef H5 || APP-PLUS
+	if (isWeixin()) {
+		auth.oAuth();
+	} else {
+		if (path !== pathLogin) {
+			push ? uni.navigateTo({
+				url: '/pages/users/login/index'
+			}) : uni.reLaunch({
+				url: '/pages/users/login/index'
+			});
+		}
+	}
+	// #endif
+
+	// #ifdef MP 
+
+
+	// #endif
+}
+
+
+export function checkLogin() {
+	let token = Cache.get(LOGIN_STATUS);
+	let expiresTime = Cache.get(EXPIRES_TIME);
+	let newTime = Math.round(new Date() / 1000);
+	if (expiresTime < newTime || !token) {
+		Cache.clear(LOGIN_STATUS);
+		Cache.clear(EXPIRES_TIME);
+		Cache.clear(USER_INFO);
+		Cache.clear(STATE_R_KEY);
+		return false;
+	} else {
+		store.commit('UPDATE_LOGIN', token);
+		let userInfo = Cache.get(USER_INFO, true);
+		if (userInfo) {
+			store.commit('UPDATE_USERINFO', userInfo);
+		}
+		return true;
+	}
+
+}

+ 253 - 0
libs/wechat.js

@@ -0,0 +1,253 @@
+// #ifdef H5
+import WechatJSSDK from "@/plugin/jweixin-module/index.js";
+// #endif
+
+import {
+	wechatConfig,
+	wechatAuth
+} from "@/api/wx.js";
+import {
+	WX_AUTH,
+	STATE_KEY,
+	LOGINTYPE,
+	BACK_URL
+} from '@/config/cache';
+import {
+	parseQuery
+} from '@/utils';
+import store from '@/store';
+import Cache from '@/utils/cache';
+
+class AuthWechat {
+	// #ifdef H5
+	constructor() {
+		//微信实例化对象
+		this.instance = WechatJSSDK;
+		//是否实例化
+		this.status = false;
+
+		this.initConfig = {};
+
+	}
+	// #endif
+	
+	isAndroid(){
+		let u = navigator.userAgent;
+		return u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
+	}
+
+	/**
+	 * 初始化wechat(分享配置)
+	 */
+	wechat() {
+		return new Promise((resolve, reject) => {
+			// if (this.status && !this.isAndroid()) return resolve(this.instance);
+			wechatConfig()
+				.then(res => {
+					this.instance.config(res.data);
+					this.initConfig = res.data;
+					this.status = true;
+					this.instance.ready(() => {
+						resolve(this.instance);
+					})
+				}).catch(err => {
+					console.log(err);
+					this.status = false;
+					reject(err);
+				});
+		});
+	}
+
+	/**
+	 * 验证是否初始化
+	 */
+	verifyInstance() {
+		let that = this;
+		return new Promise((resolve, reject) => {
+			if (that.instance === null && !that.status) {
+				that.wechat().then(res => {
+					resolve(that.instance);
+				}).catch(() => {
+					return reject();
+				})
+			} else {
+				return resolve(that.instance);
+			}
+		})
+	}
+	// 微信公众号的共享地址
+	openAddress() {
+		return new Promise((resolve, reject) => {
+			this.wechat().then(wx => {
+				this.toPromise(wx.openAddress).then(res => {
+					resolve(res);
+				}).catch(err => {
+					reject(err);
+				});
+			}).catch(err => {
+				reject(err);
+			})
+		});
+	}
+
+	/**
+	 * 微信支付
+	 * @param {Object} config
+	 */
+	pay(config) {
+		return new Promise((resolve, reject) => {
+			this.wechat().then((wx) => {
+				this.toPromise(wx.chooseWXPay, config).then(res => {
+					resolve(res);
+				}).catch(res => {
+					reject(res);
+				});
+			}).catch(res => {
+				reject(res);
+			});
+		});
+	}
+
+	toPromise(fn, config = {}) {
+		return new Promise((resolve, reject) => {
+			fn({
+				...config,
+				success(res) {
+					resolve(res);
+				},
+				fail(err) {
+					reject(err);
+				},
+				complete(err) {
+					reject(err);
+				},
+				cancel(err) {
+					reject(err);
+				}
+			});
+		});
+	}
+
+	/**
+	 * 自动去授权
+	 */
+	oAuth() {
+		if (uni.getStorageSync(WX_AUTH) && store.state.app.token) return;
+		const {
+			code
+		} = parseQuery();
+		if (!code) return this.toAuth();
+	}
+
+	clearAuthStatus() {
+
+	}
+
+	/**
+	 * 授权登陆获取token
+	 * @param {Object} code
+	 */
+	auth(code) {
+		return new Promise((resolve, reject) => {
+			let loginType = Cache.get(LOGINTYPE);
+			wechatAuth(code, parseInt(Cache.get("spread")), loginType)
+				.then(({
+					data
+				}) => {
+					let expires_time = data.expires_time.substring(0, 19);
+					expires_time = expires_time.replace(/-/g, '/');
+					expires_time = new Date(expires_time).getTime();
+					let newTime = Math.round(new Date() / 1000);
+					store.commit("LOGIN", {
+						token: data.token,
+						time: expires_time - newTime
+					});
+					Cache.set(WX_AUTH, code);
+					Cache.clear(STATE_KEY);
+					loginType && Cache.clear(LOGINTYPE);
+					resolve();
+				})
+				.catch(reject);
+		});
+	}
+
+	/**
+	 * 获取跳转授权后的地址
+	 * @param {Object} appId
+	 */
+	getAuthUrl(appId) {
+		const redirect_uri = encodeURIComponent(
+			`${location.origin}/pages/auth/index?back_url=` +
+			encodeURIComponent(
+				encodeURIComponent(
+					uni.getStorageSync(BACK_URL) ?
+					uni.getStorageSync(BACK_URL) :
+					location.pathname + location.search
+				)
+			)
+		);
+		uni.removeStorageSync(BACK_URL);
+		const state = encodeURIComponent(
+			("" + Math.random()).split(".")[1] + "authorizestate"
+		);
+		uni.setStorageSync(STATE_KEY, state);
+		return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`;
+	}
+
+	/**
+	 * 跳转自动登陆
+	 */
+	toAuth() {
+		let that = this;
+		this.wechat().then(wx => {
+			location.href = this.getAuthUrl(that.initConfig.appId);
+		})
+	}
+
+	/**
+	 * 绑定事件
+	 * @param {Object} name 事件名
+	 * @param {Object} config 参数
+	 */
+	wechatEvevt(name, config) {
+		let that = this;
+		return new Promise((resolve, reject) => {
+			let configDefault = {
+				fail(res) {
+					console.log(res,11111);
+					if (that.instance) return reject({
+						is_ready: true,
+						wx: that.instance
+					});
+					that.verifyInstance().then(wx => {
+						return reject({
+							is_ready: true,
+							wx: wx
+						});
+					})
+				},
+				success(res) {
+					return resolve(res,2222);
+				}
+			};
+			Object.assign(configDefault, config);
+			that.wechat().then(wx => {
+				if (typeof name === 'object') {
+					name.forEach(item => {
+						wx[item] && wx[item](configDefault)
+					})
+				} else {
+					wx[name] && wx[name](configDefault)
+				}
+			})
+		});
+	}
+
+	isWeixin() {
+		return navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1;
+	}
+
+}
+
+export default new AuthWechat();
+

+ 44 - 0
main.js

@@ -0,0 +1,44 @@
+import Vue from 'vue'
+import store from './store'
+import App from './App'
+/**
+ *  所有测试用数据均存放于根目录json.js
+ *  
+ *  css部分使用了App.vue下的全局样式和iconfont图标,有需要图标库的可以留言。
+ *  示例使用了uni.scss下的变量, 除变量外已尽量移除特有语法,可直接替换为其他预处理器使用
+ */
+const msg = (title, duration=1500, mask=false, icon='none')=>{
+	//统一提示方便全局修改
+	if(Boolean(title) === false){
+		return;
+	}
+	uni.showToast({
+		title,
+		duration,
+		mask,
+		icon
+	});
+}
+
+const prePage = ()=>{
+	// 获取当前页面
+	let pages = getCurrentPages();
+	let prePage = pages[pages.length - 2];
+	// #ifdef H5
+	return prePage;
+	// #endif
+	return prePage.$vm;
+}
+
+
+Vue.config.productionTip = false
+Vue.prototype.$fire = new Vue();
+Vue.prototype.$store = store;
+Vue.prototype.$api = {msg, prePage};
+
+App.mpType = 'app'
+
+const app = new Vue({
+    ...App
+})
+app.$mount()

+ 203 - 0
manifest.json

@@ -0,0 +1,203 @@
+{
+    "name" : "绿津",
+    "appid" : "__UNI__F0EBD91",
+    "description" : "",
+    "versionName" : "1.0.19",
+    "versionCode" : 122,
+    "transformPx" : false,
+    "app-plus" : {
+        /* 5+App特有相关 */
+        "usingComponents" : true,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "modules" : {
+            "Maps" : {},
+            "Geolocation" : {},
+            "OAuth" : {},
+            "Payment" : {},
+            "Share" : {}
+        },
+        /* 模块配置 */
+        "distribute" : {
+            /* 应用发布信息 */
+            "android" : {
+                /* android打包配置 */
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.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.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ],
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
+            },
+            "ios" : {
+                "idfa" : false,
+                "privacyDescription" : {
+                    "NSPhotoLibraryUsageDescription" : "用于提交审核认证",
+                    "NSLocationWhenInUseUsageDescription" : "该应用需要持续获取用户地理位置,以便为你进行导航",
+                    "NSLocationAlwaysUsageDescription" : "该应用需要你的地理位置,以便为你提供当前位置信息",
+                    "NSPhotoLibraryAddUsageDescription" : "该应用需要读取你的相册,以便为你编辑个人信息",
+                    "NSCameraUsageDescription" : "该应用需要你的相机,以便你完成信息认证",
+                    "NSLocationAlwaysAndWhenInUseUsageDescription" : "该应用需要你的地理位置,以便为你提供当前位置信息"
+                },
+                "dSYMs" : false
+            },
+            /* ios打包配置 */
+            "sdkConfigs" : {
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "7e8fabcd781f77afbd37eaf98dd54498",
+                        "appkey_android" : "605c71799909b1b96fbc15dbe161cca0"
+                    }
+                },
+                "oauth" : {
+                    "weixin" : {
+                        "appid" : "wx016c3a0056b79c15",
+                        "appsecret" : "ab387ea25d15ad1f6d91d72ddc64bf96",
+                        "UniversalLinks" : "https://www.zjljzn.com/uni-universallinks/__UNI__F0EBD91/"
+                    },
+                    "apple" : {}
+                },
+                "ad" : {},
+                "geolocation" : {
+                    "amap" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appkey_ios" : "7e8fabcd781f77afbd37eaf98dd54498",
+                        "appkey_android" : "605c71799909b1b96fbc15dbe161cca0"
+                    },
+                    "system" : {
+                        "__platform__" : [ "ios", "android" ]
+                    }
+                },
+                "payment" : {
+                    "alipay" : {
+                        "__platform__" : [ "ios", "android" ]
+                    },
+                    "weixin" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appid" : "wx016c3a0056b79c15",
+                        "UniversalLinks" : "https://www.zjljzn.com/uni-universallinks/__UNI__F0EBD91/"
+                    }
+                },
+                "push" : {},
+                "share" : {
+                    "weixin" : {
+                        "appid" : "wx016c3a0056b79c15",
+                        "UniversalLinks" : "https://www.zjljzn.com/uni-universallinks/__UNI__F0EBD91/"
+                    }
+                },
+                "statics" : {}
+            },
+            "splashscreen" : {
+                "androidStyle" : "common",
+                "iosStyle" : "common",
+                "android" : {
+                    "hdpi" : "unpackage/启动图/安卓/482.9.png",
+                    "xhdpi" : "unpackage/启动图/安卓/722.9.png",
+                    "xxhdpi" : "unpackage/启动图/安卓/1082.9.png"
+                },
+                "ios" : {
+                    "storyboard" : "unpackage/启动图/ios/CustomStoryboard.zip"
+                }
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "unpackage/res/icons/72x72.png",
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
+                },
+                "ios" : {
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
+                    "ipad" : {
+                        "app" : "unpackage/res/icons/76x76.png",
+                        "app@2x" : "unpackage/res/icons/152x152.png",
+                        "notification" : "unpackage/res/icons/20x20.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
+                        "settings" : "unpackage/res/icons/29x29.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "spotlight" : "unpackage/res/icons/40x40.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
+                    },
+                    "iphone" : {
+                        "app@2x" : "unpackage/res/icons/120x120.png",
+                        "app@3x" : "unpackage/res/icons/180x180.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
+                    }
+                }
+            }
+        }
+    },
+    /* SDK配置 */
+    "quickapp" : {},
+    /* 快应用特有相关 */
+    "mp-weixin" : {
+        /* 小程序特有相关 */
+        "usingComponents" : true,
+        "appid" : "wx1af9ca9ccd6ca98b",
+        "setting" : {
+            "urlCheck" : true,
+            "minified" : true
+        },
+        "permission" : {
+            "scope.userLocation" : {
+                "desc" : "为了定位车辆位置需要获取定位信息"
+            }
+        },
+        "lazyCodeLoading" : "requiredComponents",
+        "requiredBackgroundModes" : [ "location" ]
+    },
+    "h5" : {
+        "title" : "绿津",
+        "domain" : "",
+        "router" : {
+            "base" : "/index/",
+            "mode" : "history"
+        },
+        "devServer" : {
+            "proxy" : {
+                "/api" : {
+                    "target" : "https://www.zjljzn.com/api",
+                    // "changeOrigin": true,
+                    "pathRewrite" : {
+                        "/api" : "" // rewrite path
+                    }
+                }
+            },
+            "https" : true
+        },
+        "sdkConfigs" : {
+            "maps" : {
+                "qqmap" : {
+                    "key" : "VYZBZ-P2TRG-RMIQ3-ITAIN-2DKBK-CKFQQ"
+                }
+            }
+        }
+    },
+    "_spaceID" : "364f3115-6ed2-4e8f-913f-836cbd3f34fa"
+}

+ 19 - 0
package.json

@@ -0,0 +1,19 @@
+{
+    "id": "alger-simg",
+    "name": "图片预览(使用简单 长按可保存分享 插件)",
+    "version": "1.1.0",
+    "description": "图片预览(使用简单) 可以双指缩放 可以保存分享",
+    "keywords": [
+        "图片",
+        "image",
+        "img",
+        "图片预览",
+        "大图"
+    ],
+    "dcloudext": {
+        "category": [
+            "前端组件",
+            "通用组件"
+        ]
+    }
+}

+ 24 - 0
pages.json

@@ -0,0 +1,24 @@
+{
+	"pages": [{
+		"path": "pages/user/user",
+		"style": {
+			"navigationStyle": "custom",
+			"navigationBarTitleText": "个人中心"
+		}
+	}],
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "uni-app",
+		"navigationBarBackgroundColor": "#FFFFFF",
+		"backgroundColor": "#f8f8f8"
+	},
+
+	"condition": { //模式配置,仅开发期间生效
+		"current": 0, //当前激活的模式(list 的索引项)
+		"list": [{
+			"name": "", //模式名称
+			"path": "", //启动页面,必选
+			"query": "" //启动参数,在页面的onLoad函数里面得到
+		}]
+	}
+}

+ 97 - 0
pages/user/user.vue

@@ -0,0 +1,97 @@
+<template>
+	<view class="content">
+
+	</view>
+</template>
+<script>
+	import {
+		mapState,
+		mapMutations
+	} from 'vuex';
+	import {
+		orderData,
+		getUserInfo
+	} from '@/api/user.js';
+	export default {
+		data() {
+			return {
+				isUserPage: true //默认用户页面
+			};
+		},
+		computed: {
+			...mapState('user', ['hasLogin']),
+		},
+		onShow() {
+			uni.setTabBarStyle({
+				backgroundColor: '#FFFFFF'
+			})
+			// 判断是否已经登录
+			this.loadBaseData();
+			// 判断是否用户页面
+			if (this.isUserPage && this.hasLogin) {
+				this.$nextTick(() => {
+					this.$refs.userPage.getUser();
+				})
+			} else if (this.hasLogin) {
+				this.$nextTick(() => {
+					this.$refs.shopPage.getInit();
+				})
+			}
+		},
+		methods: {
+			toJSON() {
+				return this;
+			},
+			...mapMutations('user', ['setUserInfo', 'setOrderInfo']),
+			changeTab(bool) {
+				if (bool) {
+					this.$refs.shopPage.getInit();
+				}
+				if (!bool) {
+					this.$refs.userPage.getUser();
+				}
+				// 判断 是否切换为商家
+				this.isUserPage = !bool;
+			},
+			// 加载初始数据
+			loadBaseData() {
+				getUserInfo({})
+					.then(({
+						data
+					}) => {
+						this.setUserInfo(data);
+						// 获取用户数据完毕后在获取订单数据防止多次跳转到登录页
+						orderData({})
+							.then(({
+								data
+							}) => {
+								this.setOrderInfo(data);
+							})
+							.catch(e => {
+								this.setOrderInfo({
+									complete_count: 0, //完成
+									received_count: 0, //待收货
+									unshipped_count: 0, //待发货
+									order_count: 0, //订单总数
+									unpaid_count: 0 //待付款
+								});
+							});
+					})
+					.catch(e => {
+						console.log(e);
+					});
+			},
+			/**
+			 * 统一跳转接口,拦截未登录路由
+			 * navigator标签现在默认没有转场动画,所以用view
+			 */
+		}
+	};
+</script>
+<style lang="scss">
+	.content {
+		/* #ifdef H5 */
+		padding-bottom: 150rpx;
+		/* #endif */
+	}
+</style>

+ 147 - 0
plugin/image-tools/index.js

@@ -0,0 +1,147 @@
+function getLocalFilePath(path) {
+    if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf('_downloads') === 0) {
+        return path
+    }
+    if (path.indexOf('file://') === 0) {
+        return path
+    }
+    if (path.indexOf('/storage/emulated/0/') === 0) {
+        return path
+    }
+    if (path.indexOf('/') === 0) {
+        var localFilePath = plus.io.convertAbsoluteFileSystem(path)
+        if (localFilePath !== path) {
+            return localFilePath
+        } else {
+            path = path.substr(1)
+        }
+    }
+    return '_www/' + path
+}
+
+export function pathToBase64(path) {
+    return new Promise(function(resolve, reject) {
+        if (typeof window === 'object' && 'document' in window) {
+            if (typeof FileReader === 'function') {
+                var xhr = new XMLHttpRequest()
+                xhr.open('GET', path, true)
+                xhr.responseType = 'blob'
+                xhr.onload = function() {
+                    if (this.status === 200) {
+                        let fileReader = new FileReader()
+                        fileReader.onload = function(e) {
+                            resolve(e.target.result)
+                        }
+                        fileReader.onerror = reject
+                        fileReader.readAsDataURL(this.response)
+                    }
+                }
+                xhr.onerror = reject
+                xhr.send()
+                return
+            }
+            var canvas = document.createElement('canvas')
+            var c2x = canvas.getContext('2d')
+            var img = new Image
+            img.onload = function() {
+                canvas.width = img.width
+                canvas.height = img.height
+                c2x.drawImage(img, 0, 0)
+                resolve(canvas.toDataURL())
+                canvas.height = canvas.width = 0
+            }
+            img.onerror = reject
+            img.src = path
+            return
+        }
+        if (typeof plus === 'object') {
+            plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) {
+                entry.file(function(file) {
+                    var fileReader = new plus.io.FileReader()
+                    fileReader.onload = function(data) {
+                        resolve(data.target.result)
+                    }
+                    fileReader.onerror = function(error) {
+                        reject(error)
+                    }
+                    fileReader.readAsDataURL(file)
+                }, function(error) {
+                    reject(error)
+                })
+            }, function(error) {
+                reject(error)
+            })
+            return
+        }
+        if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+            wx.getFileSystemManager().readFile({
+                filePath: path,
+                encoding: 'base64',
+                success: function(res) {
+                    resolve('data:image/png;base64,' + res.data)
+                },
+                fail: function(error) {
+                    reject(error)
+                }
+            })
+            return
+        }
+        reject(new Error('not support'))
+    })
+}
+
+export function base64ToPath(base64) {
+    return new Promise(function(resolve, reject) {
+        if (typeof window === 'object' && 'document' in window) {
+            base64 = base64.split(',')
+            var type = base64[0].match(/:(.*?);/)[1]
+            var str = atob(base64[1])
+            var n = str.length
+            var array = new Uint8Array(n)
+            while (n--) {
+                array[n] = str.charCodeAt(n)
+            }
+            return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { type: type })))
+        }
+        var extName = base64.match(/data\:\S+\/(\S+);/)
+        if (extName) {
+            extName = extName[1]
+        } else {
+            reject(new Error('base64 error'))
+        }
+        var fileName = Date.now() + '.' + extName
+        if (typeof plus === 'object') {
+            var bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
+            bitmap.loadBase64Data(base64, function() {
+                var filePath = '_doc/uniapp_temp/' + fileName
+                bitmap.save(filePath, {}, function() {
+                    bitmap.clear()
+                    resolve(filePath)
+                }, function(error) {
+                    bitmap.clear()
+                    reject(error)
+                })
+            }, function(error) {
+                bitmap.clear()
+                reject(error)
+            })
+            return
+        }
+        if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) {
+            var filePath = wx.env.USER_DATA_PATH + '/' + fileName
+            wx.getFileSystemManager().writeFile({
+                filePath: filePath,
+                data: base64.replace(/^data:\S+\/\S+;base64,/, ''),
+                encoding: 'base64',
+                success: function() {
+                    resolve(filePath)
+                },
+                fail: function(error) {
+                    reject(error)
+                }
+            })
+            return
+        }
+        reject(new Error('not support'))
+    })
+}

文件差异内容过多而无法显示
+ 0 - 0
plugin/jweixin-module/index.js


+ 242 - 0
static/css/cmy.css

@@ -0,0 +1,242 @@
+.bg-color-red {
+	background-color: #e93323 !important;
+}
+
+/*水平线*/
+.hr {
+	width: 100%;
+	position: relative;
+	border-bottom: 1px solid #dddddd;
+	/* height: 0.5rpx; */
+}
+
+/* 一行显示 */
+.clamp {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	display: block;
+}
+
+/* 二行显示 */
+.clamp2 {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+/* 二行显示 */
+.ellipsis {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-box-orient: vertical;
+	-webkit-line-clamp: 2;
+}
+
+.common-hover {
+	background: #f5f5f5;
+}
+
+/* 角标 */
+.corner {
+	background-color: #e51c23;
+	position: absolute;
+	right: -18rpx;
+	top: -18rpx;
+	color: #FFFFFF;
+	text-align: center;
+	border-radius: 999px;
+	font-size: 24rpx !important;
+	min-width: 35rpx;
+	min-height: 35rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	line-height: 1;
+}
+
+.flex_item {
+	display: flex;
+	align-items: center;
+	/* justify-content: space-between; */
+}
+
+/* 左右顶格加上下居中 */
+.flex-between-center {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+}
+
+/* flex布局-整体居中 */
+.flex-center {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+/* flex-开始居中 */
+.flex-start {
+	display: flex;
+	align-items: center;
+	justify-content: flex-start;
+}
+/* 一行居中显示 */
+.flex-line{
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	flex-direction: column;
+}
+
+/*文字对齐*/
+.text-left {
+	text-align: left !important;
+}
+
+.text-center {
+	text-align: center !important;
+}
+
+.text-justify {
+	text-align: justify !important;
+}
+
+.text-right {
+	text-align: right !important;
+}
+
+.text-default {
+	color: #212121 !important;
+}
+
+.text-white {
+	color: #ffffff !important;
+}
+
+.text-primary {
+	color: #00bcd4 !important;
+}
+
+.text-success {
+	color: #009688 !important;
+}
+
+.text-info {
+	color: #03a9f4 !important;
+}
+
+.text-warning {
+	color: #ffc107 !important;
+}
+
+.text-danger {
+	color: #e51c23 !important;
+}
+
+.text-pink {
+	color: #e91e63 !important;
+}
+
+.text-purple {
+	color: #673ab7 !important;
+}
+
+.text-indigo {
+	color: #3f51b5 !important;
+}
+
+.text-gray {
+	color: #999999 !important;
+}
+
+.bg-default {
+	background-color: #f5f5f5 !important;
+}
+
+.bg-primary {
+	background-color: #00bcd4 !important;
+}
+
+.bg-success {
+	background-color: #009688 !important;
+}
+
+.bg-info {
+	background-color: #03a9f4 !important;
+}
+
+.bg-warning {
+	background-color: #FFB238 !important;
+}
+
+.bg-danger {
+	background-color: #DC4D46 !important;
+}
+
+.bg-pink {
+	background-color: #e91e63 !important;
+}
+
+.bg-purple {
+	background-color: #673ab7 !important;
+}
+
+.bg-indigo {
+	background-color: #3f51b5 !important;
+}
+
+.bg-white {
+	background-color: white !important;
+}
+
+.bg-gray {
+	background-color: #e3e3e3 !important;
+}
+
+/* 边框 */
+.border-radius-15 {
+	border-radius: 15rpx;
+}
+
+.border-radius-10 {
+	border-radius: 10rpx;
+}
+
+.border-radius-all {
+	border-radius: 1000rpx;
+}
+
+/* 底部边线 */
+.borde-b {
+	border-bottom: 1px solid #dddddd;
+}
+
+/* 弹性盒子 */
+.flex {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.items-left {
+	justify-content: flex-start;
+}
+
+.items-right {
+	justify-content: flex-end;
+}
+
+.flex-shrink-false {
+	flex-shrink: 0;
+}
+
+.flex-grow-true {
+	flex-grow: 1;
+}
+
+.position-relative {
+	position: relative;
+}

+ 47 - 0
store/index.js

@@ -0,0 +1,47 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import user from './model/user'
+import shop from './model/shop'
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+	state: {
+		// baseURL:"http://yrh.liuniu946.com",//'http://eb.shuibo.net',//请求地址配置 
+		baseURL:'https://www.zjljzn.com',//请求地址配置 
+		// baseURL:'http://dp.frp.shuibo.net',//请求地址配置 
+		urlFile:'/index',//项目部署所在文件夹
+		hasLogin:false,
+		// #ifdef H5
+		loginInterceptor:false,//是否打开强制登录
+		fx:true,//是否显示分销
+		// #endif
+		firstUse:false,//保存是否已经加载过初次加载图片
+		isShowIllegality:false,//是否显示不过审的内容
+		// #ifdef APP-PLUS
+		fx:false,//是否显示分销
+		// #endif
+	},
+	mutations: {
+		// 保存是否要加载引导图
+		setFirstUse(state, provider){
+			state.firstUse = provider;
+			uni.setStorage({ //缓存用户登陆状态
+				key: 'guideMap',
+				data: provider
+			})
+		},
+		// #ifdef APP-PLUS
+		// 是否需要显示阴阳代码
+		setFx(state, provider){
+			state.fx = provider;
+		}
+		// #endif
+	},
+	modules:{
+		user,
+		shop
+	},
+	actions: {}
+})
+
+export default store

+ 34 - 0
store/model/shop.js

@@ -0,0 +1,34 @@
+let state = {
+	shopDetail: {}, //用户当前所属地区商家信息
+	shopAction:{
+		name:'',
+		image:'',
+	}//商店账号商家数据
+}
+
+let mutations = {
+	// 保存用户信息
+	setShopInfo(state, provider) {
+		state.shopDetail = provider;
+		uni.setStorage({ //缓存用户登陆状态
+			key: 'shopDetail',
+			data: provider
+		})
+	},
+	setShopAction(state, provider) {
+		state.shopAction = provider;
+		uni.setStorage({ //缓存用户登陆状态
+			key: 'shopDetailAction',
+			data: provider
+		})
+	},
+}
+
+let getters = {}
+
+export default {
+	namespaced: true,
+	state,
+	mutations,
+	getters
+}

+ 68 - 0
store/model/user.js

@@ -0,0 +1,68 @@
+let state = {
+	userInfo: {}, //用户信息
+	orderInfo: {
+		complete_count: 0, //完成
+		received_count: 0, //待收货
+		unshipped_count: 0, //待发货
+		order_count: 0, //订单总数
+		unpaid_count: 0 //待付款
+	}, //订单信息
+	hasLogin: false, //是否登录
+	address: {
+		latitude: '',
+		longitude: '',
+	}
+}
+
+let mutations = {
+	// 登录
+	login(state) {
+		state.hasLogin = true;
+	},
+	// 退出登录
+	logout(state, provider) {
+		state.hasLogin = false;
+		// 清空基础信息
+		state.userInfo = {};
+		state.orderInfo = {
+			complete_count: 0, //完成
+			received_count: 0, //待收货
+			unshipped_count: 0, //待发货
+			order_count: 0, //订单总数
+			unpaid_count: 0 //待付款
+		};
+		// 清除缓存用户信息
+		uni.removeStorage({
+			key: 'userInfo'
+		})
+		// 清除缓存token
+		uni.removeStorage({
+			key: 'token'
+		})
+	},
+	// 保存用户信息
+	setUserInfo(state, provider) {
+		state.userInfo = provider;
+		uni.setStorage({ //缓存用户登陆状态
+			key: 'userInfo',
+			data: provider
+		})
+	},
+	// 保存订单信息
+	setOrderInfo(state, provider) {
+		state.orderInfo = provider;
+	},
+	// 保存当前用户所在位置
+	setAddress(state, provider) {
+		state.address = provider;
+	}
+}
+
+let getters = {}
+
+export default {
+	namespaced: true,
+	state,
+	mutations,
+	getters
+}

+ 47 - 0
uni.scss

@@ -0,0 +1,47 @@
+/* 页面左右间距 */
+$page-row-spacing: 30rpx;
+//页面基础颜色
+$page-color-base: #f8f8f8;//页面背景颜色
+$page-color-light: #F4F4F4;
+// 主题颜色
+$base-color: #0BBB62;//项目颜色
+$box-shadow-color:#5dbc7c;//阴影颜色
+$font-color:#5dbc7c;//字体颜色
+$font-color-spec: #5dbc7c;//可操作文字颜色
+$background-color:#5dbc7c;//按钮背景颜色
+// 小图标大小
+$uni-img-size-base:36rpx;
+/* 文字尺寸 */
+$font-sm: 24rpx;
+$font-base: 28rpx;
+$font-lg: 32rpx;
+/*文字颜色*/
+$font-color-dark: #303133;//黑
+$font-color-base: #606266;//基础
+$font-color-white:#ffffff;//白色
+$font-color-light: #909399;//灰色
+$font-color-disabled: #c0c4cc;//禁用
+/* 边框颜色 */
+$border-color-dark: #dcdfe6;//黑
+$border-color-base: #e4e7ed;//基础灰
+$border-color-light: #ebeef5;//亮灰
+// uni自带边框颜色
+$uni-border-color:#ebeef5;
+/*颜色*/
+$color-yellow: #FFE92F;
+$color-gray: #999999;
+$color-green: #0BBB62;
+$color-red: #FF4241;
+/* 图片加载中颜色 */
+$image-bg-color: #eee;
+/* 行为相关颜色 */
+$uni-color-primary: #5dbc7c;
+$uni-color-success: #0BBB62;
+$uni-color-warning: #FFA836;
+$uni-color-error: #FF4241;
+// 提交框阴影
+$box-shadow: 0rpx 0rpx 10rpx 10rpx #f3f3f3;
+// 圆角
+$border-radius-sm: 15rpx;
+// 渐变背景颜色
+$bg-green-gradual: linear-gradient(#5dbc7c, #71d094);

+ 18 - 0
uni_modules/ksp-cropper/changelog.md

@@ -0,0 +1,18 @@
+## 1.1.5(2022-06-14)
+填新版HBuilderX的坑,简单测试是没问题了。
+## 1.1.4(2022-02-15)
+修护ios下微信小程序第一次裁剪的bug
+## 1.1.3(2022-02-10)
+修护APP点击无效的bug
+## 1.1.2(2022-01-24)
+优化一些细节
+## 1.1.1(2022-01-19)
+更新示例项目
+## 1.1.0(2022-01-18)
+新增旋转功能
+## 1.0.2(2022-01-13)
+修护mode="fixed"模式无效的bug
+## 1.0.1(2021-12-20)
+修护IOS下,小程序点击没反应的bug
+## 1.0.0(2021-12-06)
+图片裁剪工具

+ 971 - 0
uni_modules/ksp-cropper/components/ksp-cropper/ksp-cropper.vue

@@ -0,0 +1,971 @@
+<template>
+<view v-show="url" :mode="modeValue" :change:mode="mwx.changeMode" :rotate="rotate" :change:rotate="mwx.changeRotate">
+	<!-- #ifdef MP-WEIXIN -->
+	<canvas type="2d" class="canvas" :style="{width: target.width + 'px', height: target.height + 'px'}"></canvas>
+	<!-- #endif -->
+	<!-- #ifdef APP-PLUS || H5 -->
+	<canvas :canvas-id="canvasId" :style="{width: target.width + 'px', height: target.height + 'px'}"></canvas>
+	<!-- #endif -->
+	<view class="panel">
+		<view class="body" @touchstart="mwx.touchstart" @touchmove="mwx.touchmove" @touchend="mwx.touchend" @touchcancel="mwx.touchcancel">
+			<view class="image-wrap" :class="{transit: transit}" :change:rect="mwx.changeImage" :rect="image">
+				<image class="image" :class="{transit: transit}" :src="url" @load="imageLoad"/>
+			</view>
+			<view class="mask"></view>
+			<view class="frame" :class="{transit: transit}" :change:rect="mwx.changeFrame" :rect="frame">
+				<view class="rect">
+					<view class="image-rect" :class="{transit: transit}">
+						<image class="image" :class="{transit: transit}" :src="url"/>
+					</view>
+				</view>
+				<view class="line-one"></view>
+				<view class="line-two"></view>
+				<view class="line-three"></view>
+				<view class="line-four"></view>
+				<view class="frame-left-top" @touchstart="mwx.touchstart"></view>
+				<view class="frame-left-bottom" @touchstart="mwx.touchstart"></view>
+				<view class="frame-right-top" @touchstart="mwx.touchstart"></view>
+				<view class="frame-right-bottom" @touchstart="mwx.touchstart"></view>
+			</view>
+		</view>
+		<view class="toolbar">
+			<view @tap="oncancle" class="btn-cancel">取消</view>
+			<view @tap="rotateAngle" class="btn-rotate">旋转</view>
+			<view @tap="onok" class="btn-ok">确定</view>
+		</view>
+	</view>
+</view>
+</template>
+<script>
+/**
+ * @property {String} mode 模式
+ *  @value fixed 固定模式,裁剪出固定大小
+ *  @value ratio 等比模式,宽高等比缩放
+ *  @value free 自由模式,不限制宽高比
+ * @property {String} url 图片路径
+ * @property {Number} width 宽度
+ * @property {Number} height 高度
+ * @property {Number} maxWidth 最大宽带
+ * @property {Number} minHeight 最大高度 
+ */
+export default {
+	props: {
+		mode: {
+			type: String,
+			default: "free"
+		},
+		url: {
+			type: String,
+			default: ""
+		},
+		width: {
+			type: Number,
+			default: 200
+		},
+		height: {
+			type: Number,
+			default: 200
+		},
+		maxWidth: {
+			type: Number,
+			default: 1024
+		},
+		maxHeight: {
+			type: Number,
+			default: 1024
+		}
+	},
+	data() {
+		return {
+			canvasId: Math.random().toString(36).slice(-6),
+			real: {
+				width: 100,
+				height: 100
+			},
+			target: {
+				width: 100,
+				height: 100
+			},
+			body: {
+				width: 100,
+				height: 100
+			},
+			frame: {
+				left: 50,
+				top: 50,
+				width: 200,
+				height: 300
+			},
+			image: {
+				left: 20,
+				top: 20,
+				width: 300,
+				height: 400
+			},
+			rotate: 0,
+			transit: false,
+			modeValue: ""
+		};
+	},
+	methods: {
+		imageLoad(event) {
+            uni.getImageInfo({
+                src: this.url,
+                success: (rst) => {
+                    this.real.width = rst.width;
+                    this.real.height = rst.height;
+                    this.target = {};
+                    var query = uni.createSelectorQuery().in(this);
+                    query.select(".body").boundingClientRect((data) => {
+                    	this.body.width = data.width;
+                    	this.body.height = data.height;
+                    	this.init();
+                    }).exec();
+                }
+            });
+		},
+		init() {
+			this.modeValue = this.mode;
+			this.rotate = 0;
+			var rate = this.width / this.height;
+			var width = this.body.width * 0.7;
+			var height = this.body.height * 0.7;
+			if (width / height > rate) {
+				width = height * rate;
+			} else {
+				height = width / rate;
+			}
+			var left = (this.body.width - width) / 2;
+			var top = (this.body.height - height) / 2;
+			this.frame = {
+				left: left,
+				top: top,
+				width: width,
+				height: height
+			};
+			rate = this.real.width / this.real.height;
+			width = this.frame.width;
+			height = this.frame.height;
+			if (width / height > rate) {
+				height = width / rate;
+			} else {
+				width = height * rate;
+			}
+			left = (this.frame.width - width) / 2 + this.frame.left;
+			top = (this.frame.height - height) / 2 + this.frame.top;
+			this.image = {
+				left: left,
+				top: top,
+				width: width,
+				height: height
+			};
+		},
+		async updateData(data) {
+			this.frame = data.frame;
+			this.image = data.image;
+			await this.$nextTick();
+			this.trimImage();
+		},
+		trimImage() {
+			var rate = this.frame.width / this.frame.height;
+			var width = this.body.width * 0.7;
+			var height = this.body.height * 0.7;
+			if (width / height > rate) {
+				width = height * rate;
+			} else {
+				height = width / rate;
+			}
+			var left = (this.body.width - width) / 2;
+			var top = (this.body.height - height) / 2;
+			var mul = width / this.frame.width;
+			var ox = this.frame.left - this.image.left;
+			var oy = this.frame.top - this.image.top;
+			this.frame = {
+				left: left,
+				top: top,
+				width: width,
+				height: height
+			};
+			width = this.image.width * mul;
+			height = this.image.height * mul;
+			left = this.frame.left - ox * mul;
+			top = this.frame.top - oy * mul;
+			this.image = {
+				left: left,
+				top: top,
+				width: width,
+				height: height
+			};
+			if (mul != 1) {
+				this.transit = true;
+				setTimeout(() => {
+					this.transit = false;
+				}, 300);
+			}
+		},
+		rotateAngle() {
+			this.rotate -= 90;
+			var width = this.image.height;
+			var height = this.image.width;
+			var left = this.image.left;
+			var top = this.image.top;
+			var rate = width / height;
+			if (width < this.frame.width) {
+				width = this.frame.width;
+				height = width / rate;
+			}
+			if (height < this.frame.height) {
+				height = this.frame.height;
+				width = height * rate;
+			}
+			if (left > this.frame.left) {
+				left = this.frame.left;
+			}
+			if (top > this.frame.top) {
+				top = this.frame.top;
+			}
+			if (left + width < this.frame.left + this.frame.width) {
+				left = this.frame.left + this.frame.width - width; 
+			}
+			if (top + height < this.frame.top + this.frame.height) {
+				top = this.frame.top + this.frame.height - height; 
+			}
+			this.image = {
+				left: left,
+				top: top,
+				width: width,
+				height: height
+			};
+			this.transit = true;
+			setTimeout(() => {
+				this.transit = false;
+			}, 300);
+		},
+		onok() {
+			// #ifdef MP-WEIXIN
+			this.cropWx();
+			// #endif
+			// #ifdef APP-PLUS || H5
+			this.cropAppH5();
+			// #endif
+		},
+		oncancle() {
+			this.$emit("cancel");
+		},
+		async cropWx() {
+			var mx = this.computeMatrix();
+			this.target = {
+				width: mx.tw,
+				height: mx.th
+			};
+			var canvas = await new Promise((resolve) => {
+				uni.createSelectorQuery()
+				.in(this)
+				.select(".canvas")
+				.fields({node: true})
+				.exec((rst) => {
+					var node = rst[0].node;
+					resolve(node);
+				});
+			});
+			canvas.width = mx.tw;
+			canvas.height = mx.th;
+			uni.showLoading({
+				title: "处理中"
+			});
+			await new Promise((resolve) => {
+				setTimeout(resolve, 200);
+			});
+			var context = canvas.getContext("2d");
+			var image = canvas.createImage();
+			await new Promise((resolve, reject) => {
+				image.onload = resolve;
+				image.onerror = reject;
+				image.src = this.url;
+			});
+			context.save();
+			context.rotate(this.rotate * Math.PI / 180);
+			context.drawImage(image, mx.sx, mx.sy, mx.sw, mx.sh, mx.dx, mx.dy, mx.dw, mx.dh);
+			context.restore();
+			wx.canvasToTempFilePath({
+				canvas: canvas,
+				destWidth: mx.tw,
+				destHeight: mx.th,
+				success: (rst) => {
+					var path = rst.tempFilePath;
+					this.$emit("ok", {
+						path: path
+					});
+				},
+				complete: () => {
+					uni.hideLoading();
+				}
+			});
+		},
+		async cropAppH5() {
+			var mx = this.computeMatrix();
+			this.target = {
+				width: mx.tw,
+				height: mx.th
+			};
+			uni.showLoading({
+				title: "处理中"
+			});
+			await new Promise((resolve) => {
+				setTimeout(resolve, 200);
+			});
+			var context = uni.createCanvasContext(this.canvasId, this);
+			context.save();
+			context.rotate(this.rotate * Math.PI / 180);
+			context.drawImage(this.url, mx.sx, mx.sy, mx.sw, mx.sh, mx.dx, mx.dy, mx.dw, mx.dh);
+			context.restore();
+			await new Promise((resolve) => {
+				context.draw(false, resolve);
+			});
+			uni.canvasToTempFilePath({ 
+				canvasId: this.canvasId,
+				destWidth: mx.tw,
+				destHeight: mx.th,
+				success: (rst) => {
+					var path = rst.tempFilePath;
+					// #ifdef H5
+					var base64 = path;
+					path = this.parseBlob(path);
+					this.$emit("ok", {
+						path: path,
+						base64: base64
+					});
+					// #endif
+					// #ifdef APP-PLUS
+					this.$emit("ok", {
+						path: path
+					});
+					// #endif
+				},
+				complete: () => {
+					uni.hideLoading();
+				}
+			}, this);
+		},
+		computeMatrix() {
+			var width = this.width;
+			var height = this.height;
+			var mul = this.image.width / this.real.width;
+			if (this.rotate % 180 != 0) {
+				mul = this.image.height / this.real.width;
+			}
+			if (this.mode != "fixed") {
+				width = this.frame.width / mul;
+				height = this.frame.height / mul;
+			}
+			var rate = width / height;
+			if (width > this.maxWidth) {
+				width = this.maxWidth;
+				height = width / rate;
+			}
+			if (height > this.maxHeight) {
+				height = this.maxHeight;
+				width = height * rate;
+			}
+			var sx = (this.frame.left - this.image.left) / mul;
+			var sy = (this.frame.top - this.image.top) / mul;
+			var sw = this.frame.width / mul;
+			var sh = this.frame.height / mul;
+			var ox = sx + sw / 2;
+			var oy = sy + sh / 2;
+			if (this.rotate % 180 != 0) {
+				var temp = sw;
+				sw = sh;
+				sh = temp;
+			}
+			var angle = this.rotate % 360;
+			if (angle < 0) {
+				angle += 360;
+			}
+			if (angle == 270) {
+				var x = this.real.width - oy;
+				var y = ox;
+				ox = x;
+				oy = y;
+			}
+			if (angle == 180) {
+				var x = this.real.width - ox;
+				var y = this.real.height - oy;
+				ox = x;
+				oy = y;
+			}
+			if (angle == 90) {
+				var x = oy;
+				var y = this.real.height - ox;
+				ox = x;
+				oy = y;
+			}
+			sx = ox - sw / 2;
+			sy = oy - sh / 2;
+			var dr = {x: 0, y: 0, w: width, h: height};
+			dr = this.parseRect(dr, -this.rotate);
+			return {
+				tw: width,
+				th: height,
+				sx: sx,
+				sy: sy,
+				sw: sw,
+				sh: sh,
+				dx: dr.x,
+				dy: dr.y,
+				dw: dr.w,
+				dh: dr.h
+			};
+		},
+		parsePoint(point, angle) {
+			var result = {};
+			result.x = point.x * Math.cos(angle * Math.PI / 180) - point.y * Math.sin(angle * Math.PI / 180);
+			result.y = point.y * Math.cos(angle * Math.PI / 180) + point.x * Math.sin(angle * Math.PI / 180);
+			return result;
+		},
+		parseRect(rect, angle) {
+			var x1 = rect.x;
+			var y1 = rect.y;
+			var x2 = rect.x + rect.w;
+			var y2 = rect.y + rect.h;
+			var p1 = this.parsePoint({x: x1, y: y1}, angle);
+			var p2 = this.parsePoint({x: x2, y: y2}, angle);
+			var result = {};
+			result.x = Math.min(p1.x, p2.x);
+			result.y = Math.min(p1.y, p2.y);
+			result.w = Math.abs(p2.x - p1.x);
+			result.h = Math.abs(p2.y - p1.y);
+			return result;
+		},
+		parseBlob(base64) {
+			var arr = base64.split(',');
+			var mime = arr[0].match(/:(.*?);/)[1];
+			var bstr = atob(arr[1]);
+			var n = bstr.length;
+			var u8arr = new Uint8Array(n);
+			for(var i = 0; i < n; i++) {
+				u8arr[i] = bstr.charCodeAt(i);
+			}
+			var url = URL || webkitURL;
+			return url.createObjectURL(new Blob([u8arr], {type: mime}));
+		},
+	}
+};
+</script>
+
+<script module="mwx" lang="wxs">
+	var mode = "";
+	var rotate = 0;
+	var image = {
+		left: 0,
+		top: 0,
+		width: 0,
+		height: 0
+	};
+	var frame = {
+		left: 0,
+		top: 0,
+		width: 0,
+		height: 0
+	};
+	var touches = [];
+	var touchType = "";
+	var start = {
+		frame: {
+			left: 0,
+			top: 0,
+			width: 0,
+			height: 0
+		},
+		image: {
+			left: 0,
+			top: 0,
+			width: 0,
+			height: 0
+		}
+	};
+	function changeMode(value) {
+		mode = value;
+	}
+	function changeRotate(value, old, oi, instance) {
+		rotate = value;
+		delayUpdateStyle(oi);
+	}
+	function changeImage(value, old, oi, instance) {
+		image = value;
+		delayUpdateStyle(oi);
+	}
+	function changeFrame(value, old, oi, instance) {
+		frame = value;
+		delayUpdateStyle(oi);
+	}
+    function delayUpdateStyle(oi) {
+        // #ifdef APP-PLUS || H5
+        setTimeout(() => {
+            updateStyle(oi);
+        });
+        // #endif
+        // #ifdef MP-WEIXIN
+        updateStyle(oi);
+        // #endif
+    }
+	function touchstart(event, oi) {
+		// #ifdef APP-PLUS || H5
+		event.preventDefault();
+		event.stopPropagation();
+		// #endif
+		touches = event.touches;
+		var instance = event.instance;
+		if (instance.hasClass("body")) {
+			touchType = "body";
+		} else if (instance.hasClass("frame-left-top")) {
+			touchType = "left-top";
+		} else if (instance.hasClass("frame-left-bottom")) {
+			touchType = "left-bottom";
+		} else if (instance.hasClass("frame-right-top")) {
+			touchType = "right-top";
+		} else if (instance.hasClass("frame-right-bottom")) {
+			touchType = "right-bottom";
+		}
+		start.frame.left = frame.left;
+		start.frame.top = frame.top;
+		start.frame.width = frame.width;
+		start.frame.height = frame.height;
+		start.image.left = image.left;
+		start.image.top = image.top;
+		start.image.width = image.width;
+		start.image.height = image.height;
+		return false;
+	}
+	function touchmove(event, oi) {
+		// #ifdef APP-PLUS || H5
+		event.preventDefault();
+		event.stopPropagation();
+		// #endif
+		var instance = event.instance;
+		if (touches.length == 1) {
+			if (touchType == "body") {
+				moveImage(touches[0], event.touches[0], oi);
+			} else {
+				scaleFrame(touches[0], event.touches[0], oi);
+			}
+		} else if (touches.length == 2 && event.touches.length == 2) {
+			var ta = touches[0];
+			var tb = touches[1];
+			var tc = event.touches[0];
+			var td = event.touches[1];
+			if (ta.identifier != tc.identifier) {
+				var temp = tc;
+				tc = td;
+				td = temp;
+			}
+			scaleImage(ta, tb, tc, td, oi);
+		}
+	}
+	function touchend(event, oi) {
+		touches = [];
+		oi.callMethod("updateData", {frame: frame, image: image});
+	}
+	function touchcancel(event, oi) {
+		touches = [];
+		oi.callMethod("updateData", {frame: frame, image: image});
+	}
+	function moveImage(ta, tb, oi) {
+		var ax = tb.clientX - ta.clientX;
+		var ay = tb.clientY - ta.clientY;
+		image.left = start.image.left + ax;
+		image.top = start.image.top + ay;
+		var left = frame.left;
+		var top = frame.top;
+		var width = frame.width;
+		var height = frame.height;
+		if (image.left > left) {
+			image.left = left;
+		}
+		if (image.top > top) {
+			image.top = top;
+		}
+		if (image.left + image.width < left + width) {
+			image.left = left + width - image.width; 
+		}
+		if (image.top + image.height < top + height) {
+			image.top = top + height - image.height;
+		}
+		updateStyle(oi);
+	}
+	function scaleImage(ta, tb, tc, td, oi) {
+		var x1 = ta.clientX;
+		var y1 = ta.clientY;
+		var x2 = tb.clientX;
+		var y2 = tb.clientY;
+		var x3 = tc.clientX;
+		var y3 = tc.clientY;
+		var x4 = td.clientX;
+		var y4 = td.clientY;
+		var ol = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+		var el = Math.sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4));
+		var ocx = (x1 + x2) / 2;
+		var ocy = (y1 + y2) / 2;
+		var ecx = (x3 + x4) / 2;
+		var ecy = (y3 + y4) / 2;
+		var ax = ecx - ocx;
+		var ay = ecy - ocy;
+		var scale = el / ol;
+		if (start.image.width * scale < frame.width) {
+			scale = frame.width / start.image.width;
+		}
+		if (start.image.height * scale < frame.height) {
+			scale = frame.height / start.image.height;
+		}
+		if (start.image.width * scale < frame.width) {
+			scale = frame.width / start.image.width;
+		}
+		image.left = start.image.left + ax - (ocx - start.image.left) * (scale - 1);
+		image.top = start.image.top + ay - (ocy - start.image.top) * (scale - 1);
+		image.width = start.image.width * scale;
+		image.height = start.image.height * scale;
+		if (image.left > frame.left) {
+			image.left = frame.left;
+		}
+		if (image.top > frame.top) {
+			image.top = frame.top;
+		}
+		if (image.left + image.width < frame.left + frame.width) {
+			image.left = frame.left + frame.width - image.width; 
+		}
+		if (image.top + image.height < frame.top + frame.height) {
+			image.top = frame.top + frame.height - image.height; 
+		}
+		updateStyle(oi);
+	}
+	function scaleFrame(ta, tb, oi) {
+		var ax = tb.clientX - ta.clientX;
+		var ay = tb.clientY - ta.clientY;
+		var x1 = start.frame.left;
+		var y1 = start.frame.top;
+		var x2 = start.frame.left + start.frame.width;
+		var y2 = start.frame.top + start.frame.height;
+		var cx1 = false;
+		var cy1 = false;
+		var cx2 = false;
+		var cy2 = false;
+		var mix = 30;
+		var rate = frame.width / frame.height;
+		if (touchType == "left-top") {
+			x1 += ax;
+			y1 += ay;
+			cx1 = true;
+			cy1 = true;
+		} else if (touchType == "left-bottom") {
+			x1 += ax;
+			y2 += ay;
+			cx1 = true;
+			cy2 = true;
+		} else if (touchType == "right-top") {
+			x2 += ax;
+			y1 += ay;
+			cx2 = true;
+			cy1 = true;
+		} else if (touchType == "right-bottom") {
+			x2 += ax;
+			y2 += ay;
+			cx2 = true;
+			cy2 = true;
+		}
+		if (x1 < image.left) {
+			x1 = image.left;
+		}
+		if (y1 < image.top) {
+			y1 = image.top;
+		}
+		if (x2 > image.left + image.width) {
+			x2 = image.left + image.width;
+		}
+		if (y2 > image.top + image.height) {
+			y2 = image.top + image.height;
+		}
+		if (cx1) {
+			if (x1 > x2 - mix) {
+				x1 = x2 - mix;
+			}
+		}
+		if (cy1) {
+			if (y1 > y2 - mix) {
+				y1 = y2 - mix;
+			}
+		}
+		if (cx2) {
+			if (x2 < x1 + mix) {
+				x2 = x1 + mix;
+			}
+		}
+		if (cy2) {
+			if (y2 < y1 + mix) {
+				y2 = y1 + mix;
+			}
+		}
+		if (cx1) {
+			if (mode != "free") {
+				var val = x2 - rate * (y2 - y1);
+				if (x1 < val) {
+					x1 = val;
+				}
+			}
+		}
+		if (cy1) {
+			if (mode != "free") {
+				var val = y2 - (x2 - x1) / rate;
+				if (y1 < val) {
+					y1 = val;
+				}
+			}
+		}
+		if (cx2) {
+			if (mode != "free") {
+				var val = rate * (y2 - y1) + x1;
+				if (x2 > val) {
+					x2 = val;
+				}
+			}
+		}
+		if (cy2) {
+			if (mode != "free") {
+				var val = (x2 - x1) / rate + y1;
+				if (y2 > val) {
+					y2 = val;
+				}
+			}
+		}
+		frame.left = x1;
+		frame.top = y1;
+		frame.width = x2 - x1;
+		frame.height = y2 - y1;
+		updateStyle(oi);
+	}
+	function updateStyle(oi) {
+		oi.selectComponent(".frame").setStyle({
+			"left": frame.left + "px",
+			"top": frame.top + "px",
+			"width": frame.width + "px",
+			"height": frame.height + "px"
+		});
+		oi.selectComponent(".image-wrap").setStyle({
+			"left": image.left + "px",
+			"top": image.top + "px",
+			"width": image.width + "px",
+			"height": image.height + "px"
+		});
+		oi.selectComponent(".image-rect").setStyle({
+			"left": image.left - frame.left + "px",
+			"top": image.top - frame.top + "px",
+			"width": image.width + "px",
+			"height": image.height + "px"
+		});
+		var left = 0;
+		var top = 0;
+		var width = image.width;
+		var height = image.height;
+		if (rotate % 180 != 0) {
+			width = image.height;
+			height = image.width;
+			top = width / 2 - height / 2;
+			left = height / 2 - width/ 2;
+		}
+		oi.selectComponent(".image-wrap .image").setStyle({
+			"left": left + "px",
+			"top": top + "px",
+			"width": width + "px",
+			"height": height + "px",
+			"transform": "rotate(" + rotate + "deg)"
+		});
+		oi.selectComponent(".image-rect .image").setStyle({
+			"left": left + "px",
+			"top": top + "px",
+			"width": width + "px",
+			"height": height + "px",
+			"transform": "rotate(" + rotate + "deg)"
+		});
+	}
+	module.exports = {
+		changeMode: changeMode,
+		changeRotate: changeRotate,
+		changeImage: changeImage,
+		changeFrame: changeFrame,
+		touchstart: touchstart,
+		touchmove: touchmove,
+		touchend: touchend,
+		touchcancel: touchcancel
+	};
+</script>
+
+<style scoped>
+.panel {
+	position: fixed;
+	width: 100%;
+	height: 100%;
+	top: 0;
+	bottom: 0;
+	z-index: 1000;
+	overflow: hidden;
+}
+.canvas {
+	position: absolute;
+	top: 5000px;
+	left: 5000px;
+}
+.toolbar {
+	position: absolute;
+	width: 100%;
+	height: 100rpx;
+	left: 0rpx;
+	bottom: 0rpx;
+	display: flex;
+	justify-content: space-around;
+	align-items: center;
+}
+.btn-cancel {
+	font-size: 40rpx;
+	color: #d5dfe5;
+	font-weight: bold;
+}
+.btn-ok {
+	font-size: 40rpx;
+	color: #FFFFFF;
+	font-weight: bold;
+}
+.btn-rotate {
+	font-size: 40rpx;
+	color: #d5dfe5;
+	font-weight: bold;
+}
+.body {
+	position: absolute;
+	left: 0rpx;
+	right: 0rpx;
+	top: 0rpx;
+	bottom: 0rpx;
+	background: black;
+	overflow: hidden;
+}
+.mask {
+	position: absolute;
+	left: 0rpx;
+	right: 0rpx;
+	top: 0rpx;
+	bottom: 0rpx;
+	background: black;
+	opacity: 0.4;
+}
+.plank {
+	position: absolute;
+	left: 0rpx;
+	right: 0rpx;
+	top: 0rpx;
+	bottom: 0rpx;
+}
+.image-wrap {
+	position: absolute;
+}
+.image-rect {
+	position: absolute;
+}
+.image {
+	position: absolute;
+}
+.frame {
+	position: absolute;
+	left: 100px;
+	top: 100px;
+	width: 200px;
+	height: 200px;
+}
+.rect {
+	position: absolute;
+	left: -2px;
+	top: -2px;
+	width: 100%;
+	height: 100%;
+	border: 2px solid white;
+	overflow: hidden;
+	box-sizing:content-box;
+}
+.line-one {
+	position: absolute;
+	width: 100%;
+	height: 1px;
+	background: white;
+	left: 0;
+	top: 33.3%;
+	box-sizing:content-box;
+}
+.line-two {
+	position: absolute;
+	width: 100%;
+	height: 1px;
+	background: white;
+	left: 0;
+	top: 66.7%;
+	box-sizing:content-box;
+}
+.line-three {
+	position: absolute;
+	width: 1px;
+	height: 100%;
+	background: white;
+	top: 0;
+	left: 33.3%;
+	box-sizing:content-box;
+}
+.line-four {
+	position: absolute;
+	width: 1px;
+	height: 100%;
+	background: white;
+	top: 0;
+	left: 66.7%;
+	box-sizing:content-box;
+}
+.frame-left-top {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	left: -6px;
+	top: -6px;
+	border-left: 4px solid red;
+	border-top: 4px solid red;
+	box-sizing:content-box;
+}
+.frame-left-bottom {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	left: -6px;
+	bottom: -6px;
+	border-left: 4px solid red;
+	border-bottom: 4px solid red;
+	box-sizing:content-box;
+}
+.frame-right-top {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	right: -6px;
+	top: -6px;
+	border-right: 4px solid red;
+	border-top: 4px solid red;
+	box-sizing:content-box;
+}
+.frame-right-bottom {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	right: -6px;
+	bottom: -6px;
+	border-right: 4px solid red;
+	border-bottom: 4px solid red;
+	box-sizing:content-box;
+}
+.transit {
+	transition: width 0.3s, height 0.3s, left 0.3s, top 0.3s, transform 0.3s;
+}
+</style>

+ 84 - 0
uni_modules/ksp-cropper/package.json

@@ -0,0 +1,84 @@
+{
+  "id": "ksp-cropper",
+  "displayName": "ksp-cropper",
+  "version": "1.1.5",
+  "description": "高性能图片裁剪工具",
+  "keywords": [
+    "头像",
+    "图片",
+    "裁剪"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "前端组件",
+        "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "u",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": {
+            "minVersion": "2.9.0"
+        },
+          "阿里": "n",
+          "百度": "n",
+          "字节跳动": "n",
+          "QQ": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}

+ 73 - 0
uni_modules/ksp-cropper/readme.md

@@ -0,0 +1,73 @@
+# ksp-cropper
+
+## 高性能图片裁剪工具
+
+### 属性说明
+|属性         |类型     |默认     |备注      |
+| :--------: | :-----: | :----:  | :----:  |
+| url        |String   |   ""    | 需要裁剪的图片路径,为空时控件隐藏,不为空时控件显示|
+| mode       |String   | "free"  | 裁剪模式|
+| width      |Number   | 200     | 图片裁剪后的宽度,固定大小时有效|
+| height     |Number   | 200     | 图片裁剪后的高度,固定大小时有效|
+| maxWidth   |Number   | 1024    | 图片裁剪后的最大宽度 |
+| maxHeight  |Number   | 1024    | 图片裁剪后的最大高度 |
+
+### mode有效值
+
+| 模式     |值       |说明   |
+| :-----: | :-----: | :----: |
+| 固定模式 |fixed    | 裁剪出指定大小的图片,一般用于头像上传    |
+| 等比缩放 |ratio    | 限定宽高比,裁剪大小不固定  |
+| 自由模式 |free     | 不限定宽高比,裁剪大小不固定  | 
+
+### 事件说明
+|事件名称     |说明     |返回     |
+| :--------: | :-----: | :----:  |
+| ok        |点击确定按钮   |   e:{path}    |
+| cancel      |点击取消按钮  | -   |
+
+
+### 示例
+
+```html
+
+<template>
+<view>
+	<button @click="select">选择图片</button>
+	<image mode="widthFix" :src="path"/>
+	<ksp-cropper mode="free" :width="200" :height="140" :maxWidth="1024" :maxHeight="1024" :url="url" @cancel="oncancel" @ok="onok"></ksp-cropper>
+</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				url: "",
+				path: ""
+			}
+		},
+		onLoad() {
+		},
+		methods: {
+			select() {
+				uni.chooseImage({
+					count: 1,
+					success: (rst) => {
+						// 设置url的值,显示控件
+						this.url = rst.tempFilePaths[0];
+					}
+				});
+			},
+			onok(ev) {
+				this.url = "";
+				this.path = ev.path;
+			},
+			oncancel() {
+				// url设置为空,隐藏控件
+				this.url = "";
+			}
+		}
+	}
+</script>
+```

+ 22 - 0
uni_modules/uni-icons/changelog.md

@@ -0,0 +1,22 @@
+## 1.3.5(2022-01-24)
+- 优化 size 属性可以传入不带单位的字符串数值
+## 1.3.4(2022-01-24)
+- 优化 size 支持其他单位
+## 1.3.3(2022-01-17)
+- 修复 nvue 有些图标不显示的bug,兼容老版本图标
+## 1.3.2(2021-12-01)
+- 优化 示例可复制图标名称
+## 1.3.1(2021-11-23)
+- 优化 兼容旧组件 type 值
+## 1.3.0(2021-11-19)
+- 新增 更多图标
+- 优化 自定义图标使用方式
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
+## 1.1.7(2021-11-08)
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.5(2021-05-12)
+- 新增 组件示例地址
+## 1.1.4(2021-02-05)
+- 调整为uni_modules目录规范

+ 1169 - 0
uni_modules/uni-icons/components/uni-icons/icons.js

@@ -0,0 +1,1169 @@
+export default {
+  "id": "2852637",
+  "name": "uniui图标库",
+  "font_family": "uniicons",
+  "css_prefix_text": "uniui-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "25027049",
+      "name": "yanse",
+      "font_class": "color",
+      "unicode": "e6cf",
+      "unicode_decimal": 59087
+    },
+    {
+      "icon_id": "25027048",
+      "name": "wallet",
+      "font_class": "wallet",
+      "unicode": "e6b1",
+      "unicode_decimal": 59057
+    },
+    {
+      "icon_id": "25015720",
+      "name": "settings-filled",
+      "font_class": "settings-filled",
+      "unicode": "e6ce",
+      "unicode_decimal": 59086
+    },
+    {
+      "icon_id": "25015434",
+      "name": "shimingrenzheng-filled",
+      "font_class": "auth-filled",
+      "unicode": "e6cc",
+      "unicode_decimal": 59084
+    },
+    {
+      "icon_id": "24934246",
+      "name": "shop-filled",
+      "font_class": "shop-filled",
+      "unicode": "e6cd",
+      "unicode_decimal": 59085
+    },
+    {
+      "icon_id": "24934159",
+      "name": "staff-filled-01",
+      "font_class": "staff-filled",
+      "unicode": "e6cb",
+      "unicode_decimal": 59083
+    },
+    {
+      "icon_id": "24932461",
+      "name": "VIP-filled",
+      "font_class": "vip-filled",
+      "unicode": "e6c6",
+      "unicode_decimal": 59078
+    },
+    {
+      "icon_id": "24932462",
+      "name": "plus_circle_fill",
+      "font_class": "plus-filled",
+      "unicode": "e6c7",
+      "unicode_decimal": 59079
+    },
+    {
+      "icon_id": "24932463",
+      "name": "folder_add-filled",
+      "font_class": "folder-add-filled",
+      "unicode": "e6c8",
+      "unicode_decimal": 59080
+    },
+    {
+      "icon_id": "24932464",
+      "name": "yanse-filled",
+      "font_class": "color-filled",
+      "unicode": "e6c9",
+      "unicode_decimal": 59081
+    },
+    {
+      "icon_id": "24932465",
+      "name": "tune-filled",
+      "font_class": "tune-filled",
+      "unicode": "e6ca",
+      "unicode_decimal": 59082
+    },
+    {
+      "icon_id": "24932455",
+      "name": "a-rilidaka-filled",
+      "font_class": "calendar-filled",
+      "unicode": "e6c0",
+      "unicode_decimal": 59072
+    },
+    {
+      "icon_id": "24932456",
+      "name": "notification-filled",
+      "font_class": "notification-filled",
+      "unicode": "e6c1",
+      "unicode_decimal": 59073
+    },
+    {
+      "icon_id": "24932457",
+      "name": "wallet-filled",
+      "font_class": "wallet-filled",
+      "unicode": "e6c2",
+      "unicode_decimal": 59074
+    },
+    {
+      "icon_id": "24932458",
+      "name": "paihangbang-filled",
+      "font_class": "medal-filled",
+      "unicode": "e6c3",
+      "unicode_decimal": 59075
+    },
+    {
+      "icon_id": "24932459",
+      "name": "gift-filled",
+      "font_class": "gift-filled",
+      "unicode": "e6c4",
+      "unicode_decimal": 59076
+    },
+    {
+      "icon_id": "24932460",
+      "name": "fire-filled",
+      "font_class": "fire-filled",
+      "unicode": "e6c5",
+      "unicode_decimal": 59077
+    },
+    {
+      "icon_id": "24928001",
+      "name": "refreshempty",
+      "font_class": "refreshempty",
+      "unicode": "e6bf",
+      "unicode_decimal": 59071
+    },
+    {
+      "icon_id": "24926853",
+      "name": "location-ellipse",
+      "font_class": "location-filled",
+      "unicode": "e6af",
+      "unicode_decimal": 59055
+    },
+    {
+      "icon_id": "24926735",
+      "name": "person-filled",
+      "font_class": "person-filled",
+      "unicode": "e69d",
+      "unicode_decimal": 59037
+    },
+    {
+      "icon_id": "24926703",
+      "name": "personadd-filled",
+      "font_class": "personadd-filled",
+      "unicode": "e698",
+      "unicode_decimal": 59032
+    },
+    {
+      "icon_id": "24923351",
+      "name": "back",
+      "font_class": "back",
+      "unicode": "e6b9",
+      "unicode_decimal": 59065
+    },
+    {
+      "icon_id": "24923352",
+      "name": "forward",
+      "font_class": "forward",
+      "unicode": "e6ba",
+      "unicode_decimal": 59066
+    },
+    {
+      "icon_id": "24923353",
+      "name": "arrowthinright",
+      "font_class": "arrow-right",
+      "unicode": "e6bb",
+      "unicode_decimal": 59067
+    },
+		{
+		  "icon_id": "24923353",
+		  "name": "arrowthinright",
+		  "font_class": "arrowthinright",
+		  "unicode": "e6bb",
+		  "unicode_decimal": 59067
+		},
+    {
+      "icon_id": "24923354",
+      "name": "arrowthinleft",
+      "font_class": "arrow-left",
+      "unicode": "e6bc",
+      "unicode_decimal": 59068
+    },
+		{
+		  "icon_id": "24923354",
+		  "name": "arrowthinleft",
+		  "font_class": "arrowthinleft",
+		  "unicode": "e6bc",
+		  "unicode_decimal": 59068
+		},
+    {
+      "icon_id": "24923355",
+      "name": "arrowthinup",
+      "font_class": "arrow-up",
+      "unicode": "e6bd",
+      "unicode_decimal": 59069
+    },
+		{
+		  "icon_id": "24923355",
+		  "name": "arrowthinup",
+		  "font_class": "arrowthinup",
+		  "unicode": "e6bd",
+		  "unicode_decimal": 59069
+		},
+    {
+      "icon_id": "24923356",
+      "name": "arrowthindown",
+      "font_class": "arrow-down",
+      "unicode": "e6be",
+      "unicode_decimal": 59070
+    },{
+      "icon_id": "24923356",
+      "name": "arrowthindown",
+      "font_class": "arrowthindown",
+      "unicode": "e6be",
+      "unicode_decimal": 59070
+    },
+    {
+      "icon_id": "24923349",
+      "name": "arrowdown",
+      "font_class": "bottom",
+      "unicode": "e6b8",
+      "unicode_decimal": 59064
+    },{
+      "icon_id": "24923349",
+      "name": "arrowdown",
+      "font_class": "arrowdown",
+      "unicode": "e6b8",
+      "unicode_decimal": 59064
+    },
+    {
+      "icon_id": "24923346",
+      "name": "arrowright",
+      "font_class": "right",
+      "unicode": "e6b5",
+      "unicode_decimal": 59061
+    },
+		{
+		  "icon_id": "24923346",
+		  "name": "arrowright",
+		  "font_class": "arrowright",
+		  "unicode": "e6b5",
+		  "unicode_decimal": 59061
+		},
+    {
+      "icon_id": "24923347",
+      "name": "arrowup",
+      "font_class": "top",
+      "unicode": "e6b6",
+      "unicode_decimal": 59062
+    },
+		{
+		  "icon_id": "24923347",
+		  "name": "arrowup",
+		  "font_class": "arrowup",
+		  "unicode": "e6b6",
+		  "unicode_decimal": 59062
+		},
+    {
+      "icon_id": "24923348",
+      "name": "arrowleft",
+      "font_class": "left",
+      "unicode": "e6b7",
+      "unicode_decimal": 59063
+    },
+		{
+		  "icon_id": "24923348",
+		  "name": "arrowleft",
+		  "font_class": "arrowleft",
+		  "unicode": "e6b7",
+		  "unicode_decimal": 59063
+		},
+    {
+      "icon_id": "24923334",
+      "name": "eye",
+      "font_class": "eye",
+      "unicode": "e651",
+      "unicode_decimal": 58961
+    },
+    {
+      "icon_id": "24923335",
+      "name": "eye-filled",
+      "font_class": "eye-filled",
+      "unicode": "e66a",
+      "unicode_decimal": 58986
+    },
+    {
+      "icon_id": "24923336",
+      "name": "eye-slash",
+      "font_class": "eye-slash",
+      "unicode": "e6b3",
+      "unicode_decimal": 59059
+    },
+    {
+      "icon_id": "24923337",
+      "name": "eye-slash-filled",
+      "font_class": "eye-slash-filled",
+      "unicode": "e6b4",
+      "unicode_decimal": 59060
+    },
+    {
+      "icon_id": "24923305",
+      "name": "info-filled",
+      "font_class": "info-filled",
+      "unicode": "e649",
+      "unicode_decimal": 58953
+    },
+    {
+      "icon_id": "24923299",
+      "name": "reload-01",
+      "font_class": "reload",
+      "unicode": "e6b2",
+      "unicode_decimal": 59058
+    },
+    {
+      "icon_id": "24923195",
+      "name": "mic_slash_fill",
+      "font_class": "micoff-filled",
+      "unicode": "e6b0",
+      "unicode_decimal": 59056
+    },
+    {
+      "icon_id": "24923165",
+      "name": "map-pin-ellipse",
+      "font_class": "map-pin-ellipse",
+      "unicode": "e6ac",
+      "unicode_decimal": 59052
+    },
+    {
+      "icon_id": "24923166",
+      "name": "map-pin",
+      "font_class": "map-pin",
+      "unicode": "e6ad",
+      "unicode_decimal": 59053
+    },
+    {
+      "icon_id": "24923167",
+      "name": "location",
+      "font_class": "location",
+      "unicode": "e6ae",
+      "unicode_decimal": 59054
+    },
+    {
+      "icon_id": "24923064",
+      "name": "starhalf",
+      "font_class": "starhalf",
+      "unicode": "e683",
+      "unicode_decimal": 59011
+    },
+    {
+      "icon_id": "24923065",
+      "name": "star",
+      "font_class": "star",
+      "unicode": "e688",
+      "unicode_decimal": 59016
+    },
+    {
+      "icon_id": "24923066",
+      "name": "star-filled",
+      "font_class": "star-filled",
+      "unicode": "e68f",
+      "unicode_decimal": 59023
+    },
+    {
+      "icon_id": "24899646",
+      "name": "a-rilidaka",
+      "font_class": "calendar",
+      "unicode": "e6a0",
+      "unicode_decimal": 59040
+    },
+    {
+      "icon_id": "24899647",
+      "name": "fire",
+      "font_class": "fire",
+      "unicode": "e6a1",
+      "unicode_decimal": 59041
+    },
+    {
+      "icon_id": "24899648",
+      "name": "paihangbang",
+      "font_class": "medal",
+      "unicode": "e6a2",
+      "unicode_decimal": 59042
+    },
+    {
+      "icon_id": "24899649",
+      "name": "font",
+      "font_class": "font",
+      "unicode": "e6a3",
+      "unicode_decimal": 59043
+    },
+    {
+      "icon_id": "24899650",
+      "name": "gift",
+      "font_class": "gift",
+      "unicode": "e6a4",
+      "unicode_decimal": 59044
+    },
+    {
+      "icon_id": "24899651",
+      "name": "link",
+      "font_class": "link",
+      "unicode": "e6a5",
+      "unicode_decimal": 59045
+    },
+    {
+      "icon_id": "24899652",
+      "name": "notification",
+      "font_class": "notification",
+      "unicode": "e6a6",
+      "unicode_decimal": 59046
+    },
+    {
+      "icon_id": "24899653",
+      "name": "staff",
+      "font_class": "staff",
+      "unicode": "e6a7",
+      "unicode_decimal": 59047
+    },
+    {
+      "icon_id": "24899654",
+      "name": "VIP",
+      "font_class": "vip",
+      "unicode": "e6a8",
+      "unicode_decimal": 59048
+    },
+    {
+      "icon_id": "24899655",
+      "name": "folder_add",
+      "font_class": "folder-add",
+      "unicode": "e6a9",
+      "unicode_decimal": 59049
+    },
+    {
+      "icon_id": "24899656",
+      "name": "tune",
+      "font_class": "tune",
+      "unicode": "e6aa",
+      "unicode_decimal": 59050
+    },
+    {
+      "icon_id": "24899657",
+      "name": "shimingrenzheng",
+      "font_class": "auth",
+      "unicode": "e6ab",
+      "unicode_decimal": 59051
+    },
+    {
+      "icon_id": "24899565",
+      "name": "person",
+      "font_class": "person",
+      "unicode": "e699",
+      "unicode_decimal": 59033
+    },
+    {
+      "icon_id": "24899566",
+      "name": "email-filled",
+      "font_class": "email-filled",
+      "unicode": "e69a",
+      "unicode_decimal": 59034
+    },
+    {
+      "icon_id": "24899567",
+      "name": "phone-filled",
+      "font_class": "phone-filled",
+      "unicode": "e69b",
+      "unicode_decimal": 59035
+    },
+    {
+      "icon_id": "24899568",
+      "name": "phone",
+      "font_class": "phone",
+      "unicode": "e69c",
+      "unicode_decimal": 59036
+    },
+    {
+      "icon_id": "24899570",
+      "name": "email",
+      "font_class": "email",
+      "unicode": "e69e",
+      "unicode_decimal": 59038
+    },
+    {
+      "icon_id": "24899571",
+      "name": "personadd",
+      "font_class": "personadd",
+      "unicode": "e69f",
+      "unicode_decimal": 59039
+    },
+    {
+      "icon_id": "24899558",
+      "name": "chatboxes-filled",
+      "font_class": "chatboxes-filled",
+      "unicode": "e692",
+      "unicode_decimal": 59026
+    },
+    {
+      "icon_id": "24899559",
+      "name": "contact",
+      "font_class": "contact",
+      "unicode": "e693",
+      "unicode_decimal": 59027
+    },
+    {
+      "icon_id": "24899560",
+      "name": "chatbubble-filled",
+      "font_class": "chatbubble-filled",
+      "unicode": "e694",
+      "unicode_decimal": 59028
+    },
+    {
+      "icon_id": "24899561",
+      "name": "contact-filled",
+      "font_class": "contact-filled",
+      "unicode": "e695",
+      "unicode_decimal": 59029
+    },
+    {
+      "icon_id": "24899562",
+      "name": "chatboxes",
+      "font_class": "chatboxes",
+      "unicode": "e696",
+      "unicode_decimal": 59030
+    },
+    {
+      "icon_id": "24899563",
+      "name": "chatbubble",
+      "font_class": "chatbubble",
+      "unicode": "e697",
+      "unicode_decimal": 59031
+    },
+    {
+      "icon_id": "24881290",
+      "name": "upload-filled",
+      "font_class": "upload-filled",
+      "unicode": "e68e",
+      "unicode_decimal": 59022
+    },
+    {
+      "icon_id": "24881292",
+      "name": "upload",
+      "font_class": "upload",
+      "unicode": "e690",
+      "unicode_decimal": 59024
+    },
+    {
+      "icon_id": "24881293",
+      "name": "weixin",
+      "font_class": "weixin",
+      "unicode": "e691",
+      "unicode_decimal": 59025
+    },
+    {
+      "icon_id": "24881274",
+      "name": "compose",
+      "font_class": "compose",
+      "unicode": "e67f",
+      "unicode_decimal": 59007
+    },
+    {
+      "icon_id": "24881275",
+      "name": "qq",
+      "font_class": "qq",
+      "unicode": "e680",
+      "unicode_decimal": 59008
+    },
+    {
+      "icon_id": "24881276",
+      "name": "download-filled",
+      "font_class": "download-filled",
+      "unicode": "e681",
+      "unicode_decimal": 59009
+    },
+    {
+      "icon_id": "24881277",
+      "name": "pengyouquan",
+      "font_class": "pyq",
+      "unicode": "e682",
+      "unicode_decimal": 59010
+    },
+    {
+      "icon_id": "24881279",
+      "name": "sound",
+      "font_class": "sound",
+      "unicode": "e684",
+      "unicode_decimal": 59012
+    },
+    {
+      "icon_id": "24881280",
+      "name": "trash-filled",
+      "font_class": "trash-filled",
+      "unicode": "e685",
+      "unicode_decimal": 59013
+    },
+    {
+      "icon_id": "24881281",
+      "name": "sound-filled",
+      "font_class": "sound-filled",
+      "unicode": "e686",
+      "unicode_decimal": 59014
+    },
+    {
+      "icon_id": "24881282",
+      "name": "trash",
+      "font_class": "trash",
+      "unicode": "e687",
+      "unicode_decimal": 59015
+    },
+    {
+      "icon_id": "24881284",
+      "name": "videocam-filled",
+      "font_class": "videocam-filled",
+      "unicode": "e689",
+      "unicode_decimal": 59017
+    },
+    {
+      "icon_id": "24881285",
+      "name": "spinner-cycle",
+      "font_class": "spinner-cycle",
+      "unicode": "e68a",
+      "unicode_decimal": 59018
+    },
+    {
+      "icon_id": "24881286",
+      "name": "weibo",
+      "font_class": "weibo",
+      "unicode": "e68b",
+      "unicode_decimal": 59019
+    },
+    {
+      "icon_id": "24881288",
+      "name": "videocam",
+      "font_class": "videocam",
+      "unicode": "e68c",
+      "unicode_decimal": 59020
+    },
+    {
+      "icon_id": "24881289",
+      "name": "download",
+      "font_class": "download",
+      "unicode": "e68d",
+      "unicode_decimal": 59021
+    },
+    {
+      "icon_id": "24879601",
+      "name": "help",
+      "font_class": "help",
+      "unicode": "e679",
+      "unicode_decimal": 59001
+    },
+    {
+      "icon_id": "24879602",
+      "name": "navigate-filled",
+      "font_class": "navigate-filled",
+      "unicode": "e67a",
+      "unicode_decimal": 59002
+    },
+    {
+      "icon_id": "24879603",
+      "name": "plusempty",
+      "font_class": "plusempty",
+      "unicode": "e67b",
+      "unicode_decimal": 59003
+    },
+    {
+      "icon_id": "24879604",
+      "name": "smallcircle",
+      "font_class": "smallcircle",
+      "unicode": "e67c",
+      "unicode_decimal": 59004
+    },
+    {
+      "icon_id": "24879605",
+      "name": "minus-filled",
+      "font_class": "minus-filled",
+      "unicode": "e67d",
+      "unicode_decimal": 59005
+    },
+    {
+      "icon_id": "24879606",
+      "name": "micoff",
+      "font_class": "micoff",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
+    {
+      "icon_id": "24879588",
+      "name": "closeempty",
+      "font_class": "closeempty",
+      "unicode": "e66c",
+      "unicode_decimal": 58988
+    },
+    {
+      "icon_id": "24879589",
+      "name": "clear",
+      "font_class": "clear",
+      "unicode": "e66d",
+      "unicode_decimal": 58989
+    },
+    {
+      "icon_id": "24879590",
+      "name": "navigate",
+      "font_class": "navigate",
+      "unicode": "e66e",
+      "unicode_decimal": 58990
+    },
+    {
+      "icon_id": "24879591",
+      "name": "minus",
+      "font_class": "minus",
+      "unicode": "e66f",
+      "unicode_decimal": 58991
+    },
+    {
+      "icon_id": "24879592",
+      "name": "image",
+      "font_class": "image",
+      "unicode": "e670",
+      "unicode_decimal": 58992
+    },
+    {
+      "icon_id": "24879593",
+      "name": "mic",
+      "font_class": "mic",
+      "unicode": "e671",
+      "unicode_decimal": 58993
+    },
+    {
+      "icon_id": "24879594",
+      "name": "paperplane",
+      "font_class": "paperplane",
+      "unicode": "e672",
+      "unicode_decimal": 58994
+    },
+    {
+      "icon_id": "24879595",
+      "name": "close",
+      "font_class": "close",
+      "unicode": "e673",
+      "unicode_decimal": 58995
+    },
+    {
+      "icon_id": "24879596",
+      "name": "help-filled",
+      "font_class": "help-filled",
+      "unicode": "e674",
+      "unicode_decimal": 58996
+    },
+    {
+      "icon_id": "24879597",
+      "name": "plus-filled",
+      "font_class": "paperplane-filled",
+      "unicode": "e675",
+      "unicode_decimal": 58997
+    },
+    {
+      "icon_id": "24879598",
+      "name": "plus",
+      "font_class": "plus",
+      "unicode": "e676",
+      "unicode_decimal": 58998
+    },
+    {
+      "icon_id": "24879599",
+      "name": "mic-filled",
+      "font_class": "mic-filled",
+      "unicode": "e677",
+      "unicode_decimal": 58999
+    },
+    {
+      "icon_id": "24879600",
+      "name": "image-filled",
+      "font_class": "image-filled",
+      "unicode": "e678",
+      "unicode_decimal": 59000
+    },
+    {
+      "icon_id": "24855900",
+      "name": "locked-filled",
+      "font_class": "locked-filled",
+      "unicode": "e668",
+      "unicode_decimal": 58984
+    },
+    {
+      "icon_id": "24855901",
+      "name": "info",
+      "font_class": "info",
+      "unicode": "e669",
+      "unicode_decimal": 58985
+    },
+    {
+      "icon_id": "24855903",
+      "name": "locked",
+      "font_class": "locked",
+      "unicode": "e66b",
+      "unicode_decimal": 58987
+    },
+    {
+      "icon_id": "24855884",
+      "name": "camera-filled",
+      "font_class": "camera-filled",
+      "unicode": "e658",
+      "unicode_decimal": 58968
+    },
+    {
+      "icon_id": "24855885",
+      "name": "chat-filled",
+      "font_class": "chat-filled",
+      "unicode": "e659",
+      "unicode_decimal": 58969
+    },
+    {
+      "icon_id": "24855886",
+      "name": "camera",
+      "font_class": "camera",
+      "unicode": "e65a",
+      "unicode_decimal": 58970
+    },
+    {
+      "icon_id": "24855887",
+      "name": "circle",
+      "font_class": "circle",
+      "unicode": "e65b",
+      "unicode_decimal": 58971
+    },
+    {
+      "icon_id": "24855888",
+      "name": "checkmarkempty",
+      "font_class": "checkmarkempty",
+      "unicode": "e65c",
+      "unicode_decimal": 58972
+    },
+    {
+      "icon_id": "24855889",
+      "name": "chat",
+      "font_class": "chat",
+      "unicode": "e65d",
+      "unicode_decimal": 58973
+    },
+    {
+      "icon_id": "24855890",
+      "name": "circle-filled",
+      "font_class": "circle-filled",
+      "unicode": "e65e",
+      "unicode_decimal": 58974
+    },
+    {
+      "icon_id": "24855891",
+      "name": "flag",
+      "font_class": "flag",
+      "unicode": "e65f",
+      "unicode_decimal": 58975
+    },
+    {
+      "icon_id": "24855892",
+      "name": "flag-filled",
+      "font_class": "flag-filled",
+      "unicode": "e660",
+      "unicode_decimal": 58976
+    },
+    {
+      "icon_id": "24855893",
+      "name": "gear-filled",
+      "font_class": "gear-filled",
+      "unicode": "e661",
+      "unicode_decimal": 58977
+    },
+    {
+      "icon_id": "24855894",
+      "name": "home",
+      "font_class": "home",
+      "unicode": "e662",
+      "unicode_decimal": 58978
+    },
+    {
+      "icon_id": "24855895",
+      "name": "home-filled",
+      "font_class": "home-filled",
+      "unicode": "e663",
+      "unicode_decimal": 58979
+    },
+    {
+      "icon_id": "24855896",
+      "name": "gear",
+      "font_class": "gear",
+      "unicode": "e664",
+      "unicode_decimal": 58980
+    },
+    {
+      "icon_id": "24855897",
+      "name": "smallcircle-filled",
+      "font_class": "smallcircle-filled",
+      "unicode": "e665",
+      "unicode_decimal": 58981
+    },
+    {
+      "icon_id": "24855898",
+      "name": "map-filled",
+      "font_class": "map-filled",
+      "unicode": "e666",
+      "unicode_decimal": 58982
+    },
+    {
+      "icon_id": "24855899",
+      "name": "map",
+      "font_class": "map",
+      "unicode": "e667",
+      "unicode_decimal": 58983
+    },
+    {
+      "icon_id": "24855825",
+      "name": "refresh-filled",
+      "font_class": "refresh-filled",
+      "unicode": "e656",
+      "unicode_decimal": 58966
+    },
+    {
+      "icon_id": "24855826",
+      "name": "refresh",
+      "font_class": "refresh",
+      "unicode": "e657",
+      "unicode_decimal": 58967
+    },
+    {
+      "icon_id": "24855808",
+      "name": "cloud-upload",
+      "font_class": "cloud-upload",
+      "unicode": "e645",
+      "unicode_decimal": 58949
+    },
+    {
+      "icon_id": "24855809",
+      "name": "cloud-download-filled",
+      "font_class": "cloud-download-filled",
+      "unicode": "e646",
+      "unicode_decimal": 58950
+    },
+    {
+      "icon_id": "24855810",
+      "name": "cloud-download",
+      "font_class": "cloud-download",
+      "unicode": "e647",
+      "unicode_decimal": 58951
+    },
+    {
+      "icon_id": "24855811",
+      "name": "cloud-upload-filled",
+      "font_class": "cloud-upload-filled",
+      "unicode": "e648",
+      "unicode_decimal": 58952
+    },
+    {
+      "icon_id": "24855813",
+      "name": "redo",
+      "font_class": "redo",
+      "unicode": "e64a",
+      "unicode_decimal": 58954
+    },
+    {
+      "icon_id": "24855814",
+      "name": "images-filled",
+      "font_class": "images-filled",
+      "unicode": "e64b",
+      "unicode_decimal": 58955
+    },
+    {
+      "icon_id": "24855815",
+      "name": "undo-filled",
+      "font_class": "undo-filled",
+      "unicode": "e64c",
+      "unicode_decimal": 58956
+    },
+    {
+      "icon_id": "24855816",
+      "name": "more",
+      "font_class": "more",
+      "unicode": "e64d",
+      "unicode_decimal": 58957
+    },
+    {
+      "icon_id": "24855817",
+      "name": "more-filled",
+      "font_class": "more-filled",
+      "unicode": "e64e",
+      "unicode_decimal": 58958
+    },
+    {
+      "icon_id": "24855818",
+      "name": "undo",
+      "font_class": "undo",
+      "unicode": "e64f",
+      "unicode_decimal": 58959
+    },
+    {
+      "icon_id": "24855819",
+      "name": "images",
+      "font_class": "images",
+      "unicode": "e650",
+      "unicode_decimal": 58960
+    },
+    {
+      "icon_id": "24855821",
+      "name": "paperclip",
+      "font_class": "paperclip",
+      "unicode": "e652",
+      "unicode_decimal": 58962
+    },
+    {
+      "icon_id": "24855822",
+      "name": "settings",
+      "font_class": "settings",
+      "unicode": "e653",
+      "unicode_decimal": 58963
+    },
+    {
+      "icon_id": "24855823",
+      "name": "search",
+      "font_class": "search",
+      "unicode": "e654",
+      "unicode_decimal": 58964
+    },
+    {
+      "icon_id": "24855824",
+      "name": "redo-filled",
+      "font_class": "redo-filled",
+      "unicode": "e655",
+      "unicode_decimal": 58965
+    },
+    {
+      "icon_id": "24841702",
+      "name": "list",
+      "font_class": "list",
+      "unicode": "e644",
+      "unicode_decimal": 58948
+    },
+    {
+      "icon_id": "24841489",
+      "name": "mail-open-filled",
+      "font_class": "mail-open-filled",
+      "unicode": "e63a",
+      "unicode_decimal": 58938
+    },
+    {
+      "icon_id": "24841491",
+      "name": "hand-thumbsdown-filled",
+      "font_class": "hand-down-filled",
+      "unicode": "e63c",
+      "unicode_decimal": 58940
+    },
+    {
+      "icon_id": "24841492",
+      "name": "hand-thumbsdown",
+      "font_class": "hand-down",
+      "unicode": "e63d",
+      "unicode_decimal": 58941
+    },
+    {
+      "icon_id": "24841493",
+      "name": "hand-thumbsup-filled",
+      "font_class": "hand-up-filled",
+      "unicode": "e63e",
+      "unicode_decimal": 58942
+    },
+    {
+      "icon_id": "24841494",
+      "name": "hand-thumbsup",
+      "font_class": "hand-up",
+      "unicode": "e63f",
+      "unicode_decimal": 58943
+    },
+    {
+      "icon_id": "24841496",
+      "name": "heart-filled",
+      "font_class": "heart-filled",
+      "unicode": "e641",
+      "unicode_decimal": 58945
+    },
+    {
+      "icon_id": "24841498",
+      "name": "mail-open",
+      "font_class": "mail-open",
+      "unicode": "e643",
+      "unicode_decimal": 58947
+    },
+    {
+      "icon_id": "24841488",
+      "name": "heart",
+      "font_class": "heart",
+      "unicode": "e639",
+      "unicode_decimal": 58937
+    },
+    {
+      "icon_id": "24839963",
+      "name": "loop",
+      "font_class": "loop",
+      "unicode": "e633",
+      "unicode_decimal": 58931
+    },
+    {
+      "icon_id": "24839866",
+      "name": "pulldown",
+      "font_class": "pulldown",
+      "unicode": "e632",
+      "unicode_decimal": 58930
+    },
+    {
+      "icon_id": "24813798",
+      "name": "scan",
+      "font_class": "scan",
+      "unicode": "e62a",
+      "unicode_decimal": 58922
+    },
+    {
+      "icon_id": "24813786",
+      "name": "bars",
+      "font_class": "bars",
+      "unicode": "e627",
+      "unicode_decimal": 58919
+    },
+    {
+      "icon_id": "24813788",
+      "name": "cart-filled",
+      "font_class": "cart-filled",
+      "unicode": "e629",
+      "unicode_decimal": 58921
+    },
+    {
+      "icon_id": "24813790",
+      "name": "checkbox",
+      "font_class": "checkbox",
+      "unicode": "e62b",
+      "unicode_decimal": 58923
+    },
+    {
+      "icon_id": "24813791",
+      "name": "checkbox-filled",
+      "font_class": "checkbox-filled",
+      "unicode": "e62c",
+      "unicode_decimal": 58924
+    },
+    {
+      "icon_id": "24813794",
+      "name": "shop",
+      "font_class": "shop",
+      "unicode": "e62f",
+      "unicode_decimal": 58927
+    },
+    {
+      "icon_id": "24813795",
+      "name": "headphones",
+      "font_class": "headphones",
+      "unicode": "e630",
+      "unicode_decimal": 58928
+    },
+    {
+      "icon_id": "24813796",
+      "name": "cart",
+      "font_class": "cart",
+      "unicode": "e631",
+      "unicode_decimal": 58929
+    }
+  ]
+}

+ 96 - 0
uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@@ -0,0 +1,96 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
+	<!-- #endif -->
+	<!-- #ifndef APP-NVUE -->
+	<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
+	<!-- #endif -->
+</template>
+
+<script>
+	import icons from './icons.js';
+	const getVal = (val) => {
+		const reg = /^[0-9]*$/g
+		return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
+	} 
+	// #ifdef APP-NVUE
+	var domModule = weex.requireModule('dom');
+	import iconUrl from './uniicons.ttf'
+	domModule.addRule('fontFace', {
+		'fontFamily': "uniicons",
+		'src': "url('"+iconUrl+"')"
+	});
+	// #endif
+
+	/**
+	 * Icons 图标
+	 * @description 用于展示 icons 图标
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
+	 * @property {Number} size 图标大小
+	 * @property {String} type 图标图案,参考示例
+	 * @property {String} color 图标颜色
+	 * @property {String} customPrefix 自定义图标
+	 * @event {Function} click 点击 Icon 触发事件
+	 */
+	export default {
+		name: 'UniIcons',
+		emits:['click'],
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			color: {
+				type: String,
+				default: '#333333'
+			},
+			size: {
+				type: [Number, String],
+				default: 16
+			},
+			customPrefix:{
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				icons: icons.glyphs
+			}
+		},
+		computed:{
+			unicode(){
+				let code = this.icons.find(v=>v.font_class === this.type)
+				if(code){
+					return unescape(`%u${code.unicode}`)
+				}
+				return ''
+			},
+			iconSize(){
+				return getVal(this.size)
+			}
+		},
+		methods: {
+			_onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/* #ifndef APP-NVUE */
+	@import './uniicons.css';
+	@font-face {
+		font-family: uniicons;
+		src: url('./uniicons.ttf') format('truetype');
+	}
+
+	/* #endif */
+	.uni-icons {
+		font-family: uniicons;
+		text-decoration: none;
+		text-align: center;
+	}
+
+</style>

+ 663 - 0
uni_modules/uni-icons/components/uni-icons/uniicons.css

@@ -0,0 +1,663 @@
+.uniui-color:before {
+  content: "\e6cf";
+}
+
+.uniui-wallet:before {
+  content: "\e6b1";
+}
+
+.uniui-settings-filled:before {
+  content: "\e6ce";
+}
+
+.uniui-auth-filled:before {
+  content: "\e6cc";
+}
+
+.uniui-shop-filled:before {
+  content: "\e6cd";
+}
+
+.uniui-staff-filled:before {
+  content: "\e6cb";
+}
+
+.uniui-vip-filled:before {
+  content: "\e6c6";
+}
+
+.uniui-plus-filled:before {
+  content: "\e6c7";
+}
+
+.uniui-folder-add-filled:before {
+  content: "\e6c8";
+}
+
+.uniui-color-filled:before {
+  content: "\e6c9";
+}
+
+.uniui-tune-filled:before {
+  content: "\e6ca";
+}
+
+.uniui-calendar-filled:before {
+  content: "\e6c0";
+}
+
+.uniui-notification-filled:before {
+  content: "\e6c1";
+}
+
+.uniui-wallet-filled:before {
+  content: "\e6c2";
+}
+
+.uniui-medal-filled:before {
+  content: "\e6c3";
+}
+
+.uniui-gift-filled:before {
+  content: "\e6c4";
+}
+
+.uniui-fire-filled:before {
+  content: "\e6c5";
+}
+
+.uniui-refreshempty:before {
+  content: "\e6bf";
+}
+
+.uniui-location-filled:before {
+  content: "\e6af";
+}
+
+.uniui-person-filled:before {
+  content: "\e69d";
+}
+
+.uniui-personadd-filled:before {
+  content: "\e698";
+}
+
+.uniui-back:before {
+  content: "\e6b9";
+}
+
+.uniui-forward:before {
+  content: "\e6ba";
+}
+
+.uniui-arrow-right:before {
+  content: "\e6bb";
+}
+
+.uniui-arrowthinright:before {
+  content: "\e6bb";
+}
+
+.uniui-arrow-left:before {
+  content: "\e6bc";
+}
+
+.uniui-arrowthinleft:before {
+  content: "\e6bc";
+}
+
+.uniui-arrow-up:before {
+  content: "\e6bd";
+}
+
+.uniui-arrowthinup:before {
+  content: "\e6bd";
+}
+
+.uniui-arrow-down:before {
+  content: "\e6be";
+}
+
+.uniui-arrowthindown:before {
+  content: "\e6be";
+}
+
+.uniui-bottom:before {
+  content: "\e6b8";
+}
+
+.uniui-arrowdown:before {
+  content: "\e6b8";
+}
+
+.uniui-right:before {
+  content: "\e6b5";
+}
+
+.uniui-arrowright:before {
+  content: "\e6b5";
+}
+
+.uniui-top:before {
+  content: "\e6b6";
+}
+
+.uniui-arrowup:before {
+  content: "\e6b6";
+}
+
+.uniui-left:before {
+  content: "\e6b7";
+}
+
+.uniui-arrowleft:before {
+  content: "\e6b7";
+}
+
+.uniui-eye:before {
+  content: "\e651";
+}
+
+.uniui-eye-filled:before {
+  content: "\e66a";
+}
+
+.uniui-eye-slash:before {
+  content: "\e6b3";
+}
+
+.uniui-eye-slash-filled:before {
+  content: "\e6b4";
+}
+
+.uniui-info-filled:before {
+  content: "\e649";
+}
+
+.uniui-reload:before {
+  content: "\e6b2";
+}
+
+.uniui-micoff-filled:before {
+  content: "\e6b0";
+}
+
+.uniui-map-pin-ellipse:before {
+  content: "\e6ac";
+}
+
+.uniui-map-pin:before {
+  content: "\e6ad";
+}
+
+.uniui-location:before {
+  content: "\e6ae";
+}
+
+.uniui-starhalf:before {
+  content: "\e683";
+}
+
+.uniui-star:before {
+  content: "\e688";
+}
+
+.uniui-star-filled:before {
+  content: "\e68f";
+}
+
+.uniui-calendar:before {
+  content: "\e6a0";
+}
+
+.uniui-fire:before {
+  content: "\e6a1";
+}
+
+.uniui-medal:before {
+  content: "\e6a2";
+}
+
+.uniui-font:before {
+  content: "\e6a3";
+}
+
+.uniui-gift:before {
+  content: "\e6a4";
+}
+
+.uniui-link:before {
+  content: "\e6a5";
+}
+
+.uniui-notification:before {
+  content: "\e6a6";
+}
+
+.uniui-staff:before {
+  content: "\e6a7";
+}
+
+.uniui-vip:before {
+  content: "\e6a8";
+}
+
+.uniui-folder-add:before {
+  content: "\e6a9";
+}
+
+.uniui-tune:before {
+  content: "\e6aa";
+}
+
+.uniui-auth:before {
+  content: "\e6ab";
+}
+
+.uniui-person:before {
+  content: "\e699";
+}
+
+.uniui-email-filled:before {
+  content: "\e69a";
+}
+
+.uniui-phone-filled:before {
+  content: "\e69b";
+}
+
+.uniui-phone:before {
+  content: "\e69c";
+}
+
+.uniui-email:before {
+  content: "\e69e";
+}
+
+.uniui-personadd:before {
+  content: "\e69f";
+}
+
+.uniui-chatboxes-filled:before {
+  content: "\e692";
+}
+
+.uniui-contact:before {
+  content: "\e693";
+}
+
+.uniui-chatbubble-filled:before {
+  content: "\e694";
+}
+
+.uniui-contact-filled:before {
+  content: "\e695";
+}
+
+.uniui-chatboxes:before {
+  content: "\e696";
+}
+
+.uniui-chatbubble:before {
+  content: "\e697";
+}
+
+.uniui-upload-filled:before {
+  content: "\e68e";
+}
+
+.uniui-upload:before {
+  content: "\e690";
+}
+
+.uniui-weixin:before {
+  content: "\e691";
+}
+
+.uniui-compose:before {
+  content: "\e67f";
+}
+
+.uniui-qq:before {
+  content: "\e680";
+}
+
+.uniui-download-filled:before {
+  content: "\e681";
+}
+
+.uniui-pyq:before {
+  content: "\e682";
+}
+
+.uniui-sound:before {
+  content: "\e684";
+}
+
+.uniui-trash-filled:before {
+  content: "\e685";
+}
+
+.uniui-sound-filled:before {
+  content: "\e686";
+}
+
+.uniui-trash:before {
+  content: "\e687";
+}
+
+.uniui-videocam-filled:before {
+  content: "\e689";
+}
+
+.uniui-spinner-cycle:before {
+  content: "\e68a";
+}
+
+.uniui-weibo:before {
+  content: "\e68b";
+}
+
+.uniui-videocam:before {
+  content: "\e68c";
+}
+
+.uniui-download:before {
+  content: "\e68d";
+}
+
+.uniui-help:before {
+  content: "\e679";
+}
+
+.uniui-navigate-filled:before {
+  content: "\e67a";
+}
+
+.uniui-plusempty:before {
+  content: "\e67b";
+}
+
+.uniui-smallcircle:before {
+  content: "\e67c";
+}
+
+.uniui-minus-filled:before {
+  content: "\e67d";
+}
+
+.uniui-micoff:before {
+  content: "\e67e";
+}
+
+.uniui-closeempty:before {
+  content: "\e66c";
+}
+
+.uniui-clear:before {
+  content: "\e66d";
+}
+
+.uniui-navigate:before {
+  content: "\e66e";
+}
+
+.uniui-minus:before {
+  content: "\e66f";
+}
+
+.uniui-image:before {
+  content: "\e670";
+}
+
+.uniui-mic:before {
+  content: "\e671";
+}
+
+.uniui-paperplane:before {
+  content: "\e672";
+}
+
+.uniui-close:before {
+  content: "\e673";
+}
+
+.uniui-help-filled:before {
+  content: "\e674";
+}
+
+.uniui-paperplane-filled:before {
+  content: "\e675";
+}
+
+.uniui-plus:before {
+  content: "\e676";
+}
+
+.uniui-mic-filled:before {
+  content: "\e677";
+}
+
+.uniui-image-filled:before {
+  content: "\e678";
+}
+
+.uniui-locked-filled:before {
+  content: "\e668";
+}
+
+.uniui-info:before {
+  content: "\e669";
+}
+
+.uniui-locked:before {
+  content: "\e66b";
+}
+
+.uniui-camera-filled:before {
+  content: "\e658";
+}
+
+.uniui-chat-filled:before {
+  content: "\e659";
+}
+
+.uniui-camera:before {
+  content: "\e65a";
+}
+
+.uniui-circle:before {
+  content: "\e65b";
+}
+
+.uniui-checkmarkempty:before {
+  content: "\e65c";
+}
+
+.uniui-chat:before {
+  content: "\e65d";
+}
+
+.uniui-circle-filled:before {
+  content: "\e65e";
+}
+
+.uniui-flag:before {
+  content: "\e65f";
+}
+
+.uniui-flag-filled:before {
+  content: "\e660";
+}
+
+.uniui-gear-filled:before {
+  content: "\e661";
+}
+
+.uniui-home:before {
+  content: "\e662";
+}
+
+.uniui-home-filled:before {
+  content: "\e663";
+}
+
+.uniui-gear:before {
+  content: "\e664";
+}
+
+.uniui-smallcircle-filled:before {
+  content: "\e665";
+}
+
+.uniui-map-filled:before {
+  content: "\e666";
+}
+
+.uniui-map:before {
+  content: "\e667";
+}
+
+.uniui-refresh-filled:before {
+  content: "\e656";
+}
+
+.uniui-refresh:before {
+  content: "\e657";
+}
+
+.uniui-cloud-upload:before {
+  content: "\e645";
+}
+
+.uniui-cloud-download-filled:before {
+  content: "\e646";
+}
+
+.uniui-cloud-download:before {
+  content: "\e647";
+}
+
+.uniui-cloud-upload-filled:before {
+  content: "\e648";
+}
+
+.uniui-redo:before {
+  content: "\e64a";
+}
+
+.uniui-images-filled:before {
+  content: "\e64b";
+}
+
+.uniui-undo-filled:before {
+  content: "\e64c";
+}
+
+.uniui-more:before {
+  content: "\e64d";
+}
+
+.uniui-more-filled:before {
+  content: "\e64e";
+}
+
+.uniui-undo:before {
+  content: "\e64f";
+}
+
+.uniui-images:before {
+  content: "\e650";
+}
+
+.uniui-paperclip:before {
+  content: "\e652";
+}
+
+.uniui-settings:before {
+  content: "\e653";
+}
+
+.uniui-search:before {
+  content: "\e654";
+}
+
+.uniui-redo-filled:before {
+  content: "\e655";
+}
+
+.uniui-list:before {
+  content: "\e644";
+}
+
+.uniui-mail-open-filled:before {
+  content: "\e63a";
+}
+
+.uniui-hand-down-filled:before {
+  content: "\e63c";
+}
+
+.uniui-hand-down:before {
+  content: "\e63d";
+}
+
+.uniui-hand-up-filled:before {
+  content: "\e63e";
+}
+
+.uniui-hand-up:before {
+  content: "\e63f";
+}
+
+.uniui-heart-filled:before {
+  content: "\e641";
+}
+
+.uniui-mail-open:before {
+  content: "\e643";
+}
+
+.uniui-heart:before {
+  content: "\e639";
+}
+
+.uniui-loop:before {
+  content: "\e633";
+}
+
+.uniui-pulldown:before {
+  content: "\e632";
+}
+
+.uniui-scan:before {
+  content: "\e62a";
+}
+
+.uniui-bars:before {
+  content: "\e627";
+}
+
+.uniui-cart-filled:before {
+  content: "\e629";
+}
+
+.uniui-checkbox:before {
+  content: "\e62b";
+}
+
+.uniui-checkbox-filled:before {
+  content: "\e62c";
+}
+
+.uniui-shop:before {
+  content: "\e62f";
+}
+
+.uniui-headphones:before {
+  content: "\e630";
+}
+
+.uniui-cart:before {
+  content: "\e631";
+}

二进制
uni_modules/uni-icons/components/uni-icons/uniicons.ttf


+ 86 - 0
uni_modules/uni-icons/package.json

@@ -0,0 +1,86 @@
+{
+  "id": "uni-icons",
+  "displayName": "uni-icons 图标",
+  "version": "1.3.5",
+  "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "icon",
+    "图标"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.2.14"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 8 - 0
uni_modules/uni-icons/readme.md

@@ -0,0 +1,8 @@
+## Icons 图标
+> **组件名:uni-icons**
+> 代码块: `uIcons`
+
+用于展示 icons 图标 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 19 - 0
uni_modules/uni-load-more/changelog.md

@@ -0,0 +1,19 @@
+## 1.3.3(2022-01-20)
+- 新增 showText属性 ,是否显示文本
+## 1.3.2(2022-01-19)
+- 修复 nvue 平台下不显示文本的bug
+## 1.3.1(2022-01-19)
+- 修复 微信小程序平台样式选择器报警告的问题
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
+## 1.2.1(2021-08-24)
+- 新增 支持国际化
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.8(2021-05-12)
+- 新增 组件示例地址
+## 1.1.7(2021-03-30)
+- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
+## 1.1.6(2021-02-05)
+- 调整为uni_modules目录规范

+ 5 - 0
uni_modules/uni-load-more/components/uni-load-more/i18n/en.json

@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "Pull up to show more",
+	"uni-load-more.contentrefresh": "loading...",
+	"uni-load-more.contentnomore": "No more data"
+}

+ 8 - 0
uni_modules/uni-load-more/components/uni-load-more/i18n/index.js

@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}

+ 5 - 0
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json

@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "上拉显示更多",
+	"uni-load-more.contentrefresh": "正在加载...",
+	"uni-load-more.contentnomore": "没有更多数据了"
+}

+ 5 - 0
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json

@@ -0,0 +1,5 @@
+{
+	"uni-load-more.contentdown": "上拉顯示更多",
+	"uni-load-more.contentrefresh": "正在加載...",
+	"uni-load-more.contentnomore": "沒有更多數據了"
+}

文件差异内容过多而无法显示
+ 112 - 0
uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue


+ 86 - 0
uni_modules/uni-load-more/package.json

@@ -0,0 +1,86 @@
+{
+  "id": "uni-load-more",
+  "displayName": "uni-load-more 加载更多",
+  "version": "1.3.3",
+  "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "加载更多",
+    "load-more"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 14 - 0
uni_modules/uni-load-more/readme.md

@@ -0,0 +1,14 @@
+
+
+### LoadMore 加载更多
+> **组件名:uni-load-more**
+> 代码块: `uLoadMore`
+
+
+用于列表中,做滚动加载使用,展示 loading 的各种状态。
+
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+

+ 16 - 0
uni_modules/uni-notice-bar/changelog.md

@@ -0,0 +1,16 @@
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-notice-bar](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
+## 1.1.1(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.9(2021-05-12)
+- 新增 组件示例地址
+## 1.0.8(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.7(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.6(2021-02-05)
+- 调整为uni_modules目录规范

+ 395 - 0
uni_modules/uni-notice-bar/components/uni-notice-bar/uni-notice-bar.vue

@@ -0,0 +1,395 @@
+<template>
+	<view v-if="show" class="uni-noticebar" :style="{ backgroundColor: backgroundColor }" @click="onClick">
+		<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound"
+			:color="color" size="22" />
+		<view ref="textBox" class="uni-noticebar__content-wrapper"
+			:class="{'uni-noticebar__content-wrapper--scrollable':scrollable, 'uni-noticebar__content-wrapper--single':!scrollable && (single || moreText)}">
+			<view :id="elIdBox" class="uni-noticebar__content"
+				:class="{'uni-noticebar__content--scrollable':scrollable, 'uni-noticebar__content--single':!scrollable && (single || moreText)}">
+				<text :id="elId" ref="animationEle" class="uni-noticebar__content-text"
+					:class="{'uni-noticebar__content-text--scrollable':scrollable,'uni-noticebar__content-text--single':!scrollable && (single || showGetMore)}"
+					:style="{color:color, width:wrapWidth+'px', 'animationDuration': animationDuration, '-webkit-animationDuration': animationDuration ,animationPlayState: webviewHide?'paused':animationPlayState,'-webkit-animationPlayState':webviewHide?'paused':animationPlayState, animationDelay: animationDelay, '-webkit-animationDelay':animationDelay}">{{text}}</text>
+			</view>
+		</view>
+		<view v-if="showGetMore === true || showGetMore === 'true'" class="uni-noticebar__more uni-cursor-point"
+			@click="clickMore">
+			<text v-if="moreText.length > 0" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text>
+			<uni-icons v-else type="right" :color="moreColor" size="16" />
+		</view>
+		<view class="uni-noticebar-close uni-cursor-point" v-if="(showClose === true || showClose === 'true') && (showGetMore === false || showGetMore === 'false')">
+			<uni-icons
+				type="closeempty" :color="color" size="16" @click="close" />
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = weex.requireModule('dom');
+	const animation = weex.requireModule('animation');
+	// #endif
+
+	/**
+	 * NoticeBar 自定义导航栏
+	 * @description 通告栏组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=30
+	 * @property {Number} speed 文字滚动的速度,默认100px/秒
+	 * @property {String} text 显示文字
+	 * @property {String} backgroundColor 背景颜色
+	 * @property {String} color 文字颜色
+	 * @property {String} moreColor 查看更多文字的颜色
+	 * @property {String} moreText 设置“查看更多”的文本
+	 * @property {Boolean} single = [true|false] 是否单行
+	 * @property {Boolean} scrollable = [true|false] 是否滚动,为true时,NoticeBar为单行
+	 * @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
+	 * @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
+	 * @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标,为true时,NoticeBar为单行
+	 * @event {Function} click 点击 NoticeBar 触发事件
+	 * @event {Function} close 关闭 NoticeBar 触发事件
+	 * @event {Function} getmore 点击”查看更多“时触发事件
+	 */
+
+	export default {
+		name: 'UniNoticeBar',
+		emits: ['click', 'getmore', 'close'],
+		props: {
+			text: {
+				type: String,
+				default: ''
+			},
+			moreText: {
+				type: String,
+				default: ''
+			},
+			backgroundColor: {
+				type: String,
+				default: '#FFF9EA'
+			},
+			speed: {
+				// 默认1s滚动100px
+				type: Number,
+				default: 100
+			},
+			color: {
+				type: String,
+				default: '#FF9A43'
+			},
+			moreColor: {
+				type: String,
+				default: '#FF9A43'
+			},
+			single: {
+				// 是否单行
+				type: [Boolean, String],
+				default: false
+			},
+			scrollable: {
+				// 是否滚动,添加后控制单行效果取消
+				type: [Boolean, String],
+				default: false
+			},
+			showIcon: {
+				// 是否显示左侧icon
+				type: [Boolean, String],
+				default: false
+			},
+			showGetMore: {
+				// 是否显示右侧查看更多
+				type: [Boolean, String],
+				default: false
+			},
+			showClose: {
+				// 是否显示左侧关闭按钮
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		data() {
+			const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			return {
+				textWidth: 0,
+				boxWidth: 0,
+				wrapWidth: '',
+				webviewHide: false,
+				// #ifdef APP-NVUE
+				stopAnimation: false,
+				// #endif
+				elId: elId,
+				elIdBox: elIdBox,
+				show: true,
+				animationDuration: 'none',
+				animationPlayState: 'paused',
+				animationDelay: '0s'
+			}
+		},
+		mounted() {
+			// #ifdef APP-PLUS
+			var pages = getCurrentPages();
+			var page = pages[pages.length - 1];
+			var currentWebview = page.$getAppWebview();
+			currentWebview.addEventListener('hide', () => {
+				this.webviewHide = true
+			})
+			currentWebview.addEventListener('show', () => {
+				this.webviewHide = false
+			})
+			// #endif
+			this.$nextTick(() => {
+				this.initSize()
+			})
+		},
+		// #ifdef APP-NVUE
+		beforeDestroy() {
+			this.stopAnimation = true
+		},
+		// #endif
+		methods: {
+			initSize() {
+				if (this.scrollable) {
+					// #ifndef APP-NVUE
+					let query = [],
+						boxWidth = 0,
+						textWidth = 0;
+					let textQuery = new Promise((resolve, reject) => {
+						uni.createSelectorQuery()
+							// #ifndef MP-ALIPAY
+							.in(this)
+							// #endif
+							.select(`#${this.elId}`)
+							.boundingClientRect()
+							.exec(ret => {
+								this.textWidth = ret[0].width
+								resolve()
+							})
+					})
+					let boxQuery = new Promise((resolve, reject) => {
+						uni.createSelectorQuery()
+							// #ifndef MP-ALIPAY
+							.in(this)
+							// #endif
+							.select(`#${this.elIdBox}`)
+							.boundingClientRect()
+							.exec(ret => {
+								this.boxWidth = ret[0].width
+								resolve()
+							})
+					})
+					query.push(textQuery)
+					query.push(boxQuery)
+					Promise.all(query).then(() => {
+						this.animationDuration = `${this.textWidth / this.speed}s`
+						this.animationDelay = `-${this.boxWidth / this.speed}s`
+						setTimeout(() => {
+							this.animationPlayState = 'running'
+						}, 1000)
+					})
+					// #endif
+					// #ifdef APP-NVUE
+					dom.getComponentRect(this.$refs['animationEle'], (res) => {
+						let winWidth = uni.getSystemInfoSync().windowWidth
+						this.textWidth = res.size.width
+						animation.transition(this.$refs['animationEle'], {
+							styles: {
+								transform: `translateX(-${winWidth}px)`
+							},
+							duration: 0,
+							timingFunction: 'linear',
+							delay: 0
+						}, () => {
+							if (!this.stopAnimation) {
+								animation.transition(this.$refs['animationEle'], {
+									styles: {
+										transform: `translateX(-${this.textWidth}px)`
+									},
+									timingFunction: 'linear',
+									duration: (this.textWidth - winWidth) / this.speed * 1000,
+									delay: 1000
+								}, () => {
+									if (!this.stopAnimation) {
+										this.loopAnimation()
+									}
+								});
+							}
+						});
+					})
+					// #endif
+				}
+				// #ifdef APP-NVUE
+				if (!this.scrollable && (this.single || this.moreText)) {
+					dom.getComponentRect(this.$refs['textBox'], (res) => {
+						this.wrapWidth = res.size.width
+					})
+				}
+				// #endif
+			},
+			loopAnimation() {
+				// #ifdef APP-NVUE
+				animation.transition(this.$refs['animationEle'], {
+					styles: {
+						transform: `translateX(0px)`
+					},
+					duration: 0
+				}, () => {
+					if (!this.stopAnimation) {
+						animation.transition(this.$refs['animationEle'], {
+							styles: {
+								transform: `translateX(-${this.textWidth}px)`
+							},
+							duration: this.textWidth / this.speed * 1000,
+							timingFunction: 'linear',
+							delay: 0
+						}, () => {
+							if (!this.stopAnimation) {
+								this.loopAnimation()
+							}
+						});
+					}
+				});
+				// #endif
+			},
+			clickMore() {
+				this.$emit('getmore')
+			},
+			close() {
+				this.show = false;
+				this.$emit('close')
+			},
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-noticebar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		width: 100%;
+		box-sizing: border-box;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		padding: 10px 12px;
+		margin-bottom: 10px;
+	}
+
+	.uni-cursor-point {
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-noticebar-close {
+		margin-left: 8px;
+		margin-right: 5px;
+	}
+
+	.uni-noticebar-icon {
+		margin-right: 5px;
+	}
+
+	.uni-noticebar__content-wrapper {
+		flex: 1;
+		flex-direction: column;
+		overflow: hidden;
+	}
+
+	.uni-noticebar__content-wrapper--single {
+		/* #ifndef APP-NVUE */
+		line-height: 18px;
+		/* #endif */
+	}
+
+	.uni-noticebar__content-wrapper--single,
+	.uni-noticebar__content-wrapper--scrollable {
+		flex-direction: row;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-noticebar__content-wrapper--scrollable {
+		position: relative;
+		height: 18px;
+	}
+
+	/* #endif */
+
+	.uni-noticebar__content--scrollable {
+		/* #ifdef APP-NVUE */
+		flex: 0;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		flex: 1;
+		display: block;
+		overflow: hidden;
+		/* #endif */
+	}
+
+	.uni-noticebar__content--single {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		flex: none;
+		width: 100%;
+		justify-content: center;
+		/* #endif */
+	}
+
+	.uni-noticebar__content-text {
+		font-size: 14px;
+		line-height: 18px;
+		/* #ifndef APP-NVUE */
+		word-break: break-all;
+		/* #endif */
+	}
+
+	.uni-noticebar__content-text--single {
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		display: block;
+		width: 100%;
+		white-space: nowrap;
+		/* #endif */
+		overflow: hidden;
+		text-overflow: ellipsis;
+	}
+
+	.uni-noticebar__content-text--scrollable {
+		/* #ifdef APP-NVUE */
+		lines: 1;
+		padding-left: 750rpx;
+		/* #endif */
+		/* #ifndef APP-NVUE */
+		position: absolute;
+		display: block;
+		height: 18px;
+		line-height: 18px;
+		white-space: nowrap;
+		padding-left: 100%;
+		animation: notice 10s 0s linear infinite both;
+		animation-play-state: paused;
+		/* #endif */
+	}
+
+	.uni-noticebar__more {
+		/* #ifndef APP-NVUE */
+		display: inline-flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: nowrap;
+		align-items: center;
+		padding-left: 5px;
+	}
+
+	.uni-noticebar__more-text {
+		font-size: 14px;
+	}
+
+	@keyframes notice {
+		100% {
+			transform: translate3d(-100%, 0, 0);
+		}
+	}
+</style>

+ 90 - 0
uni_modules/uni-notice-bar/package.json

@@ -0,0 +1,90 @@
+{
+  "id": "uni-notice-bar",
+  "displayName": "uni-notice-bar 通告栏",
+  "version": "1.2.0",
+  "description": "NoticeBar 通告栏组件,常用于展示公告信息,可设为滚动公告",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "通告栏",
+    "公告",
+    "跑马灯"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 13 - 0
uni_modules/uni-notice-bar/readme.md

@@ -0,0 +1,13 @@
+
+
+## NoticeBar 通告栏
+> **组件名:uni-notice-bar**
+> 代码块: `uNoticeBar`
+
+
+通告栏组件 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-notice-bar)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+

+ 25 - 0
uni_modules/uni-number-box/changelog.md

@@ -0,0 +1,25 @@
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+## 1.1.2(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-04-20)
+- 修复 uni-number-box 浮点数运算不精确的 bug
+- 修复 uni-number-box change 事件触发不正确的 bug
+- 新增 uni-number-box v-model 双向绑定
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+
+## 1.0.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 v-model
+- 新增 支持 focus、blur 事件
+- 新增 支持 PC 端

+ 221 - 0
uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue

@@ -0,0 +1,221 @@
+<template>
+	<view class="uni-numbox">
+		<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }" :style="{color}">-</text>
+		</view>
+		<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value" type="number"
+			v-model="inputValue" :style="{background, color}" />
+		<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }" :style="{color}">+</text>
+		</view>
+	</view>
+</template>
+<script>
+	/**
+	 * NumberBox 数字输入框
+	 * @description 带加减按钮的数字输入框
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=31
+	 * @property {Number} value 输入框当前值
+	 * @property {Number} min 最小值
+	 * @property {Number} max 最大值
+	 * @property {Number} step 每次点击改变的间隔大小
+	 * @property {String} background 背景色
+	 * @property {String} color 字体颜色(前景色)
+	 * @property {Boolean} disabled = [true|false] 是否为禁用状态
+	 * @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
+	 * @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
+	 * @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象
+	 */
+
+	export default {
+		name: "UniNumberBox",
+		emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
+		props: {
+			value: {
+				type: [Number, String],
+				default: 1
+			},
+			modelValue: {
+				type: [Number, String],
+				default: 1
+			},
+			min: {
+				type: Number,
+				default: 0
+			},
+			max: {
+				type: Number,
+				default: 100
+			},
+			step: {
+				type: Number,
+				default: 1
+			},
+			background: {
+				type: String,
+				default: '#f5f5f5'
+			},
+			color: {
+				type: String,
+				default: '#333'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				inputValue: 0
+			};
+		},
+		watch: {
+			value(val) {
+				this.inputValue = +val;
+			},
+			modelValue(val) {
+				this.inputValue = +val;
+			}
+		},
+		created() {
+			if (this.value === 1) {
+				this.inputValue = +this.modelValue;
+			}
+			if (this.modelValue === 1) {
+				this.inputValue = +this.value;
+			}
+		},
+		methods: {
+			_calcValue(type) {
+				if (this.disabled) {
+					return;
+				}
+				const scale = this._getDecimalScale();
+				let value = this.inputValue * scale;
+				let step = this.step * scale;
+				if (type === "minus") {
+					value -= step;
+					if (value < (this.min * scale)) {
+						return;
+					}
+					if (value > (this.max * scale)) {
+						value = this.max * scale
+					}
+				}
+
+				if (type === "plus") {
+					value += step;
+					if (value > (this.max * scale)) {
+						return;
+					}
+					if (value < (this.min * scale)) {
+						value = this.min * scale
+					}
+				}
+
+				this.inputValue = (value / scale).toFixed(String(scale).length - 1);
+				this.$emit("change", +this.inputValue);
+				// TODO vue2 兼容
+				this.$emit("input", +this.inputValue);
+				// TODO vue3 兼容
+				this.$emit("update:modelValue", +this.inputValue);
+			},
+			_getDecimalScale() {
+
+				let scale = 1;
+				// 浮点型
+				if (~~this.step !== this.step) {
+					scale = Math.pow(10, String(this.step).split(".")[1].length);
+				}
+				return scale;
+			},
+			_onBlur(event) {
+				this.$emit('blur', event)
+				let value = event.detail.value;
+				if (!value) {
+					// this.inputValue = 0;
+					return;
+				}
+				value = +value;
+				if (value > this.max) {
+					value = this.max;
+				} else if (value < this.min) {
+					value = this.min;
+				}
+				const scale = this._getDecimalScale();
+				this.inputValue = value.toFixed(String(scale).length - 1);
+				this.$emit("change", +this.inputValue);
+				this.$emit("input", +this.inputValue);
+			},
+			_onFocus(event) {
+				this.$emit('focus', event)
+			}
+		}
+	};
+</script>
+<style lang="scss" scoped>
+	$box-height: 26px;
+	$bg: #f5f5f5;
+	$br: 2px;
+	$color: #333;
+
+	.uni-numbox {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-numbox-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		padding: 0 8px;
+		min-width:50rpx ;
+		background-color: $bg;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-numbox__value {
+		margin: 0 2px;
+		background-color: $bg;
+		width: 40px;
+		height: $box-height;
+		text-align: center;
+		font-size: 14px;
+		border-left-width: 0;
+		border-right-width: 0;
+		color: $color;
+	}
+
+	.uni-numbox__minus {
+		border-top-left-radius: $br;
+		border-bottom-left-radius: $br;
+	}
+
+	.uni-numbox__plus {
+		border-top-right-radius: $br;
+		border-bottom-right-radius: $br;
+	}
+
+	.uni-numbox--text {
+		// fix nvue
+		line-height: 20px;
+
+		font-size: 20px;
+		font-weight: 300;
+		color: $color;
+	}
+
+	.uni-numbox .uni-numbox--disabled {
+		color: #c0c0c0 !important;
+		/* #ifdef H5 */
+		cursor: not-allowed;
+		/* #endif */
+	}
+</style>

+ 85 - 0
uni_modules/uni-number-box/package.json

@@ -0,0 +1,85 @@
+{
+  "id": "uni-number-box",
+  "displayName": "uni-number-box 数字输入框",
+  "version": "1.2.1",
+  "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "数字输入框"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 13 - 0
uni_modules/uni-number-box/readme.md

@@ -0,0 +1,13 @@
+
+
+## NumberBox 数字输入框
+> **组件名:uni-number-box**
+> 代码块: `uNumberBox`
+
+
+带加减按钮的数字输入框。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+

+ 56 - 0
uni_modules/uni-popup/changelog.md

@@ -0,0 +1,56 @@
+## 1.7.7(2022-03-17)
+- 修复 快速调用open出现问题的Bug
+## 1.7.6(2022-02-14)
+- 修复 safeArea 属性不能设置为false的bug
+## 1.7.5(2022-01-19)
+- 修复 isMaskClick 失效的bug
+## 1.7.4(2022-01-19)
+- 新增 cancelText \ confirmText 属性 ,可自定义文本
+- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
+- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
+## 1.7.3(2022-01-13)
+- 修复 设置 safeArea 属性不生效的bug
+## 1.7.2(2021-11-26)
+- 优化 组件示例
+## 1.7.1(2021-11-26)
+- 修复 vuedoc 文字错误
+## 1.7.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
+## 1.6.2(2021-08-24)
+- 新增 支持国际化
+## 1.6.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.6.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.5.0(2021-06-23)
+- 新增 mask-click 遮罩层点击事件
+## 1.4.5(2021-06-22)
+- 修复 nvue 平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+## 1.4.4(2021-06-18)
+- 修复 H5平台中间弹出后,点击内容,再点击遮罩无法关闭的Bug
+## 1.4.3(2021-06-08)
+- 修复 错误的 watch 字段
+- 修复 safeArea 属性不生效的问题
+- 修复 点击内容,再点击遮罩无法关闭的Bug
+## 1.4.2(2021-05-12)
+- 新增 组件示例地址
+## 1.4.1(2021-04-29)
+- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
+## 1.4.0 (2021-04-29)
+- 新增 type 属性的 left\right 值,支持左右弹出
+- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
+- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
+- 新增 safeArea 属性,是否适配底部安全区
+- 修复 App\h5\微信小程序底部安全区占位不对的Bug
+- 修复 App 端弹出等待的Bug
+- 优化 提升低配设备性能,优化动画卡顿问题
+- 优化 更简单的组件自定义方式
+## 1.2.9(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.2.8(2021-02-05)
+- 调整为uni_modules目录规范
+## 1.2.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 PC 端
+- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端

+ 45 - 0
uni_modules/uni-popup/components/uni-popup-dialog/keypress.js

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

+ 271 - 0
uni_modules/uni-popup/components/uni-popup-dialog/uni-popup-dialog.vue

@@ -0,0 +1,271 @@
+<template>
+	<view class="uni-popup-dialog">
+		<view class="uni-dialog-title">
+			<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
+		</view>
+		<view v-if="mode === 'base'" class="uni-dialog-content">
+			<slot>
+				<text class="uni-dialog-content-text">{{content}}</text>
+			</slot>
+		</view>
+		<view v-else class="uni-dialog-content">
+			<slot>
+				<input class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholderText" :focus="focus" >
+			</slot>
+		</view>
+		<view class="uni-dialog-button-group">
+			<view class="uni-dialog-button" @click="closeDialog">
+				<text class="uni-dialog-button-text">{{closeText}}</text>
+			</view>
+			<view class="uni-dialog-button uni-border-left" @click="onOk">
+				<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
+			</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	import popup from '../uni-popup/popup.js'
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from '../uni-popup/i18n/index.js'
+	const {	t } = initVueI18n(messages)
+	/**
+	 * PopUp 弹出层-对话框样式
+	 * @description 弹出层-对话框样式
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} value input 模式下的默认值
+	 * @property {String} placeholder input 模式下输入提示
+	 * @property {String} type = [success|warning|info|error] 主题样式
+	 *  @value success 成功
+	 * 	@value warning 提示
+	 * 	@value info 消息
+	 * 	@value error 错误
+	 * @property {String} mode = [base|input] 模式、
+	 * 	@value base 基础对话框
+	 * 	@value input 可输入对话框
+	 * @property {String} content 对话框内容
+	 * @property {Boolean} beforeClose 是否拦截取消事件
+	 * @event {Function} confirm 点击确认按钮触发
+	 * @event {Function} close 点击取消按钮触发
+	 */
+
+	export default {
+		name: "uniPopupDialog",
+		mixins: [popup],
+		emits:['confirm','close'],
+		props: {
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			placeholder: {
+				type: [String, Number],
+				default: ''
+			},
+			type: {
+				type: String,
+				default: 'error'
+			},
+			mode: {
+				type: String,
+				default: 'base'
+			},
+			title: {
+				type: String,
+				default: ''
+			},
+			content: {
+				type: String,
+				default: ''
+			},
+			beforeClose: {
+				type: Boolean,
+				default: false
+			},
+			cancelText:{
+				type: String,
+				default: ''
+			},
+			confirmText:{
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				dialogType: 'error',
+				focus: false,
+				val: ""
+			}
+		},
+		computed: {
+			okText() {
+				return this.confirmText || t("uni-popup.ok")
+			},
+			closeText() {
+				return this.cancelText || t("uni-popup.cancel")
+			},
+			placeholderText() {
+				return this.placeholder || t("uni-popup.placeholder")
+			},
+			titleText() {
+				return this.title || t("uni-popup.title")
+			}
+		},
+		watch: {
+			type(val) {
+				this.dialogType = val
+			},
+			mode(val) {
+				if (val === 'input') {
+					this.dialogType = 'info'
+				}
+			},
+			value(val) {
+				this.val = val
+			}
+		},
+		created() {
+			// 对话框遮罩不可点击
+			this.popup.disableMask()
+			// this.popup.closeMask()
+			if (this.mode === 'input') {
+				this.dialogType = 'info'
+				this.val = this.value
+			} else {
+				this.dialogType = this.type
+			}
+		},
+		mounted() {
+			this.focus = true
+		},
+		methods: {
+			/**
+			 * 点击确认按钮
+			 */
+			onOk() {
+				if (this.mode === 'input'){
+					this.$emit('confirm', this.val)
+				}else{
+					this.$emit('confirm')
+				}
+				if(this.beforeClose) return
+				this.popup.close()
+			},
+			/**
+			 * 点击取消按钮
+			 */
+			closeDialog() {
+				this.$emit('close')
+				if(this.beforeClose) return
+				this.popup.close()
+			},
+			close(){
+				this.popup.close()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" >
+	.uni-popup-dialog {
+		width: 300px;
+		border-radius: 11px;
+		background-color: #fff;
+	}
+
+	.uni-dialog-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		padding-top: 25px;
+	}
+
+	.uni-dialog-title-text {
+		font-size: 16px;
+		font-weight: 500;
+	}
+
+	.uni-dialog-content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		padding: 20px;
+	}
+
+	.uni-dialog-content-text {
+		font-size: 14px;
+		color: #6C6C6C;
+	}
+
+	.uni-dialog-button-group {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		border-top-color: #f5f5f5;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-dialog-button {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+
+		flex: 1;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 45px;
+	}
+
+	.uni-border-left {
+		border-left-color: #f0f0f0;
+		border-left-style: solid;
+		border-left-width: 1px;
+	}
+
+	.uni-dialog-button-text {
+		font-size: 16px;
+		color: #333;
+	}
+
+	.uni-button-color {
+		color: #007aff;
+	}
+
+	.uni-dialog-input {
+		flex: 1;
+		font-size: 14px;
+		border: 1px #eee solid;
+		height: 40px;
+		padding: 0 10px;
+		border-radius: 5px;
+		color: #555;
+	}
+
+	.uni-popup__success {
+		color: #4cd964;
+	}
+
+	.uni-popup__warn {
+		color: #f0ad4e;
+	}
+
+	.uni-popup__error {
+		color: #dd524d;
+	}
+
+	.uni-popup__info {
+		color: #909399;
+	}
+</style>

+ 143 - 0
uni_modules/uni-popup/components/uni-popup-message/uni-popup-message.vue

@@ -0,0 +1,143 @@
+<template>
+	<view class="uni-popup-message">
+		<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
+			<slot>
+				<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
+			</slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	import popup from '../uni-popup/popup.js'
+	/**
+	 * PopUp 弹出层-消息提示
+	 * @description 弹出层-消息提示
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [success|warning|info|error] 主题样式
+	 *  @value success 成功
+	 * 	@value warning 提示
+	 * 	@value info 消息
+	 * 	@value error 错误
+	 * @property {String} message 消息提示文字
+	 * @property {String} duration 显示时间,设置为 0 则不会自动关闭
+	 */
+
+	export default {
+		name: 'uniPopupMessage',
+		mixins:[popup],
+		props: {
+			/**
+			 * 主题 success/warning/info/error	  默认 success
+			 */
+			type: {
+				type: String,
+				default: 'success'
+			},
+			/**
+			 * 消息文字
+			 */
+			message: {
+				type: String,
+				default: ''
+			},
+			/**
+			 * 显示时间,设置为 0 则不会自动关闭
+			 */
+			duration: {
+				type: Number,
+				default: 3000
+			},
+			maskShow:{
+				type:Boolean,
+				default:false
+			}
+		},
+		data() {
+			return {}
+		},
+		created() {
+			this.popup.maskShow = this.maskShow
+			this.popup.messageChild = this
+		},
+		methods: {
+			timerClose(){
+				if(this.duration === 0) return
+				clearTimeout(this.timer) 
+				this.timer = setTimeout(()=>{
+					this.popup.close()
+				},this.duration)
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	.uni-popup-message {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+	}
+
+	.uni-popup-message__box {
+		background-color: #e1f3d8;
+		padding: 10px 15px;
+		border-color: #eee;
+		border-style: solid;
+		border-width: 1px;
+		flex: 1;
+	}
+
+	@media screen and (min-width: 500px) {
+		.fixforpc-width {
+			margin-top: 20px;
+			border-radius: 4px;
+			flex: none;
+			min-width: 380px;
+			/* #ifndef APP-NVUE */
+			max-width: 50%;
+			/* #endif */
+			/* #ifdef APP-NVUE */
+			max-width: 500px;
+			/* #endif */
+		}
+	}
+
+	.uni-popup-message-text {
+		font-size: 14px;
+		padding: 0;
+	}
+
+	.uni-popup__success {
+		background-color: #e1f3d8;
+	}
+
+	.uni-popup__success-text {
+		color: #67C23A;
+	}
+
+	.uni-popup__warn {
+		background-color: #faecd8;
+	}
+
+	.uni-popup__warn-text {
+		color: #E6A23C;
+	}
+
+	.uni-popup__error {
+		background-color: #fde2e2;
+	}
+
+	.uni-popup__error-text {
+		color: #F56C6C;
+	}
+
+	.uni-popup__info {
+		background-color: #F2F6FC;
+	}
+
+	.uni-popup__info-text {
+		color: #909399;
+	}
+</style>

+ 187 - 0
uni_modules/uni-popup/components/uni-popup-share/uni-popup-share.vue

@@ -0,0 +1,187 @@
+<template>
+	<view class="uni-popup-share">
+		<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
+		<view class="uni-share-content">
+			<view class="uni-share-content-box">
+				<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
+					<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
+					<text class="uni-share-text">{{item.text}}</text>
+				</view>
+
+			</view>
+		</view>
+		<view class="uni-share-button-box">
+			<button class="uni-share-button" @click="close">{{cancelText}}</button>
+		</view>
+	</view>
+</template>
+
+<script>
+	import popup from '../uni-popup/popup.js'
+	import {
+	initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from '../uni-popup/i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+	export default {
+		name: 'UniPopupShare',
+		mixins:[popup],
+		emits:['select'],
+		props: {
+			title: {
+				type: String,
+				default: ''
+			},
+			beforeClose: {
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				bottomData: [{
+						text: '微信',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
+						name: 'wx'
+					},
+					{
+						text: '支付宝',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
+						name: 'wx'
+					},
+					{
+						text: 'QQ',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
+						name: 'qq'
+					},
+					{
+						text: '新浪',
+						icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
+						name: 'sina'
+					},
+					// {
+					// 	text: '百度',
+					// 	icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
+					// 	name: 'copy'
+					// },
+					// {
+					// 	text: '其他',
+					// 	icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
+					// 	name: 'more'
+					// }
+				]
+			}
+		},
+		created() {},
+		computed: {
+			cancelText() {
+				return t("uni-popup.cancel")
+			},
+		shareTitleText() {
+				return this.title || t("uni-popup.shareTitle")
+			}
+		},
+		methods: {
+			/**
+			 * 选择内容
+			 */
+			select(item, index) {
+				this.$emit('select', {
+					item,
+					index
+				})
+				this.close()
+
+			},
+			/**
+			 * 关闭窗口
+			 */
+			close() {
+				if(this.beforeClose) return
+				this.popup.close()
+			}
+		}
+	}
+</script>
+<style lang="scss" >
+	.uni-popup-share {
+		background-color: #fff;
+		border-top-left-radius: 11px;
+		border-top-right-radius: 11px;
+	}
+	.uni-share-title {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		height: 40px;
+	}
+	.uni-share-title-text {
+		font-size: 14px;
+		color: #666;
+	}
+	.uni-share-content {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		padding-top: 10px;
+	}
+
+	.uni-share-content-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex-wrap: wrap;
+		width: 360px;
+	}
+
+	.uni-share-content-item {
+		width: 90px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		padding: 10px 0;
+		align-items: center;
+	}
+
+	.uni-share-content-item:active {
+		background-color: #f5f5f5;
+	}
+
+	.uni-share-image {
+		width: 30px;
+		height: 30px;
+	}
+
+	.uni-share-text {
+		margin-top: 10px;
+		font-size: 14px;
+		color: #3B4144;
+	}
+
+	.uni-share-button-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		padding: 10px 15px;
+	}
+
+	.uni-share-button {
+		flex: 1;
+		border-radius: 50px;
+		color: #666;
+		font-size: 16px;
+	}
+
+	.uni-share-button::after {
+		border-radius: 50px;
+	}
+</style>

+ 7 - 0
uni_modules/uni-popup/components/uni-popup/i18n/en.json

@@ -0,0 +1,7 @@
+{
+	"uni-popup.cancel": "cancel",
+	"uni-popup.ok": "ok",
+	"uni-popup.placeholder": "pleace enter",
+	"uni-popup.title": "Hint",
+	"uni-popup.shareTitle": "Share to"
+}

+ 8 - 0
uni_modules/uni-popup/components/uni-popup/i18n/index.js

@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}

+ 7 - 0
uni_modules/uni-popup/components/uni-popup/i18n/zh-Hans.json

@@ -0,0 +1,7 @@
+{
+	"uni-popup.cancel": "取消",
+	"uni-popup.ok": "确定",
+	"uni-popup.placeholder": "请输入",
+		"uni-popup.title": "提示",
+		"uni-popup.shareTitle": "分享到"
+}

+ 7 - 0
uni_modules/uni-popup/components/uni-popup/i18n/zh-Hant.json

@@ -0,0 +1,7 @@
+{
+	"uni-popup.cancel": "取消",
+	"uni-popup.ok": "確定",
+	"uni-popup.placeholder": "請輸入",
+	"uni-popup.title": "提示",
+	"uni-popup.shareTitle": "分享到"
+}

+ 45 - 0
uni_modules/uni-popup/components/uni-popup/keypress.js

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

+ 26 - 0
uni_modules/uni-popup/components/uni-popup/popup.js

@@ -0,0 +1,26 @@
+
+export default {
+	data() {
+		return {
+			
+		}
+	},
+	created(){
+		this.popup = this.getParent()
+	},
+	methods:{
+		/**
+		 * 获取父元素实例
+		 */
+		getParent(name = 'uniPopup') {
+			let parent = this.$parent;
+			let parentName = parent.$options.name;
+			while (parentName !== name) {
+				parent = parent.$parent;
+				if (!parent) return false
+				parentName = parent.$options.name;
+			}
+			return parent;
+		},
+	}
+}

+ 475 - 0
uni_modules/uni-popup/components/uni-popup/uni-popup.vue

@@ -0,0 +1,475 @@
+<template>
+	<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']"
+		@touchmove.stop.prevent="clear">
+		<view @touchstart="touchstart">
+			<uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
+				:duration="duration" :show="showTrans" @click="onTap" />
+			<uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
+				:show="showTrans" @click="onTap">
+				<view class="uni-popup__wrapper" :style="{ backgroundColor: bg }" :class="[popupstyle]" @click="clear">
+					<slot />
+				</view>
+			</uni-transition>
+		</view>
+		<!-- #ifdef H5 -->
+		<keypress v-if="maskShow" @esc="onTap" />
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import keypress from './keypress.js'
+	// #endif
+
+	/**
+	 * PopUp 弹出层
+	 * @description 弹出层组件,为了解决遮罩弹层的问题
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
+	 * @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
+	 * 	@value top 顶部弹出
+	 * 	@value center 中间弹出
+	 * 	@value bottom 底部弹出
+	 * 	@value left		左侧弹出
+	 * 	@value right  右侧弹出
+	 * 	@value message 消息提示
+	 * 	@value dialog 对话框
+	 * 	@value share 底部分享示例
+	 * @property {Boolean} animation = [true|false] 是否开启动画
+	 * @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
+	 * @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
+	 * @property {String}  backgroundColor 主窗口背景色
+	 * @property {String}  maskBackgroundColor 蒙版颜色
+	 * @property {Boolean} safeArea		   是否适配底部安全区
+	 * @event {Function} change 打开关闭弹窗触发,e={show: false}
+	 * @event {Function} maskClick 点击遮罩触发
+	 */
+
+	export default {
+		name: 'uniPopup',
+		components: {
+			// #ifdef H5
+			keypress
+			// #endif
+		},
+		emits: ['change', 'maskClick'],
+		props: {
+			// 开启动画
+			animation: {
+				type: Boolean,
+				default: true
+			},
+			// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
+			// message: 消息提示 ; dialog : 对话框
+			type: {
+				type: String,
+				default: 'center'
+			},
+			// maskClick
+			isMaskClick: {
+				type: Boolean,
+				default: null
+			},
+			// TODO 2 个版本后废弃属性 ,使用 isMaskClick
+			maskClick: {
+				type: Boolean,
+				default: null
+			},
+			backgroundColor: {
+				type: String,
+				default: 'none'
+			},
+			safeArea: {
+				type: Boolean,
+				default: true
+			},
+			maskBackgroundColor: {
+				type: String,
+				default: 'rgba(0, 0, 0, 0.4)'
+			},
+		},
+
+		watch: {
+			/**
+			 * 监听type类型
+			 */
+			type: {
+				handler: function(type) {
+					if (!this.config[type]) return
+					this[this.config[type]](true)
+				},
+				immediate: true
+			},
+			isDesktop: {
+				handler: function(newVal) {
+					if (!this.config[newVal]) return
+					this[this.config[this.type]](true)
+				},
+				immediate: true
+			},
+			/**
+			 * 监听遮罩是否可点击
+			 * @param {Object} val
+			 */
+			maskClick: {
+				handler: function(val) {
+					this.mkclick = val
+				},
+				immediate: true
+			},
+			isMaskClick: {
+				handler: function(val) {
+					this.mkclick = val
+				},
+				immediate: true
+			},
+			// H5 下禁止底部滚动
+			showPopup(show) {
+				// #ifdef H5
+				// fix by mehaotian 处理 h5 滚动穿透的问题
+				document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
+				// #endif
+			}
+		},
+		data() {
+			return {
+				duration: 300,
+				ani: [],
+				showPopup: false,
+				showTrans: false,
+				popupWidth: 0,
+				popupHeight: 0,
+				config: {
+					top: 'top',
+					bottom: 'bottom',
+					center: 'center',
+					left: 'left',
+					right: 'right',
+					message: 'top',
+					dialog: 'center',
+					share: 'bottom'
+				},
+				maskClass: {
+					position: 'fixed',
+					bottom: 0,
+					top: 0,
+					left: 0,
+					right: 0,
+					backgroundColor: 'rgba(0, 0, 0, 0.4)'
+				},
+				transClass: {
+					position: 'fixed',
+					left: 0,
+					right: 0
+				},
+				maskShow: true,
+				mkclick: true,
+				popupstyle: this.isDesktop ? 'fixforpc-top' : 'top'
+			}
+		},
+		computed: {
+			isDesktop() {
+				return this.popupWidth >= 500 && this.popupHeight >= 500
+			},
+			bg() {
+				if (this.backgroundColor === '' || this.backgroundColor === 'none') {
+					return 'transparent'
+				}
+				return this.backgroundColor
+			}
+		},
+		mounted() {
+			const fixSize = () => {
+				const {
+					windowWidth,
+					windowHeight,
+					windowTop,
+					safeArea,
+					screenHeight,
+					safeAreaInsets
+				} = uni.getSystemInfoSync()
+				this.popupWidth = windowWidth
+				this.popupHeight = windowHeight + windowTop
+				// TODO fix by mehaotian 是否适配底部安全区 ,目前微信ios 、和 app ios 计算有差异,需要框架修复
+				if (safeArea && this.safeArea) {
+					// #ifdef MP-WEIXIN
+					this.safeAreaInsets = screenHeight - safeArea.bottom
+					// #endif
+					// #ifndef MP-WEIXIN
+					this.safeAreaInsets = safeAreaInsets.bottom
+					// #endif
+				} else {
+					this.safeAreaInsets = 0
+				}
+			}
+			fixSize()
+			// #ifdef H5
+			// window.addEventListener('resize', fixSize)
+			// this.$once('hook:beforeDestroy', () => {
+			// 	window.removeEventListener('resize', fixSize)
+			// })
+			// #endif
+		},
+		// #ifndef VUE3
+		// TODO vue2
+		destroyed() {
+			this.setH5Visible()
+		},
+		// #endif
+		// #ifdef VUE3
+		// TODO vue3
+		unmounted() {
+			this.setH5Visible()
+		},
+		// #endif
+		created() {
+			// this.mkclick =  this.isMaskClick || this.maskClick
+			if (this.isMaskClick === null && this.maskClick === null) {
+				this.mkclick = true
+			} else {
+				this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
+			}
+			if (this.animation) {
+				this.duration = 300
+			} else {
+				this.duration = 0
+			}
+			// TODO 处理 message 组件生命周期异常的问题
+			this.messageChild = null
+			// TODO 解决头条冒泡的问题
+			this.clearPropagation = false
+			this.maskClass.backgroundColor = this.maskBackgroundColor
+		},
+		methods: {
+			setH5Visible() {
+				// #ifdef H5
+				// fix by mehaotian 处理 h5 滚动穿透的问题
+				document.getElementsByTagName('body')[0].style.overflow = 'visible'
+				// #endif
+			},
+			/**
+			 * 公用方法,不显示遮罩层
+			 */
+			closeMask() {
+				this.maskShow = false
+			},
+			/**
+			 * 公用方法,遮罩层禁止点击
+			 */
+			disableMask() {
+				this.mkclick = false
+			},
+			// TODO nvue 取消冒泡
+			clear(e) {
+				// #ifndef APP-NVUE
+				e.stopPropagation()
+				// #endif
+				this.clearPropagation = true
+			},
+
+			open(direction) {
+				// fix by mehaotian 处理快速打开关闭的情况
+				if(this.showPopup){
+					clearTimeout(this.timer)
+					this.showPopup = false
+				}
+				let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
+				if (!(direction && innerType.indexOf(direction) !== -1)) {
+					direction = this.type
+				}
+				if (!this.config[direction]) {
+					console.error('缺少类型:', direction)
+					return
+				}
+				this[this.config[direction]]()
+				this.$emit('change', {
+					show: true,
+					type: direction
+				})
+			},
+			close(type) {
+				this.showTrans = false
+				this.$emit('change', {
+					show: false,
+					type: this.type
+				})
+				clearTimeout(this.timer)
+				// // 自定义关闭事件
+				// this.customOpen && this.customClose()
+				this.timer = setTimeout(() => {
+					this.showPopup = false
+				}, 300)
+			},
+			// TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容
+			touchstart() {
+				this.clearPropagation = false
+			},
+
+			onTap() {
+				if (this.clearPropagation) {
+					// fix by mehaotian 兼容 nvue
+					this.clearPropagation = false
+					return
+				}
+				this.$emit('maskClick')
+				if (!this.mkclick) return
+				this.close()
+			},
+			/**
+			 * 顶部弹出样式处理
+			 */
+			top(type) {
+				this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
+				this.ani = ['slide-top']
+				this.transClass = {
+					position: 'fixed',
+					left: 0,
+					right: 0,
+					backgroundColor: this.bg
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPopup = true
+				this.showTrans = true
+				this.$nextTick(() => {
+					if (this.messageChild && this.type === 'message') {
+						this.messageChild.timerClose()
+					}
+				})
+			},
+			/**
+			 * 底部弹出样式处理
+			 */
+			bottom(type) {
+				this.popupstyle = 'bottom'
+				this.ani = ['slide-bottom']
+				this.transClass = {
+					position: 'fixed',
+					left: 0,
+					right: 0,
+					bottom: 0,
+					paddingBottom: this.safeAreaInsets + 'px',
+					backgroundColor: this.bg
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPopup = true
+				this.showTrans = true
+			},
+			/**
+			 * 中间弹出样式处理
+			 */
+			center(type) {
+				this.popupstyle = 'center'
+				this.ani = ['zoom-out', 'fade']
+				this.transClass = {
+					position: 'fixed',
+					/* #ifndef APP-NVUE */
+					display: 'flex',
+					flexDirection: 'column',
+					/* #endif */
+					bottom: 0,
+					left: 0,
+					right: 0,
+					top: 0,
+					justifyContent: 'center',
+					alignItems: 'center'
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPopup = true
+				this.showTrans = true
+			},
+			left(type) {
+				this.popupstyle = 'left'
+				this.ani = ['slide-left']
+				this.transClass = {
+					position: 'fixed',
+					left: 0,
+					bottom: 0,
+					top: 0,
+					backgroundColor: this.bg,
+					/* #ifndef APP-NVUE */
+					display: 'flex',
+					flexDirection: 'column'
+					/* #endif */
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPopup = true
+				this.showTrans = true
+			},
+			right(type) {
+				this.popupstyle = 'right'
+				this.ani = ['slide-right']
+				this.transClass = {
+					position: 'fixed',
+					bottom: 0,
+					right: 0,
+					top: 0,
+					backgroundColor: this.bg,
+					/* #ifndef APP-NVUE */
+					display: 'flex',
+					flexDirection: 'column'
+					/* #endif */
+				}
+				// TODO 兼容 type 属性 ,后续会废弃
+				if (type) return
+				this.showPopup = true
+				this.showTrans = true
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.uni-popup {
+		position: fixed;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+
+		/* #endif */
+		&.top,
+		&.left,
+		&.right {
+			/* #ifdef H5 */
+			top: var(--window-top);
+			/* #endif */
+			/* #ifndef H5 */
+			top: 0;
+			/* #endif */
+		}
+
+		.uni-popup__wrapper {
+			/* #ifndef APP-NVUE */
+			display: block;
+			/* #endif */
+			position: relative;
+
+			/* iphonex 等安全区设置,底部安全区适配 */
+			/* #ifndef APP-NVUE */
+			// padding-bottom: constant(safe-area-inset-bottom);
+			// padding-bottom: env(safe-area-inset-bottom);
+			/* #endif */
+			&.left,
+			&.right {
+				/* #ifdef H5 */
+				padding-top: var(--window-top);
+				/* #endif */
+				/* #ifndef H5 */
+				padding-top: 0;
+				/* #endif */
+				flex: 1;
+			}
+		}
+	}
+
+	.fixforpc-z-index {
+		/* #ifndef APP-NVUE */
+		z-index: 999;
+		/* #endif */
+	}
+
+	.fixforpc-top {
+		top: 0;
+	}
+</style>

+ 90 - 0
uni_modules/uni-popup/package.json

@@ -0,0 +1,90 @@
+{
+	"id": "uni-popup",
+	"displayName": "uni-popup 弹出层",
+	"version": "1.7.7",
+	"description": " Popup 组件,提供常用的弹层",
+	"keywords": [
+        "uni-ui",
+        "弹出层",
+        "弹窗",
+        "popup",
+        "弹框"
+    ],
+	"repository": "https://github.com/dcloudio/uni-ui",
+	"engines": {
+		"HBuilderX": ""
+	},
+	"directories": {
+		"example": "../../temps/example_temps"
+	},
+	"dcloudext": {
+		"category": [
+			"前端组件",
+			"通用组件"
+		],
+		"sale": {
+			"regular": {
+				"price": "0.00"
+			},
+			"sourcecode": {
+				"price": "0.00"
+			}
+		},
+		"contact": {
+			"qq": ""
+		},
+		"declaration": {
+			"ads": "无",
+			"data": "无",
+			"permissions": "无"
+		},
+		"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+	},
+	"uni_modules": {
+		"dependencies": [
+			"uni-scss",
+			"uni-transition"
+		],
+		"encrypt": [],
+		"platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y"
+			},
+			"client": {
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "y",
+					"百度": "y",
+					"字节跳动": "y",
+					"QQ": "y"
+				},
+				"快应用": {
+					"华为": "u",
+					"联盟": "u"
+                },
+                "Vue": {
+                    "vue2": "y",
+                    "vue3": "y"
+                }
+			}
+		}
+	}
+}

+ 17 - 0
uni_modules/uni-popup/readme.md

@@ -0,0 +1,17 @@
+
+
+## Popup 弹出层
+> **组件名:uni-popup**
+> 代码块: `uPopup`
+> 关联组件:`uni-transition`
+
+
+弹出层组件,在应用中弹出一个消息提示窗口、提示框等
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
+
+

+ 25 - 0
uni_modules/uni-rate/changelog.md

@@ -0,0 +1,25 @@
+## 1.3.1(2022-02-25)
+- 修复 条件判断 `NaN` 错误的 bug
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-rate](https://uniapp.dcloud.io/component/uniui/uni-rate)
+## 1.2.2(2021-09-10)
+- 优化 默认值修改为 0 颗星
+## 1.2.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.2(2021-05-12)
+- 新增 组件示例地址
+## 1.1.1(2021-04-21)
+- 修复 布局变化后 uni-rate  星星计算不准确的 bug
+- 优化 添加依赖 uni-icons, 导入 uni-rate 自动下载依赖
+## 1.1.0(2021-04-16)
+- 修复 uni-rate 属性 margin 值为 string 组件失效的 bug
+
+## 1.0.9(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.8(2021-02-05)
+- 调整为uni_modules目录规范
+- 支持 pc 端

+ 361 - 0
uni_modules/uni-rate/components/uni-rate/uni-rate.vue

@@ -0,0 +1,361 @@
+<template>
+	<view>
+		<view ref="uni-rate" class="uni-rate">
+			<view class="uni-rate__icon" :class="{'uni-cursor-not-allowed': disabled}"
+				:style="{ 'margin-right': marginNumber + 'px' }" v-for="(star, index) in stars" :key="index"
+				@touchstart.stop="touchstart" @touchmove.stop="touchmove" @mousedown.stop="mousedown"
+				@mousemove.stop="mousemove" @mouseleave="mouseleave">
+				<uni-icons :color="color" :size="size" :type="isFill ? 'star-filled' : 'star'" />
+				<!-- #ifdef APP-NVUE -->
+				<view :style="{ width: star.activeWitch.replace('%','')*size/100+'px'}" class="uni-rate__icon-on">
+					<uni-icons style="text-align: left;" :color="disabled?'#ccc':activeColor" :size="size"
+						type="star-filled" />
+				</view>
+				<!-- #endif -->
+				<!-- #ifndef APP-NVUE -->
+				<view :style="{ width: star.activeWitch}" class="uni-rate__icon-on">
+					<uni-icons :color="disabled?disabledColor:activeColor" :size="size" type="star-filled" />
+				</view>
+				<!-- #endif -->
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// #ifdef APP-NVUE
+	const dom = uni.requireNativePlugin('dom');
+	// #endif
+	/**
+	 * Rate 评分
+	 * @description 评分组件
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=33
+	 * @property {Boolean} 	isFill = [true|false] 		星星的类型,是否为实心类型, 默认为实心
+	 * @property {String} 	color 						未选中状态的星星颜色,默认为 "#ececec"
+	 * @property {String} 	activeColor 				选中状态的星星颜色,默认为 "#ffca3e"
+	 * @property {String} 	disabledColor 				禁用状态的星星颜色,默认为 "#c0c0c0"
+	 * @property {Number} 	size 						星星的大小
+	 * @property {Number} 	value/v-model 				当前评分
+	 * @property {Number} 	max 						最大评分评分数量,目前一分一颗星
+	 * @property {Number} 	margin 						星星的间距,单位 px
+	 * @property {Boolean} 	disabled = [true|false] 	是否为禁用状态,默认为 false
+	 * @property {Boolean} 	readonly = [true|false] 	是否为只读状态,默认为 false
+	 * @property {Boolean} 	allowHalf = [true|false] 	是否实现半星,默认为 false
+	 * @property {Boolean} 	touchable = [true|false] 	是否支持滑动手势,默认为 true
+	 * @event {Function} change 						uniRate 的 value 改变时触发事件,e={value:Number}
+	 */
+
+	export default {
+		name: "UniRate",
+		props: {
+			isFill: {
+				// 星星的类型,是否镂空
+				type: [Boolean, String],
+				default: true
+			},
+			color: {
+				// 星星未选中的颜色
+				type: String,
+				default: "#ececec"
+			},
+			activeColor: {
+				// 星星选中状态颜色
+				type: String,
+				default: "#ffca3e"
+			},
+			disabledColor: {
+				// 星星禁用状态颜色
+				type: String,
+				default: "#c0c0c0"
+			},
+			size: {
+				// 星星的大小
+				type: [Number, String],
+				default: 24
+			},
+			value: {
+				// 当前评分
+				type: [Number, String],
+				default: 0
+			},
+			modelValue: {
+				// 当前评分
+				type: [Number, String],
+				default: 0
+			},
+			max: {
+				// 最大评分
+				type: [Number, String],
+				default: 5
+			},
+			margin: {
+				// 星星的间距
+				type: [Number, String],
+				default: 0
+			},
+			disabled: {
+				// 是否可点击
+				type: [Boolean, String],
+				default: false
+			},
+			readonly: {
+				// 是否只读
+				type: [Boolean, String],
+				default: false
+			},
+			allowHalf: {
+				// 是否显示半星
+				type: [Boolean, String],
+				default: false
+			},
+			touchable: {
+				// 是否支持滑动手势
+				type: [Boolean, String],
+				default: true
+			}
+		},
+		data() {
+			return {
+				valueSync: "",
+				userMouseFristMove: true,
+				userRated: false,
+				userLastRate: 1
+			};
+		},
+		watch: {
+			value(newVal) {
+				this.valueSync = Number(newVal);
+			},
+			modelValue(newVal) {
+				this.valueSync = Number(newVal);
+			},
+		},
+		computed: {
+			stars() {
+				const value = this.valueSync ? this.valueSync : 0;
+				const starList = [];
+				const floorValue = Math.floor(value);
+				const ceilValue = Math.ceil(value);
+				for (let i = 0; i < this.max; i++) {
+					if (floorValue > i) {
+						starList.push({
+							activeWitch: "100%"
+						});
+					} else if (ceilValue - 1 === i) {
+						starList.push({
+							activeWitch: (value - floorValue) * 100 + "%"
+						});
+					} else {
+						starList.push({
+							activeWitch: "0"
+						});
+					}
+				}
+				return starList;
+			},
+
+			marginNumber() {
+				return Number(this.margin)
+			}
+		},
+		created() {
+			this.valueSync = Number(this.value || this.modelValue);
+			this._rateBoxLeft = 0
+			this._oldValue = null
+		},
+		mounted() {
+			setTimeout(() => {
+				this._getSize()
+			}, 100)
+			// #ifdef H5
+			this.PC = this.IsPC()
+			// #endif
+		},
+		methods: {
+			touchstart(e) {
+				// #ifdef H5
+				if (this.IsPC()) return
+				// #endif
+				if (this.readonly || this.disabled) return
+				const {
+					clientX,
+					screenX
+				} = e.changedTouches[0]
+				// TODO 做一下兼容,只有 Nvue 下才有 screenX,其他平台式 clientX
+				this._getRateCount(clientX || screenX)
+			},
+			touchmove(e) {
+				// #ifdef H5
+				if (this.IsPC()) return
+				// #endif
+				if (this.readonly || this.disabled || !this.touchable) return
+				const {
+					clientX,
+					screenX
+				} = e.changedTouches[0]
+				this._getRateCount(clientX || screenX)
+			},
+
+			/**
+			 * 兼容 PC @tian
+			 */
+
+			mousedown(e) {
+				// #ifdef H5
+				if (!this.IsPC()) return
+				if (this.readonly || this.disabled) return
+				const {
+					clientX,
+				} = e
+				this.userLastRate = this.valueSync
+				this._getRateCount(clientX)
+				this.userRated = true
+				// #endif
+			},
+			mousemove(e) {
+				// #ifdef H5
+				if (!this.IsPC()) return
+				if (this.userRated) return
+				if (this.userMouseFristMove) {
+					console.log('---mousemove----', this.valueSync);
+					this.userLastRate = this.valueSync
+					this.userMouseFristMove = false
+				}
+				if (this.readonly || this.disabled || !this.touchable) return
+				const {
+					clientX,
+				} = e
+				this._getRateCount(clientX)
+				// #endif
+			},
+			mouseleave(e) {
+				// #ifdef H5
+				if (!this.IsPC()) return
+				if (this.readonly || this.disabled || !this.touchable) return
+				if (this.userRated) {
+					this.userRated = false
+					return
+				}
+				this.valueSync = this.userLastRate
+				// #endif
+			},
+			// #ifdef H5
+			IsPC() {
+				var userAgentInfo = navigator.userAgent;
+				var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
+				var flag = true;
+				for (let v = 0; v < Agents.length - 1; v++) {
+					if (userAgentInfo.indexOf(Agents[v]) > 0) {
+						flag = false;
+						break;
+					}
+				}
+				return flag;
+			},
+			// #endif
+
+			/**
+			 * 获取星星个数
+			 */
+			_getRateCount(clientX) {
+				this._getSize()
+				const size = Number(this.size)
+				if (isNaN(size)) {
+					return new Error('size 属性只能设置为数字')
+				}
+				const rateMoveRange = clientX - this._rateBoxLeft
+				let index = parseInt(rateMoveRange / (size + this.marginNumber))
+				index = index < 0 ? 0 : index;
+				index = index > this.max ? this.max : index;
+				const range = parseInt(rateMoveRange - (size + this.marginNumber) * index);
+				let value = 0;
+				if (this._oldValue === index && !this.PC) return;
+				this._oldValue = index;
+				if (this.allowHalf) {
+					if (range > (size / 2)) {
+						value = index + 1
+					} else {
+						value = index + 0.5
+					}
+				} else {
+					value = index + 1
+				}
+
+				value = Math.max(0.5, Math.min(value, this.max))
+				this.valueSync = value
+				this._onChange()
+			},
+
+			/**
+			 * 触发动态修改
+			 */
+			_onChange() {
+
+				this.$emit("input", this.valueSync);
+				this.$emit("update:modelValue", this.valueSync);
+				this.$emit("change", {
+					value: this.valueSync
+				});
+			},
+			/**
+			 * 获取星星距离屏幕左侧距离
+			 */
+			_getSize() {
+				// #ifndef APP-NVUE
+				uni.createSelectorQuery()
+					.in(this)
+					.select('.uni-rate')
+					.boundingClientRect()
+					.exec(ret => {
+						if (ret) {
+							this._rateBoxLeft = ret[0].left
+						}
+					})
+				// #endif
+				// #ifdef APP-NVUE
+				dom.getComponentRect(this.$refs['uni-rate'], (ret) => {
+					const size = ret.size
+					if (size) {
+						this._rateBoxLeft = size.left
+					}
+				})
+				// #endif
+			}
+		}
+	};
+</script>
+
+<style lang="scss">
+	.uni-rate {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		line-height: 1;
+		font-size: 0;
+		flex-direction: row;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-rate__icon {
+		position: relative;
+		line-height: 1;
+		font-size: 0;
+	}
+
+	.uni-rate__icon-on {
+		overflow: hidden;
+		position: absolute;
+		top: 0;
+		left: 0;
+		line-height: 1;
+		text-align: left;
+	}
+
+	.uni-cursor-not-allowed {
+		/* #ifdef H5 */
+		cursor: not-allowed !important;
+		/* #endif */
+	}
+</style>

+ 88 - 0
uni_modules/uni-rate/package.json

@@ -0,0 +1,88 @@
+{
+  "id": "uni-rate",
+  "displayName": "uni-rate 评分",
+  "version": "1.3.1",
+  "description": "Rate 评分组件,可自定义评分星星图标的大小、间隔、评分数。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "评分"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 12 - 0
uni_modules/uni-rate/readme.md

@@ -0,0 +1,12 @@
+
+
+## Rate 评分
+> **组件名:uni-rate**
+> 代码块: `uRate`
+> 关联组件:`uni-icons`
+
+
+评分组件,多用于购买商品后,对商品进行评价等场景
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-rate)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 8 - 0
uni_modules/uni-scss/changelog.md

@@ -0,0 +1,8 @@
+## 1.0.3(2022-01-21)
+- 优化 组件示例
+## 1.0.2(2021-11-22)
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
+## 1.0.1(2021-11-22)
+- 修复 vue3中scss语法兼容问题
+## 1.0.0(2021-11-18)
+- init

+ 1 - 0
uni_modules/uni-scss/index.scss

@@ -0,0 +1 @@
+@import './styles/index.scss';

+ 82 - 0
uni_modules/uni-scss/package.json

@@ -0,0 +1,82 @@
+{
+  "id": "uni-scss",
+  "displayName": "uni-scss 辅助样式",
+  "version": "1.0.3",
+  "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
+  "keywords": [
+    "uni-scss",
+    "uni-ui",
+    "辅助样式"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "JS SDK",
+        "通用 SDK"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 4 - 0
uni_modules/uni-scss/readme.md

@@ -0,0 +1,4 @@
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 7 - 0
uni_modules/uni-scss/styles/index.scss

@@ -0,0 +1,7 @@
+@import './setting/_variables.scss';
+@import './setting/_border.scss';
+@import './setting/_color.scss';
+@import './setting/_space.scss';
+@import './setting/_radius.scss';
+@import './setting/_text.scss';
+@import './setting/_styles.scss';

+ 3 - 0
uni_modules/uni-scss/styles/setting/_border.scss

@@ -0,0 +1,3 @@
+.uni-border {
+	border: 1px $uni-border-1 solid;
+}

+ 66 - 0
uni_modules/uni-scss/styles/setting/_color.scss

@@ -0,0 +1,66 @@
+
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
+// @mixin get-styles($k,$c) {
+// 	@if $k == size or $k == weight{
+// 		font-#{$k}:#{$c}
+// 	}@else{
+// 		#{$k}:#{$c}
+// 	}
+// }
+$uni-ui-color:(
+	// 主色
+	primary: $uni-primary,
+	primary-disable: $uni-primary-disable,
+	primary-light: $uni-primary-light,
+	// 辅助色
+	success: $uni-success,
+	success-disable: $uni-success-disable,
+	success-light: $uni-success-light,
+	warning: $uni-warning,
+	warning-disable: $uni-warning-disable,
+	warning-light: $uni-warning-light,
+	error: $uni-error,
+	error-disable: $uni-error-disable,
+	error-light: $uni-error-light,
+	info: $uni-info,
+	info-disable: $uni-info-disable,
+	info-light: $uni-info-light,
+	// 中性色
+	main-color: $uni-main-color,
+	base-color: $uni-base-color,
+	secondary-color: $uni-secondary-color,
+	extra-color: $uni-extra-color,
+	// 背景色
+	bg-color: $uni-bg-color,
+	// 边框颜色
+	border-1: $uni-border-1,
+	border-2: $uni-border-2,
+	border-3: $uni-border-3,
+	border-4: $uni-border-4,
+	// 黑色
+	black:$uni-black,
+	// 白色
+	white:$uni-white,
+	// 透明
+	transparent:$uni-transparent
+) !default;
+@each $key, $child in $uni-ui-color {
+	.uni-#{"" + $key} {
+		color: $child;
+	}
+	.uni-#{"" + $key}-bg {
+		background-color: $child;
+	}
+}
+.uni-shadow-sm {
+	box-shadow: $uni-shadow-sm;
+}
+.uni-shadow-base {
+	box-shadow: $uni-shadow-base;
+}
+.uni-shadow-lg {
+	box-shadow: $uni-shadow-lg;
+}
+.uni-mask {
+	background-color:$uni-mask;
+}

+ 55 - 0
uni_modules/uni-scss/styles/setting/_radius.scss

@@ -0,0 +1,55 @@
+@mixin radius($r,$d:null ,$important: false){
+  $radius-value:map-get($uni-radius, $r) if($important, !important, null);
+  // Key exists within the $uni-radius variable
+  @if (map-has-key($uni-radius, $r) and  $d){
+		@if $d == t {
+				border-top-left-radius:$radius-value;
+				border-top-right-radius:$radius-value;
+		}@else if $d == r {
+				border-top-right-radius:$radius-value;
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == b {
+				border-bottom-left-radius:$radius-value;
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == l {
+				border-top-left-radius:$radius-value;
+				border-bottom-left-radius:$radius-value;
+		}@else if $d == tl {
+				border-top-left-radius:$radius-value;
+		}@else if $d == tr {
+				border-top-right-radius:$radius-value;
+		}@else if $d == br {
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == bl {
+				border-bottom-left-radius:$radius-value;
+		}
+  }@else{
+		border-radius:$radius-value;
+  }
+}
+
+@each $key, $child in $uni-radius {
+	@if($key){
+		.uni-radius-#{"" + $key} {
+				@include radius($key)
+		}
+	}@else{
+		.uni-radius {
+				@include radius($key)
+		}
+	}
+}
+
+@each $direction in t, r, b, l,tl, tr, br, bl {
+	@each $key, $child in $uni-radius {
+		@if($key){
+			.uni-radius-#{"" + $direction}-#{"" + $key} {
+				@include radius($key,$direction,false)
+			}
+		}@else{
+			.uni-radius-#{$direction} {
+				@include radius($key,$direction,false)
+			}
+		}
+	}
+}

+ 56 - 0
uni_modules/uni-scss/styles/setting/_space.scss

@@ -0,0 +1,56 @@
+
+@mixin fn($space,$direction,$size,$n) {
+	@if $n {
+		#{$space}-#{$direction}: #{$size*$uni-space-root}px
+	} @else {
+		 #{$space}-#{$direction}: #{-$size*$uni-space-root}px
+	}
+}
+@mixin get-styles($direction,$i,$space,$n){
+	@if $direction == t {
+		@include fn($space, top,$i,$n);
+	} 
+	@if $direction == r {
+		@include fn($space, right,$i,$n);
+	} 
+	@if $direction == b {
+		@include fn($space, bottom,$i,$n);
+	} 
+	@if $direction == l {
+	 @include fn($space, left,$i,$n);
+	} 
+	@if $direction == x {
+		@include fn($space, left,$i,$n);
+		@include fn($space, right,$i,$n);
+	} 
+	@if $direction == y {
+		@include fn($space, top,$i,$n);
+		@include fn($space, bottom,$i,$n);
+	} 
+	@if $direction == a {
+		@if $n {
+			#{$space}:#{$i*$uni-space-root}px;
+		} @else {
+			#{$space}:#{-$i*$uni-space-root}px;
+		}
+	} 
+}
+
+@each $orientation in m,p {
+	$space: margin;
+	@if $orientation == m {
+		$space: margin;
+	} @else {
+		$space: padding;
+	}
+	@for $i from 0 through 16 {
+		@each $direction in t, r, b, l, x, y, a {
+			.uni-#{$orientation}#{$direction}-#{$i} { 
+				@include  get-styles($direction,$i,$space,true);
+			} 
+			.uni-#{$orientation}#{$direction}-n#{$i} { 
+				@include  get-styles($direction,$i,$space,false);
+			}
+		}
+	}
+}

+ 167 - 0
uni_modules/uni-scss/styles/setting/_styles.scss

@@ -0,0 +1,167 @@
+/* #ifndef APP-NVUE */
+
+$-color-white:#fff;
+$-color-black:#000;
+@mixin base-style($color) {
+	color: #fff;
+	background-color: $color;
+	border-color: mix($-color-black, $color, 8%);
+	&:not([hover-class]):active {
+		background: mix($-color-black, $color, 10%);
+		border-color: mix($-color-black, $color, 20%);
+		color: $-color-white;
+		outline: none;
+	}
+}
+@mixin is-color($color) {
+	@include base-style($color);
+	&[loading] {
+		@include base-style($color);
+		&::before {
+			margin-right:5px;
+		}
+	}
+	&[disabled] {
+	  &,
+		&[loading],
+	  &:not([hover-class]):active {
+	    color: $-color-white;
+			border-color: mix(darken($color,10%), $-color-white);
+	    background-color: mix($color, $-color-white);
+	  }
+	}
+
+}
+@mixin base-plain-style($color) {
+	color:$color;
+	background-color: mix($-color-white, $color, 90%);
+	border-color: mix($-color-white, $color, 70%);
+	&:not([hover-class]):active {
+	  background: mix($-color-white, $color, 80%);
+	  color: $color;
+	  outline: none;
+		border-color: mix($-color-white, $color, 50%);
+	}
+}
+@mixin is-plain($color){
+	&[plain] {
+		@include base-plain-style($color);
+		&[loading] {
+			@include base-plain-style($color);
+			&::before {
+				margin-right:5px;
+			}
+		}
+		&[disabled] {
+		  &,
+		  &:active {
+		    color: mix($-color-white, $color, 40%);
+		    background-color: mix($-color-white, $color, 90%);
+				border-color: mix($-color-white, $color, 80%);
+		  }
+		}
+	}
+}
+
+
+.uni-btn {
+	margin: 5px;
+	color: #393939;
+	border:1px solid #ccc;
+	font-size: 16px;
+	font-weight: 200;
+	background-color: #F9F9F9;
+	// TODO 暂时处理边框隐藏一边的问题
+	overflow: visible;
+	&::after{
+		border: none;
+	}
+
+	&:not([type]),&[type=default] {
+		color: #999;
+		&[loading] {
+			background: none;
+			&::before {
+				margin-right:5px;
+			}
+		}
+
+
+
+		&[disabled]{
+			color: mix($-color-white, #999, 60%);
+		  &,
+			&[loading],
+		  &:active {
+				color: mix($-color-white, #999, 60%);
+		    background-color: mix($-color-white,$-color-black , 98%);
+				border-color: mix($-color-white,  #999, 85%);
+		  }
+		}
+
+		&[plain] {
+			color: #999;
+			background: none;
+			border-color: $uni-border-1;
+			&:not([hover-class]):active {
+				background: none;
+			  color: mix($-color-white, $-color-black, 80%);
+				border-color: mix($-color-white, $-color-black, 90%);
+			  outline: none;
+			}
+			&[disabled]{
+			  &,
+				&[loading],
+			  &:active {
+			    background: none;
+					color: mix($-color-white, #999, 60%);
+					border-color: mix($-color-white,  #999, 85%);
+			  }
+			}
+		}
+	}
+
+	&:not([hover-class]):active {
+	  color: mix($-color-white, $-color-black, 50%);
+	}
+
+	&[size=mini] {
+		font-size: 16px;
+		font-weight: 200;
+		border-radius: 8px;
+	}
+
+
+
+	&.uni-btn-small {
+		font-size: 14px;
+	}
+	&.uni-btn-mini {
+		font-size: 12px;
+	}
+
+	&.uni-btn-radius {
+		border-radius: 999px;
+	}
+	&[type=primary] {
+		@include is-color($uni-primary);
+		@include is-plain($uni-primary)
+	}
+	&[type=success] {
+		@include is-color($uni-success);
+		@include is-plain($uni-success)
+	}
+	&[type=error] {
+		@include is-color($uni-error);
+		@include is-plain($uni-error)
+	}
+	&[type=warning] {
+		@include is-color($uni-warning);
+		@include is-plain($uni-warning)
+	}
+	&[type=info] {
+		@include is-color($uni-info);
+		@include is-plain($uni-info)
+	}
+}
+/* #endif */

+ 24 - 0
uni_modules/uni-scss/styles/setting/_text.scss

@@ -0,0 +1,24 @@
+@mixin get-styles($k,$c) {
+	@if $k == size or $k == weight{
+		font-#{$k}:#{$c}
+	}@else{
+		#{$k}:#{$c}
+	}
+}
+
+@each $key, $child in $uni-headings {
+	/* #ifndef APP-NVUE */
+	.uni-#{$key} {
+		@each $k, $c in $child {
+			@include get-styles($k,$c)
+		}
+	}
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	.container .uni-#{$key} {
+		@each $k, $c in $child {
+			@include get-styles($k,$c)
+		}
+	}
+	/* #endif */
+}

+ 146 - 0
uni_modules/uni-scss/styles/setting/_variables.scss

@@ -0,0 +1,146 @@
+// @use "sass:math";
+@import  '../tools/functions.scss';
+// 间距基础倍数
+$uni-space-root: 2 !default;
+// 边框半径默认值
+$uni-radius-root:5px !default;
+$uni-radius: () !default;
+// 边框半径断点
+$uni-radius: map-deep-merge(
+  (
+    0: 0,
+		// TODO 当前版本暂时不支持 sm 属性
+    // 'sm': math.div($uni-radius-root, 2),
+    null: $uni-radius-root,
+    'lg': $uni-radius-root * 2,
+    'xl': $uni-radius-root * 6,
+    'pill': 9999px,
+    'circle': 50%
+  ),
+  $uni-radius
+);
+// 字体家族
+$body-font-family: 'Roboto', sans-serif !default;
+// 文本
+$heading-font-family: $body-font-family !default;
+$uni-headings: () !default;
+$letterSpacing: -0.01562em;
+$uni-headings: map-deep-merge(
+  (
+    'h1': (
+      size: 32px,
+			weight: 300,
+			line-height: 50px,
+			// letter-spacing:-0.01562em
+    ),
+    'h2': (
+      size: 28px,
+      weight: 300,
+      line-height: 40px,
+      // letter-spacing: -0.00833em
+    ),
+    'h3': (
+      size: 24px,
+      weight: 400,
+      line-height: 32px,
+      // letter-spacing: normal
+    ),
+    'h4': (
+      size: 20px,
+      weight: 400,
+      line-height: 30px,
+      // letter-spacing: 0.00735em
+    ),
+    'h5': (
+      size: 16px,
+      weight: 400,
+      line-height: 24px,
+      // letter-spacing: normal
+    ),
+    'h6': (
+      size: 14px,
+      weight: 500,
+      line-height: 18px,
+      // letter-spacing: 0.0125em
+    ),
+    'subtitle': (
+      size: 12px,
+      weight: 400,
+      line-height: 20px,
+      // letter-spacing: 0.00937em
+    ),
+    'body': (
+      font-size: 14px,
+			font-weight: 400,
+			line-height: 22px,
+			// letter-spacing: 0.03125em
+    ),
+    'caption': (
+      'size': 12px,
+      'weight': 400,
+      'line-height': 20px,
+      // 'letter-spacing': 0.03333em,
+      // 'text-transform': false
+    )
+  ),
+  $uni-headings
+);
+
+
+
+// 主色
+$uni-primary: #2979ff !default;
+$uni-primary-disable:lighten($uni-primary,20%) !default;
+$uni-primary-light: lighten($uni-primary,25%) !default;
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37 !default;
+$uni-success-disable:lighten($uni-success,20%) !default;
+$uni-success-light: lighten($uni-success,25%) !default;
+
+$uni-warning: #f3a73f !default;
+$uni-warning-disable:lighten($uni-warning,20%) !default;
+$uni-warning-light: lighten($uni-warning,25%) !default;
+
+$uni-error: #e43d33 !default;
+$uni-error-disable:lighten($uni-error,20%) !default;
+$uni-error-light: lighten($uni-error,25%) !default;
+
+$uni-info: #8f939c !default;
+$uni-info-disable:lighten($uni-info,20%) !default;
+$uni-info-light: lighten($uni-info,25%) !default;
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a !default; 			// 主要文字
+$uni-base-color: #6a6a6a !default;			// 常规文字
+$uni-secondary-color: #909399 !default;	// 次要文字
+$uni-extra-color: #c7c7c7 !default;			// 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0 !default;
+$uni-border-2: #EDEDED !default;
+$uni-border-3: #DCDCDC !default;
+$uni-border-4: #B9B9B9 !default;
+
+// 常规色
+$uni-black: #000000 !default;
+$uni-white: #ffffff !default;
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
+
+// 背景色
+$uni-bg-color: #f7f7f7 !default;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px !default;
+$uni-spacing-base: 15px !default;
+$uni-spacing-lg: 30px !default;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;

+ 19 - 0
uni_modules/uni-scss/styles/tools/functions.scss

@@ -0,0 +1,19 @@
+// 合并 map
+@function map-deep-merge($parent-map, $child-map){
+	$result: $parent-map;
+	@each $key, $child in $child-map {
+		$parent-has-key: map-has-key($result, $key);
+		$parent-value: map-get($result, $key);
+		$parent-type: type-of($parent-value);
+		$child-type: type-of($child);
+		$parent-is-map: $parent-type == map;
+		$child-is-map: $child-type == map;
+			
+		@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
+			$result: map-merge($result, ( $key: $child ));
+		}@else {
+			$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
+		}
+	}
+	@return $result;
+};

+ 31 - 0
uni_modules/uni-scss/theme.scss

@@ -0,0 +1,31 @@
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+// 主色
+$uni-primary: #2979ff;
+// 辅助色
+$uni-success: #4cd964;
+// 警告色
+$uni-warning: #f0ad4e;
+// 错误色
+$uni-error: #dd524d;
+// 描述色
+$uni-info: #909399;
+// 中性色
+$uni-main-color: #303133;
+$uni-base-color: #606266;
+$uni-secondary-color: #909399;
+$uni-extra-color: #C0C4CC;
+// 背景色
+$uni-bg-color: #f5f5f5;
+// 边框颜色
+$uni-border-1: #DCDFE6;
+$uni-border-2: #E4E7ED;
+$uni-border-3: #EBEEF5;
+$uni-border-4: #F2F6FC;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);

+ 62 - 0
uni_modules/uni-scss/variables.scss

@@ -0,0 +1,62 @@
+@import './styles/setting/_variables.scss';
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+
+// 主色
+$uni-primary: #2979ff;
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
+$uni-primary-light: mix(#fff,$uni-primary,80%);
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37;
+$uni-success-disable:mix(#fff,$uni-success,50%);
+$uni-success-light: mix(#fff,$uni-success,80%);
+
+$uni-warning: #f3a73f;
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
+$uni-warning-light: mix(#fff,$uni-warning,80%);
+
+$uni-error: #e43d33;
+$uni-error-disable:mix(#fff,$uni-error,50%);
+$uni-error-light: mix(#fff,$uni-error,80%);
+
+$uni-info: #8f939c;
+$uni-info-disable:mix(#fff,$uni-info,50%);
+$uni-info-light: mix(#fff,$uni-info,80%);
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a; 			// 主要文字
+$uni-base-color: #6a6a6a;			// 常规文字
+$uni-secondary-color: #909399;	// 次要文字
+$uni-extra-color: #c7c7c7;			// 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0;
+$uni-border-2: #EDEDED;
+$uni-border-3: #DCDCDC;
+$uni-border-4: #B9B9B9;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
+
+// 背景色
+$uni-bg-color: #f7f7f7;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px;
+$uni-spacing-base: 15px;
+$uni-spacing-lg: 30px;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4);

+ 20 - 0
uni_modules/uni-transition/changelog.md

@@ -0,0 +1,20 @@
+## 1.3.1(2021-11-23)
+- 修复 init 方法初始化问题
+## 1.3.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
+## 1.2.1(2021-09-27)
+- 修复 init 方法不生效的 Bug
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.1(2021-05-12)
+- 新增 示例地址
+- 修复 示例项目缺少组件的 Bug
+## 1.1.0(2021-04-22)
+- 新增 通过方法自定义动画
+- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
+- 优化 动画触发逻辑,使动画更流畅
+- 优化 支持单独的动画类型
+- 优化 文档示例
+## 1.0.2(2021-02-05)
+- 调整为 uni_modules 目录规范

+ 128 - 0
uni_modules/uni-transition/components/uni-transition/createAnimation.js

@@ -0,0 +1,128 @@
+// const defaultOption = {
+// 	duration: 300,
+// 	timingFunction: 'linear',
+// 	delay: 0,
+// 	transformOrigin: '50% 50% 0'
+// }
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+// #endif
+class MPAnimation {
+	constructor(options, _this) {
+		this.options = options
+		this.animation = uni.createAnimation(options)
+		this.currentStepAnimates = {}
+		this.next = 0
+		this.$ = _this
+
+	}
+
+	_nvuePushAnimates(type, args) {
+		let aniObj = this.currentStepAnimates[this.next]
+		let styles = {}
+		if (!aniObj) {
+			styles = {
+				styles: {},
+				config: {}
+			}
+		} else {
+			styles = aniObj
+		}
+		if (animateTypes1.includes(type)) {
+			if (!styles.styles.transform) {
+				styles.styles.transform = ''
+			}
+			let unit = ''
+			if(type === 'rotate'){
+				unit = 'deg'
+			}
+			styles.styles.transform += `${type}(${args+unit}) `
+		} else {
+			styles.styles[type] = `${args}`
+		}
+		this.currentStepAnimates[this.next] = styles
+	}
+	_animateRun(styles = {}, config = {}) {
+		let ref = this.$.$refs['ani'].ref
+		if (!ref) return
+		return new Promise((resolve, reject) => {
+			nvueAnimation.transition(ref, {
+				styles,
+				...config
+			}, res => {
+				resolve()
+			})
+		})
+	}
+
+	_nvueNextAnimate(animates, step = 0, fn) {
+		let obj = animates[step]
+		if (obj) {
+			let {
+				styles,
+				config
+			} = obj
+			this._animateRun(styles, config).then(() => {
+				step += 1
+				this._nvueNextAnimate(animates, step, fn)
+			})
+		} else {
+			this.currentStepAnimates = {}
+			typeof fn === 'function' && fn()
+			this.isEnd = true
+		}
+	}
+
+	step(config = {}) {
+		// #ifndef APP-NVUE
+		this.animation.step(config)
+		// #endif
+		// #ifdef APP-NVUE
+		this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+		this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+		this.next++
+		// #endif
+		return this
+	}
+
+	run(fn) {
+		// #ifndef APP-NVUE
+		this.$.animationData = this.animation.export()
+		this.$.timer = setTimeout(() => {
+			typeof fn === 'function' && fn()
+		}, this.$.durationTime)
+		// #endif
+		// #ifdef APP-NVUE
+		this.isEnd = false
+		let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
+		if(!ref) return
+		this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
+		this.next = 0
+		// #endif
+	}
+}
+
+
+const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+	'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+	'translateZ'
+]
+const animateTypes2 = ['opacity', 'backgroundColor']
+const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+	MPAnimation.prototype[type] = function(...args) {
+		// #ifndef APP-NVUE
+		this.animation[type](...args)
+		// #endif
+		// #ifdef APP-NVUE
+		this._nvuePushAnimates(type, args)
+		// #endif
+		return this
+	}
+})
+
+export function createAnimation(option, _this) {
+	if(!_this) return
+	clearTimeout(_this.timer)
+	return new MPAnimation(option, _this)
+}

+ 277 - 0
uni_modules/uni-transition/components/uni-transition/uni-transition.vue

@@ -0,0 +1,277 @@
+<template>
+	<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
+</template>
+
+<script>
+import { createAnimation } from './createAnimation'
+
+/**
+ * Transition 过渡动画
+ * @description 简单过渡动画组件
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=985
+ * @property {Boolean} show = [false|true] 控制组件显示或隐藏
+ * @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
+ *  @value fade 渐隐渐出过渡
+ *  @value slide-top 由上至下过渡
+ *  @value slide-right 由右至左过渡
+ *  @value slide-bottom 由下至上过渡
+ *  @value slide-left 由左至右过渡
+ *  @value zoom-in 由小到大过渡
+ *  @value zoom-out 由大到小过渡
+ * @property {Number} duration 过渡动画持续时间
+ * @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
+ */
+export default {
+	name: 'uniTransition',
+	emits:['click','change'],
+	props: {
+		show: {
+			type: Boolean,
+			default: false
+		},
+		modeClass: {
+			type: [Array, String],
+			default() {
+				return 'fade'
+			}
+		},
+		duration: {
+			type: Number,
+			default: 300
+		},
+		styles: {
+			type: Object,
+			default() {
+				return {}
+			}
+		},
+		customClass:{
+			type: String,
+			default: ''
+		}
+	},
+	data() {
+		return {
+			isShow: false,
+			transform: '',
+			opacity: 1,
+			animationData: {},
+			durationTime: 300,
+			config: {}
+		}
+	},
+	watch: {
+		show: {
+			handler(newVal) {
+				if (newVal) {
+					this.open()
+				} else {
+					// 避免上来就执行 close,导致动画错乱
+					if (this.isShow) {
+						this.close()
+					}
+				}
+			},
+			immediate: true
+		}
+	},
+	computed: {
+		// 生成样式数据
+		stylesObject() {
+			let styles = {
+				...this.styles,
+				'transition-duration': this.duration / 1000 + 's'
+			}
+			let transform = ''
+			for (let i in styles) {
+				let line = this.toLine(i)
+				transform += line + ':' + styles[i] + ';'
+			}
+			return transform
+		},
+		// 初始化动画条件
+		transformStyles() {
+			return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
+		}
+	},
+	created() {
+		// 动画默认配置
+		this.config = {
+			duration: this.duration,
+			timingFunction: 'ease',
+			transformOrigin: '50% 50%',
+			delay: 0
+		}
+		this.durationTime = this.duration
+	},
+	methods: {
+		/**
+		 *  ref 触发 初始化动画
+		 */
+		init(obj = {}) {
+			if (obj.duration) {
+				this.durationTime = obj.duration
+			}
+			this.animation = createAnimation(Object.assign(this.config, obj),this)
+		},
+		/**
+		 * 点击组件触发回调
+		 */
+		onClick() {
+			this.$emit('click', {
+				detail: this.isShow
+			})
+		},
+		/**
+		 * ref 触发 动画分组
+		 * @param {Object} obj
+		 */
+		step(obj, config = {}) {
+			if (!this.animation) return
+			for (let i in obj) {
+				try {
+					if(typeof obj[i] === 'object'){
+						this.animation[i](...obj[i])
+					}else{
+						this.animation[i](obj[i])
+					}
+				} catch (e) {
+					console.error(`方法 ${i} 不存在`)
+				}
+			}
+			this.animation.step(config)
+			return this
+		},
+		/**
+		 *  ref 触发 执行动画
+		 */
+		run(fn) {
+			if (!this.animation) return
+			this.animation.run(fn)
+		},
+		// 开始过度动画
+		open() {
+			clearTimeout(this.timer)
+			this.transform = ''
+			this.isShow = true
+			let { opacity, transform } = this.styleInit(false)
+			if (typeof opacity !== 'undefined') {
+				this.opacity = opacity
+			}
+			this.transform = transform
+			// 确保动态样式已经生效后,执行动画,如果不加 nextTick ,会导致 wx 动画执行异常
+			this.$nextTick(() => {
+				// TODO 定时器保证动画完全执行,目前有些问题,后面会取消定时器
+				this.timer = setTimeout(() => {
+					this.animation = createAnimation(this.config, this)
+					this.tranfromInit(false).step()
+					this.animation.run()
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				}, 20)
+			})
+		},
+		// 关闭过度动画
+		close(type) {
+			if (!this.animation) return
+			this.tranfromInit(true)
+				.step()
+				.run(() => {
+					this.isShow = false
+					this.animationData = null
+					this.animation = null
+					let { opacity, transform } = this.styleInit(false)
+					this.opacity = opacity || 1
+					this.transform = transform
+					this.$emit('change', {
+						detail: this.isShow
+					})
+				})
+		},
+		// 处理动画开始前的默认样式
+		styleInit(type) {
+			let styles = {
+				transform: ''
+			}
+			let buildStyle = (type, mode) => {
+				if (mode === 'fade') {
+					styles.opacity = this.animationType(type)[mode]
+				} else {
+					styles.transform += this.animationType(type)[mode] + ' '
+				}
+			}
+			if (typeof this.modeClass === 'string') {
+				buildStyle(type, this.modeClass)
+			} else {
+				this.modeClass.forEach(mode => {
+					buildStyle(type, mode)
+				})
+			}
+			return styles
+		},
+		// 处理内置组合动画
+		tranfromInit(type) {
+			let buildTranfrom = (type, mode) => {
+				let aniNum = null
+				if (mode === 'fade') {
+					aniNum = type ? 0 : 1
+				} else {
+					aniNum = type ? '-100%' : '0'
+					if (mode === 'zoom-in') {
+						aniNum = type ? 0.8 : 1
+					}
+					if (mode === 'zoom-out') {
+						aniNum = type ? 1.2 : 1
+					}
+					if (mode === 'slide-right') {
+						aniNum = type ? '100%' : '0'
+					}
+					if (mode === 'slide-bottom') {
+						aniNum = type ? '100%' : '0'
+					}
+				}
+				this.animation[this.animationMode()[mode]](aniNum)
+			}
+			if (typeof this.modeClass === 'string') {
+				buildTranfrom(type, this.modeClass)
+			} else {
+				this.modeClass.forEach(mode => {
+					buildTranfrom(type, mode)
+				})
+			}
+
+			return this.animation
+		},
+		animationType(type) {
+			return {
+				fade: type ? 1 : 0,
+				'slide-top': `translateY(${type ? '0' : '-100%'})`,
+				'slide-right': `translateX(${type ? '0' : '100%'})`,
+				'slide-bottom': `translateY(${type ? '0' : '100%'})`,
+				'slide-left': `translateX(${type ? '0' : '-100%'})`,
+				'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
+				'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
+			}
+		},
+		// 内置动画类型与实际动画对应字典
+		animationMode() {
+			return {
+				fade: 'opacity',
+				'slide-top': 'translateY',
+				'slide-right': 'translateX',
+				'slide-bottom': 'translateY',
+				'slide-left': 'translateX',
+				'zoom-in': 'scale',
+				'zoom-out': 'scale'
+			}
+		},
+		// 驼峰转中横线
+		toLine(name) {
+			return name.replace(/([A-Z])/g, '-$1').toLowerCase()
+		}
+	}
+}
+</script>
+
+<style></style>

+ 87 - 0
uni_modules/uni-transition/package.json

@@ -0,0 +1,87 @@
+{
+  "id": "uni-transition",
+  "displayName": "uni-transition 过渡动画",
+  "version": "1.3.1",
+  "description": "元素的简单过渡动画",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "动画",
+    "过渡",
+    "过渡动画"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 11 - 0
uni_modules/uni-transition/readme.md

@@ -0,0 +1,11 @@
+
+
+## Transition 过渡动画
+> **组件名:uni-transition**
+> 代码块: `uTransition`
+
+
+元素过渡动画
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 1 - 0
unpackage/cache/.storyboard

@@ -0,0 +1 @@
+md5=977df7cb7388338f234c3b055980eb38

二进制
unpackage/cache/apk/__UNI__F0EBD91_cm.apk


+ 1 - 0
unpackage/cache/apk/apkurl

@@ -0,0 +1 @@
+https://ide.dcloud.net.cn/build/download/d991aab0-c535-11ec-8f11-534fe4a2490a

文件差异内容过多而无法显示
+ 0 - 0
unpackage/cache/apk/cmManifestCache.json


+ 30 - 0
unpackage/cache/appleConfig.ini

@@ -0,0 +1,30 @@
+[appleAppid]
+appleAppid=com.ljzn.inc
+
+[iosStyle]
+iosStyle=common
+
+[universalLinks]
+universalLinks=https://www.zjljzn.com/uni-universallinks/__UNI__F0EBD91/
+spaceid=364f3115-6ed2-4e8f-913f-836cbd3f34fa
+
+[universalLinks_qq]
+universalLinks_qq=
+spaceid_qq=
+
+[universalLinks_weibo]
+universalLinks_weibo=
+spaceid_weibo=
+
+[appstore]
+appstore=
+
+[iphone]
+app%402x=7e0d1a8a8dca82bcaf13a0059e872dcb
+app%403x=4d4877e3ab920aaf1ce8ea7b0136b2ad
+notification%402x=cdd8c2cbf6be3335e3780c0ea7f79689
+notification%403x=4de0fe89e904bf0c94b6d8e7d95edd64
+settings%402x=56a77bb57b2a59b9baec109471945b77
+settings%403x=a4ab7ba5bebab6052fa00acf2e6075e0
+spotlight%402x=de105411b49ea5371e9a7224b0d5d88f
+spotlight%403x=7e0d1a8a8dca82bcaf13a0059e872dcb

+ 3 - 0
unpackage/cache/certdata

@@ -0,0 +1,3 @@
+andrCertfile=D:/item/newDdc/unpackage/证书/安卓证书/gyy.keystore
+andrCertAlias=gyy.inc
+andrCertPass=7IwuiYJfyRjKKTfhI7sjzw==

+ 3 - 0
unpackage/cache/certdataios

@@ -0,0 +1,3 @@
+iosProfile=D:/绿津/newDdc/unpackage/证书/ios证书/个人证书/zjlj.mobileprovision
+ioscertFile=D:/绿津/newDdc/unpackage/证书/ios证书/个人证书/lj.p12
+ioscertPassword=7IwuiYJfyRjKKTfhI7sjzw==

+ 11 - 0
unpackage/cache/ipa/apple-app-site-association

@@ -0,0 +1,11 @@
+{
+    "applinks" : {
+        "apps" : [],
+        "details" : [
+            {
+                "appID" : "9KHNX7L8SV.com.ljzn.inc",
+                "paths" : [ "*", "D91" ]
+            }
+        ]
+    }
+}

二进制
unpackage/cache/wgt/__UNI__F0EBD91/.manifest/google-keystore.keystore


二进制
unpackage/cache/wgt/__UNI__F0EBD91/.manifest/icon-android-hdpi.png


二进制
unpackage/cache/wgt/__UNI__F0EBD91/.manifest/icon-android-xhdpi.png


部分文件因为文件数量过多而无法显示