commit 7a066b3026b23ea28ea3d34e6e9c386874e4a5a9
Author: Jerry Yan <792602257@qq.com>
Date: Mon Jun 16 10:09:19 2025 +0800
1.0.0
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..64057b6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.hbuilderx
+unpackage
+.vscode
+.idea
+node_modules
\ No newline at end of file
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..eda367b
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,68 @@
+
+
+
+
diff --git a/common/ajax.js b/common/ajax.js
new file mode 100644
index 0000000..4bb67a5
--- /dev/null
+++ b/common/ajax.js
@@ -0,0 +1,118 @@
+import ajax from '@/uni_modules/uni-ajax/js_sdk/index.js';
+import {
+ TaCache
+} from './cache';
+import {
+ TaToast
+} from './toast';
+import {
+ objectHasKey
+} from './util';
+
+// 执行队列
+let _tasks = []
+let _status = true
+
+export const baseUrl = 'https://www.gafzgc.com/'
+// export const baseUrl = 'http://127.0.0.1:8000/'
+
+// 创建请求实例,检查登录状态及业务异常,返回 Body 内容( 建议使用 TaPost 处理)
+const TaHttp = ajax.create({
+ baseURL: baseUrl
+})
+
+// 创建请求实例,不检查登录状态及业务异常,返回 Body 内容
+export const TaAjax = ajax.create({
+ baseURL: baseUrl
+})
+
+// 通用 POST 提交,检查登录状态及业务异常,返回 Body 内容,可中断请求
+export function TaPost(uri, data = {}, load = '', options = {}) {
+ load.length > 0 && TaToast.loading(load)
+ return new Promise((resolve, reject) => {
+ if (_status) {
+ _tasks.push(options.fetcher = new ajax.Fetcher())
+ TaHttp.post(uri, data, options).then((ret) => {
+ ret.code === 1 ? resolve(ret) : reject(ret)
+ }).finally(() => {
+ load.length > 0 && TaToast.loadhide()
+ _tasks.splice(_tasks.indexOf(options.fetcher), 1)
+ })
+ } else {
+ load.length > 0 && TaToast.loadhide()
+ reject({
+ code: 0,
+ info: '请求已被阻止!'
+ })
+ }
+ })
+}
+
+// 阻止 POST 请求 ( 20毫秒内阻止请求 )
+export function TaPostAbort() {
+ _status = false;
+ _tasks.forEach((x, i) => (x.abort(), _tasks.splice(i, 1)))
+ return new Promise(resolve => setTimeout(() => resolve(_status = true), 20))
+}
+
+// 添加请求拦截器
+TaHttp.interceptors.request.use(useRequestInterceptor, error => Promise.reject(error))
+TaAjax.interceptors.request.use(useRequestInterceptor, error => Promise.reject(error))
+
+// 添加响应拦截器
+TaHttp.interceptors.response.use(response => useResponseInterceptor(response, true), error => Promise.reject(error))
+TaAjax.interceptors.response.use(response => useResponseInterceptor(response, false), error => Promise.reject(error))
+
+// 定义请求拦截函数
+function useRequestInterceptor(config) {
+ // 检查是否有 Api-Token 配置,没有则自动追加配置
+ let token = TaCache.get('auth.token')
+ if (token) config.header['Api-Token'] = token
+ // 检查是否有 Content-Type 配置,没有则自动追加配置
+ if (!objectHasKey(config.header, 'content-type')) {
+ config.header['Content-Type'] = 'application/x-www-form-urlencoded'
+ }
+ return config
+}
+
+// 定义结果拦截函数
+function useResponseInterceptor(response, checkAuth) {
+ // 获取返回的数据
+ let body = response.data || {
+ code: 0,
+ info: 'unknow',
+ data: {}
+ }
+ // 网络请求异常处理
+ if (response.statusCode === 404) {
+ TaToast.error(body.info || '资源不存在!')
+ return Promise.reject(body)
+ } else if (response.statusCode === 500) {
+ TaToast.error(body.info || '服务异常!')
+ return Promise.reject(body)
+ } else if (response.statusCode !== 200) {
+ TaToast.error(body.info || '请求异常!' + body.code)
+ return Promise.reject(body)
+ }
+ // 接口返回异常处理
+ if (checkAuth) {
+ if (body.code === 402) {
+ TaPostAbort(), TaToast.error(body.info || '请完善资料!').then(() => uni.navigateTo({
+ url: '/pages/user/bind/bind'
+ }))
+ return Promise.reject(body)
+ } else if ((body.code === 401 || body.code === 403)) {
+ TaPostAbort(), TaToast.error(body.info || '需要登录授权!').then(() => DataUser.logout())
+ return Promise.reject(body)
+ } else if (body.code !== 1) {
+ body.info && TaToast.error(body.info)
+ return Promise.reject(body)
+ }
+ }
+ // 任何请求,如果有返回 Token 都进行保存授权令牌
+ if (body.data && typeof body.data.token === 'string') {
+ TaCache.set('auth.token', body.data.token)
+ }
+ // 返回主体内容
+ return Promise.resolve(body);
+}
\ No newline at end of file
diff --git a/common/cache.js b/common/cache.js
new file mode 100644
index 0000000..733630b
--- /dev/null
+++ b/common/cache.js
@@ -0,0 +1,29 @@
+
+// 本地缓存封装
+export const TaCache = {
+
+ // 写入缓存数据,可配置有效时间(毫秒)
+ set(name, value, expire = 0) {
+ expire = expire > 0 ? Date.now() + expire : 0
+ uni.setStorageSync(name, JSON.stringify([value, expire]))
+ return value;
+ },
+
+ /* 获取缓存数据 */
+ get(name, defa = null) {
+ try {
+ let text = uni.getStorageSync(name)
+ if (!text) return defa
+ let data = JSON.parse(text)
+ let isExpire = (data[1] || 0) > 0 && data[1] < Date.now()
+ return isExpire ? (TaCache.del(name), defa) : data[0]
+ } catch (e) {
+ return defa
+ }
+ },
+
+ /* 删除缓存数据 */
+ del(name) {
+ uni.removeStorageSync(name)
+ },
+}
diff --git a/common/free.css b/common/free.css
new file mode 100644
index 0000000..96932a3
--- /dev/null
+++ b/common/free.css
@@ -0,0 +1,458 @@
+/* #ifndef APP-PLUS-NVUE */
+.status_bar {height: var(--status-bar-height); width: 100%;}
+/* scroll-view */
+.scroll-row{ width: 100%;white-space: nowrap; }
+.scroll-row-item{ display: inline-block!important; }
+/* #endif */
+/* 图标 */
+.iconfont{
+ font-family:iconfont;
+}
+.view,.text{
+ font-size:28rpx;
+ line-height:1.8;
+ color:#000000;
+}
+.img-in{font-size:0;}
+/* 宽度 */
+/* #ifndef APP-PLUS-NVUE */
+.w-100{ width: 100%; }
+.w-80{width: 80%;}
+.w-33{width: 33%;}
+/* #endif */
+.w-50{width: 50%;}
+.w-25{width: 25%;}
+.w-20{width: 20%;}
+.row {
+ margin-right: -20rpx;
+ margin-left: -20rpx;
+ /* #ifndef APP-PLUS-NVUE */
+ display: flex;
+ /* #endif */
+ flex-wrap: wrap;
+ flex-direction: row;
+}
+
+
+.col-12 { width: 750rpx;}
+.col-11 { width: 687.5rpx; }
+.col-10 { width: 625rpx; }
+.col-9 { width: 562.5rpx; }
+.col-8 { width: 500rpx; }
+.col-7 { width: 437.5rpx; }
+.col-6 { width: 375rpx; }
+.col-5 { width: 312.5rpx;}
+.col-4 {width: 250rpx;}
+.col-3 {width: 187.5rpx;}
+.col-2 {width: 125rpx;}
+
+
+.col-1 {width: 62.5rpx;}
+
+.col-offset-12 { margin-left: 750rpx;}
+.col-offset-11 { margin-left: 687.5rpx; }
+.col-offset-10 { margin-left: 625rpx; }
+.col-offset-9 { margin-left: 562.5rpx; }
+.col-offset-8 { margin-left: 500rpx; }
+.col-offset-7 { margin-left: 437.5rpx; }
+.col-offset-6 { margin-left: 375rpx; }
+.col-offset-5 { margin-left: 312.5rpx;}
+.col-offset-4 {margin-left: 250rpx;}
+.col-offset-3 {margin-left: 187.5rpx;}
+.col-offset-2 {margin-left: 125rpx;}
+.col-offset-1 {margin-left: 62.5rpx;}
+.col-offset-0 {margin-left: 0;}
+
+/* flex 布局 */
+.flex{
+ /* #ifndef APP-PLUS-NVUE */
+ display:flex!important;
+ /* #endif */
+ flex-direction:row;
+}
+.flex-row{ flex-direction:row!important; }
+.flex-column{ flex-direction:column!important; }
+.flex-row-reverse{ flex-direction:row-reverse!important; }
+.flex-column-reverse{ flex-direction:column-reverse!important; }
+.flex-wrap{ flex-wrap:wrap;}
+.flex-nowrap{ flex-wrap:nowrap;}
+.justify-start{justify-content:flex-start;}
+.justify-end{justify-content:flex-end;}
+.justify-between{justify-content:space-between;}
+.justify-center{justify-content:center;}
+.align-center{ align-items: center; }
+.align-stretch{ align-items: stretch; }
+.align-start{ align-items: flex-start; }
+.align-end{ align-items: flex-end; }
+/* #ifndef APP-PLUS-NVUE */
+.content-start {align-content: flex-start;}
+.content-end {align-content: flex-end;}
+.content-center {align-content: center;}
+.content-between {align-content: space-between;}
+.content-around {align-content: space-around;}
+.content-stretch {align-content: stretch;}
+/* #endif */
+.flex-1{ flex: 1; }
+.flex-2{ flex: 2; }
+.flex-3{ flex: 3; }
+.flex-4{ flex: 4; }
+.flex-5{ flex: 5; }
+/* #ifndef APP-PLUS-NVUE */
+.flex-shrink{ flex-shrink: 0; }
+/* #endif */
+
+.containerx {
+ padding-right: 20rpx;
+ padding-left: 20rpx;
+}
+/* -- 内外边距 -- */
+.m-0 { margin: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.m-auto{ margin: auto; }
+/* #endif */
+.m-1 { margin: 10rpx; }
+.m-2 { margin: 20rpx; }
+.m-3 { margin: 30rpx; }
+.m-4 { margin: 40rpx; }
+.m-5 { margin: 50rpx; }
+.mt-0 { margin-top: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.mt-auto { margin-top: auto; }
+/* #endif */
+.mt-1 { margin-top: 10rpx; }
+.mt-2 { margin-top: 20rpx; }
+.mt-3 { margin-top: 30rpx; }
+.mt-4 { margin-top: 40rpx; }
+.mt-5 { margin-top: 50rpx; }
+.mb-0 { margin-bottom: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.mb-auto { margin-bottom: auto; }
+/* #endif */
+.mb-1 { margin-bottom: 10rpx; }
+.mb-2 { margin-bottom: 20rpx; }
+.mb-3 { margin-bottom: 30rpx; }
+.mb-4 { margin-bottom: 40rpx; }
+.mb-5 { margin-bottom: 50rpx; }
+.mb-6 { margin-bottom: 60rpx; }
+.mb-7 { margin-bottom: 70rpx; }
+.ml-0 { margin-left: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.ml-auto { margin-left: auto; }
+/* #endif */
+.ml-1 { margin-left: 10rpx; }
+.ml-2 { margin-left: 20rpx; }
+.ml-3 { margin-left: 30rpx; }
+.ml-4 { margin-left: 40rpx; }
+.ml-5 { margin-left: 50rpx; }
+.mr-0 { margin-right: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.mr-auto { margin-right: auto; }
+/* #endif */
+.mr-1 { margin-right: 10rpx; }
+.mr-2 { margin-right: 20rpx; }
+.mr-3 { margin-right: 30rpx; }
+.mr-4 { margin-right: 40rpx; }
+.mr-5 { margin-right: 50rpx; }
+.my-0 { margin-top: 0; margin-bottom: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.my-auto { margin-top: auto; margin-bottom: auto; }
+/* #endif */
+.my-1 { margin-top: 10rpx; margin-bottom: 10rpx; }
+.my-2 { margin-top: 20rpx; margin-bottom: 20rpx; }
+.my-3 { margin-top: 30rpx; margin-bottom: 30rpx; }
+.my-4 { margin-top: 40rpx; margin-bottom: 40rpx; }
+.my-5 { margin-top: 50rpx; margin-bottom: 50rpx; }
+.mx-0 { margin-left: 0; margin-right: 0; }
+/* #ifndef APP-PLUS-NVUE */
+.mx-auto { margin-left: auto; margin-right: auto; }
+/* #endif */
+.mx-1 { margin-left: 10rpx; margin-right: 10rpx;}
+.mx-2 { margin-left: 20rpx; margin-right: 20rpx;}
+.mx-3 { margin-left: 30rpx; margin-right: 30rpx;}
+.mx-4 { margin-left: 40rpx; margin-right: 40rpx;}
+.mx-5 { margin-left: 50rpx; margin-right: 50rpx;}
+
+.p-0 { padding: 0; }
+.p { padding: 5rpx; }
+.p-1 { padding: 10rpx; }
+.p-2 { padding: 20rpx; }
+.p-3 { padding: 30rpx; }
+.p-4 { padding: 40rpx; }
+.p-5 { padding: 50rpx; }
+.pt-0 { padding-top: 0; }
+.pt { padding-top: 5rpx; }
+.pt-1 { padding-top: 10rpx; }
+.pt-2 { padding-top: 20rpx; }
+.pt-3 { padding-top: 30rpx; }
+.pt-4 { padding-top: 40rpx; }
+.pt-5 { padding-top: 50rpx; }
+.pb-0 { padding-bottom: 0; }
+.pb-1 { padding-bottom: 10rpx; }
+.pb { padding-bottom: 5rpx; }
+.pb-2 { padding-bottom: 20rpx; }
+.pb-3 { padding-bottom: 30rpx; }
+.pb-4 { padding-bottom: 40rpx; }
+.pb-5 { padding-bottom: 50rpx; }
+.pl-0 { padding-left: 0; }
+.pl { padding-left: 5rpx; }
+.pl-1 { padding-left: 10rpx; }
+.pl-2 { padding-left: 20rpx; }
+.pl-3 { padding-left: 30rpx; }
+.pl-4 { padding-left: 40rpx; }
+.pl-5 { padding-left: 50rpx; }
+.pl-9 { padding-left: 90rpx; }
+.pr-0 { padding-right: 0; }
+.pr { padding-right: 5rpx; }
+.pr-1 { padding-right: 10rpx; }
+.pr-2 { padding-right: 20rpx; }
+.pr-3 { padding-right: 30rpx; }
+.pr-4 { padding-right: 40rpx; }
+.pr-5 { padding-right: 50rpx; }
+.py-0 { padding-top: 0; padding-bottom: 0; }
+.py { padding-top: 5rpx; padding-bottom: 5rpx; }
+.py-1 { padding-top: 10rpx; padding-bottom: 10rpx; }
+.py-2 { padding-top: 20rpx; padding-bottom: 20rpx; }
+.py-25{padding-top: 25rpx; padding-bottom: 25rpx;}
+.py-3 { padding-top: 30rpx; padding-bottom: 30rpx; }
+.py-4 { padding-top: 40rpx; padding-bottom: 40rpx; }
+.py-5 { padding-top: 50rpx; padding-bottom: 50rpx; }
+.px-0 { padding-left: 0; padding-right: 0; }
+.px-1 { padding-left: 10rpx; padding-right: 10rpx;}
+.px { padding-left: 5rpx; padding-right: 5rpx;}
+.px-2 { padding-left: 20rpx; padding-right: 20rpx;}
+.px-3 { padding-left: 30rpx; padding-right: 30rpx;}
+.px-4 { padding-left: 40rpx; padding-right: 40rpx;}
+.px-5 { padding-left: 50rpx; padding-right: 50rpx;}
+
+.font16{font-size: 16rpx!important;}
+.font18{font-size: 18rpx!important;}
+.font20{font-size: 20rpx!important;}
+.font22{font-size: 22rpx!important;}
+.font24{font-size: 24rpx!important;}
+.font26{font-size: 26rpx!important;}
+.font28{font-size: 28rpx!important;}
+.font30{font-size: 30rpx!important;}
+.font32{font-size: 32rpx!important;}
+.font34{font-size: 34rpx!important;}
+.font36{font-size: 36rpx!important;}
+.font38{font-size: 38rpx!important;}
+.font40{font-size: 40rpx!important;}
+.font50{font-size: 50rpx!important;}
+.font60{font-size: 60rpx!important;}
+/* 文字缩进 */
+/* #ifndef APP-PLUS-NVUE */
+.text-indent{text-indent:2;}
+.line15{line-height: 1.5;}
+.line2{line-height: 1.8;}
+/* #endif */
+/* 文字划线 */
+.text-through{text-decoration:line-through;}
+/* 文字对齐 */
+.text-left { text-align: left;}
+.text-right { text-align: right;}
+.text-center { text-align: center;}
+/* 文字换行溢出处理 */
+.text-ellipsis {
+ /* #ifndef APP-PLUS-NVUE */
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ /* #endif */
+ /* #ifdef APP-PLUS-NVUE */
+ lines: 1;
+ /* #endif */
+}
+.text-ellipsis-1 {
+ /* #ifndef APP-PLUS-NVUE */
+ text-overflow: -o-ellipsis-lastline;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ line-clamp: 1;
+ -webkit-box-orient: vertical;
+ /* #endif */
+}
+
+
+ .text-ellipsis-2 {
+ /* #ifndef APP-PLUS-NVUE */
+ text-overflow: -o-ellipsis-lastline;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ line-clamp: 2;
+ -webkit-box-orient: vertical;
+ /* #endif */}
+/* 文字粗细和斜体 */
+.font-weight-light {font-weight: 300;} /*细*/
+.font-weight-lighter {font-weight: 100;}/*更细*/
+.font-weight-normal { font-weight: 400;} /*正常*/
+.font-weight-bold { font-weight: 700;} /*粗*/
+.font-weight-bolder { font-weight: bold;} /*更粗*/
+.font-italic { font-style: italic;} /*斜体*/
+/* 文字颜色 */
+.text-white {color: #ffffff;}
+.text-primary {color: #2979ff;}
+.text-hover-primary { color: #94bcff;}
+.text-secondary {color: #6c757d;}
+.text-hover-secondary { color: #494f54;}
+.text-success {color: #18bc37;}
+.text-hover-success{color: #8cde9b;}
+.text-info { color: #8f939c;}
+.text-hover-info {color: #c7c9ce;}
+.text-warning {color: #ffc107;}
+.text-hover-warning { color: #f9d39f;}
+.text-danger { color: #e43d33 ;}
+.text-hover-danger { color: #f29e99;}
+.text-light { color: #e9e9eb;}
+.text-hover-light { color: #cbd3da;}
+.text-dark { color: #343a40;}
+.text-hover-dark{ color: #8f939c;}
+.text-body { color: #000000;}
+.text-muted { color: #979797;}
+/* 浅灰色 */
+.text-light-muted { color: #A9A5A0;}
+.text-light-black { color: rgba(0, 0, 0, 0.5);}
+.text-light-white { color: rgba(255, 255, 255, 0.5);}
+
+/* 背景颜色 */
+
+.bg-primary { background-color: #2979ff;}
+.bg-hover-primary:hover{ background-color: #94bcff;}
+.bg-secondary { background-color: #6c757d;}
+.bg-hover-secondary:hover{ background-color: #545b62;}
+.bg-success { background-color: #18bc37;}
+.bg-hover-success { background-color: #8cde9b;}
+.bg-info { background-color: #8f939c;}
+.bg-hover-info { background-color: #c7c9ce;}
+.bg-warning { background-color: #f3a73f;}
+.bg-hover-warning { background-color: #f9d39f;}
+.bg-danger { background-color: #e43d33 ;}
+.bg-hover-danger{ background-color: #f29e99;}
+.bg-light { background-color: #e9e9eb;}
+.bg-hover-light{ background-color: #f1f1f1;}
+.bg-dark { background-color: #333333;}
+.bg-hover-dark { background-color: #1d2124;}
+.bg-white { background-color: #ffffff;}
+.bg-transparent { background-color: transparent;}
+/* 边框 */
+.border { border-width: 1rpx;border-style: solid;border-color: #dee2e6;}
+.border-top {
+ border-top-width: 1rpx;
+ border-top-style: solid;
+ border-top-color: #dee2e6;
+}
+.border-right {
+ border-right-width: 1rpx;
+ border-right-style: solid;
+ border-right-color: #dee2e6;
+}
+.border-bottom {
+ border-bottom-width: 1rpx;
+ border-bottom-style: solid;
+ border-bottom-color: #dee2e6;
+}
+.border-left {
+ border-left-width: 1rpx;
+ border-left-style: solid;
+ border-left-color: #dee2e6;
+}
+.border-dotted-bottom {
+ border-bottom-width: 1rpx;
+ border-bottom-style: dotted;
+ border-bottom-color: #dee2e6;
+}
+.border-0 { border-width: 0!important;}
+.border-top-0 { border-top-width: 0!important;}
+.border-right-0 {border-right-width: 0!important;}
+.border-bottom-0 {border-bottom-width: 0!important;}
+.border-left-0 {border-left-width: 0!important;}
+.border-primary { border-color: #2979ff;}
+.border-secondary {border-color: #6c757d;}
+.border-light-secondary {border-color: #E9E8E5;}
+.border-success {border-color: #18bc37;}
+.border-info {border-color: #8f939c;}
+.border-warning {border-color: #f3a73f;}
+.border-danger {border-color:#e43d33 ;}
+.border-light {border-color: #e9e9eb;}
+.border-dark {border-color: #343a40;}
+.border-white {border-color: #FFFFFF;}
+
+
+/* 圆角 */
+.rounded { border-radius: 8rpx;}
+.rounded-lg { border-radius: 14rpx;}
+.rounded-top {
+ border-top-left-radius: 8rpx;
+ border-top-right-radius: 8rpx;
+}
+.rounded-top-lg {
+ border-top-left-radius: 14rpx;
+ border-top-right-radius: 14rpx;
+}
+.rounded-right {
+ border-top-right-radius: 8rpx;
+ border-bottom-right-radius: 8rpx;
+}
+.rounded-bottom {
+ border-bottom-right-radius: 8rpx;
+ border-bottom-left-radius: 8rpx;
+}
+.rounded-bottom-lg {
+ border-bottom-right-radius: 14rpx;
+ border-bottom-left-radius: 14rpx;
+}
+.rounded-left {
+ border-top-left-radius: 8rpx;
+ border-bottom-left-radius: 8rpx;
+ }
+.rounded-circle { border-radius: 100rpx;}
+.rounded-circle-left { border-radius: 100rpx 0 0 100rpx;}
+.rounded-circle-right { border-radius:0 100rpx 100rpx 0 ;}
+.rounded-0 { border-radius: 0;}
+/* 显示 */
+/* #ifndef APP-PLUS-NVUE */
+.d-none{ display: none; }
+.d-inline-block{ display: inline-block; }
+.d-block{ display: block; }
+/* #endif */
+/* 内容溢出 */
+.overflow-hidden { overflow: hidden;}
+/* 定位 */
+.position-relative { position: relative;}
+.position-absolute { position: absolute;}
+.position-fixed { position: fixed;}
+.position-sticky{position: sticky;top: 0; z-index: 1000;}
+/* 定位 - 固定顶部 */
+.fixed-top {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+/* 定位 - 固定底部 */
+.fixed-bottom {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 3;
+}
+.top-0 { top: 0; }
+.left-0 { left: 0; }
+.right-0 { right: 0; }
+.bottom-0 { bottom: 0; }
+
+/* 阴影 */
+/* #ifndef APP-PLUS-NVUE */
+.shadow { box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.15);}
+.shadow-lg { box-shadow: 0rpx 40rpx 100rpx 0rpx rgba(0, 0, 0, 0.175);}
+.shadow-none { box-shadow: none !important;}
+/* #endif */
+.cu-tabbar-height {height: 110upx;}
+.cny::before {content: "¥";font-size: 60%;margin-right: 10rpx;}
+.cny_jf::before {content: "积分";font-size: 60%;margin-right: 10rpx;}
+.opacity9{opacity: 0.9;}
\ No newline at end of file
diff --git a/common/html-parser.js b/common/html-parser.js
new file mode 100644
index 0000000..20a89b2
--- /dev/null
+++ b/common/html-parser.js
@@ -0,0 +1,352 @@
+/*
+ * HTML5 Parser By Sam Blowes
+ *
+ * Designed for HTML5 documents
+ *
+ * Original code by John Resig (ejohn.org)
+ * http://ejohn.org/blog/pure-javascript-html-parser/
+ * Original code by Erik Arvidsson, Mozilla Public License
+ * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+ *
+ * ----------------------------------------------------------------------------
+ * License
+ * ----------------------------------------------------------------------------
+ *
+ * This code is triple licensed using Apache Software License 2.0,
+ * Mozilla Public License or GNU Public License
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is Simple HTML Parser.
+ *
+ * The Initial Developer of the Original Code is Erik Arvidsson.
+ * Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
+ * Reserved.
+ *
+ * ////////////////////////////////////////////////////////////////////////////
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ----------------------------------------------------------------------------
+ * Usage
+ * ----------------------------------------------------------------------------
+ *
+ * // Use like so:
+ * HTMLParser(htmlString, {
+ * start: function(tag, attrs, unary) {},
+ * end: function(tag) {},
+ * chars: function(text) {},
+ * comment: function(text) {}
+ * });
+ *
+ * // or to get an XML string:
+ * HTMLtoXML(htmlString);
+ *
+ * // or to get an XML DOM Document
+ * HTMLtoDOM(htmlString);
+ *
+ * // or to inject into an existing document/DOM node
+ * HTMLtoDOM(htmlString, document);
+ * HTMLtoDOM(htmlString, document.body);
+ *
+ */
+// Regular Expressions for parsing tags and attributes
+var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
+var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
+var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
+
+var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
+// fixed by xxx 将 ins 标签从块级名单中移除
+
+var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
+
+var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
+// (and which close themselves)
+
+var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
+
+var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
+
+var special = makeMap('script,style');
+function HTMLParser(html, handler) {
+ var index;
+ var chars;
+ var match;
+ var stack = [];
+ var last = html;
+
+ stack.last = function () {
+ return this[this.length - 1];
+ };
+
+ while (html) {
+ chars = true; // Make sure we're not in a script or style element
+
+ if (!stack.last() || !special[stack.last()]) {
+ // Comment
+ if (html.indexOf('');
+
+ if (index >= 0) {
+ if (handler.comment) {
+ handler.comment(html.substring(4, index));
+ }
+
+ html = html.substring(index + 3);
+ chars = false;
+ } // end tag
+
+ } else if (html.indexOf('') == 0) {
+ match = html.match(endTag);
+
+ if (match) {
+ html = html.substring(match[0].length);
+ match[0].replace(endTag, parseEndTag);
+ chars = false;
+ } // start tag
+
+ } else if (html.indexOf('<') == 0) {
+ match = html.match(startTag);
+
+ if (match) {
+ html = html.substring(match[0].length);
+ match[0].replace(startTag, parseStartTag);
+ chars = false;
+ }
+ }
+
+ if (chars) {
+ index = html.indexOf('<');
+ var text = index < 0 ? html : html.substring(0, index);
+ html = index < 0 ? '' : html.substring(index);
+
+ if (handler.chars) {
+ handler.chars(text);
+ }
+ }
+ } else {
+ html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
+ text = text.replace(/|/g, '$1$2');
+
+ if (handler.chars) {
+ handler.chars(text);
+ }
+
+ return '';
+ });
+ parseEndTag('', stack.last());
+ }
+
+ if (html == last) {
+ throw 'Parse Error: ' + html;
+ }
+
+ last = html;
+ } // Clean up any remaining tags
+
+
+ parseEndTag();
+
+ function parseStartTag(tag, tagName, rest, unary) {
+ tagName = tagName.toLowerCase();
+
+ if (block[tagName]) {
+ while (stack.last() && inline[stack.last()]) {
+ parseEndTag('', stack.last());
+ }
+ }
+
+ if (closeSelf[tagName] && stack.last() == tagName) {
+ parseEndTag('', tagName);
+ }
+
+ unary = empty[tagName] || !!unary;
+
+ if (!unary) {
+ stack.push(tagName);
+ }
+
+ if (handler.start) {
+ var attrs = [];
+ rest.replace(attr, function (match, name) {
+ var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
+ attrs.push({
+ name: name,
+ value: value,
+ escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
+
+ });
+ });
+
+ if (handler.start) {
+ handler.start(tagName, attrs, unary);
+ }
+ }
+ }
+
+ function parseEndTag(tag, tagName) {
+ // If no tag name is provided, clean shop
+ if (!tagName) {
+ var pos = 0;
+ } // Find the closest opened tag of the same type
+ else {
+ for (var pos = stack.length - 1; pos >= 0; pos--) {
+ if (stack[pos] == tagName) {
+ break;
+ }
+ }
+ }
+
+ if (pos >= 0) {
+ // Close all the open elements, up the stack
+ for (var i = stack.length - 1; i >= pos; i--) {
+ if (handler.end) {
+ handler.end(stack[i]);
+ }
+ } // Remove the open elements from the stack
+
+
+ stack.length = pos;
+ }
+ }
+}
+
+function makeMap(str) {
+ var obj = {};
+ var items = str.split(',');
+
+ for (var i = 0; i < items.length; i++) {
+ obj[items[i]] = true;
+ }
+
+ return obj;
+}
+
+function removeDOCTYPE(html) {
+ return html.replace(/<\?xml.*\?>\n/, '').replace(/\n/, '').replace(/\n/, '');
+}
+
+function parseAttrs(attrs) {
+ return attrs.reduce(function (pre, attr) {
+ var value = attr.value;
+ var name = attr.name;
+
+ if (pre[name]) {
+ pre[name] = pre[name] + " " + value;
+ } else {
+ pre[name] = value;
+ }
+
+ return pre;
+ }, {});
+}
+
+function parseHtml(html) {
+ html = removeDOCTYPE(html);
+ var stacks = [];
+ var results = {
+ node: 'root',
+ children: []
+ };
+ HTMLParser(html, {
+ start: function start(tag, attrs, unary) {
+ var node = {
+ name: tag
+ };
+
+ if (attrs.length !== 0) {
+ node.attrs = parseAttrs(attrs);
+ }
+
+ if (unary) {
+ var parent = stacks[0] || results;
+
+ if (!parent.children) {
+ parent.children = [];
+ }
+
+ parent.children.push(node);
+ } else {
+ stacks.unshift(node);
+ }
+ },
+ end: function end(tag) {
+ var node = stacks.shift();
+ if (node.name !== tag) console.error('invalid state: mismatch end tag');
+
+ if (stacks.length === 0) {
+ results.children.push(node);
+ } else {
+ var parent = stacks[0];
+
+ if (!parent.children) {
+ parent.children = [];
+ }
+
+ parent.children.push(node);
+ }
+ },
+ chars: function chars(text) {
+ var node = {
+ type: 'text',
+ text: text
+ };
+
+ if (stacks.length === 0) {
+ results.children.push(node);
+ } else {
+ var parent = stacks[0];
+
+ if (!parent.children) {
+ parent.children = [];
+ }
+
+ parent.children.push(node);
+ }
+ },
+ comment: function comment(text) {
+ var node = {
+ node: 'comment',
+ text: text
+ };
+ var parent = stacks[0];
+
+ if (!parent.children) {
+ parent.children = [];
+ }
+
+ parent.children.push(node);
+ }
+ });
+ return results.children;
+}
+
+export default parseHtml;
diff --git a/common/image.js b/common/image.js
new file mode 100644
index 0000000..66ad9e3
--- /dev/null
+++ b/common/image.js
@@ -0,0 +1,76 @@
+// 读取图片 Base64 内容
+export function TaImageToBase64(file, maxw = 500) {
+ return new Promise((resolve, reject) => {
+ if (uni.compressImage) {
+ uni.compressImage({
+ src: file,
+ quality: 80,
+ width: maxw + "px",
+ fail: err => reject(err),
+ success: res =>
+ readFileAsBase64(res.tempFilePath)
+ .then(resolve)
+ .catch(reject)
+ })
+ } else {
+ let img = new Image();
+ (img.crossOrigin = "Anonymous"),
+ (img.onload = () => {
+ let c = document.createElement("canvas")
+ let w = img.naturalWidth,
+ h = img.naturalHeight;
+ (c.width = Math.min(maxw, w)), (c.height = c.width * (h / w))
+ // @ts-ignore
+ c.getContext("2d").drawImage(img, 0, 0, c.width, c.height)
+ resolve(c.toDataURL("image/jpeg", 0.8))
+ }),
+ (img.src = file),
+ (img.onerror = () => reject(new Error("Failed to load image")))
+ }
+ })
+
+ // 读取文件为 base64 格式
+ function readFileAsBase64(file) {
+ return new Promise((resolve, reject) => {
+ let rd = new plus.io.FileReader()
+ rd.onerror = e => reject(e)
+ rd.onloadend = v => resolve(v.target.result)
+ // @ts-ignore
+ rd.readAsDataURL(plus.io.convertLocalFileSystemURL(file))
+ })
+ }
+}
+
+// 下载图片到本地
+export function TaImageDownload(imgUrl, name = "") {
+ return new Promise((resolve, reject) => {
+ // #ifdef H5
+ const link = document.createElement("a")
+ link.href = imgUrl
+ link.download =
+ name ||
+ Math.random()
+ .toString()
+ .replace("0.", "img") + `.png`
+ link.style.display = "none"
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ resolve(true)
+ // #endif
+
+ // #ifndef H5
+ uni.downloadFile({
+ url: imgUrl,
+ success: ret => {
+ if (ret.statusCode === 200)
+ uni.saveImageToPhotosAlbum({
+ filePath: ret.tempFilePath,
+ fail: err => TaToast.error("保存失败!", err).then(reject),
+ success: () => TaToast.success("保存成功!").then(resolve)
+ })
+ }
+ })
+ // #endif
+ })
+}
\ No newline at end of file
diff --git a/common/qqmap-wx-jssdk.js b/common/qqmap-wx-jssdk.js
new file mode 100644
index 0000000..595b65b
--- /dev/null
+++ b/common/qqmap-wx-jssdk.js
@@ -0,0 +1,1122 @@
+/**
+ * 微信小程序JavaScriptSDK
+ *
+ * @version 1.2
+ * @date 2019-03-06
+ */
+
+var ERROR_CONF = {
+ KEY_ERR: 311,
+ KEY_ERR_MSG: 'key格式错误',
+ PARAM_ERR: 310,
+ PARAM_ERR_MSG: '请求参数信息有误',
+ SYSTEM_ERR: 600,
+ SYSTEM_ERR_MSG: '系统错误',
+ WX_ERR_CODE: 1000,
+ WX_OK_CODE: 200
+};
+var BASE_URL = 'https://apis.map.qq.com/ws/';
+var URL_SEARCH = BASE_URL + 'place/v1/search';
+var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
+var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
+var URL_CITY_LIST = BASE_URL + 'district/v1/list';
+var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
+var URL_DISTANCE = BASE_URL + 'distance/v1/';
+var URL_DIRECTION = BASE_URL + 'direction/v1/';
+var MODE = {
+ driving: 'driving',
+ transit: 'transit'
+};
+var EARTH_RADIUS = 6378136.49;
+var Utils = {
+ /**
+ * md5加密方法
+ * 版权所有©2011 Sebastian Tschan,https://blueimp.net
+ */
+ safeAdd(x, y) {
+ var lsw = (x & 0xffff) + (y & 0xffff);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xffff);
+ },
+ bitRotateLeft(num, cnt) {
+ return (num << cnt) | (num >>> (32 - cnt));
+ },
+ md5cmn(q, a, b, x, s, t) {
+ return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b);
+ },
+ md5ff(a, b, c, d, x, s, t) {
+ return this.md5cmn((b & c) | (~b & d), a, b, x, s, t);
+ },
+ md5gg(a, b, c, d, x, s, t) {
+ return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t);
+ },
+ md5hh(a, b, c, d, x, s, t) {
+ return this.md5cmn(b ^ c ^ d, a, b, x, s, t);
+ },
+ md5ii(a, b, c, d, x, s, t) {
+ return this.md5cmn(c ^ (b | ~d), a, b, x, s, t);
+ },
+ binlMD5(x, len) {
+ /* append padding */
+ x[len >> 5] |= 0x80 << (len % 32);
+ x[((len + 64) >>> 9 << 4) + 14] = len;
+
+ var i;
+ var olda;
+ var oldb;
+ var oldc;
+ var oldd;
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for (i = 0; i < x.length; i += 16) {
+ olda = a;
+ oldb = b;
+ oldc = c;
+ oldd = d;
+
+ a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
+ d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
+ c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
+ b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
+ a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
+ d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
+ c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
+ b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
+ a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
+ d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
+ c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
+ b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
+ a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
+ d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
+ c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
+ b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+ a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
+ d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
+ c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
+ b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
+ a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
+ d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
+ c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
+ b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
+ a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
+ d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
+ c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
+ b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
+ a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
+ d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
+ c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
+ b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+ a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
+ d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
+ c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
+ b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
+ a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
+ d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
+ c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
+ b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
+ a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
+ d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
+ c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
+ b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
+ a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
+ d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
+ c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
+ b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+ a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
+ d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
+ c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
+ b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
+ a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
+ d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
+ c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
+ b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
+ a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
+ d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
+ c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
+ b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
+ a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
+ d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
+ c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
+ b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+ a = this.safeAdd(a, olda);
+ b = this.safeAdd(b, oldb);
+ c = this.safeAdd(c, oldc);
+ d = this.safeAdd(d, oldd);
+ }
+ return [a, b, c, d];
+ },
+ binl2rstr(input) {
+ var i;
+ var output = '';
+ var length32 = input.length * 32;
+ for (i = 0; i < length32; i += 8) {
+ output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
+ }
+ return output;
+ },
+ rstr2binl(input) {
+ var i;
+ var output = [];
+ output[(input.length >> 2) - 1] = undefined;
+ for (i = 0; i < output.length; i += 1) {
+ output[i] = 0;
+ }
+ var length8 = input.length * 8;
+ for (i = 0; i < length8; i += 8) {
+ output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
+ }
+ return output;
+ },
+ rstrMD5(s) {
+ return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8));
+ },
+ rstrHMACMD5(key, data) {
+ var i;
+ var bkey = this.rstr2binl(key);
+ var ipad = [];
+ var opad = [];
+ var hash;
+ ipad[15] = opad[15] = undefined;
+ if (bkey.length > 16) {
+ bkey = this.binlMD5(bkey, key.length * 8);
+ }
+ for (i = 0; i < 16; i += 1) {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5c5c5c5c;
+ }
+ hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
+ return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128));
+ },
+ rstr2hex(input) {
+ var hexTab = '0123456789abcdef';
+ var output = '';
+ var x;
+ var i;
+ for (i = 0; i < input.length; i += 1) {
+ x = input.charCodeAt(i);
+ output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
+ }
+ return output;
+ },
+ str2rstrUTF8(input) {
+ return unescape(encodeURIComponent(input));
+ },
+ rawMD5(s) {
+ return this.rstrMD5(this.str2rstrUTF8(s));
+ },
+ hexMD5(s) {
+ return this.rstr2hex(this.rawMD5(s));
+ },
+ rawHMACMD5(k, d) {
+ return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d));
+ },
+ hexHMACMD5(k, d) {
+ return this.rstr2hex(this.rawHMACMD5(k, d));
+ },
+
+ md5(string, key, raw) {
+ if (!key) {
+ if (!raw) {
+ return this.hexMD5(string);
+ }
+ return this.rawMD5(string);
+ }
+ if (!raw) {
+ return this.hexHMACMD5(key, string);
+ }
+ return this.rawHMACMD5(key, string);
+ },
+ /**
+ * 得到md5加密后的sig参数
+ * @param {Object} requestParam 接口参数
+ * @param {String} sk签名字符串
+ * @param {String} featrue 方法名
+ * @return 返回加密后的sig参数
+ */
+ getSig(requestParam, sk, feature, mode) {
+ var sig = null;
+ var requestArr = [];
+ Object.keys(requestParam).sort().forEach(function(key){
+ requestArr.push(key + '=' + requestParam[key]);
+ });
+ if (feature == 'search') {
+ sig = '/ws/place/v1/search?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'suggest') {
+ sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'reverseGeocoder') {
+ sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'geocoder') {
+ sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'getCityList') {
+ sig = '/ws/district/v1/list?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'getDistrictByCityId') {
+ sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'calculateDistance') {
+ sig = '/ws/distance/v1/?' + requestArr.join('&') + sk;
+ }
+ if (feature == 'direction') {
+ sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk;
+ }
+ sig = this.md5(sig);
+ return sig;
+ },
+ /**
+ * 得到终点query字符串
+ * @param {Array|String} 检索数据
+ */
+ location2query(data) {
+ if (typeof data == 'string') {
+ return data;
+ }
+ var query = '';
+ for (var i = 0; i < data.length; i++) {
+ var d = data[i];
+ if (!!query) {
+ query += ';';
+ }
+ if (d.location) {
+ query = query + d.location.lat + ',' + d.location.lng;
+ }
+ if (d.latitude && d.longitude) {
+ query = query + d.latitude + ',' + d.longitude;
+ }
+ }
+ return query;
+ },
+
+ /**
+ * 计算角度
+ */
+ rad(d) {
+ return d * Math.PI / 180.0;
+ },
+ /**
+ * 处理终点location数组
+ * @return 返回终点数组
+ */
+ getEndLocation(location){
+ var to = location.split(';');
+ var endLocation = [];
+ for (var i = 0; i < to.length; i++) {
+ endLocation.push({
+ lat: parseFloat(to[i].split(',')[0]),
+ lng: parseFloat(to[i].split(',')[1])
+ })
+ }
+ return endLocation;
+ },
+
+ /**
+ * 计算两点间直线距离
+ * @param a 表示纬度差
+ * @param b 表示经度差
+ * @return 返回的是距离,单位m
+ */
+ getDistance(latFrom, lngFrom, latTo, lngTo) {
+ var radLatFrom = this.rad(latFrom);
+ var radLatTo = this.rad(latTo);
+ var a = radLatFrom - radLatTo;
+ var b = this.rad(lngFrom) - this.rad(lngTo);
+ var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
+ distance = distance * EARTH_RADIUS;
+ distance = Math.round(distance * 10000) / 10000;
+ return parseFloat(distance.toFixed(0));
+ },
+ /**
+ * 使用微信接口进行定位
+ */
+ getWXLocation(success, fail, complete) {
+ wx.getLocation({
+ type: 'gcj02',
+ success: success,
+ fail: fail,
+ complete: complete
+ });
+ },
+
+ /**
+ * 获取location参数
+ */
+ getLocationParam(location) {
+ if (typeof location == 'string') {
+ var locationArr = location.split(',');
+ if (locationArr.length === 2) {
+ location = {
+ latitude: location.split(',')[0],
+ longitude: location.split(',')[1]
+ };
+ } else {
+ location = {};
+ }
+ }
+ return location;
+ },
+
+ /**
+ * 回调函数默认处理
+ */
+ polyfillParam(param) {
+ param.success = param.success || function () { };
+ param.fail = param.fail || function () { };
+ param.complete = param.complete || function () { };
+ },
+
+ /**
+ * 验证param对应的key值是否为空
+ *
+ * @param {Object} param 接口参数
+ * @param {String} key 对应参数的key
+ */
+ checkParamKeyEmpty(param, key) {
+ if (!param[key]) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * 验证参数中是否存在检索词keyword
+ *
+ * @param {Object} param 接口参数
+ */
+ checkKeyword(param){
+ return !this.checkParamKeyEmpty(param, 'keyword');
+ },
+
+ /**
+ * 验证location值
+ *
+ * @param {Object} param 接口参数
+ */
+ checkLocation(param) {
+ var location = this.getLocationParam(param.location);
+ if (!location || !location.latitude || !location.longitude) {
+ var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误');
+ param.fail(errconf);
+ param.complete(errconf);
+ return false;
+ }
+ return true;
+ },
+
+ /**
+ * 构造错误数据结构
+ * @param {Number} errCode 错误码
+ * @param {Number} errMsg 错误描述
+ */
+ buildErrorConfig(errCode, errMsg) {
+ return {
+ status: errCode,
+ message: errMsg
+ };
+ },
+
+ /**
+ *
+ * 数据处理函数
+ * 根据传入参数不同处理不同数据
+ * @param {String} feature 功能名称
+ * search 地点搜索
+ * suggest关键词提示
+ * reverseGeocoder逆地址解析
+ * geocoder地址解析
+ * getCityList获取城市列表:父集
+ * getDistrictByCityId获取区县列表:子集
+ * calculateDistance距离计算
+ * @param {Object} param 接口参数
+ * @param {Object} data 数据
+ */
+ handleData(param,data,feature){
+ if (feature == 'search') {
+ var searchResult = data.data;
+ var searchSimplify = [];
+ for (var i = 0; i < searchResult.length; i++) {
+ searchSimplify.push({
+ id: searchResult[i].id || null,
+ title: searchResult[i].title || null,
+ latitude: searchResult[i].location && searchResult[i].location.lat || null,
+ longitude: searchResult[i].location && searchResult[i].location.lng || null,
+ address: searchResult[i].address || null,
+ category: searchResult[i].category || null,
+ tel: searchResult[i].tel || null,
+ adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
+ city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
+ district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
+ province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
+ })
+ }
+ param.success(data, {
+ searchResult: searchResult,
+ searchSimplify: searchSimplify
+ })
+ } else if (feature == 'suggest') {
+ var suggestResult = data.data;
+ var suggestSimplify = [];
+ for (var i = 0; i < suggestResult.length; i++) {
+ suggestSimplify.push({
+ adcode: suggestResult[i].adcode || null,
+ address: suggestResult[i].address || null,
+ category: suggestResult[i].category || null,
+ city: suggestResult[i].city || null,
+ district: suggestResult[i].district || null,
+ id: suggestResult[i].id || null,
+ latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
+ longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
+ province: suggestResult[i].province || null,
+ title: suggestResult[i].title || null,
+ type: suggestResult[i].type || null
+ })
+ }
+ param.success(data, {
+ suggestResult: suggestResult,
+ suggestSimplify: suggestSimplify
+ })
+ } else if (feature == 'reverseGeocoder') {
+ var reverseGeocoderResult = data.result;
+ var reverseGeocoderSimplify = {
+ address: reverseGeocoderResult.address || null,
+ latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
+ longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
+ adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
+ city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
+ district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
+ nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
+ province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
+ street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
+ street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
+ recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
+ rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
+ };
+ if (reverseGeocoderResult.pois) {//判断是否返回周边poi
+ var pois = reverseGeocoderResult.pois;
+ var poisSimplify = [];
+ for (var i = 0;i < pois.length;i++) {
+ poisSimplify.push({
+ id: pois[i].id || null,
+ title: pois[i].title || null,
+ latitude: pois[i].location && pois[i].location.lat || null,
+ longitude: pois[i].location && pois[i].location.lng || null,
+ address: pois[i].address || null,
+ category: pois[i].category || null,
+ adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
+ city: pois[i].ad_info && pois[i].ad_info.city || null,
+ district: pois[i].ad_info && pois[i].ad_info.district || null,
+ province: pois[i].ad_info && pois[i].ad_info.province || null
+ })
+ }
+ param.success(data,{
+ reverseGeocoderResult: reverseGeocoderResult,
+ reverseGeocoderSimplify: reverseGeocoderSimplify,
+ pois: pois,
+ poisSimplify: poisSimplify
+ })
+ } else {
+ param.success(data, {
+ reverseGeocoderResult: reverseGeocoderResult,
+ reverseGeocoderSimplify: reverseGeocoderSimplify
+ })
+ }
+ } else if (feature == 'geocoder') {
+ var geocoderResult = data.result;
+ var geocoderSimplify = {
+ title: geocoderResult.title || null,
+ latitude: geocoderResult.location && geocoderResult.location.lat || null,
+ longitude: geocoderResult.location && geocoderResult.location.lng || null,
+ adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
+ province: geocoderResult.address_components && geocoderResult.address_components.province || null,
+ city: geocoderResult.address_components && geocoderResult.address_components.city || null,
+ district: geocoderResult.address_components && geocoderResult.address_components.district || null,
+ street: geocoderResult.address_components && geocoderResult.address_components.street || null,
+ street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
+ level: geocoderResult.level || null
+ };
+ param.success(data,{
+ geocoderResult: geocoderResult,
+ geocoderSimplify: geocoderSimplify
+ });
+ } else if (feature == 'getCityList') {
+ var provinceResult = data.result[0];
+ var cityResult = data.result[1];
+ var districtResult = data.result[2];
+ param.success(data,{
+ provinceResult: provinceResult,
+ cityResult: cityResult,
+ districtResult: districtResult
+ });
+ } else if (feature == 'getDistrictByCityId') {
+ var districtByCity = data.result[0];
+ param.success(data, districtByCity);
+ } else if (feature == 'calculateDistance') {
+ var calculateDistanceResult = data.result.elements;
+ var distance = [];
+ for (var i = 0; i < calculateDistanceResult.length; i++){
+ distance.push(calculateDistanceResult[i].distance);
+ }
+ param.success(data, {
+ calculateDistanceResult: calculateDistanceResult,
+ distance: distance
+ });
+ } else if (feature == 'direction') {
+ var direction = data.result.routes;
+ param.success(data,direction);
+ } else {
+ param.success(data);
+ }
+ },
+
+ /**
+ * 构造微信请求参数,公共属性处理
+ *
+ * @param {Object} param 接口参数
+ * @param {Object} param 配置项
+ * @param {String} feature 方法名
+ */
+ buildWxRequestConfig(param, options, feature) {
+ var that = this;
+ options.header = { "content-type": "application/json" };
+ options.method = 'GET';
+ options.success = function (res) {
+ var data = res.data;
+ if (data.status === 0) {
+ that.handleData(param, data, feature);
+ } else {
+ param.fail(data);
+ }
+ };
+ options.fail = function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ options.complete = function (res) {
+ var statusCode = +res.statusCode;
+ switch(statusCode) {
+ case ERROR_CONF.WX_ERR_CODE: {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ break;
+ }
+ case ERROR_CONF.WX_OK_CODE: {
+ var data = res.data;
+ if (data.status === 0) {
+ param.complete(data);
+ } else {
+ param.complete(that.buildErrorConfig(data.status, data.message));
+ }
+ break;
+ }
+ default:{
+ param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
+ }
+
+ }
+ };
+ return options;
+ },
+
+ /**
+ * 处理用户参数是否传入坐标进行不同的处理
+ */
+ locationProcess(param, locationsuccess, locationfail, locationcomplete) {
+ var that = this;
+ locationfail = locationfail || function (res) {
+ res.statusCode = ERROR_CONF.WX_ERR_CODE;
+ param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ };
+ locationcomplete = locationcomplete || function (res) {
+ if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
+ param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
+ }
+ };
+ if (!param.location) {
+ that.getWXLocation(locationsuccess, locationfail, locationcomplete);
+ } else if (that.checkLocation(param)) {
+ var location = Utils.getLocationParam(param.location);
+ locationsuccess(location);
+ }
+ }
+};
+
+
+class QQMapWX {
+
+ /**
+ * 构造函数
+ *
+ * @param {Object} options 接口参数,key 为必选参数
+ */
+ constructor(options) {
+ if (!options.key) {
+ throw Error('key值不能为空');
+ }
+ this.key = options.key;
+ };
+
+ /**
+ * POI周边检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * @see http://lbs.qq.com/webservice_v1/guide-search.html
+ */
+ search(options) {
+ var that = this;
+ options = options || {};
+
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ orderby: options.orderby || '_distance',
+ page_size: options.page_size || 10,
+ page_index: options.page_index || 1,
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+
+ var distance = options.distance || "1000";
+ var auto_extend = options.auto_extend || 1;
+ var region = null;
+ var rectangle = null;
+
+ //判断城市限定参数
+ if (options.region) {
+ region = options.region;
+ }
+
+ //矩形限定坐标(暂时只支持字符串格式)
+ if (options.rectangle) {
+ rectangle = options.rectangle;
+ }
+
+ var locationsuccess = function (result) {
+ if (region && !rectangle) {
+ //城市限定参数拼接
+ requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+ }
+ } else if (rectangle && !region) {
+ //矩形搜索
+ requestParam.boundary = "rectangle(" + rectangle + ")";
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+ }
+ } else {
+ requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
+ }
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SEARCH,
+ data: requestParam
+ }, 'search'));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ };
+
+ /**
+ * sug模糊检索
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 参数对象结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-suggestion.html
+ */
+ getSuggestion(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (!Utils.checkKeyword(options)) {
+ return;
+ }
+
+ var requestParam = {
+ keyword: options.keyword,
+ region: options.region || '全国',
+ region_fix: options.region_fix || 0,
+ policy: options.policy || 0,
+ page_size: options.page_size || 10,//控制显示条数
+ page_index: options.page_index || 1,//控制页数
+ get_subpois : options.get_subpois || 0,//返回子地点
+ output: 'json',
+ key: that.key
+ };
+ //长地址
+ if (options.address_format) {
+ requestParam.address_format = options.address_format;
+ }
+ //过滤
+ if (options.filter) {
+ requestParam.filter = options.filter;
+ }
+ //排序
+ if (options.location) {
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }, "suggest"));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ } else {
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_SUGGESTION,
+ data: requestParam
+ }, "suggest"));
+ }
+ };
+
+ /**
+ * 逆地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-gcoder.html
+ */
+ reverseGeocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ coord_type: options.coord_type || 5,
+ get_poi: options.get_poi || 0,
+ output: 'json',
+ key: that.key
+ };
+ if (options.poi_options) {
+ requestParam.poi_options = options.poi_options
+ }
+
+ var locationsuccess = function (result) {
+ requestParam.location = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ }, 'reverseGeocoder'));
+ };
+ Utils.locationProcess(options, locationsuccess);
+ };
+
+ /**
+ * 地址解析
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-geocoder.html
+ */
+ geocoder(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'address')) {
+ return;
+ }
+
+ var requestParam = {
+ address: options.address,
+ output: 'json',
+ key: that.key
+ };
+
+ //城市限定
+ if (options.region) {
+ requestParam.region = options.region;
+ }
+
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder');
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_GET_GEOCODER,
+ data: requestParam
+ },'geocoder'));
+ };
+
+
+ /**
+ * 获取城市列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getCityList(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+ var requestParam = {
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList');
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_CITY_LIST,
+ data: requestParam
+ },'getCityList'));
+ };
+
+ /**
+ * 获取对应城市ID的区县列表
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-region.html
+ */
+ getDistrictByCityId(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'id')) {
+ return;
+ }
+
+ var requestParam = {
+ id: options.id || '',
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId');
+ }
+
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_AREA_LIST,
+ data: requestParam
+ },'getDistrictByCityId'));
+ };
+
+ /**
+ * 用于单起点到多终点的路线距离(非直线距离)计算:
+ * 支持两种距离计算方式:步行和驾车。
+ * 起点到终点最大限制直线距离10公里。
+ *
+ * 新增直线距离计算。
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * http://lbs.qq.com/webservice_v1/guide-distance.html
+ */
+ calculateDistance(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'to')) {
+ return;
+ }
+
+ var requestParam = {
+ mode: options.mode || 'walking',
+ to: Utils.location2query(options.to),
+ output: 'json',
+ key: that.key
+ };
+
+ if (options.from) {
+ options.location = options.from;
+ }
+
+ //计算直线距离
+ if(requestParam.mode == 'straight'){
+ var locationsuccess = function (result) {
+ var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
+ var data = {
+ message:"query ok",
+ result:{
+ elements:[]
+ },
+ status:0
+ };
+ for (var i = 0; i < locationTo.length; i++) {
+ data.result.elements.push({//将坐标存入
+ distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
+ duration:0,
+ from:{
+ lat: result.latitude,
+ lng:result.longitude
+ },
+ to:{
+ lat: locationTo[i].lat,
+ lng: locationTo[i].lng
+ }
+ });
+ }
+ var calculateResult = data.result.elements;
+ var distanceResult = [];
+ for (var i = 0; i < calculateResult.length; i++) {
+ distanceResult.push(calculateResult[i].distance);
+ }
+ return options.success(data,{
+ calculateResult: calculateResult,
+ distanceResult: distanceResult
+ });
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ } else {
+ var locationsuccess = function (result) {
+ requestParam.from = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance');
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: URL_DISTANCE,
+ data: requestParam
+ },'calculateDistance'));
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ }
+ };
+
+ /**
+ * 路线规划:
+ *
+ * @param {Object} options 接口参数对象
+ *
+ * 请求参数结构可以参考
+ * https://lbs.qq.com/webservice_v1/guide-road.html
+ */
+ direction(options) {
+ var that = this;
+ options = options || {};
+ Utils.polyfillParam(options);
+
+ if (Utils.checkParamKeyEmpty(options, 'to')) {
+ return;
+ }
+
+ var requestParam = {
+ output: 'json',
+ key: that.key
+ };
+
+ //to格式处理
+ if (typeof options.to == 'string') {
+ requestParam.to = options.to;
+ } else {
+ requestParam.to = options.to.latitude + ',' + options.to.longitude;
+ }
+ //初始化局部请求域名
+ var SET_URL_DIRECTION = null;
+ //设置默认mode属性
+ options.mode = options.mode || MODE.driving;
+
+ //设置请求域名
+ SET_URL_DIRECTION = URL_DIRECTION + options.mode;
+
+ if (options.from) {
+ options.location = options.from;
+ }
+
+ if (options.mode == MODE.driving) {
+ if (options.from_poi) {
+ requestParam.from_poi = options.from_poi;
+ }
+ if (options.heading) {
+ requestParam.heading = options.heading;
+ }
+ if (options.speed) {
+ requestParam.speed = options.speed;
+ }
+ if (options.accuracy) {
+ requestParam.accuracy = options.accuracy;
+ }
+ if (options.road_type) {
+ requestParam.road_type = options.road_type;
+ }
+ if (options.to_poi) {
+ requestParam.to_poi = options.to_poi;
+ }
+ if (options.from_track) {
+ requestParam.from_track = options.from_track;
+ }
+ if (options.waypoints) {
+ requestParam.waypoints = options.waypoints;
+ }
+ if (options.policy) {
+ requestParam.policy = options.policy;
+ }
+ if (options.plate_number) {
+ requestParam.plate_number = options.plate_number;
+ }
+ }
+
+ if (options.mode == MODE.transit) {
+ if (options.departure_time) {
+ requestParam.departure_time = options.departure_time;
+ }
+ if (options.policy) {
+ requestParam.policy = options.policy;
+ }
+ }
+
+ var locationsuccess = function (result) {
+ requestParam.from = result.latitude + ',' + result.longitude;
+ if (options.sig) {
+ requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode);
+ }
+ wx.request(Utils.buildWxRequestConfig(options, {
+ url: SET_URL_DIRECTION,
+ data: requestParam
+ }, 'direction'));
+ };
+
+ Utils.locationProcess(options, locationsuccess);
+ }
+};
+
+module.exports = QQMapWX;
\ No newline at end of file
diff --git a/common/toast.js b/common/toast.js
new file mode 100644
index 0000000..4459bc9
--- /dev/null
+++ b/common/toast.js
@@ -0,0 +1,56 @@
+// Toast 默认延时关闭时间
+const _time_ = 2000;
+
+// Toast 消息处理,最多显示七个汉字
+export const TaToast = {
+
+ // 隐藏消息显示
+ hide() {
+ uni.hideToast()
+ },
+
+ // 通用消息显示
+ show(info, type = 'none', mask = true, time = _time_) {
+ return new Promise(resolve => {
+ setTimeout(resolve, time)
+ uni.showToast({
+ mask: mask || false,
+ icon: type || 'none',
+ title: info,
+ duration: time
+ })
+ })
+ },
+
+ // 异常消息显示
+ error(info, mask = true, time = _time_) {
+ return this.show(info, 'error', mask, time)
+ },
+
+ // 成功消息显示
+ success(info, mask = true, time = _time_) {
+ return this.show(info, 'success', mask, time)
+ },
+
+ // 确认消息框架
+ confirm(content, title = '操作确认?') {
+ return new Promise((resolve, reject) => uni.showModal({
+ title,
+ content,
+ success: (res) => (res.cancel && reject(), res.confirm && resolve(res))
+ }))
+ },
+
+ // 显示加载消息
+ loading(info = '', mask = true) {
+ uni.showLoading({
+ mask: mask,
+ title: info
+ })
+ },
+
+ // 隐藏加载消息
+ loadhide() {
+ uni.hideLoading()
+ }
+}
\ No newline at end of file
diff --git a/common/util.js b/common/util.js
new file mode 100644
index 0000000..d7c3887
--- /dev/null
+++ b/common/util.js
@@ -0,0 +1,89 @@
+function friendlyDate(timestamp) {
+ var formats = {
+ 'year': '%n% 年前',
+ 'month': '%n% 月前',
+ 'day': '%n% 天前',
+ 'hour': '%n% 小时前',
+ 'minute': '%n% 分钟前',
+ 'second': '%n% 秒前',
+ };
+
+ var now = Date.now();
+ var seconds = Math.floor((now - timestamp) / 1000);
+ var minutes = Math.floor(seconds / 60);
+ var hours = Math.floor(minutes / 60);
+ var days = Math.floor(hours / 24);
+ var months = Math.floor(days / 30);
+ var years = Math.floor(months / 12);
+
+ var diffType = '';
+ var diffValue = 0;
+ if (years > 0) {
+ diffType = 'year';
+ diffValue = years;
+ } else {
+ if (months > 0) {
+ diffType = 'month';
+ diffValue = months;
+ } else {
+ if (days > 0) {
+ diffType = 'day';
+ diffValue = days;
+ } else {
+ if (hours > 0) {
+ diffType = 'hour';
+ diffValue = hours;
+ } else {
+ if (minutes > 0) {
+ diffType = 'minute';
+ diffValue = minutes;
+ } else {
+ diffType = 'second';
+ diffValue = seconds === 0 ? (seconds = 1) : seconds;
+ }
+ }
+ }
+ }
+ }
+ return formats[diffType].replace('%n%', diffValue);
+}
+
+function objectHasKey(o, k) {
+ return Object.keys(o).some((v) => v.toLowerCase() === k.toLowerCase())
+}
+
+
+// 下载图片到本地
+function TaImageDownload(imgUrl, name = '') {
+ return new Promise((resolve, reject) => {
+
+ // #ifdef H5
+ const link = document.createElement('a')
+ link.href = imgUrl
+ link.download = name || (Math.random().toString().replace('0.', 'img') + `.png`)
+ link.style.display = 'none'
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ resolve(true)
+ // #endif
+
+ // #ifndef H5
+ uni.downloadFile({
+ url: imgUrl, success: (ret) => {
+ if (ret.statusCode === 200) uni.saveImageToPhotosAlbum({
+ filePath: ret.tempFilePath,
+ fail: (err) => TaToast.error('保存失败!', err).then(reject),
+ success: () => TaToast.success('保存成功!').then(resolve),
+ });
+ }
+ });
+ // #endif
+ })
+}
+
+export {
+ TaImageDownload,
+ friendlyDate,
+ objectHasKey
+}
diff --git a/components/i-account-list/i-account-list.vue b/components/i-account-list/i-account-list.vue
new file mode 100644
index 0000000..fa26f09
--- /dev/null
+++ b/components/i-account-list/i-account-list.vue
@@ -0,0 +1,38 @@
+
+
+
+
+ 100
+ 优惠券
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-account/i-account.vue b/components/i-account/i-account.vue
new file mode 100644
index 0000000..9f54164
--- /dev/null
+++ b/components/i-account/i-account.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+ 小王
+ 187****0002
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-address-list/i-address-list.vue b/components/i-address-list/i-address-list.vue
new file mode 100644
index 0000000..c577ac6
--- /dev/null
+++ b/components/i-address-list/i-address-list.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+ {{item.user_name}}
+ {{item.user_phone}}
+
+ {{item.region_prov}}{{item.region_city}}{{item.region_area}}{{item.region_addr}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-cart-list/i-cart-list.vue b/components/i-cart-list/i-cart-list.vue
new file mode 100644
index 0000000..0664d16
--- /dev/null
+++ b/components/i-cart-list/i-cart-list.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+ 现货供应抗震盘螺大量批发
+
+
+
+ 类型:
+ 螺纹钢-20*20-GB2301-马场空
+
+
+
+ 99.9
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-list-top/i-list-top.vue b/components/i-list-top/i-list-top.vue
new file mode 100644
index 0000000..bbb3019
--- /dev/null
+++ b/components/i-list-top/i-list-top.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+ {{item.price_selling}}
+
+ {{item.price_market}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-loading/i-loading.vue b/components/i-loading/i-loading.vue
new file mode 100644
index 0000000..a97feec
--- /dev/null
+++ b/components/i-loading/i-loading.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 加载中,请稍候
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-message-list/i-message-list.vue b/components/i-message-list/i-message-list.vue
new file mode 100644
index 0000000..e4fb1c0
--- /dev/null
+++ b/components/i-message-list/i-message-list.vue
@@ -0,0 +1,67 @@
+
+
+
+ {{item.title}}
+
+ {{item.content}}
+
+
+
+
+ {{item.create_at}}
+
+
+
+
+
+
+
+
+
+
diff --git a/components/i-my-list/i-my-list.vue b/components/i-my-list/i-my-list.vue
new file mode 100644
index 0000000..78043f2
--- /dev/null
+++ b/components/i-my-list/i-my-list.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+ 编辑资料
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-nav-list/i-nav-list.vue b/components/i-nav-list/i-nav-list.vue
new file mode 100644
index 0000000..fbac02d
--- /dev/null
+++ b/components/i-nav-list/i-nav-list.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+ 标题
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-news-list/i-news-list.vue b/components/i-news-list/i-news-list.vue
new file mode 100644
index 0000000..4f8c8a2
--- /dev/null
+++ b/components/i-news-list/i-news-list.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ {{item.title}}
+
+
+ {{item.publish_at}}
+
+
+
+
+ {{item.view_count}}人浏览
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-nodata/i-nodata.vue b/components/i-nodata/i-nodata.vue
new file mode 100644
index 0000000..e3e37ec
--- /dev/null
+++ b/components/i-nodata/i-nodata.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+ {{title}}
+ {{subtitle}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-notice-list/i-notice-list.vue b/components/i-notice-list/i-notice-list.vue
new file mode 100644
index 0000000..0f1717d
--- /dev/null
+++ b/components/i-notice-list/i-notice-list.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+ 特别公告:禁止上传 任何 涉及 第三方版权资料
+
+
+ 更多
+
+
+
+
+
+
diff --git a/components/i-order-list/i-order-list.vue b/components/i-order-list/i-order-list.vue
new file mode 100644
index 0000000..2df2b06
--- /dev/null
+++ b/components/i-order-list/i-order-list.vue
@@ -0,0 +1,113 @@
+
+
+
+
+ {{item.create_time}}
+ 已取消
+ 待支付
+ 待验证
+ 待发货
+ 待收货
+ 已收货
+
+
+
+
+
+ {{gitem.gname}}
+
+
+ {{gitem.total_price_cost}}
+
+
+ 数量:
+ {{gitem.stock_sales}}
+
+
+
+
+
+
+
+
+
+ 共
+ {{item.number_goods}}
+ 件商品
+
+
+ 总消耗
+ {{item.amount_total}}
+
+
+
+ 取消
+ 确认收货
+ 支付
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-search/i-search.vue b/components/i-search/i-search.vue
new file mode 100644
index 0000000..fe7385c
--- /dev/null
+++ b/components/i-search/i-search.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-spread/i-spread.vue b/components/i-spread/i-spread.vue
new file mode 100644
index 0000000..a8a6156
--- /dev/null
+++ b/components/i-spread/i-spread.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+ {{btnTxt}}
+ {{shrinkBtnTxt}}
+
+
+
+
diff --git a/components/i-swiper/i-swiper.vue b/components/i-swiper/i-swiper.vue
new file mode 100644
index 0000000..93b8561
--- /dev/null
+++ b/components/i-swiper/i-swiper.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-thumb-list/i-thumb-list.vue b/components/i-thumb-list/i-thumb-list.vue
new file mode 100644
index 0000000..5b8abbc
--- /dev/null
+++ b/components/i-thumb-list/i-thumb-list.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+ {{item.content}}
+
+
+
+
+ {{item.create_at}}
+
+
+
+
+ {{item.like_count}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-tutorial-list/i-tutorial-list.vue b/components/i-tutorial-list/i-tutorial-list.vue
new file mode 100644
index 0000000..bc8ff30
--- /dev/null
+++ b/components/i-tutorial-list/i-tutorial-list.vue
@@ -0,0 +1,46 @@
+
+
+
+ {{item.title}}
+
+
+
+ {{item.view_count}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-user-share-list/i-user-share-list.vue b/components/i-user-share-list/i-user-share-list.vue
new file mode 100644
index 0000000..ef71f0b
--- /dev/null
+++ b/components/i-user-share-list/i-user-share-list.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+ {{item.content}}
+ 未处理
+ 已处理
+
+
+
+
+ {{item.create_at}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/i-video-list/i-video-list.vue b/components/i-video-list/i-video-list.vue
new file mode 100644
index 0000000..925bd23
--- /dev/null
+++ b/components/i-video-list/i-video-list.vue
@@ -0,0 +1,57 @@
+
+
+
+ 视频标题
+
+
+
+
+
+
+
+
+
+ 小王
+
+
+
+ 111
+
+
+
+ 222
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/pick-regions/pick-regions.vue b/components/pick-regions/pick-regions.vue
new file mode 100644
index 0000000..4062e0f
--- /dev/null
+++ b/components/pick-regions/pick-regions.vue
@@ -0,0 +1,137 @@
+
+
+
+
+
+
+
diff --git a/components/pick-regions/regions.json b/components/pick-regions/regions.json
new file mode 100644
index 0000000..310abee
--- /dev/null
+++ b/components/pick-regions/regions.json
@@ -0,0 +1 @@
+[{"code":"11","name":"北京市","childs":[{"code":"1101","name":"市辖区","childs":[{"code":"110101","name":"东城区"},{"code":"110102","name":"西城区"},{"code":"110105","name":"朝阳区"},{"code":"110106","name":"丰台区"},{"code":"110107","name":"石景山区"},{"code":"110108","name":"海淀区"},{"code":"110109","name":"门头沟区"},{"code":"110111","name":"房山区"},{"code":"110112","name":"通州区"},{"code":"110113","name":"顺义区"},{"code":"110114","name":"昌平区"},{"code":"110115","name":"大兴区"},{"code":"110116","name":"怀柔区"},{"code":"110117","name":"平谷区"},{"code":"110118","name":"密云区"},{"code":"110119","name":"延庆区"}]}]},{"code":"12","name":"天津市","childs":[{"code":"1201","name":"市辖区","childs":[{"code":"120101","name":"和平区"},{"code":"120102","name":"河东区"},{"code":"120103","name":"河西区"},{"code":"120104","name":"南开区"},{"code":"120105","name":"河北区"},{"code":"120106","name":"红桥区"},{"code":"120110","name":"东丽区"},{"code":"120111","name":"西青区"},{"code":"120112","name":"津南区"},{"code":"120113","name":"北辰区"},{"code":"120114","name":"武清区"},{"code":"120115","name":"宝坻区"},{"code":"120116","name":"滨海新区"},{"code":"120117","name":"宁河区"},{"code":"120118","name":"静海区"},{"code":"120119","name":"蓟州区"}]}]},{"code":"13","name":"河北省","childs":[{"code":"1301","name":"石家庄市","childs":[{"code":"130102","name":"长安区"},{"code":"130104","name":"桥西区"},{"code":"130105","name":"新华区"},{"code":"130107","name":"井陉矿区"},{"code":"130108","name":"裕华区"},{"code":"130109","name":"藁城区"},{"code":"130110","name":"鹿泉区"},{"code":"130111","name":"栾城区"},{"code":"130121","name":"井陉县"},{"code":"130123","name":"正定县"},{"code":"130125","name":"行唐县"},{"code":"130126","name":"灵寿县"},{"code":"130127","name":"高邑县"},{"code":"130128","name":"深泽县"},{"code":"130129","name":"赞皇县"},{"code":"130130","name":"无极县"},{"code":"130131","name":"平山县"},{"code":"130132","name":"元氏县"},{"code":"130133","name":"赵县"},{"code":"130183","name":"晋州市"},{"code":"130184","name":"新乐市"}]},{"code":"1302","name":"唐山市","childs":[{"code":"130202","name":"路南区"},{"code":"130203","name":"路北区"},{"code":"130204","name":"古冶区"},{"code":"130205","name":"开平区"},{"code":"130207","name":"丰南区"},{"code":"130208","name":"丰润区"},{"code":"130209","name":"曹妃甸区"},{"code":"130223","name":"滦县"},{"code":"130224","name":"滦南县"},{"code":"130225","name":"乐亭县"},{"code":"130227","name":"迁西县"},{"code":"130229","name":"玉田县"},{"code":"130281","name":"遵化市"},{"code":"130283","name":"迁安市"}]},{"code":"1303","name":"秦皇岛市","childs":[{"code":"130302","name":"海港区"},{"code":"130303","name":"山海关区"},{"code":"130304","name":"北戴河区"},{"code":"130306","name":"抚宁区"},{"code":"130321","name":"青龙满族自治县"},{"code":"130322","name":"昌黎县"},{"code":"130324","name":"卢龙县"}]},{"code":"1304","name":"邯郸市","childs":[{"code":"130402","name":"邯山区"},{"code":"130403","name":"丛台区"},{"code":"130404","name":"复兴区"},{"code":"130406","name":"峰峰矿区"},{"code":"130421","name":"邯郸县"},{"code":"130423","name":"临漳县"},{"code":"130424","name":"成安县"},{"code":"130425","name":"大名县"},{"code":"130426","name":"涉县"},{"code":"130427","name":"磁县"},{"code":"130428","name":"肥乡县"},{"code":"130429","name":"永年县"},{"code":"130430","name":"邱县"},{"code":"130431","name":"鸡泽县"},{"code":"130432","name":"广平县"},{"code":"130433","name":"馆陶县"},{"code":"130434","name":"魏县"},{"code":"130435","name":"曲周县"},{"code":"130481","name":"武安市"}]},{"code":"1305","name":"邢台市","childs":[{"code":"130502","name":"桥东区"},{"code":"130503","name":"桥西区"},{"code":"130521","name":"邢台县"},{"code":"130522","name":"临城县"},{"code":"130523","name":"内丘县"},{"code":"130524","name":"柏乡县"},{"code":"130525","name":"隆尧县"},{"code":"130526","name":"任县"},{"code":"130527","name":"南和县"},{"code":"130528","name":"宁晋县"},{"code":"130529","name":"巨鹿县"},{"code":"130530","name":"新河县"},{"code":"130531","name":"广宗县"},{"code":"130532","name":"平乡县"},{"code":"130533","name":"威县"},{"code":"130534","name":"清河县"},{"code":"130535","name":"临西县"},{"code":"130581","name":"南宫市"},{"code":"130582","name":"沙河市"}]},{"code":"1306","name":"保定市","childs":[{"code":"130602","name":"竞秀区"},{"code":"130606","name":"莲池区"},{"code":"130607","name":"满城区"},{"code":"130608","name":"清苑区"},{"code":"130609","name":"徐水区"},{"code":"130623","name":"涞水县"},{"code":"130624","name":"阜平县"},{"code":"130626","name":"定兴县"},{"code":"130627","name":"唐县"},{"code":"130628","name":"高阳县"},{"code":"130629","name":"容城县"},{"code":"130630","name":"涞源县"},{"code":"130631","name":"望都县"},{"code":"130632","name":"安新县"},{"code":"130633","name":"易县"},{"code":"130634","name":"曲阳县"},{"code":"130635","name":"蠡县"},{"code":"130636","name":"顺平县"},{"code":"130637","name":"博野县"},{"code":"130638","name":"雄县"},{"code":"130681","name":"涿州市"},{"code":"130683","name":"安国市"},{"code":"130684","name":"高碑店市"}]},{"code":"1307","name":"张家口市","childs":[{"code":"130702","name":"桥东区"},{"code":"130703","name":"桥西区"},{"code":"130705","name":"宣化区"},{"code":"130706","name":"下花园区"},{"code":"130708","name":"万全区"},{"code":"130709","name":"崇礼区"},{"code":"130722","name":"张北县"},{"code":"130723","name":"康保县"},{"code":"130724","name":"沽源县"},{"code":"130725","name":"尚义县"},{"code":"130726","name":"蔚县"},{"code":"130727","name":"阳原县"},{"code":"130728","name":"怀安县"},{"code":"130730","name":"怀来县"},{"code":"130731","name":"涿鹿县"},{"code":"130732","name":"赤城县"}]},{"code":"1308","name":"承德市","childs":[{"code":"130802","name":"双桥区"},{"code":"130803","name":"双滦区"},{"code":"130804","name":"鹰手营子矿区"},{"code":"130821","name":"承德县"},{"code":"130822","name":"兴隆县"},{"code":"130823","name":"平泉县"},{"code":"130824","name":"滦平县"},{"code":"130825","name":"隆化县"},{"code":"130826","name":"丰宁满族自治县"},{"code":"130827","name":"宽城满族自治县"},{"code":"130828","name":"围场满族蒙古族自治县"}]},{"code":"1309","name":"沧州市","childs":[{"code":"130902","name":"新华区"},{"code":"130903","name":"运河区"},{"code":"130921","name":"沧县"},{"code":"130922","name":"青县"},{"code":"130923","name":"东光县"},{"code":"130924","name":"海兴县"},{"code":"130925","name":"盐山县"},{"code":"130926","name":"肃宁县"},{"code":"130927","name":"南皮县"},{"code":"130928","name":"吴桥县"},{"code":"130929","name":"献县"},{"code":"130930","name":"孟村回族自治县"},{"code":"130981","name":"泊头市"},{"code":"130982","name":"任丘市"},{"code":"130983","name":"黄骅市"},{"code":"130984","name":"河间市"}]},{"code":"1310","name":"廊坊市","childs":[{"code":"131002","name":"安次区"},{"code":"131003","name":"广阳区"},{"code":"131022","name":"固安县"},{"code":"131023","name":"永清县"},{"code":"131024","name":"香河县"},{"code":"131025","name":"大城县"},{"code":"131026","name":"文安县"},{"code":"131028","name":"大厂回族自治县"},{"code":"131081","name":"霸州市"},{"code":"131082","name":"三河市"}]},{"code":"1311","name":"衡水市","childs":[{"code":"131102","name":"桃城区"},{"code":"131103","name":"冀州区"},{"code":"131121","name":"枣强县"},{"code":"131122","name":"武邑县"},{"code":"131123","name":"武强县"},{"code":"131124","name":"饶阳县"},{"code":"131125","name":"安平县"},{"code":"131126","name":"故城县"},{"code":"131127","name":"景县"},{"code":"131128","name":"阜城县"},{"code":"131182","name":"深州市"}]},{"code":"1390","name":"省直辖县级行政区划","childs":[{"code":"139001","name":"定州市"},{"code":"139002","name":"辛集市"}]}]},{"code":"14","name":"山西省","childs":[{"code":"1401","name":"太原市","childs":[{"code":"140105","name":"小店区"},{"code":"140106","name":"迎泽区"},{"code":"140107","name":"杏花岭区"},{"code":"140108","name":"尖草坪区"},{"code":"140109","name":"万柏林区"},{"code":"140110","name":"晋源区"},{"code":"140121","name":"清徐县"},{"code":"140122","name":"阳曲县"},{"code":"140123","name":"娄烦县"},{"code":"140181","name":"古交市"}]},{"code":"1402","name":"大同市","childs":[{"code":"140202","name":"城区"},{"code":"140203","name":"矿区"},{"code":"140211","name":"南郊区"},{"code":"140212","name":"新荣区"},{"code":"140221","name":"阳高县"},{"code":"140222","name":"天镇县"},{"code":"140223","name":"广灵县"},{"code":"140224","name":"灵丘县"},{"code":"140225","name":"浑源县"},{"code":"140226","name":"左云县"},{"code":"140227","name":"大同县"}]},{"code":"1403","name":"阳泉市","childs":[{"code":"140302","name":"城区"},{"code":"140303","name":"矿区"},{"code":"140311","name":"郊区"},{"code":"140321","name":"平定县"},{"code":"140322","name":"盂县"}]},{"code":"1404","name":"长治市","childs":[{"code":"140402","name":"城区"},{"code":"140411","name":"郊区"},{"code":"140421","name":"长治县"},{"code":"140423","name":"襄垣县"},{"code":"140424","name":"屯留县"},{"code":"140425","name":"平顺县"},{"code":"140426","name":"黎城县"},{"code":"140427","name":"壶关县"},{"code":"140428","name":"长子县"},{"code":"140429","name":"武乡县"},{"code":"140430","name":"沁县"},{"code":"140431","name":"沁源县"},{"code":"140481","name":"潞城市"}]},{"code":"1405","name":"晋城市","childs":[{"code":"140502","name":"城区"},{"code":"140521","name":"沁水县"},{"code":"140522","name":"阳城县"},{"code":"140524","name":"陵川县"},{"code":"140525","name":"泽州县"},{"code":"140581","name":"高平市"}]},{"code":"1406","name":"朔州市","childs":[{"code":"140602","name":"朔城区"},{"code":"140603","name":"平鲁区"},{"code":"140621","name":"山阴县"},{"code":"140622","name":"应县"},{"code":"140623","name":"右玉县"},{"code":"140624","name":"怀仁县"}]},{"code":"1407","name":"晋中市","childs":[{"code":"140702","name":"榆次区"},{"code":"140721","name":"榆社县"},{"code":"140722","name":"左权县"},{"code":"140723","name":"和顺县"},{"code":"140724","name":"昔阳县"},{"code":"140725","name":"寿阳县"},{"code":"140726","name":"太谷县"},{"code":"140727","name":"祁县"},{"code":"140728","name":"平遥县"},{"code":"140729","name":"灵石县"},{"code":"140781","name":"介休市"}]},{"code":"1408","name":"运城市","childs":[{"code":"140802","name":"盐湖区"},{"code":"140821","name":"临猗县"},{"code":"140822","name":"万荣县"},{"code":"140823","name":"闻喜县"},{"code":"140824","name":"稷山县"},{"code":"140825","name":"新绛县"},{"code":"140826","name":"绛县"},{"code":"140827","name":"垣曲县"},{"code":"140828","name":"夏县"},{"code":"140829","name":"平陆县"},{"code":"140830","name":"芮城县"},{"code":"140881","name":"永济市"},{"code":"140882","name":"河津市"}]},{"code":"1409","name":"忻州市","childs":[{"code":"140902","name":"忻府区"},{"code":"140921","name":"定襄县"},{"code":"140922","name":"五台县"},{"code":"140923","name":"代县"},{"code":"140924","name":"繁峙县"},{"code":"140925","name":"宁武县"},{"code":"140926","name":"静乐县"},{"code":"140927","name":"神池县"},{"code":"140928","name":"五寨县"},{"code":"140929","name":"岢岚县"},{"code":"140930","name":"河曲县"},{"code":"140931","name":"保德县"},{"code":"140932","name":"偏关县"},{"code":"140981","name":"原平市"}]},{"code":"1410","name":"临汾市","childs":[{"code":"141002","name":"尧都区"},{"code":"141021","name":"曲沃县"},{"code":"141022","name":"翼城县"},{"code":"141023","name":"襄汾县"},{"code":"141024","name":"洪洞县"},{"code":"141025","name":"古县"},{"code":"141026","name":"安泽县"},{"code":"141027","name":"浮山县"},{"code":"141028","name":"吉县"},{"code":"141029","name":"乡宁县"},{"code":"141030","name":"大宁县"},{"code":"141031","name":"隰县"},{"code":"141032","name":"永和县"},{"code":"141033","name":"蒲县"},{"code":"141034","name":"汾西县"},{"code":"141081","name":"侯马市"},{"code":"141082","name":"霍州市"}]},{"code":"1411","name":"吕梁市","childs":[{"code":"141102","name":"离石区"},{"code":"141121","name":"文水县"},{"code":"141122","name":"交城县"},{"code":"141123","name":"兴县"},{"code":"141124","name":"临县"},{"code":"141125","name":"柳林县"},{"code":"141126","name":"石楼县"},{"code":"141127","name":"岚县"},{"code":"141128","name":"方山县"},{"code":"141129","name":"中阳县"},{"code":"141130","name":"交口县"},{"code":"141181","name":"孝义市"},{"code":"141182","name":"汾阳市"}]}]},{"code":"15","name":"内蒙古自治区","childs":[{"code":"1501","name":"呼和浩特市","childs":[{"code":"150102","name":"新城区"},{"code":"150103","name":"回民区"},{"code":"150104","name":"玉泉区"},{"code":"150105","name":"赛罕区"},{"code":"150121","name":"土默特左旗"},{"code":"150122","name":"托克托县"},{"code":"150123","name":"和林格尔县"},{"code":"150124","name":"清水河县"},{"code":"150125","name":"武川县"}]},{"code":"1502","name":"包头市","childs":[{"code":"150202","name":"东河区"},{"code":"150203","name":"昆都仑区"},{"code":"150204","name":"青山区"},{"code":"150205","name":"石拐区"},{"code":"150206","name":"白云鄂博矿区"},{"code":"150207","name":"九原区"},{"code":"150221","name":"土默特右旗"},{"code":"150222","name":"固阳县"},{"code":"150223","name":"达尔罕茂明安联合旗"}]},{"code":"1503","name":"乌海市","childs":[{"code":"150302","name":"海勃湾区"},{"code":"150303","name":"海南区"},{"code":"150304","name":"乌达区"}]},{"code":"1504","name":"赤峰市","childs":[{"code":"150402","name":"红山区"},{"code":"150403","name":"元宝山区"},{"code":"150404","name":"松山区"},{"code":"150421","name":"阿鲁科尔沁旗"},{"code":"150422","name":"巴林左旗"},{"code":"150423","name":"巴林右旗"},{"code":"150424","name":"林西县"},{"code":"150425","name":"克什克腾旗"},{"code":"150426","name":"翁牛特旗"},{"code":"150428","name":"喀喇沁旗"},{"code":"150429","name":"宁城县"},{"code":"150430","name":"敖汉旗"}]},{"code":"1505","name":"通辽市","childs":[{"code":"150502","name":"科尔沁区"},{"code":"150521","name":"科尔沁左翼中旗"},{"code":"150522","name":"科尔沁左翼后旗"},{"code":"150523","name":"开鲁县"},{"code":"150524","name":"库伦旗"},{"code":"150525","name":"奈曼旗"},{"code":"150526","name":"扎鲁特旗"},{"code":"150581","name":"霍林郭勒市"}]},{"code":"1506","name":"鄂尔多斯市","childs":[{"code":"150602","name":"东胜区"},{"code":"150603","name":"康巴什区"},{"code":"150621","name":"达拉特旗"},{"code":"150622","name":"准格尔旗"},{"code":"150623","name":"鄂托克前旗"},{"code":"150624","name":"鄂托克旗"},{"code":"150625","name":"杭锦旗"},{"code":"150626","name":"乌审旗"},{"code":"150627","name":"伊金霍洛旗"}]},{"code":"1507","name":"呼伦贝尔市","childs":[{"code":"150702","name":"海拉尔区"},{"code":"150703","name":"扎赉诺尔区"},{"code":"150721","name":"阿荣旗"},{"code":"150722","name":"莫力达瓦达斡尔族自治旗"},{"code":"150723","name":"鄂伦春自治旗"},{"code":"150724","name":"鄂温克族自治旗"},{"code":"150725","name":"陈巴尔虎旗"},{"code":"150726","name":"新巴尔虎左旗"},{"code":"150727","name":"新巴尔虎右旗"},{"code":"150781","name":"满洲里市"},{"code":"150782","name":"牙克石市"},{"code":"150783","name":"扎兰屯市"},{"code":"150784","name":"额尔古纳市"},{"code":"150785","name":"根河市"}]},{"code":"1508","name":"巴彦淖尔市","childs":[{"code":"150802","name":"临河区"},{"code":"150821","name":"五原县"},{"code":"150822","name":"磴口县"},{"code":"150823","name":"乌拉特前旗"},{"code":"150824","name":"乌拉特中旗"},{"code":"150825","name":"乌拉特后旗"},{"code":"150826","name":"杭锦后旗"}]},{"code":"1509","name":"乌兰察布市","childs":[{"code":"150902","name":"集宁区"},{"code":"150921","name":"卓资县"},{"code":"150922","name":"化德县"},{"code":"150923","name":"商都县"},{"code":"150924","name":"兴和县"},{"code":"150925","name":"凉城县"},{"code":"150926","name":"察哈尔右翼前旗"},{"code":"150927","name":"察哈尔右翼中旗"},{"code":"150928","name":"察哈尔右翼后旗"},{"code":"150929","name":"四子王旗"},{"code":"150981","name":"丰镇市"}]},{"code":"1522","name":"兴安盟","childs":[{"code":"152201","name":"乌兰浩特市"},{"code":"152202","name":"阿尔山市"},{"code":"152221","name":"科尔沁右翼前旗"},{"code":"152222","name":"科尔沁右翼中旗"},{"code":"152223","name":"扎赉特旗"},{"code":"152224","name":"突泉县"}]},{"code":"1525","name":"锡林郭勒盟","childs":[{"code":"152501","name":"二连浩特市"},{"code":"152502","name":"锡林浩特市"},{"code":"152522","name":"阿巴嘎旗"},{"code":"152523","name":"苏尼特左旗"},{"code":"152524","name":"苏尼特右旗"},{"code":"152525","name":"东乌珠穆沁旗"},{"code":"152526","name":"西乌珠穆沁旗"},{"code":"152527","name":"太仆寺旗"},{"code":"152528","name":"镶黄旗"},{"code":"152529","name":"正镶白旗"},{"code":"152530","name":"正蓝旗"},{"code":"152531","name":"多伦县"}]},{"code":"1529","name":"阿拉善盟","childs":[{"code":"152921","name":"阿拉善左旗"},{"code":"152922","name":"阿拉善右旗"},{"code":"152923","name":"额济纳旗"}]}]},{"code":"21","name":"辽宁省","childs":[{"code":"2101","name":"沈阳市","childs":[{"code":"210102","name":"和平区"},{"code":"210103","name":"沈河区"},{"code":"210104","name":"大东区"},{"code":"210105","name":"皇姑区"},{"code":"210106","name":"铁西区"},{"code":"210111","name":"苏家屯区"},{"code":"210112","name":"浑南区"},{"code":"210113","name":"沈北新区"},{"code":"210114","name":"于洪区"},{"code":"210115","name":"辽中区"},{"code":"210123","name":"康平县"},{"code":"210124","name":"法库县"},{"code":"210181","name":"新民市"}]},{"code":"2102","name":"大连市","childs":[{"code":"210202","name":"中山区"},{"code":"210203","name":"西岗区"},{"code":"210204","name":"沙河口区"},{"code":"210211","name":"甘井子区"},{"code":"210212","name":"旅顺口区"},{"code":"210213","name":"金州区"},{"code":"210214","name":"普兰店区"},{"code":"210224","name":"长海县"},{"code":"210281","name":"瓦房店市"},{"code":"210283","name":"庄河市"}]},{"code":"2103","name":"鞍山市","childs":[{"code":"210302","name":"铁东区"},{"code":"210303","name":"铁西区"},{"code":"210304","name":"立山区"},{"code":"210311","name":"千山区"},{"code":"210321","name":"台安县"},{"code":"210323","name":"岫岩满族自治县"},{"code":"210381","name":"海城市"}]},{"code":"2104","name":"抚顺市","childs":[{"code":"210402","name":"新抚区"},{"code":"210403","name":"东洲区"},{"code":"210404","name":"望花区"},{"code":"210411","name":"顺城区"},{"code":"210421","name":"抚顺县"},{"code":"210422","name":"新宾满族自治县"},{"code":"210423","name":"清原满族自治县"}]},{"code":"2105","name":"本溪市","childs":[{"code":"210502","name":"平山区"},{"code":"210503","name":"溪湖区"},{"code":"210504","name":"明山区"},{"code":"210505","name":"南芬区"},{"code":"210521","name":"本溪满族自治县"},{"code":"210522","name":"桓仁满族自治县"}]},{"code":"2106","name":"丹东市","childs":[{"code":"210602","name":"元宝区"},{"code":"210603","name":"振兴区"},{"code":"210604","name":"振安区"},{"code":"210624","name":"宽甸满族自治县"},{"code":"210681","name":"东港市"},{"code":"210682","name":"凤城市"}]},{"code":"2107","name":"锦州市","childs":[{"code":"210702","name":"古塔区"},{"code":"210703","name":"凌河区"},{"code":"210711","name":"太和区"},{"code":"210726","name":"黑山县"},{"code":"210727","name":"义县"},{"code":"210781","name":"凌海市"},{"code":"210782","name":"北镇市"}]},{"code":"2108","name":"营口市","childs":[{"code":"210802","name":"站前区"},{"code":"210803","name":"西市区"},{"code":"210804","name":"鲅鱼圈区"},{"code":"210811","name":"老边区"},{"code":"210881","name":"盖州市"},{"code":"210882","name":"大石桥市"}]},{"code":"2109","name":"阜新市","childs":[{"code":"210902","name":"海州区"},{"code":"210903","name":"新邱区"},{"code":"210904","name":"太平区"},{"code":"210905","name":"清河门区"},{"code":"210911","name":"细河区"},{"code":"210921","name":"阜新蒙古族自治县"},{"code":"210922","name":"彰武县"}]},{"code":"2110","name":"辽阳市","childs":[{"code":"211002","name":"白塔区"},{"code":"211003","name":"文圣区"},{"code":"211004","name":"宏伟区"},{"code":"211005","name":"弓长岭区"},{"code":"211011","name":"太子河区"},{"code":"211021","name":"辽阳县"},{"code":"211081","name":"灯塔市"}]},{"code":"2111","name":"盘锦市","childs":[{"code":"211102","name":"双台子区"},{"code":"211103","name":"兴隆台区"},{"code":"211104","name":"大洼区"},{"code":"211122","name":"盘山县"}]},{"code":"2112","name":"铁岭市","childs":[{"code":"211202","name":"银州区"},{"code":"211204","name":"清河区"},{"code":"211221","name":"铁岭县"},{"code":"211223","name":"西丰县"},{"code":"211224","name":"昌图县"},{"code":"211281","name":"调兵山市"},{"code":"211282","name":"开原市"}]},{"code":"2113","name":"朝阳市","childs":[{"code":"211302","name":"双塔区"},{"code":"211303","name":"龙城区"},{"code":"211321","name":"朝阳县"},{"code":"211322","name":"建平县"},{"code":"211324","name":"喀喇沁左翼蒙古族自治县"},{"code":"211381","name":"北票市"},{"code":"211382","name":"凌源市"}]},{"code":"2114","name":"葫芦岛市","childs":[{"code":"211402","name":"连山区"},{"code":"211403","name":"龙港区"},{"code":"211404","name":"南票区"},{"code":"211421","name":"绥中县"},{"code":"211422","name":"建昌县"},{"code":"211481","name":"兴城市"}]}]},{"code":"22","name":"吉林省","childs":[{"code":"2201","name":"长春市","childs":[{"code":"220102","name":"南关区"},{"code":"220103","name":"宽城区"},{"code":"220104","name":"朝阳区"},{"code":"220105","name":"二道区"},{"code":"220106","name":"绿园区"},{"code":"220112","name":"双阳区"},{"code":"220113","name":"九台区"},{"code":"220122","name":"农安县"},{"code":"220182","name":"榆树市"},{"code":"220183","name":"德惠市"}]},{"code":"2202","name":"吉林市","childs":[{"code":"220202","name":"昌邑区"},{"code":"220203","name":"龙潭区"},{"code":"220204","name":"船营区"},{"code":"220211","name":"丰满区"},{"code":"220221","name":"永吉县"},{"code":"220281","name":"蛟河市"},{"code":"220282","name":"桦甸市"},{"code":"220283","name":"舒兰市"},{"code":"220284","name":"磐石市"}]},{"code":"2203","name":"四平市","childs":[{"code":"220302","name":"铁西区"},{"code":"220303","name":"铁东区"},{"code":"220322","name":"梨树县"},{"code":"220323","name":"伊通满族自治县"},{"code":"220381","name":"公主岭市"},{"code":"220382","name":"双辽市"}]},{"code":"2204","name":"辽源市","childs":[{"code":"220402","name":"龙山区"},{"code":"220403","name":"西安区"},{"code":"220421","name":"东丰县"},{"code":"220422","name":"东辽县"}]},{"code":"2205","name":"通化市","childs":[{"code":"220502","name":"东昌区"},{"code":"220503","name":"二道江区"},{"code":"220521","name":"通化县"},{"code":"220523","name":"辉南县"},{"code":"220524","name":"柳河县"},{"code":"220581","name":"梅河口市"},{"code":"220582","name":"集安市"}]},{"code":"2206","name":"白山市","childs":[{"code":"220602","name":"浑江区"},{"code":"220605","name":"江源区"},{"code":"220621","name":"抚松县"},{"code":"220622","name":"靖宇县"},{"code":"220623","name":"长白朝鲜族自治县"},{"code":"220681","name":"临江市"}]},{"code":"2207","name":"松原市","childs":[{"code":"220702","name":"宁江区"},{"code":"220721","name":"前郭尔罗斯蒙古族自治县"},{"code":"220722","name":"长岭县"},{"code":"220723","name":"乾安县"},{"code":"220781","name":"扶余市"}]},{"code":"2208","name":"白城市","childs":[{"code":"220802","name":"洮北区"},{"code":"220821","name":"镇赉县"},{"code":"220822","name":"通榆县"},{"code":"220881","name":"洮南市"},{"code":"220882","name":"大安市"}]},{"code":"2224","name":"延边朝鲜族自治州","childs":[{"code":"222401","name":"延吉市"},{"code":"222402","name":"图们市"},{"code":"222403","name":"敦化市"},{"code":"222404","name":"珲春市"},{"code":"222405","name":"龙井市"},{"code":"222406","name":"和龙市"},{"code":"222424","name":"汪清县"},{"code":"222426","name":"安图县"}]}]},{"code":"23","name":"黑龙江省","childs":[{"code":"2301","name":"哈尔滨市","childs":[{"code":"230102","name":"道里区"},{"code":"230103","name":"南岗区"},{"code":"230104","name":"道外区"},{"code":"230108","name":"平房区"},{"code":"230109","name":"松北区"},{"code":"230110","name":"香坊区"},{"code":"230111","name":"呼兰区"},{"code":"230112","name":"阿城区"},{"code":"230113","name":"双城区"},{"code":"230123","name":"依兰县"},{"code":"230124","name":"方正县"},{"code":"230125","name":"宾县"},{"code":"230126","name":"巴彦县"},{"code":"230127","name":"木兰县"},{"code":"230128","name":"通河县"},{"code":"230129","name":"延寿县"},{"code":"230183","name":"尚志市"},{"code":"230184","name":"五常市"}]},{"code":"2302","name":"齐齐哈尔市","childs":[{"code":"230202","name":"龙沙区"},{"code":"230203","name":"建华区"},{"code":"230204","name":"铁锋区"},{"code":"230205","name":"昂昂溪区"},{"code":"230206","name":"富拉尔基区"},{"code":"230207","name":"碾子山区"},{"code":"230208","name":"梅里斯达斡尔族区"},{"code":"230221","name":"龙江县"},{"code":"230223","name":"依安县"},{"code":"230224","name":"泰来县"},{"code":"230225","name":"甘南县"},{"code":"230227","name":"富裕县"},{"code":"230229","name":"克山县"},{"code":"230230","name":"克东县"},{"code":"230231","name":"拜泉县"},{"code":"230281","name":"讷河市"}]},{"code":"2303","name":"鸡西市","childs":[{"code":"230302","name":"鸡冠区"},{"code":"230303","name":"恒山区"},{"code":"230304","name":"滴道区"},{"code":"230305","name":"梨树区"},{"code":"230306","name":"城子河区"},{"code":"230307","name":"麻山区"},{"code":"230321","name":"鸡东县"},{"code":"230381","name":"虎林市"},{"code":"230382","name":"密山市"}]},{"code":"2304","name":"鹤岗市","childs":[{"code":"230402","name":"向阳区"},{"code":"230403","name":"工农区"},{"code":"230404","name":"南山区"},{"code":"230405","name":"兴安区"},{"code":"230406","name":"东山区"},{"code":"230407","name":"兴山区"},{"code":"230421","name":"萝北县"},{"code":"230422","name":"绥滨县"}]},{"code":"2305","name":"双鸭山市","childs":[{"code":"230502","name":"尖山区"},{"code":"230503","name":"岭东区"},{"code":"230505","name":"四方台区"},{"code":"230506","name":"宝山区"},{"code":"230521","name":"集贤县"},{"code":"230522","name":"友谊县"},{"code":"230523","name":"宝清县"},{"code":"230524","name":"饶河县"}]},{"code":"2306","name":"大庆市","childs":[{"code":"230602","name":"萨尔图区"},{"code":"230603","name":"龙凤区"},{"code":"230604","name":"让胡路区"},{"code":"230605","name":"红岗区"},{"code":"230606","name":"大同区"},{"code":"230621","name":"肇州县"},{"code":"230622","name":"肇源县"},{"code":"230623","name":"林甸县"},{"code":"230624","name":"杜尔伯特蒙古族自治县"}]},{"code":"2307","name":"伊春市","childs":[{"code":"230702","name":"伊春区"},{"code":"230703","name":"南岔区"},{"code":"230704","name":"友好区"},{"code":"230705","name":"西林区"},{"code":"230706","name":"翠峦区"},{"code":"230707","name":"新青区"},{"code":"230708","name":"美溪区"},{"code":"230709","name":"金山屯区"},{"code":"230710","name":"五营区"},{"code":"230711","name":"乌马河区"},{"code":"230712","name":"汤旺河区"},{"code":"230713","name":"带岭区"},{"code":"230714","name":"乌伊岭区"},{"code":"230715","name":"红星区"},{"code":"230716","name":"上甘岭区"},{"code":"230722","name":"嘉荫县"},{"code":"230781","name":"铁力市"}]},{"code":"2308","name":"佳木斯市","childs":[{"code":"230803","name":"向阳区"},{"code":"230804","name":"前进区"},{"code":"230805","name":"东风区"},{"code":"230811","name":"郊区"},{"code":"230822","name":"桦南县"},{"code":"230826","name":"桦川县"},{"code":"230828","name":"汤原县"},{"code":"230881","name":"同江市"},{"code":"230882","name":"富锦市"},{"code":"230883","name":"抚远市"}]},{"code":"2309","name":"七台河市","childs":[{"code":"230902","name":"新兴区"},{"code":"230903","name":"桃山区"},{"code":"230904","name":"茄子河区"},{"code":"230921","name":"勃利县"}]},{"code":"2310","name":"牡丹江市","childs":[{"code":"231002","name":"东安区"},{"code":"231003","name":"阳明区"},{"code":"231004","name":"爱民区"},{"code":"231005","name":"西安区"},{"code":"231025","name":"林口县"},{"code":"231081","name":"绥芬河市"},{"code":"231083","name":"海林市"},{"code":"231084","name":"宁安市"},{"code":"231085","name":"穆棱市"},{"code":"231086","name":"东宁市"}]},{"code":"2311","name":"黑河市","childs":[{"code":"231102","name":"爱辉区"},{"code":"231121","name":"嫩江县"},{"code":"231123","name":"逊克县"},{"code":"231124","name":"孙吴县"},{"code":"231181","name":"北安市"},{"code":"231182","name":"五大连池市"}]},{"code":"2312","name":"绥化市","childs":[{"code":"231202","name":"北林区"},{"code":"231221","name":"望奎县"},{"code":"231222","name":"兰西县"},{"code":"231223","name":"青冈县"},{"code":"231224","name":"庆安县"},{"code":"231225","name":"明水县"},{"code":"231226","name":"绥棱县"},{"code":"231281","name":"安达市"},{"code":"231282","name":"肇东市"},{"code":"231283","name":"海伦市"}]},{"code":"2327","name":"大兴安岭地区","childs":[{"code":"232721","name":"呼玛县"},{"code":"232722","name":"塔河县"},{"code":"232723","name":"漠河县"}]}]},{"code":"31","name":"上海市","childs":[{"code":"3101","name":"市辖区","childs":[{"code":"310101","name":"黄浦区"},{"code":"310104","name":"徐汇区"},{"code":"310105","name":"长宁区"},{"code":"310106","name":"静安区"},{"code":"310107","name":"普陀区"},{"code":"310109","name":"虹口区"},{"code":"310110","name":"杨浦区"},{"code":"310112","name":"闵行区"},{"code":"310113","name":"宝山区"},{"code":"310114","name":"嘉定区"},{"code":"310115","name":"浦东新区"},{"code":"310116","name":"金山区"},{"code":"310117","name":"松江区"},{"code":"310118","name":"青浦区"},{"code":"310120","name":"奉贤区"},{"code":"310151","name":"崇明区"}]}]},{"code":"32","name":"江苏省","childs":[{"code":"3201","name":"南京市","childs":[{"code":"320102","name":"玄武区"},{"code":"320104","name":"秦淮区"},{"code":"320105","name":"建邺区"},{"code":"320106","name":"鼓楼区"},{"code":"320111","name":"浦口区"},{"code":"320113","name":"栖霞区"},{"code":"320114","name":"雨花台区"},{"code":"320115","name":"江宁区"},{"code":"320116","name":"六合区"},{"code":"320117","name":"溧水区"},{"code":"320118","name":"高淳区"}]},{"code":"3202","name":"无锡市","childs":[{"code":"320205","name":"锡山区"},{"code":"320206","name":"惠山区"},{"code":"320211","name":"滨湖区"},{"code":"320213","name":"梁溪区"},{"code":"320214","name":"新吴区"},{"code":"320281","name":"江阴市"},{"code":"320282","name":"宜兴市"}]},{"code":"3203","name":"徐州市","childs":[{"code":"320302","name":"鼓楼区"},{"code":"320303","name":"云龙区"},{"code":"320305","name":"贾汪区"},{"code":"320311","name":"泉山区"},{"code":"320312","name":"铜山区"},{"code":"320321","name":"丰县"},{"code":"320322","name":"沛县"},{"code":"320324","name":"睢宁县"},{"code":"320381","name":"新沂市"},{"code":"320382","name":"邳州市"}]},{"code":"3204","name":"常州市","childs":[{"code":"320402","name":"天宁区"},{"code":"320404","name":"钟楼区"},{"code":"320411","name":"新北区"},{"code":"320412","name":"武进区"},{"code":"320413","name":"金坛区"},{"code":"320481","name":"溧阳市"}]},{"code":"3205","name":"苏州市","childs":[{"code":"320505","name":"虎丘区"},{"code":"320506","name":"吴中区"},{"code":"320507","name":"相城区"},{"code":"320508","name":"姑苏区"},{"code":"320509","name":"吴江区"},{"code":"320581","name":"常熟市"},{"code":"320582","name":"张家港市"},{"code":"320583","name":"昆山市"},{"code":"320585","name":"太仓市"}]},{"code":"3206","name":"南通市","childs":[{"code":"320602","name":"崇川区"},{"code":"320611","name":"港闸区"},{"code":"320612","name":"通州区"},{"code":"320621","name":"海安县"},{"code":"320623","name":"如东县"},{"code":"320681","name":"启东市"},{"code":"320682","name":"如皋市"},{"code":"320684","name":"海门市"}]},{"code":"3207","name":"连云港市","childs":[{"code":"320703","name":"连云区"},{"code":"320706","name":"海州区"},{"code":"320707","name":"赣榆区"},{"code":"320722","name":"东海县"},{"code":"320723","name":"灌云县"},{"code":"320724","name":"灌南县"}]},{"code":"3208","name":"淮安市","childs":[{"code":"320803","name":"淮安区"},{"code":"320804","name":"淮阴区"},{"code":"320812","name":"清江浦区"},{"code":"320813","name":"洪泽区"},{"code":"320826","name":"涟水县"},{"code":"320830","name":"盱眙县"},{"code":"320831","name":"金湖县"}]},{"code":"3209","name":"盐城市","childs":[{"code":"320902","name":"亭湖区"},{"code":"320903","name":"盐都区"},{"code":"320904","name":"大丰区"},{"code":"320921","name":"响水县"},{"code":"320922","name":"滨海县"},{"code":"320923","name":"阜宁县"},{"code":"320924","name":"射阳县"},{"code":"320925","name":"建湖县"},{"code":"320981","name":"东台市"}]},{"code":"3210","name":"扬州市","childs":[{"code":"321002","name":"广陵区"},{"code":"321003","name":"邗江区"},{"code":"321012","name":"江都区"},{"code":"321023","name":"宝应县"},{"code":"321081","name":"仪征市"},{"code":"321084","name":"高邮市"}]},{"code":"3211","name":"镇江市","childs":[{"code":"321102","name":"京口区"},{"code":"321111","name":"润州区"},{"code":"321112","name":"丹徒区"},{"code":"321181","name":"丹阳市"},{"code":"321182","name":"扬中市"},{"code":"321183","name":"句容市"}]},{"code":"3212","name":"泰州市","childs":[{"code":"321202","name":"海陵区"},{"code":"321203","name":"高港区"},{"code":"321204","name":"姜堰区"},{"code":"321281","name":"兴化市"},{"code":"321282","name":"靖江市"},{"code":"321283","name":"泰兴市"}]},{"code":"3213","name":"宿迁市","childs":[{"code":"321302","name":"宿城区"},{"code":"321311","name":"宿豫区"},{"code":"321322","name":"沭阳县"},{"code":"321323","name":"泗阳县"},{"code":"321324","name":"泗洪县"}]}]},{"code":"33","name":"浙江省","childs":[{"code":"3301","name":"杭州市","childs":[{"code":"330102","name":"上城区"},{"code":"330103","name":"下城区"},{"code":"330104","name":"江干区"},{"code":"330105","name":"拱墅区"},{"code":"330106","name":"西湖区"},{"code":"330108","name":"滨江区"},{"code":"330109","name":"萧山区"},{"code":"330110","name":"余杭区"},{"code":"330111","name":"富阳区"},{"code":"330122","name":"桐庐县"},{"code":"330127","name":"淳安县"},{"code":"330182","name":"建德市"},{"code":"330185","name":"临安市"}]},{"code":"3302","name":"宁波市","childs":[{"code":"330203","name":"海曙区"},{"code":"330204","name":"江东区"},{"code":"330205","name":"江北区"},{"code":"330206","name":"北仑区"},{"code":"330211","name":"镇海区"},{"code":"330212","name":"鄞州区"},{"code":"330225","name":"象山县"},{"code":"330226","name":"宁海县"},{"code":"330281","name":"余姚市"},{"code":"330282","name":"慈溪市"},{"code":"330283","name":"奉化市"}]},{"code":"3303","name":"温州市","childs":[{"code":"330302","name":"鹿城区"},{"code":"330303","name":"龙湾区"},{"code":"330304","name":"瓯海区"},{"code":"330305","name":"洞头区"},{"code":"330324","name":"永嘉县"},{"code":"330326","name":"平阳县"},{"code":"330327","name":"苍南县"},{"code":"330328","name":"文成县"},{"code":"330329","name":"泰顺县"},{"code":"330381","name":"瑞安市"},{"code":"330382","name":"乐清市"}]},{"code":"3304","name":"嘉兴市","childs":[{"code":"330402","name":"南湖区"},{"code":"330411","name":"秀洲区"},{"code":"330421","name":"嘉善县"},{"code":"330424","name":"海盐县"},{"code":"330481","name":"海宁市"},{"code":"330482","name":"平湖市"},{"code":"330483","name":"桐乡市"}]},{"code":"3305","name":"湖州市","childs":[{"code":"330502","name":"吴兴区"},{"code":"330503","name":"南浔区"},{"code":"330521","name":"德清县"},{"code":"330522","name":"长兴县"},{"code":"330523","name":"安吉县"}]},{"code":"3306","name":"绍兴市","childs":[{"code":"330602","name":"越城区"},{"code":"330603","name":"柯桥区"},{"code":"330604","name":"上虞区"},{"code":"330624","name":"新昌县"},{"code":"330681","name":"诸暨市"},{"code":"330683","name":"嵊州市"}]},{"code":"3307","name":"金华市","childs":[{"code":"330702","name":"婺城区"},{"code":"330703","name":"金东区"},{"code":"330723","name":"武义县"},{"code":"330726","name":"浦江县"},{"code":"330727","name":"磐安县"},{"code":"330781","name":"兰溪市"},{"code":"330782","name":"义乌市"},{"code":"330783","name":"东阳市"},{"code":"330784","name":"永康市"}]},{"code":"3308","name":"衢州市","childs":[{"code":"330802","name":"柯城区"},{"code":"330803","name":"衢江区"},{"code":"330822","name":"常山县"},{"code":"330824","name":"开化县"},{"code":"330825","name":"龙游县"},{"code":"330881","name":"江山市"}]},{"code":"3309","name":"舟山市","childs":[{"code":"330902","name":"定海区"},{"code":"330903","name":"普陀区"},{"code":"330921","name":"岱山县"},{"code":"330922","name":"嵊泗县"}]},{"code":"3310","name":"台州市","childs":[{"code":"331002","name":"椒江区"},{"code":"331003","name":"黄岩区"},{"code":"331004","name":"路桥区"},{"code":"331021","name":"玉环县"},{"code":"331022","name":"三门县"},{"code":"331023","name":"天台县"},{"code":"331024","name":"仙居县"},{"code":"331081","name":"温岭市"},{"code":"331082","name":"临海市"}]},{"code":"3311","name":"丽水市","childs":[{"code":"331102","name":"莲都区"},{"code":"331121","name":"青田县"},{"code":"331122","name":"缙云县"},{"code":"331123","name":"遂昌县"},{"code":"331124","name":"松阳县"},{"code":"331125","name":"云和县"},{"code":"331126","name":"庆元县"},{"code":"331127","name":"景宁畲族自治县"},{"code":"331181","name":"龙泉市"}]}]},{"code":"34","name":"安徽省","childs":[{"code":"3401","name":"合肥市","childs":[{"code":"340102","name":"瑶海区"},{"code":"340103","name":"庐阳区"},{"code":"340104","name":"蜀山区"},{"code":"340111","name":"包河区"},{"code":"340121","name":"长丰县"},{"code":"340122","name":"肥东县"},{"code":"340123","name":"肥西县"},{"code":"340124","name":"庐江县"},{"code":"340181","name":"巢湖市"}]},{"code":"3402","name":"芜湖市","childs":[{"code":"340202","name":"镜湖区"},{"code":"340203","name":"弋江区"},{"code":"340207","name":"鸠江区"},{"code":"340208","name":"三山区"},{"code":"340221","name":"芜湖县"},{"code":"340222","name":"繁昌县"},{"code":"340223","name":"南陵县"},{"code":"340225","name":"无为县"}]},{"code":"3403","name":"蚌埠市","childs":[{"code":"340302","name":"龙子湖区"},{"code":"340303","name":"蚌山区"},{"code":"340304","name":"禹会区"},{"code":"340311","name":"淮上区"},{"code":"340321","name":"怀远县"},{"code":"340322","name":"五河县"},{"code":"340323","name":"固镇县"}]},{"code":"3404","name":"淮南市","childs":[{"code":"340402","name":"大通区"},{"code":"340403","name":"田家庵区"},{"code":"340404","name":"谢家集区"},{"code":"340405","name":"八公山区"},{"code":"340406","name":"潘集区"},{"code":"340421","name":"凤台县"},{"code":"340422","name":"寿县"}]},{"code":"3405","name":"马鞍山市","childs":[{"code":"340503","name":"花山区"},{"code":"340504","name":"雨山区"},{"code":"340506","name":"博望区"},{"code":"340521","name":"当涂县"},{"code":"340522","name":"含山县"},{"code":"340523","name":"和县"}]},{"code":"3406","name":"淮北市","childs":[{"code":"340602","name":"杜集区"},{"code":"340603","name":"相山区"},{"code":"340604","name":"烈山区"},{"code":"340621","name":"濉溪县"}]},{"code":"3407","name":"铜陵市","childs":[{"code":"340705","name":"铜官区"},{"code":"340706","name":"义安区"},{"code":"340711","name":"郊区"},{"code":"340722","name":"枞阳县"}]},{"code":"3408","name":"安庆市","childs":[{"code":"340802","name":"迎江区"},{"code":"340803","name":"大观区"},{"code":"340811","name":"宜秀区"},{"code":"340822","name":"怀宁县"},{"code":"340824","name":"潜山县"},{"code":"340825","name":"太湖县"},{"code":"340826","name":"宿松县"},{"code":"340827","name":"望江县"},{"code":"340828","name":"岳西县"},{"code":"340881","name":"桐城市"}]},{"code":"3410","name":"黄山市","childs":[{"code":"341002","name":"屯溪区"},{"code":"341003","name":"黄山区"},{"code":"341004","name":"徽州区"},{"code":"341021","name":"歙县"},{"code":"341022","name":"休宁县"},{"code":"341023","name":"黟县"},{"code":"341024","name":"祁门县"}]},{"code":"3411","name":"滁州市","childs":[{"code":"341102","name":"琅琊区"},{"code":"341103","name":"南谯区"},{"code":"341122","name":"来安县"},{"code":"341124","name":"全椒县"},{"code":"341125","name":"定远县"},{"code":"341126","name":"凤阳县"},{"code":"341181","name":"天长市"},{"code":"341182","name":"明光市"}]},{"code":"3412","name":"阜阳市","childs":[{"code":"341202","name":"颍州区"},{"code":"341203","name":"颍东区"},{"code":"341204","name":"颍泉区"},{"code":"341221","name":"临泉县"},{"code":"341222","name":"太和县"},{"code":"341225","name":"阜南县"},{"code":"341226","name":"颍上县"},{"code":"341282","name":"界首市"}]},{"code":"3413","name":"宿州市","childs":[{"code":"341302","name":"埇桥区"},{"code":"341321","name":"砀山县"},{"code":"341322","name":"萧县"},{"code":"341323","name":"灵璧县"},{"code":"341324","name":"泗县"}]},{"code":"3415","name":"六安市","childs":[{"code":"341502","name":"金安区"},{"code":"341503","name":"裕安区"},{"code":"341504","name":"叶集区"},{"code":"341522","name":"霍邱县"},{"code":"341523","name":"舒城县"},{"code":"341524","name":"金寨县"},{"code":"341525","name":"霍山县"}]},{"code":"3416","name":"亳州市","childs":[{"code":"341602","name":"谯城区"},{"code":"341621","name":"涡阳县"},{"code":"341622","name":"蒙城县"},{"code":"341623","name":"利辛县"}]},{"code":"3417","name":"池州市","childs":[{"code":"341702","name":"贵池区"},{"code":"341721","name":"东至县"},{"code":"341722","name":"石台县"},{"code":"341723","name":"青阳县"}]},{"code":"3418","name":"宣城市","childs":[{"code":"341802","name":"宣州区"},{"code":"341821","name":"郎溪县"},{"code":"341822","name":"广德县"},{"code":"341823","name":"泾县"},{"code":"341824","name":"绩溪县"},{"code":"341825","name":"旌德县"},{"code":"341881","name":"宁国市"}]}]},{"code":"35","name":"福建省","childs":[{"code":"3501","name":"福州市","childs":[{"code":"350102","name":"鼓楼区"},{"code":"350103","name":"台江区"},{"code":"350104","name":"仓山区"},{"code":"350105","name":"马尾区"},{"code":"350111","name":"晋安区"},{"code":"350121","name":"闽侯县"},{"code":"350122","name":"连江县"},{"code":"350123","name":"罗源县"},{"code":"350124","name":"闽清县"},{"code":"350125","name":"永泰县"},{"code":"350128","name":"平潭县"},{"code":"350181","name":"福清市"},{"code":"350182","name":"长乐市"}]},{"code":"3502","name":"厦门市","childs":[{"code":"350203","name":"思明区"},{"code":"350205","name":"海沧区"},{"code":"350206","name":"湖里区"},{"code":"350211","name":"集美区"},{"code":"350212","name":"同安区"},{"code":"350213","name":"翔安区"}]},{"code":"3503","name":"莆田市","childs":[{"code":"350302","name":"城厢区"},{"code":"350303","name":"涵江区"},{"code":"350304","name":"荔城区"},{"code":"350305","name":"秀屿区"},{"code":"350322","name":"仙游县"}]},{"code":"3504","name":"三明市","childs":[{"code":"350402","name":"梅列区"},{"code":"350403","name":"三元区"},{"code":"350421","name":"明溪县"},{"code":"350423","name":"清流县"},{"code":"350424","name":"宁化县"},{"code":"350425","name":"大田县"},{"code":"350426","name":"尤溪县"},{"code":"350427","name":"沙县"},{"code":"350428","name":"将乐县"},{"code":"350429","name":"泰宁县"},{"code":"350430","name":"建宁县"},{"code":"350481","name":"永安市"}]},{"code":"3505","name":"泉州市","childs":[{"code":"350502","name":"鲤城区"},{"code":"350503","name":"丰泽区"},{"code":"350504","name":"洛江区"},{"code":"350505","name":"泉港区"},{"code":"350521","name":"惠安县"},{"code":"350524","name":"安溪县"},{"code":"350525","name":"永春县"},{"code":"350526","name":"德化县"},{"code":"350527","name":"金门县"},{"code":"350581","name":"石狮市"},{"code":"350582","name":"晋江市"},{"code":"350583","name":"南安市"}]},{"code":"3506","name":"漳州市","childs":[{"code":"350602","name":"芗城区"},{"code":"350603","name":"龙文区"},{"code":"350622","name":"云霄县"},{"code":"350623","name":"漳浦县"},{"code":"350624","name":"诏安县"},{"code":"350625","name":"长泰县"},{"code":"350626","name":"东山县"},{"code":"350627","name":"南靖县"},{"code":"350628","name":"平和县"},{"code":"350629","name":"华安县"},{"code":"350681","name":"龙海市"}]},{"code":"3507","name":"南平市","childs":[{"code":"350702","name":"延平区"},{"code":"350703","name":"建阳区"},{"code":"350721","name":"顺昌县"},{"code":"350722","name":"浦城县"},{"code":"350723","name":"光泽县"},{"code":"350724","name":"松溪县"},{"code":"350725","name":"政和县"},{"code":"350781","name":"邵武市"},{"code":"350782","name":"武夷山市"},{"code":"350783","name":"建瓯市"}]},{"code":"3508","name":"龙岩市","childs":[{"code":"350802","name":"新罗区"},{"code":"350803","name":"永定区"},{"code":"350821","name":"长汀县"},{"code":"350823","name":"上杭县"},{"code":"350824","name":"武平县"},{"code":"350825","name":"连城县"},{"code":"350881","name":"漳平市"}]},{"code":"3509","name":"宁德市","childs":[{"code":"350902","name":"蕉城区"},{"code":"350921","name":"霞浦县"},{"code":"350922","name":"古田县"},{"code":"350923","name":"屏南县"},{"code":"350924","name":"寿宁县"},{"code":"350925","name":"周宁县"},{"code":"350926","name":"柘荣县"},{"code":"350981","name":"福安市"},{"code":"350982","name":"福鼎市"}]}]},{"code":"36","name":"江西省","childs":[{"code":"3601","name":"南昌市","childs":[{"code":"360102","name":"东湖区"},{"code":"360103","name":"西湖区"},{"code":"360104","name":"青云谱区"},{"code":"360105","name":"湾里区"},{"code":"360111","name":"青山湖区"},{"code":"360112","name":"新建区"},{"code":"360121","name":"南昌县"},{"code":"360123","name":"安义县"},{"code":"360124","name":"进贤县"}]},{"code":"3602","name":"景德镇市","childs":[{"code":"360202","name":"昌江区"},{"code":"360203","name":"珠山区"},{"code":"360222","name":"浮梁县"},{"code":"360281","name":"乐平市"}]},{"code":"3603","name":"萍乡市","childs":[{"code":"360302","name":"安源区"},{"code":"360313","name":"湘东区"},{"code":"360321","name":"莲花县"},{"code":"360322","name":"上栗县"},{"code":"360323","name":"芦溪县"}]},{"code":"3604","name":"九江市","childs":[{"code":"360402","name":"濂溪区"},{"code":"360403","name":"浔阳区"},{"code":"360421","name":"九江县"},{"code":"360423","name":"武宁县"},{"code":"360424","name":"修水县"},{"code":"360425","name":"永修县"},{"code":"360426","name":"德安县"},{"code":"360428","name":"都昌县"},{"code":"360429","name":"湖口县"},{"code":"360430","name":"彭泽县"},{"code":"360481","name":"瑞昌市"},{"code":"360482","name":"共青城市"},{"code":"360483","name":"庐山市"}]},{"code":"3605","name":"新余市","childs":[{"code":"360502","name":"渝水区"},{"code":"360521","name":"分宜县"}]},{"code":"3606","name":"鹰潭市","childs":[{"code":"360602","name":"月湖区"},{"code":"360622","name":"余江县"},{"code":"360681","name":"贵溪市"}]},{"code":"3607","name":"赣州市","childs":[{"code":"360702","name":"章贡区"},{"code":"360703","name":"南康区"},{"code":"360721","name":"赣县"},{"code":"360722","name":"信丰县"},{"code":"360723","name":"大余县"},{"code":"360724","name":"上犹县"},{"code":"360725","name":"崇义县"},{"code":"360726","name":"安远县"},{"code":"360727","name":"龙南县"},{"code":"360728","name":"定南县"},{"code":"360729","name":"全南县"},{"code":"360730","name":"宁都县"},{"code":"360731","name":"于都县"},{"code":"360732","name":"兴国县"},{"code":"360733","name":"会昌县"},{"code":"360734","name":"寻乌县"},{"code":"360735","name":"石城县"},{"code":"360781","name":"瑞金市"}]},{"code":"3608","name":"吉安市","childs":[{"code":"360802","name":"吉州区"},{"code":"360803","name":"青原区"},{"code":"360821","name":"吉安县"},{"code":"360822","name":"吉水县"},{"code":"360823","name":"峡江县"},{"code":"360824","name":"新干县"},{"code":"360825","name":"永丰县"},{"code":"360826","name":"泰和县"},{"code":"360827","name":"遂川县"},{"code":"360828","name":"万安县"},{"code":"360829","name":"安福县"},{"code":"360830","name":"永新县"},{"code":"360881","name":"井冈山市"}]},{"code":"3609","name":"宜春市","childs":[{"code":"360902","name":"袁州区"},{"code":"360921","name":"奉新县"},{"code":"360922","name":"万载县"},{"code":"360923","name":"上高县"},{"code":"360924","name":"宜丰县"},{"code":"360925","name":"靖安县"},{"code":"360926","name":"铜鼓县"},{"code":"360981","name":"丰城市"},{"code":"360982","name":"樟树市"},{"code":"360983","name":"高安市"}]},{"code":"3610","name":"抚州市","childs":[{"code":"361002","name":"临川区"},{"code":"361021","name":"南城县"},{"code":"361022","name":"黎川县"},{"code":"361023","name":"南丰县"},{"code":"361024","name":"崇仁县"},{"code":"361025","name":"乐安县"},{"code":"361026","name":"宜黄县"},{"code":"361027","name":"金溪县"},{"code":"361028","name":"资溪县"},{"code":"361029","name":"东乡县"},{"code":"361030","name":"广昌县"}]},{"code":"3611","name":"上饶市","childs":[{"code":"361102","name":"信州区"},{"code":"361103","name":"广丰区"},{"code":"361121","name":"上饶县"},{"code":"361123","name":"玉山县"},{"code":"361124","name":"铅山县"},{"code":"361125","name":"横峰县"},{"code":"361126","name":"弋阳县"},{"code":"361127","name":"余干县"},{"code":"361128","name":"鄱阳县"},{"code":"361129","name":"万年县"},{"code":"361130","name":"婺源县"},{"code":"361181","name":"德兴市"}]}]},{"code":"37","name":"山东省","childs":[{"code":"3701","name":"济南市","childs":[{"code":"370102","name":"历下区"},{"code":"370103","name":"市中区"},{"code":"370104","name":"槐荫区"},{"code":"370105","name":"天桥区"},{"code":"370112","name":"历城区"},{"code":"370113","name":"长清区"},{"code":"370124","name":"平阴县"},{"code":"370125","name":"济阳县"},{"code":"370126","name":"商河县"},{"code":"370181","name":"章丘市"}]},{"code":"3702","name":"青岛市","childs":[{"code":"370202","name":"市南区"},{"code":"370203","name":"市北区"},{"code":"370211","name":"黄岛区"},{"code":"370212","name":"崂山区"},{"code":"370213","name":"李沧区"},{"code":"370214","name":"城阳区"},{"code":"370281","name":"胶州市"},{"code":"370282","name":"即墨市"},{"code":"370283","name":"平度市"},{"code":"370285","name":"莱西市"}]},{"code":"3703","name":"淄博市","childs":[{"code":"370302","name":"淄川区"},{"code":"370303","name":"张店区"},{"code":"370304","name":"博山区"},{"code":"370305","name":"临淄区"},{"code":"370306","name":"周村区"},{"code":"370321","name":"桓台县"},{"code":"370322","name":"高青县"},{"code":"370323","name":"沂源县"}]},{"code":"3704","name":"枣庄市","childs":[{"code":"370402","name":"市中区"},{"code":"370403","name":"薛城区"},{"code":"370404","name":"峄城区"},{"code":"370405","name":"台儿庄区"},{"code":"370406","name":"山亭区"},{"code":"370481","name":"滕州市"}]},{"code":"3705","name":"东营市","childs":[{"code":"370502","name":"东营区"},{"code":"370503","name":"河口区"},{"code":"370505","name":"垦利区"},{"code":"370522","name":"利津县"},{"code":"370523","name":"广饶县"}]},{"code":"3706","name":"烟台市","childs":[{"code":"370602","name":"芝罘区"},{"code":"370611","name":"福山区"},{"code":"370612","name":"牟平区"},{"code":"370613","name":"莱山区"},{"code":"370634","name":"长岛县"},{"code":"370681","name":"龙口市"},{"code":"370682","name":"莱阳市"},{"code":"370683","name":"莱州市"},{"code":"370684","name":"蓬莱市"},{"code":"370685","name":"招远市"},{"code":"370686","name":"栖霞市"},{"code":"370687","name":"海阳市"}]},{"code":"3707","name":"潍坊市","childs":[{"code":"370702","name":"潍城区"},{"code":"370703","name":"寒亭区"},{"code":"370704","name":"坊子区"},{"code":"370705","name":"奎文区"},{"code":"370724","name":"临朐县"},{"code":"370725","name":"昌乐县"},{"code":"370781","name":"青州市"},{"code":"370782","name":"诸城市"},{"code":"370783","name":"寿光市"},{"code":"370784","name":"安丘市"},{"code":"370785","name":"高密市"},{"code":"370786","name":"昌邑市"}]},{"code":"3708","name":"济宁市","childs":[{"code":"370811","name":"任城区"},{"code":"370812","name":"兖州区"},{"code":"370826","name":"微山县"},{"code":"370827","name":"鱼台县"},{"code":"370828","name":"金乡县"},{"code":"370829","name":"嘉祥县"},{"code":"370830","name":"汶上县"},{"code":"370831","name":"泗水县"},{"code":"370832","name":"梁山县"},{"code":"370881","name":"曲阜市"},{"code":"370883","name":"邹城市"}]},{"code":"3709","name":"泰安市","childs":[{"code":"370902","name":"泰山区"},{"code":"370911","name":"岱岳区"},{"code":"370921","name":"宁阳县"},{"code":"370923","name":"东平县"},{"code":"370982","name":"新泰市"},{"code":"370983","name":"肥城市"}]},{"code":"3710","name":"威海市","childs":[{"code":"371002","name":"环翠区"},{"code":"371003","name":"文登区"},{"code":"371082","name":"荣成市"},{"code":"371083","name":"乳山市"}]},{"code":"3711","name":"日照市","childs":[{"code":"371102","name":"东港区"},{"code":"371103","name":"岚山区"},{"code":"371121","name":"五莲县"},{"code":"371122","name":"莒县"}]},{"code":"3712","name":"莱芜市","childs":[{"code":"371202","name":"莱城区"},{"code":"371203","name":"钢城区"}]},{"code":"3713","name":"临沂市","childs":[{"code":"371302","name":"兰山区"},{"code":"371311","name":"罗庄区"},{"code":"371312","name":"河东区"},{"code":"371321","name":"沂南县"},{"code":"371322","name":"郯城县"},{"code":"371323","name":"沂水县"},{"code":"371324","name":"兰陵县"},{"code":"371325","name":"费县"},{"code":"371326","name":"平邑县"},{"code":"371327","name":"莒南县"},{"code":"371328","name":"蒙阴县"},{"code":"371329","name":"临沭县"}]},{"code":"3714","name":"德州市","childs":[{"code":"371402","name":"德城区"},{"code":"371403","name":"陵城区"},{"code":"371422","name":"宁津县"},{"code":"371423","name":"庆云县"},{"code":"371424","name":"临邑县"},{"code":"371425","name":"齐河县"},{"code":"371426","name":"平原县"},{"code":"371427","name":"夏津县"},{"code":"371428","name":"武城县"},{"code":"371481","name":"乐陵市"},{"code":"371482","name":"禹城市"}]},{"code":"3715","name":"聊城市","childs":[{"code":"371502","name":"东昌府区"},{"code":"371521","name":"阳谷县"},{"code":"371522","name":"莘县"},{"code":"371523","name":"茌平县"},{"code":"371524","name":"东阿县"},{"code":"371525","name":"冠县"},{"code":"371526","name":"高唐县"},{"code":"371581","name":"临清市"}]},{"code":"3716","name":"滨州市","childs":[{"code":"371602","name":"滨城区"},{"code":"371603","name":"沾化区"},{"code":"371621","name":"惠民县"},{"code":"371622","name":"阳信县"},{"code":"371623","name":"无棣县"},{"code":"371625","name":"博兴县"},{"code":"371626","name":"邹平县"}]},{"code":"3717","name":"菏泽市","childs":[{"code":"371702","name":"牡丹区"},{"code":"371703","name":"定陶区"},{"code":"371721","name":"曹县"},{"code":"371722","name":"单县"},{"code":"371723","name":"成武县"},{"code":"371724","name":"巨野县"},{"code":"371725","name":"郓城县"},{"code":"371726","name":"鄄城县"},{"code":"371728","name":"东明县"}]}]},{"code":"41","name":"河南省","childs":[{"code":"4101","name":"郑州市","childs":[{"code":"410102","name":"中原区"},{"code":"410103","name":"二七区"},{"code":"410104","name":"管城回族区"},{"code":"410105","name":"金水区"},{"code":"410106","name":"上街区"},{"code":"410108","name":"惠济区"},{"code":"410122","name":"中牟县"},{"code":"410181","name":"巩义市"},{"code":"410182","name":"荥阳市"},{"code":"410183","name":"新密市"},{"code":"410184","name":"新郑市"},{"code":"410185","name":"登封市"}]},{"code":"4102","name":"开封市","childs":[{"code":"410202","name":"龙亭区"},{"code":"410203","name":"顺河回族区"},{"code":"410204","name":"鼓楼区"},{"code":"410205","name":"禹王台区"},{"code":"410211","name":"金明区"},{"code":"410212","name":"祥符区"},{"code":"410221","name":"杞县"},{"code":"410222","name":"通许县"},{"code":"410223","name":"尉氏县"},{"code":"410225","name":"兰考县"}]},{"code":"4103","name":"洛阳市","childs":[{"code":"410302","name":"老城区"},{"code":"410303","name":"西工区"},{"code":"410304","name":"瀍河回族区"},{"code":"410305","name":"涧西区"},{"code":"410306","name":"吉利区"},{"code":"410311","name":"洛龙区"},{"code":"410322","name":"孟津县"},{"code":"410323","name":"新安县"},{"code":"410324","name":"栾川县"},{"code":"410325","name":"嵩县"},{"code":"410326","name":"汝阳县"},{"code":"410327","name":"宜阳县"},{"code":"410328","name":"洛宁县"},{"code":"410329","name":"伊川县"},{"code":"410381","name":"偃师市"}]},{"code":"4104","name":"平顶山市","childs":[{"code":"410402","name":"新华区"},{"code":"410403","name":"卫东区"},{"code":"410404","name":"石龙区"},{"code":"410411","name":"湛河区"},{"code":"410421","name":"宝丰县"},{"code":"410422","name":"叶县"},{"code":"410423","name":"鲁山县"},{"code":"410425","name":"郏县"},{"code":"410481","name":"舞钢市"},{"code":"410482","name":"汝州市"}]},{"code":"4105","name":"安阳市","childs":[{"code":"410502","name":"文峰区"},{"code":"410503","name":"北关区"},{"code":"410505","name":"殷都区"},{"code":"410506","name":"龙安区"},{"code":"410522","name":"安阳县"},{"code":"410523","name":"汤阴县"},{"code":"410526","name":"滑县"},{"code":"410527","name":"内黄县"},{"code":"410581","name":"林州市"}]},{"code":"4106","name":"鹤壁市","childs":[{"code":"410602","name":"鹤山区"},{"code":"410603","name":"山城区"},{"code":"410611","name":"淇滨区"},{"code":"410621","name":"浚县"},{"code":"410622","name":"淇县"}]},{"code":"4107","name":"新乡市","childs":[{"code":"410702","name":"红旗区"},{"code":"410703","name":"卫滨区"},{"code":"410704","name":"凤泉区"},{"code":"410711","name":"牧野区"},{"code":"410721","name":"新乡县"},{"code":"410724","name":"获嘉县"},{"code":"410725","name":"原阳县"},{"code":"410726","name":"延津县"},{"code":"410727","name":"封丘县"},{"code":"410728","name":"长垣县"},{"code":"410781","name":"卫辉市"},{"code":"410782","name":"辉县市"}]},{"code":"4108","name":"焦作市","childs":[{"code":"410802","name":"解放区"},{"code":"410803","name":"中站区"},{"code":"410804","name":"马村区"},{"code":"410811","name":"山阳区"},{"code":"410821","name":"修武县"},{"code":"410822","name":"博爱县"},{"code":"410823","name":"武陟县"},{"code":"410825","name":"温县"},{"code":"410882","name":"沁阳市"},{"code":"410883","name":"孟州市"}]},{"code":"4109","name":"濮阳市","childs":[{"code":"410902","name":"华龙区"},{"code":"410922","name":"清丰县"},{"code":"410923","name":"南乐县"},{"code":"410926","name":"范县"},{"code":"410927","name":"台前县"},{"code":"410928","name":"濮阳县"}]},{"code":"4110","name":"许昌市","childs":[{"code":"411002","name":"魏都区"},{"code":"411023","name":"许昌县"},{"code":"411024","name":"鄢陵县"},{"code":"411025","name":"襄城县"},{"code":"411081","name":"禹州市"},{"code":"411082","name":"长葛市"}]},{"code":"4111","name":"漯河市","childs":[{"code":"411102","name":"源汇区"},{"code":"411103","name":"郾城区"},{"code":"411104","name":"召陵区"},{"code":"411121","name":"舞阳县"},{"code":"411122","name":"临颍县"}]},{"code":"4112","name":"三门峡市","childs":[{"code":"411202","name":"湖滨区"},{"code":"411203","name":"陕州区"},{"code":"411221","name":"渑池县"},{"code":"411224","name":"卢氏县"},{"code":"411281","name":"义马市"},{"code":"411282","name":"灵宝市"}]},{"code":"4113","name":"南阳市","childs":[{"code":"411302","name":"宛城区"},{"code":"411303","name":"卧龙区"},{"code":"411321","name":"南召县"},{"code":"411322","name":"方城县"},{"code":"411323","name":"西峡县"},{"code":"411324","name":"镇平县"},{"code":"411325","name":"内乡县"},{"code":"411326","name":"淅川县"},{"code":"411327","name":"社旗县"},{"code":"411328","name":"唐河县"},{"code":"411329","name":"新野县"},{"code":"411330","name":"桐柏县"},{"code":"411381","name":"邓州市"}]},{"code":"4114","name":"商丘市","childs":[{"code":"411402","name":"梁园区"},{"code":"411403","name":"睢阳区"},{"code":"411421","name":"民权县"},{"code":"411422","name":"睢县"},{"code":"411423","name":"宁陵县"},{"code":"411424","name":"柘城县"},{"code":"411425","name":"虞城县"},{"code":"411426","name":"夏邑县"},{"code":"411481","name":"永城市"}]},{"code":"4115","name":"信阳市","childs":[{"code":"411502","name":"浉河区"},{"code":"411503","name":"平桥区"},{"code":"411521","name":"罗山县"},{"code":"411522","name":"光山县"},{"code":"411523","name":"新县"},{"code":"411524","name":"商城县"},{"code":"411525","name":"固始县"},{"code":"411526","name":"潢川县"},{"code":"411527","name":"淮滨县"},{"code":"411528","name":"息县"}]},{"code":"4116","name":"周口市","childs":[{"code":"411602","name":"川汇区"},{"code":"411621","name":"扶沟县"},{"code":"411622","name":"西华县"},{"code":"411623","name":"商水县"},{"code":"411624","name":"沈丘县"},{"code":"411625","name":"郸城县"},{"code":"411626","name":"淮阳县"},{"code":"411627","name":"太康县"},{"code":"411628","name":"鹿邑县"},{"code":"411681","name":"项城市"}]},{"code":"4117","name":"驻马店市","childs":[{"code":"411702","name":"驿城区"},{"code":"411721","name":"西平县"},{"code":"411722","name":"上蔡县"},{"code":"411723","name":"平舆县"},{"code":"411724","name":"正阳县"},{"code":"411725","name":"确山县"},{"code":"411726","name":"泌阳县"},{"code":"411727","name":"汝南县"},{"code":"411728","name":"遂平县"},{"code":"411729","name":"新蔡县"}]},{"code":"4190","name":"省直辖县级行政区划","childs":[{"code":"419001","name":"济源市"}]}]},{"code":"42","name":"湖北省","childs":[{"code":"4201","name":"武汉市","childs":[{"code":"420102","name":"江岸区"},{"code":"420103","name":"江汉区"},{"code":"420104","name":"硚口区"},{"code":"420105","name":"汉阳区"},{"code":"420106","name":"武昌区"},{"code":"420107","name":"青山区"},{"code":"420111","name":"洪山区"},{"code":"420112","name":"东西湖区"},{"code":"420113","name":"汉南区"},{"code":"420114","name":"蔡甸区"},{"code":"420115","name":"江夏区"},{"code":"420116","name":"黄陂区"},{"code":"420117","name":"新洲区"}]},{"code":"4202","name":"黄石市","childs":[{"code":"420202","name":"黄石港区"},{"code":"420203","name":"西塞山区"},{"code":"420204","name":"下陆区"},{"code":"420205","name":"铁山区"},{"code":"420222","name":"阳新县"},{"code":"420281","name":"大冶市"}]},{"code":"4203","name":"十堰市","childs":[{"code":"420302","name":"茅箭区"},{"code":"420303","name":"张湾区"},{"code":"420304","name":"郧阳区"},{"code":"420322","name":"郧西县"},{"code":"420323","name":"竹山县"},{"code":"420324","name":"竹溪县"},{"code":"420325","name":"房县"},{"code":"420381","name":"丹江口市"}]},{"code":"4205","name":"宜昌市","childs":[{"code":"420502","name":"西陵区"},{"code":"420503","name":"伍家岗区"},{"code":"420504","name":"点军区"},{"code":"420505","name":"猇亭区"},{"code":"420506","name":"夷陵区"},{"code":"420525","name":"远安县"},{"code":"420526","name":"兴山县"},{"code":"420527","name":"秭归县"},{"code":"420528","name":"长阳土家族自治县"},{"code":"420529","name":"五峰土家族自治县"},{"code":"420581","name":"宜都市"},{"code":"420582","name":"当阳市"},{"code":"420583","name":"枝江市"}]},{"code":"4206","name":"襄阳市","childs":[{"code":"420602","name":"襄城区"},{"code":"420606","name":"樊城区"},{"code":"420607","name":"襄州区"},{"code":"420624","name":"南漳县"},{"code":"420625","name":"谷城县"},{"code":"420626","name":"保康县"},{"code":"420682","name":"老河口市"},{"code":"420683","name":"枣阳市"},{"code":"420684","name":"宜城市"}]},{"code":"4207","name":"鄂州市","childs":[{"code":"420702","name":"梁子湖区"},{"code":"420703","name":"华容区"},{"code":"420704","name":"鄂城区"}]},{"code":"4208","name":"荆门市","childs":[{"code":"420802","name":"东宝区"},{"code":"420804","name":"掇刀区"},{"code":"420821","name":"京山县"},{"code":"420822","name":"沙洋县"},{"code":"420881","name":"钟祥市"}]},{"code":"4209","name":"孝感市","childs":[{"code":"420902","name":"孝南区"},{"code":"420921","name":"孝昌县"},{"code":"420922","name":"大悟县"},{"code":"420923","name":"云梦县"},{"code":"420981","name":"应城市"},{"code":"420982","name":"安陆市"},{"code":"420984","name":"汉川市"}]},{"code":"4210","name":"荆州市","childs":[{"code":"421002","name":"沙市区"},{"code":"421003","name":"荆州区"},{"code":"421022","name":"公安县"},{"code":"421023","name":"监利县"},{"code":"421024","name":"江陵县"},{"code":"421081","name":"石首市"},{"code":"421083","name":"洪湖市"},{"code":"421087","name":"松滋市"}]},{"code":"4211","name":"黄冈市","childs":[{"code":"421102","name":"黄州区"},{"code":"421121","name":"团风县"},{"code":"421122","name":"红安县"},{"code":"421123","name":"罗田县"},{"code":"421124","name":"英山县"},{"code":"421125","name":"浠水县"},{"code":"421126","name":"蕲春县"},{"code":"421127","name":"黄梅县"},{"code":"421181","name":"麻城市"},{"code":"421182","name":"武穴市"}]},{"code":"4212","name":"咸宁市","childs":[{"code":"421202","name":"咸安区"},{"code":"421221","name":"嘉鱼县"},{"code":"421222","name":"通城县"},{"code":"421223","name":"崇阳县"},{"code":"421224","name":"通山县"},{"code":"421281","name":"赤壁市"}]},{"code":"4213","name":"随州市","childs":[{"code":"421303","name":"曾都区"},{"code":"421321","name":"随县"},{"code":"421381","name":"广水市"}]},{"code":"4228","name":"恩施土家族苗族自治州","childs":[{"code":"422801","name":"恩施市"},{"code":"422802","name":"利川市"},{"code":"422822","name":"建始县"},{"code":"422823","name":"巴东县"},{"code":"422825","name":"宣恩县"},{"code":"422826","name":"咸丰县"},{"code":"422827","name":"来凤县"},{"code":"422828","name":"鹤峰县"}]},{"code":"4290","name":"省直辖县级行政区划","childs":[{"code":"429004","name":"仙桃市"},{"code":"429005","name":"潜江市"},{"code":"429006","name":"天门市"},{"code":"429021","name":"神农架林区"}]}]},{"code":"43","name":"湖南省","childs":[{"code":"4301","name":"长沙市","childs":[{"code":"430102","name":"芙蓉区"},{"code":"430103","name":"天心区"},{"code":"430104","name":"岳麓区"},{"code":"430105","name":"开福区"},{"code":"430111","name":"雨花区"},{"code":"430112","name":"望城区"},{"code":"430121","name":"长沙县"},{"code":"430124","name":"宁乡县"},{"code":"430181","name":"浏阳市"}]},{"code":"4302","name":"株洲市","childs":[{"code":"430202","name":"荷塘区"},{"code":"430203","name":"芦淞区"},{"code":"430204","name":"石峰区"},{"code":"430211","name":"天元区"},{"code":"430221","name":"株洲县"},{"code":"430223","name":"攸县"},{"code":"430224","name":"茶陵县"},{"code":"430225","name":"炎陵县"},{"code":"430281","name":"醴陵市"}]},{"code":"4303","name":"湘潭市","childs":[{"code":"430302","name":"雨湖区"},{"code":"430304","name":"岳塘区"},{"code":"430321","name":"湘潭县"},{"code":"430381","name":"湘乡市"},{"code":"430382","name":"韶山市"}]},{"code":"4304","name":"衡阳市","childs":[{"code":"430405","name":"珠晖区"},{"code":"430406","name":"雁峰区"},{"code":"430407","name":"石鼓区"},{"code":"430408","name":"蒸湘区"},{"code":"430412","name":"南岳区"},{"code":"430421","name":"衡阳县"},{"code":"430422","name":"衡南县"},{"code":"430423","name":"衡山县"},{"code":"430424","name":"衡东县"},{"code":"430426","name":"祁东县"},{"code":"430481","name":"耒阳市"},{"code":"430482","name":"常宁市"}]},{"code":"4305","name":"邵阳市","childs":[{"code":"430502","name":"双清区"},{"code":"430503","name":"大祥区"},{"code":"430511","name":"北塔区"},{"code":"430521","name":"邵东县"},{"code":"430522","name":"新邵县"},{"code":"430523","name":"邵阳县"},{"code":"430524","name":"隆回县"},{"code":"430525","name":"洞口县"},{"code":"430527","name":"绥宁县"},{"code":"430528","name":"新宁县"},{"code":"430529","name":"城步苗族自治县"},{"code":"430581","name":"武冈市"}]},{"code":"4306","name":"岳阳市","childs":[{"code":"430602","name":"岳阳楼区"},{"code":"430603","name":"云溪区"},{"code":"430611","name":"君山区"},{"code":"430621","name":"岳阳县"},{"code":"430623","name":"华容县"},{"code":"430624","name":"湘阴县"},{"code":"430626","name":"平江县"},{"code":"430681","name":"汨罗市"},{"code":"430682","name":"临湘市"}]},{"code":"4307","name":"常德市","childs":[{"code":"430702","name":"武陵区"},{"code":"430703","name":"鼎城区"},{"code":"430721","name":"安乡县"},{"code":"430722","name":"汉寿县"},{"code":"430723","name":"澧县"},{"code":"430724","name":"临澧县"},{"code":"430725","name":"桃源县"},{"code":"430726","name":"石门县"},{"code":"430781","name":"津市市"}]},{"code":"4308","name":"张家界市","childs":[{"code":"430802","name":"永定区"},{"code":"430811","name":"武陵源区"},{"code":"430821","name":"慈利县"},{"code":"430822","name":"桑植县"}]},{"code":"4309","name":"益阳市","childs":[{"code":"430902","name":"资阳区"},{"code":"430903","name":"赫山区"},{"code":"430921","name":"南县"},{"code":"430922","name":"桃江县"},{"code":"430923","name":"安化县"},{"code":"430981","name":"沅江市"}]},{"code":"4310","name":"郴州市","childs":[{"code":"431002","name":"北湖区"},{"code":"431003","name":"苏仙区"},{"code":"431021","name":"桂阳县"},{"code":"431022","name":"宜章县"},{"code":"431023","name":"永兴县"},{"code":"431024","name":"嘉禾县"},{"code":"431025","name":"临武县"},{"code":"431026","name":"汝城县"},{"code":"431027","name":"桂东县"},{"code":"431028","name":"安仁县"},{"code":"431081","name":"资兴市"}]},{"code":"4311","name":"永州市","childs":[{"code":"431102","name":"零陵区"},{"code":"431103","name":"冷水滩区"},{"code":"431121","name":"祁阳县"},{"code":"431122","name":"东安县"},{"code":"431123","name":"双牌县"},{"code":"431124","name":"道县"},{"code":"431125","name":"江永县"},{"code":"431126","name":"宁远县"},{"code":"431127","name":"蓝山县"},{"code":"431128","name":"新田县"},{"code":"431129","name":"江华瑶族自治县"}]},{"code":"4312","name":"怀化市","childs":[{"code":"431202","name":"鹤城区"},{"code":"431221","name":"中方县"},{"code":"431222","name":"沅陵县"},{"code":"431223","name":"辰溪县"},{"code":"431224","name":"溆浦县"},{"code":"431225","name":"会同县"},{"code":"431226","name":"麻阳苗族自治县"},{"code":"431227","name":"新晃侗族自治县"},{"code":"431228","name":"芷江侗族自治县"},{"code":"431229","name":"靖州苗族侗族自治县"},{"code":"431230","name":"通道侗族自治县"},{"code":"431281","name":"洪江市"}]},{"code":"4313","name":"娄底市","childs":[{"code":"431302","name":"娄星区"},{"code":"431321","name":"双峰县"},{"code":"431322","name":"新化县"},{"code":"431381","name":"冷水江市"},{"code":"431382","name":"涟源市"}]},{"code":"4331","name":"湘西土家族苗族自治州","childs":[{"code":"433101","name":"吉首市"},{"code":"433122","name":"泸溪县"},{"code":"433123","name":"凤凰县"},{"code":"433124","name":"花垣县"},{"code":"433125","name":"保靖县"},{"code":"433126","name":"古丈县"},{"code":"433127","name":"永顺县"},{"code":"433130","name":"龙山县"}]}]},{"code":"44","name":"广东省","childs":[{"code":"4401","name":"广州市","childs":[{"code":"440103","name":"荔湾区"},{"code":"440104","name":"越秀区"},{"code":"440105","name":"海珠区"},{"code":"440106","name":"天河区"},{"code":"440111","name":"白云区"},{"code":"440112","name":"黄埔区"},{"code":"440113","name":"番禺区"},{"code":"440114","name":"花都区"},{"code":"440115","name":"南沙区"},{"code":"440117","name":"从化区"},{"code":"440118","name":"增城区"}]},{"code":"4402","name":"韶关市","childs":[{"code":"440203","name":"武江区"},{"code":"440204","name":"浈江区"},{"code":"440205","name":"曲江区"},{"code":"440222","name":"始兴县"},{"code":"440224","name":"仁化县"},{"code":"440229","name":"翁源县"},{"code":"440232","name":"乳源瑶族自治县"},{"code":"440233","name":"新丰县"},{"code":"440281","name":"乐昌市"},{"code":"440282","name":"南雄市"}]},{"code":"4403","name":"深圳市","childs":[{"code":"440303","name":"罗湖区"},{"code":"440304","name":"福田区"},{"code":"440305","name":"南山区"},{"code":"440306","name":"宝安区"},{"code":"440307","name":"龙岗区"},{"code":"440308","name":"盐田区"}]},{"code":"4404","name":"珠海市","childs":[{"code":"440402","name":"香洲区"},{"code":"440403","name":"斗门区"},{"code":"440404","name":"金湾区"}]},{"code":"4405","name":"汕头市","childs":[{"code":"440507","name":"龙湖区"},{"code":"440511","name":"金平区"},{"code":"440512","name":"濠江区"},{"code":"440513","name":"潮阳区"},{"code":"440514","name":"潮南区"},{"code":"440515","name":"澄海区"},{"code":"440523","name":"南澳县"}]},{"code":"4406","name":"佛山市","childs":[{"code":"440604","name":"禅城区"},{"code":"440605","name":"南海区"},{"code":"440606","name":"顺德区"},{"code":"440607","name":"三水区"},{"code":"440608","name":"高明区"}]},{"code":"4407","name":"江门市","childs":[{"code":"440703","name":"蓬江区"},{"code":"440704","name":"江海区"},{"code":"440705","name":"新会区"},{"code":"440781","name":"台山市"},{"code":"440783","name":"开平市"},{"code":"440784","name":"鹤山市"},{"code":"440785","name":"恩平市"}]},{"code":"4408","name":"湛江市","childs":[{"code":"440802","name":"赤坎区"},{"code":"440803","name":"霞山区"},{"code":"440804","name":"坡头区"},{"code":"440811","name":"麻章区"},{"code":"440823","name":"遂溪县"},{"code":"440825","name":"徐闻县"},{"code":"440881","name":"廉江市"},{"code":"440882","name":"雷州市"},{"code":"440883","name":"吴川市"}]},{"code":"4409","name":"茂名市","childs":[{"code":"440902","name":"茂南区"},{"code":"440904","name":"电白区"},{"code":"440981","name":"高州市"},{"code":"440982","name":"化州市"},{"code":"440983","name":"信宜市"}]},{"code":"4412","name":"肇庆市","childs":[{"code":"441202","name":"端州区"},{"code":"441203","name":"鼎湖区"},{"code":"441204","name":"高要区"},{"code":"441223","name":"广宁县"},{"code":"441224","name":"怀集县"},{"code":"441225","name":"封开县"},{"code":"441226","name":"德庆县"},{"code":"441284","name":"四会市"}]},{"code":"4413","name":"惠州市","childs":[{"code":"441302","name":"惠城区"},{"code":"441303","name":"惠阳区"},{"code":"441322","name":"博罗县"},{"code":"441323","name":"惠东县"},{"code":"441324","name":"龙门县"}]},{"code":"4414","name":"梅州市","childs":[{"code":"441402","name":"梅江区"},{"code":"441403","name":"梅县区"},{"code":"441422","name":"大埔县"},{"code":"441423","name":"丰顺县"},{"code":"441424","name":"五华县"},{"code":"441426","name":"平远县"},{"code":"441427","name":"蕉岭县"},{"code":"441481","name":"兴宁市"}]},{"code":"4415","name":"汕尾市","childs":[{"code":"441502","name":"城区"},{"code":"441521","name":"海丰县"},{"code":"441523","name":"陆河县"},{"code":"441581","name":"陆丰市"}]},{"code":"4416","name":"河源市","childs":[{"code":"441602","name":"源城区"},{"code":"441621","name":"紫金县"},{"code":"441622","name":"龙川县"},{"code":"441623","name":"连平县"},{"code":"441624","name":"和平县"},{"code":"441625","name":"东源县"}]},{"code":"4417","name":"阳江市","childs":[{"code":"441702","name":"江城区"},{"code":"441704","name":"阳东区"},{"code":"441721","name":"阳西县"},{"code":"441781","name":"阳春市"}]},{"code":"4418","name":"清远市","childs":[{"code":"441802","name":"清城区"},{"code":"441803","name":"清新区"},{"code":"441821","name":"佛冈县"},{"code":"441823","name":"阳山县"},{"code":"441825","name":"连山壮族瑶族自治县"},{"code":"441826","name":"连南瑶族自治县"},{"code":"441881","name":"英德市"},{"code":"441882","name":"连州市"}]},{"code":"441900","name":"东莞市","childs":[{"code":"441900003","name":"东城街道办事处"},{"code":"441900004","name":"南城街道办事处"},{"code":"441900005","name":"万江街道办事处"},{"code":"441900006","name":"莞城街道办事处"},{"code":"441900101","name":"石碣镇"},{"code":"441900102","name":"石龙镇"},{"code":"441900103","name":"茶山镇"},{"code":"441900104","name":"石排镇"},{"code":"441900105","name":"企石镇"},{"code":"441900106","name":"横沥镇"},{"code":"441900107","name":"桥头镇"},{"code":"441900108","name":"谢岗镇"},{"code":"441900109","name":"东坑镇"},{"code":"441900110","name":"常平镇"},{"code":"441900111","name":"寮步镇"},{"code":"441900112","name":"樟木头镇"},{"code":"441900113","name":"大朗镇"},{"code":"441900114","name":"黄江镇"},{"code":"441900115","name":"清溪镇"},{"code":"441900116","name":"塘厦镇"},{"code":"441900117","name":"凤岗镇"},{"code":"441900118","name":"大岭山镇"},{"code":"441900119","name":"长安镇"},{"code":"441900121","name":"虎门镇"},{"code":"441900122","name":"厚街镇"},{"code":"441900123","name":"沙田镇"},{"code":"441900124","name":"道滘镇"},{"code":"441900125","name":"洪梅镇"},{"code":"441900126","name":"麻涌镇"},{"code":"441900127","name":"望牛墩镇"},{"code":"441900128","name":"中堂镇"},{"code":"441900129","name":"高埗镇"},{"code":"441900401","name":"松山湖管委会"},{"code":"441900402","name":"虎门港管委会"},{"code":"441900403","name":"东莞生态园"}]},{"code":"442000","name":"中山市","childs":[{"code":"442000001","name":"石岐区街道办事处"},{"code":"442000002","name":"东区街道办事处"},{"code":"442000003","name":"火炬开发区街道办事处"},{"code":"442000004","name":"西区街道办事处"},{"code":"442000005","name":"南区街道办事处"},{"code":"442000006","name":"五桂山街道办事处"},{"code":"442000100","name":"小榄镇"},{"code":"442000101","name":"黄圃镇"},{"code":"442000102","name":"民众镇"},{"code":"442000103","name":"东凤镇"},{"code":"442000104","name":"东升镇"},{"code":"442000105","name":"古镇镇"},{"code":"442000106","name":"沙溪镇"},{"code":"442000107","name":"坦洲镇"},{"code":"442000108","name":"港口镇"},{"code":"442000109","name":"三角镇"},{"code":"442000110","name":"横栏镇"},{"code":"442000111","name":"南头镇"},{"code":"442000112","name":"阜沙镇"},{"code":"442000113","name":"南朗镇"},{"code":"442000114","name":"三乡镇"},{"code":"442000115","name":"板芙镇"},{"code":"442000116","name":"大涌镇"},{"code":"442000117","name":"神湾镇"}]},{"code":"4451","name":"潮州市","childs":[{"code":"445102","name":"湘桥区"},{"code":"445103","name":"潮安区"},{"code":"445122","name":"饶平县"}]},{"code":"4452","name":"揭阳市","childs":[{"code":"445202","name":"榕城区"},{"code":"445203","name":"揭东区"},{"code":"445222","name":"揭西县"},{"code":"445224","name":"惠来县"},{"code":"445281","name":"普宁市"}]},{"code":"4453","name":"云浮市","childs":[{"code":"445302","name":"云城区"},{"code":"445303","name":"云安区"},{"code":"445321","name":"新兴县"},{"code":"445322","name":"郁南县"},{"code":"445381","name":"罗定市"}]}]},{"code":"45","name":"广西壮族自治区","childs":[{"code":"4501","name":"南宁市","childs":[{"code":"450102","name":"兴宁区"},{"code":"450103","name":"青秀区"},{"code":"450105","name":"江南区"},{"code":"450107","name":"西乡塘区"},{"code":"450108","name":"良庆区"},{"code":"450109","name":"邕宁区"},{"code":"450110","name":"武鸣区"},{"code":"450123","name":"隆安县"},{"code":"450124","name":"马山县"},{"code":"450125","name":"上林县"},{"code":"450126","name":"宾阳县"},{"code":"450127","name":"横县"}]},{"code":"4502","name":"柳州市","childs":[{"code":"450202","name":"城中区"},{"code":"450203","name":"鱼峰区"},{"code":"450204","name":"柳南区"},{"code":"450205","name":"柳北区"},{"code":"450206","name":"柳江区"},{"code":"450222","name":"柳城县"},{"code":"450223","name":"鹿寨县"},{"code":"450224","name":"融安县"},{"code":"450225","name":"融水苗族自治县"},{"code":"450226","name":"三江侗族自治县"}]},{"code":"4503","name":"桂林市","childs":[{"code":"450302","name":"秀峰区"},{"code":"450303","name":"叠彩区"},{"code":"450304","name":"象山区"},{"code":"450305","name":"七星区"},{"code":"450311","name":"雁山区"},{"code":"450312","name":"临桂区"},{"code":"450321","name":"阳朔县"},{"code":"450323","name":"灵川县"},{"code":"450324","name":"全州县"},{"code":"450325","name":"兴安县"},{"code":"450326","name":"永福县"},{"code":"450327","name":"灌阳县"},{"code":"450328","name":"龙胜各族自治县"},{"code":"450329","name":"资源县"},{"code":"450330","name":"平乐县"},{"code":"450331","name":"荔浦县"},{"code":"450332","name":"恭城瑶族自治县"}]},{"code":"4504","name":"梧州市","childs":[{"code":"450403","name":"万秀区"},{"code":"450405","name":"长洲区"},{"code":"450406","name":"龙圩区"},{"code":"450421","name":"苍梧县"},{"code":"450422","name":"藤县"},{"code":"450423","name":"蒙山县"},{"code":"450481","name":"岑溪市"}]},{"code":"4505","name":"北海市","childs":[{"code":"450502","name":"海城区"},{"code":"450503","name":"银海区"},{"code":"450512","name":"铁山港区"},{"code":"450521","name":"合浦县"}]},{"code":"4506","name":"防城港市","childs":[{"code":"450602","name":"港口区"},{"code":"450603","name":"防城区"},{"code":"450621","name":"上思县"},{"code":"450681","name":"东兴市"}]},{"code":"4507","name":"钦州市","childs":[{"code":"450702","name":"钦南区"},{"code":"450703","name":"钦北区"},{"code":"450721","name":"灵山县"},{"code":"450722","name":"浦北县"}]},{"code":"4508","name":"贵港市","childs":[{"code":"450802","name":"港北区"},{"code":"450803","name":"港南区"},{"code":"450804","name":"覃塘区"},{"code":"450821","name":"平南县"},{"code":"450881","name":"桂平市"}]},{"code":"4509","name":"玉林市","childs":[{"code":"450902","name":"玉州区"},{"code":"450903","name":"福绵区"},{"code":"450921","name":"容县"},{"code":"450922","name":"陆川县"},{"code":"450923","name":"博白县"},{"code":"450924","name":"兴业县"},{"code":"450981","name":"北流市"}]},{"code":"4510","name":"百色市","childs":[{"code":"451002","name":"右江区"},{"code":"451021","name":"田阳县"},{"code":"451022","name":"田东县"},{"code":"451023","name":"平果县"},{"code":"451024","name":"德保县"},{"code":"451026","name":"那坡县"},{"code":"451027","name":"凌云县"},{"code":"451028","name":"乐业县"},{"code":"451029","name":"田林县"},{"code":"451030","name":"西林县"},{"code":"451031","name":"隆林各族自治县"},{"code":"451081","name":"靖西市"}]},{"code":"4511","name":"贺州市","childs":[{"code":"451102","name":"八步区"},{"code":"451103","name":"平桂区"},{"code":"451121","name":"昭平县"},{"code":"451122","name":"钟山县"},{"code":"451123","name":"富川瑶族自治县"}]},{"code":"4512","name":"河池市","childs":[{"code":"451202","name":"金城江区"},{"code":"451221","name":"南丹县"},{"code":"451222","name":"天峨县"},{"code":"451223","name":"凤山县"},{"code":"451224","name":"东兰县"},{"code":"451225","name":"罗城仫佬族自治县"},{"code":"451226","name":"环江毛南族自治县"},{"code":"451227","name":"巴马瑶族自治县"},{"code":"451228","name":"都安瑶族自治县"},{"code":"451229","name":"大化瑶族自治县"},{"code":"451281","name":"宜州市"}]},{"code":"4513","name":"来宾市","childs":[{"code":"451302","name":"兴宾区"},{"code":"451321","name":"忻城县"},{"code":"451322","name":"象州县"},{"code":"451323","name":"武宣县"},{"code":"451324","name":"金秀瑶族自治县"},{"code":"451381","name":"合山市"}]},{"code":"4514","name":"崇左市","childs":[{"code":"451402","name":"江州区"},{"code":"451421","name":"扶绥县"},{"code":"451422","name":"宁明县"},{"code":"451423","name":"龙州县"},{"code":"451424","name":"大新县"},{"code":"451425","name":"天等县"},{"code":"451481","name":"凭祥市"}]}]},{"code":"46","name":"海南省","childs":[{"code":"4601","name":"海口市","childs":[{"code":"460105","name":"秀英区"},{"code":"460106","name":"龙华区"},{"code":"460107","name":"琼山区"},{"code":"460108","name":"美兰区"}]},{"code":"4602","name":"三亚市","childs":[{"code":"460202","name":"海棠区"},{"code":"460203","name":"吉阳区"},{"code":"460204","name":"天涯区"},{"code":"460205","name":"崖州区"}]},{"code":"4603","name":"三沙市","childs":[{"code":"460321","name":"西沙群岛"},{"code":"460322","name":"南沙群岛"},{"code":"460323","name":"中沙群岛的岛礁及其海域"}]},{"code":"460400","name":"儋州市","childs":[{"code":"460400100","name":"那大镇"},{"code":"460400101","name":"和庆镇"},{"code":"460400102","name":"南丰镇"},{"code":"460400103","name":"大成镇"},{"code":"460400104","name":"雅星镇"},{"code":"460400105","name":"兰洋镇"},{"code":"460400106","name":"光村镇"},{"code":"460400107","name":"木棠镇"},{"code":"460400108","name":"海头镇"},{"code":"460400109","name":"峨蔓镇"},{"code":"460400110","name":"三都镇"},{"code":"460400111","name":"王五镇"},{"code":"460400112","name":"白马井镇"},{"code":"460400113","name":"中和镇"},{"code":"460400114","name":"排浦镇"},{"code":"460400115","name":"东成镇"},{"code":"460400116","name":"新州镇"},{"code":"460400400","name":"国营西培农场"},{"code":"460400404","name":"国营西联农场"},{"code":"460400405","name":"国营蓝洋农场"},{"code":"460400407","name":"国营八一农场"},{"code":"460400499","name":"洋浦经济开发区"},{"code":"460400500","name":"华南热作学院"}]},{"code":"4690","name":"省直辖县级行政区划","childs":[{"code":"469001","name":"五指山市"},{"code":"469002","name":"琼海市"},{"code":"469005","name":"文昌市"},{"code":"469006","name":"万宁市"},{"code":"469007","name":"东方市"},{"code":"469021","name":"定安县"},{"code":"469022","name":"屯昌县"},{"code":"469023","name":"澄迈县"},{"code":"469024","name":"临高县"},{"code":"469025","name":"白沙黎族自治县"},{"code":"469026","name":"昌江黎族自治县"},{"code":"469027","name":"乐东黎族自治县"},{"code":"469028","name":"陵水黎族自治县"},{"code":"469029","name":"保亭黎族苗族自治县"},{"code":"469030","name":"琼中黎族苗族自治县"}]}]},{"code":"50","name":"重庆市","childs":[{"code":"5001","name":"市辖区","childs":[{"code":"500101","name":"万州区"},{"code":"500102","name":"涪陵区"},{"code":"500103","name":"渝中区"},{"code":"500104","name":"大渡口区"},{"code":"500105","name":"江北区"},{"code":"500106","name":"沙坪坝区"},{"code":"500107","name":"九龙坡区"},{"code":"500108","name":"南岸区"},{"code":"500109","name":"北碚区"},{"code":"500110","name":"綦江区"},{"code":"500111","name":"大足区"},{"code":"500112","name":"渝北区"},{"code":"500113","name":"巴南区"},{"code":"500114","name":"黔江区"},{"code":"500115","name":"长寿区"},{"code":"500116","name":"江津区"},{"code":"500117","name":"合川区"},{"code":"500118","name":"永川区"},{"code":"500119","name":"南川区"},{"code":"500120","name":"璧山区"},{"code":"500151","name":"铜梁区"},{"code":"500152","name":"潼南区"},{"code":"500153","name":"荣昌区"},{"code":"500154","name":"开州区"}]},{"code":"5002","name":"县","childs":[{"code":"500228","name":"梁平县"},{"code":"500229","name":"城口县"},{"code":"500230","name":"丰都县"},{"code":"500231","name":"垫江县"},{"code":"500232","name":"武隆县"},{"code":"500233","name":"忠县"},{"code":"500235","name":"云阳县"},{"code":"500236","name":"奉节县"},{"code":"500237","name":"巫山县"},{"code":"500238","name":"巫溪县"},{"code":"500240","name":"石柱土家族自治县"},{"code":"500241","name":"秀山土家族苗族自治县"},{"code":"500242","name":"酉阳土家族苗族自治县"},{"code":"500243","name":"彭水苗族土家族自治县"}]}]},{"code":"51","name":"四川省","childs":[{"code":"5101","name":"成都市","childs":[{"code":"510104","name":"锦江区"},{"code":"510105","name":"青羊区"},{"code":"510106","name":"金牛区"},{"code":"510107","name":"武侯区"},{"code":"510108","name":"成华区"},{"code":"510112","name":"龙泉驿区"},{"code":"510113","name":"青白江区"},{"code":"510114","name":"新都区"},{"code":"510115","name":"温江区"},{"code":"510116","name":"双流区"},{"code":"510121","name":"金堂县"},{"code":"510124","name":"郫县"},{"code":"510129","name":"大邑县"},{"code":"510131","name":"蒲江县"},{"code":"510132","name":"新津县"},{"code":"510181","name":"都江堰市"},{"code":"510182","name":"彭州市"},{"code":"510183","name":"邛崃市"},{"code":"510184","name":"崇州市"},{"code":"510185","name":"简阳市"}]},{"code":"5103","name":"自贡市","childs":[{"code":"510302","name":"自流井区"},{"code":"510303","name":"贡井区"},{"code":"510304","name":"大安区"},{"code":"510311","name":"沿滩区"},{"code":"510321","name":"荣县"},{"code":"510322","name":"富顺县"}]},{"code":"5104","name":"攀枝花市","childs":[{"code":"510402","name":"东区"},{"code":"510403","name":"西区"},{"code":"510411","name":"仁和区"},{"code":"510421","name":"米易县"},{"code":"510422","name":"盐边县"}]},{"code":"5105","name":"泸州市","childs":[{"code":"510502","name":"江阳区"},{"code":"510503","name":"纳溪区"},{"code":"510504","name":"龙马潭区"},{"code":"510521","name":"泸县"},{"code":"510522","name":"合江县"},{"code":"510524","name":"叙永县"},{"code":"510525","name":"古蔺县"}]},{"code":"5106","name":"德阳市","childs":[{"code":"510603","name":"旌阳区"},{"code":"510623","name":"中江县"},{"code":"510626","name":"罗江县"},{"code":"510681","name":"广汉市"},{"code":"510682","name":"什邡市"},{"code":"510683","name":"绵竹市"}]},{"code":"5107","name":"绵阳市","childs":[{"code":"510703","name":"涪城区"},{"code":"510704","name":"游仙区"},{"code":"510705","name":"安州区"},{"code":"510722","name":"三台县"},{"code":"510723","name":"盐亭县"},{"code":"510725","name":"梓潼县"},{"code":"510726","name":"北川羌族自治县"},{"code":"510727","name":"平武县"},{"code":"510781","name":"江油市"}]},{"code":"5108","name":"广元市","childs":[{"code":"510802","name":"利州区"},{"code":"510811","name":"昭化区"},{"code":"510812","name":"朝天区"},{"code":"510821","name":"旺苍县"},{"code":"510822","name":"青川县"},{"code":"510823","name":"剑阁县"},{"code":"510824","name":"苍溪县"}]},{"code":"5109","name":"遂宁市","childs":[{"code":"510903","name":"船山区"},{"code":"510904","name":"安居区"},{"code":"510921","name":"蓬溪县"},{"code":"510922","name":"射洪县"},{"code":"510923","name":"大英县"}]},{"code":"5110","name":"内江市","childs":[{"code":"511002","name":"市中区"},{"code":"511011","name":"东兴区"},{"code":"511024","name":"威远县"},{"code":"511025","name":"资中县"},{"code":"511028","name":"隆昌县"}]},{"code":"5111","name":"乐山市","childs":[{"code":"511102","name":"市中区"},{"code":"511111","name":"沙湾区"},{"code":"511112","name":"五通桥区"},{"code":"511113","name":"金口河区"},{"code":"511123","name":"犍为县"},{"code":"511124","name":"井研县"},{"code":"511126","name":"夹江县"},{"code":"511129","name":"沐川县"},{"code":"511132","name":"峨边彝族自治县"},{"code":"511133","name":"马边彝族自治县"},{"code":"511181","name":"峨眉山市"}]},{"code":"5113","name":"南充市","childs":[{"code":"511302","name":"顺庆区"},{"code":"511303","name":"高坪区"},{"code":"511304","name":"嘉陵区"},{"code":"511321","name":"南部县"},{"code":"511322","name":"营山县"},{"code":"511323","name":"蓬安县"},{"code":"511324","name":"仪陇县"},{"code":"511325","name":"西充县"},{"code":"511381","name":"阆中市"}]},{"code":"5114","name":"眉山市","childs":[{"code":"511402","name":"东坡区"},{"code":"511403","name":"彭山区"},{"code":"511421","name":"仁寿县"},{"code":"511423","name":"洪雅县"},{"code":"511424","name":"丹棱县"},{"code":"511425","name":"青神县"}]},{"code":"5115","name":"宜宾市","childs":[{"code":"511502","name":"翠屏区"},{"code":"511503","name":"南溪区"},{"code":"511521","name":"宜宾县"},{"code":"511523","name":"江安县"},{"code":"511524","name":"长宁县"},{"code":"511525","name":"高县"},{"code":"511526","name":"珙县"},{"code":"511527","name":"筠连县"},{"code":"511528","name":"兴文县"},{"code":"511529","name":"屏山县"}]},{"code":"5116","name":"广安市","childs":[{"code":"511602","name":"广安区"},{"code":"511603","name":"前锋区"},{"code":"511621","name":"岳池县"},{"code":"511622","name":"武胜县"},{"code":"511623","name":"邻水县"},{"code":"511681","name":"华蓥市"}]},{"code":"5117","name":"达州市","childs":[{"code":"511702","name":"通川区"},{"code":"511703","name":"达川区"},{"code":"511722","name":"宣汉县"},{"code":"511723","name":"开江县"},{"code":"511724","name":"大竹县"},{"code":"511725","name":"渠县"},{"code":"511781","name":"万源市"}]},{"code":"5118","name":"雅安市","childs":[{"code":"511802","name":"雨城区"},{"code":"511803","name":"名山区"},{"code":"511822","name":"荥经县"},{"code":"511823","name":"汉源县"},{"code":"511824","name":"石棉县"},{"code":"511825","name":"天全县"},{"code":"511826","name":"芦山县"},{"code":"511827","name":"宝兴县"}]},{"code":"5119","name":"巴中市","childs":[{"code":"511902","name":"巴州区"},{"code":"511903","name":"恩阳区"},{"code":"511921","name":"通江县"},{"code":"511922","name":"南江县"},{"code":"511923","name":"平昌县"}]},{"code":"5120","name":"资阳市","childs":[{"code":"512002","name":"雁江区"},{"code":"512021","name":"安岳县"},{"code":"512022","name":"乐至县"}]},{"code":"5132","name":"阿坝藏族羌族自治州","childs":[{"code":"513201","name":"马尔康市"},{"code":"513221","name":"汶川县"},{"code":"513222","name":"理县"},{"code":"513223","name":"茂县"},{"code":"513224","name":"松潘县"},{"code":"513225","name":"九寨沟县"},{"code":"513226","name":"金川县"},{"code":"513227","name":"小金县"},{"code":"513228","name":"黑水县"},{"code":"513230","name":"壤塘县"},{"code":"513231","name":"阿坝县"},{"code":"513232","name":"若尔盖县"},{"code":"513233","name":"红原县"}]},{"code":"5133","name":"甘孜藏族自治州","childs":[{"code":"513301","name":"康定市"},{"code":"513322","name":"泸定县"},{"code":"513323","name":"丹巴县"},{"code":"513324","name":"九龙县"},{"code":"513325","name":"雅江县"},{"code":"513326","name":"道孚县"},{"code":"513327","name":"炉霍县"},{"code":"513328","name":"甘孜县"},{"code":"513329","name":"新龙县"},{"code":"513330","name":"德格县"},{"code":"513331","name":"白玉县"},{"code":"513332","name":"石渠县"},{"code":"513333","name":"色达县"},{"code":"513334","name":"理塘县"},{"code":"513335","name":"巴塘县"},{"code":"513336","name":"乡城县"},{"code":"513337","name":"稻城县"},{"code":"513338","name":"得荣县"}]},{"code":"5134","name":"凉山彝族自治州","childs":[{"code":"513401","name":"西昌市"},{"code":"513422","name":"木里藏族自治县"},{"code":"513423","name":"盐源县"},{"code":"513424","name":"德昌县"},{"code":"513425","name":"会理县"},{"code":"513426","name":"会东县"},{"code":"513427","name":"宁南县"},{"code":"513428","name":"普格县"},{"code":"513429","name":"布拖县"},{"code":"513430","name":"金阳县"},{"code":"513431","name":"昭觉县"},{"code":"513432","name":"喜德县"},{"code":"513433","name":"冕宁县"},{"code":"513434","name":"越西县"},{"code":"513435","name":"甘洛县"},{"code":"513436","name":"美姑县"},{"code":"513437","name":"雷波县"}]}]},{"code":"52","name":"贵州省","childs":[{"code":"5201","name":"贵阳市","childs":[{"code":"520102","name":"南明区"},{"code":"520103","name":"云岩区"},{"code":"520111","name":"花溪区"},{"code":"520112","name":"乌当区"},{"code":"520113","name":"白云区"},{"code":"520115","name":"观山湖区"},{"code":"520121","name":"开阳县"},{"code":"520122","name":"息烽县"},{"code":"520123","name":"修文县"},{"code":"520181","name":"清镇市"}]},{"code":"5202","name":"六盘水市","childs":[{"code":"520201","name":"钟山区"},{"code":"520203","name":"六枝特区"},{"code":"520221","name":"水城县"},{"code":"520222","name":"盘县"}]},{"code":"5203","name":"遵义市","childs":[{"code":"520302","name":"红花岗区"},{"code":"520303","name":"汇川区"},{"code":"520304","name":"播州区"},{"code":"520322","name":"桐梓县"},{"code":"520323","name":"绥阳县"},{"code":"520324","name":"正安县"},{"code":"520325","name":"道真仡佬族苗族自治县"},{"code":"520326","name":"务川仡佬族苗族自治县"},{"code":"520327","name":"凤冈县"},{"code":"520328","name":"湄潭县"},{"code":"520329","name":"余庆县"},{"code":"520330","name":"习水县"},{"code":"520381","name":"赤水市"},{"code":"520382","name":"仁怀市"}]},{"code":"5204","name":"安顺市","childs":[{"code":"520402","name":"西秀区"},{"code":"520403","name":"平坝区"},{"code":"520422","name":"普定县"},{"code":"520423","name":"镇宁布依族苗族自治县"},{"code":"520424","name":"关岭布依族苗族自治县"},{"code":"520425","name":"紫云苗族布依族自治县"}]},{"code":"5205","name":"毕节市","childs":[{"code":"520502","name":"七星关区"},{"code":"520521","name":"大方县"},{"code":"520522","name":"黔西县"},{"code":"520523","name":"金沙县"},{"code":"520524","name":"织金县"},{"code":"520525","name":"纳雍县"},{"code":"520526","name":"威宁彝族回族苗族自治县"},{"code":"520527","name":"赫章县"}]},{"code":"5206","name":"铜仁市","childs":[{"code":"520602","name":"碧江区"},{"code":"520603","name":"万山区"},{"code":"520621","name":"江口县"},{"code":"520622","name":"玉屏侗族自治县"},{"code":"520623","name":"石阡县"},{"code":"520624","name":"思南县"},{"code":"520625","name":"印江土家族苗族自治县"},{"code":"520626","name":"德江县"},{"code":"520627","name":"沿河土家族自治县"},{"code":"520628","name":"松桃苗族自治县"}]},{"code":"5223","name":"黔西南布依族苗族自治州","childs":[{"code":"522301","name":"兴义市"},{"code":"522322","name":"兴仁县"},{"code":"522323","name":"普安县"},{"code":"522324","name":"晴隆县"},{"code":"522325","name":"贞丰县"},{"code":"522326","name":"望谟县"},{"code":"522327","name":"册亨县"},{"code":"522328","name":"安龙县"}]},{"code":"5226","name":"黔东南苗族侗族自治州","childs":[{"code":"522601","name":"凯里市"},{"code":"522622","name":"黄平县"},{"code":"522623","name":"施秉县"},{"code":"522624","name":"三穗县"},{"code":"522625","name":"镇远县"},{"code":"522626","name":"岑巩县"},{"code":"522627","name":"天柱县"},{"code":"522628","name":"锦屏县"},{"code":"522629","name":"剑河县"},{"code":"522630","name":"台江县"},{"code":"522631","name":"黎平县"},{"code":"522632","name":"榕江县"},{"code":"522633","name":"从江县"},{"code":"522634","name":"雷山县"},{"code":"522635","name":"麻江县"},{"code":"522636","name":"丹寨县"}]},{"code":"5227","name":"黔南布依族苗族自治州","childs":[{"code":"522701","name":"都匀市"},{"code":"522702","name":"福泉市"},{"code":"522722","name":"荔波县"},{"code":"522723","name":"贵定县"},{"code":"522725","name":"瓮安县"},{"code":"522726","name":"独山县"},{"code":"522727","name":"平塘县"},{"code":"522728","name":"罗甸县"},{"code":"522729","name":"长顺县"},{"code":"522730","name":"龙里县"},{"code":"522731","name":"惠水县"},{"code":"522732","name":"三都水族自治县"}]}]},{"code":"53","name":"云南省","childs":[{"code":"5301","name":"昆明市","childs":[{"code":"530102","name":"五华区"},{"code":"530103","name":"盘龙区"},{"code":"530111","name":"官渡区"},{"code":"530112","name":"西山区"},{"code":"530113","name":"东川区"},{"code":"530114","name":"呈贡区"},{"code":"530122","name":"晋宁县"},{"code":"530124","name":"富民县"},{"code":"530125","name":"宜良县"},{"code":"530126","name":"石林彝族自治县"},{"code":"530127","name":"嵩明县"},{"code":"530128","name":"禄劝彝族苗族自治县"},{"code":"530129","name":"寻甸回族彝族自治县"},{"code":"530181","name":"安宁市"}]},{"code":"5303","name":"曲靖市","childs":[{"code":"530302","name":"麒麟区"},{"code":"530303","name":"沾益区"},{"code":"530321","name":"马龙县"},{"code":"530322","name":"陆良县"},{"code":"530323","name":"师宗县"},{"code":"530324","name":"罗平县"},{"code":"530325","name":"富源县"},{"code":"530326","name":"会泽县"},{"code":"530381","name":"宣威市"}]},{"code":"5304","name":"玉溪市","childs":[{"code":"530402","name":"红塔区"},{"code":"530403","name":"江川区"},{"code":"530422","name":"澄江县"},{"code":"530423","name":"通海县"},{"code":"530424","name":"华宁县"},{"code":"530425","name":"易门县"},{"code":"530426","name":"峨山彝族自治县"},{"code":"530427","name":"新平彝族傣族自治县"},{"code":"530428","name":"元江哈尼族彝族傣族自治县"}]},{"code":"5305","name":"保山市","childs":[{"code":"530502","name":"隆阳区"},{"code":"530521","name":"施甸县"},{"code":"530523","name":"龙陵县"},{"code":"530524","name":"昌宁县"},{"code":"530581","name":"腾冲市"}]},{"code":"5306","name":"昭通市","childs":[{"code":"530602","name":"昭阳区"},{"code":"530621","name":"鲁甸县"},{"code":"530622","name":"巧家县"},{"code":"530623","name":"盐津县"},{"code":"530624","name":"大关县"},{"code":"530625","name":"永善县"},{"code":"530626","name":"绥江县"},{"code":"530627","name":"镇雄县"},{"code":"530628","name":"彝良县"},{"code":"530629","name":"威信县"},{"code":"530630","name":"水富县"}]},{"code":"5307","name":"丽江市","childs":[{"code":"530702","name":"古城区"},{"code":"530721","name":"玉龙纳西族自治县"},{"code":"530722","name":"永胜县"},{"code":"530723","name":"华坪县"},{"code":"530724","name":"宁蒗彝族自治县"}]},{"code":"5308","name":"普洱市","childs":[{"code":"530802","name":"思茅区"},{"code":"530821","name":"宁洱哈尼族彝族自治县"},{"code":"530822","name":"墨江哈尼族自治县"},{"code":"530823","name":"景东彝族自治县"},{"code":"530824","name":"景谷傣族彝族自治县"},{"code":"530825","name":"镇沅彝族哈尼族拉祜族自治县"},{"code":"530826","name":"江城哈尼族彝族自治县"},{"code":"530827","name":"孟连傣族拉祜族佤族自治县"},{"code":"530828","name":"澜沧拉祜族自治县"},{"code":"530829","name":"西盟佤族自治县"}]},{"code":"5309","name":"临沧市","childs":[{"code":"530902","name":"临翔区"},{"code":"530921","name":"凤庆县"},{"code":"530922","name":"云县"},{"code":"530923","name":"永德县"},{"code":"530924","name":"镇康县"},{"code":"530925","name":"双江拉祜族佤族布朗族傣族自治县"},{"code":"530926","name":"耿马傣族佤族自治县"},{"code":"530927","name":"沧源佤族自治县"}]},{"code":"5323","name":"楚雄彝族自治州","childs":[{"code":"532301","name":"楚雄市"},{"code":"532322","name":"双柏县"},{"code":"532323","name":"牟定县"},{"code":"532324","name":"南华县"},{"code":"532325","name":"姚安县"},{"code":"532326","name":"大姚县"},{"code":"532327","name":"永仁县"},{"code":"532328","name":"元谋县"},{"code":"532329","name":"武定县"},{"code":"532331","name":"禄丰县"}]},{"code":"5325","name":"红河哈尼族彝族自治州","childs":[{"code":"532501","name":"个旧市"},{"code":"532502","name":"开远市"},{"code":"532503","name":"蒙自市"},{"code":"532504","name":"弥勒市"},{"code":"532523","name":"屏边苗族自治县"},{"code":"532524","name":"建水县"},{"code":"532525","name":"石屏县"},{"code":"532527","name":"泸西县"},{"code":"532528","name":"元阳县"},{"code":"532529","name":"红河县"},{"code":"532530","name":"金平苗族瑶族傣族自治县"},{"code":"532531","name":"绿春县"},{"code":"532532","name":"河口瑶族自治县"}]},{"code":"5326","name":"文山壮族苗族自治州","childs":[{"code":"532601","name":"文山市"},{"code":"532622","name":"砚山县"},{"code":"532623","name":"西畴县"},{"code":"532624","name":"麻栗坡县"},{"code":"532625","name":"马关县"},{"code":"532626","name":"丘北县"},{"code":"532627","name":"广南县"},{"code":"532628","name":"富宁县"}]},{"code":"5328","name":"西双版纳傣族自治州","childs":[{"code":"532801","name":"景洪市"},{"code":"532822","name":"勐海县"},{"code":"532823","name":"勐腊县"}]},{"code":"5329","name":"大理白族自治州","childs":[{"code":"532901","name":"大理市"},{"code":"532922","name":"漾濞彝族自治县"},{"code":"532923","name":"祥云县"},{"code":"532924","name":"宾川县"},{"code":"532925","name":"弥渡县"},{"code":"532926","name":"南涧彝族自治县"},{"code":"532927","name":"巍山彝族回族自治县"},{"code":"532928","name":"永平县"},{"code":"532929","name":"云龙县"},{"code":"532930","name":"洱源县"},{"code":"532931","name":"剑川县"},{"code":"532932","name":"鹤庆县"}]},{"code":"5331","name":"德宏傣族景颇族自治州","childs":[{"code":"533102","name":"瑞丽市"},{"code":"533103","name":"芒市"},{"code":"533122","name":"梁河县"},{"code":"533123","name":"盈江县"},{"code":"533124","name":"陇川县"}]},{"code":"5333","name":"怒江傈僳族自治州","childs":[{"code":"533301","name":"泸水市"},{"code":"533323","name":"福贡县"},{"code":"533324","name":"贡山独龙族怒族自治县"},{"code":"533325","name":"兰坪白族普米族自治县"}]},{"code":"5334","name":"迪庆藏族自治州","childs":[{"code":"533401","name":"香格里拉市"},{"code":"533422","name":"德钦县"},{"code":"533423","name":"维西傈僳族自治县"}]}]},{"code":"54","name":"西藏自治区","childs":[{"code":"5401","name":"拉萨市","childs":[{"code":"540102","name":"城关区"},{"code":"540103","name":"堆龙德庆区"},{"code":"540121","name":"林周县"},{"code":"540122","name":"当雄县"},{"code":"540123","name":"尼木县"},{"code":"540124","name":"曲水县"},{"code":"540126","name":"达孜县"},{"code":"540127","name":"墨竹工卡县"}]},{"code":"5402","name":"日喀则市","childs":[{"code":"540202","name":"桑珠孜区"},{"code":"540221","name":"南木林县"},{"code":"540222","name":"江孜县"},{"code":"540223","name":"定日县"},{"code":"540224","name":"萨迦县"},{"code":"540225","name":"拉孜县"},{"code":"540226","name":"昂仁县"},{"code":"540227","name":"谢通门县"},{"code":"540228","name":"白朗县"},{"code":"540229","name":"仁布县"},{"code":"540230","name":"康马县"},{"code":"540231","name":"定结县"},{"code":"540232","name":"仲巴县"},{"code":"540233","name":"亚东县"},{"code":"540234","name":"吉隆县"},{"code":"540235","name":"聂拉木县"},{"code":"540236","name":"萨嘎县"},{"code":"540237","name":"岗巴县"}]},{"code":"5403","name":"昌都市","childs":[{"code":"540302","name":"卡若区"},{"code":"540321","name":"江达县"},{"code":"540322","name":"贡觉县"},{"code":"540323","name":"类乌齐县"},{"code":"540324","name":"丁青县"},{"code":"540325","name":"察雅县"},{"code":"540326","name":"八宿县"},{"code":"540327","name":"左贡县"},{"code":"540328","name":"芒康县"},{"code":"540329","name":"洛隆县"},{"code":"540330","name":"边坝县"}]},{"code":"5404","name":"林芝市","childs":[{"code":"540402","name":"巴宜区"},{"code":"540421","name":"工布江达县"},{"code":"540422","name":"米林县"},{"code":"540423","name":"墨脱县"},{"code":"540424","name":"波密县"},{"code":"540425","name":"察隅县"},{"code":"540426","name":"朗县"}]},{"code":"5405","name":"山南市","childs":[{"code":"540502","name":"乃东区"},{"code":"540521","name":"扎囊县"},{"code":"540522","name":"贡嘎县"},{"code":"540523","name":"桑日县"},{"code":"540524","name":"琼结县"},{"code":"540525","name":"曲松县"},{"code":"540526","name":"措美县"},{"code":"540527","name":"洛扎县"},{"code":"540528","name":"加查县"},{"code":"540529","name":"隆子县"},{"code":"540530","name":"错那县"},{"code":"540531","name":"浪卡子县"}]},{"code":"5424","name":"那曲地区","childs":[{"code":"542421","name":"那曲县"},{"code":"542422","name":"嘉黎县"},{"code":"542423","name":"比如县"},{"code":"542424","name":"聂荣县"},{"code":"542425","name":"安多县"},{"code":"542426","name":"申扎县"},{"code":"542427","name":"索县"},{"code":"542428","name":"班戈县"},{"code":"542429","name":"巴青县"},{"code":"542430","name":"尼玛县"},{"code":"542431","name":"双湖县"}]},{"code":"5425","name":"阿里地区","childs":[{"code":"542521","name":"普兰县"},{"code":"542522","name":"札达县"},{"code":"542523","name":"噶尔县"},{"code":"542524","name":"日土县"},{"code":"542525","name":"革吉县"},{"code":"542526","name":"改则县"},{"code":"542527","name":"措勤县"}]}]},{"code":"61","name":"陕西省","childs":[{"code":"6101","name":"西安市","childs":[{"code":"610102","name":"新城区"},{"code":"610103","name":"碑林区"},{"code":"610104","name":"莲湖区"},{"code":"610111","name":"灞桥区"},{"code":"610112","name":"未央区"},{"code":"610113","name":"雁塔区"},{"code":"610114","name":"阎良区"},{"code":"610115","name":"临潼区"},{"code":"610116","name":"长安区"},{"code":"610117","name":"高陵区"},{"code":"610122","name":"蓝田县"},{"code":"610124","name":"周至县"},{"code":"610125","name":"户县"}]},{"code":"6102","name":"铜川市","childs":[{"code":"610202","name":"王益区"},{"code":"610203","name":"印台区"},{"code":"610204","name":"耀州区"},{"code":"610222","name":"宜君县"}]},{"code":"6103","name":"宝鸡市","childs":[{"code":"610302","name":"渭滨区"},{"code":"610303","name":"金台区"},{"code":"610304","name":"陈仓区"},{"code":"610322","name":"凤翔县"},{"code":"610323","name":"岐山县"},{"code":"610324","name":"扶风县"},{"code":"610326","name":"眉县"},{"code":"610327","name":"陇县"},{"code":"610328","name":"千阳县"},{"code":"610329","name":"麟游县"},{"code":"610330","name":"凤县"},{"code":"610331","name":"太白县"}]},{"code":"6104","name":"咸阳市","childs":[{"code":"610402","name":"秦都区"},{"code":"610403","name":"杨陵区"},{"code":"610404","name":"渭城区"},{"code":"610422","name":"三原县"},{"code":"610423","name":"泾阳县"},{"code":"610424","name":"乾县"},{"code":"610425","name":"礼泉县"},{"code":"610426","name":"永寿县"},{"code":"610427","name":"彬县"},{"code":"610428","name":"长武县"},{"code":"610429","name":"旬邑县"},{"code":"610430","name":"淳化县"},{"code":"610431","name":"武功县"},{"code":"610481","name":"兴平市"}]},{"code":"6105","name":"渭南市","childs":[{"code":"610502","name":"临渭区"},{"code":"610503","name":"华州区"},{"code":"610522","name":"潼关县"},{"code":"610523","name":"大荔县"},{"code":"610524","name":"合阳县"},{"code":"610525","name":"澄城县"},{"code":"610526","name":"蒲城县"},{"code":"610527","name":"白水县"},{"code":"610528","name":"富平县"},{"code":"610581","name":"韩城市"},{"code":"610582","name":"华阴市"}]},{"code":"6106","name":"延安市","childs":[{"code":"610602","name":"宝塔区"},{"code":"610603","name":"安塞区"},{"code":"610621","name":"延长县"},{"code":"610622","name":"延川县"},{"code":"610623","name":"子长县"},{"code":"610625","name":"志丹县"},{"code":"610626","name":"吴起县"},{"code":"610627","name":"甘泉县"},{"code":"610628","name":"富县"},{"code":"610629","name":"洛川县"},{"code":"610630","name":"宜川县"},{"code":"610631","name":"黄龙县"},{"code":"610632","name":"黄陵县"}]},{"code":"6107","name":"汉中市","childs":[{"code":"610702","name":"汉台区"},{"code":"610721","name":"南郑县"},{"code":"610722","name":"城固县"},{"code":"610723","name":"洋县"},{"code":"610724","name":"西乡县"},{"code":"610725","name":"勉县"},{"code":"610726","name":"宁强县"},{"code":"610727","name":"略阳县"},{"code":"610728","name":"镇巴县"},{"code":"610729","name":"留坝县"},{"code":"610730","name":"佛坪县"}]},{"code":"6108","name":"榆林市","childs":[{"code":"610802","name":"榆阳区"},{"code":"610803","name":"横山区"},{"code":"610821","name":"神木县"},{"code":"610822","name":"府谷县"},{"code":"610824","name":"靖边县"},{"code":"610825","name":"定边县"},{"code":"610826","name":"绥德县"},{"code":"610827","name":"米脂县"},{"code":"610828","name":"佳县"},{"code":"610829","name":"吴堡县"},{"code":"610830","name":"清涧县"},{"code":"610831","name":"子洲县"}]},{"code":"6109","name":"安康市","childs":[{"code":"610902","name":"汉滨区"},{"code":"610921","name":"汉阴县"},{"code":"610922","name":"石泉县"},{"code":"610923","name":"宁陕县"},{"code":"610924","name":"紫阳县"},{"code":"610925","name":"岚皋县"},{"code":"610926","name":"平利县"},{"code":"610927","name":"镇坪县"},{"code":"610928","name":"旬阳县"},{"code":"610929","name":"白河县"}]},{"code":"6110","name":"商洛市","childs":[{"code":"611002","name":"商州区"},{"code":"611021","name":"洛南县"},{"code":"611022","name":"丹凤县"},{"code":"611023","name":"商南县"},{"code":"611024","name":"山阳县"},{"code":"611025","name":"镇安县"},{"code":"611026","name":"柞水县"}]}]},{"code":"62","name":"甘肃省","childs":[{"code":"6201","name":"兰州市","childs":[{"code":"620102","name":"城关区"},{"code":"620103","name":"七里河区"},{"code":"620104","name":"西固区"},{"code":"620105","name":"安宁区"},{"code":"620111","name":"红古区"},{"code":"620121","name":"永登县"},{"code":"620122","name":"皋兰县"},{"code":"620123","name":"榆中县"}]},{"code":"620201","name":"嘉峪关市","childs":[{"code":"620201100","name":"新城镇"},{"code":"620201101","name":"峪泉镇"},{"code":"620201102","name":"文殊镇"},{"code":"620201401","name":"雄关区"},{"code":"620201402","name":"镜铁区"},{"code":"620201403","name":"长城区"}]},{"code":"6203","name":"金昌市","childs":[{"code":"620302","name":"金川区"},{"code":"620321","name":"永昌县"}]},{"code":"6204","name":"白银市","childs":[{"code":"620402","name":"白银区"},{"code":"620403","name":"平川区"},{"code":"620421","name":"靖远县"},{"code":"620422","name":"会宁县"},{"code":"620423","name":"景泰县"}]},{"code":"6205","name":"天水市","childs":[{"code":"620502","name":"秦州区"},{"code":"620503","name":"麦积区"},{"code":"620521","name":"清水县"},{"code":"620522","name":"秦安县"},{"code":"620523","name":"甘谷县"},{"code":"620524","name":"武山县"},{"code":"620525","name":"张家川回族自治县"}]},{"code":"6206","name":"武威市","childs":[{"code":"620602","name":"凉州区"},{"code":"620621","name":"民勤县"},{"code":"620622","name":"古浪县"},{"code":"620623","name":"天祝藏族自治县"}]},{"code":"6207","name":"张掖市","childs":[{"code":"620702","name":"甘州区"},{"code":"620721","name":"肃南裕固族自治县"},{"code":"620722","name":"民乐县"},{"code":"620723","name":"临泽县"},{"code":"620724","name":"高台县"},{"code":"620725","name":"山丹县"}]},{"code":"6208","name":"平凉市","childs":[{"code":"620802","name":"崆峒区"},{"code":"620821","name":"泾川县"},{"code":"620822","name":"灵台县"},{"code":"620823","name":"崇信县"},{"code":"620824","name":"华亭县"},{"code":"620825","name":"庄浪县"},{"code":"620826","name":"静宁县"}]},{"code":"6209","name":"酒泉市","childs":[{"code":"620902","name":"肃州区"},{"code":"620921","name":"金塔县"},{"code":"620922","name":"瓜州县"},{"code":"620923","name":"肃北蒙古族自治县"},{"code":"620924","name":"阿克塞哈萨克族自治县"},{"code":"620981","name":"玉门市"},{"code":"620982","name":"敦煌市"}]},{"code":"6210","name":"庆阳市","childs":[{"code":"621002","name":"西峰区"},{"code":"621021","name":"庆城县"},{"code":"621022","name":"环县"},{"code":"621023","name":"华池县"},{"code":"621024","name":"合水县"},{"code":"621025","name":"正宁县"},{"code":"621026","name":"宁县"},{"code":"621027","name":"镇原县"}]},{"code":"6211","name":"定西市","childs":[{"code":"621102","name":"安定区"},{"code":"621121","name":"通渭县"},{"code":"621122","name":"陇西县"},{"code":"621123","name":"渭源县"},{"code":"621124","name":"临洮县"},{"code":"621125","name":"漳县"},{"code":"621126","name":"岷县"}]},{"code":"6212","name":"陇南市","childs":[{"code":"621202","name":"武都区"},{"code":"621221","name":"成县"},{"code":"621222","name":"文县"},{"code":"621223","name":"宕昌县"},{"code":"621224","name":"康县"},{"code":"621225","name":"西和县"},{"code":"621226","name":"礼县"},{"code":"621227","name":"徽县"},{"code":"621228","name":"两当县"}]},{"code":"6229","name":"临夏回族自治州","childs":[{"code":"622901","name":"临夏市"},{"code":"622921","name":"临夏县"},{"code":"622922","name":"康乐县"},{"code":"622923","name":"永靖县"},{"code":"622924","name":"广河县"},{"code":"622925","name":"和政县"},{"code":"622926","name":"东乡族自治县"},{"code":"622927","name":"积石山保安族东乡族撒拉族自治县"}]},{"code":"6230","name":"甘南藏族自治州","childs":[{"code":"623001","name":"合作市"},{"code":"623021","name":"临潭县"},{"code":"623022","name":"卓尼县"},{"code":"623023","name":"舟曲县"},{"code":"623024","name":"迭部县"},{"code":"623025","name":"玛曲县"},{"code":"623026","name":"碌曲县"},{"code":"623027","name":"夏河县"}]}]},{"code":"63","name":"青海省","childs":[{"code":"6301","name":"西宁市","childs":[{"code":"630102","name":"城东区"},{"code":"630103","name":"城中区"},{"code":"630104","name":"城西区"},{"code":"630105","name":"城北区"},{"code":"630121","name":"大通回族土族自治县"},{"code":"630122","name":"湟中县"},{"code":"630123","name":"湟源县"}]},{"code":"6302","name":"海东市","childs":[{"code":"630202","name":"乐都区"},{"code":"630203","name":"平安区"},{"code":"630222","name":"民和回族土族自治县"},{"code":"630223","name":"互助土族自治县"},{"code":"630224","name":"化隆回族自治县"},{"code":"630225","name":"循化撒拉族自治县"}]},{"code":"6322","name":"海北藏族自治州","childs":[{"code":"632221","name":"门源回族自治县"},{"code":"632222","name":"祁连县"},{"code":"632223","name":"海晏县"},{"code":"632224","name":"刚察县"}]},{"code":"6323","name":"黄南藏族自治州","childs":[{"code":"632321","name":"同仁县"},{"code":"632322","name":"尖扎县"},{"code":"632323","name":"泽库县"},{"code":"632324","name":"河南蒙古族自治县"}]},{"code":"6325","name":"海南藏族自治州","childs":[{"code":"632521","name":"共和县"},{"code":"632522","name":"同德县"},{"code":"632523","name":"贵德县"},{"code":"632524","name":"兴海县"},{"code":"632525","name":"贵南县"}]},{"code":"6326","name":"果洛藏族自治州","childs":[{"code":"632621","name":"玛沁县"},{"code":"632622","name":"班玛县"},{"code":"632623","name":"甘德县"},{"code":"632624","name":"达日县"},{"code":"632625","name":"久治县"},{"code":"632626","name":"玛多县"}]},{"code":"6327","name":"玉树藏族自治州","childs":[{"code":"632701","name":"玉树市"},{"code":"632722","name":"杂多县"},{"code":"632723","name":"称多县"},{"code":"632724","name":"治多县"},{"code":"632725","name":"囊谦县"},{"code":"632726","name":"曲麻莱县"}]},{"code":"6328","name":"海西蒙古族藏族自治州","childs":[{"code":"632801","name":"格尔木市"},{"code":"632802","name":"德令哈市"},{"code":"632821","name":"乌兰县"},{"code":"632822","name":"都兰县"},{"code":"632823","name":"天峻县"}]}]},{"code":"64","name":"宁夏回族自治区","childs":[{"code":"6401","name":"银川市","childs":[{"code":"640104","name":"兴庆区"},{"code":"640105","name":"西夏区"},{"code":"640106","name":"金凤区"},{"code":"640121","name":"永宁县"},{"code":"640122","name":"贺兰县"},{"code":"640181","name":"灵武市"}]},{"code":"6402","name":"石嘴山市","childs":[{"code":"640202","name":"大武口区"},{"code":"640205","name":"惠农区"},{"code":"640221","name":"平罗县"}]},{"code":"6403","name":"吴忠市","childs":[{"code":"640302","name":"利通区"},{"code":"640303","name":"红寺堡区"},{"code":"640323","name":"盐池县"},{"code":"640324","name":"同心县"},{"code":"640381","name":"青铜峡市"}]},{"code":"6404","name":"固原市","childs":[{"code":"640402","name":"原州区"},{"code":"640422","name":"西吉县"},{"code":"640423","name":"隆德县"},{"code":"640424","name":"泾源县"},{"code":"640425","name":"彭阳县"}]},{"code":"6405","name":"中卫市","childs":[{"code":"640502","name":"沙坡头区"},{"code":"640521","name":"中宁县"},{"code":"640522","name":"海原县"}]}]},{"code":"65","name":"新疆维吾尔自治区","childs":[{"code":"6501","name":"乌鲁木齐市","childs":[{"code":"650102","name":"天山区"},{"code":"650103","name":"沙依巴克区"},{"code":"650104","name":"新市区"},{"code":"650105","name":"水磨沟区"},{"code":"650106","name":"头屯河区"},{"code":"650107","name":"达坂城区"},{"code":"650109","name":"米东区"},{"code":"650121","name":"乌鲁木齐县"}]},{"code":"6502","name":"克拉玛依市","childs":[{"code":"650202","name":"独山子区"},{"code":"650203","name":"克拉玛依区"},{"code":"650204","name":"白碱滩区"},{"code":"650205","name":"乌尔禾区"}]},{"code":"6504","name":"吐鲁番市","childs":[{"code":"650402","name":"高昌区"},{"code":"650421","name":"鄯善县"},{"code":"650422","name":"托克逊县"}]},{"code":"6505","name":"哈密市","childs":[{"code":"650502","name":"伊州区"},{"code":"650521","name":"巴里坤哈萨克自治县"},{"code":"650522","name":"伊吾县"}]},{"code":"6523","name":"昌吉回族自治州","childs":[{"code":"652301","name":"昌吉市"},{"code":"652302","name":"阜康市"},{"code":"652323","name":"呼图壁县"},{"code":"652324","name":"玛纳斯县"},{"code":"652325","name":"奇台县"},{"code":"652327","name":"吉木萨尔县"},{"code":"652328","name":"木垒哈萨克自治县"}]},{"code":"6527","name":"博尔塔拉蒙古自治州","childs":[{"code":"652701","name":"博乐市"},{"code":"652702","name":"阿拉山口市"},{"code":"652722","name":"精河县"},{"code":"652723","name":"温泉县"}]},{"code":"6528","name":"巴音郭楞蒙古自治州","childs":[{"code":"652801","name":"库尔勒市"},{"code":"652822","name":"轮台县"},{"code":"652823","name":"尉犁县"},{"code":"652824","name":"若羌县"},{"code":"652825","name":"且末县"},{"code":"652826","name":"焉耆回族自治县"},{"code":"652827","name":"和静县"},{"code":"652828","name":"和硕县"},{"code":"652829","name":"博湖县"}]},{"code":"6529","name":"阿克苏地区","childs":[{"code":"652901","name":"阿克苏市"},{"code":"652922","name":"温宿县"},{"code":"652923","name":"库车县"},{"code":"652924","name":"沙雅县"},{"code":"652925","name":"新和县"},{"code":"652926","name":"拜城县"},{"code":"652927","name":"乌什县"},{"code":"652928","name":"阿瓦提县"},{"code":"652929","name":"柯坪县"}]},{"code":"6530","name":"克孜勒苏柯尔克孜自治州","childs":[{"code":"653001","name":"阿图什市"},{"code":"653022","name":"阿克陶县"},{"code":"653023","name":"阿合奇县"},{"code":"653024","name":"乌恰县"}]},{"code":"6531","name":"喀什地区","childs":[{"code":"653101","name":"喀什市"},{"code":"653121","name":"疏附县"},{"code":"653122","name":"疏勒县"},{"code":"653123","name":"英吉沙县"},{"code":"653124","name":"泽普县"},{"code":"653125","name":"莎车县"},{"code":"653126","name":"叶城县"},{"code":"653127","name":"麦盖提县"},{"code":"653128","name":"岳普湖县"},{"code":"653129","name":"伽师县"},{"code":"653130","name":"巴楚县"},{"code":"653131","name":"塔什库尔干塔吉克自治县"}]},{"code":"6532","name":"和田地区","childs":[{"code":"653201","name":"和田市"},{"code":"653221","name":"和田县"},{"code":"653222","name":"墨玉县"},{"code":"653223","name":"皮山县"},{"code":"653224","name":"洛浦县"},{"code":"653225","name":"策勒县"},{"code":"653226","name":"于田县"},{"code":"653227","name":"民丰县"}]},{"code":"6540","name":"伊犁哈萨克自治州","childs":[{"code":"654002","name":"伊宁市"},{"code":"654003","name":"奎屯市"},{"code":"654004","name":"霍尔果斯市"},{"code":"654021","name":"伊宁县"},{"code":"654022","name":"察布查尔锡伯自治县"},{"code":"654023","name":"霍城县"},{"code":"654024","name":"巩留县"},{"code":"654025","name":"新源县"},{"code":"654026","name":"昭苏县"},{"code":"654027","name":"特克斯县"},{"code":"654028","name":"尼勒克县"}]},{"code":"6542","name":"塔城地区","childs":[{"code":"654201","name":"塔城市"},{"code":"654202","name":"乌苏市"},{"code":"654221","name":"额敏县"},{"code":"654223","name":"沙湾县"},{"code":"654224","name":"托里县"},{"code":"654225","name":"裕民县"},{"code":"654226","name":"和布克赛尔蒙古自治县"}]},{"code":"6543","name":"阿勒泰地区","childs":[{"code":"654301","name":"阿勒泰市"},{"code":"654321","name":"布尔津县"},{"code":"654322","name":"富蕴县"},{"code":"654323","name":"福海县"},{"code":"654324","name":"哈巴河县"},{"code":"654325","name":"青河县"},{"code":"654326","name":"吉木乃县"}]},{"code":"6590","name":"自治区直辖县级行政区划","childs":[{"code":"659001","name":"石河子市"},{"code":"659002","name":"阿拉尔市"},{"code":"659003","name":"图木舒克市"},{"code":"659004","name":"五家渠市"},{"code":"659006","name":"铁门关市"}]}]},{"code":"71","name":"台湾省","childs":[]},{"code":"81","name":"香港特别行政区","childs":[]},{"code":"82","name":"澳门特别行政区","childs":[]}]
\ No newline at end of file
diff --git a/components/u-parse/components/wxParseAudio.vue b/components/u-parse/components/wxParseAudio.vue
new file mode 100644
index 0000000..86df246
--- /dev/null
+++ b/components/u-parse/components/wxParseAudio.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
diff --git a/components/u-parse/components/wxParseImg.vue b/components/u-parse/components/wxParseImg.vue
new file mode 100644
index 0000000..f558456
--- /dev/null
+++ b/components/u-parse/components/wxParseImg.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
diff --git a/components/u-parse/components/wxParseTable.vue b/components/u-parse/components/wxParseTable.vue
new file mode 100644
index 0000000..e1e25bf
--- /dev/null
+++ b/components/u-parse/components/wxParseTable.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/u-parse/components/wxParseTemplate0.vue b/components/u-parse/components/wxParseTemplate0.vue
new file mode 100644
index 0000000..0c76e74
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate0.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate1.vue b/components/u-parse/components/wxParseTemplate1.vue
new file mode 100644
index 0000000..a864f23
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate1.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate10.vue b/components/u-parse/components/wxParseTemplate10.vue
new file mode 100644
index 0000000..9a8d8b6
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate10.vue
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate11.vue b/components/u-parse/components/wxParseTemplate11.vue
new file mode 100644
index 0000000..1402d11
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate11.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
+
+ \n
+
+
+
+
+
+ {{node.text}}
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate2.vue b/components/u-parse/components/wxParseTemplate2.vue
new file mode 100644
index 0000000..d6d027d
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate2.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate3.vue b/components/u-parse/components/wxParseTemplate3.vue
new file mode 100644
index 0000000..f899edd
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate3.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate4.vue b/components/u-parse/components/wxParseTemplate4.vue
new file mode 100644
index 0000000..9bd558c
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate4.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate5.vue b/components/u-parse/components/wxParseTemplate5.vue
new file mode 100644
index 0000000..4f6cc27
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate5.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate6.vue b/components/u-parse/components/wxParseTemplate6.vue
new file mode 100644
index 0000000..4781c64
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate6.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate7.vue b/components/u-parse/components/wxParseTemplate7.vue
new file mode 100644
index 0000000..1efc4dc
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate7.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate8.vue b/components/u-parse/components/wxParseTemplate8.vue
new file mode 100644
index 0000000..2ac546f
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate8.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseTemplate9.vue b/components/u-parse/components/wxParseTemplate9.vue
new file mode 100644
index 0000000..c771e5f
--- /dev/null
+++ b/components/u-parse/components/wxParseTemplate9.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{node.text}}
+
+
+
+
diff --git a/components/u-parse/components/wxParseVideo.vue b/components/u-parse/components/wxParseVideo.vue
new file mode 100644
index 0000000..a952f58
--- /dev/null
+++ b/components/u-parse/components/wxParseVideo.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
diff --git a/components/u-parse/libs/html2json.js b/components/u-parse/libs/html2json.js
new file mode 100644
index 0000000..0927382
--- /dev/null
+++ b/components/u-parse/libs/html2json.js
@@ -0,0 +1,261 @@
+/**
+ * html2Json 改造来自: https://github.com/Jxck/html2json
+ *
+ *
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ * 垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+
+import wxDiscode from './wxDiscode';
+import HTMLParser from './htmlparser';
+
+function makeMap(str) {
+ const obj = {};
+ const items = str.split(',');
+ for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
+ return obj;
+}
+
+// Block Elements - HTML 5
+const block = makeMap('br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');
+
+// Inline Elements - HTML 5
+const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');
+
+// Elements that you can, intentionally, leave open
+// (and which close themselves)
+const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
+
+function removeDOCTYPE(html) {
+ const isDocument = /
([^]*)<\/body>/.test(html);
+ return isDocument ? RegExp.$1 : html;
+}
+
+function trimHtml(html) {
+ return html
+ .replace(//gi, '')
+ .replace(/\/\*.*?\*\//gi, '')
+ .replace(/[ ]+/gi, '')
+ .replace(/
+```
+
+
+## 渲染 Markdown
+
+> 先将 markdown 转换为 html 即可
+
+```
+npm install marked
+```
+
+``` js
+import marked from 'marked'
+import uParse from '@/components/u-parse/u-parse.vue'
+
+export default {
+ components: {
+ uParse
+ },
+ data () {
+ return {
+ article: marked(`#hello, markdown!`)
+ }
+ }
+}
+```
diff --git a/components/u-parse/u-parse.css b/components/u-parse/u-parse.css
new file mode 100644
index 0000000..691993a
--- /dev/null
+++ b/components/u-parse/u-parse.css
@@ -0,0 +1,232 @@
+/**
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ * 垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+
+.wxParse {
+ width: 100%;
+ font-family: Helvetica, sans-serif;
+ font-size: 30upx;
+ color: #666;
+ line-height: 1.8;
+}
+
+.wxParse view {
+ word-break: hyphenate;
+}
+
+.wxParse .inline {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+
+.wxParse .div {
+ margin: 0;
+ padding: 0;
+}
+
+.wxParse .h1 .text {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+.wxParse .h2 .text {
+ font-size: 1.5em;
+ margin: 0.83em 0;
+}
+.wxParse .h3 .text {
+ font-size: 1.17em;
+ margin: 1em 0;
+}
+.wxParse .h4 .text {
+ margin: 1.33em 0;
+}
+.wxParse .h5 .text {
+ font-size: 0.83em;
+ margin: 1.67em 0;
+}
+.wxParse .h6 .text {
+ font-size: 0.67em;
+ margin: 2.33em 0;
+}
+
+.wxParse .h1 .text,
+.wxParse .h2 .text,
+.wxParse .h3 .text,
+.wxParse .h4 .text,
+.wxParse .h5 .text,
+.wxParse .h6 .text,
+.wxParse .b,
+.wxParse .strong {
+ font-weight: bolder;
+}
+
+
+.wxParse .p {
+ margin: 1em 0;
+}
+
+.wxParse .i,
+.wxParse .cite,
+.wxParse .em,
+.wxParse .var,
+.wxParse .address {
+ font-style: italic;
+}
+
+.wxParse .pre,
+.wxParse .tt,
+.wxParse .code,
+.wxParse .kbd,
+.wxParse .samp {
+ font-family: monospace;
+}
+.wxParse .pre {
+ overflow: auto;
+ background: #f5f5f5;
+ padding: 16upx;
+ white-space: pre;
+ margin: 1em 0upx;
+}
+.wxParse .code {
+ display: inline;
+ background: #f5f5f5;
+}
+
+.wxParse .big {
+ font-size: 1.17em;
+}
+
+.wxParse .small,
+.wxParse .sub,
+.wxParse .sup {
+ font-size: 0.83em;
+}
+
+.wxParse .sub {
+ vertical-align: sub;
+}
+.wxParse .sup {
+ vertical-align: super;
+}
+
+.wxParse .s,
+.wxParse .strike,
+.wxParse .del {
+ text-decoration: line-through;
+}
+
+.wxParse .strong,
+.wxParse .s {
+ display: inline;
+}
+
+.wxParse .a {
+ color: deepskyblue;
+}
+
+.wxParse .video {
+ text-align: center;
+ margin: 22upx 0;
+}
+
+.wxParse .video-video {
+ width: 100%;
+}
+
+.wxParse .img {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ max-width: 100%;
+ overflow: hidden;
+}
+
+.wxParse .blockquote {
+ margin: 10upx 0;
+ padding: 22upx 0 22upx 22upx;
+ font-family: Courier, Calibri, "宋体";
+ background: #f5f5f5;
+ border-left: 6upx solid #dbdbdb;
+}
+.wxParse .blockquote .p {
+ margin: 0;
+}
+
+.wxParse .ul, .wxParse .ol {
+ display: block;
+ margin: 1em 0;
+ padding-left: 33upx;
+}
+.wxParse .ol {
+ list-style-type: disc;
+}
+.wxParse .ol {
+ list-style-type: decimal;
+}
+.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template {
+ display: list-item;
+ align-items: baseline;
+ text-align: match-parent;
+}
+
+.wxParse .ol>.li,.wxParse .ul>.li {
+ display: list-item;
+ align-items: baseline;
+ text-align: match-parent;
+}
+.wxParse .ul .ul, .wxParse .ol .ul {
+ list-style-type: circle;
+}
+.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul {
+ list-style-type: square;
+}
+
+.wxParse .u {
+ text-decoration: underline;
+}
+.wxParse .hide {
+ display: none;
+}
+.wxParse .del {
+ display: inline;
+}
+.wxParse .figure {
+ overflow: hidden;
+}
+
+.wxParse .table {
+ width: 100%;
+}
+.wxParse .thead, .wxParse .tfoot, .wxParse .tr {
+ display: flex;
+ flex-direction: row;
+}
+.wxParse .tr {
+ width:100%;
+ display: flex;
+ border-right: 2upx solid #e0e0e0;
+ border-bottom: 2upx solid #e0e0e0;
+}
+.wxParse .th,
+.wxParse .td {
+ display: flex;
+ width: 1276upx;
+ overflow: auto;
+ flex: 1;
+ padding: 11upx;
+ border-left: 2upx solid #e0e0e0;
+}
+.wxParse .td:last {
+ border-top: 2upx solid #e0e0e0;
+}
+.wxParse .th {
+ background: #f0f0f0;
+ border-top: 2upx solid #e0e0e0;
+}
diff --git a/components/u-parse/u-parse.vue b/components/u-parse/u-parse.vue
new file mode 100644
index 0000000..494e60c
--- /dev/null
+++ b/components/u-parse/u-parse.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c3ff205
--- /dev/null
+++ b/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..c1caf36
--- /dev/null
+++ b/main.js
@@ -0,0 +1,22 @@
+import App from './App'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+ ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+export function createApp() {
+ const app = createSSRApp(App)
+ return {
+ app
+ }
+}
+// #endif
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..a71de2a
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,92 @@
+{
+ "name" : "uni-guangan",
+ "appid" : "__UNI__8389A82",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "usingComponents" : true,
+ "nvueStyleCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {},
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "wx8ebfd37103471d92",
+ "setting" : {
+ "urlCheck" : false,
+ "postcss" : true,
+ "es6" : true,
+ "minified" : true
+ },
+ "usingComponents" : true,
+ "permission" : {
+ "scope.userLocation" : {
+ "desc" : "获取和定位问题位置"
+ }
+ },
+ "requiredPrivateInfos" : [ "getLocation" ]
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "vueVersion" : "3",
+ "locale" : "zh-Hans",
+ "fallbackLocale" : "zh-Hans",
+ "h5" : {
+ "sdkConfigs" : {
+ "maps" : {
+ "tencent" : {
+ "key" : "NRFBZ-ZGV6Z-V6FXJ-73O4E-5ZW53-MYFCR"
+ }
+ }
+ }
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..3ea8a65
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,227 @@
+{
+ "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+ {
+ "path": "pages/index/index",
+ "style": {
+ "navigationBarTitleText": "首页"
+ }
+ },
+ {
+ "path": "pages/user/index",
+ "style": {
+ "navigationBarTitleText": "我的"
+ }
+ },
+ {
+ "path": "pages/news/detail",
+ "style": {
+ "navigationBarTitleText": "文章详情"
+ }
+ },
+ {
+ "path" : "pages/user/login",
+ "style" :
+ {
+ "navigationBarTitleText" : "用户登录"
+ }
+ },
+ {
+ "path" : "pages/points-mall/index",
+ "style" :
+ {
+ "navigationBarTitleText" : "积分商城"
+ }
+ },
+ {
+ "path" : "pages/user/point",
+ "style" :
+ {
+ "navigationBarTitleText" : "我的积分"
+ }
+ },
+ {
+ "path" : "pages/user-share/user-share",
+ "style" :
+ {
+ "navigationBarTitleText" : "随手拍"
+ }
+ },
+ {
+ "path" : "pages/tutorial/tutorial",
+ "style" :
+ {
+ "navigationBarTitleText" : "办事指南"
+ }
+ },
+ {
+ "path" : "pages/tutorial/detail",
+ "style" :
+ {
+ "navigationBarTitleText" : "办事指南详情"
+ }
+ },
+ {
+ "path" : "pages/message/message",
+ "style" :
+ {
+ "navigationBarTitleText" : "我的消息"
+ }
+ },
+ {
+ "path" : "pages/user/user_share",
+ "style" :
+ {
+ "navigationBarTitleText" : "我的随手拍"
+ }
+ },
+ {
+ "path" : "pages/user-share/detail",
+ "style" :
+ {
+ "navigationBarTitleText" : "随手拍详情"
+ }
+ },
+ {
+ "path" : "pages/thumb/thumb",
+ "style" :
+ {
+ "navigationBarTitleText" : "城市点赞"
+ }
+ },
+ {
+ "path" : "pages/thumb/list",
+ "style" :
+ {
+ "navigationBarTitleText" : "城市点赞列表"
+ }
+ },
+ {
+ "path" : "pages/const/help",
+ "style" :
+ {
+ "navigationBarTitleText" : "帮助中心"
+ }
+ },
+ {
+ "path" : "pages/const/about",
+ "style" :
+ {
+ "navigationBarTitleText" : "关于我们"
+ }
+ },
+ {
+ "path" : "pages/const/license",
+ "style" :
+ {
+ "navigationBarTitleText" : "用户协议"
+ }
+ },
+ {
+ "path" : "pages/const/privacy",
+ "style" :
+ {
+ "navigationBarTitleText" : "隐私协议"
+ }
+ },
+ {
+ "path" : "pages/const/more",
+ "style" :
+ {
+ "navigationBarTitleText" : "更多设置"
+ }
+ },
+ {
+ "path" : "pages/thumb/detail",
+ "style" :
+ {
+ "navigationBarTitleText" : "点赞城市详情"
+ }
+ },
+ {
+ "path" : "pages/points-mall/detail",
+ "style" :
+ {
+ "navigationBarTitleText" : "商品详情"
+ }
+ },
+ {
+ "path" : "pages/points-mall/buy",
+ "style" :
+ {
+ "navigationBarTitleText" : "确认兑换"
+ }
+ },
+ {
+ "path" : "pages/user/address",
+ "style" :
+ {
+ "navigationBarTitleText" : "收货地址管理"
+ }
+ },
+ {
+ "path" : "pages/user/address_edit",
+ "style" :
+ {
+ "navigationBarTitleText" : "编辑地址"
+ }
+ },
+ {
+ "path" : "pages/user/order",
+ "style" :
+ {
+ "navigationBarTitleText" : "订单列表"
+ }
+ },
+ {
+ "path" : "pages/user/info",
+ "style" :
+ {
+ "navigationBarTitleText" : "账号管理"
+ }
+ },
+ {
+ "path" : "pages/user/bind/bind",
+ "style" :
+ {
+ "navigationBarTitleText" : "绑定手机"
+ }
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "广安",
+ "navigationBarBackgroundColor": "#F8F8F8",
+ "backgroundColor": "#F8F8F8"
+ },
+ "uniIdRouter": {},
+ "tabBar": {
+ "color": "#555555",
+ "selectedColor": "#2F85FC",
+ "iconWidth": "128rpx",
+ "list": [{
+ "iconPath": "/static/images/icon-home-n.png",
+ "selectedIconPath": "/static/images/icon-home.png",
+ "pagePath": "pages/index/index",
+ "text": "首页"
+ },
+ {
+ "iconPath": "static/images/icon-dzcs-n.png",
+ "selectedIconPath": "static/images/icon-dzcs.png",
+ "pagePath": "pages/thumb/list",
+ "text": "点赞城市"
+ },
+ {
+ "iconPath": "static/images/icon-bszn-n.png",
+ "selectedIconPath": "static/images/icon-bszn.png",
+ "pagePath": "pages/tutorial/tutorial",
+ "text": "办事指南"
+ },
+ {
+ "iconPath": "static/images/icon-my-n.png",
+ "selectedIconPath": "static/images/icon-my.png",
+ "pagePath": "pages/user/index",
+ "text": "我的"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/pages/const/about.vue b/pages/const/about.vue
new file mode 100644
index 0000000..928c57d
--- /dev/null
+++ b/pages/const/about.vue
@@ -0,0 +1,22 @@
+
+
+ 关于我们页面
+
+
+
+
+
+
diff --git a/pages/const/help.vue b/pages/const/help.vue
new file mode 100644
index 0000000..bf0ad90
--- /dev/null
+++ b/pages/const/help.vue
@@ -0,0 +1,22 @@
+
+
+ 帮助页面
+
+
+
+
+
+
diff --git a/pages/const/license.vue b/pages/const/license.vue
new file mode 100644
index 0000000..407c303
--- /dev/null
+++ b/pages/const/license.vue
@@ -0,0 +1,22 @@
+
+
+ 用户条例
+
+
+
+
+
+
diff --git a/pages/const/more.vue b/pages/const/more.vue
new file mode 100644
index 0000000..2fab532
--- /dev/null
+++ b/pages/const/more.vue
@@ -0,0 +1,89 @@
+
+
+
+
+ 帮助中心
+
+
+
+
+ 关于我们
+
+
+
+
+ 通知提醒
+
+
+
+
+ 用户协议
+
+
+
+
+ 隐私政策
+
+
+
+
+
+
+
+
diff --git a/pages/const/privacy.vue b/pages/const/privacy.vue
new file mode 100644
index 0000000..5380308
--- /dev/null
+++ b/pages/const/privacy.vue
@@ -0,0 +1,22 @@
+
+
+ 隐私政策
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..87267b2
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,299 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 随手拍
+
+
+
+ 积分商城
+
+
+
+ 办事指南
+
+
+
+ 点赞城市
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/message/message.vue b/pages/message/message.vue
new file mode 100644
index 0000000..03eb0db
--- /dev/null
+++ b/pages/message/message.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/news/detail.vue b/pages/news/detail.vue
new file mode 100644
index 0000000..d5c71c8
--- /dev/null
+++ b/pages/news/detail.vue
@@ -0,0 +1,78 @@
+
+
+
+ {{newsInfo.title}}
+
+
+
+ {{newsInfo.author}}
+
+
+
+ {{newsInfo.view_count}}
+
+
+
+ {{newsInfo.publish_at}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/points-mall/buy.vue b/pages/points-mall/buy.vue
new file mode 100644
index 0000000..a67c2f1
--- /dev/null
+++ b/pages/points-mall/buy.vue
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+ 请选择收货地址
+
+
+
+
+
+
+ {{address.user_name}}
+ {{address.user_phone}}
+
+ {{address.region_prov}}{{address.region_city}}{{address.region_area}}{{address.region_addr}}
+
+
+
+
+
+ 订单编号
+ {{order.order_no}}
+
+
+
+
+ 商品积分
+ {{order.amount_goods}}
+
+
+
+ 备注信息
+
+
+
+
+
+
+ 消耗:
+ {{order.amount_total}}
+
+ 立即兑换
+
+
+
+
+
+
+
+
diff --git a/pages/points-mall/detail.vue b/pages/points-mall/detail.vue
new file mode 100644
index 0000000..8a9faab
--- /dev/null
+++ b/pages/points-mall/detail.vue
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+ {{goodsInfo.name}}
+
+
+
+ {{goodsInfo.price_selling}}
+
+ {{goodsInfo.price_market}}
+
+
+
+ 图文详情
+
+
+
+
+
+
+
+
+
+
+ 首页
+
+
+
+ 立即兑换
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/points-mall/index.vue b/pages/points-mall/index.vue
new file mode 100644
index 0000000..708f324
--- /dev/null
+++ b/pages/points-mall/index.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/thumb/detail.vue b/pages/thumb/detail.vue
new file mode 100644
index 0000000..dbbd589
--- /dev/null
+++ b/pages/thumb/detail.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+ 点赞内容
+ {{info.content}}
+
+
+ 点赞时间
+ {{info.create_at}}
+
+
+ 图片
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/thumb/list.vue b/pages/thumb/list.vue
new file mode 100644
index 0000000..02bb819
--- /dev/null
+++ b/pages/thumb/list.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/thumb/thumb.vue b/pages/thumb/thumb.vue
new file mode 100644
index 0000000..6cf6e93
--- /dev/null
+++ b/pages/thumb/thumb.vue
@@ -0,0 +1,129 @@
+
+
+
+ 点赞城市内容:
+
+
+
+ 相关图片:
+
+
+
![]()
+

+
+
+

+
+
+
+
+
+ 立即提交
+
+
+
+
+
+
+
+
diff --git a/pages/tutorial/detail.vue b/pages/tutorial/detail.vue
new file mode 100644
index 0000000..0dda780
--- /dev/null
+++ b/pages/tutorial/detail.vue
@@ -0,0 +1,64 @@
+
+
+
+ {{newsInfo.title}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/tutorial/tutorial.vue b/pages/tutorial/tutorial.vue
new file mode 100644
index 0000000..7372792
--- /dev/null
+++ b/pages/tutorial/tutorial.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user-share/detail.vue b/pages/user-share/detail.vue
new file mode 100644
index 0000000..7f733e0
--- /dev/null
+++ b/pages/user-share/detail.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+ 反馈内容
+ {{info.content}}
+
+
+ 反馈地址
+ {{info.ticket_region}} {{info.ticket_address}}
+
+
+ 反馈地址
+ {{info.create_at}}
+
+
+ 图片
+
+
+
+
+
+
+
+ 处理记录
+
+
+ 处理时间:{{item.create_at}}
+ {{item.content}}
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user-share/user-share.vue b/pages/user-share/user-share.vue
new file mode 100644
index 0000000..5c8713e
--- /dev/null
+++ b/pages/user-share/user-share.vue
@@ -0,0 +1,205 @@
+
+
+
+
+ 随手拍简单、高效的反馈并上传问题
+
+
+ 问题类型:
+
+
+ {{type_name}}
+
+ 请选择问题分类
+
+
+
+ 反馈内容:
+
+
+
+ 问题地址:
+
+
+ {{province}}{{city}}{{area}}
+ 省市区
+
+
+
+
+
+
+ 联系方式:
+
+
+
+
+
+
+
+
+ 相关图片:
+
+
+
![]()
+

+
+
+

+
+
+
+
+
+ 立即提交
+
+
+
+
+
+
+
+
diff --git a/pages/user/address.vue b/pages/user/address.vue
new file mode 100644
index 0000000..db6b459
--- /dev/null
+++ b/pages/user/address.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/address_edit.vue b/pages/user/address_edit.vue
new file mode 100644
index 0000000..6083755
--- /dev/null
+++ b/pages/user/address_edit.vue
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{province}}{{city}}{{district}}
+
+ 省市区
+
+
+
+
+
+
+
+
+
+ 清空当前信息
+
+
+
+
+ 立即保存
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/user/bind/bind.vue b/pages/user/bind/bind.vue
new file mode 100644
index 0000000..2dc99d9
--- /dev/null
+++ b/pages/user/bind/bind.vue
@@ -0,0 +1,150 @@
+
+
+
+
+ 绑定手机
+
+
+
+
+
+ 手机验证码
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/index.vue b/pages/user/index.vue
new file mode 100644
index 0000000..66d567f
--- /dev/null
+++ b/pages/user/index.vue
@@ -0,0 +1,203 @@
+
+
+
+
+
+ Hi,{{userInfo.nickname || userInfo.extra.nickName}}
+
+
+
+
+ 账号管理
+
+
+
+
+ 我的随手拍
+
+
+
+
+ 用户积分
+
+
+
+
+ 我的订单
+
+
+
+
+ 我的消息
+
+
+
+
+ 更多设置
+
+
+
+
+
+
+
+
diff --git a/pages/user/info.vue b/pages/user/info.vue
new file mode 100644
index 0000000..2308a3c
--- /dev/null
+++ b/pages/user/info.vue
@@ -0,0 +1,157 @@
+
+
+
+
+ 账号昵称
+
+
+
+
+
+ 修改头像
+
+
+
+
+
+
+
+
diff --git a/pages/user/login.vue b/pages/user/login.vue
new file mode 100644
index 0000000..649ea8c
--- /dev/null
+++ b/pages/user/login.vue
@@ -0,0 +1,101 @@
+
+
+
+
+ 登录
+
+
+
+
+
+ 微信授权
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/user/order.vue b/pages/user/order.vue
new file mode 100644
index 0000000..029034c
--- /dev/null
+++ b/pages/user/order.vue
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/point.vue b/pages/user/point.vue
new file mode 100644
index 0000000..8c2249e
--- /dev/null
+++ b/pages/user/point.vue
@@ -0,0 +1,143 @@
+
+
+
+
+ {{point}}
+ 当前积分
+
+
+
+
+
+
+
+ {{item.reason}}
+ {{item.create_at}}
+
+
+
+
+ {{item.point>0?'+':''}}{{item.point}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/user/user_share.vue b/pages/user/user_share.vue
new file mode 100644
index 0000000..2b5ecab
--- /dev/null
+++ b/pages/user/user_share.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/images/addImage.png b/static/images/addImage.png
new file mode 100644
index 0000000..cd9d39a
Binary files /dev/null and b/static/images/addImage.png differ
diff --git a/static/images/delete.png b/static/images/delete.png
new file mode 100644
index 0000000..fb0191f
Binary files /dev/null and b/static/images/delete.png differ
diff --git a/static/images/icon-bszn-n.png b/static/images/icon-bszn-n.png
new file mode 100644
index 0000000..eb08f22
Binary files /dev/null and b/static/images/icon-bszn-n.png differ
diff --git a/static/images/icon-bszn.png b/static/images/icon-bszn.png
new file mode 100644
index 0000000..9fef031
Binary files /dev/null and b/static/images/icon-bszn.png differ
diff --git a/static/images/icon-city.png b/static/images/icon-city.png
new file mode 100644
index 0000000..25ad0d2
Binary files /dev/null and b/static/images/icon-city.png differ
diff --git a/static/images/icon-dzcs-n.png b/static/images/icon-dzcs-n.png
new file mode 100644
index 0000000..a50cd94
Binary files /dev/null and b/static/images/icon-dzcs-n.png differ
diff --git a/static/images/icon-dzcs.png b/static/images/icon-dzcs.png
new file mode 100644
index 0000000..4ca3c67
Binary files /dev/null and b/static/images/icon-dzcs.png differ
diff --git a/static/images/icon-guide.png b/static/images/icon-guide.png
new file mode 100644
index 0000000..7330de1
Binary files /dev/null and b/static/images/icon-guide.png differ
diff --git a/static/images/icon-home-n.png b/static/images/icon-home-n.png
new file mode 100644
index 0000000..2ce44ea
Binary files /dev/null and b/static/images/icon-home-n.png differ
diff --git a/static/images/icon-home.png b/static/images/icon-home.png
new file mode 100644
index 0000000..752e37b
Binary files /dev/null and b/static/images/icon-home.png differ
diff --git a/static/images/icon-like.png b/static/images/icon-like.png
new file mode 100644
index 0000000..1c8ed46
Binary files /dev/null and b/static/images/icon-like.png differ
diff --git a/static/images/icon-mall-n.png b/static/images/icon-mall-n.png
new file mode 100644
index 0000000..f4fe2ca
Binary files /dev/null and b/static/images/icon-mall-n.png differ
diff --git a/static/images/icon-mall.png b/static/images/icon-mall.png
new file mode 100644
index 0000000..ec7598c
Binary files /dev/null and b/static/images/icon-mall.png differ
diff --git a/static/images/icon-my-n.png b/static/images/icon-my-n.png
new file mode 100644
index 0000000..994ab54
Binary files /dev/null and b/static/images/icon-my-n.png differ
diff --git a/static/images/icon-my.png b/static/images/icon-my.png
new file mode 100644
index 0000000..ccd427a
Binary files /dev/null and b/static/images/icon-my.png differ
diff --git a/static/images/icon-nolike.png b/static/images/icon-nolike.png
new file mode 100644
index 0000000..08de4c8
Binary files /dev/null and b/static/images/icon-nolike.png differ
diff --git a/static/images/icon-photograph.png b/static/images/icon-photograph.png
new file mode 100644
index 0000000..ea90a70
Binary files /dev/null and b/static/images/icon-photograph.png differ
diff --git a/static/images/icon-store.png b/static/images/icon-store.png
new file mode 100644
index 0000000..324ea22
Binary files /dev/null and b/static/images/icon-store.png differ
diff --git a/static/images/icon-time.png b/static/images/icon-time.png
new file mode 100644
index 0000000..3d66c98
Binary files /dev/null and b/static/images/icon-time.png differ
diff --git a/static/images/icon-warn.png b/static/images/icon-warn.png
new file mode 100644
index 0000000..bf91b24
Binary files /dev/null and b/static/images/icon-warn.png differ
diff --git a/static/images/user-no-avatar.png b/static/images/user-no-avatar.png
new file mode 100644
index 0000000..6cbdbb2
Binary files /dev/null and b/static/images/user-no-avatar.png differ
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 0000000..b5771e2
Binary files /dev/null and b/static/logo.png differ
diff --git a/uni.promisify.adaptor.js b/uni.promisify.adaptor.js
new file mode 100644
index 0000000..5fec4f3
--- /dev/null
+++ b/uni.promisify.adaptor.js
@@ -0,0 +1,13 @@
+uni.addInterceptor({
+ returnValue (res) {
+ if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+ return res;
+ }
+ return new Promise((resolve, reject) => {
+ res.then((res) => {
+ if (!res) return resolve(res)
+ return res[0] ? reject(res[0]) : resolve(res[1])
+ });
+ });
+ },
+});
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..3b1c648
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color: #333; //基本色
+$uni-text-color-inverse: #fff; //反色
+$uni-text-color-grey: #999; //辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable: #c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color: #ffffff;
+$uni-bg-color-grey: #f8f8f8;
+$uni-bg-color-hover: #f1f1f1; //点击状态颜色
+$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color: #e5e5e5;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm: 12px;
+$uni-font-size-base: 14px;
+$uni-font-size-lg: 16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm: 20px;
+$uni-img-size-base: 26px;
+$uni-img-size-lg: 40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 4rpx;
+$uni-border-radius-base: 6rpx;
+$uni-border-radius-lg: 12rpx;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 8rpx;
+$uni-spacing-col-base: 16rpx;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2c405a; // 文章标题颜色
+$uni-font-size-title: 20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle: 18px;
+$uni-color-paragraph: #3f536e; // 文章段落颜色
+$uni-font-size-paragraph: 15px;
\ No newline at end of file
diff --git a/uni_modules/uni-ajax/README.md b/uni_modules/uni-ajax/README.md
new file mode 100644
index 0000000..7f1a611
--- /dev/null
+++ b/uni_modules/uni-ajax/README.md
@@ -0,0 +1,83 @@
+## ✨ 特性
+
+- 支持 Promise API
+- 支持 Typescript 开发
+- 拦截请求和响应
+- 自定义配置请求实例
+- 多种 Method 方法请求
+- 支持 RequestTask 操作
+
+## 🍟 文档
+
+**[uniajax.ponjs.com](https://uniajax.ponjs.com)**
+
+## 🥗 安装
+
+**插件市场**
+
+在插件市场右上角选择 `使用HBuilder X 导入插件` 或者 `下载插件ZIP`
+
+**NPM**
+
+```bash
+# 如果您的项目是HBuilder X创建的,根目录又没有package.json文件的话,请先执行如下命令:
+# npm init -y
+
+# 安装
+npm install uni-ajax
+
+# 更新
+npm update uni-ajax
+```
+
+## 🥐 实例
+
+新建 `ajax.js` 文件(文件名可自定义)用于处理拦截器、接口根地址、默认配置等,详细配置请[查看文档](https://uniajax.ponjs.com/instance/create.html)
+
+```JavaScript
+// ajax.js
+
+import ajax from 'uni-ajax' // 引入 uni-ajax 模块
+
+const instance = ajax.create(config) // 创建请求实例
+
+instance.interceptors.request.use(onFulfilled, onRejected) // 添加请求拦截器
+instance.interceptors.response.use(onFulfilled, onRejected) // 添加响应拦截器
+
+export default instance // 导出创建后的实例
+```
+
+## 🥪 使用
+
+**请求方法**
+
+```JavaScript
+// 常规方法
+ajax()
+
+// 请求方法别名
+ajax.get()
+ajax.post()
+ajax.put()
+ajax.delete()
+```
+
+**RequestTask**
+
+```JavaScript
+import ajax, { Fetcher } from 'uni-ajax'
+
+const fetcher = new Fetcher()
+ajax({ fetcher })
+
+fetcher.abort() // 中断请求任务
+const requestTask = await fetcher.source() // 获取请求任务对象
+```
+
+**其他属性方法**
+
+```JavaScript
+ajax.defaults // 全局默认配置
+ajax.config // 当前实例配置
+ajax.getURL(config) // 获取实例请求地址
+```
diff --git a/uni_modules/uni-ajax/changelog.md b/uni_modules/uni-ajax/changelog.md
new file mode 100644
index 0000000..d5191ef
--- /dev/null
+++ b/uni_modules/uni-ajax/changelog.md
@@ -0,0 +1,35 @@
+## 2.5.1(2023-01-16)
+- 精简代码,体积更小,性能提升
+- 废弃封装请求任务方法和 xhr 属性 [详情](https://uniajax.ponjs.com/guide/usage#requesttask)
+- 新增 fetcher 属性获取请求任务 [详情](https://uniajax.ponjs.com/api/config#fetcher)
+- 移除回调函数属性 success / fail / complete [详情](https://uniajax.ponjs.com/guide/usage#发起请求)
+## 2.4.6(2022-12-01)
+- 新增自定义响应内容类型 CustomResponse [详情](https://uniajax.ponjs.com/guide/typescript#定义类型)
+- 修改自定义请求配置类型 CustomConfig [详情](https://uniajax.ponjs.com/guide/typescript#定义类型)
+- 优化插件市场安装引入路径 [详情](https://uniajax.ponjs.com/guide/installation#插件市场)
+- 优化创建请求类工厂函数
+
+## 2.4.5(2022-07-08)
+- 优化使用拦截器的 Typescript 类型 [详情](https://uniajax.ponjs.com/api#interceptors)
+
+## 2.4.4(2022-04-01)
+- 修复 params 参数被转成 JSON 字符串问题 [详情](https://uniajax.ponjs.com/api/config#params)
+
+## 2.4.3(2022-02-24)
+- 兼容支付宝小程序不支持 `class extends Promise` 错误
+- 去除多余的 defaults 默认值 [详情](https://uniajax.ponjs.com/api#defaults)
+
+## 2.4.2(2022-02-01)
+- 修改 params 配置参数 [详情](https://uniajax.ponjs.com/api/config#params)
+- 新增 query 配置参数 [详情](https://uniajax.ponjs.com/api/config#query)
+- 优化 create 方法的 TypeScript 参数类型
+
+## 2.4.1(2022-01-15)
+- 全新的获取实例配置机制 [详情](https://uniajax.ponjs.com/guide/instance#实例配置)
+- 新增全局默认配置 [详情](https://uniajax.ponjs.com/guide/instance#全局配置)
+- 新增获取请求地址方法 [详情](https://uniajax.ponjs.com/api#geturl)
+- 去除获取 baseURL 和 origin 属性
+
+## 2.4.0(2022-01-15)
+**全新版本发布**
+注意 2.4.x 版本与 2.3.x 以下版本存在些许差异!
diff --git a/uni_modules/uni-ajax/js_sdk/index.d.ts b/uni_modules/uni-ajax/js_sdk/index.d.ts
new file mode 100644
index 0000000..4f41322
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/index.d.ts
@@ -0,0 +1,103 @@
+export type AnyObject = { [x: string]: any }
+
+export type Data = string | AnyObject | ArrayBuffer
+export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'HEAD' | 'OPTIONS' | 'TRACE'
+export type DataType = 'json' | 'text' | 'html'
+export type ResponseType = 'text' | 'arraybuffer'
+
+export interface RequestTask {
+ abort: () => void
+ onHeadersReceived?: (listener: (header: any) => void) => void
+ offHeadersReceived?: (listener: (header: any) => void) => void
+}
+
+export interface FetcherInstance {
+ resolve: (value: T) => void
+ reject: (reason?: any) => void
+ source: () => Promise
+ abort: () => Promise
+}
+
+export interface FetcherConstructor {
+ new (): FetcherInstance
+}
+
+export interface CustomConfig {}
+
+export interface AjaxRequestConfig extends CustomConfig {
+ baseURL?: string
+ url?: string
+ data?: Data
+ query?: AnyObject
+ params?: AnyObject
+ header?: any
+ method?: Method
+ timeout?: number
+ dataType?: DataType
+ responseType?: ResponseType
+ sslVerify?: boolean
+ withCredentials?: boolean
+ firstIpv4?: boolean
+ fetcher?: FetcherInstance
+ validateStatus?: ((statusCode?: number) => boolean) | null
+ adapter?: (config: AjaxRequestConfig) => Promise
+}
+
+export type AjaxConfigType =
+ | AjaxRequestConfig
+ | (() => AjaxRequestConfig)
+ | (() => Promise)
+ | void
+
+export interface AjaxResponse {
+ data: T
+ statusCode: number
+ header: any
+ config: AjaxRequestConfig
+ errMsg: string
+ cookies: string[]
+}
+
+export interface AjaxInterceptorManager {
+ use(onFulfilled?: (value: V) => T | Promise, onRejected?: (error: any) => any): number
+ eject(id: number): void
+}
+
+export interface CustomResponse {}
+
+export type AjaxResult = keyof CustomResponse extends never ? AjaxResponse : CustomResponse
+
+export interface AjaxInvoke {
+ >(config?: AjaxRequestConfig): Promise
+ >(url?: string, data?: Data, config?: AjaxRequestConfig): Promise
+}
+
+export interface AjaxInstance extends AjaxInvoke {
+ get: AjaxInvoke
+ post: AjaxInvoke
+ put: AjaxInvoke
+ delete: AjaxInvoke
+ connect: AjaxInvoke
+ head: AjaxInvoke
+ options: AjaxInvoke
+ trace: AjaxInvoke
+ getURL(config?: AjaxConfigType): Promise
+ readonly defaults: AjaxRequestConfig
+ readonly config: T
+ interceptors: {
+ request: AjaxInterceptorManager
+ response: AjaxInterceptorManager
+ }
+}
+
+export interface AjaxStatic extends AjaxInstance {
+ create(config?: T): AjaxInstance
+ Fetcher: FetcherConstructor
+}
+
+declare const Ajax: AjaxStatic
+declare const Fetcher: FetcherConstructor
+
+export { Fetcher }
+
+export default Ajax
diff --git a/uni_modules/uni-ajax/js_sdk/index.js b/uni_modules/uni-ajax/js_sdk/index.js
new file mode 100644
index 0000000..1b4d732
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/index.js
@@ -0,0 +1,14 @@
+import Ajax from './lib/core/Ajax'
+import Fetcher from './lib/adapters/Fetcher'
+
+const ajax = Ajax()
+
+ajax.create = function create(instanceConfig) {
+ return Ajax(instanceConfig)
+}
+
+ajax.Fetcher = Fetcher
+
+export { Fetcher }
+
+export default ajax
diff --git a/uni_modules/uni-ajax/js_sdk/lib/adapters/Fetcher.js b/uni_modules/uni-ajax/js_sdk/lib/adapters/Fetcher.js
new file mode 100644
index 0000000..b8c801e
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/adapters/Fetcher.js
@@ -0,0 +1,22 @@
+const PROMISE = Symbol('$$promise')
+
+export default class Fetcher {
+ get [Symbol.toStringTag]() {
+ return '[object Fetcher]'
+ }
+
+ constructor() {
+ this[PROMISE] = new Promise((resolve, reject) => {
+ this.resolve = resolve
+ this.reject = reject
+ })
+ }
+
+ async source() {
+ return this[PROMISE]
+ }
+
+ async abort() {
+ ;(await this.source())?.abort()
+ }
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/adapters/http.js b/uni_modules/uni-ajax/js_sdk/lib/adapters/http.js
new file mode 100644
index 0000000..865c706
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/adapters/http.js
@@ -0,0 +1,16 @@
+export default function adapter(config) {
+ return new Promise((resolve, reject) => {
+ const requestTask = uni.request({
+ ...config,
+ complete: result => {
+ // 根据状态码判断要执行的触发的状态
+ const response = { config, ...result }
+ !config.validateStatus || config.validateStatus(result.statusCode)
+ ? resolve(response)
+ : reject(response)
+ }
+ })
+
+ config.fetcher?.resolve(requestTask)
+ })
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/core/Ajax.js b/uni_modules/uni-ajax/js_sdk/lib/core/Ajax.js
new file mode 100644
index 0000000..b3d5b71
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/core/Ajax.js
@@ -0,0 +1,72 @@
+import InterceptorManager from './InterceptorManager'
+import buildURL from '../helpers/buildURL'
+import mergeConfig from '../helpers/mergeConfig'
+import dispatchRequest from './dispatchRequest'
+import { detachCancel, dispatchCancel, interceptCancel } from './handleCancel'
+import defaults, { METHOD } from '../defaults'
+import { forEach, merge } from '../utils'
+
+export default function Ajax(defaultConfig) {
+ // 挂载当前实例配置
+ ajax.config = Object.freeze(
+ typeof defaultConfig === 'object' ? merge(defaultConfig) : defaultConfig
+ )
+
+ // 挂载全局默认配置引用
+ ajax.defaults = defaults
+
+ // 挂载拦截器
+ ajax.interceptors = {
+ request: new InterceptorManager(),
+ response: new InterceptorManager()
+ }
+
+ // 挂载获取实例请求地址方法
+ ajax.getURL = async function getURL(config) {
+ const combineConfig = await mergeConfig(defaults, defaultConfig, config)
+ return buildURL(combineConfig).replace(/^\?/, '')
+ }
+
+ // 挂载对应的 method 方法
+ forEach(METHOD, method => {
+ ajax[method] = function methodAjax(url, data, config) {
+ if (typeof url === 'string') return ajax(url, data, { ...config, method })
+ return ajax({ ...url, method })
+ }
+ })
+
+ function ajax(url, data, config) {
+ const newConfig = typeof url === 'string' ? { ...config, url, data } : { ...url }
+
+ // 声明 Promise 链
+ const chain = [dispatchRequest, dispatchCancel]
+
+ // 将请求拦截遍历添加到链前面
+ ajax.interceptors.request.forEach(
+ ({ fulfilled, rejected }) => chain.unshift(fulfilled, rejected),
+ true
+ )
+
+ // 将响应拦截遍历添加到链后面
+ ajax.interceptors.response.forEach(
+ ({ fulfilled, rejected }) => chain.push(fulfilled, interceptCancel(rejected)),
+ false
+ )
+
+ // 先执行获取 config 请求配置
+ chain.unshift(config => mergeConfig(defaults, defaultConfig, config), undefined)
+
+ // 处理发起请求前的错误数据
+ chain.push(undefined, detachCancel)
+
+ // 创建请求Promise,后面遍历链将链上方法传递到then回调
+ let request = Promise.resolve(newConfig)
+ while (chain.length) {
+ request = request.then(chain.shift(), chain.shift())
+ }
+
+ return request
+ }
+
+ return ajax
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/core/InterceptorManager.js b/uni_modules/uni-ajax/js_sdk/lib/core/InterceptorManager.js
new file mode 100644
index 0000000..2cdaa7c
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/core/InterceptorManager.js
@@ -0,0 +1,32 @@
+/**
+ * 拦截器类
+ */
+export default class InterceptorManager {
+ handlers = []
+
+ use(fulfilled, rejected) {
+ this.handlers.push({
+ fulfilled,
+ rejected
+ })
+ return this.handlers.length - 1
+ }
+
+ eject(id) {
+ if (this.handlers[id]) {
+ this.handlers[id] = null
+ }
+ }
+
+ forEach(fn, reverse = false) {
+ if (reverse) {
+ for (let i = this.handlers.length - 1; i >= 0; i--) {
+ this.handlers[i] !== null && fn(this.handlers[i])
+ }
+ } else {
+ for (let i = 0, l = this.handlers.length; i < l; i++) {
+ this.handlers[i] !== null && fn(this.handlers[i])
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/core/dispatchRequest.js b/uni_modules/uni-ajax/js_sdk/lib/core/dispatchRequest.js
new file mode 100644
index 0000000..a95f253
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/core/dispatchRequest.js
@@ -0,0 +1,29 @@
+import buildURL from '../helpers/buildURL'
+import isCallback from '../helpers/isCallback'
+import { forEach, isPlainObject, merge } from '../utils'
+import { HEADER } from '../defaults'
+
+/** 派发请求方法 */
+export default function dispatchRequest(config) {
+ // 拼接 url
+ config.url = buildURL(config)
+
+ // 请求方法转大写
+ config.method = (config.method || 'get').toUpperCase()
+
+ // 调整 header 优先级
+ config.header = merge(
+ config.header.common,
+ config.header[config.method.toLowerCase()],
+ config.header
+ )
+
+ // 清除多余的请求头
+ forEach(HEADER, h => isPlainObject(config.header[h]) && delete config.header[h])
+
+ // 清除回调函数
+ forEach(config, (val, key) => isCallback(key) && delete config[key])
+
+ // 执行请求方法
+ return config.adapter(config)
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/core/handleCancel.js b/uni_modules/uni-ajax/js_sdk/lib/core/handleCancel.js
new file mode 100644
index 0000000..96f3df4
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/core/handleCancel.js
@@ -0,0 +1,35 @@
+const CANCEL = Symbol('$$cancel')
+
+function hasCancel(target) {
+ return target === null || target === undefined
+ ? false
+ : Object.prototype.hasOwnProperty.call(target, CANCEL)
+}
+
+/**
+ * 派发请求拒绝方法,处理发起请求前错误,取消执行请求,并防止进入响应拦截器
+ * @param {*} reason 错误原因
+ * @returns {Promise} 封装了 CANCEL 的失败对象
+ */
+export function dispatchCancel(reason) {
+ return Promise.reject({ [CANCEL]: reason })
+}
+
+/**
+ * 拦截失败对象
+ * @param {Function} rejected 响应错误拦截器
+ */
+export function interceptCancel(rejected) {
+ // 判断发起请求前是否发生错误,如果发生错误则不执行后面的响应错误拦截器
+ return (
+ rejected && (response => (hasCancel(response) ? Promise.reject(response) : rejected(response)))
+ )
+}
+
+/**
+ * 分离失败对象
+ * @param {*} response 封装了 CANCEL 的失败对象
+ */
+export function detachCancel(error) {
+ return Promise.reject(hasCancel(error) ? error[CANCEL] : error)
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/defaults.js b/uni_modules/uni-ajax/js_sdk/lib/defaults.js
new file mode 100644
index 0000000..f5f0413
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/defaults.js
@@ -0,0 +1,16 @@
+import adapter from './adapters/http'
+import { forEach } from './utils'
+
+export const METHOD = ['get', 'post', 'put', 'delete', 'connect', 'head', 'options', 'trace']
+export const HEADER = ['common', ...METHOD]
+
+const defaults = {
+ adapter,
+ header: {},
+ method: 'GET',
+ validateStatus: statusCode => statusCode >= 200 && statusCode < 300
+}
+
+forEach(HEADER, h => (defaults.header[h] = {}))
+
+export default defaults
diff --git a/uni_modules/uni-ajax/js_sdk/lib/helpers/buildURL.js b/uni_modules/uni-ajax/js_sdk/lib/helpers/buildURL.js
new file mode 100644
index 0000000..f9332ff
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/helpers/buildURL.js
@@ -0,0 +1,83 @@
+import { forEach, isArray } from '../utils'
+
+/**
+ * 根据 baseURL 和 url 拼接
+ * @param {string} baseURL 请求根地址
+ * @param {string} relativeURL 请求参数地址
+ * @returns {string} 拼接后的地址
+ */
+function combineURL(baseURL = '', relativeURL = '') {
+ // 判断是否 http:// 或 https:// 开头
+ if (/^https?:\/\//.test(relativeURL)) return relativeURL
+ // 去除 baseURL 结尾斜杠,去除 relativeURL 开头斜杠,再判断拼接
+ return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL
+}
+
+function encode(val) {
+ return encodeURIComponent(val)
+ .replace(/%3A/gi, ':')
+ .replace(/%24/g, '$')
+ .replace(/%2C/gi, ',')
+ .replace(/%20/g, '+')
+ .replace(/%5B/gi, '[')
+ .replace(/%5D/gi, ']')
+}
+
+function querystring(url, params) {
+ let query
+
+ const parts = []
+ forEach(params, (val, key) => {
+ if (val === null || typeof val === 'undefined') return
+
+ if (isArray(val)) key = key + '[]'
+ else val = [val]
+
+ forEach(val, v => {
+ if (v !== null && typeof v === 'object') {
+ v = JSON.stringify(v)
+ }
+ parts.push(encode(key) + '=' + encode(v))
+ })
+ })
+ query = parts.join('&')
+
+ if (query) {
+ const hashmarkIndex = url.indexOf('#')
+ hashmarkIndex !== -1 && (url = url.slice(0, hashmarkIndex))
+ url += (url.indexOf('?') === -1 ? '?' : '&') + query
+ }
+
+ return url
+}
+
+/**
+ * 根据 baseURL、url、params query 编译请求URL
+ * @returns {string} 处理后的地址
+ */
+export default function buildURL({ baseURL, url: relativeURL, params, query } = {}) {
+ let url = combineURL(baseURL, relativeURL)
+
+ if (!params && !query) {
+ return url
+ }
+
+ if (params) {
+ if (/\/:/.test(url)) {
+ // 是否是 params 参数地址,并对应设置
+ forEach(params, (val, key) => {
+ url = url.replace(`/:${key}`, `/${encode(String(val))}`)
+ })
+ } else if (!query) {
+ // 兼容旧的 params 属性设置 query
+ url = querystring(url, params)
+ }
+ }
+
+ // 设置 query 参数
+ if (query) {
+ url = querystring(url, query)
+ }
+
+ return url
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/helpers/isCallback.js b/uni_modules/uni-ajax/js_sdk/lib/helpers/isCallback.js
new file mode 100644
index 0000000..3bdf921
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/helpers/isCallback.js
@@ -0,0 +1,8 @@
+/**
+ * 判断参数是否含有回调参数 success / fail / complete 之一
+ * @param {string} field 参数的 Key 值字符串
+ * @returns {boolean} 返回判断值
+ */
+export default function isCallback(field) {
+ return ['success', 'fail', 'complete'].includes(field)
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/helpers/mergeConfig.js b/uni_modules/uni-ajax/js_sdk/lib/helpers/mergeConfig.js
new file mode 100644
index 0000000..26131ef
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/helpers/mergeConfig.js
@@ -0,0 +1,41 @@
+import { assign, forEach } from '../utils'
+
+/**
+ * 深度合并,且不合并 undefined 值
+ * @param {object} obj1 前对象
+ * @param {object} obj2 后对象
+ * @returns {object} 合并后的对象
+ */
+function merge(obj1 = {}, obj2 = {}) {
+ const obj = {}
+
+ const objKeys = Object.keys({ ...obj1, ...obj2 })
+
+ forEach(objKeys, prop => {
+ if (obj2[prop] !== undefined) {
+ obj[prop] = assign(obj1[prop], obj2[prop])
+ } else if (obj1[prop] !== undefined) {
+ obj[prop] = assign(undefined, obj1[prop])
+ }
+ })
+
+ return obj
+}
+
+/**
+ * 合并请求配置
+ * @param {...object|function} args 请求配置
+ * @returns {object} 合并后的请求配置
+ */
+export default async function mergeConfig(...args) {
+ let config = {}
+
+ for (let i = 0, l = args.length; i < l; i++) {
+ const current = typeof args[i] === 'function' ? await args[i]() : args[i]
+ config = merge(config, current)
+ }
+
+ config.method = config.method.toUpperCase()
+
+ return config
+}
diff --git a/uni_modules/uni-ajax/js_sdk/lib/utils.js b/uni_modules/uni-ajax/js_sdk/lib/utils.js
new file mode 100644
index 0000000..c94b006
--- /dev/null
+++ b/uni_modules/uni-ajax/js_sdk/lib/utils.js
@@ -0,0 +1,77 @@
+/**
+ * 获取值的原始类型字符串,例如 [object Object]
+ */
+const _toString = Object.prototype.toString
+
+/**
+ * 判断是否为数组
+ * @param {*} val 要判断的值
+ * @returns {boolean} 返回判断结果
+ */
+export function isArray(val) {
+ return _toString.call(val) === '[object Array]'
+}
+
+/**
+ * 判断是否为普通对象
+ * @param {*} val 要判断的值
+ * @returns {boolean} 返回判断结果
+ */
+export function isPlainObject(val) {
+ return _toString.call(val) === '[object Object]'
+}
+
+/**
+ * 遍历
+ * @param {object|array} obj 要迭代的对象
+ * @param {function} fn 为每个项调用的回调
+ */
+export function forEach(obj, fn) {
+ if (obj === null || obj === undefined) return
+ if (typeof obj !== 'object') obj = [obj]
+ if (isArray(obj)) {
+ for (let i = 0, l = obj.length; i < l; i++) {
+ fn.call(null, obj[i], i, obj)
+ }
+ } else {
+ for (const k in obj) {
+ if (Object.prototype.hasOwnProperty.call(obj, k)) {
+ fn.call(null, obj[k], k, obj)
+ }
+ }
+ }
+}
+
+/**
+ * 对象深合并
+ * @param {...object} args 对象
+ * @returns {object} 合并后的对象
+ */
+export function merge(...args) {
+ const result = {}
+ for (let i = 0, l = args.length; i < l; i++) {
+ if (isPlainObject(args[i])) {
+ forEach(args[i], (val, key) => {
+ result[key] = assign(result[key], val)
+ })
+ }
+ }
+ return result
+}
+
+/**
+ * 合并分配到目标对象
+ * @param {*} target 目标对象
+ * @param {*} source 源对象
+ * @returns {*} 目标对象
+ */
+export function assign(target, source) {
+ if (isPlainObject(target) && isPlainObject(source)) {
+ return merge(target, source)
+ } else if (isPlainObject(source)) {
+ return merge({}, source)
+ } else if (isArray(source)) {
+ return source.slice()
+ }
+ return source
+}
diff --git a/uni_modules/uni-ajax/package.json b/uni_modules/uni-ajax/package.json
new file mode 100644
index 0000000..f6845a9
--- /dev/null
+++ b/uni_modules/uni-ajax/package.json
@@ -0,0 +1,74 @@
+{
+ "id": "u-ajax",
+ "displayName": "request uni-ajax 请求",
+ "version": "2.5.1",
+ "description": "封装 uni.request,支持拦截器、接口根地址、默认配置、中断请求等功能",
+ "keywords": [
+ "ajax",
+ "http",
+ "promise",
+ "request",
+ "task"
+],
+ "main": "./js_sdk/index.js",
+ "types": "./js_sdk/index.d.ts",
+ "repository": "https://github.com/ponjs/uni-ajax",
+ "dcloudext": {
+ "type": "sdk-js",
+ "declaration": {
+ "ads": "无",
+ "data": "插件不采集任何数据",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/uni-ajax",
+ "contact": {
+ "qq": ""
+ }
+ },
+ "uni_modules": {
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "y",
+ "快手": "y",
+ "飞书": "y",
+ "京东": "y"
+ },
+ "快应用": {
+ "华为": "y",
+ "联盟": "y"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-badge/changelog.md b/uni_modules/uni-badge/changelog.md
new file mode 100644
index 0000000..e352c60
--- /dev/null
+++ b/uni_modules/uni-badge/changelog.md
@@ -0,0 +1,33 @@
+## 1.2.2(2023-01-28)
+- 修复 运行/打包 控制台警告问题
+## 1.2.1(2022-09-05)
+- 修复 当 text 超过 max-num 时,badge 的宽度计算是根据 text 的长度计算,更改为 css 计算实际展示宽度,详见:[https://ask.dcloud.net.cn/question/150473](https://ask.dcloud.net.cn/question/150473)
+## 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-badge](https://uniapp.dcloud.io/component/uniui/uni-badge)
+## 1.1.7(2021-11-08)
+- 优化 升级ui
+- 修改 size 属性默认值调整为 small
+- 修改 type 属性,默认值调整为 error,info 替换 default
+## 1.1.6(2021-09-22)
+- 修复 在字节小程序上样式不生效的 bug
+## 1.1.5(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.4(2021-07-29)
+- 修复 去掉 nvue 不支持css 的 align-self 属性,nvue 下不暂支持 absolute 属性
+## 1.1.3(2021-06-24)
+- 优化 示例项目
+## 1.1.1(2021-05-12)
+- 新增 组件示例地址
+## 1.1.0(2021-05-12)
+- 新增 uni-badge 的 absolute 属性,支持定位
+- 新增 uni-badge 的 offset 属性,支持定位偏移
+- 新增 uni-badge 的 is-dot 属性,支持仅显示有一个小点
+- 新增 uni-badge 的 max-num 属性,支持自定义封顶的数字值,超过 99 显示99+
+- 优化 uni-badge 属性 custom-style, 支持以对象形式自定义样式
+## 1.0.7(2021-05-07)
+- 修复 uni-badge 在 App 端,数字小于10时不是圆形的bug
+- 修复 uni-badge 在父元素不是 flex 布局时,宽度缩小的bug
+- 新增 uni-badge 属性 custom-style, 支持自定义样式
+## 1.0.6(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-badge/components/uni-badge/uni-badge.vue b/uni_modules/uni-badge/components/uni-badge/uni-badge.vue
new file mode 100644
index 0000000..956354b
--- /dev/null
+++ b/uni_modules/uni-badge/components/uni-badge/uni-badge.vue
@@ -0,0 +1,268 @@
+
+
+
+ {{displayValue}}
+
+
+
+
+
+
diff --git a/uni_modules/uni-badge/package.json b/uni_modules/uni-badge/package.json
new file mode 100644
index 0000000..b0bac93
--- /dev/null
+++ b/uni_modules/uni-badge/package.json
@@ -0,0 +1,85 @@
+{
+ "id": "uni-badge",
+ "displayName": "uni-badge 数字角标",
+ "version": "1.2.2",
+ "description": "数字角标(徽章)组件,在元素周围展示消息提醒,一般用于列表、九宫格、按钮等地方。",
+ "keywords": [
+ "",
+ "badge",
+ "uni-ui",
+ "uniui",
+ "数字角标",
+ "徽章"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "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"
+ },
+ "快应用": {
+ "华为": "y",
+ "联盟": "y"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-badge/readme.md b/uni_modules/uni-badge/readme.md
new file mode 100644
index 0000000..bdf175d
--- /dev/null
+++ b/uni_modules/uni-badge/readme.md
@@ -0,0 +1,10 @@
+## Badge 数字角标
+> **组件名:uni-badge**
+> 代码块: `uBadge`
+
+数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景,
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-badge)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+
+
diff --git a/uni_modules/uni-calendar/changelog.md b/uni_modules/uni-calendar/changelog.md
new file mode 100644
index 0000000..a728bb8
--- /dev/null
+++ b/uni_modules/uni-calendar/changelog.md
@@ -0,0 +1,28 @@
+## 1.4.11(2024-01-10)
+- 修复 回到今天时,月份显示不一致问题
+## 1.4.10(2023-04-10)
+- 修复 某些情况 monthSwitch 未触发的Bug
+## 1.4.9(2023-02-02)
+- 修复 某些情况切换月份错误的Bug
+## 1.4.8(2023-01-30)
+- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/161964)
+## 1.4.7(2022-09-16)
+- 优化 支持使用 uni-scss 控制主题色
+## 1.4.6(2022-09-08)
+- 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件的Bug
+## 1.4.5(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式的Bug
+## 1.4.4(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式的Bug
+## 1.4.3(2021-09-22)
+- 修复 startDate、 endDate 属性失效的Bug
+## 1.4.2(2021-08-24)
+- 新增 支持国际化
+## 1.4.1(2021-08-05)
+- 修复 弹出层被 tabbar 遮盖的Bug
+## 1.4.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.3.16(2021-05-12)
+- 新增 组件示例地址
+## 1.3.15(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-calendar/components/uni-calendar/calendar.js b/uni_modules/uni-calendar/components/uni-calendar/calendar.js
new file mode 100644
index 0000000..b8d7d6f
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/calendar.js
@@ -0,0 +1,546 @@
+/**
+* @1900-2100区间内的公历、农历互转
+* @charset UTF-8
+* @github https://github.com/jjonline/calendar.js
+* @Author Jea杨(JJonline@JJonline.Cn)
+* @Time 2014-7-21
+* @Time 2016-8-13 Fixed 2033hex、Attribution Annals
+* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
+* @Time 2017-7-24 Fixed use getTerm Func Param Error.use solar year,NOT lunar year
+* @Version 1.0.3
+* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
+* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
+*/
+/* eslint-disable */
+var calendar = {
+
+ /**
+ * 农历1900-2100的润大小信息表
+ * @Array Of Property
+ * @return Hex
+ */
+ lunarInfo: [0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, // 1900-1909
+ 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, // 1910-1919
+ 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, // 1920-1929
+ 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, // 1930-1939
+ 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, // 1940-1949
+ 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, // 1950-1959
+ 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, // 1960-1969
+ 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, // 1970-1979
+ 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, // 1980-1989
+ 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, // 1990-1999
+ 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, // 2000-2009
+ 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, // 2010-2019
+ 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, // 2020-2029
+ 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, // 2030-2039
+ 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, // 2040-2049
+ /** Add By JJonline@JJonline.Cn**/
+ 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20, 0x1a6c4, 0x0aae0, // 2050-2059
+ 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0, 0x0a6d0, 0x055d4, // 2060-2069
+ 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4, 0x0a5b0, 0x052b0, // 2070-2079
+ 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570, 0x054e4, 0x0d160, // 2080-2089
+ 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, // 2090-2099
+ 0x0d520], // 2100
+
+ /**
+ * 公历每个月份的天数普通表
+ * @Array Of Property
+ * @return Number
+ */
+ solarMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
+
+ /**
+ * 天干地支之天干速查表
+ * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
+ * @return Cn string
+ */
+ Gan: ['\u7532', '\u4e59', '\u4e19', '\u4e01', '\u620a', '\u5df1', '\u5e9a', '\u8f9b', '\u58ec', '\u7678'],
+
+ /**
+ * 天干地支之地支速查表
+ * @Array Of Property
+ * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
+ * @return Cn string
+ */
+ Zhi: ['\u5b50', '\u4e11', '\u5bc5', '\u536f', '\u8fb0', '\u5df3', '\u5348', '\u672a', '\u7533', '\u9149', '\u620c', '\u4ea5'],
+
+ /**
+ * 天干地支之地支速查表<=>生肖
+ * @Array Of Property
+ * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
+ * @return Cn string
+ */
+ Animals: ['\u9f20', '\u725b', '\u864e', '\u5154', '\u9f99', '\u86c7', '\u9a6c', '\u7f8a', '\u7334', '\u9e21', '\u72d7', '\u732a'],
+
+ /**
+ * 24节气速查表
+ * @Array Of Property
+ * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
+ * @return Cn string
+ */
+ solarTerm: ['\u5c0f\u5bd2', '\u5927\u5bd2', '\u7acb\u6625', '\u96e8\u6c34', '\u60ca\u86f0', '\u6625\u5206', '\u6e05\u660e', '\u8c37\u96e8', '\u7acb\u590f', '\u5c0f\u6ee1', '\u8292\u79cd', '\u590f\u81f3', '\u5c0f\u6691', '\u5927\u6691', '\u7acb\u79cb', '\u5904\u6691', '\u767d\u9732', '\u79cb\u5206', '\u5bd2\u9732', '\u971c\u964d', '\u7acb\u51ac', '\u5c0f\u96ea', '\u5927\u96ea', '\u51ac\u81f3'],
+
+ /**
+ * 1900-2100各年的24节气日期速查表
+ * @Array Of Property
+ * @return 0x string For splice
+ */
+ sTermInfo: ['9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f',
+ '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f', 'b027097bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd0b06bdb0722c965ce1cfcc920f',
+ 'b027097bd097c36b0b6fc9274c91aa', '9778397bd19801ec9210c965cc920e', '97b6b97bd19801ec95f8c965cc920f',
+ '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd197c36c9210c9274c91aa',
+ '97b6b97bd19801ec95f8c965cc920e', '97bd09801d98082c95f8e1cfcc920f', '97bd097bd097c36b0b6fc9210c8dc2',
+ '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec95f8c965cc920e', '97bcf97c3598082c95f8e1cfcc920f',
+ '97bd097bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf97c3598082c95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f',
+ '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf97c359801ec95f8c965cc920f', '97bd097bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf97c359801ec95f8c965cc920f', '97bd097bd07f595b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9210c8dc2', '9778397bd19801ec9210c9274c920e', '97b6b97bd19801ec95f8c965cc920f',
+ '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+ '97b6b97bd19801ec95f8c965cc920f', '97bd07f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+ '9778397bd097c36c9210c9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bd07f1487f595b0b0bc920fb0722',
+ '7f0e397bd097c36b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e', '97bcf7f1487f531b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b97bd19801ec9210c965cc920e',
+ '97bcf7f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b97bd19801ec9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+ '9778397bd097c36b0b6fc9210c91aa', '97b6b97bd197c36c9210c9274c920e', '97bcf7f0e47f531b0b0bb0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '9778397bd097c36c9210c9274c920e',
+ '97b6b7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c36b0b6fc9210c8dc2',
+ '9778397bd097c36b0b70c9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc9210c8dc2', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f595b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+ '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc920fb0722', '9778397bd097c36b0b6fc9274c91aa', '97b6b7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9274c91aa',
+ '97b6b7f0e47f531b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+ '9778397bd097c36b0b6fc9210c91aa', '97b6b7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '9778397bd097c36b0b6fc9210c8dc2', '977837f0e37f149b0723b0787b0721',
+ '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f5307f595b0b0bc920fb0722', '7f0e397bd097c35b0b6fc9210c8dc2',
+ '977837f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e37f1487f595b0b0bb0b6fb0722',
+ '7f0e397bd097c35b0b6fc9210c8dc2', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722', '977837f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd097c35b0b6fc920fb0722',
+ '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0b0bb0b6fb0722', '7f0e397bd07f595b0b0bc920fb0722',
+ '977837f0e37f14998082b0723b06bd', '7f07e7f0e37f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+ '7f0e397bd07f595b0b0bc920fb0722', '977837f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b0721',
+ '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f595b0b0bb0b6fb0722', '7f0e37f0e37f14898082b0723b02d5',
+ '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e37f1487f531b0b0bb0b6fb0722',
+ '7f0e37f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e37f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e37f14898082b072297c35',
+ '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722',
+ '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f149b0723b0787b0721',
+ '7f0e27f1487f531b0b0bb0b6fb0722', '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14998082b0723b06bd',
+ '7f07e7f0e47f149b0723b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722', '7f0e37f0e366aa89801eb072297c35',
+ '7ec967f0e37f14998082b0723b06bd', '7f07e7f0e37f14998083b0787b0721', '7f0e27f0e47f531b0723b0b6fb0722',
+ '7f0e37f0e366aa89801eb072297c35', '7ec967f0e37f14898082b0723b02d5', '7f07e7f0e37f14998082b0787b0721',
+ '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66aa89801e9808297c35', '665f67f0e37f14898082b0723b02d5',
+ '7ec967f0e37f14998082b0787b0721', '7f07e7f0e47f531b0723b0b6fb0722', '7f0e36665b66a449801e9808297c35',
+ '665f67f0e37f14898082b0723b02d5', '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721',
+ '7f0e36665b66a449801e9808297c35', '665f67f0e37f14898082b072297c35', '7ec967f0e37f14998082b0787b06bd',
+ '7f07e7f0e47f531b0723b0b6fb0721', '7f0e26665b66a449801e9808297c35', '665f67f0e37f1489801eb072297c35',
+ '7ec967f0e37f14998082b0787b06bd', '7f07e7f0e47f531b0723b0b6fb0721', '7f0e27f1487f531b0b0bb0b6fb0722'],
+
+ /**
+ * 数字转中文速查表
+ * @Array Of Property
+ * @trans ['日','一','二','三','四','五','六','七','八','九','十']
+ * @return Cn string
+ */
+ nStr1: ['\u65e5', '\u4e00', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341'],
+
+ /**
+ * 日期转农历称呼速查表
+ * @Array Of Property
+ * @trans ['初','十','廿','卅']
+ * @return Cn string
+ */
+ nStr2: ['\u521d', '\u5341', '\u5eff', '\u5345'],
+
+ /**
+ * 月份转农历称呼速查表
+ * @Array Of Property
+ * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
+ * @return Cn string
+ */
+ nStr3: ['\u6b63', '\u4e8c', '\u4e09', '\u56db', '\u4e94', '\u516d', '\u4e03', '\u516b', '\u4e5d', '\u5341', '\u51ac', '\u814a'],
+
+ /**
+ * 返回农历y年一整年的总天数
+ * @param lunar Year
+ * @return Number
+ * @eg:var count = calendar.lYearDays(1987) ;//count=387
+ */
+ lYearDays: function (y) {
+ var i; var sum = 348
+ for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y - 1900] & i) ? 1 : 0 }
+ return (sum + this.leapDays(y))
+ },
+
+ /**
+ * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
+ * @param lunar Year
+ * @return Number (0-12)
+ * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
+ */
+ leapMonth: function (y) { // 闰字编码 \u95f0
+ return (this.lunarInfo[y - 1900] & 0xf)
+ },
+
+ /**
+ * 返回农历y年闰月的天数 若该年没有闰月则返回0
+ * @param lunar Year
+ * @return Number (0、29、30)
+ * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
+ */
+ leapDays: function (y) {
+ if (this.leapMonth(y)) {
+ return ((this.lunarInfo[y - 1900] & 0x10000) ? 30 : 29)
+ }
+ return (0)
+ },
+
+ /**
+ * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
+ * @param lunar Year
+ * @return Number (-1、29、30)
+ * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
+ */
+ monthDays: function (y, m) {
+ if (m > 12 || m < 1) { return -1 }// 月份参数从1至12,参数错误返回-1
+ return ((this.lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29)
+ },
+
+ /**
+ * 返回公历(!)y年m月的天数
+ * @param solar Year
+ * @return Number (-1、28、29、30、31)
+ * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
+ */
+ solarDays: function (y, m) {
+ if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
+ var ms = m - 1
+ if (ms == 1) { // 2月份的闰平规律测算后确认返回28或29
+ return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28)
+ } else {
+ return (this.solarMonth[ms])
+ }
+ },
+
+ /**
+ * 农历年份转换为干支纪年
+ * @param lYear 农历年的年份数
+ * @return Cn string
+ */
+ toGanZhiYear: function (lYear) {
+ var ganKey = (lYear - 3) % 10
+ var zhiKey = (lYear - 3) % 12
+ if (ganKey == 0) ganKey = 10// 如果余数为0则为最后一个天干
+ if (zhiKey == 0) zhiKey = 12// 如果余数为0则为最后一个地支
+ return this.Gan[ganKey - 1] + this.Zhi[zhiKey - 1]
+ },
+
+ /**
+ * 公历月、日判断所属星座
+ * @param cMonth [description]
+ * @param cDay [description]
+ * @return Cn string
+ */
+ toAstro: function (cMonth, cDay) {
+ var s = '\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf'
+ var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22]
+ return s.substr(cMonth * 2 - (cDay < arr[cMonth - 1] ? 2 : 0), 2) + '\u5ea7'// 座
+ },
+
+ /**
+ * 传入offset偏移量返回干支
+ * @param offset 相对甲子的偏移量
+ * @return Cn string
+ */
+ toGanZhi: function (offset) {
+ return this.Gan[offset % 10] + this.Zhi[offset % 12]
+ },
+
+ /**
+ * 传入公历(!)y年获得该年第n个节气的公历日期
+ * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起
+ * @return day Number
+ * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
+ */
+ getTerm: function (y, n) {
+ if (y < 1900 || y > 2100) { return -1 }
+ if (n < 1 || n > 24) { return -1 }
+ var _table = this.sTermInfo[y - 1900]
+ var _info = [
+ parseInt('0x' + _table.substr(0, 5)).toString(),
+ parseInt('0x' + _table.substr(5, 5)).toString(),
+ parseInt('0x' + _table.substr(10, 5)).toString(),
+ parseInt('0x' + _table.substr(15, 5)).toString(),
+ parseInt('0x' + _table.substr(20, 5)).toString(),
+ parseInt('0x' + _table.substr(25, 5)).toString()
+ ]
+ var _calday = [
+ _info[0].substr(0, 1),
+ _info[0].substr(1, 2),
+ _info[0].substr(3, 1),
+ _info[0].substr(4, 2),
+
+ _info[1].substr(0, 1),
+ _info[1].substr(1, 2),
+ _info[1].substr(3, 1),
+ _info[1].substr(4, 2),
+
+ _info[2].substr(0, 1),
+ _info[2].substr(1, 2),
+ _info[2].substr(3, 1),
+ _info[2].substr(4, 2),
+
+ _info[3].substr(0, 1),
+ _info[3].substr(1, 2),
+ _info[3].substr(3, 1),
+ _info[3].substr(4, 2),
+
+ _info[4].substr(0, 1),
+ _info[4].substr(1, 2),
+ _info[4].substr(3, 1),
+ _info[4].substr(4, 2),
+
+ _info[5].substr(0, 1),
+ _info[5].substr(1, 2),
+ _info[5].substr(3, 1),
+ _info[5].substr(4, 2)
+ ]
+ return parseInt(_calday[n - 1])
+ },
+
+ /**
+ * 传入农历数字月份返回汉语通俗表示法
+ * @param lunar month
+ * @return Cn string
+ * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
+ */
+ toChinaMonth: function (m) { // 月 => \u6708
+ if (m > 12 || m < 1) { return -1 } // 若参数错误 返回-1
+ var s = this.nStr3[m - 1]
+ s += '\u6708'// 加上月字
+ return s
+ },
+
+ /**
+ * 传入农历日期数字返回汉字表示法
+ * @param lunar day
+ * @return Cn string
+ * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
+ */
+ toChinaDay: function (d) { // 日 => \u65e5
+ var s
+ switch (d) {
+ case 10:
+ s = '\u521d\u5341'; break
+ case 20:
+ s = '\u4e8c\u5341'; break
+ break
+ case 30:
+ s = '\u4e09\u5341'; break
+ break
+ default :
+ s = this.nStr2[Math.floor(d / 10)]
+ s += this.nStr1[d % 10]
+ }
+ return (s)
+ },
+
+ /**
+ * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
+ * @param y year
+ * @return Cn string
+ * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
+ */
+ getAnimal: function (y) {
+ return this.Animals[(y - 4) % 12]
+ },
+
+ /**
+ * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
+ * @param y solar year
+ * @param m solar month
+ * @param d solar day
+ * @return JSON object
+ * @eg:console.log(calendar.solar2lunar(1987,11,01));
+ */
+ solar2lunar: function (y, m, d) { // 参数区间1900.1.31~2100.12.31
+ // 年份限定、上限
+ if (y < 1900 || y > 2100) {
+ return -1// undefined转换为数字变为NaN
+ }
+ // 公历传参最下限
+ if (y == 1900 && m == 1 && d < 31) {
+ return -1
+ }
+ // 未传参 获得当天
+ if (!y) {
+ var objDate = new Date()
+ } else {
+ var objDate = new Date(y, parseInt(m) - 1, d)
+ }
+ var i; var leap = 0; var temp = 0
+ // 修正ymd参数
+ var y = objDate.getFullYear()
+ var m = objDate.getMonth() + 1
+ var d = objDate.getDate()
+ var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000
+ for (i = 1900; i < 2101 && offset > 0; i++) {
+ temp = this.lYearDays(i)
+ offset -= temp
+ }
+ if (offset < 0) {
+ offset += temp; i--
+ }
+
+ // 是否今天
+ var isTodayObj = new Date()
+ var isToday = false
+ if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) {
+ isToday = true
+ }
+ // 星期几
+ var nWeek = objDate.getDay()
+ var cWeek = this.nStr1[nWeek]
+ // 数字表示周几顺应天朝周一开始的惯例
+ if (nWeek == 0) {
+ nWeek = 7
+ }
+ // 农历年
+ var year = i
+ var leap = this.leapMonth(i) // 闰哪个月
+ var isLeap = false
+
+ // 效验闰月
+ for (i = 1; i < 13 && offset > 0; i++) {
+ // 闰月
+ if (leap > 0 && i == (leap + 1) && isLeap == false) {
+ --i
+ isLeap = true; temp = this.leapDays(year) // 计算农历闰月天数
+ } else {
+ temp = this.monthDays(year, i)// 计算农历普通月天数
+ }
+ // 解除闰月
+ if (isLeap == true && i == (leap + 1)) { isLeap = false }
+ offset -= temp
+ }
+ // 闰月导致数组下标重叠取反
+ if (offset == 0 && leap > 0 && i == leap + 1) {
+ if (isLeap) {
+ isLeap = false
+ } else {
+ isLeap = true; --i
+ }
+ }
+ if (offset < 0) {
+ offset += temp; --i
+ }
+ // 农历月
+ var month = i
+ // 农历日
+ var day = offset + 1
+ // 天干地支处理
+ var sm = m - 1
+ var gzY = this.toGanZhiYear(year)
+
+ // 当月的两个节气
+ // bugfix-2017-7-24 11:03:38 use lunar Year Param `y` Not `year`
+ var firstNode = this.getTerm(y, (m * 2 - 1))// 返回当月「节」为几日开始
+ var secondNode = this.getTerm(y, (m * 2))// 返回当月「节」为几日开始
+
+ // 依据12节气修正干支月
+ var gzM = this.toGanZhi((y - 1900) * 12 + m + 11)
+ if (d >= firstNode) {
+ gzM = this.toGanZhi((y - 1900) * 12 + m + 12)
+ }
+
+ // 传入的日期的节气与否
+ var isTerm = false
+ var Term = null
+ if (firstNode == d) {
+ isTerm = true
+ Term = this.solarTerm[m * 2 - 2]
+ }
+ if (secondNode == d) {
+ isTerm = true
+ Term = this.solarTerm[m * 2 - 1]
+ }
+ // 日柱 当月一日与 1900/1/1 相差天数
+ var dayCyclical = Date.UTC(y, sm, 1, 0, 0, 0, 0) / 86400000 + 25567 + 10
+ var gzD = this.toGanZhi(dayCyclical + d - 1)
+ // 该日期所属的星座
+ var astro = this.toAstro(m, d)
+
+ return { 'lYear': year, 'lMonth': month, 'lDay': day, 'Animal': this.getAnimal(year), 'IMonthCn': (isLeap ? '\u95f0' : '') + this.toChinaMonth(month), 'IDayCn': this.toChinaDay(day), 'cYear': y, 'cMonth': m, 'cDay': d, 'gzYear': gzY, 'gzMonth': gzM, 'gzDay': gzD, 'isToday': isToday, 'isLeap': isLeap, 'nWeek': nWeek, 'ncWeek': '\u661f\u671f' + cWeek, 'isTerm': isTerm, 'Term': Term, 'astro': astro }
+ },
+
+ /**
+ * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
+ * @param y lunar year
+ * @param m lunar month
+ * @param d lunar day
+ * @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
+ * @return JSON object
+ * @eg:console.log(calendar.lunar2solar(1987,9,10));
+ */
+ lunar2solar: function (y, m, d, isLeapMonth) { // 参数区间1900.1.31~2100.12.1
+ var isLeapMonth = !!isLeapMonth
+ var leapOffset = 0
+ var leapMonth = this.leapMonth(y)
+ var leapDay = this.leapDays(y)
+ if (isLeapMonth && (leapMonth != m)) { return -1 }// 传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
+ if (y == 2100 && m == 12 && d > 1 || y == 1900 && m == 1 && d < 31) { return -1 }// 超出了最大极限值
+ var day = this.monthDays(y, m)
+ var _day = day
+ // bugFix 2016-9-25
+ // if month is leap, _day use leapDays method
+ if (isLeapMonth) {
+ _day = this.leapDays(y, m)
+ }
+ if (y < 1900 || y > 2100 || d > _day) { return -1 }// 参数合法性效验
+
+ // 计算农历的时间差
+ var offset = 0
+ for (var i = 1900; i < y; i++) {
+ offset += this.lYearDays(i)
+ }
+ var leap = 0; var isAdd = false
+ for (var i = 1; i < m; i++) {
+ leap = this.leapMonth(y)
+ if (!isAdd) { // 处理闰月
+ if (leap <= i && leap > 0) {
+ offset += this.leapDays(y); isAdd = true
+ }
+ }
+ offset += this.monthDays(y, i)
+ }
+ // 转换闰月农历 需补充该年闰月的前一个月的时差
+ if (isLeapMonth) { offset += day }
+ // 1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
+ var stmap = Date.UTC(1900, 1, 30, 0, 0, 0)
+ var calObj = new Date((offset + d - 31) * 86400000 + stmap)
+ var cY = calObj.getUTCFullYear()
+ var cM = calObj.getUTCMonth() + 1
+ var cD = calObj.getUTCDate()
+
+ return this.solar2lunar(cY, cM, cD)
+ }
+}
+
+export default calendar
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
new file mode 100644
index 0000000..fcbd13c
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/en.json
@@ -0,0 +1,12 @@
+{
+ "uni-calender.ok": "ok",
+ "uni-calender.cancel": "cancel",
+ "uni-calender.today": "today",
+ "uni-calender.MON": "MON",
+ "uni-calender.TUE": "TUE",
+ "uni-calender.WED": "WED",
+ "uni-calender.THU": "THU",
+ "uni-calender.FRI": "FRI",
+ "uni-calender.SAT": "SAT",
+ "uni-calender.SUN": "SUN"
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js b/uni_modules/uni-calendar/components/uni-calendar/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/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
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
new file mode 100644
index 0000000..1ca43de
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hans.json
@@ -0,0 +1,12 @@
+{
+ "uni-calender.ok": "确定",
+ "uni-calender.cancel": "取消",
+ "uni-calender.today": "今日",
+ "uni-calender.SUN": "日",
+ "uni-calender.MON": "一",
+ "uni-calender.TUE": "二",
+ "uni-calender.WED": "三",
+ "uni-calender.THU": "四",
+ "uni-calender.FRI": "五",
+ "uni-calender.SAT": "六"
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
new file mode 100644
index 0000000..e0fe33b
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/i18n/zh-Hant.json
@@ -0,0 +1,12 @@
+{
+ "uni-calender.ok": "確定",
+ "uni-calender.cancel": "取消",
+ "uni-calender.today": "今日",
+ "uni-calender.SUN": "日",
+ "uni-calender.MON": "一",
+ "uni-calender.TUE": "二",
+ "uni-calender.WED": "三",
+ "uni-calender.THU": "四",
+ "uni-calender.FRI": "五",
+ "uni-calender.SAT": "六"
+}
diff --git a/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
new file mode 100644
index 0000000..a54135e
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue
@@ -0,0 +1,187 @@
+
+
+
+
+ {{weeks.date}}
+ {{todayText}}
+ {{weeks.isDay ? todayText : (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}
+ {{weeks.extraInfo.info}}
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
new file mode 100644
index 0000000..0beebfb
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/uni-calendar.vue
@@ -0,0 +1,567 @@
+
+
+
+
+
+
+
+
+ {{nowDate.month}}
+
+
+
+ {{SUNText}}
+
+
+ {{monText}}
+
+
+ {{TUEText}}
+
+
+ {{WEDText}}
+
+
+ {{THUText}}
+
+
+ {{FRIText}}
+
+
+ {{SATText}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-calendar/components/uni-calendar/util.js b/uni_modules/uni-calendar/components/uni-calendar/util.js
new file mode 100644
index 0000000..5ec8a92
--- /dev/null
+++ b/uni_modules/uni-calendar/components/uni-calendar/util.js
@@ -0,0 +1,360 @@
+import CALENDAR from './calendar.js'
+
+class Calendar {
+ constructor({
+ date,
+ selected,
+ startDate,
+ endDate,
+ range
+ } = {}) {
+ // 当前日期
+ this.date = this.getDate(new Date()) // 当前初入日期
+ // 打点信息
+ this.selected = selected || [];
+ // 范围开始
+ this.startDate = startDate
+ // 范围结束
+ this.endDate = endDate
+ this.range = range
+ // 多选状态
+ this.cleanMultipleStatus()
+ // 每周日期
+ this.weeks = {}
+ // this._getWeek(this.date.fullDate)
+ }
+ /**
+ * 设置日期
+ * @param {Object} date
+ */
+ setDate(date) {
+ this.selectDate = this.getDate(date)
+ this._getWeek(this.selectDate.fullDate)
+ }
+
+ /**
+ * 清理多选状态
+ */
+ cleanMultipleStatus() {
+ this.multipleStatus = {
+ before: '',
+ after: '',
+ data: []
+ }
+ }
+
+ /**
+ * 重置开始日期
+ */
+ resetSatrtDate(startDate) {
+ // 范围开始
+ this.startDate = startDate
+
+ }
+
+ /**
+ * 重置结束日期
+ */
+ resetEndDate(endDate) {
+ // 范围结束
+ this.endDate = endDate
+ }
+
+ /**
+ * 获取任意时间
+ */
+ getDate(date, AddDayCount = 0, str = 'day') {
+ if (!date) {
+ date = new Date()
+ }
+ if (typeof date !== 'object') {
+ date = date.replace(/-/g, '/')
+ }
+ const dd = new Date(date)
+ switch (str) {
+ case 'day':
+ dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
+ break
+ case 'month':
+ if (dd.getDate() === 31 && AddDayCount>0) {
+ dd.setDate(dd.getDate() + AddDayCount)
+ } else {
+ const preMonth = dd.getMonth()
+ dd.setMonth(preMonth + AddDayCount) // 获取AddDayCount天后的日期
+ const nextMonth = dd.getMonth()
+ // 处理 pre 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
+ if(AddDayCount<0 && preMonth!==0 && nextMonth-preMonth>AddDayCount){
+ dd.setMonth(nextMonth+(nextMonth-preMonth+AddDayCount))
+ }
+ // 处理 next 切换月份目标月份为2月没有当前日(30 31) 切换错误问题
+ if(AddDayCount>0 && nextMonth-preMonth>AddDayCount){
+ dd.setMonth(nextMonth-(nextMonth-preMonth-AddDayCount))
+ }
+ }
+ break
+ case 'year':
+ dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
+ break
+ }
+ const y = dd.getFullYear()
+ const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
+ const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
+ return {
+ fullDate: y + '-' + m + '-' + d,
+ year: y,
+ month: m,
+ date: d,
+ day: dd.getDay()
+ }
+ }
+
+
+ /**
+ * 获取上月剩余天数
+ */
+ _getLastMonthDays(firstDay, full) {
+ let dateArr = []
+ for (let i = firstDay; i > 0; i--) {
+ const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
+ dateArr.push({
+ date: beforeDate,
+ month: full.month - 1,
+ lunar: this.getlunar(full.year, full.month - 1, beforeDate),
+ disable: true
+ })
+ }
+ return dateArr
+ }
+ /**
+ * 获取本月天数
+ */
+ _currentMonthDys(dateData, full) {
+ let dateArr = []
+ let fullDate = this.date.fullDate
+ for (let i = 1; i <= dateData; i++) {
+ let nowDate = full.year + '-' + (full.month < 10 ?
+ full.month : full.month) + '-' + (i < 10 ?
+ '0' + i : i)
+ // 是否今天
+ let isDay = fullDate === nowDate
+ // 获取打点信息
+ let info = this.selected && this.selected.find((item) => {
+ if (this.dateEqual(nowDate, item.date)) {
+ return item
+ }
+ })
+
+ // 日期禁用
+ let disableBefore = true
+ let disableAfter = true
+ if (this.startDate) {
+ // let dateCompBefore = this.dateCompare(this.startDate, fullDate)
+ // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
+ disableBefore = this.dateCompare(this.startDate, nowDate)
+ }
+
+ if (this.endDate) {
+ // let dateCompAfter = this.dateCompare(fullDate, this.endDate)
+ // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
+ disableAfter = this.dateCompare(nowDate, this.endDate)
+ }
+ let multiples = this.multipleStatus.data
+ let checked = false
+ let multiplesStatus = -1
+ if (this.range) {
+ if (multiples) {
+ multiplesStatus = multiples.findIndex((item) => {
+ return this.dateEqual(item, nowDate)
+ })
+ }
+ if (multiplesStatus !== -1) {
+ checked = true
+ }
+ }
+ let data = {
+ fullDate: nowDate,
+ year: full.year,
+ date: i,
+ multiple: this.range ? checked : false,
+ beforeMultiple: this.dateEqual(this.multipleStatus.before, nowDate),
+ afterMultiple: this.dateEqual(this.multipleStatus.after, nowDate),
+ month: full.month,
+ lunar: this.getlunar(full.year, full.month, i),
+ disable: !(disableBefore && disableAfter),
+ isDay
+ }
+ if (info) {
+ data.extraInfo = info
+ }
+
+ dateArr.push(data)
+ }
+ return dateArr
+ }
+ /**
+ * 获取下月天数
+ */
+ _getNextMonthDays(surplus, full) {
+ let dateArr = []
+ for (let i = 1; i < surplus + 1; i++) {
+ dateArr.push({
+ date: i,
+ month: Number(full.month) + 1,
+ lunar: this.getlunar(full.year, Number(full.month) + 1, i),
+ disable: true
+ })
+ }
+ return dateArr
+ }
+
+ /**
+ * 获取当前日期详情
+ * @param {Object} date
+ */
+ getInfo(date) {
+ if (!date) {
+ date = new Date()
+ }
+ const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
+ return dateInfo
+ }
+
+ /**
+ * 比较时间大小
+ */
+ dateCompare(startDate, endDate) {
+ // 计算截止时间
+ startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+ // 计算详细项的截止时间
+ endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+ if (startDate <= endDate) {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ /**
+ * 比较时间是否相等
+ */
+ dateEqual(before, after) {
+ // 计算截止时间
+ before = new Date(before.replace('-', '/').replace('-', '/'))
+ // 计算详细项的截止时间
+ after = new Date(after.replace('-', '/').replace('-', '/'))
+ if (before.getTime() - after.getTime() === 0) {
+ return true
+ } else {
+ return false
+ }
+ }
+
+
+ /**
+ * 获取日期范围内所有日期
+ * @param {Object} begin
+ * @param {Object} end
+ */
+ geDateAll(begin, end) {
+ var arr = []
+ var ab = begin.split('-')
+ var ae = end.split('-')
+ var db = new Date()
+ db.setFullYear(ab[0], ab[1] - 1, ab[2])
+ var de = new Date()
+ de.setFullYear(ae[0], ae[1] - 1, ae[2])
+ var unixDb = db.getTime() - 24 * 60 * 60 * 1000
+ var unixDe = de.getTime() - 24 * 60 * 60 * 1000
+ for (var k = unixDb; k <= unixDe;) {
+ k = k + 24 * 60 * 60 * 1000
+ arr.push(this.getDate(new Date(parseInt(k))).fullDate)
+ }
+ return arr
+ }
+ /**
+ * 计算阴历日期显示
+ */
+ getlunar(year, month, date) {
+ return CALENDAR.solar2lunar(year, month, date)
+ }
+ /**
+ * 设置打点
+ */
+ setSelectInfo(data, value) {
+ this.selected = value
+ this._getWeek(data)
+ }
+
+ /**
+ * 获取多选状态
+ */
+ setMultiple(fullDate) {
+ let {
+ before,
+ after
+ } = this.multipleStatus
+
+ if (!this.range) return
+ if (before && after) {
+ this.multipleStatus.before = ''
+ this.multipleStatus.after = ''
+ this.multipleStatus.data = []
+ } else {
+ if (!before) {
+ this.multipleStatus.before = fullDate
+ } else {
+ this.multipleStatus.after = fullDate
+ if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+ this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
+ } else {
+ this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
+ }
+ }
+ }
+ this._getWeek(fullDate)
+ }
+
+ /**
+ * 获取每周数据
+ * @param {Object} dateData
+ */
+ _getWeek(dateData) {
+ const {
+ year,
+ month
+ } = this.getDate(dateData)
+ let firstDay = new Date(year, month - 1, 1).getDay()
+ let currentDay = new Date(year, month, 0).getDate()
+ let dates = {
+ lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
+ currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
+ nextMonthDays: [], // 下个月开始几天
+ weeks: []
+ }
+ let canlender = []
+ const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
+ dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
+ canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
+ let weeks = {}
+ // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
+ for (let i = 0; i < canlender.length; i++) {
+ if (i % 7 === 0) {
+ weeks[parseInt(i / 7)] = new Array(7)
+ }
+ weeks[parseInt(i / 7)][i % 7] = canlender[i]
+ }
+ this.canlender = canlender
+ this.weeks = weeks
+ }
+
+ //静态方法
+ // static init(date) {
+ // if (!this.instance) {
+ // this.instance = new Calendar(date);
+ // }
+ // return this.instance;
+ // }
+}
+
+
+export default Calendar
diff --git a/uni_modules/uni-calendar/package.json b/uni_modules/uni-calendar/package.json
new file mode 100644
index 0000000..bceaed3
--- /dev/null
+++ b/uni_modules/uni-calendar/package.json
@@ -0,0 +1,85 @@
+{
+ "id": "uni-calendar",
+ "displayName": "uni-calendar 日历",
+ "version": "1.4.11",
+ "description": "日历组件",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "日历",
+ "",
+ "打卡",
+ "日历选择"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-calendar/readme.md b/uni_modules/uni-calendar/readme.md
new file mode 100644
index 0000000..4e1748c
--- /dev/null
+++ b/uni_modules/uni-calendar/readme.md
@@ -0,0 +1,103 @@
+
+
+## Calendar 日历
+> **组件名:uni-calendar**
+> 代码块: `uCalendar`
+
+
+日历组件
+
+> **注意事项**
+> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
+> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js)
+> - 仅支持自定义组件模式
+> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date()
+> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意
+> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动
+
+
+### 安装方式
+
+本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
+
+如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
+
+### 基本用法
+
+在 ``template`` 中使用组件
+
+```html
+
+
+
+```
+
+### 通过方法打开日历
+
+需要设置 `insert` 为 `false`
+
+```html
+
+
+
+
+```
+
+```javascript
+
+export default {
+ data() {
+ return {};
+ },
+ methods: {
+ open(){
+ this.$refs.calendar.open();
+ },
+ confirm(e) {
+ console.log(e);
+ }
+ }
+};
+
+```
+
+
+## API
+
+### Calendar Props
+
+| 属性名 | 类型 | 默认值| 说明 |
+| - | - | - | - |
+| date | String |- | 自定义当前时间,默认为今天 |
+| lunar | Boolean | false | 显示农历 |
+| startDate | String |- | 日期选择范围-开始日期 |
+| endDate | String |- | 日期选择范围-结束日期 |
+| range | Boolean | false | 范围选择 |
+| insert | Boolean | false | 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式 |
+|clearDate |Boolean |true |弹窗模式是否清空上次选择内容 |
+| selected | Array |- | 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] |
+|showMonth | Boolean | true | 是否显示月份为背景 |
+
+### Calendar Events
+
+| 事件名 | 说明 |返回值|
+| - | - | - |
+| open | 弹出日历组件,`insert :false` 时生效|- |
+
+
+
+
+
+## 组件示例
+
+点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar)
diff --git a/uni_modules/uni-card/changelog.md b/uni_modules/uni-card/changelog.md
new file mode 100644
index 0000000..c3cd8c4
--- /dev/null
+++ b/uni_modules/uni-card/changelog.md
@@ -0,0 +1,26 @@
+## 1.3.1(2021-12-20)
+- 修复 在vue页面下略缩图显示不正常的bug
+## 1.3.0(2021-11-19)
+- 重构插槽的用法 ,header 替换为 title
+- 新增 actions 插槽
+- 新增 cover 封面图属性和插槽
+- 新增 padding 内容默认内边距离
+- 新增 margin 卡片默认外边距离
+- 新增 spacing 卡片默认内边距
+- 新增 shadow 卡片阴影属性
+- 取消 mode 属性,可使用组合插槽代替
+- 取消 note 属性 ,使用actions插槽代替
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-card](https://uniapp.dcloud.io/component/uniui/uni-card)
+## 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.8(2021-07-01)
+- 优化 图文卡片无图片加载时,提供占位图标
+- 新增 header 插槽,自定义卡片头部( 图文卡片 mode="style" 时,不支持)
+- 修复 thumbnail 不存在仍然占位的 bug
+## 1.1.7(2021-05-12)
+- 新增 组件示例地址
+## 1.1.6(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-card/components/uni-card/uni-card.vue b/uni_modules/uni-card/components/uni-card/uni-card.vue
new file mode 100644
index 0000000..38cf594
--- /dev/null
+++ b/uni_modules/uni-card/components/uni-card/uni-card.vue
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-card/package.json b/uni_modules/uni-card/package.json
new file mode 100644
index 0000000..f16224d
--- /dev/null
+++ b/uni_modules/uni-card/package.json
@@ -0,0 +1,90 @@
+{
+ "id": "uni-card",
+ "displayName": "uni-card 卡片",
+ "version": "1.3.1",
+ "description": "Card 组件,提供常见的卡片样式。",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "card",
+ "",
+ "卡片"
+],
+ "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-icons",
+ "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"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-card/readme.md b/uni_modules/uni-card/readme.md
new file mode 100644
index 0000000..7434e71
--- /dev/null
+++ b/uni_modules/uni-card/readme.md
@@ -0,0 +1,12 @@
+
+
+## Card 卡片
+> **组件名:uni-card**
+> 代码块: `uCard`
+
+卡片视图组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-card)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
+
+
diff --git a/uni_modules/uni-collapse/changelog.md b/uni_modules/uni-collapse/changelog.md
new file mode 100644
index 0000000..455308a
--- /dev/null
+++ b/uni_modules/uni-collapse/changelog.md
@@ -0,0 +1,38 @@
+## 1.4.4(2024-03-20)
+- 修复 titleBorder类型修正
+## 1.4.3(2022-01-25)
+- 修复 初始化的时候 ,open 属性失效的bug
+## 1.4.2(2022-01-21)
+- 修复 微信小程序resize后组件收起的bug
+## 1.4.1(2021-11-22)
+- 修复 vue3中个别scss变量无法找到的问题
+## 1.4.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-collapse](https://uniapp.dcloud.io/component/uniui/uni-collapse)
+## 1.3.3(2021-08-17)
+- 优化 show-arrow 属性默认为true
+## 1.3.2(2021-08-17)
+- 新增 show-arrow 属性,控制是否显示右侧箭头
+## 1.3.1(2021-07-30)
+- 优化 vue3下小程序事件警告的问题
+## 1.3.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.2.2(2021-07-21)
+- 修复 由1.2.0版本引起的 change 事件返回 undefined 的Bug
+## 1.2.1(2021-07-21)
+- 优化 组件示例
+## 1.2.0(2021-07-21)
+- 新增 组件折叠动画
+- 新增 value\v-model 属性 ,动态修改面板折叠状态
+- 新增 title 插槽 ,可定义面板标题
+- 新增 border 属性 ,显示隐藏面板内容分隔线
+- 新增 title-border 属性 ,显示隐藏面板标题分隔线
+- 修复 resize 方法失效的Bug
+- 修复 change 事件返回参数不正确的Bug
+- 优化 H5、App 平台自动更具内容更新高度,无需调用 reszie() 方法
+## 1.1.7(2021-05-12)
+- 新增 组件示例地址
+## 1.1.6(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.1.5(2021-02-05)
+- 调整为uni_modules目录规范
\ No newline at end of file
diff --git a/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue b/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
new file mode 100644
index 0000000..2f0862e
--- /dev/null
+++ b/uni_modules/uni-collapse/components/uni-collapse-item/uni-collapse-item.vue
@@ -0,0 +1,402 @@
+
+
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue b/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
new file mode 100644
index 0000000..384c39a
--- /dev/null
+++ b/uni_modules/uni-collapse/components/uni-collapse/uni-collapse.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-collapse/package.json b/uni_modules/uni-collapse/package.json
new file mode 100644
index 0000000..65c5c2e
--- /dev/null
+++ b/uni_modules/uni-collapse/package.json
@@ -0,0 +1,86 @@
+{
+ "id": "uni-collapse",
+ "displayName": "uni-collapse 折叠面板",
+ "version": "1.4.4",
+ "description": "Collapse 组件,可以折叠 / 展开的内容区域。",
+ "keywords": [
+ "uni-ui",
+ "折叠",
+ "折叠面板",
+ "手风琴"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "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"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-collapse/readme.md b/uni_modules/uni-collapse/readme.md
new file mode 100644
index 0000000..bc758eb
--- /dev/null
+++ b/uni_modules/uni-collapse/readme.md
@@ -0,0 +1,12 @@
+
+
+## Collapse 折叠面板
+> **组件名:uni-collapse**
+> 代码块: `uCollapse`
+> 关联组件:`uni-collapse-item`、`uni-icons`。
+
+
+折叠面板用来折叠/显示过长的内容或者是列表。通常是在多内容分类项使用,折叠不重要的内容,显示重要内容。点击可以展开折叠部分。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-collapse)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-combox/changelog.md b/uni_modules/uni-combox/changelog.md
new file mode 100644
index 0000000..23c2748
--- /dev/null
+++ b/uni_modules/uni-combox/changelog.md
@@ -0,0 +1,15 @@
+## 1.0.1(2021-11-23)
+- 优化 label、label-width 属性
+## 1.0.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-combox](https://uniapp.dcloud.io/component/uniui/uni-combox)
+## 0.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.0.6(2021-05-12)
+- 新增 组件示例地址
+## 0.0.5(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 0.0.4(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 0.0.3(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-combox/components/uni-combox/uni-combox.vue b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
new file mode 100644
index 0000000..d4cb79d
--- /dev/null
+++ b/uni_modules/uni-combox/components/uni-combox/uni-combox.vue
@@ -0,0 +1,275 @@
+
+
+
+ {{label}}
+
+
+
+
+
+
+
+
+
+
+ {{emptyTips}}
+
+
+ {{item}}
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-combox/package.json b/uni_modules/uni-combox/package.json
new file mode 100644
index 0000000..4a05c3f
--- /dev/null
+++ b/uni_modules/uni-combox/package.json
@@ -0,0 +1,90 @@
+{
+ "id": "uni-combox",
+ "displayName": "uni-combox 组合框",
+ "version": "1.0.1",
+ "description": "可以选择也可以输入的表单项 ",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "combox",
+ "组合框",
+ "select"
+],
+ "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": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-combox/readme.md b/uni_modules/uni-combox/readme.md
new file mode 100644
index 0000000..ffa2cc8
--- /dev/null
+++ b/uni_modules/uni-combox/readme.md
@@ -0,0 +1,11 @@
+
+
+## Combox 组合框
+> **组件名:uni-combox**
+> 代码块: `uCombox`
+
+
+组合框组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-combox)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-countdown/changelog.md b/uni_modules/uni-countdown/changelog.md
new file mode 100644
index 0000000..16fc324
--- /dev/null
+++ b/uni_modules/uni-countdown/changelog.md
@@ -0,0 +1,26 @@
+## 1.2.3(2024-02-20)
+- 新增 支持控制小时,分钟的显隐:showHour showMinute
+## 1.2.2(2022-01-19)
+- 修复 在微信小程序中样式不生效的bug
+## 1.2.1(2022-01-18)
+- 新增 update 方法 ,在动态更新时间后,刷新组件
+## 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-countdown](https://uniapp.dcloud.io/component/uniui/uni-countdown)
+## 1.1.3(2021-10-18)
+- 重构
+- 新增 font-size 支持自定义字体大小
+## 1.1.2(2021-08-24)
+- 新增 支持国际化
+## 1.1.1(2021-07-30)
+- 优化 vue3下小程序事件警告的问题
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.5(2021-06-18)
+- 修复 uni-countdown 重复赋值跳两秒的 bug
+## 1.0.4(2021-05-12)
+- 新增 组件示例地址
+## 1.0.3(2021-05-08)
+- 修复 uni-countdown 不能控制倒计时的 bug
+## 1.0.2(2021-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json b/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json
new file mode 100644
index 0000000..06309cb
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/en.json
@@ -0,0 +1,6 @@
+{
+ "uni-countdown.day": "day",
+ "uni-countdown.h": "h",
+ "uni-countdown.m": "m",
+ "uni-countdown.s": "s"
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js b/uni_modules/uni-countdown/components/uni-countdown/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/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
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json
new file mode 100644
index 0000000..358cdd1
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hans.json
@@ -0,0 +1,6 @@
+{
+ "uni-countdown.day": "天",
+ "uni-countdown.h": "时",
+ "uni-countdown.m": "分",
+ "uni-countdown.s": "秒"
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json
new file mode 100644
index 0000000..e5a63de
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/i18n/zh-Hant.json
@@ -0,0 +1,6 @@
+{
+ "uni-countdown.day": "天",
+ "uni-countdown.h": "時",
+ "uni-countdown.m": "分",
+ "uni-countdown.s": "秒"
+}
diff --git a/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
new file mode 100644
index 0000000..1e28dda
--- /dev/null
+++ b/uni_modules/uni-countdown/components/uni-countdown/uni-countdown.vue
@@ -0,0 +1,281 @@
+
+
+ {{ d }}
+ {{dayText}}
+ {{ h }}
+ {{ showColon ? ':' : hourText }}
+ {{ i }}
+ {{ showColon ? ':' : minuteText }}
+ {{ s }}
+ {{secondText}}
+
+
+
+
diff --git a/uni_modules/uni-countdown/package.json b/uni_modules/uni-countdown/package.json
new file mode 100644
index 0000000..6622074
--- /dev/null
+++ b/uni_modules/uni-countdown/package.json
@@ -0,0 +1,83 @@
+{
+ "id": "uni-countdown",
+ "displayName": "uni-countdown 倒计时",
+ "version": "1.2.3",
+ "description": "CountDown 倒计时组件",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "countdown",
+ "倒计时"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "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"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-countdown/readme.md b/uni_modules/uni-countdown/readme.md
new file mode 100644
index 0000000..4bcb1aa
--- /dev/null
+++ b/uni_modules/uni-countdown/readme.md
@@ -0,0 +1,10 @@
+
+
+## CountDown 倒计时
+> **组件名:uni-countdown**
+> 代码块: `uCountDown`
+
+倒计时组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-countdown)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-data-checkbox/changelog.md b/uni_modules/uni-data-checkbox/changelog.md
new file mode 100644
index 0000000..b475fcb
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/changelog.md
@@ -0,0 +1,49 @@
+## 1.0.5(2024-03-20)
+- 修复 单选模式下选中样式不生效的bug
+## 1.0.4(2024-01-27)
+- 修复 修复错别字chagne为change
+## 1.0.3(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.0.2(2022-06-30)
+- 优化 在 uni-forms 中的依赖注入方式
+## 1.0.1(2022-02-07)
+- 修复 multiple 为 true 时,v-model 的值为 null 报错的 bug
+## 1.0.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-data-checkbox](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
+## 0.2.5(2021-08-23)
+- 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
+## 0.2.4(2021-08-17)
+- 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
+## 0.2.3(2021-08-11)
+- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+## 0.2.2(2021-07-30)
+- 优化 在uni-forms组件,与label不对齐的问题
+## 0.2.1(2021-07-27)
+- 修复 单选默认值为0不能选中的Bug
+## 0.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.1.11(2021-07-06)
+- 优化 删除无用日志
+## 0.1.10(2021-07-05)
+- 修复 由 0.1.9 引起的非 nvue 端图标不显示的问题
+## 0.1.9(2021-07-05)
+- 修复 nvue 黑框样式问题
+## 0.1.8(2021-06-28)
+- 修复 selectedTextColor 属性不生效的Bug
+## 0.1.7(2021-06-02)
+- 新增 map 属性,可以方便映射text/value属性
+## 0.1.6(2021-05-26)
+- 修复 不关联服务空间的情况下组件报错的Bug
+## 0.1.5(2021-05-12)
+- 新增 组件示例地址
+## 0.1.4(2021-04-09)
+- 修复 nvue 下无法选中的问题
+## 0.1.3(2021-03-22)
+- 新增 disabled属性
+## 0.1.2(2021-02-24)
+- 优化 默认颜色显示
+## 0.1.1(2021-02-24)
+- 新增 支持nvue
+## 0.1.0(2021-02-18)
+- “暂无数据”显示居中
diff --git a/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
new file mode 100644
index 0000000..81d3f07
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/components/uni-data-checkbox/uni-data-checkbox.vue
@@ -0,0 +1,849 @@
+
+
+
+
+
+ {{mixinDatacomErrorMessage}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-checkbox/package.json b/uni_modules/uni-data-checkbox/package.json
new file mode 100644
index 0000000..fc15e8b
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/package.json
@@ -0,0 +1,84 @@
+{
+ "id": "uni-data-checkbox",
+ "displayName": "uni-data-checkbox 数据选择器",
+ "version": "1.0.5",
+ "description": "通过数据驱动的单选框和复选框",
+ "keywords": [
+ "uni-ui",
+ "checkbox",
+ "单选",
+ "多选",
+ "单选多选"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": "^3.1.1"
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": ["uni-load-more","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"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-data-checkbox/readme.md b/uni_modules/uni-data-checkbox/readme.md
new file mode 100644
index 0000000..6eb253d
--- /dev/null
+++ b/uni_modules/uni-data-checkbox/readme.md
@@ -0,0 +1,18 @@
+
+
+## DataCheckbox 数据驱动的单选复选框
+> **组件名:uni-data-checkbox**
+> 代码块: `uDataCheckbox`
+
+
+本组件是基于uni-app基础组件checkbox的封装。本组件要解决问题包括:
+
+1. 数据绑定型组件:给本组件绑定一个data,会自动渲染一组候选内容。再以往,开发者需要编写不少代码实现类似功能
+2. 自动的表单校验:组件绑定了data,且符合[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)组件的表单校验规范,搭配使用会自动实现表单校验
+3. 本组件合并了单选多选
+4. 本组件有若干风格选择,如普通的单选多选框、并列button风格、tag风格。开发者可以快速选择需要的风格。但作为一个封装组件,样式代码虽然不用自己写了,却会牺牲一定的样式自定义性
+
+在uniCloud开发中,`DB Schema`中配置了enum枚举等类型后,在web控制台的[自动生成表单](https://uniapp.dcloud.io/uniCloud/schema?id=autocode)功能中,会自动生成``uni-data-checkbox``组件并绑定好data
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-checkbox)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-data-picker/changelog.md b/uni_modules/uni-data-picker/changelog.md
new file mode 100644
index 0000000..8aaad24
--- /dev/null
+++ b/uni_modules/uni-data-picker/changelog.md
@@ -0,0 +1,77 @@
+## 2.0.0(2023-12-14)
+- 新增 支持 uni-app-x
+## 1.1.2(2023-04-11)
+- 修复 更改 modelValue 报错的 bug
+- 修复 v-for 未使用 key 值控制台 warning
+## 1.1.1(2023-02-21)
+- 修复代码合并时引发 value 属性为空时不渲染数据的问题
+## 1.1.0(2023-02-15)
+- 修复 localdata 不支持动态更新的bug
+## 1.0.9(2023-02-15)
+- 修复 localdata 不支持动态更新的bug
+## 1.0.8(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 1.0.7(2022-07-06)
+- 优化 pc端图标位置不正确的问题
+## 1.0.6(2022-07-05)
+- 优化 显示样式
+## 1.0.5(2022-07-04)
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+## 1.0.4(2022-04-19)
+- 修复 字节小程序 本地数据无法选择下一级的Bug
+## 1.0.3(2022-02-25)
+- 修复 nvue 不支持的 v-show 的 bug
+## 1.0.2(2022-02-25)
+- 修复 条件编译 nvue 不支持的 css 样式
+## 1.0.1(2021-11-23)
+- 修复 由上个版本引发的map、v-model等属性不生效的bug
+## 1.0.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-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+## 0.4.9(2021-10-28)
+- 修复 VUE2 v-model 概率无效的 bug
+## 0.4.8(2021-10-27)
+- 修复 v-model 概率无效的 bug
+## 0.4.7(2021-10-25)
+- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
+- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
+## 0.4.6(2021-10-19)
+- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
+## 0.4.5(2021-09-26)
+- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
+- 修复 readonly 为 true 时报错的 bug
+## 0.4.4(2021-09-26)
+- 修复 上一版本造成的 map 属性失效的 bug
+- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
+## 0.4.3(2021-09-24)
+- 修复 某些情况下级联未触发的 bug
+## 0.4.2(2021-09-23)
+- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
+- 新增 选项内容过长自动添加省略号
+## 0.4.1(2021-09-15)
+- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
+## 0.4.0(2021-07-13)
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.3.5(2021-06-04)
+- 修复 无法加载云端数据的问题
+## 0.3.4(2021-05-28)
+- 修复 v-model 无效问题
+- 修复 loaddata 为空数据组时加载时间过长问题
+- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
+## 0.3.3(2021-05-12)
+- 新增 组件示例地址
+## 0.3.2(2021-04-22)
+- 修复 非树形数据有 where 属性查询报错的问题
+## 0.3.1(2021-04-15)
+- 修复 本地数据概率无法回显时问题
+## 0.3.0(2021-04-07)
+- 新增 支持云端非树形表结构数据
+- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
+## 0.2.0(2021-03-15)
+- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
+## 0.1.9(2021-03-09)
+- 修复 微信小程序某些情况下无法选择的问题
+## 0.1.8(2021-02-05)
+- 优化 部分样式在 nvue 上的兼容表现
+## 0.1.7(2021-02-05)
+- 调整为 uni_modules 目录规范
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
new file mode 100644
index 0000000..6ef26a2
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+ name: 'Keypress',
+ props: {
+ disable: {
+ type: Boolean,
+ default: false
+ }
+ },
+ mounted () {
+ const keyNames = {
+ esc: ['Esc', 'Escape'],
+ tab: 'Tab',
+ enter: 'Enter',
+ space: [' ', 'Spacebar'],
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ delete: ['Backspace', 'Delete', 'Del']
+ }
+ const listener = ($event) => {
+ if (this.disable) {
+ return
+ }
+ const keyName = Object.keys(keyNames).find(key => {
+ const keyName = $event.key
+ const value = keyNames[key]
+ return value === keyName || (Array.isArray(value) && value.includes(keyName))
+ })
+ if (keyName) {
+ // 避免和其他按键事件冲突
+ setTimeout(() => {
+ this.$emit(keyName, {})
+ }, 0)
+ }
+ }
+ document.addEventListener('keyup', listener)
+ this.$once('hook:beforeDestroy', () => {
+ document.removeEventListener('keyup', listener)
+ })
+ },
+ render: () => {}
+}
+// #endif
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
new file mode 100644
index 0000000..82031e1
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
@@ -0,0 +1,380 @@
+
+
+
+
+
+ {{error!.errMsg}}
+
+
+
+ {{item[mappingTextName]}}
+ {{split}}
+
+
+
+ {{placeholder}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{popupTitle}}
+
+
+
+
+
+
+
+
+ {{error!.errMsg}}
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
new file mode 100644
index 0000000..179a4e0
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
@@ -0,0 +1,551 @@
+
+
+
+
+
+ {{errorMessage}}
+
+
+
+
+
+
+ {{item.text}}{{split}}
+
+
+
+ {{placeholder}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{popupTitle}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/loading.uts b/uni_modules/uni-data-picker/components/uni-data-pickerview/loading.uts
new file mode 100644
index 0000000..baa0dff
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/loading.uts
@@ -0,0 +1 @@
+export const imgbase : string = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZVHb98LM+F5bHL8khA1iSeiyQBCRM+YGqKUnnJTDLGI0BGZlKDIU2MMglUiDApEZvSsZnQtBRJtKwQNKQMFYeRDR10WOLd8ljYXdh+v8v5fR3Od+797t1dnOnO/Ofce77z+J//+b/P+ZqtXbs2sJ9MJhNUV1cHJ06cCJo3bx7EPc2aNcvpy7pWrVoF+/fvDyoqKoI2bdoE9fX1F7TjN8a+EXBn/fkfvw942Tf+wYMHg9mzZwfjxo0LDhw4EPa1x2MbFw/fOGfPng1qa2tzcCkILsLDydq2bRsunpOTMM7TD/W/tZDZhPdeKD+yGxHhdu3aBV27dg3OnDlzMVANMheLAO3btw8KCwuDmpoaX5OxbgUIMEq7K8IcPnw4KCsrC/r37x8cP378/4cAXAB3vqSkJMuiDhTkw+XcuXNhOWbMmKBly5YhUT8xArhyFvP0BfwRsAuwxJZJsm/nzp2DTp06he/OU+cZ64K6o0ePBkOHDg2GDx8e6gEbJ5Q/NHNuAJQ1hgBeHUDlR7nVTkY8rQAvAi4z34vR/mPs1FoRsaCgIJThI0eOBC1atEiFGGV+5MiRoS45efJkqFjJFXV1dQuA012m2WcwTw98fy6CqBdsaiIO4CScrGPHjvk4odhavPquRtFWXEC25VgkREKOCh/qDSq+vn37htzD/mZTOmOc5U7zKzBPEedygWshcDyWvs30igAbU+6oyMgJBCFhwQE0fccxN60Ay9iebbjoDh06hMowjQxT4fXq1SskArmHZpkArvixp/kWzHdMeArExSJEaiXIjjRjRJ4DaAGWpibLzXN3Fm1vA5teBgh3j1Rv3bp1YgKwPdmf2p9zcyNYYgPKMfY0T5f5nNYdw158nJ8QawW4CLKwiOBSEgO/hok2eBydR+3dYH+PLxA5J8Vv0KBBwenTp0P2JWAx6+yFEBfs8lMY+y0SWMBNI9E4ThKi58VKTg3FQZS1RQF1cz27eC0QHMu+3E0SkUowjhVt5VdaWhp07949ZHv2Qd1EjDXM2cla1M0nl3GxAs3J9yREzyTdFVKVFOaE9qRA8GM0WebRuo9JGZKA7Mv2SeS/Z8+eoQ9BArMfFrLGo6jvxbhHbJZnKX2Rzz1O7QhJJ9Cs2ZMaWIyq/zhdeqPNfIoHd58clIQD+JSXl4dKlyIAuBdVXZwFVWKspSSoxE++h8x4k3uCnEhE4I5KwRiFWGOU0QWKiCYLbdoRMRKAu2kQ9vkfLU6dOhX06NEjlH+yMRZSinnuyWnYosVcji8CEA/6Cg2JF+IIUBqnGKUTCNwtwBN4f89RiK1R96DEgO2o0NDmtEdvVFdVVYV+P3UAPUEs6GFwV3PHmXkD4vh74iDFJysVI/MlaQhwKeBNTLYX5VuA8T4/gZxA4MRGFxDB6R7OmYPfyykGRJbyie+XnGYnQIC/coH9+vULiYrxrkL9ZA9+0ykaHIfEpM7ge8TiJ2CsHYwyMfafAF1yCGBHYIbCVDjDjKt7BeB51D+LgQa6OkG7IDYEEtvQ7lnXLKLtLdLuJBpE4gPUXcW2+PkZwOex+4cGDhwYDBkyRL7/HFcEwUGPo/8uWRUpYnfxGHco8HkewLHLyYmAawAPuIFZxhOpDfJQ8gbUv41yORAptMWBNr6oqMhWird5+u+iHmBb2nhjDV7HWBNQTgK8y11l5NetWzc5ULscAtSj7nbNI0skhWeUZCc0W4nyH/jO4Vz0u1IeYhbk4AiwM6tjxIWByHsoZ9qcIBPJd/y+DwPfBESOmCa/QF3WiZHucLlEDpNxcNhmheEOPgdQNx6/VZFQzFZ5TN08AHXQt2Ii3EdyFuUsPtTcGPhW5iMiCNELvz+Gdn9huG4HUJaW/w3g0wxV0XaG7arG2WeKiUWYM4Y7GO5ezshTARbbWGw/DvXkpp/ivVvE0JVoMxN4rpGzJMhE5Pl+xlATsDIqikP9F9D2z3h9nOksEUFhK+qO4rcPkoalMQ/HqJLIyb3F3JdjrCcw1yZ8joyJLR5gCo54etlag7qIoeNh1N1BRYj3DTFJ0elotxPlVzkGuYAmL0VSJVGAJA41c4Z6A3BzTLfn0HYwYKEI6CUAMzZEWvLsIcQOo1AmmyyM72nHJCfYsogflGV6jEk9vyQZXSuq6w4c16NsGcGZbwOPr+H1RkOk2LEzjNepxQkihHSCQ4ynAYNRx2zMKV92CQMWqj8J0BRE8EShxRFN6YrfCRhC0x3r/Zm4IbQCcmJoV0kMamllccR6FjHqUC5F2R/wS2dcymOlfAKOS4KmzQb5cpNC2MC7JhVn5wjXoJ44rYhLh8n0eXOCorJxa7POjbSlCGVczr34/RsAmrcvo9s+wGp3tzVhntxiXiJ4nvEYb4FJkf0O8HocAePmLvCxnL0AORraVekJk6TYjDabRVXfRE2lCN1h6ZQRN1+InUbsCpKwoBZHh0dODN9JBCUffItXxEavTQkUtnfTVAplCWL3JISz29h4NjotnuSsQKJCk8dF+kJR6RARjrqFVmfPnj3ZbK8cIJ0msd6jgHPGtfVTQ8VLmlvh4mct9sobRmPic0DyDQQnx/NlfYUgyz59+oScsH379pAwXABD32nTpoUHIToESeI5mnbE/UqDdyLcafEBf2MCqgC7NwxIbMREJQ0g4D4sfJwnD+AmRrII05cfMWJE+L1169bQr+fip06dGp4oJ83lmYd5wj/EmMa4TaHivo4EeCguYZBnkB5g2aWA69OIEnUHOaGysjIYMGBAMGnSpODYsWPZwCpFmm4lNq+4gSLQA7jcX8DwtjEyRC8wjabnXEx9kfWnTJkSJkAo90xpJVV+FmcVNeYAF5zWngS4C4O91MBxmAv8blLEpbjI5sz9MTdAhcgkCT1RO8mZkAjfiYpTEvStAS53Uw1vAiUGgZ3GpuQEYvoiBqlIan7kSDHnTwJQFNiPu0+5VxCVYhcZIjNrdXUDdp+Eq5AZ3Gkg8QAyVZRZIk4Tl4QAbF9cXJxNYZMAtAokgs4BrNxEpCtteXg7DDTMDKYNSuQdKsnJBek7HxewvxaosWxLYXtw+cJp18217wql4aKCfBNoEu0O5VU+PhctJ0YeXD4C6JQpyrlpSLTojpGGGN5YwNziChdIZLk4lvLcFJ9jMX3QdiImY9bmGQU+TRUL5CHITTRlgF8D9ouD1MfmLoEPl5xokIumZ2cfgMpHt47IW9N64Hsh7wQYYjyIugWuF5fCqYncXRd5vPMWyizzvhi/32+nvG0dZc9vR6fZOu0md5e+uC408FvKSIOZwXlGvxPv95izA2Vtvg1xKFWARI+vMX66HUhpQQb643uW1bSjuTWyw2SBvDrBvjFic1eGGlz5esq3ko9uSIlBRqPuFcCv8F4WIcN12nVaBd0SaYwI6PDDImR11JkqgHcPmQssjxIn6bUshygDFJUTxPMpHk+jfjPgupgdnYV2R/g7xSjtpah8RJBewhwf0gGK6XI92u4wXFEU40afJ4DN4h5LcAd+40HI3JgJecuT0c062W0i2hQJUTcxan3/CMW1PF2K6bbA+Daz4xRs1D3Br1Cm0OihKCqizW78/nXAF/G5TXrEcVzaNMH6CyMswqsAHqDyDLEyou8lwOXnKF8DjI6KjV3KzMBiXkDH8ij/H214J5A596ekrZ3F0zXlWeL7+P5eUrNo3/QwC15uxthuzidy7DzKRwEDaAViiDgKbTbz7CJnzo0bN7pIfIiid8SuPwn25o3QCmpnyjlZkyxPP8EomCJzrGb7GJMx7tNsq4MT2xMUYaiErZOluTzKsnz3gwCeCZyVRZJfYplNEokEjwrPtxlxjeYAk+F1F74VAzPxQRNYYdtpOUvWs8J1sGhBJMNsb7igN8plJs1eSmLIhLKE4rvaCX27gOhLpLOsIzJ7qn/i+wZzcvSOZ23/du8TZjwV8zHIXoP4R3ifBxiFz1dcVpa3aPntPE+c6TmIWE9EtcMmAcPdWAhYhAXxcLOQi9L1WhD1Sc8p1d2oL7XGiRKp8F4A2i8K/nfI+y/gsTDJ/YC/8+AD5Uh04KHiGl+cIFPnBDDrPMjwRGkLXyxO4VGbfQWnDH2v0bVWE3C9QOXlepbgjEfIJQI6XDG3z5ahD9cw2pS78ipB85wyScNTvsVzlzzhL8/jRrnmVjfFJK/m3m4nj9vbgQTguT8XZTjsm672R5uJKEaQmBI/c58gyus8ZDagLpEVSJBIyHp4jn++xqPV71OgQgJYEWOtZ/haxRtKmWOBu8xdBLftWltsY84zE6WIEy/eIOWL+BaayMx+KHtL7EAkqdNDLiEXmEMUHniedtJqg9HmZtfvt26vNi0BdG3Ft3g8ZOf7PAu59TxtzivLNIekyi+wD1i8CuUiD9FXAa8C+/xS3JPmZnomyc7H+fb4/Se0bk41Fel621r4cgVxbq91V4jVqwB7HTe2M7jgB+QWHavZkDRPmZcASoZEmBx6i75bGjPcMdL4/VKGFAGWZkGzPG0XAbdL9A81G5LOmUnC9hHKJeO7dcUMjblSl12867ElFTtaGl20xvvLGPdVz/8TVuU7y0x1PG7vtNg24oz9Uo/Z412++VFWI7Fcog9tu9Lm6gvRmIPv9x1xmQAu6RDkXtbOtlGEmpgD5Nvnyc0dcv0EE6cfdi1HmhMf9wDF3k3gtRvEedhxjpgfqPb9PU9iEJHnyOUA7bQUXh6kq/D7l2iTjWv7XOD530BDr8jIrus+srXjt4MzumJMHuTsBa63YKE1+RR5lBjEikCCnWKWiHdzOgKO+nRIBAF88za/IFmJ3eMZov4CYxGBabcpGL8EYx+SeMXJeRwHNsV/h+vdxeuhEpN3ZyNY78Gm2fknJxVGhyjixPiQvVkNzT1elD9Py/aTAL64Hb9vcYmC9zfdXdT/C1LeGbg4rnBaAihDFJH12W5ulfNCNe/xTsP3bp8ikzJs5BF+5PNfAQYAPaseTdsEcaYAAAAASUVORK5CYII='
\ No newline at end of file
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
new file mode 100644
index 0000000..cfae22a
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
@@ -0,0 +1,622 @@
+export default {
+ props: {
+ localdata: {
+ type: [Array, Object],
+ default () {
+ return []
+ }
+ },
+ spaceInfo: {
+ type: Object,
+ default () {
+ return {}
+ }
+ },
+ collection: {
+ type: String,
+ default: ''
+ },
+ action: {
+ type: String,
+ default: ''
+ },
+ field: {
+ type: String,
+ default: ''
+ },
+ orderby: {
+ type: String,
+ default: ''
+ },
+ where: {
+ type: [String, Object],
+ default: ''
+ },
+ pageData: {
+ type: String,
+ default: 'add'
+ },
+ pageCurrent: {
+ type: Number,
+ default: 1
+ },
+ pageSize: {
+ type: Number,
+ default: 500
+ },
+ getcount: {
+ type: [Boolean, String],
+ default: false
+ },
+ getone: {
+ type: [Boolean, String],
+ default: false
+ },
+ gettree: {
+ type: [Boolean, String],
+ default: false
+ },
+ manual: {
+ type: Boolean,
+ default: false
+ },
+ value: {
+ type: [Array, String, Number],
+ default () {
+ return []
+ }
+ },
+ modelValue: {
+ type: [Array, String, Number],
+ default () {
+ return []
+ }
+ },
+ preload: {
+ type: Boolean,
+ default: false
+ },
+ stepSearh: {
+ type: Boolean,
+ default: true
+ },
+ selfField: {
+ type: String,
+ default: ''
+ },
+ parentField: {
+ type: String,
+ default: ''
+ },
+ multiple: {
+ type: Boolean,
+ default: false
+ },
+ map: {
+ type: Object,
+ default () {
+ return {
+ text: "text",
+ value: "value"
+ }
+ }
+ }
+ },
+ data() {
+ return {
+ loading: false,
+ errorMessage: '',
+ loadMore: {
+ contentdown: '',
+ contentrefresh: '',
+ contentnomore: ''
+ },
+ dataList: [],
+ selected: [],
+ selectedIndex: 0,
+ page: {
+ current: this.pageCurrent,
+ size: this.pageSize,
+ count: 0
+ }
+ }
+ },
+ computed: {
+ isLocalData() {
+ return !this.collection.length;
+ },
+ isCloudData() {
+ return this.collection.length > 0;
+ },
+ isCloudDataList() {
+ return (this.isCloudData && (!this.parentField && !this.selfField));
+ },
+ isCloudDataTree() {
+ return (this.isCloudData && this.parentField && this.selfField);
+ },
+ dataValue() {
+ let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
+ this.modelValue !== undefined);
+ return isModelValue ? this.modelValue : this.value;
+ },
+ hasValue() {
+ if (typeof this.dataValue === 'number') {
+ return true
+ }
+ return (this.dataValue != null) && (this.dataValue.length > 0)
+ }
+ },
+ created() {
+ this.$watch(() => {
+ var al = [];
+ ['pageCurrent',
+ 'pageSize',
+ 'spaceInfo',
+ 'value',
+ 'modelValue',
+ 'localdata',
+ 'collection',
+ 'action',
+ 'field',
+ 'orderby',
+ 'where',
+ 'getont',
+ 'getcount',
+ 'gettree'
+ ].forEach(key => {
+ al.push(this[key])
+ });
+ return al
+ }, (newValue, oldValue) => {
+ let needReset = false
+ for (let i = 2; i < newValue.length; i++) {
+ if (newValue[i] != oldValue[i]) {
+ needReset = true
+ break
+ }
+ }
+ if (newValue[0] != oldValue[0]) {
+ this.page.current = this.pageCurrent
+ }
+ this.page.size = this.pageSize
+
+ this.onPropsChange()
+ })
+ this._treeData = []
+ },
+ methods: {
+ onPropsChange() {
+ this._treeData = [];
+ },
+
+ // 填充 pickview 数据
+ async loadData() {
+ if (this.isLocalData) {
+ this.loadLocalData();
+ } else if (this.isCloudDataList) {
+ this.loadCloudDataList();
+ } else if (this.isCloudDataTree) {
+ this.loadCloudDataTree();
+ }
+ },
+
+ // 加载本地数据
+ async loadLocalData() {
+ this._treeData = [];
+ this._extractTree(this.localdata, this._treeData);
+
+ let inputValue = this.dataValue;
+ if (inputValue === undefined) {
+ return;
+ }
+
+ if (Array.isArray(inputValue)) {
+ inputValue = inputValue[inputValue.length - 1];
+ if (typeof inputValue === 'object' && inputValue[this.map.value]) {
+ inputValue = inputValue[this.map.value];
+ }
+ }
+
+ this.selected = this._findNodePath(inputValue, this.localdata);
+ },
+
+ // 加载 Cloud 数据 (单列)
+ async loadCloudDataList() {
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ try {
+ let response = await this.getCommand();
+ let responseData = response.result.data;
+
+ this._treeData = responseData;
+
+ this._updateBindData();
+ this._updateSelected();
+
+ this.onDataChange();
+ } catch (e) {
+ this.errorMessage = e;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // 加载 Cloud 数据 (树形)
+ async loadCloudDataTree() {
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ try {
+ let commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataTreeWhere()
+ };
+ if (this.gettree) {
+ commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
+ }
+
+ let response = await this.getCommand(commandOptions);
+ let responseData = response.result.data;
+
+ this._treeData = responseData;
+ this._updateBindData();
+ this._updateSelected();
+
+ this.onDataChange();
+ } catch (e) {
+ this.errorMessage = e;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // 加载 Cloud 数据 (节点)
+ async loadCloudDataNode(callback) {
+ if (this.loading) {
+ return;
+ }
+ this.loading = true;
+
+ try {
+ let commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataNodeWhere()
+ };
+
+ let response = await this.getCommand(commandOptions);
+ let responseData = response.result.data;
+
+ callback(responseData);
+ } catch (e) {
+ this.errorMessage = e;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // 回显 Cloud 数据
+ getCloudDataValue() {
+ if (this.isCloudDataList) {
+ return this.getCloudDataListValue();
+ }
+
+ if (this.isCloudDataTree) {
+ return this.getCloudDataTreeValue();
+ }
+ },
+
+ // 回显 Cloud 数据 (单列)
+ getCloudDataListValue() {
+ // 根据 field's as value标识匹配 where 条件
+ let where = [];
+ let whereField = this._getForeignKeyByField();
+ if (whereField) {
+ where.push(`${whereField} == '${this.dataValue}'`)
+ }
+
+ where = where.join(' || ');
+
+ if (this.where) {
+ where = `(${this.where}) && (${where})`
+ }
+
+ return this.getCommand({
+ field: this._cloudDataPostField(),
+ where
+ }).then((res) => {
+ this.selected = res.result.data;
+ return res.result.data;
+ });
+ },
+
+ // 回显 Cloud 数据 (树形)
+ getCloudDataTreeValue() {
+ return this.getCommand({
+ field: this._cloudDataPostField(),
+ getTreePath: {
+ startWith: `${this.selfField}=='${this.dataValue}'`
+ }
+ }).then((res) => {
+ let treePath = [];
+ this._extractTreePath(res.result.data, treePath);
+ this.selected = treePath;
+ return treePath;
+ });
+ },
+
+ getCommand(options = {}) {
+ /* eslint-disable no-undef */
+ let db = uniCloud.database(this.spaceInfo)
+
+ const action = options.action || this.action
+ if (action) {
+ db = db.action(action)
+ }
+
+ const collection = options.collection || this.collection
+ db = db.collection(collection)
+
+ const where = options.where || this.where
+ if (!(!where || !Object.keys(where).length)) {
+ db = db.where(where)
+ }
+
+ const field = options.field || this.field
+ if (field) {
+ db = db.field(field)
+ }
+
+ const orderby = options.orderby || this.orderby
+ if (orderby) {
+ db = db.orderBy(orderby)
+ }
+
+ const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
+ const size = options.pageSize !== undefined ? options.pageSize : this.page.size
+ const getCount = options.getcount !== undefined ? options.getcount : this.getcount
+ const getTree = options.gettree !== undefined ? options.gettree : this.gettree
+
+ const getOptions = {
+ getCount,
+ getTree
+ }
+ if (options.getTreePath) {
+ getOptions.getTreePath = options.getTreePath
+ }
+
+ db = db.skip(size * (current - 1)).limit(size).get(getOptions)
+
+ return db
+ },
+
+ _cloudDataPostField() {
+ let fields = [this.field];
+ if (this.parentField) {
+ fields.push(`${this.parentField} as parent_value`);
+ }
+ return fields.join(',');
+ },
+
+ _cloudDataTreeWhere() {
+ let result = []
+ let selected = this.selected
+ let parentField = this.parentField
+ if (parentField) {
+ result.push(`${parentField} == null || ${parentField} == ""`)
+ }
+ if (selected.length) {
+ for (var i = 0; i < selected.length - 1; i++) {
+ result.push(`${parentField} == '${selected[i].value}'`)
+ }
+ }
+
+ let where = []
+ if (this.where) {
+ where.push(`(${this.where})`)
+ }
+
+ if (result.length) {
+ where.push(`(${result.join(' || ')})`)
+ }
+
+ return where.join(' && ')
+ },
+
+ _cloudDataNodeWhere() {
+ let where = []
+ let selected = this.selected;
+ if (selected.length) {
+ where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
+ }
+
+ where = where.join(' || ');
+
+ if (this.where) {
+ return `(${this.where}) && (${where})`
+ }
+
+ return where
+ },
+
+ _getWhereByForeignKey() {
+ let result = []
+ let whereField = this._getForeignKeyByField();
+ if (whereField) {
+ result.push(`${whereField} == '${this.dataValue}'`)
+ }
+
+ if (this.where) {
+ return `(${this.where}) && (${result.join(' || ')})`
+ }
+
+ return result.join(' || ')
+ },
+
+ _getForeignKeyByField() {
+ let fields = this.field.split(',');
+ let whereField = null;
+ for (let i = 0; i < fields.length; i++) {
+ const items = fields[i].split('as');
+ if (items.length < 2) {
+ continue;
+ }
+ if (items[1].trim() === 'value') {
+ whereField = items[0].trim();
+ break;
+ }
+ }
+ return whereField;
+ },
+
+ _updateBindData(node) {
+ const {
+ dataList,
+ hasNodes
+ } = this._filterData(this._treeData, this.selected)
+
+ let isleaf = this._stepSearh === false && !hasNodes
+
+ if (node) {
+ node.isleaf = isleaf
+ }
+
+ this.dataList = dataList
+ this.selectedIndex = dataList.length - 1
+
+ if (!isleaf && this.selected.length < dataList.length) {
+ this.selected.push({
+ value: null,
+ text: "请选择"
+ })
+ }
+
+ return {
+ isleaf,
+ hasNodes
+ }
+ },
+
+ _updateSelected() {
+ let dl = this.dataList
+ let sl = this.selected
+ let textField = this.map.text
+ let valueField = this.map.value
+ for (let i = 0; i < sl.length; i++) {
+ let value = sl[i].value
+ let dl2 = dl[i]
+ for (let j = 0; j < dl2.length; j++) {
+ let item2 = dl2[j]
+ if (item2[valueField] === value) {
+ sl[i].text = item2[textField]
+ break
+ }
+ }
+ }
+ },
+
+ _filterData(data, paths) {
+ let dataList = []
+ let hasNodes = true
+
+ dataList.push(data.filter((item) => {
+ return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
+ }))
+ for (let i = 0; i < paths.length; i++) {
+ let value = paths[i].value
+ let nodes = data.filter((item) => {
+ return item.parent_value === value
+ })
+
+ if (nodes.length) {
+ dataList.push(nodes)
+ } else {
+ hasNodes = false
+ }
+ }
+
+ return {
+ dataList,
+ hasNodes
+ }
+ },
+
+ _extractTree(nodes, result, parent_value) {
+ let list = result || []
+ let valueField = this.map.value
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i]
+
+ let child = {}
+ for (let key in node) {
+ if (key !== 'children') {
+ child[key] = node[key]
+ }
+ }
+ if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
+ child.parent_value = parent_value
+ }
+ result.push(child)
+
+ let children = node.children
+ if (children) {
+ this._extractTree(children, result, node[valueField])
+ }
+ }
+ },
+
+ _extractTreePath(nodes, result) {
+ let list = result || []
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i]
+
+ let child = {}
+ for (let key in node) {
+ if (key !== 'children') {
+ child[key] = node[key]
+ }
+ }
+ result.push(child)
+
+ let children = node.children
+ if (children) {
+ this._extractTreePath(children, result)
+ }
+ }
+ },
+
+ _findNodePath(key, nodes, path = []) {
+ let textField = this.map.text
+ let valueField = this.map.value
+ for (let i = 0; i < nodes.length; i++) {
+ let node = nodes[i]
+ let children = node.children
+ let text = node[textField]
+ let value = node[valueField]
+
+ path.push({
+ value,
+ text
+ })
+
+ if (value === key) {
+ return path
+ }
+
+ if (children) {
+ const p = this._findNodePath(key, children, path)
+ if (p.length) {
+ return p
+ }
+ }
+
+ path.pop()
+ }
+ return []
+ }
+ }
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
new file mode 100644
index 0000000..372795d
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
@@ -0,0 +1,693 @@
+export type PaginationType = {
+ current : number,
+ size : number,
+ count : number
+}
+
+export type LoadMoreType = {
+ contentdown : string,
+ contentrefresh : string,
+ contentnomore : string
+}
+
+export type SelectedItemType = {
+ name : string,
+ value : string,
+}
+
+export type GetCommandOptions = {
+ collection ?: UTSJSONObject,
+ field ?: string,
+ orderby ?: string,
+ where ?: any,
+ pageData ?: string,
+ pageCurrent ?: number,
+ pageSize ?: number,
+ getCount ?: boolean,
+ getTree ?: any,
+ getTreePath ?: UTSJSONObject,
+ startwith ?: string,
+ limitlevel ?: number,
+ groupby ?: string,
+ groupField ?: string,
+ distinct ?: boolean,
+ pageIndistinct ?: boolean,
+ foreignKey ?: string,
+ loadtime ?: string,
+ manual ?: boolean
+}
+
+const DefaultSelectedNode = {
+ text: '请选择',
+ value: ''
+}
+
+export const dataPicker = defineMixin({
+ props: {
+ localdata: {
+ type: Array as PropType>,
+ default: [] as Array
+ },
+ collection: {
+ type: Object,
+ default: ''
+ },
+ field: {
+ type: String,
+ default: ''
+ },
+ orderby: {
+ type: String,
+ default: ''
+ },
+ where: {
+ type: Object,
+ default: ''
+ },
+ pageData: {
+ type: String,
+ default: 'add'
+ },
+ pageCurrent: {
+ type: Number,
+ default: 1
+ },
+ pageSize: {
+ type: Number,
+ default: 20
+ },
+ getcount: {
+ type: Boolean,
+ default: false
+ },
+ gettree: {
+ type: Object,
+ default: ''
+ },
+ gettreepath: {
+ type: Object,
+ default: ''
+ },
+ startwith: {
+ type: String,
+ default: ''
+ },
+ limitlevel: {
+ type: Number,
+ default: 10
+ },
+ groupby: {
+ type: String,
+ default: ''
+ },
+ groupField: {
+ type: String,
+ default: ''
+ },
+ distinct: {
+ type: Boolean,
+ default: false
+ },
+ pageIndistinct: {
+ type: Boolean,
+ default: false
+ },
+ foreignKey: {
+ type: String,
+ default: ''
+ },
+ loadtime: {
+ type: String,
+ default: 'auto'
+ },
+ manual: {
+ type: Boolean,
+ default: false
+ },
+ preload: {
+ type: Boolean,
+ default: false
+ },
+ stepSearh: {
+ type: Boolean,
+ default: true
+ },
+ selfField: {
+ type: String,
+ default: ''
+ },
+ parentField: {
+ type: String,
+ default: ''
+ },
+ multiple: {
+ type: Boolean,
+ default: false
+ },
+ value: {
+ type: Object,
+ default: ''
+ },
+ modelValue: {
+ type: Object,
+ default: ''
+ },
+ defaultProps: {
+ type: Object as PropType,
+ }
+ },
+ data() {
+ return {
+ loading: false,
+ error: null as UniCloudError | null,
+ treeData: [] as Array,
+ selectedIndex: 0,
+ selectedNodes: [] as Array,
+ selectedPages: [] as Array[],
+ selectedValue: '',
+ selectedPaths: [] as Array,
+ pagination: {
+ current: 1,
+ size: 20,
+ count: 0
+ } as PaginationType
+ }
+ },
+ computed: {
+ mappingTextName() : string {
+ // TODO
+ return (this.defaultProps != null) ? this.defaultProps!.getString('text', 'text') : 'text'
+ },
+ mappingValueName() : string {
+ // TODO
+ return (this.defaultProps != null) ? this.defaultProps!.getString('value', 'value') : 'value'
+ },
+ currentDataList() : Array {
+ if (this.selectedIndex > this.selectedPages.length - 1) {
+ return [] as Array
+ }
+ return this.selectedPages[this.selectedIndex]
+ },
+ isLocalData() : boolean {
+ return this.localdata.length > 0
+ },
+ isCloudData() : boolean {
+ return this._checkIsNotNull(this.collection)
+ },
+ isCloudDataList() : boolean {
+ return (this.isCloudData && (this.parentField.length == 0 && this.selfField.length == 0))
+ },
+ isCloudDataTree() : boolean {
+ return (this.isCloudData && this.parentField.length > 0 && this.selfField.length > 0)
+ },
+ dataValue() : any {
+ return this.hasModelValue ? this.modelValue : this.value
+ },
+ hasCloudTreeData() : boolean {
+ return this.treeData.length > 0
+ },
+ hasModelValue() : boolean {
+ if (typeof this.modelValue == 'string') {
+ const valueString = this.modelValue as string
+ return (valueString.length > 0)
+ } else if (Array.isArray(this.modelValue)) {
+ const valueArray = this.modelValue as Array
+ return (valueArray.length > 0)
+ }
+ return false
+ },
+ hasCloudDataValue() : boolean {
+ if (typeof this.dataValue == 'string') {
+ const valueString = this.dataValue as string
+ return (valueString.length > 0)
+ }
+ return false
+ }
+ },
+ created() {
+ this.pagination.current = this.pageCurrent
+ this.pagination.size = this.pageSize
+
+ this.$watch(
+ () : any => [
+ this.pageCurrent,
+ this.pageSize,
+ this.localdata,
+ this.value,
+ this.collection,
+ this.field,
+ this.getcount,
+ this.orderby,
+ this.where,
+ this.groupby,
+ this.groupField,
+ this.distinct
+ ],
+ (newValue : Array, oldValue : Array) => {
+ this.pagination.size = this.pageSize
+ if (newValue[0] !== oldValue[0]) {
+ this.pagination.current = this.pageCurrent
+ }
+
+ this.onPropsChange()
+ }
+ )
+ },
+ methods: {
+ onPropsChange() {
+ this.selectedIndex = 0
+ this.treeData.length = 0
+ this.selectedNodes.length = 0
+ this.selectedPages.length = 0
+ this.selectedPaths.length = 0
+
+ // 加载数据
+ this.$nextTick(() => {
+ this.loadData()
+ })
+ },
+
+ onTabSelect(index : number) {
+ this.selectedIndex = index
+ },
+
+ onNodeClick(nodeData : UTSJSONObject) {
+ if (nodeData.getBoolean('disable', false)) {
+ return
+ }
+
+ const isLeaf = this._checkIsLeafNode(nodeData)
+
+ this._trimSelectedNodes(nodeData)
+
+ this.$emit('nodeclick', nodeData)
+
+ if (this.isLocalData) {
+ if (isLeaf || !this._checkHasChildren(nodeData)) {
+ this.onFinish()
+ }
+ } else if (this.isCloudDataList) {
+ this.onFinish()
+ } else if (this.isCloudDataTree) {
+ if (isLeaf) {
+ this.onFinish()
+ } else if (!this._checkHasChildren(nodeData)) {
+ // 尝试请求一次,如果没有返回数据标记为叶子节点
+ this.loadCloudDataNode(nodeData)
+ }
+ }
+ },
+
+ getChangeNodes(): Array {
+ const nodes: Array = []
+ this.selectedNodes.forEach((node : UTSJSONObject) => {
+ const newNode: UTSJSONObject = {}
+ newNode[this.mappingTextName] = node.getString(this.mappingTextName)
+ newNode[this.mappingValueName] = node.getString(this.mappingValueName)
+ nodes.push(newNode)
+ })
+ return nodes
+ },
+
+ onFinish() { },
+
+ // 加载数据(自动判定环境)
+ loadData() {
+ if (this.isLocalData) {
+ this.loadLocalData()
+ } else if (this.isCloudDataList) {
+ this.loadCloudDataList()
+ } else if (this.isCloudDataTree) {
+ this.loadCloudDataTree()
+ }
+ },
+
+ // 加载本地数据
+ loadLocalData() {
+ this.treeData = this.localdata
+ if (Array.isArray(this.dataValue)) {
+ const value = this.dataValue as Array
+ this.selectedPaths = value.slice(0)
+ this._pushSelectedTreeNodes(value, this.localdata)
+ } else {
+ this._pushSelectedNodes(this.localdata)
+ }
+ },
+
+ // 加载 Cloud 数据 (单列)
+ loadCloudDataList() {
+ this._loadCloudData(null, (data : Array) => {
+ this.treeData = data
+ this._pushSelectedNodes(data)
+ })
+ },
+
+ // 加载 Cloud 数据 (树形)
+ loadCloudDataTree() {
+ let commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataTreeWhere(),
+ getTree: true
+ } as GetCommandOptions
+ if (this._checkIsNotNull(this.gettree)) {
+ commandOptions.startwith = `${this.selfField}=='${this.dataValue as string}'`
+ }
+ this._loadCloudData(commandOptions, (data : Array) => {
+ this.treeData = data
+ if (this.selectedPaths.length > 0) {
+ this._pushSelectedTreeNodes(this.selectedPaths, data)
+ } else {
+ this._pushSelectedNodes(data)
+ }
+ })
+ },
+
+ // 加载 Cloud 数据 (节点)
+ loadCloudDataNode(nodeData : UTSJSONObject) {
+ const commandOptions = {
+ field: this._cloudDataPostField(),
+ where: this._cloudDataNodeWhere()
+ } as GetCommandOptions
+ this._loadCloudData(commandOptions, (data : Array) => {
+ nodeData['children'] = data
+ if (data.length == 0) {
+ nodeData['isleaf'] = true
+ this.onFinish()
+ } else {
+ this._pushSelectedNodes(data)
+ }
+ })
+ },
+
+ // 回显 Cloud Tree Path
+ loadCloudDataPath() {
+ if (!this.hasCloudDataValue) {
+ return
+ }
+
+ const command : GetCommandOptions = {}
+
+ // 单列
+ if (this.isCloudDataList) {
+ // 根据 field's as value标识匹配 where 条件
+ let where : Array = [];
+ let whereField = this._getForeignKeyByField();
+ if (whereField.length > 0) {
+ where.push(`${whereField} == '${this.dataValue as string}'`)
+ }
+
+ let whereString = where.join(' || ')
+ if (this._checkIsNotNull(this.where)) {
+ whereString = `(${this.where}) && (${whereString})`
+ }
+
+ command.field = this._cloudDataPostField()
+ command.where = whereString
+ }
+
+ // 树形
+ if (this.isCloudDataTree) {
+ command.field = this._cloudDataPostField()
+ command.getTreePath = {
+ startWith: `${this.selfField}=='${this.dataValue as string}'`
+ }
+ }
+
+ this._loadCloudData(command, (data : Array) => {
+ this._extractTreePath(data, this.selectedPaths)
+ })
+ },
+
+ _loadCloudData(options ?: GetCommandOptions, callback ?: ((data : Array) => void)) {
+ if (this.loading) {
+ return
+ }
+ this.loading = true
+
+ this.error = null
+
+ this._getCommand(options).then((response : UniCloudDBGetResult) => {
+ callback?.(response.data)
+ }).catch((err : any | null) => {
+ this.error = err as UniCloudError
+ }).finally(() => {
+ this.loading = false
+ })
+ },
+
+ _cloudDataPostField() : string {
+ let fields = [this.field];
+ if (this.parentField.length > 0) {
+ fields.push(`${this.parentField} as parent_value`)
+ }
+ return fields.join(',')
+ },
+
+ _cloudDataTreeWhere() : string {
+ let result : Array = []
+ let selectedNodes = this.selectedNodes.length > 0 ? this.selectedNodes : this.selectedPaths
+ let parentField = this.parentField
+ if (parentField.length > 0) {
+ result.push(`${parentField} == null || ${parentField} == ""`)
+ }
+ if (selectedNodes.length > 0) {
+ for (var i = 0; i < selectedNodes.length - 1; i++) {
+ const parentFieldValue = selectedNodes[i].getString('value', '')
+ result.push(`${parentField} == '${parentFieldValue}'`)
+ }
+ }
+
+ let where : Array = []
+ if (this._checkIsNotNull(this.where)) {
+ where.push(`(${this.where as string})`)
+ }
+
+ if (result.length > 0) {
+ where.push(`(${result.join(' || ')})`)
+ }
+
+ return where.join(' && ')
+ },
+
+ _cloudDataNodeWhere() : string {
+ const where : Array = []
+ if (this.selectedNodes.length > 0) {
+ const value = this.selectedNodes[this.selectedNodes.length - 1].getString('value', '')
+ where.push(`${this.parentField} == '${value}'`)
+ }
+
+ let whereString = where.join(' || ')
+ if (this._checkIsNotNull(this.where)) {
+ return `(${this.where as string}) && (${whereString})`
+ }
+
+ return whereString
+ },
+
+ _getWhereByForeignKey() : string {
+ let result : Array = []
+ let whereField = this._getForeignKeyByField();
+ if (whereField.length > 0) {
+ result.push(`${whereField} == '${this.dataValue as string}'`)
+ }
+
+ if (this._checkIsNotNull(this.where)) {
+ return `(${this.where}) && (${result.join(' || ')})`
+ }
+
+ return result.join(' || ')
+ },
+
+ _getForeignKeyByField() : string {
+ const fields = this.field.split(',')
+ let whereField = ''
+ for (let i = 0; i < fields.length; i++) {
+ const items = fields[i].split('as')
+ if (items.length < 2) {
+ continue
+ }
+ if (items[1].trim() === 'value') {
+ whereField = items[0].trim()
+ break
+ }
+ }
+ return whereField
+ },
+
+ _getCommand(options ?: GetCommandOptions) : Promise {
+ let db = uniCloud.databaseForJQL()
+
+ let collection = Array.isArray(this.collection) ? db.collection(...(this.collection as Array)) : db.collection(this.collection)
+
+ let filter : UniCloudDBFilter | null = null
+ if (this.foreignKey.length > 0) {
+ filter = collection.foreignKey(this.foreignKey)
+ }
+
+ const where : any = options?.where ?? this.where
+ if (typeof where == 'string') {
+ const whereString = where as string
+ if (whereString.length > 0) {
+ filter = (filter != null) ? filter.where(where) : collection.where(where)
+ }
+ } else {
+ filter = (filter != null) ? filter.where(where) : collection.where(where)
+ }
+
+ let query : UniCloudDBQuery | null = null
+ if (this.field.length > 0) {
+ query = (filter != null) ? filter.field(this.field) : collection.field(this.field)
+ }
+ if (this.groupby.length > 0) {
+ if (query != null) {
+ query = query.groupBy(this.groupby)
+ } else if (filter != null) {
+ query = filter.groupBy(this.groupby)
+ }
+ }
+ if (this.groupField.length > 0) {
+ if (query != null) {
+ query = query.groupField(this.groupField)
+ } else if (filter != null) {
+ query = filter.groupField(this.groupField)
+ }
+ }
+ if (this.distinct == true) {
+ if (query != null) {
+ query = query.distinct(this.field)
+ } else if (filter != null) {
+ query = filter.distinct(this.field)
+ }
+ }
+ if (this.orderby.length > 0) {
+ if (query != null) {
+ query = query.orderBy(this.orderby)
+ } else if (filter != null) {
+ query = filter.orderBy(this.orderby)
+ }
+ }
+
+ const size = this.pagination.size
+ const current = this.pagination.current
+ if (query != null) {
+ query = query.skip(size * (current - 1)).limit(size)
+ } else if (filter != null) {
+ query = filter.skip(size * (current - 1)).limit(size)
+ } else {
+ query = collection.skip(size * (current - 1)).limit(size)
+ }
+
+ const getOptions = {}
+ const treeOptions = {
+ limitLevel: this.limitlevel,
+ startWith: this.startwith
+ }
+ if (this.getcount == true) {
+ getOptions['getCount'] = this.getcount
+ }
+
+ const getTree : any = options?.getTree ?? this.gettree
+ if (typeof getTree == 'string') {
+ const getTreeString = getTree as string
+ if (getTreeString.length > 0) {
+ getOptions['getTree'] = treeOptions
+ }
+ } else if (typeof getTree == 'object') {
+ getOptions['getTree'] = treeOptions
+ } else {
+ getOptions['getTree'] = getTree
+ }
+
+ const getTreePath = options?.getTreePath ?? this.gettreepath
+ if (typeof getTreePath == 'string') {
+ const getTreePathString = getTreePath as string
+ if (getTreePathString.length > 0) {
+ getOptions['getTreePath'] = getTreePath
+ }
+ } else {
+ getOptions['getTreePath'] = getTreePath
+ }
+
+ return query.get(getOptions)
+ },
+
+ _checkIsNotNull(value : any) : boolean {
+ if (typeof value == 'string') {
+ const valueString = value as string
+ return (valueString.length > 0)
+ } else if (value instanceof UTSJSONObject) {
+ return true
+ }
+ return false
+ },
+
+ _checkIsLeafNode(nodeData : UTSJSONObject) : boolean {
+ if (this.selectedIndex >= this.limitlevel) {
+ return true
+ }
+
+ if (nodeData.getBoolean('isleaf', false)) {
+ return true
+ }
+
+ return false
+ },
+
+ _checkHasChildren(nodeData : UTSJSONObject) : boolean {
+ const children = nodeData.getArray('children') ?? ([] as Array)
+ return children.length > 0
+ },
+
+ _pushSelectedNodes(nodes : Array) {
+ this.selectedNodes.push(DefaultSelectedNode)
+ this.selectedPages.push(nodes)
+ this.selectedIndex = this.selectedPages.length - 1
+ },
+
+ _trimSelectedNodes(nodeData : UTSJSONObject) {
+ this.selectedNodes.splice(this.selectedIndex)
+ this.selectedNodes.push(nodeData)
+
+ if (this.selectedPages.length > 0) {
+ this.selectedPages.splice(this.selectedIndex + 1)
+ }
+
+ const children = nodeData.getArray('children') ?? ([] as Array)
+ if (children.length > 0) {
+ this.selectedNodes.push(DefaultSelectedNode)
+ this.selectedPages.push(children)
+ }
+
+ this.selectedIndex = this.selectedPages.length - 1
+ },
+
+ _pushSelectedTreeNodes(paths : Array, nodes : Array) {
+ let children : Array = nodes
+ paths.forEach((node : UTSJSONObject) => {
+ const findNode = children.find((item : UTSJSONObject) : boolean => {
+ return (item.getString(this.mappingValueName) == node.getString(this.mappingValueName))
+ })
+ if (findNode != null) {
+ this.selectedPages.push(children)
+ this.selectedNodes.push(node)
+ children = findNode.getArray('children') ?? ([] as Array)
+ }
+ })
+ this.selectedIndex = this.selectedPages.length - 1
+ },
+
+ _extractTreePath(nodes : Array, result : Array) {
+ if (nodes.length == 0) {
+ return
+ }
+
+ const node = nodes[0]
+ result.push(node)
+
+ const children = node.getArray('children')
+ if (Array.isArray(children) && children!.length > 0) {
+ this._extractTreePath(children, result)
+ }
+ }
+ }
+})
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
new file mode 100644
index 0000000..39fe1c3
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
@@ -0,0 +1,76 @@
+.uni-data-pickerview {
+ position: relative;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.loading-cover {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(150, 150, 150, .1);
+}
+
+.error {
+ background-color: #fff;
+ padding: 15px;
+}
+
+.error-text {
+ color: #DD524D;
+}
+
+.selected-node-list {
+ flex-direction: row;
+ flex-wrap: nowrap;
+}
+
+.selected-node-item {
+ margin-left: 10px;
+ margin-right: 10px;
+ padding: 8px 10px 8px 10px;
+ border-bottom: 2px solid transparent;
+}
+
+.selected-node-item-active {
+ color: #007aff;
+ border-bottom-color: #007aff;
+}
+
+.list-view {
+ flex: 1;
+}
+
+.list-item {
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 12px 15px;
+ border-bottom: 1px solid #f0f0f0;
+}
+
+.item-text {
+ color: #333333;
+}
+
+.item-text-disabled {
+ opacity: .5;
+}
+
+.item-text-overflow {
+ overflow: hidden;
+}
+
+.check {
+ margin-right: 5px;
+ border: 2px solid #007aff;
+ border-left: 0;
+ border-top: 0;
+ height: 12px;
+ width: 6px;
+ transform-origin: center;
+ transform: rotate(45deg);
+}
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
new file mode 100644
index 0000000..f4780f3
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
@@ -0,0 +1,69 @@
+
+
+
+ {{error!.errMsg}}
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+ {{item[mappingTextName]}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
new file mode 100644
index 0000000..6ebced9
--- /dev/null
+++ b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
@@ -0,0 +1,323 @@
+
+
+
+
+
+ {{item.text || ''}}
+
+
+
+
+
+
+ {{item[map.text]}}
+
+
+
+
+
+
+
+
+ {{errorMessage}}
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-picker/package.json b/uni_modules/uni-data-picker/package.json
new file mode 100644
index 0000000..a508162
--- /dev/null
+++ b/uni_modules/uni-data-picker/package.json
@@ -0,0 +1,91 @@
+{
+ "id": "uni-data-picker",
+ "displayName": "uni-data-picker 数据驱动的picker选择器",
+ "version": "2.0.0",
+ "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "picker",
+ "级联",
+ "省市区",
+ ""
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uni-load-more",
+ "uni-icons",
+ "uni-scss"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "y",
+ "app-uvue": "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",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-data-picker/readme.md b/uni_modules/uni-data-picker/readme.md
new file mode 100644
index 0000000..19dd0e8
--- /dev/null
+++ b/uni_modules/uni-data-picker/readme.md
@@ -0,0 +1,22 @@
+## DataPicker 级联选择
+> **组件名:uni-data-picker**
+> 代码块: `uDataPicker`
+> 关联组件:`uni-data-pickerview`、`uni-load-more`。
+
+
+`` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
+
+支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
+
+候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。
+
+`` 组件尤其适用于地址选择、分类选择等选择类。
+
+`` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。
+
+`` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。
+
+在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-data-select/changelog.md b/uni_modules/uni-data-select/changelog.md
new file mode 100644
index 0000000..016e3d2
--- /dev/null
+++ b/uni_modules/uni-data-select/changelog.md
@@ -0,0 +1,39 @@
+## 1.0.8(2024-03-28)
+- 修复 在vue2下:style动态绑定导致编译失败的bug
+## 1.0.7(2024-01-20)
+- 修复 长文本回显超过容器的bug,超过容器部分显示省略号
+## 1.0.6(2023-04-12)
+- 修复 微信小程序点击时会改变背景颜色的 bug
+## 1.0.5(2023-02-03)
+- 修复 禁用时会显示清空按钮
+## 1.0.4(2023-02-02)
+- 优化 查询条件短期内多次变更只查询最后一次变更后的结果
+- 调整 内部缓存键名调整为 uni-data-select-lastSelectedValue
+## 1.0.3(2023-01-16)
+- 修复 不关联服务空间报错的问题
+## 1.0.2(2023-01-14)
+- 新增 属性 `format` 可用于格式化显示选项内容
+## 1.0.1(2022-12-06)
+- 修复 当where变化时,数据不会自动更新的问题
+## 0.1.9(2022-09-05)
+- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
+## 0.1.8(2022-08-29)
+- 修复 点击的位置不准确
+## 0.1.7(2022-08-12)
+- 新增 支持 disabled 属性
+## 0.1.6(2022-07-06)
+- 修复 pc端宽度异常的bug
+## 0.1.5
+- 修复 pc端宽度异常的bug
+## 0.1.4(2022-07-05)
+- 优化 显示样式
+## 0.1.3(2022-06-02)
+- 修复 localdata 赋值不生效的 bug
+- 新增 支持 uni.scss 修改颜色
+- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
+## 0.1.2(2022-05-08)
+- 修复 当 value 为 0 时选择不生效的 bug
+## 0.1.1(2022-05-07)
+- 新增 记住上次的选项(仅 collection 存在时有效)
+## 0.1.0(2022-04-22)
+- 初始化
diff --git a/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue b/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
new file mode 100644
index 0000000..edab65a
--- /dev/null
+++ b/uni_modules/uni-data-select/components/uni-data-select/uni-data-select.vue
@@ -0,0 +1,562 @@
+
+
+ {{label + ':'}}
+
+
+
+ {{textShow}}
+ {{typePlaceholder}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{emptyTips}}
+
+
+ {{formatItemName(item)}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-data-select/package.json b/uni_modules/uni-data-select/package.json
new file mode 100644
index 0000000..5864594
--- /dev/null
+++ b/uni_modules/uni-data-select/package.json
@@ -0,0 +1,86 @@
+{
+ "id": "uni-data-select",
+ "displayName": "uni-data-select 下拉框选择器",
+ "version": "1.0.8",
+ "description": "通过数据驱动的下拉框选择器",
+ "keywords": [
+ "uni-ui",
+ "select",
+ "uni-data-select",
+ "下拉框",
+ "下拉选"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": "^3.1.1"
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": ["uni-load-more"],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "client": {
+ "App": {
+ "app-vue": "u",
+ "app-nvue": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "u",
+ "百度": "u",
+ "字节跳动": "u",
+ "QQ": "u",
+ "京东": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-data-select/readme.md b/uni_modules/uni-data-select/readme.md
new file mode 100644
index 0000000..eb58de3
--- /dev/null
+++ b/uni_modules/uni-data-select/readme.md
@@ -0,0 +1,8 @@
+## DataSelect 下拉框选择器
+> **组件名:uni-data-select**
+> 代码块: `uDataSelect`
+
+当选项过多时,使用下拉菜单展示并选择内容
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-select)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
diff --git a/uni_modules/uni-dateformat/changelog.md b/uni_modules/uni-dateformat/changelog.md
new file mode 100644
index 0000000..d551d7b
--- /dev/null
+++ b/uni_modules/uni-dateformat/changelog.md
@@ -0,0 +1,10 @@
+## 1.0.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-dateformat](https://uniapp.dcloud.io/component/uniui/uni-dateformat)
+## 0.0.5(2021-07-08)
+- 调整 默认时间不再是当前时间,而是显示'-'字符
+## 0.0.4(2021-05-12)
+- 新增 组件示例地址
+## 0.0.3(2021-02-04)
+- 调整为uni_modules目录规范
+- 修复 iOS 平台日期格式化出错的问题
diff --git a/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js b/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js
new file mode 100644
index 0000000..e00d559
--- /dev/null
+++ b/uni_modules/uni-dateformat/components/uni-dateformat/date-format.js
@@ -0,0 +1,200 @@
+// yyyy-MM-dd hh:mm:ss.SSS 所有支持的类型
+function pad(str, length = 2) {
+ str += ''
+ while (str.length < length) {
+ str = '0' + str
+ }
+ return str.slice(-length)
+}
+
+const parser = {
+ yyyy: (dateObj) => {
+ return pad(dateObj.year, 4)
+ },
+ yy: (dateObj) => {
+ return pad(dateObj.year)
+ },
+ MM: (dateObj) => {
+ return pad(dateObj.month)
+ },
+ M: (dateObj) => {
+ return dateObj.month
+ },
+ dd: (dateObj) => {
+ return pad(dateObj.day)
+ },
+ d: (dateObj) => {
+ return dateObj.day
+ },
+ hh: (dateObj) => {
+ return pad(dateObj.hour)
+ },
+ h: (dateObj) => {
+ return dateObj.hour
+ },
+ mm: (dateObj) => {
+ return pad(dateObj.minute)
+ },
+ m: (dateObj) => {
+ return dateObj.minute
+ },
+ ss: (dateObj) => {
+ return pad(dateObj.second)
+ },
+ s: (dateObj) => {
+ return dateObj.second
+ },
+ SSS: (dateObj) => {
+ return pad(dateObj.millisecond, 3)
+ },
+ S: (dateObj) => {
+ return dateObj.millisecond
+ },
+}
+
+// 这都n年了iOS依然不认识2020-12-12,需要转换为2020/12/12
+function getDate(time) {
+ if (time instanceof Date) {
+ return time
+ }
+ switch (typeof time) {
+ case 'string':
+ {
+ // 2020-12-12T12:12:12.000Z、2020-12-12T12:12:12.000
+ if (time.indexOf('T') > -1) {
+ return new Date(time)
+ }
+ return new Date(time.replace(/-/g, '/'))
+ }
+ default:
+ return new Date(time)
+ }
+}
+
+export function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') {
+ if (!date && date !== 0) {
+ return ''
+ }
+ date = getDate(date)
+ const dateObj = {
+ year: date.getFullYear(),
+ month: date.getMonth() + 1,
+ day: date.getDate(),
+ hour: date.getHours(),
+ minute: date.getMinutes(),
+ second: date.getSeconds(),
+ millisecond: date.getMilliseconds()
+ }
+ const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/
+ let flag = true
+ let result = format
+ while (flag) {
+ flag = false
+ result = result.replace(tokenRegExp, function(matched) {
+ flag = true
+ return parser[matched](dateObj)
+ })
+ }
+ return result
+}
+
+export function friendlyDate(time, {
+ locale = 'zh',
+ threshold = [60000, 3600000],
+ format = 'yyyy/MM/dd hh:mm:ss'
+}) {
+ if (time === '-') {
+ return time
+ }
+ if (!time && time !== 0) {
+ return ''
+ }
+ const localeText = {
+ zh: {
+ year: '年',
+ month: '月',
+ day: '天',
+ hour: '小时',
+ minute: '分钟',
+ second: '秒',
+ ago: '前',
+ later: '后',
+ justNow: '刚刚',
+ soon: '马上',
+ template: '{num}{unit}{suffix}'
+ },
+ en: {
+ year: 'year',
+ month: 'month',
+ day: 'day',
+ hour: 'hour',
+ minute: 'minute',
+ second: 'second',
+ ago: 'ago',
+ later: 'later',
+ justNow: 'just now',
+ soon: 'soon',
+ template: '{num} {unit} {suffix}'
+ }
+ }
+ const text = localeText[locale] || localeText.zh
+ let date = getDate(time)
+ let ms = date.getTime() - Date.now()
+ let absMs = Math.abs(ms)
+ if (absMs < threshold[0]) {
+ return ms < 0 ? text.justNow : text.soon
+ }
+ if (absMs >= threshold[1]) {
+ return formatDate(date, format)
+ }
+ let num
+ let unit
+ let suffix = text.later
+ if (ms < 0) {
+ suffix = text.ago
+ ms = -ms
+ }
+ const seconds = Math.floor((ms) / 1000)
+ const minutes = Math.floor(seconds / 60)
+ const hours = Math.floor(minutes / 60)
+ const days = Math.floor(hours / 24)
+ const months = Math.floor(days / 30)
+ const years = Math.floor(months / 12)
+ switch (true) {
+ case years > 0:
+ num = years
+ unit = text.year
+ break
+ case months > 0:
+ num = months
+ unit = text.month
+ break
+ case days > 0:
+ num = days
+ unit = text.day
+ break
+ case hours > 0:
+ num = hours
+ unit = text.hour
+ break
+ case minutes > 0:
+ num = minutes
+ unit = text.minute
+ break
+ default:
+ num = seconds
+ unit = text.second
+ break
+ }
+
+ if (locale === 'en') {
+ if (num === 1) {
+ num = 'a'
+ } else {
+ unit += 's'
+ }
+ }
+
+ return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g,
+ suffix)
+}
diff --git a/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue b/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue
new file mode 100644
index 0000000..c5ed030
--- /dev/null
+++ b/uni_modules/uni-dateformat/components/uni-dateformat/uni-dateformat.vue
@@ -0,0 +1,88 @@
+
+ {{dateShow}}
+
+
+
+
+
diff --git a/uni_modules/uni-dateformat/package.json b/uni_modules/uni-dateformat/package.json
new file mode 100644
index 0000000..786a670
--- /dev/null
+++ b/uni_modules/uni-dateformat/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "uni-dateformat",
+ "displayName": "uni-dateformat 日期格式化",
+ "version": "1.0.0",
+ "description": "日期格式化组件,可以将日期格式化为1分钟前、刚刚等形式",
+ "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"
+ },
+ "快应用": {
+ "华为": "y",
+ "联盟": "y"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-dateformat/readme.md b/uni_modules/uni-dateformat/readme.md
new file mode 100644
index 0000000..37ddb6e
--- /dev/null
+++ b/uni_modules/uni-dateformat/readme.md
@@ -0,0 +1,11 @@
+
+
+### DateFormat 日期格式化
+> **组件名:uni-dateformat**
+> 代码块: `uDateformat`
+
+
+日期格式化组件。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-dateformat)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/changelog.md b/uni_modules/uni-datetime-picker/changelog.md
new file mode 100644
index 0000000..8798e93
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/changelog.md
@@ -0,0 +1,160 @@
+## 2.2.34(2024-04-24)
+- 新增 日期点击事件,在点击日期时会触发该事件。
+## 2.2.33(2024-04-15)
+- 修复 抖音小程序事件传递失效bug
+## 2.2.32(2024-02-20)
+- 修复 日历的close事件触发异常的bug [详情](https://github.com/dcloudio/uni-ui/issues/844)
+## 2.2.31(2024-02-20)
+- 修复 h5平台 右边日历的月份默认+1的bug [详情](https://github.com/dcloudio/uni-ui/issues/841)
+## 2.2.30(2024-01-31)
+- 修复 隐藏“秒”时,在IOS15及以下版本时出现 结束时间在开始时间之前 的bug [详情](https://github.com/dcloudio/uni-ui/issues/788)
+## 2.2.29(2024-01-20)
+- 新增 show事件,弹窗弹出时触发该事件 [详情](https://github.com/dcloudio/uni-app/issues/4694)
+## 2.2.28(2024-01-18)
+- 去除 noChange事件,当进行日期范围选择时,若只选了一天,则开始结束日期都为同一天 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+## 2.2.27(2024-01-10)
+- 优化 增加noChange事件,当进行日期范围选择时,若有空值,则触发该事件 [详情](https://github.com/dcloudio/uni-ui/issues/815)
+## 2.2.26(2024-01-08)
+- 修复 字节小程序时间选择范围器失效问题 [详情](https://github.com/dcloudio/uni-ui/issues/834)
+## 2.2.25(2023-10-18)
+- 修复 PC端初次修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+## 2.2.24(2023-06-02)
+- 修复 部分情况修改时间,开始、结束时间显示异常的Bug [详情](https://ask.dcloud.net.cn/question/171146)
+- 优化 当前月可以选择上月、下月的日期的Bug
+## 2.2.23(2023-05-02)
+- 修复 部分情况修改时间,开始时间未更新的Bug [详情](https://github.com/dcloudio/uni-ui/issues/737)
+- 修复 部分平台及设备第一次点击无法显示弹框的Bug
+- 修复 ios 日期格式未补零显示及使用异常的Bug [详情](https://ask.dcloud.net.cn/question/162979)
+## 2.2.22(2023-03-30)
+- 修复 日历 picker 修改年月后,自动选中当月1日的Bug [详情](https://ask.dcloud.net.cn/question/165937)
+- 修复 小程序端 低版本 ios NaN的Bug [详情](https://ask.dcloud.net.cn/question/162979)
+## 2.2.21(2023-02-20)
+- 修复 firefox 浏览器显示区域点击无法拉起日历弹框的Bug [详情](https://ask.dcloud.net.cn/question/163362)
+## 2.2.20(2023-02-17)
+- 优化 值为空依然选中当天问题
+- 优化 提供 default-value 属性支持配置选择器打开时默认显示的时间
+- 优化 非范围选择未选择日期时间,点击确认按钮选中当前日期时间
+- 优化 字节小程序日期时间范围选择,底部日期换行的Bug
+## 2.2.19(2023-02-09)
+- 修复 2.2.18 引起范围选择配置 end 选择无效的Bug [详情](https://github.com/dcloudio/uni-ui/issues/686)
+## 2.2.18(2023-02-08)
+- 修复 移动端范围选择change事件触发异常的Bug [详情](https://github.com/dcloudio/uni-ui/issues/684)
+- 优化 PC端输入日期格式错误时返回当前日期时间
+- 优化 PC端输入日期时间超出 start、end 限制的Bug
+- 优化 移动端日期时间范围用法时间展示不完整问题
+## 2.2.17(2023-02-04)
+- 修复 小程序端绑定 Date 类型报错的Bug [详情](https://github.com/dcloudio/uni-ui/issues/679)
+- 修复 vue3 time-picker 无法显示绑定时分秒的Bug
+## 2.2.16(2023-02-02)
+- 修复 字节小程序报错的Bug
+## 2.2.15(2023-02-02)
+- 修复 某些情况切换月份错误的Bug
+## 2.2.14(2023-01-30)
+- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/162033)
+## 2.2.13(2023-01-10)
+- 修复 多次加载组件造成内存占用的Bug
+## 2.2.12(2022-12-01)
+- 修复 vue3 下 i18n 国际化初始值不正确的Bug
+## 2.2.11(2022-09-19)
+- 修复 支付宝小程序样式错乱的Bug [详情](https://github.com/dcloudio/uni-app/issues/3861)
+## 2.2.10(2022-09-19)
+- 修复 反向选择日期范围,日期显示异常的Bug [详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false)
+## 2.2.9(2022-09-16)
+- 可以使用 uni-scss 控制主题色
+## 2.2.8(2022-09-08)
+- 修复 close事件无效的Bug
+## 2.2.7(2022-09-05)
+- 修复 移动端 maskClick 无效的Bug [详情](https://ask.dcloud.net.cn/question/140824)
+## 2.2.6(2022-06-30)
+- 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
+## 2.2.5(2022-06-24)
+- 修复 日历顶部年月及底部确认未国际化的Bug
+## 2.2.4(2022-03-31)
+- 修复 Vue3 下动态赋值,单选类型未响应的Bug
+## 2.2.3(2022-03-28)
+- 修复 Vue3 下动态赋值未响应的Bug
+## 2.2.2(2021-12-10)
+- 修复 clear-icon 属性在小程序平台不生效的Bug
+## 2.2.1(2021-12-10)
+- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的Bug
+## 2.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源 [详情](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移 [https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
+## 2.1.5(2021-11-09)
+- 新增 提供组件设计资源,组件样式调整
+## 2.1.4(2021-09-10)
+- 修复 hide-second 在移动端的Bug
+- 修复 单选赋默认值时,赋值日期未高亮的Bug
+- 修复 赋默认值时,移动端未正确显示时间的Bug
+## 2.1.3(2021-09-09)
+- 新增 hide-second 属性,支持只使用时分,隐藏秒
+## 2.1.2(2021-09-03)
+- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
+- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
+- 优化 调整字号大小,美化日历界面
+- 修复 因国际化导致的 placeholder 失效的Bug
+## 2.1.1(2021-08-24)
+- 新增 支持国际化
+- 优化 范围选择器在 pc 端过宽的问题
+## 2.1.0(2021-08-09)
+- 新增 适配 vue3
+## 2.0.19(2021-08-09)
+- 新增 支持作为 uni-forms 子组件相关功能
+- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的Bug
+## 2.0.18(2021-08-05)
+- 修复 type 属性动态赋值无效的Bug
+- 修复 ‘确认’按钮被 tabbar 遮盖 bug
+- 修复 组件未赋值时范围选左、右日历相同的Bug
+## 2.0.17(2021-08-04)
+- 修复 范围选未正确显示当前值的Bug
+- 修复 h5 平台(移动端)报错 'cale' of undefined 的Bug
+## 2.0.16(2021-07-21)
+- 新增 return-type 属性支持返回 date 日期对象
+## 2.0.15(2021-07-14)
+- 修复 单选日期类型,初始赋值后不在当前日历的Bug
+- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
+- 优化 移动端移除显示框的清空按钮,无实际用途
+## 2.0.14(2021-07-14)
+- 修复 组件赋值为空,界面未更新的Bug
+- 修复 start 和 end 不能动态赋值的Bug
+- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的Bug
+## 2.0.13(2021-07-08)
+- 修复 范围选择不能动态赋值的Bug
+## 2.0.12(2021-07-08)
+- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
+## 2.0.11(2021-07-08)
+- 优化 弹出层在超出视窗边缘定位不准确的问题
+## 2.0.10(2021-07-08)
+- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的Bug
+- 优化 弹出层在超出视窗边缘被遮盖的问题
+## 2.0.9(2021-07-07)
+- 新增 maskClick 事件
+- 修复 特殊情况日历 rpx 布局错误的Bug,rpx -> px
+- 修复 范围选择时清空返回值不合理的bug,['', ''] -> []
+## 2.0.8(2021-07-07)
+- 新增 日期时间显示框支持插槽
+## 2.0.7(2021-07-01)
+- 优化 添加 uni-icons 依赖
+## 2.0.6(2021-05-22)
+- 修复 图标在小程序上不显示的Bug
+- 优化 重命名引用组件,避免潜在组件命名冲突
+## 2.0.5(2021-05-20)
+- 优化 代码目录扁平化
+## 2.0.4(2021-05-12)
+- 新增 组件示例地址
+## 2.0.3(2021-05-10)
+- 修复 ios 下不识别 '-' 日期格式的Bug
+- 优化 pc 下弹出层添加边框和阴影
+## 2.0.2(2021-05-08)
+- 修复 在 admin 中获取弹出层定位错误的bug
+## 2.0.1(2021-05-08)
+- 修复 type 属性向下兼容,默认值从 date 变更为 datetime
+## 2.0.0(2021-04-30)
+- 支持日历形式的日期+时间的范围选择
+ > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)
+## 1.0.6(2021-03-18)
+- 新增 hide-second 属性,时间支持仅选择时、分
+- 修复 选择跟显示的日期不一样的Bug
+- 修复 chang事件触发2次的Bug
+- 修复 分、秒 end 范围错误的Bug
+- 优化 更好的 nvue 适配
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
new file mode 100644
index 0000000..dba9887
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
@@ -0,0 +1,177 @@
+
+
+
+
+ {{weeks.date}}
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
new file mode 100644
index 0000000..0f9e121
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
@@ -0,0 +1,947 @@
+
+
+
+
+
+
+
+
+
+
+ {{nowDate.month}}
+
+
+
+
+ {{SUNText}}
+
+
+ {{MONText}}
+
+
+ {{TUEText}}
+
+
+ {{WEDText}}
+
+
+ {{THUText}}
+
+
+ {{FRIText}}
+
+
+ {{SATText}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{tempSingleDate ? tempSingleDate : selectDateText}}
+
+
+
+
+
+
+ {{tempRange.before ? tempRange.before : startDateText}}
+
+
+
+
+
+
+
+
+ {{tempRange.after ? tempRange.after : endDateText}}
+
+
+
+
+
+
+ {{confirmText}}
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
new file mode 100644
index 0000000..024f22f
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
@@ -0,0 +1,22 @@
+{
+ "uni-datetime-picker.selectDate": "select date",
+ "uni-datetime-picker.selectTime": "select time",
+ "uni-datetime-picker.selectDateTime": "select date and time",
+ "uni-datetime-picker.startDate": "start date",
+ "uni-datetime-picker.endDate": "end date",
+ "uni-datetime-picker.startTime": "start time",
+ "uni-datetime-picker.endTime": "end time",
+ "uni-datetime-picker.ok": "ok",
+ "uni-datetime-picker.clear": "clear",
+ "uni-datetime-picker.cancel": "cancel",
+ "uni-datetime-picker.year": "-",
+ "uni-datetime-picker.month": "",
+ "uni-calender.MON": "MON",
+ "uni-calender.TUE": "TUE",
+ "uni-calender.WED": "WED",
+ "uni-calender.THU": "THU",
+ "uni-calender.FRI": "FRI",
+ "uni-calender.SAT": "SAT",
+ "uni-calender.SUN": "SUN",
+ "uni-calender.confirm": "confirm"
+}
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/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
+}
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
new file mode 100644
index 0000000..d2df5e7
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
@@ -0,0 +1,22 @@
+{
+ "uni-datetime-picker.selectDate": "选择日期",
+ "uni-datetime-picker.selectTime": "选择时间",
+ "uni-datetime-picker.selectDateTime": "选择日期时间",
+ "uni-datetime-picker.startDate": "开始日期",
+ "uni-datetime-picker.endDate": "结束日期",
+ "uni-datetime-picker.startTime": "开始时间",
+ "uni-datetime-picker.endTime": "结束时间",
+ "uni-datetime-picker.ok": "确定",
+ "uni-datetime-picker.clear": "清除",
+ "uni-datetime-picker.cancel": "取消",
+ "uni-datetime-picker.year": "年",
+ "uni-datetime-picker.month": "月",
+ "uni-calender.SUN": "日",
+ "uni-calender.MON": "一",
+ "uni-calender.TUE": "二",
+ "uni-calender.WED": "三",
+ "uni-calender.THU": "四",
+ "uni-calender.FRI": "五",
+ "uni-calender.SAT": "六",
+ "uni-calender.confirm": "确认"
+}
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
new file mode 100644
index 0000000..d23fa3c
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
@@ -0,0 +1,22 @@
+{
+ "uni-datetime-picker.selectDate": "選擇日期",
+ "uni-datetime-picker.selectTime": "選擇時間",
+ "uni-datetime-picker.selectDateTime": "選擇日期時間",
+ "uni-datetime-picker.startDate": "開始日期",
+ "uni-datetime-picker.endDate": "結束日期",
+ "uni-datetime-picker.startTime": "開始时间",
+ "uni-datetime-picker.endTime": "結束时间",
+ "uni-datetime-picker.ok": "確定",
+ "uni-datetime-picker.clear": "清除",
+ "uni-datetime-picker.cancel": "取消",
+ "uni-datetime-picker.year": "年",
+ "uni-datetime-picker.month": "月",
+ "uni-calender.SUN": "日",
+ "uni-calender.MON": "一",
+ "uni-calender.TUE": "二",
+ "uni-calender.WED": "三",
+ "uni-calender.THU": "四",
+ "uni-calender.FRI": "五",
+ "uni-calender.SAT": "六",
+ "uni-calender.confirm": "確認"
+}
\ No newline at end of file
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
new file mode 100644
index 0000000..1817692
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
@@ -0,0 +1,940 @@
+
+
+
+
+
+ {{time}}
+
+ {{selectTimeText}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
new file mode 100644
index 0000000..11fc45a
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
@@ -0,0 +1,1057 @@
+
+
+
+
+
+
+
+ {{ displayValue || singlePlaceholderText }}
+
+
+
+
+ {{ displayRangeValue.startDate || startPlaceholderText }}
+
+ {{rangeSeparator}}
+
+ {{ displayRangeValue.endDate || endPlaceholderText }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
new file mode 100644
index 0000000..01802fa
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
@@ -0,0 +1,421 @@
+class Calendar {
+ constructor({
+ selected,
+ startDate,
+ endDate,
+ range,
+ } = {}) {
+ // 当前日期
+ this.date = this.getDateObj(new Date()) // 当前初入日期
+ // 打点信息
+ this.selected = selected || [];
+ // 起始时间
+ this.startDate = startDate
+ // 终止时间
+ this.endDate = endDate
+ // 是否范围选择
+ this.range = range
+ // 多选状态
+ this.cleanMultipleStatus()
+ // 每周日期
+ this.weeks = {}
+ this.lastHover = false
+ }
+ /**
+ * 设置日期
+ * @param {Object} date
+ */
+ setDate(date) {
+ const selectDate = this.getDateObj(date)
+ this.getWeeks(selectDate.fullDate)
+ }
+
+ /**
+ * 清理多选状态
+ */
+ cleanMultipleStatus() {
+ this.multipleStatus = {
+ before: '',
+ after: '',
+ data: []
+ }
+ }
+
+ setStartDate(startDate) {
+ this.startDate = startDate
+ }
+
+ setEndDate(endDate) {
+ this.endDate = endDate
+ }
+
+ getPreMonthObj(date) {
+ date = fixIosDateFormat(date)
+ date = new Date(date)
+
+ const oldMonth = date.getMonth()
+ date.setMonth(oldMonth - 1)
+ const newMonth = date.getMonth()
+ if (oldMonth !== 0 && newMonth - oldMonth === 0) {
+ date.setMonth(newMonth - 1)
+ }
+ return this.getDateObj(date)
+ }
+ getNextMonthObj(date) {
+ date = fixIosDateFormat(date)
+ date = new Date(date)
+
+ const oldMonth = date.getMonth()
+ date.setMonth(oldMonth + 1)
+ const newMonth = date.getMonth()
+ if (newMonth - oldMonth > 1) {
+ date.setMonth(newMonth - 1)
+ }
+ return this.getDateObj(date)
+ }
+
+ /**
+ * 获取指定格式Date对象
+ */
+ getDateObj(date) {
+ date = fixIosDateFormat(date)
+ date = new Date(date)
+
+ return {
+ fullDate: getDate(date),
+ year: date.getFullYear(),
+ month: addZero(date.getMonth() + 1),
+ date: addZero(date.getDate()),
+ day: date.getDay()
+ }
+ }
+
+ /**
+ * 获取上一个月日期集合
+ */
+ getPreMonthDays(amount, dateObj) {
+ const result = []
+ for (let i = amount - 1; i >= 0; i--) {
+ const month = dateObj.month - 1
+ result.push({
+ date: new Date(dateObj.year, month, -i).getDate(),
+ month,
+ disable: true
+ })
+ }
+ return result
+ }
+ /**
+ * 获取本月日期集合
+ */
+ getCurrentMonthDays(amount, dateObj) {
+ const result = []
+ const fullDate = this.date.fullDate
+ for (let i = 1; i <= amount; i++) {
+ const currentDate = `${dateObj.year}-${dateObj.month}-${addZero(i)}`
+ const isToday = fullDate === currentDate
+ // 获取打点信息
+ const info = this.selected && this.selected.find((item) => {
+ if (this.dateEqual(currentDate, item.date)) {
+ return item
+ }
+ })
+
+ // 日期禁用
+ let disableBefore = true
+ let disableAfter = true
+ if (this.startDate) {
+ disableBefore = dateCompare(this.startDate, currentDate)
+ }
+
+ if (this.endDate) {
+ disableAfter = dateCompare(currentDate, this.endDate)
+ }
+
+ let multiples = this.multipleStatus.data
+ let multiplesStatus = -1
+ if (this.range && multiples) {
+ multiplesStatus = multiples.findIndex((item) => {
+ return this.dateEqual(item, currentDate)
+ })
+ }
+ const checked = multiplesStatus !== -1
+
+ result.push({
+ fullDate: currentDate,
+ year: dateObj.year,
+ date: i,
+ multiple: this.range ? checked : false,
+ beforeMultiple: this.isLogicBefore(currentDate, this.multipleStatus.before, this.multipleStatus.after),
+ afterMultiple: this.isLogicAfter(currentDate, this.multipleStatus.before, this.multipleStatus.after),
+ month: dateObj.month,
+ disable: (this.startDate && !dateCompare(this.startDate, currentDate)) || (this.endDate && !dateCompare(
+ currentDate, this.endDate)),
+ isToday,
+ userChecked: false,
+ extraInfo: info
+ })
+ }
+ return result
+ }
+ /**
+ * 获取下一个月日期集合
+ */
+ _getNextMonthDays(amount, dateObj) {
+ const result = []
+ const month = dateObj.month + 1
+ for (let i = 1; i <= amount; i++) {
+ result.push({
+ date: i,
+ month,
+ disable: true
+ })
+ }
+ return result
+ }
+
+ /**
+ * 获取当前日期详情
+ * @param {Object} date
+ */
+ getInfo(date) {
+ if (!date) {
+ date = new Date()
+ }
+
+ return this.calendar.find(item => item.fullDate === this.getDateObj(date).fullDate)
+ }
+
+ /**
+ * 比较时间是否相等
+ */
+ dateEqual(before, after) {
+ before = new Date(fixIosDateFormat(before))
+ after = new Date(fixIosDateFormat(after))
+ return before.valueOf() === after.valueOf()
+ }
+
+ /**
+ * 比较真实起始日期
+ */
+
+ isLogicBefore(currentDate, before, after) {
+ let logicBefore = before
+ if (before && after) {
+ logicBefore = dateCompare(before, after) ? before : after
+ }
+ return this.dateEqual(logicBefore, currentDate)
+ }
+
+ isLogicAfter(currentDate, before, after) {
+ let logicAfter = after
+ if (before && after) {
+ logicAfter = dateCompare(before, after) ? after : before
+ }
+ return this.dateEqual(logicAfter, currentDate)
+ }
+
+ /**
+ * 获取日期范围内所有日期
+ * @param {Object} begin
+ * @param {Object} end
+ */
+ geDateAll(begin, end) {
+ var arr = []
+ var ab = begin.split('-')
+ var ae = end.split('-')
+ var db = new Date()
+ db.setFullYear(ab[0], ab[1] - 1, ab[2])
+ var de = new Date()
+ de.setFullYear(ae[0], ae[1] - 1, ae[2])
+ var unixDb = db.getTime() - 24 * 60 * 60 * 1000
+ var unixDe = de.getTime() - 24 * 60 * 60 * 1000
+ for (var k = unixDb; k <= unixDe;) {
+ k = k + 24 * 60 * 60 * 1000
+ arr.push(this.getDateObj(new Date(parseInt(k))).fullDate)
+ }
+ return arr
+ }
+
+ /**
+ * 获取多选状态
+ */
+ setMultiple(fullDate) {
+ if (!this.range) return
+
+ let {
+ before,
+ after
+ } = this.multipleStatus
+ if (before && after) {
+ if (!this.lastHover) {
+ this.lastHover = true
+ return
+ }
+ this.multipleStatus.before = fullDate
+ this.multipleStatus.after = ''
+ this.multipleStatus.data = []
+ this.multipleStatus.fulldate = ''
+ this.lastHover = false
+ } else {
+ if (!before) {
+ this.multipleStatus.before = fullDate
+ this.multipleStatus.after = undefined;
+ this.lastHover = false
+ } else {
+ this.multipleStatus.after = fullDate
+ if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+ this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
+ .after);
+ } else {
+ this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
+ .before);
+ }
+ this.lastHover = true
+ }
+ }
+ this.getWeeks(fullDate)
+ }
+
+ /**
+ * 鼠标 hover 更新多选状态
+ */
+ setHoverMultiple(fullDate) {
+ //抖音小程序点击会触发hover事件,需要避免一下
+ // #ifndef MP-TOUTIAO
+ if (!this.range || this.lastHover) return
+ const {
+ before
+ } = this.multipleStatus
+
+ if (!before) {
+ this.multipleStatus.before = fullDate
+ } else {
+ this.multipleStatus.after = fullDate
+ if (dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+ this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
+ } else {
+ this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
+ }
+ }
+ this.getWeeks(fullDate)
+ // #endif
+
+ }
+
+ /**
+ * 更新默认值多选状态
+ */
+ setDefaultMultiple(before, after) {
+ this.multipleStatus.before = before
+ this.multipleStatus.after = after
+ if (before && after) {
+ if (dateCompare(before, after)) {
+ this.multipleStatus.data = this.geDateAll(before, after);
+ this.getWeeks(after)
+ } else {
+ this.multipleStatus.data = this.geDateAll(after, before);
+ this.getWeeks(before)
+ }
+ }
+ }
+
+ /**
+ * 获取每周数据
+ * @param {Object} dateData
+ */
+ getWeeks(dateData) {
+ const {
+ year,
+ month,
+ } = this.getDateObj(dateData)
+
+ const preMonthDayAmount = new Date(year, month - 1, 1).getDay()
+ const preMonthDays = this.getPreMonthDays(preMonthDayAmount, this.getDateObj(dateData))
+
+ const currentMonthDayAmount = new Date(year, month, 0).getDate()
+ const currentMonthDays = this.getCurrentMonthDays(currentMonthDayAmount, this.getDateObj(dateData))
+
+ const nextMonthDayAmount = 42 - preMonthDayAmount - currentMonthDayAmount
+ const nextMonthDays = this._getNextMonthDays(nextMonthDayAmount, this.getDateObj(dateData))
+
+ const calendarDays = [...preMonthDays, ...currentMonthDays, ...nextMonthDays]
+
+ const weeks = new Array(6)
+ for (let i = 0; i < calendarDays.length; i++) {
+ const index = Math.floor(i / 7)
+ if (!weeks[index]) {
+ weeks[index] = new Array(7)
+ }
+ weeks[index][i % 7] = calendarDays[i]
+ }
+
+ this.calendar = calendarDays
+ this.weeks = weeks
+ }
+}
+
+function getDateTime(date, hideSecond) {
+ return `${getDate(date)} ${getTime(date, hideSecond)}`
+}
+
+function getDate(date) {
+ date = fixIosDateFormat(date)
+ date = new Date(date)
+ const year = date.getFullYear()
+ const month = date.getMonth() + 1
+ const day = date.getDate()
+ return `${year}-${addZero(month)}-${addZero(day)}`
+}
+
+function getTime(date, hideSecond) {
+ date = fixIosDateFormat(date)
+ date = new Date(date)
+ const hour = date.getHours()
+ const minute = date.getMinutes()
+ const second = date.getSeconds()
+ return hideSecond ? `${addZero(hour)}:${addZero(minute)}` : `${addZero(hour)}:${addZero(minute)}:${addZero(second)}`
+}
+
+function addZero(num) {
+ if (num < 10) {
+ num = `0${num}`
+ }
+ return num
+}
+
+function getDefaultSecond(hideSecond) {
+ return hideSecond ? '00:00' : '00:00:00'
+}
+
+function dateCompare(startDate, endDate) {
+ startDate = new Date(fixIosDateFormat(startDate))
+ endDate = new Date(fixIosDateFormat(endDate))
+ return startDate <= endDate
+}
+
+function checkDate(date) {
+ const dateReg = /((19|20)\d{2})(-|\/)\d{1,2}(-|\/)\d{1,2}/g
+ return date.match(dateReg)
+}
+//ios低版本15及以下,无法匹配 没有 ’秒‘ 时的情况,所以需要在末尾 秒 加上 问号
+const dateTimeReg = /^\d{4}-(0?[1-9]|1[012])-(0?[1-9]|[12][0-9]|3[01])( [0-5]?[0-9]:[0-5]?[0-9](:[0-5]?[0-9])?)?$/;
+
+function fixIosDateFormat(value) {
+ if (typeof value === 'string' && dateTimeReg.test(value)) {
+ value = value.replace(/-/g, '/')
+ }
+ return value
+}
+
+export {
+ Calendar,
+ getDateTime,
+ getDate,
+ getTime,
+ addZero,
+ getDefaultSecond,
+ dateCompare,
+ checkDate,
+ fixIosDateFormat
+}
diff --git a/uni_modules/uni-datetime-picker/package.json b/uni_modules/uni-datetime-picker/package.json
new file mode 100644
index 0000000..4d1b05c
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "uni-datetime-picker",
+ "displayName": "uni-datetime-picker 日期选择器",
+ "version": "2.2.34",
+ "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
+ "keywords": [
+ "uni-datetime-picker",
+ "uni-ui",
+ "uniui",
+ "日期时间选择器",
+ "日期时间"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uni-scss",
+ "uni-icons"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-datetime-picker/readme.md b/uni_modules/uni-datetime-picker/readme.md
new file mode 100644
index 0000000..162fbef
--- /dev/null
+++ b/uni_modules/uni-datetime-picker/readme.md
@@ -0,0 +1,21 @@
+
+
+> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护`
+
+## DatetimePicker 时间选择器
+
+> **组件名:uni-datetime-picker**
+> 代码块: `uDatetimePicker`
+
+
+该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。
+
+若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。
+
+**_点击 picker 默认值规则:_**
+
+- 若设置初始值 value, 会显示在 picker 显示框中
+- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-drawer/changelog.md b/uni_modules/uni-drawer/changelog.md
new file mode 100644
index 0000000..6d2488c
--- /dev/null
+++ b/uni_modules/uni-drawer/changelog.md
@@ -0,0 +1,13 @@
+## 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-drawer](https://uniapp.dcloud.io/component/uniui/uni-drawer)
+## 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-02-04)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-drawer/components/uni-drawer/keypress.js b/uni_modules/uni-drawer/components/uni-drawer/keypress.js
new file mode 100644
index 0000000..62dda46
--- /dev/null
+++ b/uni_modules/uni-drawer/components/uni-drawer/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
diff --git a/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
new file mode 100644
index 0000000..2471521
--- /dev/null
+++ b/uni_modules/uni-drawer/components/uni-drawer/uni-drawer.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-drawer/package.json b/uni_modules/uni-drawer/package.json
new file mode 100644
index 0000000..dd056e4
--- /dev/null
+++ b/uni_modules/uni-drawer/package.json
@@ -0,0 +1,87 @@
+{
+ "id": "uni-drawer",
+ "displayName": "uni-drawer 抽屉",
+ "version": "1.2.1",
+ "description": "抽屉式导航,用于展示侧滑菜单,侧滑导航。",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "drawer",
+ "抽屉",
+ "侧滑导航"
+],
+ "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"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-drawer/readme.md b/uni_modules/uni-drawer/readme.md
new file mode 100644
index 0000000..dcf6e6b
--- /dev/null
+++ b/uni_modules/uni-drawer/readme.md
@@ -0,0 +1,10 @@
+
+
+## Drawer 抽屉
+> **组件名:uni-drawer**
+> 代码块: `uDrawer`
+
+抽屉侧滑菜单。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-drawer)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-easyinput/changelog.md b/uni_modules/uni-easyinput/changelog.md
new file mode 100644
index 0000000..6677b07
--- /dev/null
+++ b/uni_modules/uni-easyinput/changelog.md
@@ -0,0 +1,113 @@
+## 1.1.18(2024-04-11)
+- 修复 easyinput组件双向绑定问题
+## 1.1.17(2024-03-28)
+- 修复 在头条小程序下丢失事件绑定的问题
+## 1.1.16(2024-03-20)
+- 修复 在密码输入情况下 清除和小眼睛覆盖bug 在edge浏览器下显示双眼睛bug
+## 1.1.15(2024-02-21)
+- 新增 左侧插槽:left
+## 1.1.14(2024-02-19)
+- 修复 onBlur的emit传值错误
+## 1.1.12(2024-01-29)
+- 补充 adjust-position文档属性补充
+## 1.1.11(2024-01-29)
+- 补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面
+## 1.1.10(2024-01-22)
+- 去除 移除无用的log输出
+## 1.1.9(2023-04-11)
+- 修复 vue3 下 keyboardheightchange 事件报错的bug
+## 1.1.8(2023-03-29)
+- 优化 trim 属性默认值
+## 1.1.7(2023-03-29)
+- 新增 cursor-spacing 属性
+## 1.1.6(2023-01-28)
+- 新增 keyboardheightchange 事件,可监听键盘高度变化
+## 1.1.5(2022-11-29)
+- 优化 主题样式
+## 1.1.4(2022-10-27)
+- 修复 props 中背景颜色无默认值的bug
+## 1.1.0(2022-06-30)
+
+- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
+- 新增 clear 事件,点击右侧叉号图标触发
+- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
+- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
+
+## 1.0.5(2022-06-07)
+
+- 优化 clearable 显示策略
+
+## 1.0.4(2022-06-07)
+
+- 优化 clearable 显示策略
+
+## 1.0.3(2022-05-20)
+
+- 修复 关闭图标某些情况下无法取消的 bug
+
+## 1.0.2(2022-04-12)
+
+- 修复 默认值不生效的 bug
+
+## 1.0.1(2022-04-02)
+
+- 修复 value 不能为 0 的 bug
+
+## 1.0.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-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
+
+## 0.1.4(2021-08-20)
+
+- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
+
+## 0.1.3(2021-08-11)
+
+- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
+
+## 0.1.2(2021-07-30)
+
+- 优化 vue3 下事件警告的问题
+
+## 0.1.1
+
+- 优化 errorMessage 属性支持 Boolean 类型
+
+## 0.1.0(2021-07-13)
+
+- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+
+## 0.0.16(2021-06-29)
+
+- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug
+
+## 0.0.15(2021-06-21)
+
+- 修复 passwordIcon 属性拼写错误的 bug
+
+## 0.0.14(2021-06-18)
+
+- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标
+- 修复 confirmType 属性不生效的问题
+
+## 0.0.13(2021-06-04)
+
+- 修复 disabled 状态可清出内容的 bug
+
+## 0.0.12(2021-05-12)
+
+- 新增 组件示例地址
+
+## 0.0.11(2021-05-07)
+
+- 修复 input-border 属性不生效的问题
+
+## 0.0.10(2021-04-30)
+
+- 修复 ios 遮挡文字、显示一半的问题
+
+## 0.0.9(2021-02-05)
+
+- 调整为 uni_modules 目录规范
+- 优化 兼容 nvue 页面
diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/common.js b/uni_modules/uni-easyinput/components/uni-easyinput/common.js
new file mode 100644
index 0000000..fde8d3c
--- /dev/null
+++ b/uni_modules/uni-easyinput/components/uni-easyinput/common.js
@@ -0,0 +1,54 @@
+/**
+ * @desc 函数防抖
+ * @param func 目标函数
+ * @param wait 延迟执行毫秒数
+ * @param immediate true - 立即执行, false - 延迟执行
+ */
+export const debounce = function(func, wait = 1000, immediate = true) {
+ let timer;
+ return function() {
+ let context = this,
+ args = arguments;
+ if (timer) clearTimeout(timer);
+ if (immediate) {
+ let callNow = !timer;
+ timer = setTimeout(() => {
+ timer = null;
+ }, wait);
+ if (callNow) func.apply(context, args);
+ } else {
+ timer = setTimeout(() => {
+ func.apply(context, args);
+ }, wait)
+ }
+ }
+}
+/**
+ * @desc 函数节流
+ * @param func 函数
+ * @param wait 延迟执行毫秒数
+ * @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
+ */
+export const throttle = (func, wait = 1000, type = 1) => {
+ let previous = 0;
+ let timeout;
+ return function() {
+ let context = this;
+ let args = arguments;
+ if (type === 1) {
+ let now = Date.now();
+
+ if (now - previous > wait) {
+ func.apply(context, args);
+ previous = now;
+ }
+ } else if (type === 2) {
+ if (!timeout) {
+ timeout = setTimeout(() => {
+ timeout = null;
+ func.apply(context, args)
+ }, wait)
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
new file mode 100644
index 0000000..d41411b
--- /dev/null
+++ b/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
@@ -0,0 +1,693 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-easyinput/package.json b/uni_modules/uni-easyinput/package.json
new file mode 100644
index 0000000..62bbff5
--- /dev/null
+++ b/uni_modules/uni-easyinput/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "uni-easyinput",
+ "displayName": "uni-easyinput 增强输入框",
+ "version": "1.1.18",
+ "description": "Easyinput 组件是对原生input组件的增强",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "input",
+ "uni-easyinput",
+ "输入框"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": [
+ "uni-scss",
+ "uni-icons"
+ ],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "n"
+ },
+ "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"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-easyinput/readme.md b/uni_modules/uni-easyinput/readme.md
new file mode 100644
index 0000000..f1faf8f
--- /dev/null
+++ b/uni_modules/uni-easyinput/readme.md
@@ -0,0 +1,11 @@
+
+
+### Easyinput 增强输入框
+> **组件名:uni-easyinput**
+> 代码块: `uEasyinput`
+
+
+easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-fab/changelog.md b/uni_modules/uni-fab/changelog.md
new file mode 100644
index 0000000..9bd4729
--- /dev/null
+++ b/uni_modules/uni-fab/changelog.md
@@ -0,0 +1,23 @@
+## 1.2.5(2023-03-29)
+- 新增 pattern.icon 属性,可自定义图标
+## 1.2.4(2022-09-07)
+小程序端由于 style 使用了对象导致报错,[详情](https://ask.dcloud.net.cn/question/152790?item_id=211778&rf=false)
+## 1.2.3(2022-09-05)
+- 修复 nvue 环境下,具有 tabBar 时,fab 组件下部位置无法正常获取 --window-bottom 的bug,详见:[https://ask.dcloud.net.cn/question/110638?notification_id=826310](https://ask.dcloud.net.cn/question/110638?notification_id=826310)
+## 1.2.2(2021-12-29)
+- 更新 组件依赖
+## 1.2.1(2021-11-19)
+- 修复 阴影颜色不正确的bug
+## 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-fab](https://uniapp.dcloud.io/component/uniui/uni-fab)
+## 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.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-02-05)
+- 调整为uni_modules目录规范
+- 优化 按钮背景色调整
+- 优化 兼容pc端
diff --git a/uni_modules/uni-fab/components/uni-fab/uni-fab.vue b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
new file mode 100644
index 0000000..dfa65c1
--- /dev/null
+++ b/uni_modules/uni-fab/components/uni-fab/uni-fab.vue
@@ -0,0 +1,491 @@
+
+
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-fab/package.json b/uni_modules/uni-fab/package.json
new file mode 100644
index 0000000..18c0810
--- /dev/null
+++ b/uni_modules/uni-fab/package.json
@@ -0,0 +1,84 @@
+{
+ "id": "uni-fab",
+ "displayName": "uni-fab 悬浮按钮",
+ "version": "1.2.5",
+ "description": "悬浮按钮 fab button ,点击可展开一个图标按钮菜单。",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "按钮",
+ "悬浮按钮",
+ "fab"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "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"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-fab/readme.md b/uni_modules/uni-fab/readme.md
new file mode 100644
index 0000000..9a444e8
--- /dev/null
+++ b/uni_modules/uni-fab/readme.md
@@ -0,0 +1,9 @@
+## Fab 悬浮按钮
+> **组件名:uni-fab**
+> 代码块: `uFab`
+
+
+点击可展开一个图形按钮菜单
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-fab)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-fav/changelog.md b/uni_modules/uni-fav/changelog.md
new file mode 100644
index 0000000..d8a08d4
--- /dev/null
+++ b/uni_modules/uni-fav/changelog.md
@@ -0,0 +1,19 @@
+## 1.2.1(2022-05-30)
+- 新增 stat 属性 ,是否开启uni统计功能
+## 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-fav](https://uniapp.dcloud.io/component/uniui/uni-fav)
+## 1.1.1(2021-08-24)
+- 新增 支持国际化
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.6(2021-05-12)
+- 新增 组件示例地址
+## 1.0.5(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.4(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.0.3(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+## 1.0.2(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/en.json b/uni_modules/uni-fav/components/uni-fav/i18n/en.json
new file mode 100644
index 0000000..9a0759e
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/en.json
@@ -0,0 +1,4 @@
+{
+ "uni-fav.collect": "collect",
+ "uni-fav.collected": "collected"
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/index.js b/uni_modules/uni-fav/components/uni-fav/i18n/index.js
new file mode 100644
index 0000000..de7509c
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/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
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json
new file mode 100644
index 0000000..67c89bf
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hans.json
@@ -0,0 +1,4 @@
+{
+ "uni-fav.collect": "收藏",
+ "uni-fav.collected": "已收藏"
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json
new file mode 100644
index 0000000..67c89bf
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/i18n/zh-Hant.json
@@ -0,0 +1,4 @@
+{
+ "uni-fav.collect": "收藏",
+ "uni-fav.collected": "已收藏"
+}
diff --git a/uni_modules/uni-fav/components/uni-fav/uni-fav.vue b/uni_modules/uni-fav/components/uni-fav/uni-fav.vue
new file mode 100644
index 0000000..d2c58df
--- /dev/null
+++ b/uni_modules/uni-fav/components/uni-fav/uni-fav.vue
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+ {{ checked ? contentFav : contentDefault }}
+
+
+
+
+
+
diff --git a/uni_modules/uni-fav/package.json b/uni_modules/uni-fav/package.json
new file mode 100644
index 0000000..cc14697
--- /dev/null
+++ b/uni_modules/uni-fav/package.json
@@ -0,0 +1,89 @@
+{
+ "id": "uni-fav",
+ "displayName": "uni-fav 收藏按钮",
+ "version": "1.2.1",
+ "description": " Fav 收藏组件,可自定义颜色、大小。",
+ "keywords": [
+ "fav",
+ "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"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-fav/readme.md b/uni_modules/uni-fav/readme.md
new file mode 100644
index 0000000..4de125d
--- /dev/null
+++ b/uni_modules/uni-fav/readme.md
@@ -0,0 +1,10 @@
+
+
+## Fav 收藏按钮
+> **组件名:uni-fav**
+> 代码块: `uFav`
+
+用于收藏功能,可点击切换选中、不选中的状态。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-fav)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-file-picker/changelog.md b/uni_modules/uni-file-picker/changelog.md
new file mode 100644
index 0000000..81e43b9
--- /dev/null
+++ b/uni_modules/uni-file-picker/changelog.md
@@ -0,0 +1,75 @@
+## 1.0.8(2024-03-20)
+- 补充 删除文件时返回文件下标
+## 1.0.7(2024-02-21)
+- 新增 微信小程序选择视频时改用chooseMedia,并返回视频缩略图
+## 1.0.6(2024-01-06)
+- 新增 微信小程序不再调用chooseImage,而是调用chooseMedia
+## 1.0.5(2024-01-03)
+- 新增 上传文件至云存储携带本地文件名称
+## 1.0.4(2023-03-29)
+- 修复 手动上传删除一个文件后不能再上传的bug
+## 1.0.3(2022-12-19)
+- 新增 sourceType 属性, 可以自定义图片和视频选择的来源
+## 1.0.2(2022-07-04)
+- 修复 在uni-forms下样式不生效的bug
+## 1.0.1(2021-11-23)
+- 修复 参数为对象的情况下,url在某些情况显示错误的bug
+## 1.0.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-file-picker](https://uniapp.dcloud.io/component/uniui/uni-file-picker)
+## 0.2.16(2021-11-08)
+- 修复 传入空对象 ,显示错误的Bug
+## 0.2.15(2021-08-30)
+- 修复 return-type="object" 时且存在v-model时,无法删除文件的Bug
+## 0.2.14(2021-08-23)
+- 新增 参数中返回 fileID 字段
+## 0.2.13(2021-08-23)
+- 修复 腾讯云传入fileID 不能回显的bug
+- 修复 选择图片后,不能放大的问题
+## 0.2.12(2021-08-17)
+- 修复 由于 0.2.11 版本引起的不能回显图片的Bug
+## 0.2.11(2021-08-16)
+- 新增 clearFiles(index) 方法,可以手动删除指定文件
+- 修复 v-model 值设为 null 报错的Bug
+## 0.2.10(2021-08-13)
+- 修复 return-type="object" 时,无法删除文件的Bug
+## 0.2.9(2021-08-03)
+- 修复 auto-upload 属性失效的Bug
+## 0.2.8(2021-07-31)
+- 修复 fileExtname属性不指定值报错的Bug
+## 0.2.7(2021-07-31)
+- 修复 在某种场景下图片不回显的Bug
+## 0.2.6(2021-07-30)
+- 修复 return-type为object下,返回值不正确的Bug
+## 0.2.5(2021-07-30)
+- 修复(重要) H5 平台下如果和uni-forms组件一同使用导致页面卡死的问题
+## 0.2.3(2021-07-28)
+- 优化 调整示例代码
+## 0.2.2(2021-07-27)
+- 修复 vue3 下赋值错误的Bug
+- 优化 h5平台下上传文件导致页面卡死的问题
+## 0.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 0.1.1(2021-07-02)
+- 修复 sourceType 缺少默认值导致 ios 无法选择文件
+## 0.1.0(2021-06-30)
+- 优化 解耦与uniCloud的强绑定关系 ,如不绑定服务空间,默认autoUpload为false且不可更改
+## 0.0.11(2021-06-30)
+- 修复 由 0.0.10 版本引发的 returnType 属性失效的问题
+## 0.0.10(2021-06-29)
+- 优化 文件上传后进度条消失时机
+## 0.0.9(2021-06-29)
+- 修复 在uni-forms 中,删除文件 ,获取的值不对的Bug
+## 0.0.8(2021-06-15)
+- 修复 删除文件时无法触发 v-model 的Bug
+## 0.0.7(2021-05-12)
+- 新增 组件示例地址
+## 0.0.6(2021-04-09)
+- 修复 选择的文件非 file-extname 字段指定的扩展名报错的Bug
+## 0.0.5(2021-04-09)
+- 优化 更新组件示例
+## 0.0.4(2021-04-09)
+- 优化 file-extname 字段支持字符串写法,多个扩展名需要用逗号分隔
+## 0.0.3(2021-02-05)
+- 调整为uni_modules目录规范
+- 修复 微信小程序不指定 fileExtname 属性选择失败的Bug
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
new file mode 100644
index 0000000..9c6bcdf
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/choose-and-upload-file.js
@@ -0,0 +1,287 @@
+'use strict';
+
+const ERR_MSG_OK = 'chooseAndUploadFile:ok';
+const ERR_MSG_FAIL = 'chooseAndUploadFile:fail';
+
+function chooseImage(opts) {
+ const {
+ count,
+ sizeType = ['original', 'compressed'],
+ sourceType,
+ extension
+ } = opts
+ return new Promise((resolve, reject) => {
+ // 微信由于旧接口不再维护,针对微信小程序平台改用chooseMedia接口
+ // #ifdef MP-WEIXIN
+ uni.chooseMedia({
+ count,
+ sizeType,
+ sourceType,
+ mediaType: ['image'],
+ extension,
+ success(res) {
+ res.tempFiles.forEach(item => {
+ item.path = item.tempFilePath;
+ })
+ resolve(normalizeChooseAndUploadFileRes(res, 'image'));
+ },
+ fail(res) {
+ reject({
+ errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
+ });
+ },
+ })
+ // #endif
+ // #ifndef MP-WEIXIN
+ uni.chooseImage({
+ count,
+ sizeType,
+ sourceType,
+ extension,
+ success(res) {
+ resolve(normalizeChooseAndUploadFileRes(res, 'image'));
+ },
+ fail(res) {
+ reject({
+ errMsg: res.errMsg.replace('chooseImage:fail', ERR_MSG_FAIL),
+ });
+ },
+ });
+ // #endif
+
+ });
+}
+
+function chooseVideo(opts) {
+ const {
+ count,
+ camera,
+ compressed,
+ maxDuration,
+ sourceType,
+ extension
+ } = opts;
+ return new Promise((resolve, reject) => {
+ // 微信由于旧接口不再维护,针对微信小程序平台改用chooseMedia接口
+ // #ifdef MP-WEIXIN
+ uni.chooseMedia({
+ count,
+ compressed,
+ maxDuration,
+ sourceType,
+ extension,
+ mediaType: ['video'],
+ success(res) {
+ const {
+ tempFiles,
+ } = res;
+ resolve(normalizeChooseAndUploadFileRes({
+ errMsg: 'chooseVideo:ok',
+ tempFiles: tempFiles.map(item => {
+ return {
+ name: item.name || '',
+ path: item.tempFilePath,
+ thumbTempFilePath: item.thumbTempFilePath,
+ size:item.size,
+ type: (res.tempFile && res.tempFile.type) || '',
+ width:item.width,
+ height:item.height,
+ duration:item.duration,
+ fileType: 'video',
+ cloudPath: '',
+ }
+ }),
+ }, 'video'));
+ },
+ fail(res) {
+ reject({
+ errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
+ });
+ },
+ })
+ // #endif
+ // #ifndef MP-WEIXIN
+ uni.chooseVideo({
+ camera,
+ compressed,
+ maxDuration,
+ sourceType,
+ extension,
+ success(res) {
+ const {
+ tempFilePath,
+ duration,
+ size,
+ height,
+ width
+ } = res;
+ resolve(normalizeChooseAndUploadFileRes({
+ errMsg: 'chooseVideo:ok',
+ tempFilePaths: [tempFilePath],
+ tempFiles: [{
+ name: (res.tempFile && res.tempFile.name) || '',
+ path: tempFilePath,
+ size,
+ type: (res.tempFile && res.tempFile.type) || '',
+ width,
+ height,
+ duration,
+ fileType: 'video',
+ cloudPath: '',
+ }, ],
+ }, 'video'));
+ },
+ fail(res) {
+ reject({
+ errMsg: res.errMsg.replace('chooseVideo:fail', ERR_MSG_FAIL),
+ });
+ },
+ });
+ // #endif
+ });
+}
+
+function chooseAll(opts) {
+ const {
+ count,
+ extension
+ } = opts;
+ return new Promise((resolve, reject) => {
+ let chooseFile = uni.chooseFile;
+ if (typeof wx !== 'undefined' &&
+ typeof wx.chooseMessageFile === 'function') {
+ chooseFile = wx.chooseMessageFile;
+ }
+ if (typeof chooseFile !== 'function') {
+ return reject({
+ errMsg: ERR_MSG_FAIL + ' 请指定 type 类型,该平台仅支持选择 image 或 video。',
+ });
+ }
+ chooseFile({
+ type: 'all',
+ count,
+ extension,
+ success(res) {
+ resolve(normalizeChooseAndUploadFileRes(res));
+ },
+ fail(res) {
+ reject({
+ errMsg: res.errMsg.replace('chooseFile:fail', ERR_MSG_FAIL),
+ });
+ },
+ });
+ });
+}
+
+function normalizeChooseAndUploadFileRes(res, fileType) {
+ res.tempFiles.forEach((item, index) => {
+ if (!item.name) {
+ item.name = item.path.substring(item.path.lastIndexOf('/') + 1);
+ }
+ if (fileType) {
+ item.fileType = fileType;
+ }
+ item.cloudPath =
+ Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.'));
+ });
+ if (!res.tempFilePaths) {
+ res.tempFilePaths = res.tempFiles.map((file) => file.path);
+ }
+ return res;
+}
+
+function uploadCloudFiles(files, max = 5, onUploadProgress) {
+ files = JSON.parse(JSON.stringify(files))
+ const len = files.length
+ let count = 0
+ let self = this
+ return new Promise(resolve => {
+ while (count < max) {
+ next()
+ }
+
+ function next() {
+ let cur = count++
+ if (cur >= len) {
+ !files.find(item => !item.url && !item.errMsg) && resolve(files)
+ return
+ }
+ const fileItem = files[cur]
+ const index = self.files.findIndex(v => v.uuid === fileItem.uuid)
+ fileItem.url = ''
+ delete fileItem.errMsg
+
+ uniCloud
+ .uploadFile({
+ filePath: fileItem.path,
+ cloudPath: fileItem.cloudPath,
+ fileType: fileItem.fileType,
+ onUploadProgress: res => {
+ res.index = index
+ onUploadProgress && onUploadProgress(res)
+ }
+ })
+ .then(res => {
+ fileItem.url = res.fileID
+ fileItem.index = index
+ if (cur < len) {
+ next()
+ }
+ })
+ .catch(res => {
+ fileItem.errMsg = res.errMsg || res.message
+ fileItem.index = index
+ if (cur < len) {
+ next()
+ }
+ })
+ }
+ })
+}
+
+
+
+
+
+function uploadFiles(choosePromise, {
+ onChooseFile,
+ onUploadProgress
+}) {
+ return choosePromise
+ .then((res) => {
+ if (onChooseFile) {
+ const customChooseRes = onChooseFile(res);
+ if (typeof customChooseRes !== 'undefined') {
+ return Promise.resolve(customChooseRes).then((chooseRes) => typeof chooseRes === 'undefined' ?
+ res : chooseRes);
+ }
+ }
+ return res;
+ })
+ .then((res) => {
+ if (res === false) {
+ return {
+ errMsg: ERR_MSG_OK,
+ tempFilePaths: [],
+ tempFiles: [],
+ };
+ }
+ return res
+ })
+}
+
+function chooseAndUploadFile(opts = {
+ type: 'all'
+}) {
+ if (opts.type === 'image') {
+ return uploadFiles(chooseImage(opts), opts);
+ } else if (opts.type === 'video') {
+ return uploadFiles(chooseVideo(opts), opts);
+ }
+ return uploadFiles(chooseAll(opts), opts);
+}
+
+export {
+ chooseAndUploadFile,
+ uploadCloudFiles
+};
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
new file mode 100644
index 0000000..fb83f63
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/uni-file-picker.vue
@@ -0,0 +1,678 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue
new file mode 100644
index 0000000..625d92e
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-file.vue
@@ -0,0 +1,325 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+
+ 点击重试
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue
new file mode 100644
index 0000000..2a29bc2
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/upload-image.vue
@@ -0,0 +1,292 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 点击重试
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-file-picker/components/uni-file-picker/utils.js b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js
new file mode 100644
index 0000000..1bc9259
--- /dev/null
+++ b/uni_modules/uni-file-picker/components/uni-file-picker/utils.js
@@ -0,0 +1,110 @@
+/**
+ * 获取文件名和后缀
+ * @param {String} name
+ */
+export const get_file_ext = (name) => {
+ const last_len = name.lastIndexOf('.')
+ const len = name.length
+ return {
+ name: name.substring(0, last_len),
+ ext: name.substring(last_len + 1, len)
+ }
+}
+
+/**
+ * 获取扩展名
+ * @param {Array} fileExtname
+ */
+export const get_extname = (fileExtname) => {
+ if (!Array.isArray(fileExtname)) {
+ let extname = fileExtname.replace(/(\[|\])/g, '')
+ return extname.split(',')
+ } else {
+ return fileExtname
+ }
+ return []
+}
+
+/**
+ * 获取文件和检测是否可选
+ */
+export const get_files_and_is_max = (res, _extname) => {
+ let filePaths = []
+ let files = []
+ if(!_extname || _extname.length === 0){
+ return {
+ filePaths,
+ files
+ }
+ }
+ res.tempFiles.forEach(v => {
+ let fileFullName = get_file_ext(v.name)
+ const extname = fileFullName.ext.toLowerCase()
+ if (_extname.indexOf(extname) !== -1) {
+ files.push(v)
+ filePaths.push(v.path)
+ }
+ })
+ if (files.length !== res.tempFiles.length) {
+ uni.showToast({
+ title: `当前选择了${res.tempFiles.length}个文件 ,${res.tempFiles.length - files.length} 个文件格式不正确`,
+ icon: 'none',
+ duration: 5000
+ })
+ }
+
+ return {
+ filePaths,
+ files
+ }
+}
+
+
+/**
+ * 获取图片信息
+ * @param {Object} filepath
+ */
+export const get_file_info = (filepath) => {
+ return new Promise((resolve, reject) => {
+ uni.getImageInfo({
+ src: filepath,
+ success(res) {
+ resolve(res)
+ },
+ fail(err) {
+ reject(err)
+ }
+ })
+ })
+}
+/**
+ * 获取封装数据
+ */
+export const get_file_data = async (files, type = 'image') => {
+ // 最终需要上传数据库的数据
+ let fileFullName = get_file_ext(files.name)
+ const extname = fileFullName.ext.toLowerCase()
+ let filedata = {
+ name: files.name,
+ uuid: files.uuid,
+ extname: extname || '',
+ cloudPath: files.cloudPath,
+ fileType: files.fileType,
+ thumbTempFilePath: files.thumbTempFilePath,
+ url: files.path || files.path,
+ size: files.size, //单位是字节
+ image: {},
+ path: files.path,
+ video: {}
+ }
+ if (type === 'image') {
+ const imageinfo = await get_file_info(files.path)
+ delete filedata.video
+ filedata.image.width = imageinfo.width
+ filedata.image.height = imageinfo.height
+ filedata.image.location = imageinfo.path
+ } else {
+ delete filedata.image
+ }
+ return filedata
+}
diff --git a/uni_modules/uni-file-picker/package.json b/uni_modules/uni-file-picker/package.json
new file mode 100644
index 0000000..004d330
--- /dev/null
+++ b/uni_modules/uni-file-picker/package.json
@@ -0,0 +1,83 @@
+{
+ "id": "uni-file-picker",
+ "displayName": "uni-file-picker 文件选择上传",
+ "version": "1.0.8",
+ "description": "文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "图片上传",
+ "文件上传"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "uni_modules": {
+ "dependencies": ["uni-scss"],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "n"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-file-picker/readme.md b/uni_modules/uni-file-picker/readme.md
new file mode 100644
index 0000000..c8399a5
--- /dev/null
+++ b/uni_modules/uni-file-picker/readme.md
@@ -0,0 +1,11 @@
+
+## FilePicker 文件选择上传
+
+> **组件名:uni-file-picker**
+> 代码块: `uFilePicker`
+
+
+文件选择上传组件,可以选择图片、视频等任意文件并上传到当前绑定的服务空间
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-file-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-forms/changelog.md b/uni_modules/uni-forms/changelog.md
new file mode 100644
index 0000000..3d998bc
--- /dev/null
+++ b/uni_modules/uni-forms/changelog.md
@@ -0,0 +1,94 @@
+## 1.4.10(2023-11-03)
+- 优化 labelWidth 描述错误
+## 1.4.9(2023-02-10)
+- 修复 required 参数无法动态绑定
+## 1.4.8(2022-08-23)
+- 优化 根据 rules 自动添加 required 的问题
+## 1.4.7(2022-08-22)
+- 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540)
+## 1.4.6(2022-07-13)
+- 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug
+## 1.4.5(2022-07-05)
+- 新增 更多表单示例
+- 优化 子表单组件过期提示的问题
+- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
+## 1.4.4(2022-07-04)
+- 更新 删除组件日志
+## 1.4.3(2022-07-04)
+- 修复 由 1.4.0 引发的 label 插槽不生效的bug
+## 1.4.2(2022-07-04)
+- 修复 子组件找不到 setValue 报错的bug
+## 1.4.1(2022-07-04)
+- 修复 uni-data-picker 在 uni-forms-item 中报错的bug
+- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
+## 1.4.0(2022-06-30)
+- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题
+- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
+- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
+- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
+- 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
+- 新增 子表单的 setRules 方法,配合自定义校验函数使用
+- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
+- 优化 动态表单校验方式,废弃拼接name的方式
+## 1.3.3(2022-06-22)
+- 修复 表单校验顺序无序问题
+## 1.3.2(2021-12-09)
+-
+## 1.3.1(2021-11-19)
+- 修复 label 插槽不生效的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-forms](https://uniapp.dcloud.io/component/uniui/uni-forms)
+## 1.2.7(2021-08-13)
+- 修复 没有添加校验规则的字段依然报错的Bug
+## 1.2.6(2021-08-11)
+- 修复 重置表单错误信息无法清除的问题
+## 1.2.5(2021-08-11)
+- 优化 组件文档
+## 1.2.4(2021-08-11)
+- 修复 表单验证只生效一次的问题
+## 1.2.3(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.2.2(2021-07-26)
+- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
+- 修复 1.2.1 引起的示例在小程序平台报错的Bug
+## 1.2.1(2021-07-22)
+- 修复 动态校验表单,默认值为空的情况下校验失效的Bug
+- 修复 不指定name属性时,运行报错的Bug
+- 优化 label默认宽度从65调整至70,使required为true且四字时不换行
+- 优化 组件示例,新增动态校验示例代码
+- 优化 组件文档,使用方式更清晰
+## 1.2.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.2(2021-06-25)
+- 修复 pattern 属性在微信小程序平台无效的问题
+## 1.1.1(2021-06-22)
+- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
+## 1.1.0(2021-06-22)
+- 修复 只写setRules方法而导致校验不生效的Bug
+- 修复 由上个办法引发的错误提示文字错位的Bug
+## 1.0.48(2021-06-21)
+- 修复 不设置 label 属性 ,无法设置label插槽的问题
+## 1.0.47(2021-06-21)
+- 修复 不设置label属性,label-width属性不生效的bug
+- 修复 setRules 方法与rules属性冲突的问题
+## 1.0.46(2021-06-04)
+- 修复 动态删减数据导致报错的问题
+## 1.0.45(2021-06-04)
+- 新增 modelValue 属性 ,value 即将废弃
+## 1.0.44(2021-06-02)
+- 新增 uni-forms-item 可以设置单独的 rules
+- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
+- 优化 submit 事件重命名为 validate
+## 1.0.43(2021-05-12)
+- 新增 组件示例地址
+## 1.0.42(2021-04-30)
+- 修复 自定义检验器失效的问题
+## 1.0.41(2021-03-05)
+- 更新 校验器
+- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug
+## 1.0.40(2021-03-04)
+- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
+## 1.0.39(2021-02-05)
+- 调整为uni_modules目录规范
+- 修复 校验器传入 int 等类型 ,返回String类型的Bug
diff --git a/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
new file mode 100644
index 0000000..0aef9cc
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue
@@ -0,0 +1,627 @@
+
+
+
+
+ *
+ {{label}}
+
+
+
+
+
+
+ {{msg}}
+
+
+
+
+
+
+
+
+
+ {{msg}}
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-forms/components/uni-forms/uni-forms.vue b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
new file mode 100644
index 0000000..9bb9ae7
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms/uni-forms.vue
@@ -0,0 +1,397 @@
+
+
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-forms/components/uni-forms/utils.js b/uni_modules/uni-forms/components/uni-forms/utils.js
new file mode 100644
index 0000000..6da2421
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms/utils.js
@@ -0,0 +1,293 @@
+/**
+ * 简单处理对象拷贝
+ * @param {Obejct} 被拷贝对象
+ * @@return {Object} 拷贝对象
+ */
+export const deepCopy = (val) => {
+ return JSON.parse(JSON.stringify(val))
+}
+/**
+ * 过滤数字类型
+ * @param {String} format 数字类型
+ * @@return {Boolean} 返回是否为数字类型
+ */
+export const typeFilter = (format) => {
+ return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
+}
+
+/**
+ * 把 value 转换成指定的类型,用于处理初始值,原因是初始值需要入库不能为 undefined
+ * @param {String} key 字段名
+ * @param {any} value 字段值
+ * @param {Object} rules 表单校验规则
+ */
+export const getValue = (key, value, rules) => {
+ const isRuleNumType = rules.find(val => val.format && typeFilter(val.format));
+ const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
+ // 输入类型为 number
+ if (!!isRuleNumType) {
+ if (!value && value !== 0) {
+ value = null
+ } else {
+ value = isNumber(Number(value)) ? Number(value) : value
+ }
+ }
+
+ // 输入类型为 boolean
+ if (!!isRuleBoolType) {
+ value = isBoolean(value) ? value : false
+ }
+
+ return value;
+}
+
+/**
+ * 获取表单数据
+ * @param {String|Array} name 真实名称,需要使用 realName 获取
+ * @param {Object} data 原始数据
+ * @param {any} value 需要设置的值
+ */
+export const setDataValue = (field, formdata, value) => {
+ formdata[field] = value
+ return value || ''
+}
+
+/**
+ * 获取表单数据
+ * @param {String|Array} field 真实名称,需要使用 realName 获取
+ * @param {Object} data 原始数据
+ */
+export const getDataValue = (field, data) => {
+ return objGet(data, field)
+}
+
+/**
+ * 获取表单类型
+ * @param {String|Array} field 真实名称,需要使用 realName 获取
+ */
+export const getDataValueType = (field, data) => {
+ const value = getDataValue(field, data)
+ return {
+ type: type(value),
+ value
+ }
+}
+
+/**
+ * 获取表单可用的真实name
+ * @param {String|Array} name 表单name
+ * @@return {String} 表单可用的真实name
+ */
+export const realName = (name, data = {}) => {
+ const base_name = _basePath(name)
+ if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) {
+ const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_')
+ return realname
+ }
+ return base_name[0] || name
+}
+
+/**
+ * 判断是否表单可用的真实name
+ * @param {String|Array} name 表单name
+ * @@return {String} 表单可用的真实name
+ */
+export const isRealName = (name) => {
+ const reg = /^_formdata_#*/
+ return reg.test(name)
+}
+
+/**
+ * 获取表单数据的原始格式
+ * @@return {Object|Array} object 需要解析的数据
+ */
+export const rawData = (object = {}, name) => {
+ let newData = JSON.parse(JSON.stringify(object))
+ let formData = {}
+ for(let i in newData){
+ let path = name2arr(i)
+ objSet(formData,path,newData[i])
+ }
+ return formData
+}
+
+/**
+ * 真实name还原为 array
+ * @param {*} name
+ */
+export const name2arr = (name) => {
+ let field = name.replace('_formdata_#', '')
+ field = field.split('#').map(v => (isNumber(v) ? Number(v) : v))
+ return field
+}
+
+/**
+ * 对象中设置值
+ * @param {Object|Array} object 源数据
+ * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c']
+ * @param {String} value 需要设置的值
+ */
+export const objSet = (object, path, value) => {
+ if (typeof object !== 'object') return object;
+ _basePath(path).reduce((o, k, i, _) => {
+ if (i === _.length - 1) {
+ // 若遍历结束直接赋值
+ o[k] = value
+ return null
+ } else if (k in o) {
+ // 若存在对应路径,则返回找到的对象,进行下一次遍历
+ return o[k]
+ } else {
+ // 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
+ o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {}
+ return o[k]
+ }
+ }, object)
+ // 返回object
+ return object;
+}
+
+// 处理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
+function _basePath(path) {
+ // 若是数组,则直接返回
+ if (Array.isArray(path)) return path
+ // 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']'
+ return path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
+}
+
+/**
+ * 从对象中获取值
+ * @param {Object|Array} object 源数据
+ * @param {String| Array} path 'a.b.c' 或 ['a',0,'b','c']
+ * @param {String} defaultVal 如果无法从调用链中获取值的默认值
+ */
+export const objGet = (object, path, defaultVal = 'undefined') => {
+ // 先将path处理成统一格式
+ let newPath = _basePath(path)
+ // 递归处理,返回最后结果
+ let val = newPath.reduce((o, k) => {
+ return (o || {})[k]
+ }, object);
+ return !val || val !== undefined ? val : defaultVal
+}
+
+
+/**
+ * 是否为 number 类型
+ * @param {any} num 需要判断的值
+ * @return {Boolean} 是否为 number
+ */
+export const isNumber = (num) => {
+ return !isNaN(Number(num))
+}
+
+/**
+ * 是否为 boolean 类型
+ * @param {any} bool 需要判断的值
+ * @return {Boolean} 是否为 boolean
+ */
+export const isBoolean = (bool) => {
+ return (typeof bool === 'boolean')
+}
+/**
+ * 是否有必填字段
+ * @param {Object} rules 规则
+ * @return {Boolean} 是否有必填字段
+ */
+export const isRequiredField = (rules) => {
+ let isNoField = false;
+ for (let i = 0; i < rules.length; i++) {
+ const ruleData = rules[i];
+ if (ruleData.required) {
+ isNoField = true;
+ break;
+ }
+ }
+ return isNoField;
+}
+
+
+/**
+ * 获取数据类型
+ * @param {Any} obj 需要获取数据类型的值
+ */
+export const type = (obj) => {
+ var class2type = {};
+
+ // 生成class2type映射
+ "Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
+ class2type["[object " + item + "]"] = item.toLowerCase();
+ })
+ if (obj == null) {
+ return obj + "";
+ }
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[Object.prototype.toString.call(obj)] || "object" :
+ typeof obj;
+}
+
+/**
+ * 判断两个值是否相等
+ * @param {any} a 值
+ * @param {any} b 值
+ * @return {Boolean} 是否相等
+ */
+export const isEqual = (a, b) => {
+ //如果a和b本来就全等
+ if (a === b) {
+ //判断是否为0和-0
+ return a !== 0 || 1 / a === 1 / b;
+ }
+ //判断是否为null和undefined
+ if (a == null || b == null) {
+ return a === b;
+ }
+ //接下来判断a和b的数据类型
+ var classNameA = toString.call(a),
+ classNameB = toString.call(b);
+ //如果数据类型不相等,则返回false
+ if (classNameA !== classNameB) {
+ return false;
+ }
+ //如果数据类型相等,再根据不同数据类型分别判断
+ switch (classNameA) {
+ case '[object RegExp]':
+ case '[object String]':
+ //进行字符串转换比较
+ return '' + a === '' + b;
+ case '[object Number]':
+ //进行数字转换比较,判断是否为NaN
+ if (+a !== +a) {
+ return +b !== +b;
+ }
+ //判断是否为0或-0
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+ case '[object Date]':
+ case '[object Boolean]':
+ return +a === +b;
+ }
+ //如果是对象类型
+ if (classNameA == '[object Object]') {
+ //获取a和b的属性长度
+ var propsA = Object.getOwnPropertyNames(a),
+ propsB = Object.getOwnPropertyNames(b);
+ if (propsA.length != propsB.length) {
+ return false;
+ }
+ for (var i = 0; i < propsA.length; i++) {
+ var propName = propsA[i];
+ //如果对应属性对应值不相等,则返回false
+ if (a[propName] !== b[propName]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ //如果是数组类型
+ if (classNameA == '[object Array]') {
+ if (a.toString() == b.toString()) {
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/uni_modules/uni-forms/components/uni-forms/validate.js b/uni_modules/uni-forms/components/uni-forms/validate.js
new file mode 100644
index 0000000..1834c6c
--- /dev/null
+++ b/uni_modules/uni-forms/components/uni-forms/validate.js
@@ -0,0 +1,486 @@
+var pattern = {
+ email: /^\S+?@\S+?\.\S+?$/,
+ idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
+ url: new RegExp(
+ "^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$",
+ 'i')
+};
+
+const FORMAT_MAPPING = {
+ "int": 'integer',
+ "bool": 'boolean',
+ "double": 'number',
+ "long": 'number',
+ "password": 'string'
+ // "fileurls": 'array'
+}
+
+function formatMessage(args, resources = '') {
+ var defaultMessage = ['label']
+ defaultMessage.forEach((item) => {
+ if (args[item] === undefined) {
+ args[item] = ''
+ }
+ })
+
+ let str = resources
+ for (let key in args) {
+ let reg = new RegExp('{' + key + '}')
+ str = str.replace(reg, args[key])
+ }
+ return str
+}
+
+function isEmptyValue(value, type) {
+ if (value === undefined || value === null) {
+ return true;
+ }
+
+ if (typeof value === 'string' && !value) {
+ return true;
+ }
+
+ if (Array.isArray(value) && !value.length) {
+ return true;
+ }
+
+ if (type === 'object' && !Object.keys(value).length) {
+ return true;
+ }
+
+ return false;
+}
+
+const types = {
+ integer(value) {
+ return types.number(value) && parseInt(value, 10) === value;
+ },
+ string(value) {
+ return typeof value === 'string';
+ },
+ number(value) {
+ if (isNaN(value)) {
+ return false;
+ }
+ return typeof value === 'number';
+ },
+ "boolean": function(value) {
+ return typeof value === 'boolean';
+ },
+ "float": function(value) {
+ return types.number(value) && !types.integer(value);
+ },
+ array(value) {
+ return Array.isArray(value);
+ },
+ object(value) {
+ return typeof value === 'object' && !types.array(value);
+ },
+ date(value) {
+ return value instanceof Date;
+ },
+ timestamp(value) {
+ if (!this.integer(value) || Math.abs(value).toString().length > 16) {
+ return false
+ }
+ return true;
+ },
+ file(value) {
+ return typeof value.url === 'string';
+ },
+ email(value) {
+ return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
+ },
+ url(value) {
+ return typeof value === 'string' && !!value.match(pattern.url);
+ },
+ pattern(reg, value) {
+ try {
+ return new RegExp(reg).test(value);
+ } catch (e) {
+ return false;
+ }
+ },
+ method(value) {
+ return typeof value === 'function';
+ },
+ idcard(value) {
+ return typeof value === 'string' && !!value.match(pattern.idcard);
+ },
+ 'url-https'(value) {
+ return this.url(value) && value.startsWith('https://');
+ },
+ 'url-scheme'(value) {
+ return value.startsWith('://');
+ },
+ 'url-web'(value) {
+ return false;
+ }
+}
+
+class RuleValidator {
+
+ constructor(message) {
+ this._message = message
+ }
+
+ async validateRule(fieldKey, fieldValue, value, data, allData) {
+ var result = null
+
+ let rules = fieldValue.rules
+
+ let hasRequired = rules.findIndex((item) => {
+ return item.required
+ })
+ if (hasRequired < 0) {
+ if (value === null || value === undefined) {
+ return result
+ }
+ if (typeof value === 'string' && !value.length) {
+ return result
+ }
+ }
+
+ var message = this._message
+
+ if (rules === undefined) {
+ return message['default']
+ }
+
+ for (var i = 0; i < rules.length; i++) {
+ let rule = rules[i]
+ let vt = this._getValidateType(rule)
+
+ Object.assign(rule, {
+ label: fieldValue.label || `["${fieldKey}"]`
+ })
+
+ if (RuleValidatorHelper[vt]) {
+ result = RuleValidatorHelper[vt](rule, value, message)
+ if (result != null) {
+ break
+ }
+ }
+
+ if (rule.validateExpr) {
+ let now = Date.now()
+ let resultExpr = rule.validateExpr(value, allData, now)
+ if (resultExpr === false) {
+ result = this._getMessage(rule, rule.errorMessage || this._message['default'])
+ break
+ }
+ }
+
+ if (rule.validateFunction) {
+ result = await this.validateFunction(rule, value, data, allData, vt)
+ if (result !== null) {
+ break
+ }
+ }
+ }
+
+ if (result !== null) {
+ result = message.TAG + result
+ }
+
+ return result
+ }
+
+ async validateFunction(rule, value, data, allData, vt) {
+ let result = null
+ try {
+ let callbackMessage = null
+ const res = await rule.validateFunction(rule, value, allData || data, (message) => {
+ callbackMessage = message
+ })
+ if (callbackMessage || (typeof res === 'string' && res) || res === false) {
+ result = this._getMessage(rule, callbackMessage || res, vt)
+ }
+ } catch (e) {
+ result = this._getMessage(rule, e.message, vt)
+ }
+ return result
+ }
+
+ _getMessage(rule, message, vt) {
+ return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default'])
+ }
+
+ _getValidateType(rule) {
+ var result = ''
+ if (rule.required) {
+ result = 'required'
+ } else if (rule.format) {
+ result = 'format'
+ } else if (rule.arrayType) {
+ result = 'arrayTypeFormat'
+ } else if (rule.range) {
+ result = 'range'
+ } else if (rule.maximum !== undefined || rule.minimum !== undefined) {
+ result = 'rangeNumber'
+ } else if (rule.maxLength !== undefined || rule.minLength !== undefined) {
+ result = 'rangeLength'
+ } else if (rule.pattern) {
+ result = 'pattern'
+ } else if (rule.validateFunction) {
+ result = 'validateFunction'
+ }
+ return result
+ }
+}
+
+const RuleValidatorHelper = {
+ required(rule, value, message) {
+ if (rule.required && isEmptyValue(value, rule.format || typeof value)) {
+ return formatMessage(rule, rule.errorMessage || message.required);
+ }
+
+ return null
+ },
+
+ range(rule, value, message) {
+ const {
+ range,
+ errorMessage
+ } = rule;
+
+ let list = new Array(range.length);
+ for (let i = 0; i < range.length; i++) {
+ const item = range[i];
+ if (types.object(item) && item.value !== undefined) {
+ list[i] = item.value;
+ } else {
+ list[i] = item;
+ }
+ }
+
+ let result = false
+ if (Array.isArray(value)) {
+ result = (new Set(value.concat(list)).size === list.length);
+ } else {
+ if (list.indexOf(value) > -1) {
+ result = true;
+ }
+ }
+
+ if (!result) {
+ return formatMessage(rule, errorMessage || message['enum']);
+ }
+
+ return null
+ },
+
+ rangeNumber(rule, value, message) {
+ if (!types.number(value)) {
+ return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
+ }
+
+ let {
+ minimum,
+ maximum,
+ exclusiveMinimum,
+ exclusiveMaximum
+ } = rule;
+ let min = exclusiveMinimum ? value <= minimum : value < minimum;
+ let max = exclusiveMaximum ? value >= maximum : value > maximum;
+
+ if (minimum !== undefined && min) {
+ return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ?
+ 'exclusiveMinimum' : 'minimum'
+ ])
+ } else if (maximum !== undefined && max) {
+ return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ?
+ 'exclusiveMaximum' : 'maximum'
+ ])
+ } else if (minimum !== undefined && maximum !== undefined && (min || max)) {
+ return formatMessage(rule, rule.errorMessage || message['number'].range)
+ }
+
+ return null
+ },
+
+ rangeLength(rule, value, message) {
+ if (!types.string(value) && !types.array(value)) {
+ return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
+ }
+
+ let min = rule.minLength;
+ let max = rule.maxLength;
+ let val = value.length;
+
+ if (min !== undefined && val < min) {
+ return formatMessage(rule, rule.errorMessage || message['length'].minLength)
+ } else if (max !== undefined && val > max) {
+ return formatMessage(rule, rule.errorMessage || message['length'].maxLength)
+ } else if (min !== undefined && max !== undefined && (val < min || val > max)) {
+ return formatMessage(rule, rule.errorMessage || message['length'].range)
+ }
+
+ return null
+ },
+
+ pattern(rule, value, message) {
+ if (!types['pattern'](rule.pattern, value)) {
+ return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
+ }
+
+ return null
+ },
+
+ format(rule, value, message) {
+ var customTypes = Object.keys(types);
+ var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType);
+
+ if (customTypes.indexOf(format) > -1) {
+ if (!types[format](value)) {
+ return formatMessage(rule, rule.errorMessage || message.typeError);
+ }
+ }
+
+ return null
+ },
+
+ arrayTypeFormat(rule, value, message) {
+ if (!Array.isArray(value)) {
+ return formatMessage(rule, rule.errorMessage || message.typeError);
+ }
+
+ for (let i = 0; i < value.length; i++) {
+ const element = value[i];
+ let formatResult = this.format(rule, element, message)
+ if (formatResult !== null) {
+ return formatResult
+ }
+ }
+
+ return null
+ }
+}
+
+class SchemaValidator extends RuleValidator {
+
+ constructor(schema, options) {
+ super(SchemaValidator.message);
+
+ this._schema = schema
+ this._options = options || null
+ }
+
+ updateSchema(schema) {
+ this._schema = schema
+ }
+
+ async validate(data, allData) {
+ let result = this._checkFieldInSchema(data)
+ if (!result) {
+ result = await this.invokeValidate(data, false, allData)
+ }
+ return result.length ? result[0] : null
+ }
+
+ async validateAll(data, allData) {
+ let result = this._checkFieldInSchema(data)
+ if (!result) {
+ result = await this.invokeValidate(data, true, allData)
+ }
+ return result
+ }
+
+ async validateUpdate(data, allData) {
+ let result = this._checkFieldInSchema(data)
+ if (!result) {
+ result = await this.invokeValidateUpdate(data, false, allData)
+ }
+ return result.length ? result[0] : null
+ }
+
+ async invokeValidate(data, all, allData) {
+ let result = []
+ let schema = this._schema
+ for (let key in schema) {
+ let value = schema[key]
+ let errorMessage = await this.validateRule(key, value, data[key], data, allData)
+ if (errorMessage != null) {
+ result.push({
+ key,
+ errorMessage
+ })
+ if (!all) break
+ }
+ }
+ return result
+ }
+
+ async invokeValidateUpdate(data, all, allData) {
+ let result = []
+ for (let key in data) {
+ let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData)
+ if (errorMessage != null) {
+ result.push({
+ key,
+ errorMessage
+ })
+ if (!all) break
+ }
+ }
+ return result
+ }
+
+ _checkFieldInSchema(data) {
+ var keys = Object.keys(data)
+ var keys2 = Object.keys(this._schema)
+ if (new Set(keys.concat(keys2)).size === keys2.length) {
+ return ''
+ }
+
+ var noExistFields = keys.filter((key) => {
+ return keys2.indexOf(key) < 0;
+ })
+ var errorMessage = formatMessage({
+ field: JSON.stringify(noExistFields)
+ }, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid'])
+ return [{
+ key: 'invalid',
+ errorMessage
+ }]
+ }
+}
+
+function Message() {
+ return {
+ TAG: "",
+ default: '验证错误',
+ defaultInvalid: '提交的字段{field}在数据库中并不存在',
+ validateFunction: '验证无效',
+ required: '{label}必填',
+ 'enum': '{label}超出范围',
+ timestamp: '{label}格式无效',
+ whitespace: '{label}不能为空',
+ typeError: '{label}类型无效',
+ date: {
+ format: '{label}日期{value}格式无效',
+ parse: '{label}日期无法解析,{value}无效',
+ invalid: '{label}日期{value}无效'
+ },
+ length: {
+ minLength: '{label}长度不能少于{minLength}',
+ maxLength: '{label}长度不能超过{maxLength}',
+ range: '{label}必须介于{minLength}和{maxLength}之间'
+ },
+ number: {
+ minimum: '{label}不能小于{minimum}',
+ maximum: '{label}不能大于{maximum}',
+ exclusiveMinimum: '{label}不能小于等于{minimum}',
+ exclusiveMaximum: '{label}不能大于等于{maximum}',
+ range: '{label}必须介于{minimum}and{maximum}之间'
+ },
+ pattern: {
+ mismatch: '{label}格式不匹配'
+ }
+ };
+}
+
+
+SchemaValidator.message = new Message();
+
+export default SchemaValidator
diff --git a/uni_modules/uni-forms/package.json b/uni_modules/uni-forms/package.json
new file mode 100644
index 0000000..464b4e6
--- /dev/null
+++ b/uni_modules/uni-forms/package.json
@@ -0,0 +1,88 @@
+{
+ "id": "uni-forms",
+ "displayName": "uni-forms 表单",
+ "version": "1.4.10",
+ "description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
+ "keywords": [
+ "uni-ui",
+ "表单",
+ "校验",
+ "表单校验",
+ "表单验证"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": ""
+ },
+ "directories": {
+ "example": "../../temps/example_temps"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+ "type": "component-vue"
+ },
+ "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",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-forms/readme.md b/uni_modules/uni-forms/readme.md
new file mode 100644
index 0000000..63d5a04
--- /dev/null
+++ b/uni_modules/uni-forms/readme.md
@@ -0,0 +1,23 @@
+
+
+## Forms 表单
+
+> **组件名:uni-forms**
+> 代码块: `uForms`、`uni-forms-item`
+> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。
+
+
+uni-app的内置组件已经有了 `