From a3d1d75a5423cb8db8d3007fda264a7e504d7d15 Mon Sep 17 00:00:00 2001
From: hengtou <717691034@qq.com>
Date: Mon, 2 Dec 2024 17:22:50 +0800
Subject: [PATCH] init
---
.gitignore | 18 +
.hbuilderx/launch.json | 21 +
API/index.js | 711 ++
API/indexApi.js | 29 +
API/login.js | 148 +
API/order.js | 288 +
API/pay.js | 65 +
API/product.js | 261 +
API/ranking.js | 89 +
API/report.js | 44 +
API/shop.js | 232 +
API/sign.js | 57 +
API/user.js | 393 +
API/virtual.js | 95 +
App.vue | 84 +
Dockerfile | 3 +
README.md | 48 +
components/ai-progress/ai-progress.vue | 176 +
components/bottom-fixed/bottom-fixed.vue | 69 +
components/code-elf-guide/code-elf-guide.vue | 120 +
.../custom-radio-item/custom-radio-item.vue | 68 +
components/empty/empty.vue | 58 +
components/icon-view/icon-view.vue | 269 +
components/icon-view/iconfont.css | 897 ++
components/index-entrance/index-entrance.vue | 107 +
components/lb-picker/README.md | 434 +
components/lb-picker/index.vue | 313 +
components/lb-picker/mixins/index.js | 45 +
.../pickers/multi-selector-picker.vue | 93 +
.../lb-picker/pickers/selector-picker.vue | 68 +
.../pickers/unlinked-selector-picker.vue | 76 +
components/lb-picker/style/picker-item.scss | 23 +
components/lb-picker/style/picker.scss | 151 +
components/lb-picker/utils.js | 110 +
components/mask-view/mask-view.vue | 120 +
.../mescroll-uni/components/mescroll-down.css | 55 +
.../mescroll-uni/components/mescroll-down.vue | 47 +
.../components/mescroll-empty.vue | 90 +
.../mescroll-uni/components/mescroll-top.vue | 83 +
.../mescroll-uni/components/mescroll-up.css | 47 +
.../mescroll-uni/components/mescroll-up.vue | 39 +
components/mescroll-uni/mescroll-body.css | 14 +
components/mescroll-uni/mescroll-body.vue | 327 +
components/mescroll-uni/mescroll-mixins.js | 65 +
.../mescroll-uni/mescroll-uni-option.js | 33 +
components/mescroll-uni/mescroll-uni.css | 36 +
components/mescroll-uni/mescroll-uni.js | 788 ++
components/mescroll-uni/mescroll-uni.vue | 413 +
.../mescroll-uni/mixins/mescroll-comp.js | 50 +
.../mescroll-uni/mixins/mescroll-more-item.js | 51 +
.../mescroll-uni/mixins/mescroll-more.js | 56 +
components/mescroll-uni/wxs/mixins.js | 102 +
components/mescroll-uni/wxs/renderjs.js | 92 +
components/mescroll-uni/wxs/wxs.wxs | 268 +
components/notice-list/notice-list.vue | 118 +
components/pick-regions/pick-regions.vue | 138 +
components/pick-regions/regions.json | 1 +
components/popup-view/popup-view.vue | 474 +
components/tab-control/tab-control.vue | 322 +
.../u-parse/components/wxParseAudio.vue | 27 +
components/u-parse/components/wxParseImg.vue | 86 +
.../u-parse/components/wxParseTemplate0.vue | 107 +
.../u-parse/components/wxParseTemplate1.vue | 99 +
.../u-parse/components/wxParseTemplate10.vue | 97 +
.../u-parse/components/wxParseTemplate11.vue | 87 +
.../u-parse/components/wxParseTemplate2.vue | 98 +
.../u-parse/components/wxParseTemplate3.vue | 98 +
.../u-parse/components/wxParseTemplate4.vue | 98 +
.../u-parse/components/wxParseTemplate5.vue | 98 +
.../u-parse/components/wxParseTemplate6.vue | 98 +
.../u-parse/components/wxParseTemplate7.vue | 98 +
.../u-parse/components/wxParseTemplate8.vue | 98 +
.../u-parse/components/wxParseTemplate9.vue | 98 +
.../u-parse/components/wxParseVideo.vue | 15 +
components/u-parse/libs/html2json.js | 261 +
components/u-parse/libs/htmlparser.js | 156 +
components/u-parse/libs/wxDiscode.js | 195 +
components/u-parse/readme.md | 102 +
components/u-parse/u-parse.css | 232 +
components/u-parse/u-parse.vue | 118 +
.../under-development/under-development.vue | 55 +
components/uni-grid-item/uni-grid-item.vue | 109 +
components/uni-grid/uni-grid.vue | 120 +
components/uni-icons/icons.js | 96 +
components/uni-icons/uni-icons.vue | 57 +
components/uni-nav-bar/uni-nav-bar.vue | 237 +
components/uni-status-bar/uni-status-bar.vue | 25 +
components/virtual-button/virtual-button.vue | 157 +
.../xinyu-logistics/xinyu-logistics.vue | 306 +
config/baseConfig.js | 63 +
get-weixin-code.html | 95 +
js_sdk/nl-precisionNum/package.json | 19 +
js_sdk/nl-precisionNum/precisionNum.js | 104 +
login.html | 53 +
main.js | 38 +
make-dev.sh | 3 +
make-test.sh | 3 +
make.sh | 3 +
manifest.json | 181 +
mixins/mixins.js | 76 +
package.json | 22 +
pages.json | 938 ++
pages/agreement/index.vue | 184 +
pages/agreement/nonage-rule.vue | 168 +
pages/agreement/nonage.vue | 115 +
pages/agreement/privacy.vue | 378 +
pages/agreement/rule.vue | 123 +
pages/agreement/total.vue | 329 +
.../crop-statusbar-height.vue | 54 +
pages/components/customNavbarPage.vue | 36 +
pages/components/customer.vue | 53 +
pages/components/empyt.vue | 63 +
pages/components/floatWindow copy 1.vue | 321 +
pages/components/floatWindow copy.vue | 210 +
pages/components/floatWindow.vue | 549 +
pages/components/header.vue | 67 +
pages/components/indexNavBarSkeletonPage.vue | 90 +
pages/components/isPayDlg.vue | 173 +
pages/components/mixins/navBarPageMixin.js | 88 +
pages/components/nav.vue | 54 +
pages/components/navBarSkeletonPage.vue | 90 +
pages/components/pagePopUp.vue | 231 +
pages/components/paymentPassword.vue | 104 +
pages/components/quotationList.vue | 294 +
pages/components/spine.vue | 114 +
pages/index/activity.vue | 1686 +++
pages/index/boxDetail.vue | 908 ++
pages/index/boxOrderConfirm.vue | 590 +
pages/index/boxPaySuccess.vue | 291 +
pages/index/card copy 1.vue | 597 +
pages/index/card copy.vue | 223 +
pages/index/card.vue | 798 ++
pages/index/components/bgGuang copy.vue | 49 +
pages/index/components/bgGuang.vue | 68 +
pages/index/components/box.vue | 89 +
pages/index/components/btn.vue | 76 +
pages/index/components/bubble.vue | 90 +
pages/index/components/buy.vue | 366 +
.../index/components/buyActivityBox copy.vue | 984 ++
pages/index/components/buyActivityBox.vue | 1213 ++
pages/index/components/buyBox copy.vue | 1238 +++
pages/index/components/buyBox.vue | 1404 +++
pages/index/components/buyBoxRun.vue | 1569 +++
pages/index/components/buyFreeBox.vue | 608 +
pages/index/components/coinDeficit.vue | 516 +
pages/index/components/lihua copy.vue | 66 +
pages/index/components/lihua.vue | 66 +
pages/index/components/line.vue | 163 +
pages/index/components/listBonus.vue | 377 +
pages/index/components/noOpen.vue | 101 +
pages/index/components/openBox copy.vue | 226 +
pages/index/components/openBox.vue | 264 +
pages/index/components/openBoxFive.vue | 265 +
pages/index/components/openBoxNine.vue | 295 +
pages/index/components/openBoxThree.vue | 267 +
pages/index/components/openFreeBox.vue | 221 +
pages/index/components/openFreeBoxFive.vue | 255 +
pages/index/components/openFreeBoxThree.vue | 264 +
pages/index/components/qp.vue | 389 +
pages/index/components/raffle.vue | 187 +
pages/index/components/rankNum.vue | 40 +
pages/index/components/sign.vue | 348 +
pages/index/components/tip.vue | 293 +
pages/index/components/top.vue | 180 +
pages/index/components/trumpet.vue | 113 +
pages/index/confirmOrder.vue | 482 +
pages/index/detail.vue | 1361 +++
pages/index/draw copy.vue | 671 ++
pages/index/draw.vue | 736 ++
pages/index/drawFree.vue | 549 +
pages/index/drawNine.vue | 675 ++
pages/index/index.vue | 743 ++
pages/index/lastRanking.vue | 293 +
pages/index/new-index copy 1.vue | 1837 +++
pages/index/new-index copy.vue | 1826 +++
pages/index/new-index-y.vue | 1292 +++
pages/index/new-index.vue | 3120 ++++++
pages/index/order.vue | 317 +
pages/index/paySuc.vue | 155 +
pages/index/prize.vue | 490 +
pages/index/ranking.vue | 1043 ++
pages/index/sign.vue | 349 +
pages/index/webview.vue | 22 +
pages/index/首页-zuiyou.vue | 1099 ++
pages/login/bind.vue | 179 +
pages/login/bindPhone.vue | 213 +
pages/login/get-weixin-code.html | 92 +
pages/login/index.vue | 214 +
pages/login/login copy.vue | 522 +
pages/login/login.vue | 344 +
pages/login/password.vue | 187 +
pages/login/past-due.vue | 76 +
pages/login/registerAndForget.vue | 236 +
pages/login/shut-down.vue | 88 +
pages/mine/about.vue | 79 +
pages/mine/addAddress copy.vue | 367 +
pages/mine/addAddress.vue | 239 +
pages/mine/address copy.vue | 352 +
pages/mine/address.vue | 269 +
pages/mine/boxConfirm copy 1.vue | 481 +
pages/mine/boxConfirm copy.vue | 682 ++
pages/mine/boxConfirm.vue | 483 +
pages/mine/boxOrder copy.vue | 327 +
pages/mine/boxOrder.vue | 214 +
pages/mine/boxRecrd copy.vue | 1858 ++++
pages/mine/boxRecrd.vue | 2118 ++++
pages/mine/collect copy.vue | 270 +
pages/mine/collect.vue | 227 +
pages/mine/components/countdow.vue | 78 +
pages/mine/coupon copy.vue | 183 +
pages/mine/coupon.vue | 261 +
pages/mine/customer.vue | 63 +
pages/mine/editName copy.vue | 79 +
pages/mine/editName.vue | 105 +
pages/mine/feedback.vue | 327 +
pages/mine/index.vue | 703 ++
pages/mine/mine.vue | 574 +
pages/mine/moreCoupon copy.vue | 167 +
pages/mine/moreCoupon.vue | 324 +
pages/mine/notice.vue | 182 +
pages/mine/noticeDetail.vue | 121 +
pages/mine/orderBoxDetail.vue | 528 +
pages/mine/orderStatusDetail copy.vue | 779 ++
pages/mine/orderStatusDetail.vue | 895 ++
pages/mine/payVirtualSuccess.vue | 164 +
pages/mine/point copy.vue | 156 +
pages/mine/point.vue | 167 +
pages/mine/prompt.vue | 255 +
pages/mine/setting copy.vue | 256 +
pages/mine/setting.vue | 392 +
pages/mine/sign copy.vue | 241 +
pages/mine/sign.vue | 582 +
pages/mine/topUp copy.vue | 230 +
pages/mine/topUp.vue | 689 ++
pages/mine/topUpOrder copy.vue | 158 +
pages/mine/topUpOrder.vue | 277 +
pages/mine/topUpSuc copy.vue | 270 +
pages/mine/topUpSuc.vue | 147 +
pages/mine/virtual.vue | 812 ++
pages/mine/virtualDetail.vue | 910 ++
pages/mine/white.vue | 14 +
pages/order/confirm.vue | 593 +
pages/order/index copy.vue | 433 +
pages/order/index.vue | 818 ++
pages/product/detail.vue | 668 ++
pages/product/product.vue | 458 +
pages/search/index.vue | 236 +
pages/search/search-list.vue | 228 +
pages/shop/cashier copy.vue | 494 +
pages/shop/confirm copy.vue | 447 +
pages/shop/confirm.vue | 451 +
pages/shop/detail copy.vue | 567 +
pages/shop/detail.vue | 1406 +++
pages/shop/index copy.vue | 479 +
pages/shop/index.vue | 489 +
pages/shop/paySuccess copy.vue | 275 +
pages/shop/paySuccess.vue | 168 +
pages/shop/search-list.vue | 263 +
pages/shop/search.vue | 171 +
pages/testPay/testPay.vue | 869 ++
uni.scss | 81 +
.../cloudfunctions/public/index.js | 26 +
.../cloudfunctions/public/package.json | 7 +
uniCloud-aliyun/database/JQL查询.jql | 12 +
uni_modules/uni-config-center/changelog.md | 6 +
uni_modules/uni-config-center/package.json | 81 +
uni_modules/uni-config-center/readme.md | 93 +
.../common/uni-config-center/index.js | 1 +
.../common/uni-config-center/package.json | 9 +
uni_modules/uni-id-common/changelog.md | 34 +
uni_modules/uni-id-common/package.json | 85 +
uni_modules/uni-id-common/readme.md | 3 +
.../common/uni-id-common/index.js | 1 +
.../common/uni-id-common/package.json | 16 +
uni_modules/uni-link/changelog.md | 17 +
.../uni-link/components/uni-link/uni-link.vue | 128 +
uni_modules/uni-link/package.json | 87 +
uni_modules/uni-link/readme.md | 11 +
uni_modules/uni-scss/changelog.md | 8 +
uni_modules/uni-scss/index.scss | 1 +
uni_modules/uni-scss/package.json | 82 +
uni_modules/uni-scss/readme.md | 4 +
uni_modules/uni-scss/styles/index.scss | 7 +
.../uni-scss/styles/setting/_border.scss | 3 +
.../uni-scss/styles/setting/_color.scss | 66 +
.../uni-scss/styles/setting/_radius.scss | 55 +
.../uni-scss/styles/setting/_space.scss | 56 +
.../uni-scss/styles/setting/_styles.scss | 167 +
.../uni-scss/styles/setting/_text.scss | 24 +
.../uni-scss/styles/setting/_variables.scss | 146 +
.../uni-scss/styles/tools/functions.scss | 19 +
uni_modules/uni-scss/theme.scss | 31 +
uni_modules/uni-scss/variables.scss | 62 +
uni_modules/yaor-webview/changelog.md | 4 +
.../components/yaor-webview/yaor-webview.vue | 41 +
uni_modules/yaor-webview/package.json | 87 +
uni_modules/yaor-webview/readme.md | 1 +
utils/filter/filterUtils.js | 33 +
utils/httpUtils.js | 117 +
utils/index copy 1.html | 1113 ++
utils/index copy 2.html | 1128 ++
utils/index copy.html | 1011 ++
utils/index.html | 1113 ++
utils/jq.js | 9814 +++++++++++++++++
utils/jsMd5.js | 1 +
utils/jsUtils.js | 61 +
utils/mathUtils.js | 55 +
utils/md5.js | 1113 ++
utils/msgUtils.js | 27 +
utils/precisionNum.js | 104 +
utils/public.js | 17 +
utils/report.js | 10 +
utils/skip.js | 41 +
utils/spine-player.min.css | 1 +
utils/testUtils.js | 12 +
utils/uniCopyUtils.js | 77 +
utils/uqrcode/uqrcode.js | 1380 +++
utils/webSocketUtils.js | 181 +
utils/webViewCom.js | 11 +
319 files changed, 103010 insertions(+)
create mode 100644 .gitignore
create mode 100644 .hbuilderx/launch.json
create mode 100644 API/index.js
create mode 100644 API/indexApi.js
create mode 100644 API/login.js
create mode 100644 API/order.js
create mode 100644 API/pay.js
create mode 100644 API/product.js
create mode 100644 API/ranking.js
create mode 100644 API/report.js
create mode 100644 API/shop.js
create mode 100644 API/sign.js
create mode 100644 API/user.js
create mode 100644 API/virtual.js
create mode 100644 App.vue
create mode 100755 Dockerfile
create mode 100644 README.md
create mode 100644 components/ai-progress/ai-progress.vue
create mode 100644 components/bottom-fixed/bottom-fixed.vue
create mode 100644 components/code-elf-guide/code-elf-guide.vue
create mode 100644 components/custom-radio-item/custom-radio-item.vue
create mode 100644 components/empty/empty.vue
create mode 100644 components/icon-view/icon-view.vue
create mode 100644 components/icon-view/iconfont.css
create mode 100644 components/index-entrance/index-entrance.vue
create mode 100644 components/lb-picker/README.md
create mode 100644 components/lb-picker/index.vue
create mode 100644 components/lb-picker/mixins/index.js
create mode 100644 components/lb-picker/pickers/multi-selector-picker.vue
create mode 100644 components/lb-picker/pickers/selector-picker.vue
create mode 100644 components/lb-picker/pickers/unlinked-selector-picker.vue
create mode 100644 components/lb-picker/style/picker-item.scss
create mode 100644 components/lb-picker/style/picker.scss
create mode 100644 components/lb-picker/utils.js
create mode 100644 components/mask-view/mask-view.vue
create mode 100644 components/mescroll-uni/components/mescroll-down.css
create mode 100644 components/mescroll-uni/components/mescroll-down.vue
create mode 100644 components/mescroll-uni/components/mescroll-empty.vue
create mode 100644 components/mescroll-uni/components/mescroll-top.vue
create mode 100644 components/mescroll-uni/components/mescroll-up.css
create mode 100644 components/mescroll-uni/components/mescroll-up.vue
create mode 100644 components/mescroll-uni/mescroll-body.css
create mode 100644 components/mescroll-uni/mescroll-body.vue
create mode 100644 components/mescroll-uni/mescroll-mixins.js
create mode 100644 components/mescroll-uni/mescroll-uni-option.js
create mode 100644 components/mescroll-uni/mescroll-uni.css
create mode 100644 components/mescroll-uni/mescroll-uni.js
create mode 100644 components/mescroll-uni/mescroll-uni.vue
create mode 100644 components/mescroll-uni/mixins/mescroll-comp.js
create mode 100644 components/mescroll-uni/mixins/mescroll-more-item.js
create mode 100644 components/mescroll-uni/mixins/mescroll-more.js
create mode 100644 components/mescroll-uni/wxs/mixins.js
create mode 100644 components/mescroll-uni/wxs/renderjs.js
create mode 100644 components/mescroll-uni/wxs/wxs.wxs
create mode 100644 components/notice-list/notice-list.vue
create mode 100755 components/pick-regions/pick-regions.vue
create mode 100755 components/pick-regions/regions.json
create mode 100644 components/popup-view/popup-view.vue
create mode 100644 components/tab-control/tab-control.vue
create mode 100644 components/u-parse/components/wxParseAudio.vue
create mode 100644 components/u-parse/components/wxParseImg.vue
create mode 100644 components/u-parse/components/wxParseTemplate0.vue
create mode 100644 components/u-parse/components/wxParseTemplate1.vue
create mode 100644 components/u-parse/components/wxParseTemplate10.vue
create mode 100644 components/u-parse/components/wxParseTemplate11.vue
create mode 100644 components/u-parse/components/wxParseTemplate2.vue
create mode 100644 components/u-parse/components/wxParseTemplate3.vue
create mode 100644 components/u-parse/components/wxParseTemplate4.vue
create mode 100644 components/u-parse/components/wxParseTemplate5.vue
create mode 100644 components/u-parse/components/wxParseTemplate6.vue
create mode 100644 components/u-parse/components/wxParseTemplate7.vue
create mode 100644 components/u-parse/components/wxParseTemplate8.vue
create mode 100644 components/u-parse/components/wxParseTemplate9.vue
create mode 100644 components/u-parse/components/wxParseVideo.vue
create mode 100644 components/u-parse/libs/html2json.js
create mode 100644 components/u-parse/libs/htmlparser.js
create mode 100644 components/u-parse/libs/wxDiscode.js
create mode 100644 components/u-parse/readme.md
create mode 100644 components/u-parse/u-parse.css
create mode 100644 components/u-parse/u-parse.vue
create mode 100644 components/under-development/under-development.vue
create mode 100644 components/uni-grid-item/uni-grid-item.vue
create mode 100644 components/uni-grid/uni-grid.vue
create mode 100644 components/uni-icons/icons.js
create mode 100644 components/uni-icons/uni-icons.vue
create mode 100644 components/uni-nav-bar/uni-nav-bar.vue
create mode 100644 components/uni-status-bar/uni-status-bar.vue
create mode 100644 components/virtual-button/virtual-button.vue
create mode 100644 components/xinyu-logistics/xinyu-logistics.vue
create mode 100644 config/baseConfig.js
create mode 100755 get-weixin-code.html
create mode 100644 js_sdk/nl-precisionNum/package.json
create mode 100644 js_sdk/nl-precisionNum/precisionNum.js
create mode 100755 login.html
create mode 100644 main.js
create mode 100644 make-dev.sh
create mode 100644 make-test.sh
create mode 100644 make.sh
create mode 100644 manifest.json
create mode 100755 mixins/mixins.js
create mode 100644 package.json
create mode 100644 pages.json
create mode 100644 pages/agreement/index.vue
create mode 100644 pages/agreement/nonage-rule.vue
create mode 100644 pages/agreement/nonage.vue
create mode 100644 pages/agreement/privacy.vue
create mode 100644 pages/agreement/rule.vue
create mode 100644 pages/agreement/total.vue
create mode 100644 pages/components/crop-statusbar-height/crop-statusbar-height.vue
create mode 100644 pages/components/customNavbarPage.vue
create mode 100644 pages/components/customer.vue
create mode 100644 pages/components/empyt.vue
create mode 100644 pages/components/floatWindow copy 1.vue
create mode 100644 pages/components/floatWindow copy.vue
create mode 100644 pages/components/floatWindow.vue
create mode 100644 pages/components/header.vue
create mode 100644 pages/components/indexNavBarSkeletonPage.vue
create mode 100644 pages/components/isPayDlg.vue
create mode 100644 pages/components/mixins/navBarPageMixin.js
create mode 100644 pages/components/nav.vue
create mode 100644 pages/components/navBarSkeletonPage.vue
create mode 100644 pages/components/pagePopUp.vue
create mode 100644 pages/components/paymentPassword.vue
create mode 100644 pages/components/quotationList.vue
create mode 100644 pages/components/spine.vue
create mode 100644 pages/index/activity.vue
create mode 100644 pages/index/boxDetail.vue
create mode 100644 pages/index/boxOrderConfirm.vue
create mode 100644 pages/index/boxPaySuccess.vue
create mode 100644 pages/index/card copy 1.vue
create mode 100644 pages/index/card copy.vue
create mode 100644 pages/index/card.vue
create mode 100644 pages/index/components/bgGuang copy.vue
create mode 100644 pages/index/components/bgGuang.vue
create mode 100644 pages/index/components/box.vue
create mode 100644 pages/index/components/btn.vue
create mode 100644 pages/index/components/bubble.vue
create mode 100644 pages/index/components/buy.vue
create mode 100644 pages/index/components/buyActivityBox copy.vue
create mode 100644 pages/index/components/buyActivityBox.vue
create mode 100644 pages/index/components/buyBox copy.vue
create mode 100644 pages/index/components/buyBox.vue
create mode 100644 pages/index/components/buyBoxRun.vue
create mode 100644 pages/index/components/buyFreeBox.vue
create mode 100644 pages/index/components/coinDeficit.vue
create mode 100644 pages/index/components/lihua copy.vue
create mode 100644 pages/index/components/lihua.vue
create mode 100644 pages/index/components/line.vue
create mode 100644 pages/index/components/listBonus.vue
create mode 100644 pages/index/components/noOpen.vue
create mode 100644 pages/index/components/openBox copy.vue
create mode 100644 pages/index/components/openBox.vue
create mode 100644 pages/index/components/openBoxFive.vue
create mode 100644 pages/index/components/openBoxNine.vue
create mode 100644 pages/index/components/openBoxThree.vue
create mode 100644 pages/index/components/openFreeBox.vue
create mode 100644 pages/index/components/openFreeBoxFive.vue
create mode 100644 pages/index/components/openFreeBoxThree.vue
create mode 100644 pages/index/components/qp.vue
create mode 100644 pages/index/components/raffle.vue
create mode 100644 pages/index/components/rankNum.vue
create mode 100644 pages/index/components/sign.vue
create mode 100644 pages/index/components/tip.vue
create mode 100644 pages/index/components/top.vue
create mode 100644 pages/index/components/trumpet.vue
create mode 100644 pages/index/confirmOrder.vue
create mode 100644 pages/index/detail.vue
create mode 100644 pages/index/draw copy.vue
create mode 100644 pages/index/draw.vue
create mode 100644 pages/index/drawFree.vue
create mode 100644 pages/index/drawNine.vue
create mode 100644 pages/index/index.vue
create mode 100644 pages/index/lastRanking.vue
create mode 100644 pages/index/new-index copy 1.vue
create mode 100644 pages/index/new-index copy.vue
create mode 100644 pages/index/new-index-y.vue
create mode 100644 pages/index/new-index.vue
create mode 100644 pages/index/order.vue
create mode 100644 pages/index/paySuc.vue
create mode 100644 pages/index/prize.vue
create mode 100644 pages/index/ranking.vue
create mode 100644 pages/index/sign.vue
create mode 100644 pages/index/webview.vue
create mode 100644 pages/index/首页-zuiyou.vue
create mode 100644 pages/login/bind.vue
create mode 100644 pages/login/bindPhone.vue
create mode 100755 pages/login/get-weixin-code.html
create mode 100644 pages/login/index.vue
create mode 100644 pages/login/login copy.vue
create mode 100644 pages/login/login.vue
create mode 100644 pages/login/password.vue
create mode 100644 pages/login/past-due.vue
create mode 100644 pages/login/registerAndForget.vue
create mode 100644 pages/login/shut-down.vue
create mode 100644 pages/mine/about.vue
create mode 100644 pages/mine/addAddress copy.vue
create mode 100644 pages/mine/addAddress.vue
create mode 100644 pages/mine/address copy.vue
create mode 100644 pages/mine/address.vue
create mode 100644 pages/mine/boxConfirm copy 1.vue
create mode 100644 pages/mine/boxConfirm copy.vue
create mode 100644 pages/mine/boxConfirm.vue
create mode 100644 pages/mine/boxOrder copy.vue
create mode 100644 pages/mine/boxOrder.vue
create mode 100644 pages/mine/boxRecrd copy.vue
create mode 100644 pages/mine/boxRecrd.vue
create mode 100644 pages/mine/collect copy.vue
create mode 100644 pages/mine/collect.vue
create mode 100644 pages/mine/components/countdow.vue
create mode 100644 pages/mine/coupon copy.vue
create mode 100644 pages/mine/coupon.vue
create mode 100644 pages/mine/customer.vue
create mode 100644 pages/mine/editName copy.vue
create mode 100644 pages/mine/editName.vue
create mode 100644 pages/mine/feedback.vue
create mode 100644 pages/mine/index.vue
create mode 100644 pages/mine/mine.vue
create mode 100644 pages/mine/moreCoupon copy.vue
create mode 100644 pages/mine/moreCoupon.vue
create mode 100644 pages/mine/notice.vue
create mode 100644 pages/mine/noticeDetail.vue
create mode 100644 pages/mine/orderBoxDetail.vue
create mode 100644 pages/mine/orderStatusDetail copy.vue
create mode 100644 pages/mine/orderStatusDetail.vue
create mode 100644 pages/mine/payVirtualSuccess.vue
create mode 100644 pages/mine/point copy.vue
create mode 100644 pages/mine/point.vue
create mode 100644 pages/mine/prompt.vue
create mode 100644 pages/mine/setting copy.vue
create mode 100644 pages/mine/setting.vue
create mode 100644 pages/mine/sign copy.vue
create mode 100644 pages/mine/sign.vue
create mode 100644 pages/mine/topUp copy.vue
create mode 100644 pages/mine/topUp.vue
create mode 100644 pages/mine/topUpOrder copy.vue
create mode 100644 pages/mine/topUpOrder.vue
create mode 100644 pages/mine/topUpSuc copy.vue
create mode 100644 pages/mine/topUpSuc.vue
create mode 100644 pages/mine/virtual.vue
create mode 100644 pages/mine/virtualDetail.vue
create mode 100644 pages/mine/white.vue
create mode 100644 pages/order/confirm.vue
create mode 100644 pages/order/index copy.vue
create mode 100644 pages/order/index.vue
create mode 100644 pages/product/detail.vue
create mode 100644 pages/product/product.vue
create mode 100644 pages/search/index.vue
create mode 100644 pages/search/search-list.vue
create mode 100644 pages/shop/cashier copy.vue
create mode 100644 pages/shop/confirm copy.vue
create mode 100644 pages/shop/confirm.vue
create mode 100644 pages/shop/detail copy.vue
create mode 100644 pages/shop/detail.vue
create mode 100644 pages/shop/index copy.vue
create mode 100644 pages/shop/index.vue
create mode 100644 pages/shop/paySuccess copy.vue
create mode 100644 pages/shop/paySuccess.vue
create mode 100644 pages/shop/search-list.vue
create mode 100644 pages/shop/search.vue
create mode 100644 pages/testPay/testPay.vue
create mode 100644 uni.scss
create mode 100644 uniCloud-aliyun/cloudfunctions/public/index.js
create mode 100644 uniCloud-aliyun/cloudfunctions/public/package.json
create mode 100644 uniCloud-aliyun/database/JQL查询.jql
create mode 100644 uni_modules/uni-config-center/changelog.md
create mode 100644 uni_modules/uni-config-center/package.json
create mode 100644 uni_modules/uni-config-center/readme.md
create mode 100644 uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
create mode 100644 uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
create mode 100644 uni_modules/uni-id-common/changelog.md
create mode 100644 uni_modules/uni-id-common/package.json
create mode 100644 uni_modules/uni-id-common/readme.md
create mode 100644 uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/index.js
create mode 100644 uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/package.json
create mode 100644 uni_modules/uni-link/changelog.md
create mode 100644 uni_modules/uni-link/components/uni-link/uni-link.vue
create mode 100644 uni_modules/uni-link/package.json
create mode 100644 uni_modules/uni-link/readme.md
create mode 100644 uni_modules/uni-scss/changelog.md
create mode 100644 uni_modules/uni-scss/index.scss
create mode 100644 uni_modules/uni-scss/package.json
create mode 100644 uni_modules/uni-scss/readme.md
create mode 100644 uni_modules/uni-scss/styles/index.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_border.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_color.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_radius.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_space.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_styles.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_text.scss
create mode 100644 uni_modules/uni-scss/styles/setting/_variables.scss
create mode 100644 uni_modules/uni-scss/styles/tools/functions.scss
create mode 100644 uni_modules/uni-scss/theme.scss
create mode 100644 uni_modules/uni-scss/variables.scss
create mode 100644 uni_modules/yaor-webview/changelog.md
create mode 100644 uni_modules/yaor-webview/components/yaor-webview/yaor-webview.vue
create mode 100644 uni_modules/yaor-webview/package.json
create mode 100644 uni_modules/yaor-webview/readme.md
create mode 100644 utils/filter/filterUtils.js
create mode 100644 utils/httpUtils.js
create mode 100755 utils/index copy 1.html
create mode 100755 utils/index copy 2.html
create mode 100755 utils/index copy.html
create mode 100755 utils/index.html
create mode 100644 utils/jq.js
create mode 100644 utils/jsMd5.js
create mode 100644 utils/jsUtils.js
create mode 100644 utils/mathUtils.js
create mode 100644 utils/md5.js
create mode 100644 utils/msgUtils.js
create mode 100644 utils/precisionNum.js
create mode 100644 utils/public.js
create mode 100644 utils/report.js
create mode 100644 utils/skip.js
create mode 100644 utils/spine-player.min.css
create mode 100644 utils/testUtils.js
create mode 100644 utils/uniCopyUtils.js
create mode 100644 utils/uqrcode/uqrcode.js
create mode 100644 utils/webSocketUtils.js
create mode 100644 utils/webViewCom.js
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..58138f3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+.DS_Store
+node_modules/
+dist/
+unpackage/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+tests/**/coverage/
+
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json
new file mode 100644
index 0000000..1b93662
--- /dev/null
+++ b/.hbuilderx/launch.json
@@ -0,0 +1,21 @@
+{
+ "version" : "1.0",
+ "configurations" : [
+ {
+ "default" :
+ {
+ "launchtype" : "local"
+ },
+ "h5" :
+ {
+ "launchtype" : "local"
+ },
+ "mp-weixin" :
+ {
+ "launchtype" : "local"
+ },
+ "provider" : "aliyun",
+ "type" : "uniCloud"
+ }
+ ]
+}
diff --git a/API/index.js b/API/index.js
new file mode 100644
index 0000000..e418d77
--- /dev/null
+++ b/API/index.js
@@ -0,0 +1,711 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'boxesPinnedApi': httpUrlFormat('/boxes/pinned', _flag),
+ 'boxesTagsApi': httpUrlFormat('/boxes/tags', _flag),
+ 'boxesApi': httpUrlFormat('/boxes', _flag),
+ 'boxRecordApi': httpUrlFormat('/box/record', _flag),
+ 'boxOrderApi': httpUrlFormat('/box/order', _flag),
+ 'boxOrderReviewApi': httpUrlFormat('/box/order/review', _flag),
+ 'boxOrderPaidApi': httpUrlFormat('/box/order/paid', _flag),
+ 'orderPaidApi': httpUrlFormat('/order/paid', _flag),
+ 'boxRecordResultApi': httpUrlFormat('/box/record/result', _flag),
+ 'boxDeliveryPreviewApi': httpUrlFormat('/order/box/delivery/preview', _flag),
+ 'boxDeliveryApi': httpUrlFormat('/order/box/delivery', _flag),
+ 'boxActivityApi': httpUrlFormat('/boxes/activity', _flag),//活动盲盒
+ 'boxActivityListApi': httpUrlFormat('/boxes/activity/list', _flag),//活动盲盒
+ 'promptCountApi': httpUrlFormat('/user/prompt/count', _flag),//用户提示卡数量
+ 'usePromptApi': httpUrlFormat('/box/order/use/prompt', _flag),//使用提示卡
+ 'activityDetailApi': httpUrlFormat('/boxes/activity/detail', _flag),//
+ 'activityDetailSourceApi': httpUrlFormat('/boxes/activity/detail/source', _flag),//
+ 'activityBuyApi': httpUrlFormat('/coin/gear/activity/box', _flag),//活动盲盒购买
+ 'activitySourceBuyApi': httpUrlFormat('/box/order/activity/source', _flag),//活动盲盒购买
+
+ 'activityReviewApi': httpUrlFormat('/box/order/activity/review', _flag),//活动盲盒订单预览
+ 'activityReviewSourceApi': httpUrlFormat('/box/order/activity/review/source', _flag),//活动盲盒订单预览-新
+
+ 'activityOrderApi': httpUrlFormat('/box/order/activity', _flag),
+ 'recoveryBatchApi': httpUrlFormat('/box/record/recovery/batch', _flag),
+ 'deliveryReviewBatchApi': httpUrlFormat('/order/box/delivery/preview/batch', _flag),
+ 'deliveryBatchApi': httpUrlFormat('/order/box/delivery/batch', _flag),
+ 'promptExchangeBatchApi': httpUrlFormat('/user/prompt/exchange/batch', _flag),
+ 'boxResultApi': httpUrlFormat('/misc/box/result', _flag),
+ 'noOpenListApi': httpUrlFormat('/box/record/no/open/list', _flag),//未开奖记录
+ 'openListApi': httpUrlFormat('/box/record/open', _flag),//开奖记录
+ 'boxesChannelPinnedApi': httpUrlFormat('/boxes/channel/pinned', _flag),//首页盲盒-渠道
+
+
+
+
+
+
+ 'orderReceive': httpUrlFormat('/order/receive', _flag),
+ 'orderList': httpUrlFormat('/order/mall_order', _flag),
+ 'boxOrder': httpUrlFormat('/order/box_order', _flag),
+ 'boxRecord': httpUrlFormat('/order/box_record', _flag),
+ 'boxOpen': httpUrlFormat('/order/box_open', _flag),
+ 'boxPickup': httpUrlFormat('/order/box_pickup', _flag),
+ 'boxRecycle': httpUrlFormat('/order/box_recycle', _flag),
+ 'boxInfo': httpUrlFormat('/order/box_info', _flag),
+ 'orderCancel': httpUrlFormat('/order/cancel', _flag),
+ 'boxOpenByBoxId': httpUrlFormat('/order/box_open_by_box_id', _flag),
+
+ 'popupAdPageApi': httpUrlFormat('/misc/popup/ad/page', _flag),
+ 'popupAdPageChannelApi': httpUrlFormat('/misc/popup/ad/page/channel', _flag),
+
+
+
+ 'activityIconApi': httpUrlFormat('/activity/icon', _flag),
+ 'activityDetailNewApi': httpUrlFormat('/activity/detail', _flag),
+
+
+ 'pointClearApi': httpUrlFormat('/user/point/clear', _flag),
+ 'activityTaskAwardApi': httpUrlFormat('/activity/task/award', _flag),
+
+
+
+
+ 'activityTaskCreateApi': httpUrlFormat('/box/order/activity/create', _flag),
+ 'freeBoxApi': httpUrlFormat('/boxes/free/box', _flag),
+ 'activityGuideApi': httpUrlFormat('/activity/guide', _flag),
+
+
+ 'indexGuideApi': httpUrlFormat('/user/index/guide', _flag),
+
+ 'activityTopLastApi': httpUrlFormat('/activity/top/last', _flag),
+
+
+
+
+}
+
+
+
+
+export function boxRecoveryApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/box/record/recovery/${data.id}`, _flag),
+ method: 'PUT',
+ data
+ })
+}
+//分页盲盒
+export function boxesApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxesApi,
+ method: 'GET',
+ data: data
+ })
+}
+//首页盲盒
+export function boxesPinnedApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.boxesPinnedApi,
+ method: 'GET',
+ data: data
+ })
+}
+//盲盒标签
+export function boxesTagsApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxesTagsApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+//盲盒开奖记录
+export function boxRecordApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxRecordApi,
+ method: 'GET',
+ data: data
+ })
+}
+// 盲盒详情
+export function boxesDetail(data,header = {}) {
+ const headerObj = {...headerVersion,...header}
+ // header['API-Version'] = ApiVersion()
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/boxes/${data.id}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+// 创建盲盒订单
+export function boxOrderApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrderApi,
+ method: 'POST',
+ data
+ })
+}
+export function boxOrderListApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrderApi,
+ method: 'GET',
+ data
+ })
+}
+// 活动盲盒
+export function boxActivityApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxActivityApi,
+ method: 'GET',
+ data
+ })
+}
+// 活动盲盒
+export function boxActivityListApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxActivityListApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+// 创建盲盒订单
+export function boxOrderReviewApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrderReviewApi,
+ method: 'GET',
+ data
+ })
+}
+// 创建盲盒订单
+export function boxOrderPaidApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrderPaidApi,
+ method: 'GET',
+ data
+ })
+}
+export function orderPaidApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderPaidApi,
+ method: 'GET',
+ data
+ })
+}
+
+// 盲盒开奖结果
+export function boxRecordResultApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxRecordResultApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+
+export function boxDeliveryPreviewApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded','API-Version': ApiVersion()},
+ // url: apiUrl.cart_item,
+ url: apiUrl.boxDeliveryPreviewApi,
+ // url: httpUrlFormat(`/order/box/delivery/preview?boxRecordId=${data.boxRecordId}&quantity=${data.quantity}`, _flag),
+ method: 'POST',
+ data: data
+ })
+}
+export function boxDeliveryApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // url: apiUrl.cart_item,
+ url: apiUrl.boxDeliveryApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+
+export function boxesChannelPinnedApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxesChannelPinnedApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+
+//商城订单列表
+export function orderList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.order,
+ method: 'GET',
+ data: data
+ })
+}
+// 删除订单
+export function delOrder(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.order,
+ method: 'DELETE',
+ data: data
+ })
+}
+// 取消订单
+export function orderCancel(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderCancel,
+ method: 'PUT',
+ data: data
+ })
+}
+// 确认收货
+export function orderReceive(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderReceive,
+ method: 'POST',
+ data: data
+ })
+}
+//创建商城订单
+export function createOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderList,
+ method: 'POST',
+ data: data
+ })
+}
+//订单预览
+export function orderPreview(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.orderPreview,
+ method: 'POST',
+ data: data
+ })
+}
+//盲盒订单列表
+export function boxOrderList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrder,
+ method: 'GET',
+ data: data
+ })
+}
+
+//创建盲盒订单
+export function boxCreateOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrder,
+ method: 'POST',
+ data: data
+ })
+}
+//礼盒/物品列表
+export function boxRecord(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxRecord,
+ method: 'GET',
+ data: data
+ })
+}
+//开盲盒
+export function boxOpen(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ header: headerObj,
+ url: apiUrl.boxOpen,
+ method: 'POST',
+ data: data
+ })
+}
+//提取盲盒
+export function boxPickup(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxPickup,
+ method: 'POST',
+ data: data
+ })
+}
+//回收盲盒
+export function boxRecycle(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.boxRecycle,
+ method: 'POST',
+ data: data
+ })
+}
+// 订单详情
+export function orderDetail(no,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/order/${no}`, _flag),
+ method: 'GET',
+ data: data
+ })
+}
+//盲盒详情
+export function boxInfo(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.boxInfo,
+ method: 'GET',
+ data: data
+ })
+}
+// 根据盲盒id开盒
+export function boxOpenByBoxId(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.boxOpenByBoxId,
+ method: 'POST',
+ data: data
+ })
+}
+// 用户提示卡数量
+export function promptCountApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.promptCountApi,
+ method: 'GET',
+ data: data
+ })
+}
+// 使用提示卡
+export function usePromptApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.usePromptApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function activityDetailApi(data,header = {}) {
+ // header['API-Version'] = ApiVersion()
+ const headerObj = {...headerVersion,...header}
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ url: apiUrl.activityDetailApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function activityDetailSourceApi(data,header = {}) {
+ // header['API-Version'] = ApiVersion()
+ const headerObj = {...headerVersion,...header}
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ url: apiUrl.activityDetailSourceApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+export function activityBuyApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.activityBuyApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function activitySourceBuyApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.activitySourceBuyApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+export function activityReviewApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.activityReviewApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function activityReviewSourceApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.activityReviewSourceApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function activityOrderApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.activityOrderApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function recoveryBatchApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.recoveryBatchApi,
+ method: 'PUT',
+ data: data
+ })
+}
+export function deliveryReviewBatchApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.deliveryReviewBatchApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function deliveryBatchApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.deliveryBatchApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function promptExchangeBatchApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.promptExchangeBatchApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function boxResultApi(data,header = {}) {
+ const headerObj = {...headerVersion,...header}
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ url: apiUrl.boxResultApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function noOpenListApi(data,header = {}) {
+ const headerObj = {...headerVersion,...header}
+ // header['API-Version'] = ApiVersion()
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ url: apiUrl.noOpenListApi,
+ method: 'GET',
+ data: data
+ })
+}
+// export function openListApi(data,header = {}) {
+// // header['API-Version'] = ApiVersion()
+// const headerObj = {...headerVersion,...header}
+// return ajaxCarryAuthorization({
+// header:headerObj,
+// url: apiUrl.openListApi,
+// method: 'GET',
+// data: data
+// })
+// }
+export function openListApi(data,header = {}) {
+ // header['API-Version'] = ApiVersion()
+ const headerObj = {...headerVersion,...header}
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ url: httpUrlFormat(`/box/record/open?ids=${data}`, _flag),
+ method: 'GET',
+ data: data
+ })
+}
+export function popupAdPageApi(data) {
+ return ajaxCarryAuthorization({
+ header:headerVersion,
+ url: apiUrl.popupAdPageApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function popupAdPageChannelApi(data) {
+ return ajaxCarryAuthorization({
+ header:headerVersion,
+ url: apiUrl.popupAdPageChannelApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+
+export function activityIconApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.activityIconApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+export function activityDetailNewApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.activityDetailNewApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+export function pointClearApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.pointClearApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function activityTaskAwardApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.activityTaskAwardApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function activityTaskCreateApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.activityTaskCreateApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+// 免费开盲盒
+export function freeBoxApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.freeBoxApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+export function activityGuideApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.activityGuideApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function setActivityGuideApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.activityGuideApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+export function indexGuideApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.indexGuideApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function setIndexGuideApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.indexGuideApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function activityTopLastApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.activityTopLastApi,
+ method: 'GET',
+ data: data
+ })
+}
diff --git a/API/indexApi.js b/API/indexApi.js
new file mode 100644
index 0000000..b063c3b
--- /dev/null
+++ b/API/indexApi.js
@@ -0,0 +1,29 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'index': httpUrlFormat('/index', _flag),
+}
+
+export function index(data) {
+ return ajaxSync({
+ header: headerVersion,
+ url: apiUrl.index,
+ method: 'GET',
+ data: data
+ })
+}
+
diff --git a/API/login.js b/API/login.js
new file mode 100644
index 0000000..26cbcd1
--- /dev/null
+++ b/API/login.js
@@ -0,0 +1,148 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'generateCode': httpUrlFormat('/generate/code', _flag),//发送短信验证码
+ 'sms_check': httpUrlFormat('/sms_check', _flag),//验证短信验证码
+ 'register': httpUrlFormat('/register', _flag),//注册
+ 'login': httpUrlFormat('/login', _flag),//登录
+ 'loginCode': httpUrlFormat('/login/code', _flag),//验证码登录
+ 'wechatAppid': httpUrlFormat('/wechat/appid', _flag),//微信获取appid
+ 'loginWechat': httpUrlFormat('/login/wechat', _flag),//微信登录
+ 'phoneWechat': httpUrlFormat('/wechat/user/phone', _flag),//微信登录
+ 'reset_password': httpUrlFormat('/reset_password', _flag),//重置密码
+ 'bindPhoneApi': httpUrlFormat('/user/bind/phone', _flag),//绑定手机号
+
+
+
+
+ 'loginXc': httpUrlFormat('/login/xiaochuan', _flag),//用户登录第三方小川
+ 'agreementDetailApi': httpUrlFormat('/misc/user/agreement/detail', _flag),//用户协议
+
+
+
+}
+export function loginXc(data) {
+ return ajaxSync({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.loginXc,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+export function smsSend(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.generateCode,
+ method: 'POST',
+ data: data
+ })
+}
+export function smsCheck(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.sms_check,
+ method: 'POST',
+ data: data
+ })
+}
+
+export function register(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.register,
+ method: 'POST',
+ data: data
+ })
+}
+export function loginCode(data) {
+ return ajaxSync({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.loginCode,
+ method: 'POST',
+ data: data
+ })
+}
+export function loginWechat(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.loginWechat,
+ method: 'POST',
+ data: data
+ })
+}
+export function loginApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.login,
+ method: 'POST',
+ data: data
+ })
+}
+export function resetPassword(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.reset_password,
+ method: 'POST',
+ data: data
+ })
+}
+export function wechatAppid(data) {
+ return ajaxSync({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.wechatAppid,
+ method: 'GET',
+ data: data
+ })
+}
+export function phoneWechat(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxSync({
+ header: headerObj,
+ url: apiUrl.phoneWechat,
+ method: 'POST',
+ data: data
+ })
+}
+export function bindPhoneApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.bindPhoneApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+export function agreementDetailApi(data) {
+ return ajaxSync({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.agreementDetailApi,
+ method: 'GET',
+ data: data
+ })
+}
diff --git a/API/order.js b/API/order.js
new file mode 100644
index 0000000..2216904
--- /dev/null
+++ b/API/order.js
@@ -0,0 +1,288 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'order': httpUrlFormat('/order', _flag),
+ 'orderPreview': httpUrlFormat('/order/preview', _flag),
+ 'orderReceive': httpUrlFormat('/order/receive', _flag),
+ 'orderList': httpUrlFormat('/order/mall_order', _flag),
+ 'boxOrder': httpUrlFormat('/order/box_order', _flag),
+ 'boxRecord': httpUrlFormat('/order/box_record', _flag),
+ 'boxOpen': httpUrlFormat('/order/box_open', _flag),
+ 'boxPickup': httpUrlFormat('/order/box_pickup', _flag),
+ 'boxRecycle': httpUrlFormat('/order/box_recycle', _flag),
+ 'boxInfo': httpUrlFormat('/order/box_info', _flag),
+ 'orderCancel': httpUrlFormat('/order/cancel', _flag),
+ 'boxOpenByBoxId': httpUrlFormat('/order/box_open_by_box_id', _flag),
+ 'orderRefundApi': httpUrlFormat('/order/refund', _flag),
+
+
+
+
+ 'channelGetApi': httpUrlFormat('/pay/channel/get', _flag),
+ 'orderReceiptApi': httpUrlFormat('/order/receipt', _flag),
+
+ 'refundTimeApi': httpUrlFormat('/misc/mall/refund/expire/time', _flag),//商品退款-过期时间
+ 'boxRefundTimeApi': httpUrlFormat('/order/box/record/expire/time', _flag),//盲盒退款-过期时间
+ 'boxRefundTimeExpiredApi': httpUrlFormat('/order/box/record/expired', _flag),//盲盒退款-过期时间
+
+}
+
+//订单预览
+export function orderPreview(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ console.log(headerObj)
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.orderPreview,
+ method: 'POST',
+ data: data
+ })
+}
+
+export function channelGetApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.channelGetApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function createShopOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.order,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+
+
+
+
+
+
+//商城订单列表
+export function orderList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.order,
+ method: 'GET',
+ data: data
+ })
+}
+// 删除订单
+export function delOrder(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.order,
+ method: 'DELETE',
+ data: data
+ })
+}
+// 取消订单
+export function orderCancel(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderCancel,
+ method: 'PUT',
+ data: data
+ })
+}
+// 确认收货
+export function orderReceive(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderReceive,
+ method: 'POST',
+ data: data
+ })
+}
+//创建商城订单
+export function createOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderList,
+ method: 'POST',
+ data: data
+ })
+}
+//盲盒订单列表
+export function boxOrderList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrder,
+ method: 'GET',
+ data: data
+ })
+}
+
+//创建盲盒订单
+export function boxCreateOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrder,
+ method: 'POST',
+ data: data
+ })
+}
+//礼盒/物品列表
+export function boxRecord(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxRecord,
+ method: 'GET',
+ data: data
+ })
+}
+//开盲盒
+export function boxOpen(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOpen,
+ method: 'POST',
+ data: data
+ })
+}
+//提取盲盒
+export function boxPickup(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxPickup,
+ method: 'POST',
+ data: data
+ })
+}
+//回收盲盒
+export function boxRecycle(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxRecycle,
+ method: 'POST',
+ data: data
+ })
+}
+// 订单详情
+export function orderDetail(no,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/order/no/${no}`, _flag),
+ method: 'GET',
+ data: data
+ })
+}
+export function orderIdDetail(id) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/box/order/${id}`, _flag),
+ method: 'GET',
+ })
+}
+export function orderDetailId(id) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/order/${id}`, _flag),
+ method: 'GET',
+ })
+}
+//盲盒详情
+export function boxInfo(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.boxInfo,
+ method: 'GET',
+ data: data
+ })
+}
+// 根据盲盒id开盒
+export function boxOpenByBoxId(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOpenByBoxId,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+
+export function orderReceiptApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderReceiptApi,
+ method: 'PUT',
+ data: data
+ })
+}
+export function orderRefundApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderRefundApi,
+ method: 'PUT',
+ data: data
+ })
+}
+
+
+// 商品退款过期时间
+export function refundTimeApi(data) {
+ return ajaxCarryAuthorization({
+ url: apiUrl.refundTimeApi,
+ method: 'GET',
+ data: data
+ })
+}
+// 盲盒退款过期时间
+export function boxRefundTimeApi(data) {
+ return ajaxCarryAuthorization({
+ url: apiUrl.boxRefundTimeApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function boxRefundTimeExpiredApi(data) {
+ return ajaxCarryAuthorization({
+ url: apiUrl.boxRefundTimeExpiredApi,
+ method: 'GET',
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/API/pay.js b/API/pay.js
new file mode 100644
index 0000000..3820450
--- /dev/null
+++ b/API/pay.js
@@ -0,0 +1,65 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'createOrderPay': httpUrlFormat('/pay/create_order', _flag),
+ 'orderPaid': httpUrlFormat('/order/box_order_paid', _flag),
+ 'orderShopPaid': httpUrlFormat('/order/order_paid', _flag),
+ 'mpScheme': httpUrlFormat('/other/wechat/mp/scheme', _flag),
+
+}
+
+export function createOrderPay(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.createOrderPay,
+ method: 'POST',
+ data: data
+ })
+}
+
+// 查询盲盒订单是否成功
+export function orderPaid(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderPaid,
+ method: 'GET',
+ data: data
+ })
+}
+// 查询商品订单是否成功
+export function orderShopPaid(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderShopPaid,
+ method: 'GET',
+ data: data
+ })
+}
+
+// https://test.06zk.com/test/pay/create_order
+
+export function mpScheme(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.mpScheme,
+ method: 'GET',
+ data
+ })
+}
\ No newline at end of file
diff --git a/API/product.js b/API/product.js
new file mode 100644
index 0000000..136bb30
--- /dev/null
+++ b/API/product.js
@@ -0,0 +1,261 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'productApi': httpUrlFormat('/product', _flag),
+ 'productTagsApi': httpUrlFormat('/product/tags', _flag),
+ 'boxesTagsApi': httpUrlFormat('/boxes/tags', _flag),
+ 'boxesApi': httpUrlFormat('/boxes', _flag),
+ 'favorItemApi': httpUrlFormat('/user/favor/item', _flag),
+ 'favorItemProductApi': httpUrlFormat('/user/favor/item/product', _flag),
+
+
+ 'orderPreview': httpUrlFormat('/order/preview', _flag),
+ 'orderReceive': httpUrlFormat('/order/receive', _flag),
+ 'orderList': httpUrlFormat('/order/mall_order', _flag),
+ 'boxOrder': httpUrlFormat('/order/box_order', _flag),
+ 'boxRecord': httpUrlFormat('/order/box_record', _flag),
+ 'boxOpen': httpUrlFormat('/order/box_open', _flag),
+ 'boxPickup': httpUrlFormat('/order/box_pickup', _flag),
+ 'boxRecycle': httpUrlFormat('/order/box_recycle', _flag),
+ 'boxInfo': httpUrlFormat('/order/box_info', _flag),
+ 'orderCancel': httpUrlFormat('/order/cancel', _flag),
+ 'boxOpenByBoxId': httpUrlFormat('/order/box_open_by_box_id', _flag),
+
+}
+
+
+
+
+//商品标签
+export function productTagsApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.productTagsApi,
+ method: 'GET',
+ data: data
+ })
+}
+//商品分页
+export function productApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.productApi,
+ method: 'GET',
+ data: data
+ })
+}
+//盲盒标签
+export function boxesTagsApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxesTagsApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+export function productDetailApi(data,header = {}) {
+ const headerObj = {...header,...headerVersion}
+ return ajaxCarryAuthorization({
+ header:headerObj,
+ url: httpUrlFormat(`/product/${data.id}`, _flag),
+ method: 'GET',
+ data: data
+ })
+}
+// 收藏
+export function favorItemApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.favorItemApi,
+ method: 'POST',
+ data: data
+ })
+}
+// 删除收藏
+export function delFavorItemApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.favorItemProductApi,
+ method: 'DELETE',
+ data: data
+ })
+}
+
+
+
+
+
+
+//商城订单列表
+export function orderList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.order,
+ method: 'GET',
+ data: data
+ })
+}
+// 删除订单
+export function delOrder(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.order,
+ method: 'DELETE',
+ data: data
+ })
+}
+// 取消订单
+export function orderCancel(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderCancel,
+ method: 'PUT',
+ data: data
+ })
+}
+// 确认收货
+export function orderReceive(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: apiUrl.orderReceive,
+ method: 'POST',
+ data: data
+ })
+}
+//创建商城订单
+export function createOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderList,
+ method: 'POST',
+ data: data
+ })
+}
+//订单预览
+export function orderPreview(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.orderPreview,
+ method: 'POST',
+ data: data
+ })
+}
+//盲盒订单列表
+export function boxOrderList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrder,
+ method: 'GET',
+ data: data
+ })
+}
+
+//创建盲盒订单
+export function boxCreateOrder(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxOrder,
+ method: 'POST',
+ data: data
+ })
+}
+//礼盒/物品列表
+export function boxRecord(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxRecord,
+ method: 'GET',
+ data: data
+ })
+}
+//开盲盒
+export function boxOpen(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ header: headerObj,
+ url: apiUrl.boxOpen,
+ method: 'POST',
+ data: data
+ })
+}
+//提取盲盒
+export function boxPickup(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxPickup,
+ method: 'POST',
+ data: data
+ })
+}
+//回收盲盒
+export function boxRecycle(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.boxRecycle,
+ method: 'POST',
+ data: data
+ })
+}
+// 订单详情
+export function orderDetail(no,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/order/${no}`, _flag),
+ method: 'GET',
+ data: data
+ })
+}
+//盲盒详情
+export function boxInfo(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.boxInfo,
+ method: 'GET',
+ data: data
+ })
+}
+// 根据盲盒id开盒
+export function boxOpenByBoxId(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.boxOpenByBoxId,
+ method: 'POST',
+ data: data
+ })
+}
diff --git a/API/ranking.js b/API/ranking.js
new file mode 100644
index 0000000..8983c3d
--- /dev/null
+++ b/API/ranking.js
@@ -0,0 +1,89 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'topStatusApi': httpUrlFormat('/top/status', _flag),
+}
+
+
+export function topUserListApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/user/list/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+export function topUserSelfApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/user/self/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+export function topStatusApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.topStatusApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+export function topUserListLastApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/user/list/last/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+export function topUserSelfLastApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/user/self/last/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+export function topRuleApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/rule/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+export function topExpiredTimeApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/expired/time/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+
+export function topDetailApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/top/${data.type}`, _flag),
+ method: 'GET',
+ data
+ })
+}
+
diff --git a/API/report.js b/API/report.js
new file mode 100644
index 0000000..1d82462
--- /dev/null
+++ b/API/report.js
@@ -0,0 +1,44 @@
+
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'reportHeartbeat': httpUrlFormat('/report/heartbeat', _flag),
+ 'reportClick': httpUrlFormat('/report/click', _flag),
+
+
+}
+
+//心跳埋点
+export function reportHeartbeatApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.reportHeartbeat,
+ method: 'POST',
+ data: data
+ })
+}
+//点击埋点
+export function reportClickApi(data) {
+ // const headerObj = {'Content-Type': 'application/x-www-form-urlencoded',...headerVersion}
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.reportClick,
+ method: 'POST',
+ data: data
+ })
+}
diff --git a/API/shop.js b/API/shop.js
new file mode 100644
index 0000000..345180c
--- /dev/null
+++ b/API/shop.js
@@ -0,0 +1,232 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'product': httpUrlFormat('/product', _flag),//商品分页
+ 'categories': httpUrlFormat('/product/categories', _flag),//商品分类
+ 'rollingImgs': httpUrlFormat('/rolling_imgs', _flag),//商品分类
+ 'favorItem': httpUrlFormat('/user/favor_item', _flag),//收藏
+ 'deliveryFee': httpUrlFormat('/product/delivery_fee', _flag),//运费
+ 'favorItemProduct': httpUrlFormat('/user/favor_item_product', _flag),//运费
+ 'searchHistoryRecommend': httpUrlFormat('/search_history/recommend', _flag),//搜索推荐
+ 'searchHistoryPersonal': httpUrlFormat('/search/history/personal', _flag),//搜索推荐
+ 'orderBoxRecordCount': httpUrlFormat('/order/box_record_count', _flag),//盲盒统计
+ 'carriageRule': httpUrlFormat('/misc/carriage/rule', _flag),
+ 'carriageGetRule': httpUrlFormat('/misc/carriage/get', _flag),
+ 'tagsChannelApi': httpUrlFormat('/product/tags/channel', _flag),
+ 'productChannelApi': httpUrlFormat('/product/channel', _flag),
+ 'productRecommendChannel': httpUrlFormat('/product/product/recommend/channel', _flag),
+ 'productChannelPointApi': httpUrlFormat('/product/channel/points', _flag),
+
+ 'tagsPointApi': httpUrlFormat('/misc/product/points/tag', _flag),
+
+}
+
+
+// 渠道商品tag
+export function tagsChannelApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.tagsChannelApi,
+ method: 'GET',
+ data: data
+ })
+}
+// 渠道商品
+export function productChannelApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.productChannelApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+export function productRecommendChannel(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.productRecommendChannel,
+ method: 'GET',
+ data: data
+ })
+}
+
+// 渠道商品积分筛选
+export function productChannelPointApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.productChannelPointApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+// 运费
+export function deliveryFee() {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.deliveryFee,
+ method: 'GET',
+ })
+}
+export function product(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.product,
+ method: 'GET',
+ data: data
+ })
+}
+// 商品分类
+export function categories(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.categories,
+ method: 'GET',
+ data: data
+ })
+}
+// 商品详情
+export function productDetail(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/product/${data}`, _flag),
+ method: 'GET',
+ })
+}
+// 商城轮播
+export function rollingImgs(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.rollingImgs,
+ method: 'GET',
+ })
+}
+// 收藏列表
+export function favorItemList(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.favorItem,
+ method: 'GET',
+ data
+ })
+}
+// 收藏
+export function favorItem(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.favorItem,
+ method: 'POST',
+ data
+ })
+}
+
+// 删除收藏
+export function delFavorItem(ids) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: httpUrlFormat(`/user/favor_item${ids}`, _flag),
+ method: 'DELETE'
+ })
+}
+// 删除商品详情收藏
+export function favorItemProduct(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // url: apiUrl.cart_item,
+ url: httpUrlFormat(`/user/favor_item_product${data}`, _flag),
+ method: 'DELETE',
+ // data: data
+ })
+}
+// 搜索推荐
+export function searchHistoryRecommend(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.searchHistoryRecommend,
+ method: 'GET',
+ data
+ })
+}
+// 搜索历史
+export function searchHistoryPersonal(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.searchHistoryPersonal,
+ method: 'GET',
+ data
+ })
+}
+// 删除搜索历史
+export function delSearchHistoryPersonal() {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.searchHistoryPersonal,
+ method: 'DELETE',
+ })
+}
+// 盲盒统计
+export function orderBoxRecordCount(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.orderBoxRecordCount,
+ method: 'GET',
+ data
+ })
+}
+export function carriageRule(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.carriageRule,
+ method: 'GET',
+ data
+ })
+}
+export function carriageGetRule(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.carriageGetRule,
+ method: 'GET',
+ data
+ })
+}
+
+export function tagsPointApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.tagsPointApi,
+ method: 'GET',
+ data
+ })
+}
+
diff --git a/API/sign.js b/API/sign.js
new file mode 100644
index 0000000..a7591b1
--- /dev/null
+++ b/API/sign.js
@@ -0,0 +1,57 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'signInInfo': httpUrlFormat('/user/sign/in/info', _flag),//用户签到信息
+ 'signIn': httpUrlFormat('/user/sign/in', _flag),//用户签到
+ 'taskList': httpUrlFormat('/task/list', _flag),//任务列表
+
+
+}
+
+export function signInInfo(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.signInInfo,
+ method: 'GET',
+ data: data
+ })
+}
+export function signIn(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.signIn,
+ method: 'POST',
+ data
+ })
+}
+export function taskListApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: apiUrl.taskList,
+ method: 'GET',
+ data: data
+ })
+}
+export function taskReceive(taskId) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/task/receive/${taskId}`, _flag),
+ method: 'POST',
+ })
+}
\ No newline at end of file
diff --git a/API/user.js b/API/user.js
new file mode 100644
index 0000000..2b92bd9
--- /dev/null
+++ b/API/user.js
@@ -0,0 +1,393 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'userInfo': httpUrlFormat('/user/info', _flag),//用户信息
+ 'userPoint': httpUrlFormat('/user/point', _flag),//
+ 'favorItemApi': httpUrlFormat('/user/favor/item', _flag),//
+ 'userAddress': httpUrlFormat('/user/address', _flag),//收获地址
+ 'boxCount': httpUrlFormat('/user/box_count', _flag),//
+ 'notice': httpUrlFormat('/misc/notice', _flag),//公告
+ 'noticeTopApi': httpUrlFormat('/misc/notice/top', _flag),//置顶公告
+ 'uploadToken': httpUrlFormat('/user/upload_token', _flag),//上传oss凭证
+ 'feedback': httpUrlFormat('/user/feedback', _flag),//意见反馈
+ 'customer': httpUrlFormat('/misc/customer', _flag),//
+ 'popupAdApi': httpUrlFormat('/misc/popup/ad', _flag),//
+ 'couponApi': httpUrlFormat('/coupon', _flag),//优惠券
+ 'userCouponApi': httpUrlFormat('/user/conpon', _flag),//用户优惠券
+ 'userCouponBatchApi': httpUrlFormat('/user/conpon/reward/batch', _flag),//用户优惠券
+
+ 'userCouponRewardApi': httpUrlFormat('/user/conpon/reward', _flag),//兑换优惠券
+ 'coinGearApi': httpUrlFormat('/coin/gear', _flag),//代币充值
+ 'coinGearRechargeApi': httpUrlFormat('/coin/gear/recharge', _flag),//代币充值订单
+ 'payMethodApi': httpUrlFormat('/misc/pay/method', _flag),//获取支付方式
+ 'coinPaidApi': httpUrlFormat('/coin/gear/recharge/paid', _flag),//
+ 'couponCountApi': httpUrlFormat('/user/coupon/count', _flag),//
+ 'miscPromptApi': httpUrlFormat('/misc/prompt', _flag),//
+ 'shareApi': httpUrlFormat('/misc/build/share', _flag),//
+ 'updateNickNameApi': httpUrlFormat('/user/update/nickname', _flag),//更新用户昵称
+
+
+
+
+ 'recordCountApi': httpUrlFormat('/user/box/record/count', _flag),//用户盲盒开奖结果数量
+ 'aliyunUploadTokenApi': httpUrlFormat('/misc/aliyun_upload_token', _flag),//获取oss上传凭证
+ 'updateAvatarApi': httpUrlFormat('/user/update/avatar', _flag),//更新头像
+ 'versionControlApi': httpUrlFormat('/misc/version/control', _flag),//版本控制
+ 'userPromptListApi': httpUrlFormat('/user/prompt', _flag),//版本控制
+
+
+
+
+
+
+}
+
+// 更新用户昵称
+export function updateNickNameApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.updateNickNameApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function favorItemDelApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.favorItemApi,
+ method: 'DELETE',
+ data: data
+ })
+}
+export function favorItemApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.favorItemApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function recordCountApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.recordCountApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+export function userPoint(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.userPoint,
+ method: 'GET',
+ data: data
+ })
+}
+
+
+
+export function userInfo(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.userInfo,
+ method: 'GET',
+ data: data
+ })
+}
+// 收货地址列表
+export function userAddress(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.userAddress,
+ method: 'GET',
+ data: data
+ })
+}
+// 新增收货地址
+export function addAddress(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.userAddress,
+ method: 'POST',
+ data: data
+ })
+}
+// 收货地址详情
+export function addressDetail(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/user/address/${data}`, _flag),
+ method: 'GET',
+ })
+}
+// 编辑收货地址
+export function editAddress(id,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/user/address/${id}`, _flag),
+ method: 'PUT',
+ data: data
+ })
+}
+
+// 删除地址
+export function delAddress(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/user/address?ids=${data.id}`, _flag),
+ method: 'DELETE',
+ data,data
+ })
+}
+
+// 礼盒物品数量
+export function boxCount(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.boxCount,
+ method: 'GET',
+ })
+}
+// 系统公告
+export function notice(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.notice,
+ method: 'GET',
+ data,data
+ })
+}
+// 系统公告详情
+export function noticeDetail(id,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/misc/notice/${id}`, _flag),
+ method: 'GET',
+ data,data
+ })
+}
+// 系统公告详情
+export function uploadToken(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.uploadToken,
+ method: 'GET',
+ data,data
+ })
+}
+// 意见反馈
+export function feedback(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.feedback,
+ method: 'POST',
+ data,data
+ })
+}
+export function customerApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.customer,
+ method: 'GET',
+ data,data
+ })
+}
+export function noticeTopApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.noticeTopApi,
+ method: 'GET',
+ data
+ })
+}
+export function popupAdApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.popupAdApi,
+ method: 'GET',
+ data
+ })
+}
+
+export function couponApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.couponApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+export function userCouponApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.userCouponApi,
+ method: 'GET',
+ data
+ })
+}
+export function userCouponRewardApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.userCouponRewardApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+
+export function coinGearApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.coinGearApi,
+ method: 'GET',
+ data
+ })
+}
+export function payMethodApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.payMethodApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+export function coinGearRechargeApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.coinGearRechargeApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function coinPaidApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.coinPaidApi,
+ method: 'GET',
+ data
+ })
+}
+
+export function userCouponBatchApi(userId,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: httpUrlFormat(`/user/conpon/reward/batch?userId=${userId}`, _flag),
+ method: 'POST',
+ data: data
+ })
+}
+export function couponCountApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.couponCountApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function miscPromptApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.miscPromptApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function shareApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.shareApi,
+ method: 'GET',
+ data: data
+ })
+}
+export function aliyunUploadTokenApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.aliyunUploadTokenApi,
+ method: 'GET',
+ data
+ })
+}
+
+
+export function updateAvatarApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.updateAvatarApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+export function versionControlApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.versionControlApi,
+ method: 'POST',
+ data
+ })
+}
+
+export function userPromptListApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.userPromptListApi,
+ method: 'GET',
+ data
+ })
+}
+
diff --git a/API/virtual.js b/API/virtual.js
new file mode 100644
index 0000000..38c581a
--- /dev/null
+++ b/API/virtual.js
@@ -0,0 +1,95 @@
+import {
+ httpUrlFormat,
+ ajaxCarryAuthorization,ajaxSync
+} from '@/utils/httpUtils.js'
+
+import { ApiVersion,AppVersion } from '@/config/baseConfig.js'
+
+const headerVersion = {
+ 'API-Version': ApiVersion(),
+ 'APP-Version':AppVersion()
+}
+
+const _flag = 'apiBaseUrl' // 请求的api空间
+
+const apiUrl = {
+ 'virtualOrderPreviewApi': httpUrlFormat('/virtual/order/preview', _flag),//商城订单预览
+ 'virtualOrderBoxPreviewApi': httpUrlFormat('/virtual/order/box/delivery/preview', _flag),//盲盒订单预览
+ 'virtualOrderApi': httpUrlFormat('/virtual/order/box/delivery', _flag),
+ 'virtualOrderPaidApi': httpUrlFormat('/virtual/order/paid', _flag),
+ 'virtualOrderListApi': httpUrlFormat('/virtual/order', _flag),
+}
+
+
+export function virtualShopOrderApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.virtualOrderListApi,
+ method: 'POST',
+ data
+ })
+}
+export function virtualOrderPreviewApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.virtualOrderPreviewApi,
+ method: 'POST',
+ data: data
+ })
+}
+export function virtualOrderBoxPreviewApi(data) {
+ const headerObj = {...headerVersion,'Content-Type': 'application/x-www-form-urlencoded'}
+ return ajaxCarryAuthorization({
+ header: headerObj,
+ url: apiUrl.virtualOrderBoxPreviewApi,
+ method: 'POST',
+ data: data
+ })
+}
+
+// 创建订单
+export function virtualOrderApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.virtualOrderApi,
+ method: 'POST',
+ data
+ })
+}
+export function virtualOrderPaidApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.virtualOrderPaidApi,
+ method: 'GET',
+ data
+ })
+}
+export function virtualOrderListApi(data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ // header: {'Content-Type': 'application/x-www-form-urlencoded'},
+ url: apiUrl.virtualOrderListApi,
+ method: 'GET',
+ data: data
+ })
+}
+
+export function virtualOrderDetailId(id) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/virtual/order/${id}`, _flag),
+ method: 'GET',
+ })
+}
+export function virtualOrderDetail(no,data) {
+ return ajaxCarryAuthorization({
+ header: headerVersion,
+ url: httpUrlFormat(`/virtual/order/no/${no}`, _flag),
+ method: 'GET',
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..4d64b6b
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,84 @@
+
+
+
diff --git a/Dockerfile b/Dockerfile
new file mode 100755
index 0000000..50c0882
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,3 @@
+FROM nginx
+EXPOSE 80
+COPY /unpackage/dist/build/h5 /usr/share/nginx/html
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..83ee196
--- /dev/null
+++ b/README.md
@@ -0,0 +1,48 @@
+# 盲盒H5基础版
+## 登录
+```bash
+ 1.登录页面('账号密码登录、验证码登录')
+```
+
+
+## 首页
+```bash
+ 1.对接首页盲盒
+ 2.盲盒标签以及标签下的盲盒
+ 3.盲盒搜索
+ 4.对接置顶公告
+ 5.广告弹窗、轮播
+ 7.对接盲盒详情
+ 8.提示卡('页面完成没有对接功能')
+ 9.购买盲盒订单预览页面
+ 10.支付('暂未对接支付通道')、购买成功页面
+ 11.开奖页面('暂无动画')
+```
+## 商城
+```bash
+ 1.商场首页('轮播未完成')
+ 2.商场搜索,搜索历史
+ 3.商品详情
+ 4.商品收藏/取消收藏
+ 5.购买提交订单
+ 6.购买成功页
+```
+## 签到
+```bash
+ 1.页面完成 暂未对接
+```
+
+
+## 个人中心
+```bash
+ 1.个人中心已完成
+ 2.设置页面('更换头像、修改昵称、关于我们暂未对接')
+ 3.隐私政策、用户协议页面完成 暂未更新内容
+ 4.优惠券、更多优惠券页面完成 暂未对接
+ 5.积分使用记录已完成
+ 6.物品页面完成 发货 回收接口已完成('发货回收接口需改成批量 页面已完成暂未对接')
+ 7.订单详情已完成(订单详情、确认收货、查看物流)
+ 8.盲盒订单已完成
+ 9.地址管理已完成(新增地址、设置默认地址)
+ 10.我的收藏已完成(取消收藏)
+```
diff --git a/components/ai-progress/ai-progress.vue b/components/ai-progress/ai-progress.vue
new file mode 100644
index 0000000..d47b45e
--- /dev/null
+++ b/components/ai-progress/ai-progress.vue
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+ {{ percentage }}%
+
+
+
+
+ {{ percentage }}%
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/bottom-fixed/bottom-fixed.vue b/components/bottom-fixed/bottom-fixed.vue
new file mode 100644
index 0000000..68a7ee8
--- /dev/null
+++ b/components/bottom-fixed/bottom-fixed.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/code-elf-guide/code-elf-guide.vue b/components/code-elf-guide/code-elf-guide.vue
new file mode 100644
index 0000000..012b72e
--- /dev/null
+++ b/components/code-elf-guide/code-elf-guide.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+ {{ item.dec }}
+
+
+
+ {{ experience }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/custom-radio-item/custom-radio-item.vue b/components/custom-radio-item/custom-radio-item.vue
new file mode 100644
index 0000000..d1a4cf4
--- /dev/null
+++ b/components/custom-radio-item/custom-radio-item.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ {{ radioTitle }}
+
+
+
+
+
+
+
diff --git a/components/empty/empty.vue b/components/empty/empty.vue
new file mode 100644
index 0000000..ee547d8
--- /dev/null
+++ b/components/empty/empty.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
diff --git a/components/icon-view/icon-view.vue b/components/icon-view/icon-view.vue
new file mode 100644
index 0000000..72a6212
--- /dev/null
+++ b/components/icon-view/icon-view.vue
@@ -0,0 +1,269 @@
+
+
+
+
+ {{label}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/icon-view/iconfont.css b/components/icon-view/iconfont.css
new file mode 100644
index 0000000..f8d929a
--- /dev/null
+++ b/components/icon-view/iconfont.css
@@ -0,0 +1,897 @@
+/* #ifdef APP-PLUS */
+@font-face {
+ font-family: "uicon-iconfont";
+ font-weight: normal;
+ font-style: normal;
+ font-display: auto;
+ src: url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2');
+}
+
+/* #endif */
+
+/* 支付宝,百度,头条小程序目前读取大的本地字体文件,导致无法显示图标,故用在线加载的方式-2020-05-12 */
+/* #ifndef APP-PLUS */
+@font-face {font-family: "uicon-iconfont";
+ src: url('//at.alicdn.com/t/font_1529455_adug8z8qzbi.eot?t=1595859460686'); /* IE9 */
+ src: url('//at.alicdn.com/t/font_1529455_adug8z8qzbi.eot?t=1595859460686#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
+ url('//at.alicdn.com/t/font_1529455_adug8z8qzbi.woff?t=1595859460686') format('woff'),
+ url('//at.alicdn.com/t/font_1529455_adug8z8qzbi.ttf?t=1595859460686') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
+ url('//at.alicdn.com/t/font_1529455_adug8z8qzbi.svg?t=1595859460686#iconfont') format('svg'); /* iOS 4.1- */
+}
+/* #endif */
+
+.u-iconfont {
+ position: relative;
+ display: flex;
+ font: normal normal normal 14px/1 "uicon-iconfont";
+ font-size: inherit;
+ text-rendering: auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.u-iconfont::before {
+ display: flex;
+ align-items: center;
+}
+
+.uicon-level:before {
+ content: "\e693";
+}
+
+.uicon-woman:before {
+ content: "\e69c";
+}
+
+.uicon-man:before {
+ content: "\e697";
+}
+
+.uicon-column-line:before {
+ content: "\e68e";
+}
+
+.uicon-empty-page:before {
+ content: "\e627";
+}
+
+.uicon-empty-data:before {
+ content: "\e62f";
+}
+
+.uicon-empty-car:before {
+ content: "\e602";
+}
+
+.uicon-empty-order:before {
+ content: "\e639";
+}
+
+.uicon-empty-address:before {
+ content: "\e646";
+}
+
+.uicon-empty-message:before {
+ content: "\e6a9";
+}
+
+.uicon-empty-search:before {
+ content: "\e664";
+}
+
+.uicon-empty-favor:before {
+ content: "\e67c";
+}
+
+.uicon-empty-coupon:before {
+ content: "\e682";
+}
+
+.uicon-empty-history:before {
+ content: "\e684";
+}
+
+.uicon-empty-permission:before {
+ content: "\e686";
+}
+
+.uicon-empty-news:before {
+ content: "\e687";
+}
+
+.uicon-empty-wifi:before {
+ content: "\e688";
+}
+
+.uicon-empty-list:before {
+ content: "\e68b";
+}
+
+.uicon-arrow-left-double:before {
+ content: "\e68c";
+}
+
+.uicon-arrow-right-double:before {
+ content: "\e68d";
+}
+
+.uicon-red-packet:before {
+ content: "\e691";
+}
+
+.uicon-red-packet-fill:before {
+ content: "\e690";
+}
+
+.uicon-order:before {
+ content: "\e68f";
+}
+
+.uicon-nav-back-arrow:before {
+ content: "\e67f";
+}
+
+.uicon-nav-back:before {
+ content: "\e683";
+}
+
+.uicon-checkbox-mark:before {
+ content: "\e6a8";
+}
+
+.uicon-arrow-up-fill:before {
+ content: "\e6b0";
+}
+
+.uicon-arrow-down-fill:before {
+ content: "\e600";
+}
+
+.uicon-backspace:before {
+ content: "\e67b";
+}
+
+.uicon-android-circle-fill:before {
+ content: "\e67e";
+}
+
+.uicon-android-fill:before {
+ content: "\e67d";
+}
+
+.uicon-question:before {
+ content: "\e715";
+}
+
+.uicon-pause:before {
+ content: "\e8fa";
+}
+
+.uicon-close:before {
+ content: "\e685";
+}
+
+.uicon-volume-up:before {
+ content: "\e633";
+}
+
+.uicon-volume-off:before {
+ content: "\e644";
+}
+
+.uicon-info:before {
+ content: "\e653";
+}
+
+.uicon-error:before {
+ content: "\e6d3";
+}
+
+.uicon-lock-opened-fill:before {
+ content: "\e974";
+}
+
+.uicon-lock-fill:before {
+ content: "\e979";
+}
+
+.uicon-lock:before {
+ content: "\e97a";
+}
+
+.uicon-photo-fill:before {
+ content: "\e98b";
+}
+
+.uicon-photo:before {
+ content: "\e98d";
+}
+
+.uicon-account-fill:before {
+ content: "\e614";
+}
+
+.uicon-minus-people-fill:before {
+ content: "\e615";
+}
+
+.uicon-plus-people-fill:before {
+ content: "\e626";
+}
+
+.uicon-account:before {
+ content: "\e628";
+}
+
+.uicon-thumb-down-fill:before {
+ content: "\e726";
+}
+
+.uicon-thumb-down:before {
+ content: "\e727";
+}
+
+.uicon-thumb-up-fill:before {
+ content: "\e72f";
+}
+
+.uicon-thumb-up:before {
+ content: "\e733";
+}
+
+.uicon-person-delete-fill:before {
+ content: "\e66a";
+}
+
+.uicon-cut:before {
+ content: "\e948";
+}
+
+.uicon-fingerprint:before {
+ content: "\e955";
+}
+
+.uicon-home-fill:before {
+ content: "\e964";
+}
+
+.uicon-home:before {
+ content: "\e965";
+}
+
+.uicon-hourglass-half-fill:before {
+ content: "\e966";
+}
+
+.uicon-hourglass:before {
+ content: "\e967";
+}
+
+.uicon-lock-open:before {
+ content: "\e973";
+}
+
+.uicon-integral-fill:before {
+ content: "\e703";
+}
+
+.uicon-integral:before {
+ content: "\e704";
+}
+
+.uicon-coupon:before {
+ content: "\e8ae";
+}
+
+.uicon-coupon-fill:before {
+ content: "\e8c4";
+}
+
+.uicon-kefu-ermai:before {
+ content: "\e656";
+}
+
+.uicon-scan:before {
+ content: "\e662";
+}
+
+.uicon-rmb:before {
+ content: "\e608";
+}
+
+.uicon-rmb-circle-fill:before {
+ content: "\e657";
+}
+
+.uicon-rmb-circle:before {
+ content: "\e677";
+}
+
+.uicon-gift:before {
+ content: "\e65b";
+}
+
+.uicon-gift-fill:before {
+ content: "\e65c";
+}
+
+.uicon-bookmark-fill:before {
+ content: "\e63b";
+}
+
+.uicon-zhuanfa:before {
+ content: "\e60b";
+}
+
+.uicon-eye-off-outline:before {
+ content: "\e62b";
+}
+
+.uicon-eye-off:before {
+ content: "\e648";
+}
+
+.uicon-pause-circle:before {
+ content: "\e643";
+}
+
+.uicon-play-circle:before {
+ content: "\e647";
+}
+
+.uicon-pause-circle-fill:before {
+ content: "\e654";
+}
+
+.uicon-play-circle-fill:before {
+ content: "\e655";
+}
+
+.uicon-grid:before {
+ content: "\e673";
+}
+
+.uicon-play-right:before {
+ content: "\e610";
+}
+
+.uicon-play-left:before {
+ content: "\e66d";
+}
+
+.uicon-calendar:before {
+ content: "\e66e";
+}
+
+.uicon-rewind-right:before {
+ content: "\e66f";
+}
+
+.uicon-rewind-left:before {
+ content: "\e671";
+}
+
+.uicon-skip-forward-right:before {
+ content: "\e672";
+}
+
+.uicon-skip-back-left:before {
+ content: "\e674";
+}
+
+.uicon-play-left-fill:before {
+ content: "\e675";
+}
+
+.uicon-play-right-fill:before {
+ content: "\e676";
+}
+
+.uicon-grid-fill:before {
+ content: "\e678";
+}
+
+.uicon-rewind-left-fill:before {
+ content: "\e679";
+}
+
+.uicon-rewind-right-fill:before {
+ content: "\e67a";
+}
+
+.uicon-pushpin:before {
+ content: "\e7e3";
+}
+
+.uicon-star:before {
+ content: "\e65f";
+}
+
+.uicon-star-fill:before {
+ content: "\e669";
+}
+
+.uicon-server-fill:before {
+ content: "\e751";
+}
+
+.uicon-server-man:before {
+ content: "\e6bc";
+}
+
+.uicon-edit-pen:before {
+ content: "\e612";
+}
+
+.uicon-edit-pen-fill:before {
+ content: "\e66b";
+}
+
+.uicon-wifi:before {
+ content: "\e667";
+}
+
+.uicon-wifi-off:before {
+ content: "\e668";
+}
+
+.uicon-file-text:before {
+ content: "\e663";
+}
+
+.uicon-file-text-fill:before {
+ content: "\e665";
+}
+
+.uicon-more-dot-fill:before {
+ content: "\e630";
+}
+
+.uicon-minus:before {
+ content: "\e618";
+}
+
+.uicon-minus-circle:before {
+ content: "\e61b";
+}
+
+.uicon-plus:before {
+ content: "\e62d";
+}
+
+.uicon-plus-circle:before {
+ content: "\e62e";
+}
+
+.uicon-minus-circle-fill:before {
+ content: "\e652";
+}
+
+.uicon-plus-circle-fill:before {
+ content: "\e661";
+}
+
+.uicon-email:before {
+ content: "\e611";
+}
+
+.uicon-email-fill:before {
+ content: "\e642";
+}
+
+.uicon-phone:before {
+ content: "\e622";
+}
+
+.uicon-phone-fill:before {
+ content: "\e64f";
+}
+
+.uicon-clock:before {
+ content: "\e60f";
+}
+
+.uicon-car:before {
+ content: "\e60c";
+}
+
+.uicon-car-fill:before {
+ content: "\e636";
+}
+
+.uicon-warning:before {
+ content: "\e694";
+}
+
+.uicon-warning-fill:before {
+ content: "\e64d";
+}
+
+.uicon-search:before {
+ content: "\e62a";
+}
+
+.uicon-baidu-circle-fill:before {
+ content: "\e680";
+}
+
+.uicon-baidu:before {
+ content: "\e681";
+}
+
+.uicon-facebook:before {
+ content: "\e689";
+}
+
+.uicon-facebook-circle-fill:before {
+ content: "\e68a";
+}
+
+.uicon-qzone:before {
+ content: "\e695";
+}
+
+.uicon-qzone-circle-fill:before {
+ content: "\e696";
+}
+
+.uicon-moments-circel-fill:before {
+ content: "\e69a";
+}
+
+.uicon-moments:before {
+ content: "\e69b";
+}
+
+.uicon-qq-circle-fill:before {
+ content: "\e6a0";
+}
+
+.uicon-qq-fill:before {
+ content: "\e6a1";
+}
+
+.uicon-weibo:before {
+ content: "\e6a4";
+}
+
+.uicon-weibo-circle-fill:before {
+ content: "\e6a5";
+}
+
+.uicon-taobao:before {
+ content: "\e6a6";
+}
+
+.uicon-taobao-circle-fill:before {
+ content: "\e6a7";
+}
+
+.uicon-twitter:before {
+ content: "\e6aa";
+}
+
+.uicon-twitter-circle-fill:before {
+ content: "\e6ab";
+}
+
+.uicon-weixin-circle-fill:before {
+ content: "\e6b1";
+}
+
+.uicon-weixin-fill:before {
+ content: "\e6b2";
+}
+
+.uicon-zhifubao-circle-fill:before {
+ content: "\e6b8";
+}
+
+.uicon-zhifubao:before {
+ content: "\e6b9";
+}
+
+.uicon-zhihu:before {
+ content: "\e6ba";
+}
+
+.uicon-zhihu-circle-fill:before {
+ content: "\e709";
+}
+
+.uicon-list:before {
+ content: "\e650";
+}
+
+.uicon-list-dot:before {
+ content: "\e616";
+}
+
+.uicon-setting:before {
+ content: "\e61f";
+}
+
+.uicon-bell:before {
+ content: "\e609";
+}
+
+.uicon-bell-fill:before {
+ content: "\e640";
+}
+
+.uicon-attach:before {
+ content: "\e632";
+}
+
+.uicon-shopping-cart:before {
+ content: "\e621";
+}
+
+.uicon-shopping-cart-fill:before {
+ content: "\e65d";
+}
+
+.uicon-tags:before {
+ content: "\e629";
+}
+
+.uicon-share:before {
+ content: "\e631";
+}
+
+.uicon-question-circle-fill:before {
+ content: "\e666";
+}
+
+.uicon-question-circle:before {
+ content: "\e625";
+}
+
+.uicon-error-circle:before {
+ content: "\e624";
+}
+
+.uicon-checkmark-circle:before {
+ content: "\e63d";
+}
+
+.uicon-close-circle:before {
+ content: "\e63f";
+}
+
+.uicon-info-circle:before {
+ content: "\e660";
+}
+
+.uicon-md-person-add:before {
+ content: "\e6e4";
+}
+
+.uicon-md-person-fill:before {
+ content: "\e6ea";
+}
+
+.uicon-bag-fill:before {
+ content: "\e617";
+}
+
+.uicon-bag:before {
+ content: "\e619";
+}
+
+.uicon-chat-fill:before {
+ content: "\e61e";
+}
+
+.uicon-chat:before {
+ content: "\e620";
+}
+
+.uicon-more-circle:before {
+ content: "\e63e";
+}
+
+.uicon-more-circle-fill:before {
+ content: "\e645";
+}
+
+.uicon-volume:before {
+ content: "\e66c";
+}
+
+.uicon-volume-fill:before {
+ content: "\e670";
+}
+
+.uicon-reload:before {
+ content: "\e788";
+}
+
+.uicon-camera:before {
+ content: "\e7d7";
+}
+
+.uicon-heart:before {
+ content: "\e7df";
+}
+
+.uicon-heart-fill:before {
+ content: "\e851";
+}
+
+.uicon-minus-square-fill:before {
+ content: "\e855";
+}
+
+.uicon-plus-square-fill:before {
+ content: "\e856";
+}
+
+.uicon-pushpin-fill:before {
+ content: "\e86e";
+}
+
+.uicon-camera-fill:before {
+ content: "\e870";
+}
+
+.uicon-setting-fill:before {
+ content: "\e872";
+}
+
+.uicon-google:before {
+ content: "\e87a";
+}
+
+.uicon-ie:before {
+ content: "\e87b";
+}
+
+.uicon-apple-fill:before {
+ content: "\e881";
+}
+
+.uicon-chrome-circle-fill:before {
+ content: "\e885";
+}
+
+.uicon-github-circle-fill:before {
+ content: "\e887";
+}
+
+.uicon-IE-circle-fill:before {
+ content: "\e889";
+}
+
+.uicon-google-circle-fill:before {
+ content: "\e88a";
+}
+
+.uicon-arrow-down:before {
+ content: "\e60d";
+}
+
+.uicon-arrow-left:before {
+ content: "\e60e";
+}
+
+.uicon-map:before {
+ content: "\e61d";
+}
+
+.uicon-man-add-fill:before {
+ content: "\e64c";
+}
+
+.uicon-tags-fill:before {
+ content: "\e651";
+}
+
+.uicon-arrow-leftward:before {
+ content: "\e601";
+}
+
+.uicon-arrow-rightward:before {
+ content: "\e603";
+}
+
+.uicon-arrow-downward:before {
+ content: "\e604";
+}
+
+.uicon-arrow-right:before {
+ content: "\e605";
+}
+
+.uicon-arrow-up:before {
+ content: "\e606";
+}
+
+.uicon-arrow-upward:before {
+ content: "\e607";
+}
+
+.uicon-bookmark:before {
+ content: "\e60a";
+}
+
+.uicon-eye:before {
+ content: "\e613";
+}
+
+.uicon-man-delete:before {
+ content: "\e61a";
+}
+
+.uicon-man-add:before {
+ content: "\e61c";
+}
+
+.uicon-trash:before {
+ content: "\e623";
+}
+
+.uicon-error-circle-fill:before {
+ content: "\e62c";
+}
+
+.uicon-calendar-fill:before {
+ content: "\e634";
+}
+
+.uicon-checkmark-circle-fill:before {
+ content: "\e635";
+}
+
+.uicon-close-circle-fill:before {
+ content: "\e637";
+}
+
+.uicon-clock-fill:before {
+ content: "\e638";
+}
+
+.uicon-checkmark:before {
+ content: "\e63a";
+}
+
+.uicon-download:before {
+ content: "\e63c";
+}
+
+.uicon-eye-fill:before {
+ content: "\e641";
+}
+
+.uicon-mic-off:before {
+ content: "\e649";
+}
+
+.uicon-mic:before {
+ content: "\e64a";
+}
+
+.uicon-info-circle-fill:before {
+ content: "\e64b";
+}
+
+.uicon-map-fill:before {
+ content: "\e64e";
+}
+
+.uicon-trash-fill:before {
+ content: "\e658";
+}
+
+.uicon-volume-off-fill:before {
+ content: "\e659";
+}
+
+.uicon-volume-up-fill:before {
+ content: "\e65a";
+}
+
+.uicon-share-fill:before {
+ content: "\e65e";
+}
\ No newline at end of file
diff --git a/components/index-entrance/index-entrance.vue b/components/index-entrance/index-entrance.vue
new file mode 100644
index 0000000..ac95407
--- /dev/null
+++ b/components/index-entrance/index-entrance.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+ {{ v[titleKey] }}
+
+
+
+
+
+
+
+
diff --git a/components/lb-picker/README.md b/components/lb-picker/README.md
new file mode 100644
index 0000000..5366935
--- /dev/null
+++ b/components/lb-picker/README.md
@@ -0,0 +1,434 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+插件市场里面的 picker 选择器不满足自己的需求,所以自己写了一个简单的 picker 选择器,可扩展、可自定义,一般满足日常需要。
+Github:[uni-lb-picker](https://github.com/liub1934/uni-lb-picker)
+插件市场:[uni-lb-picker](https://ext.dcloud.net.cn/plugin?id=1111)
+
+> 如果问题最好去 github 反馈,插件市场评论区留下五星好评即可,[点我去反馈](https://github.com/liub1934/uni-lb-picker/issues/new)
+
+> **由于之前`cancel`拼写失误,写成了`cancle`,`v1.08`现已修正,如果之前版本有使用`cancel`事件的,更新后请及时修正。**
+
+## 兼容性
+
+App + H5 + 各平台小程序(快应用及 360 未测试,nvue 待支持)
+
+## 功能
+
+1、单选
+2、多级联动,非多级联动,理论支持任意级数
+3、省市区选择,基于多级联动
+4、自定义选择器头部确定取消按钮颜色及插槽支持
+5、选择器可视区自定义滚动个数
+6、自定义数据字段,满足不同人的需求
+7、自定义选择器样式
+8、单选及非联动选择支持扁平化的简单数据,如下形式:
+
+```javascript
+// 单选列表
+list1: ['选项1', '选项2', '选项2'],
+// 非联动选择列表
+list2: [
+ ['选项1', '选项2', '选项3'],
+ ['选项11', '选项22', '选项33'],
+ ['选项111', '选项222', '选项333']
+]
+```
+
+## 引入插件
+
+单独引入,在需要使用的页面上 import 引入即可
+
+```html
+
+
+
+
+
+
+
+```
+
+全局引入,`main.js`中 import 引入并注册即可全局使用
+
+```jsvascript
+import LbPicker from '@/components/lb-picker'
+Vue.component("lb-picker", LbPicker)
+```
+
+easycom 引入
+
+`pages.json`加上如下配置:
+
+```json
+"easycom": {
+ "autoscan": true,
+ "custom": {
+ "lb-picker": "@/components/lb-picker/index.vue"
+ }
+}
+```
+
+npm 安装引入:
+
+```shell
+npm install uni-lb-picker
+```
+
+```jsvascript
+import LbPicker from 'uni-lb-picker'
+```
+
+## 选择器数据格式
+
+### 单选
+
+常规数据
+
+```javascript
+list: [
+ {
+ label: '选项1',
+ value: '1'
+ },
+ {
+ label: '选项2',
+ value: '2'
+ }
+]
+```
+
+扁平化简单数据
+
+```javascript
+list: ['选项1', '选项2']
+```
+
+### 多级联动
+
+```javascript
+list: [
+ {
+ label: '选项1',
+ value: '1',
+ children: [
+ {
+ label: '选项1-1',
+ value: '1-1',
+ children: [
+ {
+ label: '选项1-1-1',
+ value: '1-1-1'
+ }
+ ]
+ }
+ ]
+ }
+]
+```
+
+### 非联动选择
+
+常规数据
+
+```javascript
+list: [
+ [
+ { label: '选项1', value: '1' },
+ { label: '选项2', value: '2' },
+ { label: '选项3', value: '3' }
+ ],
+ [
+ { label: '选项11', value: '11' },
+ { label: '选项22', value: '22' },
+ { label: '选项33', value: '33' }
+ ],
+ [
+ { label: '选项111', value: '111' },
+ { label: '选项222', value: '222' },
+ { label: '选项333', value: '333' }
+ ]
+]
+```
+
+扁平化简单数据
+
+```javascript
+list: [
+ ['选项1', '选项2', '选项3'],
+ ['选项11', '选项22', '选项33'],
+ ['选项111', '选项222', '选项333']
+]
+```
+
+## 调用显示选择器
+
+通过`ref`形式手动调用`show`方法显示,隐藏同理调用`hide`
+
+```text
+
+
+this.$refs.picker.show() // 显示
+this.$refs.picker.hide() // 隐藏
+```
+
+## 绑定值及设置默认值
+
+支持 vue 中`v-model`写法绑定值,无需自己维护选中值的索引。
+
+```javascript
+
+
+
+data () {
+ return {
+ value1: '' // 单选
+ value2: [] // 多列联动选择
+ }
+}
+```
+
+## 多个选择器
+
+通过设置不同的`ref`,然后调用即可
+
+```javascript
+
+
+
+this.$refs.picker1.show() // picker1显示
+this.$refs.picker2.show() // picker2显示
+```
+
+## 省市区选择
+
+省市区选择是基于多列联动选择,数据来源:[https://github.com/modood/Administrative-divisions-of-China](https://github.com/modood/Administrative-divisions-of-China),
+省市区文件位于`/pages/demos/area-data-min.js`,自行引入即可,可参考`demo3省市区选择`,
+也可使用自己已有的省市区数据,如果数据字段不一样,也可以自定义,参考下方自定义数据字段。
+
+## 自定义数据字段
+
+为了满足不同人的需求,插件支持自定义数据字段名称, 插件默认的数据字段如下形式:
+
+```javascript
+list: [
+ {
+ label: '选择1',
+ value: 1,
+ children: []
+ },
+ {
+ label: '选择1',
+ value: 1,
+ children: []
+ }
+]
+```
+
+如果你的数据字段和上面不一样,如下形式:
+
+```javascript
+list: [
+ {
+ text: '选择1',
+ id: 1,
+ child: []
+ },
+ {
+ text: '选择1',
+ id: 1,
+ child: []
+ }
+]
+```
+
+通过设置参数中的`props`即可,如下所示:
+
+```javascript
+
+
+data () {
+ return {
+ myProps: {
+ label: 'text',
+ value: 'id',
+ children: 'child'
+ }
+ }
+}
+```
+
+## 插槽使用
+
+选择器支持一些可自定义化的插槽,如选择器的取消和确定文字按钮,如果需要对其自定义处理的话,比如加个 icon 图标之类的,可使用插槽,使用方法如下:
+
+```html
+
+ 我是自定义取消
+ 我是自定义确定
+
+```
+
+其他插槽见下。
+
+## 参数及事件
+
+### Props
+
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+| :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :------------------ | :--------------------------------------------------------------- | :------------------------------------------------ |
+| value/v-model | 绑定值,联动选择为 Array 类型 | String/Number/Array | - | - |
+| mode | 选择器类型,支持单列,多列联动 | String | selector 单选/multiSelector 多级联动/unlinkedSelector 多级非联动 | selector |
+| list | 选择器数据(v1.0.7 单选及非联动多选支持扁平数据:['选项 1', '选项 2']) | Array | - | - |
+| level | 多列联动层级,仅 mode 为 multiSelector 有效 | Number | - | 2 |
+| props | 自定义数据字段 | Object | - | {label:'label',value:'value',children:'children'} |
+| cancel-text | 取消文字 | String | - | 取消 |
+| cancel-color | 取消文字颜色 | String | - | #999 |
+| confirm-text | 确定文字 | String | - | 确定 |
+| confirm-color | 确定文字颜色 | String | - | #007aff |
+| empty-text | (v1.0.7 新增)选择器列表为空的时候显示的文字 | String | - | 暂无数据 |
+| empty-color | (v1.0.7 新增)暂无数据文字颜色 | String | - | #999 |
+| column-num | 可视滚动区域内滚动个数,最好设置奇数值 | Number | - | 5 |
+| radius | 选择器顶部圆角,支持 rpx,如 radius="10rpx" | String | - | - |
+| ~~column-style~~ | ~~选择器默认样式(已弃用,见下方自定义样式说明)~~ | Object | - | - |
+| ~~active-column-style~~ | ~~选择器选中样式(已弃用,见下方自定义样式说明)~~ | Object | - | - |
+| loading | 选择器是否显示加载中,可使用 loading 插槽自定义加载效果 | Boolean | - | - |
+| mask-color | 遮罩层颜色 | String | - | rgba(0, 0, 0, 0.4) |
+| close-on-click-mask | 点击遮罩层是否关闭选择器 | Boolean | true/false | true |
+| ~~change-on-init~~ | ~~(v1.0.7 已弃用)初始化时是否触发 change 事件~~ | Boolean | true/false | - |
+| dataset | (v1.0.7 新增)可以向组件中传递任意的自定义的数据(对象形式数据),如`:dataset="{name:'test'}"`,在`confirm`或`change`事件中可以取到 | Object | - | - |
+| show-header | (v1.0.8 新增)是否显示选择器头部 | Boolean | - | true |
+| inline | (v1.0.8 新增)inline 模式,开启后默认显示选择器,无需点击弹出,可以配合`show-header`一起使用 | Boolean | - | - |
+| z-index | (v1.0.9 新增)选择器层级,遮罩层默认-1 | Number | - | 999 |
+
+### 方法
+
+| 方法名 | 说明 | 参数 | 返回值 |
+| :------------- | :------------------------------------- | :-------------- | :----------------------------------------------------------------------------------------------------------- |
+| show | 打开选择器 | - | |
+| hide | 关闭选择器 | - | |
+| getColumnsInfo | (v1.1.0 新增)根据 value 获取选择器信息 | 绑定值的`value` | 同`change` `confirm`回调参数,如果传入的`value`获取不到信息则只返回一个含有`dataset`的对象,具体自行打印查看 |
+
+### Events
+
+| 事件名称 | 说明 | 回调参数 |
+| :------- | :--------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| show | 选择器打开时触发 | - |
+| hide | 选择器隐藏时触发 | - |
+| change | 选择器滚动时触发,此时不会改变绑定的值 | `{ index, item, value, change }` `index`触发滚动后新的索引,单选时是具体的索引值,多列联动选择时为数组。`item`触发滚动后新的的完整内容,包括`label`、`value`等,单选时为对象,多列选择时为数组对象。`value`触发滚动后新的 value 值,单列选择时为具体值,多列联动选择时为数组。`change`触发事件的类型,详情参考下面的 change 事件备注 |
+| confirm | 点击选择器确定时触发,此时会改变绑定的值 | 同上`change`事件说明 |
+| cancel | 点击选择器取消时触发 | 同上`change`事件说明 |
+
+### `change` 事件备注
+
+如果绑定的值是空的,`change`触发后里面的内容都是列表的第一项。
+`change`事件会在以下情况触发:
+
+- 初始化
+- 绑定值 value 变化
+- 选择器 list 列表变化
+- 滚动选择器
+
+以上情况会在回调函数中都可以取到`change`变化的类型,对应上面的情况包括以下:
+
+- `init`
+- `value`
+- `list`
+- `scroll`
+
+根据这些类型大家可以在`change`的时候按需处理自己的业务逻辑,`init`现在指挥在调用选择器弹出的时候触发。
+下面的说明情况已失效,如需要在页面显示的时候根据`value`的值显示相应的中文,调用`v1.10`新增的方法`getColumnsInfo`,传入绑定的值即可获取到你想要的所有信息。
+~~比如一种常见的情况,有默认值的时候需要显示默认值的文字,此时可以`change`事件中判断`change`的类型是否是`init`,如果是的话可以取事件回调中的`item`进行显示绑定值对应的文字信息。~~
+
+```javascript
+handleChange (e) {
+ if (e.change === 'init') {
+ console.log(e.item.label) // 单选 选项1
+ console.log(e.item.map(item => item.label).join('-')) // 多选 选项1-选项11
+ }
+}
+```
+
+### 插槽
+
+| 插槽名 | 说明 |
+| :------------ | :------------------ |
+| cancel-text | 选择器取消文字插槽 |
+| action-center | 选择器顶部中间插槽 |
+| confirm-text | 选择器确定文字插槽 |
+| loading | 选择器 loading 插槽 |
+| empty | 选择器 空数据 插槽 |
+
+### 选择器自定义样式
+
+原先的`column-style`和`active-column-style`已弃用,如需修改默认样式及选中样式参考`demo9`
+
+```css
+
+```
+
+### 获取选中值的文字
+
+`@confirm`事件中可以拿到:
+
+单选:
+
+```javascript
+handleConfirm (e) {
+ console.log(e.item.label) // 选项1
+}
+```
+
+联动选择:
+
+```javascript
+handleConfirm (e) {
+ console.log(e.item.map(item => item.label).join('-')) // 选项1-选项11
+}
+```
+
+## Tips
+
+微信小程序端,滚动时在 iOS 自带振动反馈,可在系统设置 -> 声音与触感 -> 系统触感反馈中关闭
+
+## 其他
+
+其他功能参考示例 Demo 代码。
diff --git a/components/lb-picker/index.vue b/components/lb-picker/index.vue
new file mode 100644
index 0000000..c844a4c
--- /dev/null
+++ b/components/lb-picker/index.vue
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ emptyText }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/lb-picker/mixins/index.js b/components/lb-picker/mixins/index.js
new file mode 100644
index 0000000..505d74f
--- /dev/null
+++ b/components/lb-picker/mixins/index.js
@@ -0,0 +1,45 @@
+import { getColumns } from '../utils'
+export const commonMixin = {
+ data () {
+ return {
+ indicatorStyle: `height: 34px`
+ }
+ },
+ created () {
+ this.init('init')
+ },
+ methods: {
+ init (changeType) {
+ if (this.list && this.list.length) {
+ const column = getColumns({
+ value: this.value,
+ list: this.list,
+ mode: this.mode,
+ props: this.props,
+ level: this.level
+ })
+ const { columns, value, item, index } = column
+ this.selectValue = value
+ this.selectItem = item
+ this.pickerColumns = columns
+ this.pickerValue = index
+ this.$emit('change', {
+ value: this.selectValue,
+ item: this.selectItem,
+ index: this.pickerValue,
+ change: changeType
+ })
+ }
+ }
+ },
+ watch: {
+ value () {
+ if (!this.isConfirmChange) {
+ this.init('value')
+ }
+ },
+ list () {
+ this.init('list')
+ }
+ }
+}
diff --git a/components/lb-picker/pickers/multi-selector-picker.vue b/components/lb-picker/pickers/multi-selector-picker.vue
new file mode 100644
index 0000000..87ac229
--- /dev/null
+++ b/components/lb-picker/pickers/multi-selector-picker.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+ {{ item[props.label] || item }}
+
+
+
+
+
+
+
+
+
+
diff --git a/components/lb-picker/pickers/selector-picker.vue b/components/lb-picker/pickers/selector-picker.vue
new file mode 100644
index 0000000..b9dbfa2
--- /dev/null
+++ b/components/lb-picker/pickers/selector-picker.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ {{ item[props.label] || item }}
+
+
+
+
+
+
+
+
+
+
diff --git a/components/lb-picker/pickers/unlinked-selector-picker.vue b/components/lb-picker/pickers/unlinked-selector-picker.vue
new file mode 100644
index 0000000..8081382
--- /dev/null
+++ b/components/lb-picker/pickers/unlinked-selector-picker.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ {{ item[props.label] || item }}
+
+
+
+
+
+
+
+
+
+
diff --git a/components/lb-picker/style/picker-item.scss b/components/lb-picker/style/picker-item.scss
new file mode 100644
index 0000000..fc497d1
--- /dev/null
+++ b/components/lb-picker/style/picker-item.scss
@@ -0,0 +1,23 @@
+.lb-picker-column {
+ height: 34px;
+ /* #ifndef APP-NVUE */
+ display: flex;
+ box-sizing: border-box;
+ white-space: nowrap;
+ overflow: hidden;
+ /* #endif */
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+}
+
+.lb-picker-column-label {
+ font-size: 16px;
+ text-align: center;
+ text-overflow: ellipsis;
+ transition-property: color;
+ transition-duration: 0.3s;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
\ No newline at end of file
diff --git a/components/lb-picker/style/picker.scss b/components/lb-picker/style/picker.scss
new file mode 100644
index 0000000..73720b0
--- /dev/null
+++ b/components/lb-picker/style/picker.scss
@@ -0,0 +1,151 @@
+.lb-picker {
+ position: relative;
+}
+
+.lb-picker-mask {
+ background-color: rgba(0, 0, 0, 0.0);
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ bottom: 0;
+}
+
+.lb-picker-mask-animation {
+ transition-property: background-color;
+ transition-duration: 0.3s;
+}
+
+.lb-picker-container {
+ position: relative;
+}
+
+.lb-picker-container-fixed {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ transform: translateY(100%);
+ /* #ifndef APP-PLUS */
+ overflow: hidden;
+ /* #endif */
+}
+
+.lb-picker-container-animation {
+ transition-property: transform;
+ transition-duration: 0.3s;
+}
+
+.lb-picker-container-show {
+ transform: translateY(0);
+}
+
+.lb-picker-header {
+ position: relative;
+ height: 45px;
+ background-color: #fff;
+ /* #ifdef APP-NVUE */
+ border-width: 1px;
+ border-style: solid;
+ border-color: #e5e5e5;
+ /* #endif */
+ /* #ifndef APP-NVUE */
+ box-sizing: border-box;
+ display: flex;
+ /* #endif */
+ flex-direction: row;
+ justify-content: space-between;
+ flex-wrap: nowrap;
+}
+
+/* #ifndef APP-PLUS */
+.lb-picker-header::after {
+ content: "";
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ height: 1px;
+ clear: both;
+ border-bottom: 1px solid #e5e5e5;
+ color: #e5e5e5;
+ transform-origin: 0 100%;
+ -webkit-transform: scaleY(0.5);
+ transform: scaleY(0.5);
+}
+
+/* #endif */
+
+.lb-picker-action {
+ padding-left: 14px;
+ padding-right: 14px;
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+}
+
+.lb-picker-action-cancel {
+ text-align: center;
+}
+
+.lb-picker-action-cancel-text {
+ font-size: 16px;
+ color: #999;
+}
+
+.lb-picker-action-confirm {
+ text-align: center;
+}
+
+.lb-picker-action-confirm-text {
+ font-size: 16px;
+ color: #007aff;
+}
+
+.lb-picker-content {
+ position: relative;
+ background-color: #fff;
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ justify-content: center;
+ flex-direction: column;
+}
+
+.lb-picker-loading,
+.lb-picker-empty {
+ /* #ifndef APP-NVUE */
+ display: flex;
+ /* #endif */
+ justify-content: center;
+ align-items: center;
+}
+
+.lb-picker-empty-text {
+ color: #999;
+ font-size: 16px;
+}
+
+.lb-picker-loading-img {
+ width: 25px;
+ height: 25px;
+ /* #ifndef APP-NVUE */
+ animation: rotating 2s linear infinite;
+ /* #endif */
+}
+
+/* #ifndef APP-NVUE */
+@keyframes rotating {
+ 0% {
+ transform: rotate(0deg)
+ }
+
+ to {
+ transform: rotate(1turn)
+ }
+}
+
+/* #endif */
\ No newline at end of file
diff --git a/components/lb-picker/utils.js b/components/lb-picker/utils.js
new file mode 100644
index 0000000..5330d9b
--- /dev/null
+++ b/components/lb-picker/utils.js
@@ -0,0 +1,110 @@
+/**
+ * 判断是否是对象
+ *
+ * @export
+ * @param {*} val
+ * @returns true/false
+ */
+export function isObject (val) {
+ return Object.prototype.toString.call(val) === '[object Object]'
+}
+
+/**
+ * 根据value获取columns信息
+ *
+ * @export
+ * @param {*} { value, list, mode, props, level }
+ * @param {number} [type=2] 查询不到value数据返回数据类型 1空值null 2默认第一个选项
+ * @returns
+ */
+export function getColumns ({ value, list, mode, props, level }, type = 2) {
+ let pickerValue = []
+ let pickerColumns = []
+ let selectValue = []
+ let selectItem = []
+ let columnsInfo = null
+ switch (mode) {
+ case 'selector':
+ let index = list.findIndex(item => {
+ return isObject(item) ? item[props.value] === value : item === value
+ })
+ if (index === -1 && type === 1) {
+ columnsInfo = null
+ } else {
+ index = index > -1 ? index : 0
+ selectItem = list[index]
+ selectValue = isObject(selectItem)
+ ? selectItem[props.value]
+ : selectItem
+ pickerColumns = list
+ pickerValue = [index]
+ columnsInfo = {
+ index: pickerValue,
+ value: selectValue,
+ item: selectItem,
+ columns: pickerColumns
+ }
+ }
+ break
+ case 'multiSelector':
+ const setPickerItems = (data = [], index = 0) => {
+ if (!data.length) return
+ const defaultValue = value || []
+ if (index < level) {
+ const value = defaultValue[index] || ''
+ let i = data.findIndex(item => item[props.value] === value)
+ if (i === -1 && type === 1) return
+ i = i > -1 ? i : 0
+ pickerValue[index] = i
+ pickerColumns[index] = data
+ if (data[i]) {
+ selectValue[index] = data[i][props.value]
+ selectItem[index] = data[i]
+ setPickerItems(data[i][props.children] || [], index + 1)
+ }
+ }
+ }
+ setPickerItems(list)
+ if (!selectValue.length && type === 1) {
+ columnsInfo = null
+ } else {
+ columnsInfo = {
+ index: pickerValue,
+ value: selectValue,
+ item: selectItem,
+ columns: pickerColumns
+ }
+ }
+ break
+ case 'unlinkedSelector':
+ list.forEach((item, i) => {
+ let index = item.findIndex(item => {
+ return isObject(item)
+ ? item[props.value] === value[i]
+ : item === value[i]
+ })
+ if (index === -1 && type === 1) return
+ index = index > -1 ? index : 0
+ const columnItem = list[i][index]
+ const valueItem = isObject(columnItem)
+ ? columnItem[props.value]
+ : columnItem
+ pickerValue[i] = index
+ selectValue[i] = valueItem
+ selectItem[i] = columnItem
+ })
+ pickerColumns = list
+ if (!selectValue.length && type === 1) {
+ columnsInfo = null
+ } else {
+ columnsInfo = {
+ index: pickerValue,
+ value: selectValue,
+ item: selectItem,
+ columns: pickerColumns
+ }
+ }
+ break
+ }
+ return columnsInfo
+}
diff --git a/components/mask-view/mask-view.vue b/components/mask-view/mask-view.vue
new file mode 100644
index 0000000..b343078
--- /dev/null
+++ b/components/mask-view/mask-view.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/components/mescroll-uni/components/mescroll-down.css b/components/mescroll-uni/components/mescroll-down.css
new file mode 100644
index 0000000..72bf106
--- /dev/null
+++ b/components/mescroll-uni/components/mescroll-down.css
@@ -0,0 +1,55 @@
+/* 下拉刷新区域 */
+.mescroll-downwarp {
+ position: absolute;
+ top: -100%;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+}
+
+/* 下拉刷新--内容区,定位于区域底部 */
+.mescroll-downwarp .downwarp-content {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ min-height: 60rpx;
+ padding: 20rpx 0;
+ text-align: center;
+}
+
+/* 下拉刷新--提示文本 */
+.mescroll-downwarp .downwarp-tip {
+ display: inline-block;
+ font-size: 28rpx;
+ vertical-align: middle;
+ margin-left: 16rpx;
+ /* color: gray; 已在style设置color,此处删去*/
+}
+
+/* 下拉刷新--旋转进度条 */
+.mescroll-downwarp .downwarp-progress {
+ display: inline-block;
+ width: 32rpx;
+ height: 32rpx;
+ border-radius: 50%;
+ border: 2rpx solid gray;
+ border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
+ vertical-align: middle;
+}
+
+/* 旋转动画 */
+.mescroll-downwarp .mescroll-rotate {
+ animation: mescrollDownRotate 0.6s linear infinite;
+}
+
+@keyframes mescrollDownRotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
\ No newline at end of file
diff --git a/components/mescroll-uni/components/mescroll-down.vue b/components/mescroll-uni/components/mescroll-down.vue
new file mode 100644
index 0000000..9fd1567
--- /dev/null
+++ b/components/mescroll-uni/components/mescroll-down.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+ {{downText}}
+
+
+
+
+
+
+
diff --git a/components/mescroll-uni/components/mescroll-empty.vue b/components/mescroll-uni/components/mescroll-empty.vue
new file mode 100644
index 0000000..6d1f2e0
--- /dev/null
+++ b/components/mescroll-uni/components/mescroll-empty.vue
@@ -0,0 +1,90 @@
+
+
+
+
+ {{ tip }}
+ {{ option.btnText }}
+
+
+
+
+
+
diff --git a/components/mescroll-uni/components/mescroll-top.vue b/components/mescroll-uni/components/mescroll-top.vue
new file mode 100644
index 0000000..5115fd8
--- /dev/null
+++ b/components/mescroll-uni/components/mescroll-top.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
diff --git a/components/mescroll-uni/components/mescroll-up.css b/components/mescroll-uni/components/mescroll-up.css
new file mode 100644
index 0000000..cbf48cd
--- /dev/null
+++ b/components/mescroll-uni/components/mescroll-up.css
@@ -0,0 +1,47 @@
+/* 上拉加载区域 */
+.mescroll-upwarp {
+ box-sizing: border-box;
+ min-height: 110rpx;
+ padding: 30rpx 0;
+ text-align: center;
+ clear: both;
+}
+
+/*提示文本 */
+.mescroll-upwarp .upwarp-tip,
+.mescroll-upwarp .upwarp-nodata {
+ display: inline-block;
+ font-size: 28rpx;
+ vertical-align: middle;
+ /* color: gray; 已在style设置color,此处删去*/
+}
+
+.mescroll-upwarp .upwarp-tip {
+ margin-left: 16rpx;
+}
+
+/*旋转进度条 */
+.mescroll-upwarp .upwarp-progress {
+ display: inline-block;
+ width: 32rpx;
+ height: 32rpx;
+ border-radius: 50%;
+ border: 2rpx solid gray;
+ border-bottom-color: transparent !important; /*已在style设置border-color,此处需加 !important*/
+ vertical-align: middle;
+}
+
+/* 旋转动画 */
+.mescroll-upwarp .mescroll-rotate {
+ animation: mescrollUpRotate 0.6s linear infinite;
+}
+
+@keyframes mescrollUpRotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
\ No newline at end of file
diff --git a/components/mescroll-uni/components/mescroll-up.vue b/components/mescroll-uni/components/mescroll-up.vue
new file mode 100644
index 0000000..11c2e1f
--- /dev/null
+++ b/components/mescroll-uni/components/mescroll-up.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ {{ mOption.textLoading }}
+
+
+ {{ mOption.textNoMore }}
+
+
+
+
+
+
diff --git a/components/mescroll-uni/mescroll-body.css b/components/mescroll-uni/mescroll-body.css
new file mode 100644
index 0000000..9cfa255
--- /dev/null
+++ b/components/mescroll-uni/mescroll-body.css
@@ -0,0 +1,14 @@
+.mescroll-body {
+ position: relative; /* 下拉刷新区域相对自身定位 */
+ height: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实现列表不满屏仍可下拉*/
+ overflow: hidden; /* 当有元素写在mescroll-body标签前面时,可遮住下拉刷新区域 */
+ box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
+}
+
+/* 适配 iPhoneX */
+@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
+ .mescroll-safearea {
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
+ }
+}
\ No newline at end of file
diff --git a/components/mescroll-uni/mescroll-body.vue b/components/mescroll-uni/mescroll-body.vue
new file mode 100644
index 0000000..96e0e65
--- /dev/null
+++ b/components/mescroll-uni/mescroll-body.vue
@@ -0,0 +1,327 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{downText}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ mescroll.optUp.textLoading }}
+
+
+ {{ mescroll.optUp.textNoMore }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/mescroll-uni/mescroll-mixins.js b/components/mescroll-uni/mescroll-mixins.js
new file mode 100644
index 0000000..a379739
--- /dev/null
+++ b/components/mescroll-uni/mescroll-mixins.js
@@ -0,0 +1,65 @@
+// mescroll-body 和 mescroll-uni 通用
+
+// import MescrollUni from "./mescroll-uni.vue";
+// import MescrollBody from "./mescroll-body.vue";
+
+const MescrollMixin = {
+ // components: { // 非H5端无法通过mixin注册组件, 只能在main.js中注册全局组件或具体界面中注册
+ // MescrollUni,
+ // MescrollBody
+ // },
+ data() {
+ return {
+ mescroll: null //mescroll实例对象
+ }
+ },
+ // 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
+ onPullDownRefresh(){
+ this.mescroll && this.mescroll.onPullDownRefresh();
+ },
+ // 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
+ onPageScroll(e) {
+ this.mescroll && this.mescroll.onPageScroll(e);
+ },
+ // 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
+ onReachBottom() {
+ this.mescroll && this.mescroll.onReachBottom();
+ },
+ methods: {
+ // mescroll组件初始化的回调,可获取到mescroll对象
+ mescrollInit(mescroll) {
+ this.mescroll = mescroll;
+ this.mescrollInitByRef(); // 兼容字节跳动小程序
+ },
+ // 以ref的方式初始化mescroll对象 (兼容字节跳动小程序: http://www.mescroll.com/qa.html?v=20200107#q26)
+ mescrollInitByRef() {
+ if(!this.mescroll || !this.mescroll.resetUpScroll){
+ let mescrollRef = this.$refs.mescrollRef;
+ if(mescrollRef) this.mescroll = mescrollRef.mescroll
+ }
+ },
+ // 下拉刷新的回调 (mixin默认resetUpScroll)
+ downCallback() {
+ if(this.mescroll.optUp.use){
+ this.mescroll.resetUpScroll()
+ }else{
+ setTimeout(()=>{
+ this.mescroll.endSuccess();
+ }, 500)
+ }
+ },
+ // 上拉加载的回调
+ upCallback() {
+ // mixin默认延时500自动结束加载
+ setTimeout(()=>{
+ this.mescroll.endErr();
+ }, 500)
+ }
+ },
+ mounted() {
+ this.mescrollInitByRef(); // 兼容字节跳动小程序, 避免未设置@init或@init此时未能取到ref的情况
+ }
+
+}
+
+export default MescrollMixin;
diff --git a/components/mescroll-uni/mescroll-uni-option.js b/components/mescroll-uni/mescroll-uni-option.js
new file mode 100644
index 0000000..d9b71d2
--- /dev/null
+++ b/components/mescroll-uni/mescroll-uni-option.js
@@ -0,0 +1,33 @@
+// 全局配置
+// mescroll-body 和 mescroll-uni 通用
+const GlobalOption = {
+ down: {
+ // 其他down的配置参数也可以写,这里只展示了常用的配置:
+ textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
+ textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
+ textLoading: '加载中 ...', // 加载中的提示文本
+ offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
+ native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
+ },
+ up: {
+ // 其他up的配置参数也可以写,这里只展示了常用的配置:
+ textLoading: '加载中 ...', // 加载中的提示文本
+ textNoMore: '-- END --', // 没有更多数据的提示文本
+ offset: 80, // 距底部多远时,触发upCallback
+ toTop: {
+ // 回到顶部按钮,需配置src才显示
+ src: "http://www.mescroll.com/img/mescroll-totop.png?v=1", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png )
+ offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px
+ right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
+ bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
+ width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
+ },
+ empty: {
+ use: true, // 是否显示空布局
+ icon: "http://www.mescroll.com/img/mescroll-empty.png?v=1", // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
+ tip: '~ 空空如也 ~' // 提示
+ }
+ }
+}
+
+export default GlobalOption
diff --git a/components/mescroll-uni/mescroll-uni.css b/components/mescroll-uni/mescroll-uni.css
new file mode 100644
index 0000000..39438cd
--- /dev/null
+++ b/components/mescroll-uni/mescroll-uni.css
@@ -0,0 +1,36 @@
+.mescroll-uni-warp{
+ height: 100%;
+}
+
+.mescroll-uni-content{
+ height: 100%;
+}
+
+.mescroll-uni {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ min-height: 200rpx;
+ overflow-y: auto;
+ box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
+}
+
+/* 定位的方式固定高度 */
+.mescroll-uni-fixed{
+ z-index: 1;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ width: auto; /* 使right生效 */
+ height: auto; /* 使bottom生效 */
+}
+
+/* 适配 iPhoneX */
+@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
+ .mescroll-safearea {
+ padding-bottom: constant(safe-area-inset-bottom);
+ padding-bottom: env(safe-area-inset-bottom);
+ }
+}
diff --git a/components/mescroll-uni/mescroll-uni.js b/components/mescroll-uni/mescroll-uni.js
new file mode 100644
index 0000000..34cf4ff
--- /dev/null
+++ b/components/mescroll-uni/mescroll-uni.js
@@ -0,0 +1,788 @@
+/* mescroll
+ * version 1.3.1
+ * 2020-07-27 wenju
+ * http://www.mescroll.com
+ */
+
+export default function MeScroll(options, isScrollBody) {
+ let me = this;
+ me.version = '1.3.1'; // mescroll版本号
+ me.options = options || {}; // 配置
+ me.isScrollBody = isScrollBody || false; // 滚动区域是否为原生页面滚动; 默认为scroll-view
+
+ me.isDownScrolling = false; // 是否在执行下拉刷新的回调
+ me.isUpScrolling = false; // 是否在执行上拉加载的回调
+ let hasDownCallback = me.options.down && me.options.down.callback; // 是否配置了down的callback
+
+ // 初始化下拉刷新
+ me.initDownScroll();
+ // 初始化上拉加载,则初始化
+ me.initUpScroll();
+
+ // 自动加载
+ setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
+ // 自动触发下拉刷新 (只有配置了down的callback才自动触发下拉刷新)
+ if ((me.optDown.use || me.optDown.native) && me.optDown.auto && hasDownCallback) {
+ if (me.optDown.autoShowLoading) {
+ me.triggerDownScroll(); // 显示下拉进度,执行下拉回调
+ } else {
+ me.optDown.callback && me.optDown.callback(me); // 不显示下拉进度,直接执行下拉回调
+ }
+ }
+ // 自动触发上拉加载
+ if(!me.isUpAutoLoad){ // 部分小程序(头条小程序)emit是异步, 会导致isUpAutoLoad判断有误, 先延时确保先执行down的callback,再执行up的callback
+ setTimeout(function(){
+ me.optUp.use && me.optUp.auto && !me.isUpAutoLoad && me.triggerUpScroll();
+ },100)
+ }
+ }, 30); // 需让me.optDown.inited和me.optUp.inited先执行
+}
+
+/* 配置参数:下拉刷新 */
+MeScroll.prototype.extendDownScroll = function(optDown) {
+ // 下拉刷新的配置
+ MeScroll.extend(optDown, {
+ use: true, // 是否启用下拉刷新; 默认true
+ auto: true, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true
+ native: false, // 是否使用系统自带的下拉刷新; 默认false; 仅mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
+ autoShowLoading: false, // 如果设置auto=true(在初始化完毕之后自动执行下拉刷新的回调),那么是否显示下拉刷新的进度; 默认false
+ isLock: false, // 是否锁定下拉刷新,默认false;
+ offset: 80, // 在列表顶部,下拉大于80px,松手即可触发下拉刷新的回调
+ startTop: 100, // scroll-view快速滚动到顶部时,此时的scroll-top可能大于0, 此值用于控制最大的误差
+ inOffsetRate: 1, // 在列表顶部,下拉的距离小于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
+ outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
+ bottomOffset: 20, // 当手指touchmove位置在距离body底部20px范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行
+ minAngle: 45, // 向下滑动最少偏移的角度,取值区间 [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突;
+ textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
+ textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
+ textLoading: '加载中 ...', // 加载中的提示文本
+ bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorTop)
+ textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
+ inited: null, // 下拉刷新初始化完毕的回调
+ inOffset: null, // 下拉的距离进入offset范围内那一刻的回调
+ outOffset: null, // 下拉的距离大于offset那一刻的回调
+ onMoving: null, // 下拉过程中的回调,滑动过程一直在执行; rate下拉区域当前高度与指定距离的比值(inOffset: rate<1; outOffset: rate>=1); downHight当前下拉区域的高度
+ beforeLoading: null, // 准备触发下拉刷新的回调: 如果return true,将不触发showLoading和callback回调; 常用来完全自定义下拉刷新, 参考案例【淘宝 v6.8.0】
+ showLoading: null, // 显示下拉刷新进度的回调
+ afterLoading: null, // 显示下拉刷新进度的回调之后,马上要执行的代码 (如: 在wxs中使用)
+ beforeEndDownScroll: null, // 准备结束下拉的回调. 返回结束下拉的延时执行时间,默认0ms; 常用于结束下拉之前再显示另外一小段动画,才去隐藏下拉刷新的场景, 参考案例【dotJump】
+ endDownScroll: null, // 结束下拉刷新的回调
+ afterEndDownScroll: null, // 结束下拉刷新的回调,马上要执行的代码 (如: 在wxs中使用)
+ callback: function(mescroll) {
+ // 下拉刷新的回调;默认重置上拉加载列表为第一页
+ mescroll.resetUpScroll();
+ }
+ })
+}
+
+/* 配置参数:上拉加载 */
+MeScroll.prototype.extendUpScroll = function(optUp) {
+ // 上拉加载的配置
+ MeScroll.extend(optUp, {
+ use: true, // 是否启用上拉加载; 默认true
+ auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true
+ isLock: false, // 是否锁定上拉加载,默认false;
+ isBoth: true, // 上拉加载时,如果滑动到列表顶部是否可以同时触发下拉刷新;默认true,两者可同时触发;
+ callback: null, // 上拉加载的回调;function(page,mescroll){ }
+ page: {
+ num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+ size: 10, // 每页数据的数量
+ time: null // 加载第一页数据服务器返回的时间; 防止用户翻页时,后台新增了数据从而导致下一页数据重复;
+ },
+ noMoreSize: 5, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看
+ offset: 80, // 距底部多远时,触发upCallback
+ textLoading: '加载中 ...', // 加载中的提示文本
+ textNoMore: '-- END --', // 没有更多数据的提示文本
+ bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorBottom)
+ textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
+ inited: null, // 初始化完毕的回调
+ showLoading: null, // 显示加载中的回调
+ showNoMore: null, // 显示无更多数据的回调
+ hideUpScroll: null, // 隐藏上拉加载的回调
+ errDistance: 60, // endErr的时候需往上滑动一段距离,使其往下滑动时再次触发onReachBottom,仅mescroll-body生效
+ toTop: {
+ // 回到顶部按钮,需配置src才显示
+ src: null, // 图片路径,默认null (绝对路径或网络图)
+ offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000
+ duration: 300, // 回到顶部的动画时长,默认300ms (当值为0或300则使用系统自带回到顶部,更流畅; 其他值则通过step模拟,部分机型可能不够流畅,所以非特殊情况不建议修改此项)
+ btnClick: null, // 点击按钮的回调
+ onShow: null, // 是否显示的回调
+ zIndex: 9990, // fixed定位z-index值
+ left: null, // 到左边的距离, 默认null. 此项有值时,right不生效. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
+ right: 20, // 到右边的距离, 默认20 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
+ bottom: 120, // 到底部的距离, 默认120 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
+ safearea: false, // bottom的偏移量是否加上底部安全区的距离, 默认false, 需要适配iPhoneX时使用 (具体的界面如果不配置此项,则取本vue的safearea值)
+ width: 72, // 回到顶部图标的宽度, 默认72 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
+ radius: "50%" // 圆角, 默认"50%" (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
+ },
+ empty: {
+ use: true, // 是否显示空布局
+ icon: null, // 图标路径
+ tip: '~ 暂无相关数据 ~', // 提示
+ btnText: '', // 按钮
+ btnClick: null, // 点击按钮的回调
+ onShow: null, // 是否显示的回调
+ fixed: false, // 是否使用fixed定位,默认false; 配置fixed为true,以下的top和zIndex才生效 (transform会使fixed失效,最终会降级为absolute)
+ top: "100rpx", // fixed定位的top值 (完整的单位值,如 "10%"; "100rpx")
+ zIndex: 99 // fixed定位z-index值
+ },
+ onScroll: false // 是否监听滚动事件
+ })
+}
+
+/* 配置参数 */
+MeScroll.extend = function(userOption, defaultOption) {
+ if (!userOption) return defaultOption;
+ for (let key in defaultOption) {
+ if (userOption[key] == null) {
+ let def = defaultOption[key];
+ if (def != null && typeof def === 'object') {
+ userOption[key] = MeScroll.extend({}, def); // 深度匹配
+ } else {
+ userOption[key] = def;
+ }
+ } else if (typeof userOption[key] === 'object') {
+ MeScroll.extend(userOption[key], defaultOption[key]); // 深度匹配
+ }
+ }
+ return userOption;
+}
+
+/* 简单判断是否配置了颜色 (非透明,非白色) */
+MeScroll.prototype.hasColor = function(color) {
+ if(!color) return false;
+ let c = color.toLowerCase();
+ return c != "#fff" && c != "#ffffff" && c != "transparent" && c != "white"
+}
+
+/* -------初始化下拉刷新------- */
+MeScroll.prototype.initDownScroll = function() {
+ let me = this;
+ // 配置参数
+ me.optDown = me.options.down || {};
+ if(!me.optDown.textColor && me.hasColor(me.optDown.bgColor)) me.optDown.textColor = "#fff"; // 当bgColor有值且textColor未设置,则textColor默认白色
+ me.extendDownScroll(me.optDown);
+
+ // 如果是mescroll-body且配置了native,则禁止自定义的下拉刷新
+ if(me.isScrollBody && me.optDown.native){
+ me.optDown.use = false
+ }else{
+ me.optDown.native = false // 仅mescroll-body支持,mescroll-uni不支持
+ }
+
+ me.downHight = 0; // 下拉区域的高度
+
+ // 在页面中加入下拉布局
+ if (me.optDown.use && me.optDown.inited) {
+ // 初始化完毕的回调
+ setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
+ me.optDown.inited(me);
+ }, 0)
+ }
+}
+
+/* 列表touchstart事件 */
+MeScroll.prototype.touchstartEvent = function(e) {
+ if (!this.optDown.use) return;
+
+ this.startPoint = this.getPoint(e); // 记录起点
+ this.startTop = this.getScrollTop(); // 记录此时的滚动条位置
+ this.startAngle = 0; // 初始角度
+ this.lastPoint = this.startPoint; // 重置上次move的点
+ this.maxTouchmoveY = this.getBodyHeight() - this.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
+ this.inTouchend = false; // 标记不是touchend
+}
+
+/* 列表touchmove事件 */
+MeScroll.prototype.touchmoveEvent = function(e) {
+ if (!this.optDown.use) return;
+ let me = this;
+
+ let scrollTop = me.getScrollTop(); // 当前滚动条的距离
+ let curPoint = me.getPoint(e); // 当前点
+
+ let moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+
+ // 向下拉 && 在顶部
+ // mescroll-body,直接判定在顶部即可
+ // scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
+ // scroll-view滚动到顶部时,scrollTop不一定为0,也有可能大于0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
+ if (moveY > 0 && (
+ (me.isScrollBody && scrollTop <= 0)
+ ||
+ (!me.isScrollBody && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop)) )
+ )) {
+ // 可下拉的条件
+ if (!me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
+ me.optUp.isBoth))) {
+
+ // 下拉的初始角度是否在配置的范围内
+ if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90]
+ if (me.startAngle < me.optDown.minAngle) return; // 如果小于配置的角度,则不往下执行下拉刷新
+
+ // 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
+ if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
+ me.inTouchend = true; // 标记执行touchend
+ me.touchendEvent(); // 提前触发touchend
+ return;
+ }
+
+ me.preventDefault(e); // 阻止默认事件
+
+ let diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
+
+ // 下拉距离 < 指定距离
+ if (me.downHight < me.optDown.offset) {
+ if (me.movetype !== 1) {
+ me.movetype = 1; // 加入标记,保证只执行一次
+ me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
+ me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
+ }
+ me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
+
+ // 指定距离 <= 下拉距离
+ } else {
+ if (me.movetype !== 2) {
+ me.movetype = 2; // 加入标记,保证只执行一次
+ me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
+ me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
+ }
+ if (diff > 0) { // 向下拉
+ me.downHight += diff * me.optDown.outOffsetRate; // 越往下,高度变化越小
+ } else { // 向上收
+ me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
+ }
+ }
+
+ me.downHight = Math.round(me.downHight) // 取整
+ let rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
+ me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
+ }
+ }
+
+ me.lastPoint = curPoint; // 记录本次移动的点
+}
+
+/* 列表touchend事件 */
+MeScroll.prototype.touchendEvent = function(e) {
+ if (!this.optDown.use) return;
+ // 如果下拉区域高度已改变,则需重置回来
+ if (this.isMoveDown) {
+ if (this.downHight >= this.optDown.offset) {
+ // 符合触发刷新的条件
+ this.triggerDownScroll();
+ } else {
+ // 不符合的话 则重置
+ this.downHight = 0;
+ this.endDownScrollCall(this);
+ }
+ this.movetype = 0;
+ this.isMoveDown = false;
+ } else if (!this.isScrollBody && this.getScrollTop() === this.startTop) { // scroll-view到顶/左/右/底的滑动事件
+ let isScrollUp = this.getPoint(e).y - this.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+ // 上滑
+ if (isScrollUp) {
+ // 需检查滑动的角度
+ let angle = this.getAngle(this.getPoint(e), this.startPoint); // 两点之间的角度,区间 [0,90]
+ if (angle > 80) {
+ // 检查并触发上拉
+ this.triggerUpScroll(true);
+ }
+ }
+ }
+}
+
+/* 根据点击滑动事件获取第一个手指的坐标 */
+MeScroll.prototype.getPoint = function(e) {
+ if (!e) {
+ return {
+ x: 0,
+ y: 0
+ }
+ }
+ if (e.touches && e.touches[0]) {
+ return {
+ x: e.touches[0].pageX,
+ y: e.touches[0].pageY
+ }
+ } else if (e.changedTouches && e.changedTouches[0]) {
+ return {
+ x: e.changedTouches[0].pageX,
+ y: e.changedTouches[0].pageY
+ }
+ } else {
+ return {
+ x: e.clientX,
+ y: e.clientY
+ }
+ }
+}
+
+/* 计算两点之间的角度: 区间 [0,90]*/
+MeScroll.prototype.getAngle = function(p1, p2) {
+ let x = Math.abs(p1.x - p2.x);
+ let y = Math.abs(p1.y - p2.y);
+ let z = Math.sqrt(x * x + y * y);
+ let angle = 0;
+ if (z !== 0) {
+ angle = Math.asin(y / z) / Math.PI * 180;
+ }
+ return angle
+}
+
+/* 触发下拉刷新 */
+MeScroll.prototype.triggerDownScroll = function() {
+ if (this.optDown.beforeLoading && this.optDown.beforeLoading(this)) {
+ //return true则处于完全自定义状态
+ } else {
+ this.showDownScroll(); // 下拉刷新中...
+ !this.optDown.native && this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
+ }
+}
+
+/* 显示下拉进度布局 */
+MeScroll.prototype.showDownScroll = function() {
+ this.isDownScrolling = true; // 标记下拉中
+ if (this.optDown.native) {
+ uni.startPullDownRefresh(); // 系统自带的下拉刷新
+ this.showDownLoadingCall(0); // 仍触发showLoading,因为上拉加载用到
+ } else{
+ this.downHight = this.optDown.offset; // 更新下拉区域高度
+ this.showDownLoadingCall(this.downHight); // 下拉刷新中...
+ }
+}
+
+MeScroll.prototype.showDownLoadingCall = function(downHight) {
+ this.optDown.showLoading && this.optDown.showLoading(this, downHight); // 下拉刷新中...
+ this.optDown.afterLoading && this.optDown.afterLoading(this, downHight); // 下拉刷新中...触发之后马上要执行的代码
+}
+
+/* 显示系统自带的下拉刷新时需要处理的业务 */
+MeScroll.prototype.onPullDownRefresh = function() {
+ this.isDownScrolling = true; // 标记下拉中
+ this.showDownLoadingCall(0); // 仍触发showLoading,因为上拉加载用到
+ this.optDown.callback && this.optDown.callback(this); // 执行回调,联网加载数据
+}
+
+/* 结束下拉刷新 */
+MeScroll.prototype.endDownScroll = function() {
+ if (this.optDown.native) { // 结束原生下拉刷新
+ this.isDownScrolling = false;
+ this.endDownScrollCall(this);
+ uni.stopPullDownRefresh();
+ return
+ }
+ let me = this;
+ // 结束下拉刷新的方法
+ let endScroll = function() {
+ me.downHight = 0;
+ me.isDownScrolling = false;
+ me.endDownScrollCall(me);
+ if(!me.isScrollBody){
+ me.setScrollHeight(0) // scroll-view重置滚动区域,使数据不满屏时仍可检查触发翻页
+ me.scrollTo(0,0) // scroll-view需重置滚动条到顶部,避免startTop大于0时,对下拉刷新的影响
+ }
+ }
+ // 结束下拉刷新时的回调
+ let delay = 0;
+ if (me.optDown.beforeEndDownScroll) delay = me.optDown.beforeEndDownScroll(me); // 结束下拉刷新的延时,单位ms
+ if (typeof delay === 'number' && delay > 0) {
+ setTimeout(endScroll, delay);
+ } else {
+ endScroll();
+ }
+}
+
+MeScroll.prototype.endDownScrollCall = function() {
+ this.optDown.endDownScroll && this.optDown.endDownScroll(this);
+ this.optDown.afterEndDownScroll && this.optDown.afterEndDownScroll(this);
+}
+
+/* 锁定下拉刷新:isLock=ture,null锁定;isLock=false解锁 */
+MeScroll.prototype.lockDownScroll = function(isLock) {
+ if (isLock == null) isLock = true;
+ this.optDown.isLock = isLock;
+}
+
+/* 锁定上拉加载:isLock=ture,null锁定;isLock=false解锁 */
+MeScroll.prototype.lockUpScroll = function(isLock) {
+ if (isLock == null) isLock = true;
+ this.optUp.isLock = isLock;
+}
+
+/* -------初始化上拉加载------- */
+MeScroll.prototype.initUpScroll = function() {
+ let me = this;
+ // 配置参数
+ me.optUp = me.options.up || {use: false}
+ if(!me.optUp.textColor && me.hasColor(me.optUp.bgColor)) me.optUp.textColor = "#fff"; // 当bgColor有值且textColor未设置,则textColor默认白色
+ me.extendUpScroll(me.optUp);
+
+ if (me.optUp.use === false) return; // 配置不使用上拉加载时,则不初始化上拉布局
+ me.optUp.hasNext = true; // 如果使用上拉,则默认有下一页
+ me.startNum = me.optUp.page.num + 1; // 记录page开始的页码
+
+ // 初始化完毕的回调
+ if (me.optUp.inited) {
+ setTimeout(function() { // 待主线程执行完毕再执行,避免new MeScroll未初始化,在回调获取不到mescroll的实例
+ me.optUp.inited(me);
+ }, 0)
+ }
+}
+
+/*滚动到底部的事件 (仅mescroll-body生效)*/
+MeScroll.prototype.onReachBottom = function() {
+ if (this.isScrollBody && !this.isUpScrolling) { // 只能支持下拉刷新的时候同时可以触发上拉加载,否则滚动到底部就需要上滑一点才能触发onReachBottom
+ if (!this.optUp.isLock && this.optUp.hasNext) {
+ this.triggerUpScroll();
+ }
+ }
+}
+
+/*列表滚动事件 (仅mescroll-body生效)*/
+MeScroll.prototype.onPageScroll = function(e) {
+ if (!this.isScrollBody) return;
+
+ // 更新滚动条的位置 (主要用于判断下拉刷新时,滚动条是否在顶部)
+ this.setScrollTop(e.scrollTop);
+
+ // 顶部按钮的显示隐藏
+ if (e.scrollTop >= this.optUp.toTop.offset) {
+ this.showTopBtn();
+ } else {
+ this.hideTopBtn();
+ }
+}
+
+/*列表滚动事件*/
+MeScroll.prototype.scroll = function(e, onScroll) {
+ // 更新滚动条的位置
+ this.setScrollTop(e.scrollTop);
+ // 更新滚动内容高度
+ this.setScrollHeight(e.scrollHeight);
+
+ // 向上滑还是向下滑动
+ if (this.preScrollY == null) this.preScrollY = 0;
+ this.isScrollUp = e.scrollTop - this.preScrollY > 0;
+ this.preScrollY = e.scrollTop;
+
+ // 上滑 && 检查并触发上拉
+ this.isScrollUp && this.triggerUpScroll(true);
+
+ // 顶部按钮的显示隐藏
+ if (e.scrollTop >= this.optUp.toTop.offset) {
+ this.showTopBtn();
+ } else {
+ this.hideTopBtn();
+ }
+
+ // 滑动监听
+ this.optUp.onScroll && onScroll && onScroll()
+}
+
+/* 触发上拉加载 */
+MeScroll.prototype.triggerUpScroll = function(isCheck) {
+ if (!this.isUpScrolling && this.optUp.use && this.optUp.callback) {
+ // 是否校验在底部; 默认不校验
+ if (isCheck === true) {
+ let canUp = false;
+ // 还有下一页 && 没有锁定 && 不在下拉中
+ if (this.optUp.hasNext && !this.optUp.isLock && !this.isDownScrolling) {
+ if (this.getScrollBottom() <= this.optUp.offset) { // 到底部
+ canUp = true; // 标记可上拉
+ }
+ }
+ if (canUp === false) return;
+ }
+ this.showUpScroll(); // 上拉加载中...
+ this.optUp.page.num++; // 预先加一页,如果失败则减回
+ this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
+ this.num = this.optUp.page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
+ this.size = this.optUp.page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
+ this.time = this.optUp.page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
+ this.optUp.callback(this); // 执行回调,联网加载数据
+ }
+}
+
+/* 显示上拉加载中 */
+MeScroll.prototype.showUpScroll = function() {
+ this.isUpScrolling = true; // 标记上拉加载中
+ this.optUp.showLoading && this.optUp.showLoading(this); // 回调
+}
+
+/* 显示上拉无更多数据 */
+MeScroll.prototype.showNoMore = function() {
+ this.optUp.hasNext = false; // 标记无更多数据
+ this.optUp.showNoMore && this.optUp.showNoMore(this); // 回调
+}
+
+/* 隐藏上拉区域**/
+MeScroll.prototype.hideUpScroll = function() {
+ this.optUp.hideUpScroll && this.optUp.hideUpScroll(this); // 回调
+}
+
+/* 结束上拉加载 */
+MeScroll.prototype.endUpScroll = function(isShowNoMore) {
+ if (isShowNoMore != null) { // isShowNoMore=null,不处理下拉状态,下拉刷新的时候调用
+ if (isShowNoMore) {
+ this.showNoMore(); // isShowNoMore=true,显示无更多数据
+ } else {
+ this.hideUpScroll(); // isShowNoMore=false,隐藏上拉加载
+ }
+ }
+ this.isUpScrolling = false; // 标记结束上拉加载
+}
+
+/* 重置上拉加载列表为第一页
+ *isShowLoading 是否显示进度布局;
+ * 1.默认null,不传参,则显示上拉加载的进度布局
+ * 2.传参true, 则显示下拉刷新的进度布局
+ * 3.传参false,则不显示上拉和下拉的进度 (常用于静默更新列表数据)
+ */
+MeScroll.prototype.resetUpScroll = function(isShowLoading) {
+ if (this.optUp && this.optUp.use) {
+ let page = this.optUp.page;
+ this.prePageNum = page.num; // 缓存重置前的页码,加载失败可退回
+ this.prePageTime = page.time; // 缓存重置前的时间,加载失败可退回
+ page.num = this.startNum; // 重置为第一页
+ page.time = null; // 重置时间为空
+ if (!this.isDownScrolling && isShowLoading !== false) { // 如果不是下拉刷新触发的resetUpScroll并且不配置列表静默更新,则显示进度;
+ if (isShowLoading == null) {
+ this.removeEmpty(); // 移除空布局
+ this.showUpScroll(); // 不传参,默认显示上拉加载的进度布局
+ } else {
+ this.showDownScroll(); // 传true,显示下拉刷新的进度布局,不清空列表
+ }
+ }
+ this.isUpAutoLoad = true; // 标记上拉已经自动执行过,避免初始化时多次触发上拉回调
+ this.num = page.num; // 把最新的页数赋值在mescroll上,避免对page的影响
+ this.size = page.size; // 把最新的页码赋值在mescroll上,避免对page的影响
+ this.time = page.time; // 把最新的页码赋值在mescroll上,避免对page的影响
+ this.optUp.callback && this.optUp.callback(this); // 执行上拉回调
+ }
+}
+
+/* 设置page.num的值 */
+MeScroll.prototype.setPageNum = function(num) {
+ this.optUp.page.num = num - 1;
+}
+
+/* 设置page.size的值 */
+MeScroll.prototype.setPageSize = function(size) {
+ this.optUp.page.size = size;
+}
+
+/* 联网回调成功,结束下拉刷新和上拉加载
+ * dataSize: 当前页的数据量(必传)
+ * totalPage: 总页数(必传)
+ * systime: 服务器时间 (可空)
+ */
+MeScroll.prototype.endByPage = function(dataSize, totalPage, systime) {
+ let hasNext;
+ if (this.optUp.use && totalPage != null) hasNext = this.optUp.page.num < totalPage; // 是否还有下一页
+ this.endSuccess(dataSize, hasNext, systime);
+}
+
+/* 联网回调成功,结束下拉刷新和上拉加载
+ * dataSize: 当前页的数据量(必传)
+ * totalSize: 列表所有数据总数量(必传)
+ * systime: 服务器时间 (可空)
+ */
+MeScroll.prototype.endBySize = function(dataSize, totalSize, systime) {
+ let hasNext;
+ if (this.optUp.use && totalSize != null) {
+ let loadSize = (this.optUp.page.num - 1) * this.optUp.page.size + dataSize; // 已加载的数据总数
+ hasNext = loadSize < totalSize; // 是否还有下一页
+ }
+ this.endSuccess(dataSize, hasNext, systime);
+}
+
+/* 联网回调成功,结束下拉刷新和上拉加载
+ * dataSize: 当前页的数据个数(不是所有页的数据总和),用于上拉加载判断是否还有下一页.如果不传,则会判断还有下一页
+ * hasNext: 是否还有下一页,布尔类型;用来解决这个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据dataSize判断,则需翻到第三页才会知道无更多数据,如果传了hasNext,则翻到第二页即可显示无更多数据.
+ * systime: 服务器时间(可空);用来解决这个小问题:当准备翻下一页时,数据库新增了几条记录,此时翻下一页,前面的几条数据会和上一页的重复;这里传入了systime,那么upCallback的page.time就会有值,把page.time传给服务器,让后台过滤新加入的那几条记录
+ */
+MeScroll.prototype.endSuccess = function(dataSize, hasNext, systime) {
+ let me = this;
+ // 结束下拉刷新
+ if (me.isDownScrolling) me.endDownScroll();
+
+ // 结束上拉加载
+ if (me.optUp.use) {
+ let isShowNoMore; // 是否已无更多数据
+ if (dataSize != null) {
+ let pageNum = me.optUp.page.num; // 当前页码
+ let pageSize = me.optUp.page.size; // 每页长度
+ // 如果是第一页
+ if (pageNum === 1) {
+ if (systime) me.optUp.page.time = systime; // 设置加载列表数据第一页的时间
+ }
+ if (dataSize < pageSize || hasNext === false) {
+ // 返回的数据不满一页时,则说明已无更多数据
+ me.optUp.hasNext = false;
+ if (dataSize === 0 && pageNum === 1) {
+ // 如果第一页无任何数据且配置了空布局
+ isShowNoMore = false;
+ me.showEmpty();
+ } else {
+ // 总列表数少于配置的数量,则不显示无更多数据
+ let allDataSize = (pageNum - 1) * pageSize + dataSize;
+ if (allDataSize < me.optUp.noMoreSize) {
+ isShowNoMore = false;
+ } else {
+ isShowNoMore = true;
+ }
+ me.removeEmpty(); // 移除空布局
+ }
+ } else {
+ // 还有下一页
+ isShowNoMore = false;
+ me.optUp.hasNext = true;
+ me.removeEmpty(); // 移除空布局
+ }
+ }
+
+ // 隐藏上拉
+ me.endUpScroll(isShowNoMore);
+ }
+}
+
+/* 回调失败,结束下拉刷新和上拉加载 */
+MeScroll.prototype.endErr = function(errDistance) {
+ // 结束下拉,回调失败重置回原来的页码和时间
+ if (this.isDownScrolling) {
+ let page = this.optUp.page;
+ if (page && this.prePageNum) {
+ page.num = this.prePageNum;
+ page.time = this.prePageTime;
+ }
+ this.endDownScroll();
+ }
+ // 结束上拉,回调失败重置回原来的页码
+ if (this.isUpScrolling) {
+ this.optUp.page.num--;
+ this.endUpScroll(false);
+ // 如果是mescroll-body,则需往回滚一定距离
+ if(this.isScrollBody && errDistance !== 0){ // 不处理0
+ if(!errDistance) errDistance = this.optUp.errDistance; // 不传,则取默认
+ this.scrollTo(this.getScrollTop() - errDistance, 0) // 往上回滚的距离
+ }
+ }
+}
+
+/* 显示空布局 */
+MeScroll.prototype.showEmpty = function() {
+ this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(true)
+}
+
+/* 移除空布局 */
+MeScroll.prototype.removeEmpty = function() {
+ this.optUp.empty.use && this.optUp.empty.onShow && this.optUp.empty.onShow(false)
+}
+
+/* 显示回到顶部的按钮 */
+MeScroll.prototype.showTopBtn = function() {
+ if (!this.topBtnShow) {
+ this.topBtnShow = true;
+ this.optUp.toTop.onShow && this.optUp.toTop.onShow(true);
+ }
+}
+
+/* 隐藏回到顶部的按钮 */
+MeScroll.prototype.hideTopBtn = function() {
+ if (this.topBtnShow) {
+ this.topBtnShow = false;
+ this.optUp.toTop.onShow && this.optUp.toTop.onShow(false);
+ }
+}
+
+/* 获取滚动条的位置 */
+MeScroll.prototype.getScrollTop = function() {
+ return this.scrollTop || 0
+}
+
+/* 记录滚动条的位置 */
+MeScroll.prototype.setScrollTop = function(y) {
+ this.scrollTop = y;
+}
+
+/* 滚动到指定位置 */
+MeScroll.prototype.scrollTo = function(y, t) {
+ this.myScrollTo && this.myScrollTo(y, t) // scrollview需自定义回到顶部方法
+}
+
+/* 自定义scrollTo */
+MeScroll.prototype.resetScrollTo = function(myScrollTo) {
+ this.myScrollTo = myScrollTo
+}
+
+/* 滚动条到底部的距离 */
+MeScroll.prototype.getScrollBottom = function() {
+ return this.getScrollHeight() - this.getClientHeight() - this.getScrollTop()
+}
+
+/* 计步器
+ star: 开始值
+ end: 结束值
+ callback(step,timer): 回调step值,计步器timer,可自行通过window.clearInterval(timer)结束计步器;
+ t: 计步时长,传0则直接回调end值;不传则默认300ms
+ rate: 周期;不传则默认30ms计步一次
+ * */
+MeScroll.prototype.getStep = function(star, end, callback, t, rate) {
+ let diff = end - star; // 差值
+ if (t === 0 || diff === 0) {
+ callback && callback(end);
+ return;
+ }
+ t = t || 300; // 时长 300ms
+ rate = rate || 30; // 周期 30ms
+ let count = t / rate; // 次数
+ let step = diff / count; // 步长
+ let i = 0; // 计数
+ let timer = setInterval(function() {
+ if (i < count - 1) {
+ star += step;
+ callback && callback(star, timer);
+ i++;
+ } else {
+ callback && callback(end, timer); // 最后一次直接设置end,避免计算误差
+ clearInterval(timer);
+ }
+ }, rate);
+}
+
+/* 滚动容器的高度 */
+MeScroll.prototype.getClientHeight = function(isReal) {
+ let h = this.clientHeight || 0
+ if (h === 0 && isReal !== true) { // 未获取到容器的高度,可临时取body的高度 (可能会有误差)
+ h = this.getBodyHeight()
+ }
+ return h
+}
+MeScroll.prototype.setClientHeight = function(h) {
+ this.clientHeight = h;
+}
+
+/* 滚动内容的高度 */
+MeScroll.prototype.getScrollHeight = function() {
+ return this.scrollHeight || 0;
+}
+MeScroll.prototype.setScrollHeight = function(h) {
+ this.scrollHeight = h;
+}
+
+/* body的高度 */
+MeScroll.prototype.getBodyHeight = function() {
+ return this.bodyHeight || 0;
+}
+MeScroll.prototype.setBodyHeight = function(h) {
+ this.bodyHeight = h;
+}
+
+/* 阻止浏览器默认滚动事件 */
+MeScroll.prototype.preventDefault = function(e) {
+ // 小程序不支持e.preventDefault, 已在wxs中禁止
+ // app的bounce只能通过配置pages.json的style.app-plus.bounce为"none"来禁止, 或使用renderjs禁止
+ // cancelable:是否可以被禁用; defaultPrevented:是否已经被禁用
+ if (e && e.cancelable && !e.defaultPrevented) e.preventDefault()
+}
\ No newline at end of file
diff --git a/components/mescroll-uni/mescroll-uni.vue b/components/mescroll-uni/mescroll-uni.vue
new file mode 100644
index 0000000..c1536e9
--- /dev/null
+++ b/components/mescroll-uni/mescroll-uni.vue
@@ -0,0 +1,413 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{downText}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ mescroll.optUp.textLoading }}
+
+
+ {{ mescroll.optUp.textNoMore }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/mescroll-uni/mixins/mescroll-comp.js b/components/mescroll-uni/mixins/mescroll-comp.js
new file mode 100644
index 0000000..6aea07b
--- /dev/null
+++ b/components/mescroll-uni/mixins/mescroll-comp.js
@@ -0,0 +1,50 @@
+/**
+ * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期:
+ * 当一个页面只有一个mescroll-body写在子组件时, 则使用mescroll-comp.js (参考 mescroll-comp 案例)
+ * 当一个页面有多个mescroll-body写在子组件时, 则使用mescroll-more.js (参考 mescroll-more 案例)
+ */
+const MescrollCompMixin = {
+ // 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件 (一级)
+ onPageScroll(e) {
+ this.handlePageScroll(e)
+ },
+ onReachBottom() {
+ this.handleReachBottom()
+ },
+ // 当down的native: true时, 还需传递此方法进到子组件
+ onPullDownRefresh(){
+ this.handlePullDownRefresh()
+ },
+ // mescroll-body写在子子子...组件的情况 (多级)
+ data() {
+ return {
+ mescroll: {
+ onPageScroll: e=>{
+ this.handlePageScroll(e)
+ },
+ onReachBottom: ()=>{
+ this.handleReachBottom()
+ },
+ onPullDownRefresh: ()=>{
+ this.handlePullDownRefresh()
+ }
+ }
+ }
+ },
+ methods:{
+ handlePageScroll(e){
+ let item = this.$refs["mescrollItem"];
+ if(item && item.mescroll) item.mescroll.onPageScroll(e);
+ },
+ handleReachBottom(){
+ let item = this.$refs["mescrollItem"];
+ if(item && item.mescroll) item.mescroll.onReachBottom();
+ },
+ handlePullDownRefresh(){
+ let item = this.$refs["mescrollItem"];
+ if(item && item.mescroll) item.mescroll.onPullDownRefresh();
+ }
+ }
+}
+
+export default MescrollCompMixin;
diff --git a/components/mescroll-uni/mixins/mescroll-more-item.js b/components/mescroll-uni/mixins/mescroll-more-item.js
new file mode 100644
index 0000000..2549158
--- /dev/null
+++ b/components/mescroll-uni/mixins/mescroll-more-item.js
@@ -0,0 +1,51 @@
+/**
+ * mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)
+ */
+const MescrollMoreItemMixin = {
+ // 支付宝小程序不支持props的mixin,需写在具体的页面中
+ // #ifndef MP-ALIPAY
+ props:{
+ i: Number, // 每个tab页的专属下标
+ index: { // 当前tab的下标
+ type: Number,
+ default(){
+ return 0
+ }
+ }
+ },
+ // #endif
+ data() {
+ return {
+ downOption:{
+ auto:false // 不自动加载
+ },
+ upOption:{
+ auto:false // 不自动加载
+ },
+ isInit: false // 当前tab是否已初始化
+ }
+ },
+ watch:{
+ // 监听下标的变化
+ index(val){
+ if (this.i === val && !this.isInit) {
+ this.isInit = true; // 标记为true
+ this.mescroll && this.mescroll.triggerDownScroll();
+ }
+ }
+ },
+ methods: {
+ // mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit)
+ mescrollInit(mescroll) {
+ this.mescroll = mescroll;
+ this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序
+ // 自动加载当前tab的数据
+ if(this.i === this.index){
+ this.isInit = true; // 标记为true
+ this.mescroll.triggerDownScroll();
+ }
+ },
+ }
+}
+
+export default MescrollMoreItemMixin;
diff --git a/components/mescroll-uni/mixins/mescroll-more.js b/components/mescroll-uni/mixins/mescroll-more.js
new file mode 100644
index 0000000..142aa75
--- /dev/null
+++ b/components/mescroll-uni/mixins/mescroll-more.js
@@ -0,0 +1,56 @@
+/**
+ * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期:
+ * 当一个页面只有一个mescroll-body写在子组件时, 则使用mescroll-comp.js (参考 mescroll-comp 案例)
+ * 当一个页面有多个mescroll-body写在子组件时, 则使用mescroll-more.js (参考 mescroll-more 案例)
+ */
+const MescrollMoreMixin = {
+ data() {
+ return {
+ tabIndex: 0 // 当前tab下标
+ }
+ },
+ // 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件
+ onPageScroll(e) {
+ let mescroll = this.getMescroll(this.tabIndex);
+ mescroll && mescroll.onPageScroll(e);
+ },
+ onReachBottom() {
+ let mescroll = this.getMescroll(this.tabIndex);
+ mescroll && mescroll.onReachBottom();
+ },
+ // 当down的native: true时, 还需传递此方法进到子组件
+ onPullDownRefresh(){
+ let mescroll = this.getMescroll(this.tabIndex);
+ mescroll && mescroll.onPullDownRefresh();
+ },
+ methods:{
+ // 根据下标获取对应子组件的mescroll
+ getMescroll(i){
+ if(!this.mescrollItems) this.mescrollItems = [];
+ if(!this.mescrollItems[i]) {
+ // v-for中的refs
+ let vForItem = this.$refs["mescrollItem"];
+ if(vForItem){
+ this.mescrollItems[i] = vForItem[i]
+ }else{
+ // 普通的refs,不可重复
+ this.mescrollItems[i] = this.$refs["mescrollItem"+i];
+ }
+ }
+ let item = this.mescrollItems[i]
+ return item ? item.mescroll : null
+ },
+ // 切换tab,恢复滚动条位置
+ tabChange(i){
+ let mescroll = this.getMescroll(i);
+ if(mescroll){
+ // 延时(比$nextTick靠谱一些),确保元素已渲染
+ setTimeout(()=>{
+ mescroll.scrollTo(mescroll.getScrollTop(),0)
+ },30)
+ }
+ }
+ }
+}
+
+export default MescrollMoreMixin;
diff --git a/components/mescroll-uni/wxs/mixins.js b/components/mescroll-uni/wxs/mixins.js
new file mode 100644
index 0000000..7f49ff7
--- /dev/null
+++ b/components/mescroll-uni/wxs/mixins.js
@@ -0,0 +1,102 @@
+// 定义在wxs (含renderjs) 逻辑层的数据和方法, 与视图层相互通信
+const WxsMixin = {
+ data() {
+ return {
+ // 传入wxs视图层的数据 (响应式)
+ wxsProp: {
+ optDown:{}, // 下拉刷新的配置
+ scrollTop:0, // 滚动条的距离
+ bodyHeight:0, // body的高度
+ isDownScrolling:false, // 是否正在下拉刷新中
+ isUpScrolling:false, // 是否正在上拉加载中
+ isScrollBody:true, // 是否为mescroll-body滚动
+ isUpBoth:true, // 上拉加载时,是否同时可以下拉刷新
+ t: 0 // 数据更新的标记 (只有数据更新了,才会触发wxs的Observer)
+ },
+
+ // 标记调用wxs视图层的方法
+ callProp: {
+ callType: '', // 方法名
+ t: 0 // 数据更新的标记 (只有数据更新了,才会触发wxs的Observer)
+ },
+
+ // 不用wxs的平台使用此处的wxsBiz对象,抹平wxs的写法 (微信小程序和APP使用的wxsBiz对象是./wxs/wxs.wxs)
+ // #ifndef MP-WEIXIN || APP-PLUS || H5
+ wxsBiz: {
+ //注册列表touchstart事件,用于下拉刷新
+ touchstartEvent: e=> {
+ this.mescroll.touchstartEvent(e);
+ },
+ //注册列表touchmove事件,用于下拉刷新
+ touchmoveEvent: e=> {
+ this.mescroll.touchmoveEvent(e);
+ },
+ //注册列表touchend事件,用于下拉刷新
+ touchendEvent: e=> {
+ this.mescroll.touchendEvent(e);
+ },
+ propObserver(){}, // 抹平wxs的写法
+ callObserver(){} // 抹平wxs的写法
+ },
+ // #endif
+
+ // 不用renderjs的平台使用此处的renderBiz对象,抹平renderjs的写法 (app 和 h5 使用的renderBiz对象是./wxs/renderjs.js)
+ // #ifndef APP-PLUS || H5
+ renderBiz: {
+ propObserver(){} // 抹平renderjs的写法
+ }
+ // #endif
+ }
+ },
+ methods: {
+ // wxs视图层调用逻辑层的回调
+ wxsCall(msg){
+ if(msg.type === 'setWxsProp'){
+ // 更新wxsProp数据 (值改变才触发更新)
+ this.wxsProp = {
+ optDown: this.mescroll.optDown,
+ scrollTop: this.mescroll.getScrollTop(),
+ bodyHeight: this.mescroll.getBodyHeight(),
+ isDownScrolling: this.mescroll.isDownScrolling,
+ isUpScrolling: this.mescroll.isUpScrolling,
+ isUpBoth: this.mescroll.optUp.isBoth,
+ isScrollBody:this.mescroll.isScrollBody,
+ t: Date.now()
+ }
+ }else if(msg.type === 'setLoadType'){
+ // 设置inOffset,outOffset的状态
+ this.downLoadType = msg.downLoadType
+ }else if(msg.type === 'triggerDownScroll'){
+ // 主动触发下拉刷新
+ this.mescroll.triggerDownScroll();
+ }else if(msg.type === 'endDownScroll'){
+ // 结束下拉刷新
+ this.mescroll.endDownScroll();
+ }else if(msg.type === 'triggerUpScroll'){
+ // 主动触发上拉加载
+ this.mescroll.triggerUpScroll(true);
+ }
+ }
+ },
+ mounted() {
+ // #ifdef MP-WEIXIN || APP-PLUS || H5
+ // 配置主动触发wxs显示加载进度的回调
+ this.mescroll.optDown.afterLoading = ()=>{
+ this.callProp = {callType: "showLoading", t: Date.now()} // 触发wxs的方法 (值改变才触发更新)
+ }
+ // 配置主动触发wxs隐藏加载进度的回调
+ this.mescroll.optDown.afterEndDownScroll = ()=>{
+ this.callProp = {callType: "endDownScroll", t: Date.now()} // 触发wxs的方法 (值改变才触发更新)
+ setTimeout(()=>{
+ if(this.downLoadType === 4 || this.downLoadType === 0){
+ this.callProp = {callType: "clearTransform", t: Date.now()} // 触发wxs的方法 (值改变才触发更新)
+ }
+ },320)
+ }
+ // 初始化wxs的数据
+ this.wxsCall({type: 'setWxsProp'})
+ // #endif
+ }
+}
+
+export default WxsMixin;
diff --git a/components/mescroll-uni/wxs/renderjs.js b/components/mescroll-uni/wxs/renderjs.js
new file mode 100644
index 0000000..207f388
--- /dev/null
+++ b/components/mescroll-uni/wxs/renderjs.js
@@ -0,0 +1,92 @@
+// 使用renderjs直接操作window对象,实现动态控制app和h5的bounce
+// bounce: iOS橡皮筋,Android半月弧,h5浏览器下拉背景等效果 (下拉刷新时禁止)
+// https://uniapp.dcloud.io/frame?id=renderjs
+
+// 与wxs的me实例一致
+var me = {}
+
+// 初始化window对象的touch事件 (仅初始化一次)
+if(window && !window.$mescrollRenderInit){
+ window.$mescrollRenderInit = true
+
+
+ window.addEventListener('touchstart', function(e){
+ if (me.disabled()) return;
+ me.startPoint = me.getPoint(e); // 记录起点
+ }, {passive: true})
+
+
+ window.addEventListener('touchmove', function(e){
+ if (me.disabled()) return;
+ if (me.getScrollTop() > 0) return; // 需在顶部下拉,才禁止bounce
+
+ var curPoint = me.getPoint(e); // 当前点
+ var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+ // 向下拉
+ if (moveY > 0) {
+ // 可下拉的条件
+ if (!me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling && me.isUpBoth))) {
+
+ // 只有touch在mescroll的view上面,才禁止bounce
+ var el = e.target;
+ var isMescrollTouch = false;
+ while (el && el.tagName && el.tagName !== 'UNI-PAGE-BODY' && el.tagName != "BODY") {
+ var cls = el.classList;
+ if (cls && cls.contains('mescroll-render-touch')) {
+ isMescrollTouch = true
+ break;
+ }
+ el = el.parentNode; // 继续检查其父元素
+ }
+ // 禁止bounce (不会对swiper和iOS侧滑返回造成影响)
+ if (isMescrollTouch && e.cancelable && !e.defaultPrevented) e.preventDefault();
+ }
+ }
+ }, {passive: false})
+}
+
+/* 获取滚动条的位置 */
+me.getScrollTop = function() {
+ return me.scrollTop || 0
+}
+
+/* 是否禁用下拉刷新 */
+me.disabled = function(){
+ return !me.optDown || !me.optDown.use || me.optDown.native
+}
+
+/* 根据点击滑动事件获取第一个手指的坐标 */
+me.getPoint = function(e) {
+ if (!e) {
+ return {x: 0,y: 0}
+ }
+ if (e.touches && e.touches[0]) {
+ return {x: e.touches[0].pageX,y: e.touches[0].pageY}
+ } else if (e.changedTouches && e.changedTouches[0]) {
+ return {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY}
+ } else {
+ return {x: e.clientX,y: e.clientY}
+ }
+}
+
+/**
+ * 监听逻辑层数据的变化 (实时更新数据)
+ */
+function propObserver(wxsProp) {
+ me.optDown = wxsProp.optDown
+ me.scrollTop = wxsProp.scrollTop
+ me.isDownScrolling = wxsProp.isDownScrolling
+ me.isUpScrolling = wxsProp.isUpScrolling
+ me.isUpBoth = wxsProp.isUpBoth
+}
+
+/* 导出模块 */
+const renderBiz = {
+ data() {
+ return {
+ propObserver: propObserver,
+ }
+ }
+}
+
+export default renderBiz;
\ No newline at end of file
diff --git a/components/mescroll-uni/wxs/wxs.wxs b/components/mescroll-uni/wxs/wxs.wxs
new file mode 100644
index 0000000..3fb4ad9
--- /dev/null
+++ b/components/mescroll-uni/wxs/wxs.wxs
@@ -0,0 +1,268 @@
+// 使用wxs处理交互动画, 提高性能, 同时避免小程序bounce对下拉刷新的影响
+// https://uniapp.dcloud.io/frame?id=wxs
+// https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.html
+
+// 模拟mescroll实例, 与mescroll.js的写法尽量保持一致
+var me = {}
+
+// ------ 自定义下拉刷新动画 start ------
+
+/* 下拉过程中的回调,滑动过程一直在执行 (rate<1为inOffset; rate>1为outOffset) */
+me.onMoving = function (ins, rate, downHight){
+ ins.requestAnimationFrame(function () {
+ ins.selectComponent('.mescroll-wxs-content').setStyle({
+ 'will-change': 'transform', // 可解决下拉过程中, image和swiper脱离文档流的问题
+ 'transform': 'translateY(' + downHight + 'px)',
+ 'transition': ''
+ })
+ // 环形进度条
+ var progress = ins.selectComponent('.mescroll-wxs-progress')
+ progress && progress.setStyle({transform: 'rotate(' + 360 * rate + 'deg)'})
+ })
+}
+
+/* 显示下拉刷新进度 */
+me.showLoading = function (ins){
+ me.downHight = me.optDown.offset
+ ins.requestAnimationFrame(function () {
+ ins.selectComponent('.mescroll-wxs-content').setStyle({
+ 'will-change': 'auto',
+ 'transform': 'translateY(' + me.downHight + 'px)',
+ 'transition': 'transform 300ms'
+ })
+ })
+}
+
+/* 结束下拉 */
+me.endDownScroll = function (ins){
+ me.downHight = 0;
+ me.isDownScrolling = false;
+ ins.requestAnimationFrame(function () {
+ ins.selectComponent('.mescroll-wxs-content').setStyle({
+ 'will-change': 'auto',
+ 'transform': 'translateY(0)', // 不可以写空串,否则scroll-view渲染不完整 (延时350ms会调clearTransform置空)
+ 'transition': 'transform 300ms'
+ })
+ })
+}
+
+/* 结束下拉动画执行完毕后, 清除transform和transition, 避免对列表内容样式造成影响, 如: h5的list-msg示例下拉进度条漏出来等 */
+me.clearTransform = function (ins){
+ ins.requestAnimationFrame(function () {
+ ins.selectComponent('.mescroll-wxs-content').setStyle({
+ 'will-change': '',
+ 'transform': '',
+ 'transition': ''
+ })
+ })
+}
+
+// ------ 自定义下拉刷新动画 end ------
+
+/**
+ * 监听逻辑层数据的变化 (实时更新数据)
+ */
+function propObserver(wxsProp) {
+ me.optDown = wxsProp.optDown
+ me.scrollTop = wxsProp.scrollTop
+ me.bodyHeight = wxsProp.bodyHeight
+ me.isDownScrolling = wxsProp.isDownScrolling
+ me.isUpScrolling = wxsProp.isUpScrolling
+ me.isUpBoth = wxsProp.isUpBoth
+ me.isScrollBody = wxsProp.isScrollBody
+ me.startTop = wxsProp.scrollTop // 及时更新touchstart触发的startTop, 避免scroll-view快速惯性滚动到顶部取值不准确
+}
+
+/**
+ * 监听逻辑层数据的变化 (调用wxs的方法)
+ */
+function callObserver(callProp, oldValue, ins) {
+ if (me.disabled()) return;
+ if(callProp.callType){
+ // 逻辑层(App Service)的style已失效,需在视图层(Webview)设置style
+ if(callProp.callType === 'showLoading'){
+ me.showLoading(ins)
+ }else if(callProp.callType === 'endDownScroll'){
+ me.endDownScroll(ins)
+ }else if(callProp.callType === 'clearTransform'){
+ me.clearTransform(ins)
+ }
+ }
+}
+
+/**
+ * touch事件
+ */
+function touchstartEvent(e, ins) {
+ me.downHight = 0; // 下拉的距离
+ me.startPoint = me.getPoint(e); // 记录起点
+ me.startTop = me.getScrollTop(); // 记录此时的滚动条位置
+ me.startAngle = 0; // 初始角度
+ me.lastPoint = me.startPoint; // 重置上次move的点
+ me.maxTouchmoveY = me.getBodyHeight() - me.optDown.bottomOffset; // 手指触摸的最大范围(写在touchstart避免body获取高度为0的情况)
+ me.inTouchend = false; // 标记不是touchend
+
+ me.callMethod(ins, {type: 'setWxsProp'}) // 同步更新wxsProp的数据 (小程序是异步的,可能touchmove先执行,才到propObserver; h5和app是同步)
+}
+
+function touchmoveEvent(e, ins) {
+ var isPrevent = true // false表示不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault (对小程序生效, h5和app无效)
+
+ if (me.disabled()) return isPrevent;
+
+ var scrollTop = me.getScrollTop(); // 当前滚动条的距离
+ var curPoint = me.getPoint(e); // 当前点
+
+ var moveY = curPoint.y - me.startPoint.y; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+
+ // 向下拉 && 在顶部
+ // mescroll-body,直接判定在顶部即可
+ // scroll-view在滚动时不会触发touchmove,当触顶/底/左/右时,才会触发touchmove
+ // scroll-view滚动到顶部时,scrollTop不一定为0,也有可能大于0; 在iOS的APP中scrollTop可能为负数,不一定和startTop相等
+ if (moveY > 0 && (
+ (me.isScrollBody && scrollTop <= 0)
+ ||
+ (!me.isScrollBody && (scrollTop <= 0 || (scrollTop <= me.optDown.startTop && scrollTop === me.startTop)) )
+ )) {
+ // 可下拉的条件
+ if (!me.inTouchend && !me.isDownScrolling && !me.optDown.isLock && (!me.isUpScrolling || (me.isUpScrolling &&
+ me.isUpBoth))) {
+
+ // 下拉的角度是否在配置的范围内
+ if(!me.startAngle) me.startAngle = me.getAngle(me.lastPoint, curPoint); // 两点之间的角度,区间 [0,90]
+ if (me.startAngle < me.optDown.minAngle) return isPrevent; // 如果小于配置的角度,则不往下执行下拉刷新
+
+ // 如果手指的位置超过配置的距离,则提前结束下拉,避免Webview嵌套导致touchend无法触发
+ if (me.maxTouchmoveY > 0 && curPoint.y >= me.maxTouchmoveY) {
+ me.inTouchend = true; // 标记执行touchend
+ touchendEvent(e, ins); // 提前触发touchend
+ return isPrevent;
+ }
+
+ isPrevent = false // 小程序是return false
+
+ var diff = curPoint.y - me.lastPoint.y; // 和上次比,移动的距离 (大于0向下,小于0向上)
+
+ // 下拉距离 < 指定距离
+ if (me.downHight < me.optDown.offset) {
+ if (me.movetype !== 1) {
+ me.movetype = 1; // 加入标记,保证只执行一次
+ // me.optDown.inOffset && me.optDown.inOffset(me); // 进入指定距离范围内那一刻的回调,只执行一次
+ me.callMethod(ins, {type: 'setLoadType', downLoadType: 1})
+ me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
+ }
+ me.downHight += diff * me.optDown.inOffsetRate; // 越往下,高度变化越小
+
+ // 指定距离 <= 下拉距离
+ } else {
+ if (me.movetype !== 2) {
+ me.movetype = 2; // 加入标记,保证只执行一次
+ // me.optDown.outOffset && me.optDown.outOffset(me); // 下拉超过指定距离那一刻的回调,只执行一次
+ me.callMethod(ins, {type: 'setLoadType', downLoadType: 2})
+ me.isMoveDown = true; // 标记下拉区域高度改变,在touchend重置回来
+ }
+ if (diff > 0) { // 向下拉
+ me.downHight += diff * me.optDown.outOffsetRate; // 越往下,高度变化越小
+ } else { // 向上收
+ me.downHight += diff; // 向上收回高度,则向上滑多少收多少高度
+ }
+ }
+
+ me.downHight = Math.round(me.downHight) // 取整
+ var rate = me.downHight / me.optDown.offset; // 下拉区域当前高度与指定距离的比值
+ // me.optDown.onMoving && me.optDown.onMoving(me, rate, me.downHight); // 下拉过程中的回调,一直在执行
+ me.onMoving(ins, rate, me.downHight)
+ }
+ }
+
+ me.lastPoint = curPoint; // 记录本次移动的点
+
+ return isPrevent // false表示不往上冒泡,相当于调用了同时调用了stopPropagation和preventDefault (对小程序生效, h5和app无效)
+}
+
+function touchendEvent(e, ins) {
+ // 如果下拉区域高度已改变,则需重置回来
+ if (me.isMoveDown) {
+ if (me.downHight >= me.optDown.offset) {
+ // 符合触发刷新的条件
+ me.downHight = me.optDown.offset; // 更新下拉区域高度
+ // me.triggerDownScroll();
+ me.callMethod(ins, {type: 'triggerDownScroll'})
+ } else {
+ // 不符合的话 则重置
+ me.downHight = 0;
+ // me.optDown.endDownScroll && me.optDown.endDownScroll(me);
+ me.callMethod(ins, {type: 'endDownScroll'})
+ }
+ me.movetype = 0;
+ me.isMoveDown = false;
+ } else if (!me.isScrollBody && me.getScrollTop() === me.startTop) { // scroll-view到顶/左/右/底的滑动事件
+ var isScrollUp = me.getPoint(e).y - me.startPoint.y < 0; // 和起点比,移动的距离,大于0向下拉,小于0向上拉
+ // 上滑
+ if (isScrollUp) {
+ // 需检查滑动的角度
+ var angle = me.getAngle(me.getPoint(e), me.startPoint); // 两点之间的角度,区间 [0,90]
+ if (angle > 80) {
+ // 检查并触发上拉
+ // me.triggerUpScroll(true);
+ me.callMethod(ins, {type: 'triggerUpScroll'})
+ }
+ }
+ }
+ me.callMethod(ins, {type: 'setWxsProp'}) // 同步更新wxsProp的数据 (小程序是异步的,可能touchmove先执行,才到propObserver; h5和app是同步)
+}
+
+/* 是否禁用下拉刷新 */
+me.disabled = function(){
+ return !me.optDown || !me.optDown.use || me.optDown.native
+}
+
+/* 根据点击滑动事件获取第一个手指的坐标 */
+me.getPoint = function(e) {
+ if (!e) {
+ return {x: 0,y: 0}
+ }
+ if (e.touches && e.touches[0]) {
+ return {x: e.touches[0].pageX,y: e.touches[0].pageY}
+ } else if (e.changedTouches && e.changedTouches[0]) {
+ return {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY}
+ } else {
+ return {x: e.clientX,y: e.clientY}
+ }
+}
+
+/* 计算两点之间的角度: 区间 [0,90]*/
+me.getAngle = function (p1, p2) {
+ var x = Math.abs(p1.x - p2.x);
+ var y = Math.abs(p1.y - p2.y);
+ var z = Math.sqrt(x * x + y * y);
+ var angle = 0;
+ if (z !== 0) {
+ angle = Math.asin(y / z) / Math.PI * 180;
+ }
+ return angle
+}
+
+/* 获取滚动条的位置 */
+me.getScrollTop = function() {
+ return me.scrollTop || 0
+}
+
+/* 获取body的高度 */
+me.getBodyHeight = function() {
+ return me.bodyHeight || 0;
+}
+
+/* 调用逻辑层的方法 */
+me.callMethod = function(ins, param) {
+ if(ins) ins.callMethod('wxsCall', param)
+}
+
+/* 导出模块 */
+module.exports = {
+ propObserver: propObserver,
+ callObserver: callObserver,
+ touchstartEvent: touchstartEvent,
+ touchmoveEvent: touchmoveEvent,
+ touchendEvent: touchendEvent
+}
\ No newline at end of file
diff --git a/components/notice-list/notice-list.vue b/components/notice-list/notice-list.vue
new file mode 100644
index 0000000..ce6819f
--- /dev/null
+++ b/components/notice-list/notice-list.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+ 暂无消息
+
+
+
+ {{ item[itemKey] }}
+
+
+
+
+
+
+
+
+
diff --git a/components/pick-regions/pick-regions.vue b/components/pick-regions/pick-regions.vue
new file mode 100755
index 0000000..035e068
--- /dev/null
+++ b/components/pick-regions/pick-regions.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/components/pick-regions/regions.json b/components/pick-regions/regions.json
new file mode 100755
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/popup-view/popup-view.vue b/components/popup-view/popup-view.vue
new file mode 100644
index 0000000..b144ed1
--- /dev/null
+++ b/components/popup-view/popup-view.vue
@@ -0,0 +1,474 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/tab-control/tab-control.vue b/components/tab-control/tab-control.vue
new file mode 100644
index 0000000..9bde305
--- /dev/null
+++ b/components/tab-control/tab-control.vue
@@ -0,0 +1,322 @@
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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..00747e4
--- /dev/null
+++ b/components/u-parse/components/wxParseImg.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
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..9be67be
--- /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/components/under-development/under-development.vue b/components/under-development/under-development.vue
new file mode 100644
index 0000000..a579c50
--- /dev/null
+++ b/components/under-development/under-development.vue
@@ -0,0 +1,55 @@
+
+
+
+
+ {{ tipsTitle }}
+
+
+
+
+
+
diff --git a/components/uni-grid-item/uni-grid-item.vue b/components/uni-grid-item/uni-grid-item.vue
new file mode 100644
index 0000000..1504ba5
--- /dev/null
+++ b/components/uni-grid-item/uni-grid-item.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/uni-grid/uni-grid.vue b/components/uni-grid/uni-grid.vue
new file mode 100644
index 0000000..e8dabd1
--- /dev/null
+++ b/components/uni-grid/uni-grid.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/uni-icons/icons.js b/components/uni-icons/icons.js
new file mode 100644
index 0000000..1f5a778
--- /dev/null
+++ b/components/uni-icons/icons.js
@@ -0,0 +1,96 @@
+export default {
+ 'contact': '\ue100',
+ 'person': '\ue101',
+ 'personadd': '\ue102',
+ 'contact-filled': '\ue130',
+ 'person-filled': '\ue131',
+ 'personadd-filled': '\ue132',
+ 'phone': '\ue200',
+ 'email': '\ue201',
+ 'chatbubble': '\ue202',
+ 'chatboxes': '\ue203',
+ 'phone-filled': '\ue230',
+ 'email-filled': '\ue231',
+ 'chatbubble-filled': '\ue232',
+ 'chatboxes-filled': '\ue233',
+ 'weibo': '\ue260',
+ 'weixin': '\ue261',
+ 'pengyouquan': '\ue262',
+ 'chat': '\ue263',
+ 'qq': '\ue264',
+ 'videocam': '\ue300',
+ 'camera': '\ue301',
+ 'mic': '\ue302',
+ 'location': '\ue303',
+ 'mic-filled': '\ue332',
+ 'speech': '\ue332',
+ 'location-filled': '\ue333',
+ 'micoff': '\ue360',
+ 'image': '\ue363',
+ 'map': '\ue364',
+ 'compose': '\ue400',
+ 'trash': '\ue401',
+ 'upload': '\ue402',
+ 'download': '\ue403',
+ 'close': '\ue404',
+ 'redo': '\ue405',
+ 'undo': '\ue406',
+ 'refresh': '\ue407',
+ 'star': '\ue408',
+ 'plus': '\ue409',
+ 'minus': '\ue410',
+ 'circle': '\ue411',
+ 'checkbox': '\ue411',
+ 'close-filled': '\ue434',
+ 'clear': '\ue434',
+ 'refresh-filled': '\ue437',
+ 'star-filled': '\ue438',
+ 'plus-filled': '\ue439',
+ 'minus-filled': '\ue440',
+ 'circle-filled': '\ue441',
+ 'checkbox-filled': '\ue442',
+ 'closeempty': '\ue460',
+ 'refreshempty': '\ue461',
+ 'reload': '\ue462',
+ 'starhalf': '\ue463',
+ 'spinner': '\ue464',
+ 'spinner-cycle': '\ue465',
+ 'search': '\ue466',
+ 'plusempty': '\ue468',
+ 'forward': '\ue470',
+ 'back': '\ue471',
+ 'left-nav': '\ue471',
+ 'checkmarkempty': '\ue472',
+ 'home': '\ue500',
+ 'navigate': '\ue501',
+ 'gear': '\ue502',
+ 'paperplane': '\ue503',
+ 'info': '\ue504',
+ 'help': '\ue505',
+ 'locked': '\ue506',
+ 'more': '\ue507',
+ 'flag': '\ue508',
+ 'home-filled': '\ue530',
+ 'gear-filled': '\ue532',
+ 'info-filled': '\ue534',
+ 'help-filled': '\ue535',
+ 'more-filled': '\ue537',
+ 'settings': '\ue560',
+ 'list': '\ue562',
+ 'bars': '\ue563',
+ 'loop': '\ue565',
+ 'paperclip': '\ue567',
+ 'eye': '\ue568',
+ 'arrowup': '\ue580',
+ 'arrowdown': '\ue581',
+ 'arrowleft': '\ue582',
+ 'arrowright': '\ue583',
+ 'arrowthinup': '\ue584',
+ 'arrowthindown': '\ue585',
+ 'arrowthinleft': '\ue586',
+ 'arrowthinright': '\ue587',
+ 'pulldown': '\ue588',
+ 'closefill': '\ue589',
+ 'sound': '\ue590',
+ 'scan': '\ue612'
+}
diff --git a/components/uni-icons/uni-icons.vue b/components/uni-icons/uni-icons.vue
new file mode 100644
index 0000000..85b4180
--- /dev/null
+++ b/components/uni-icons/uni-icons.vue
@@ -0,0 +1,57 @@
+
+ {{icons[type]}}
+
+
+
+
+
diff --git a/components/uni-nav-bar/uni-nav-bar.vue b/components/uni-nav-bar/uni-nav-bar.vue
new file mode 100644
index 0000000..0d4500d
--- /dev/null
+++ b/components/uni-nav-bar/uni-nav-bar.vue
@@ -0,0 +1,237 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/uni-status-bar/uni-status-bar.vue b/components/uni-status-bar/uni-status-bar.vue
new file mode 100644
index 0000000..4d9fb30
--- /dev/null
+++ b/components/uni-status-bar/uni-status-bar.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/virtual-button/virtual-button.vue b/components/virtual-button/virtual-button.vue
new file mode 100644
index 0000000..94eff05
--- /dev/null
+++ b/components/virtual-button/virtual-button.vue
@@ -0,0 +1,157 @@
+
+
+
+
+ 虚拟按钮
+
+
+
+
+
+
+
diff --git a/components/xinyu-logistics/xinyu-logistics.vue b/components/xinyu-logistics/xinyu-logistics.vue
new file mode 100644
index 0000000..14aa218
--- /dev/null
+++ b/components/xinyu-logistics/xinyu-logistics.vue
@@ -0,0 +1,306 @@
+
+
+
+
+
+
+
+ {{wlInfo.logisticsStatus == 1 ? '已签收' : '配送中'}}
+ {{name}}
+ {{wlInfo.brand}} {{wlInfo.no}}
+
+
+
+
+
+
+
+
+
+ [收货地址]{{address}}
+
+
+
+
+
+
+ {{index == 0 && logisticsStatus == 1 ? '已签收' : '配送中'}}
+ {{item.time.split(' ')[0]}} {{item.time.split(' ')[1]}}
+ {{item.context}}
+
+
+
+
+
+
+
+
+
+
diff --git a/config/baseConfig.js b/config/baseConfig.js
new file mode 100644
index 0000000..83e195f
--- /dev/null
+++ b/config/baseConfig.js
@@ -0,0 +1,63 @@
+// 环境判断:开发、生产
+const envType = process.env.NODE_ENV === 'development' ? 'develop' : 'produce';
+// console.log(envType);
+// 获取当前app的版本
+const systemInfo = uni.getSystemInfoSync();
+// 应用程序版本号
+// 条件编译,只在H5渲染
+const version_number = systemInfo.appVersion ? systemInfo.appVersion : '0.0.1';
+console.log(version_number,'版本号');
+const apiUrl = {
+ develop: {
+ // apiBaseUrl:'http://192.168.2.17:8080', // cky
+ // apiBaseUrl:'http://192.168.2.130:8905', // 130
+ // apiBaseUrl: 'http://192.168.2.51:9321', // 正式
+ // apiBaseUrl:'http://192.168.2.130:8905', // 130
+ // apiBaseUrl: 'http://192.168.2.51:9321', // 正式
+ // apiBaseUrl: 'http://192.168.2.130:8905',
+ apiBaseUrl: 'https://api.app.blindbox.06zk.com', // 正式
+ // apiBaseUrl:'https://test.blindbox.06zk.com/api', // 101
+ // apiBaseUrl:'http://192.168.2.71:8080', // 101
+
+ wsUrl: 'ws://xxx', // 正式WebSocket连接地址
+ weChatCode: 'https://auth.wechat.06zk.com',
+ apiVersion:'0.0.1',
+ appVersion:version_number
+ },
+ produce: {
+ // apiBaseUrl:'http://192.168.2.130:8905', // 130
+ // apiBaseUrl: 'https://api.app.blindbox.06zk.com', // 正式
+ // apiBaseUrl:'https://test.blindbox.06zk.com/api', // 101
+ // apiBaseUrl: 'http://192.168.2.51:9321', // 正式
+ apiBaseUrl: 'https://api.app.blindbox.06zk.com', // 正式
+ // apiBaseUrl:'https://test.blindbox.06zk.com/api', // 101
+ // apiBaseUrl: 'http://192.168.2.51:9321', // 正式
+ wsUrl: 'ws://xxxx', // 正式WebSocket连接地址
+ weChatCode: 'https://auth.wechat.06zk.com',
+ apiVersion:'0.0.1',
+ appVersion:version_number
+ // weChatCode: 'https://auth.wechat.miyamama.cn' //正式
+ }
+};
+
+const ApiVersion = function() {
+ return apiUrl[envType]['apiVersion']
+};
+const AppVersion = function() {
+ return apiUrl[envType]['appVersion']
+};
+const baseUrl = function(nameSpace) {
+ return apiUrl[envType][nameSpace]
+};
+
+// 其他服务地址配置
+const otherServerUrl = {
+ // gameUrl: 'http://web.wgmwdt.com/games'
+}
+
+export {
+ baseUrl,
+ otherServerUrl,
+ ApiVersion,
+ AppVersion
+};
\ No newline at end of file
diff --git a/get-weixin-code.html b/get-weixin-code.html
new file mode 100755
index 0000000..eeca52e
--- /dev/null
+++ b/get-weixin-code.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+ 微信登录
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/js_sdk/nl-precisionNum/package.json b/js_sdk/nl-precisionNum/package.json
new file mode 100644
index 0000000..dd62125
--- /dev/null
+++ b/js_sdk/nl-precisionNum/package.json
@@ -0,0 +1,19 @@
+{
+ "id": "nl-precisionNum",
+ "name": "防止加减乘除精度丢失",
+ "version": "1.0.2",
+ "description": "运算时防止数据精度丢失",
+ "keywords": [
+ "numAdd",
+ "numSub",
+ "numMulti",
+ "numDiv"
+ ],
+ "dcloudext": {
+ "category": [
+ "JS SDK",
+ "通用 SDK"
+ ]
+ },
+ "displayName": "防止加减乘除精度丢失"
+}
\ No newline at end of file
diff --git a/js_sdk/nl-precisionNum/precisionNum.js b/js_sdk/nl-precisionNum/precisionNum.js
new file mode 100644
index 0000000..2f34f2d
--- /dev/null
+++ b/js_sdk/nl-precisionNum/precisionNum.js
@@ -0,0 +1,104 @@
+/*
+ * 判断obj是否为一个整数 整数取整后还是等于自己。利用这个特性来判断是否是整数
+ */
+function isInteger(obj) {
+ // 或者使用 Number.isInteger()
+ return Math.floor(obj) === obj
+}
+/*
+ * 将一个浮点数转成整数,返回整数和倍数。如 3.14 >> 314,倍数是 100
+ * @param floatNum {number} 小数
+ * @return {object}
+ * {times:100, num: 314}
+ */
+function toInteger(floatNum) {
+ // 初始化数字与精度 times精度倍数 num转化后的整数
+ var ret = {
+ times: 1,
+ num: 0
+ }
+ var isNegative = floatNum < 0 //是否是小数
+ if (isInteger(floatNum)) { // 是否是整数
+ ret.num = floatNum
+ return ret //是整数直接返回
+ }
+ var strfi = floatNum + '' // 转换为字符串
+ var dotPos = strfi.indexOf('.')
+ var len = strfi.substr(dotPos + 1).length // 拿到小数点之后的位数
+ var times = Math.pow(10, len) // 精度倍数
+ /* 为什么加0.5?
+ 前面讲过乘法也会出现精度问题
+ 假设传入0.16344556此时倍数为100000000
+ Math.abs(0.16344556) * 100000000=0.16344556*10000000=1634455.5999999999
+ 少了0.0000000001
+ 加上0.5 0.16344556*10000000+0.5=1634456.0999999999 parseInt之后乘法的精度问题得以矫正
+ */
+ var intNum = parseInt(Math.abs(floatNum) * times + 0.5, 10)
+ ret.times = times
+ if (isNegative) {
+ intNum = -intNum
+ }
+ ret.num = intNum
+ return ret
+}
+
+/*
+ * 核心方法,实现加减乘除运算,确保不丢失精度
+ * 思路:把小数放大为整数(乘),进行算术运算,再缩小为小数(除)
+ * @param a {number} 运算数1
+ * @param b {number} 运算数2
+ */
+function operation(a, b, op) {
+ var o1 = toInteger(a)
+ var o2 = toInteger(b)
+ var n1 = o1.num // 3.25+3.153
+ var n2 = o2.num
+ var t1 = o1.times
+ var t2 = o2.times
+ var max = t1 > t2 ? t1 : t2
+ var result = null
+ switch (op) {
+ // 加减需要根据倍数关系来处理
+ case 'add':
+ if (t1 === t2) { // 两个小数倍数相同
+ result = n1 + n2
+ } else if (t1 > t2) {
+ // o1 小数位 大于 o2
+ result = n1 + n2 * (t1 / t2)
+ } else { // o1小数位小于 o2
+ result = n1 * (t2 / t1) + n2
+ }
+ return result / max
+ case 'subtract':
+ if (t1 === t2) {
+ result = n1 - n2
+ } else if (t1 > t2) {
+ result = n1 - n2 * (t1 / t2)
+ } else {
+ result = n1 * (t2 / t1) - n2
+ }
+ return result / max
+ case 'multiply':
+ // 325*3153/(100*1000) 扩大100倍 ==>缩小100倍
+ result = (n1 * n2) / (t1 * t2)
+ return result
+ case 'divide':
+ // (325/3153)*(1000/100) 缩小100倍 ==>扩大100倍
+ result = (n1 / n2) * (t2 / t1)
+ return result
+ }
+}
+
+// 加减乘除的四个接口
+export function numAdd(a, b) {
+ return operation(a, b, 'add')
+}
+export function numSub(a, b) {
+ return operation(a, b, 'subtract')
+}
+export function numMulti(a, b) {
+ return operation(a, b, 'multiply')
+}
+export function numDiv(a, b) {
+ return operation(a*100, b*100, 'divide')
+}
diff --git a/login.html b/login.html
new file mode 100755
index 0000000..177113f
--- /dev/null
+++ b/login.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..06ae30e
--- /dev/null
+++ b/main.js
@@ -0,0 +1,38 @@
+import Vue from 'vue'
+import App from './App'
+
+import msgUtils from './utils/msgUtils.js'
+import path from './utils/skip'
+import '@/utils/filter/filterUtils.js'
+
+// 注册全局组件
+import MescrollBody from "@/components/mescroll-uni/mescroll-body.vue"
+import MescrollUni from "@/components/mescroll-uni/mescroll-uni.vue"
+Vue.component('mescroll-body', MescrollBody)
+Vue.component('mescroll-uni', MescrollUni)
+
+
+
+
+// #ifdef H5
+// 提交前需要注释 本地调试使用
+// const vconsole = require('vconsole')
+// Vue.prototype.$vconsole = new vconsole() // 使用vconsole
+// #endif
+
+import CustomNavbarPage from '@/pages/components/customNavbarPage.vue'
+import CropStatusbarHeight from '@/pages/components/crop-statusbar-height/crop-statusbar-height.vue'
+Vue.component('custom-navbar-page', CustomNavbarPage)
+Vue.component('crop-statusbar-height', CropStatusbarHeight)
+
+Vue.config.productionTip = false
+Vue.prototype.$api = msgUtils
+Vue.prototype.$path = path
+
+App.mpType = 'app'
+
+const app = new Vue({
+ ...App,
+ path
+})
+app.$mount()
diff --git a/make-dev.sh b/make-dev.sh
new file mode 100644
index 0000000..84c2175
--- /dev/null
+++ b/make-dev.sh
@@ -0,0 +1,3 @@
+docker build -t registry.cn-shanghai.aliyuncs.com/box-mall/box-mall-app-web:2.0 --platform=linux/amd64 .
+
+docker push registry.cn-shanghai.aliyuncs.com/box-mall/box-mall-app-web:2.0
\ No newline at end of file
diff --git a/make-test.sh b/make-test.sh
new file mode 100644
index 0000000..731836c
--- /dev/null
+++ b/make-test.sh
@@ -0,0 +1,3 @@
+docker build -t registry.cn-shanghai.aliyuncs.com/box-mall/box-mall-app-web:1.0 --platform=linux/amd64 .
+
+docker push registry.cn-shanghai.aliyuncs.com/box-mall/box-mall-app-web:1.0
\ No newline at end of file
diff --git a/make.sh b/make.sh
new file mode 100644
index 0000000..bf1c9a2
--- /dev/null
+++ b/make.sh
@@ -0,0 +1,3 @@
+docker build -t registry.cn-shanghai.aliyuncs.com/miyamama_box/box-mall-app-web:1.0 --platform=linux/amd64 .
+
+docker push registry.cn-shanghai.aliyuncs.com/miyamama_box/box-mall-app-web:1.0
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..7fee793
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,181 @@
+{
+ "name" : "妙趣盲盒",
+ "appid" : "__UNI__8AC2CA7",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : 100,
+ "transformPx" : false,
+ /* 5+App特有相关 */
+ "app-plus" : {
+ "safearea" : {
+ "bottom" : {
+ "offset" : "auto"
+ }
+ },
+ "usingComponents" : true,
+ "nvueCompiler" : "uni-app",
+ "compilerVersion" : 3,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : false,
+ "waiting" : false,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ /* 模块配置 */
+ "modules" : {
+ "Maps" : {},
+ "OAuth" : {},
+ "Payment" : {},
+ "Share" : {}
+ },
+ /* 应用发布信息 */
+ "distribute" : {
+ /* android打包配置 */
+ "android" : {
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ],
+ "autoSdkPermissions" : false
+ },
+ /* ios打包配置 */
+ "ios" : {},
+ /* SDK配置 */
+ "sdkConfigs" : {
+ "ad" : {},
+ "maps" : {
+ "amap" : {
+ "appkey_ios" : "40a745f83e5c11c12aa6c7dea464dbb9",
+ "appkey_android" : "40a745f83e5c11c12aa6c7dea464dbb9"
+ }
+ },
+ "oauth" : {
+ "weixin" : {
+ "appid" : "wx836b447885f16f22",
+ "UniversalLinks" : ""
+ }
+ },
+ "payment" : {
+ "weixin" : {
+ "__platform__" : [ "ios", "android" ],
+ "appid" : "wx836b447885f16f22",
+ "UniversalLinks" : ""
+ },
+ "alipay" : {
+ "__platform__" : [ "ios", "android" ]
+ }
+ },
+ "share" : {
+ "weixin" : {
+ "appid" : "wx836b447885f16f22",
+ "UniversalLinks" : ""
+ }
+ }
+ },
+ "splashscreen" : {
+ "androidStyle" : "common",
+ "android" : {
+ "hdpi" : "static/common/splash.9.png",
+ "xhdpi" : "static/common/splash.9.png",
+ "xxhdpi" : "static/common/splash.9.png"
+ }
+ },
+ "icons" : {
+ "android" : {
+ "hdpi" : "unpackage/res/icons/72x72.png",
+ "xhdpi" : "unpackage/res/icons/96x96.png",
+ "xxhdpi" : "unpackage/res/icons/144x144.png",
+ "xxxhdpi" : "unpackage/res/icons/192x192.png"
+ },
+ "ios" : {
+ "appstore" : "unpackage/res/icons/1024x1024.png",
+ "ipad" : {
+ "app" : "unpackage/res/icons/76x76.png",
+ "app@2x" : "unpackage/res/icons/152x152.png",
+ "notification" : "unpackage/res/icons/20x20.png",
+ "notification@2x" : "unpackage/res/icons/40x40.png",
+ "proapp@2x" : "unpackage/res/icons/167x167.png",
+ "settings" : "unpackage/res/icons/29x29.png",
+ "settings@2x" : "unpackage/res/icons/58x58.png",
+ "spotlight" : "unpackage/res/icons/40x40.png",
+ "spotlight@2x" : "unpackage/res/icons/80x80.png"
+ },
+ "iphone" : {
+ "app@2x" : "unpackage/res/icons/120x120.png",
+ "app@3x" : "unpackage/res/icons/180x180.png",
+ "notification@2x" : "unpackage/res/icons/40x40.png",
+ "notification@3x" : "unpackage/res/icons/60x60.png",
+ "settings@2x" : "unpackage/res/icons/58x58.png",
+ "settings@3x" : "unpackage/res/icons/87x87.png",
+ "spotlight@2x" : "unpackage/res/icons/80x80.png",
+ "spotlight@3x" : "unpackage/res/icons/120x120.png"
+ }
+ }
+ }
+ },
+ "uniStatistics" : {
+ "enable" : false
+ }
+ },
+ /* 快应用特有相关 */
+ "quickapp" : {},
+ /* 小程序特有相关 */
+ "mp-weixin" : {
+ "appid" : "wx836b447885f16f22",
+ "setting" : {
+ "urlCheck" : false,
+ "es6" : true
+ },
+ "usingComponents" : true,
+ "permission" : {
+ "scope.userLocation" : {
+ "desc" : "获取与门店距离"
+ }
+ },
+ "requiredPrivateInfos" : [ "getLocation" ]
+ },
+ "mp-alipay" : {
+ "usingComponents" : true
+ },
+ "mp-baidu" : {
+ "usingComponents" : true
+ },
+ "mp-toutiao" : {
+ "usingComponents" : true
+ },
+ "uniStatistics" : {
+ "enable" : false
+ },
+ "h5" : {
+ "router" : {
+ "mode" : "hash",
+ "base" : "./"
+ }
+ },
+ "uniCloud" : {
+ "provider" : "aliyun",
+ "spaceId" : "mp-ee8153d2-d55b-4e47-82d3-64303d9910ea",
+ "clientSecret" : "c8SiFkxUtsnS/CBjDJBgbg=="
+ }
+}
diff --git a/mixins/mixins.js b/mixins/mixins.js
new file mode 100755
index 0000000..d8498cb
--- /dev/null
+++ b/mixins/mixins.js
@@ -0,0 +1,76 @@
+export const myMixins = {
+ components: {},
+ data() {
+ return {
+ mixinsTimer:null,
+ mixinsTime:0,
+ btnTimer:null
+ };
+ },
+ onShow(){
+ // pages/index/index //首页
+ // pages/index/detail //盲盒详情
+ // pages/index/card //使用提示卡
+ // pages/index/confirmOrder //盲盒确认订单
+ // pages/index/confirmOrder //盲盒支付成功页面
+ // pages/index/prize //开奖页面
+
+ // pages/product/product //商品列表
+ // pages/search/index//商品搜索
+ // pages/search/search-list//商品搜索列表
+ // pages/product/detail //商品详情页
+ // pages/order/confirm //商品确认订单
+ // pages/shop/paySuccess //商品支付成功页面
+
+
+ // pages/mine/sign//签到
+
+
+ // pages/mine/index //个人中心
+ // pages/mine/setting //设置
+ // pages/mine/editName //修改昵称
+ // pages/agreement/index //用户协议
+ // pages/agreement/privacy //隐私政策
+ // pages/mine/about //关于我们
+ // pages/mine/point //积分使用记录
+ // pages/mine/coupon //优惠券
+ // pages/mine/moreCoupon //更多优惠券
+ // pages/mine/boxRecrd //物品
+ // pages/mine/boxConfirm//物品发货提交订单
+ // pages/order/index//我的订单
+ // pages/mine/orderStatusDetail//订单详情
+ // pages/mine/boxOrder//盲盒订单
+ // pages/mine/address//地址管理
+ // pages/mine/addAddress //编辑新增地址
+ // pages/mine/collect//收藏列表
+
+
+ const pages = getCurrentPages();
+ const currentPage = pages[pages.length - 1];
+ const url = currentPage.route; // 当前页面路径
+ const options = currentPage.options; // 当前页面参数
+ console.log(url);
+ this.mixinsTimer = setInterval(() => {
+ this.mixinsTime++
+ },1000)
+ },
+ onHide(){
+ clearInterval(this.mixinsTimer)
+ console.log(this.mixinsTime)
+ this.mixinsTimer = null
+ this.mixinsTime = 0
+ console.log('页面隐藏,即将返回上一页,');
+
+ this.btnTimer = Math.floor(Math.random() * (1 - 100000 + 1)) + 100000
+ clearInterval(this.btnTimer)
+
+ },
+ onUnload(){
+ console.log('页面卸载,即将返回上一页');
+ },
+ mounted() {
+
+ },
+ methods: {
+ },
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..becc6e2
--- /dev/null
+++ b/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "exchangeMatch",
+ "version": "1.0.0",
+ "description": "",
+ "main": "main.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "crypto-js": "^4.2.0",
+ "decimal": "^0.0.2",
+ "decimal.js": "^10.4.3",
+ "hqchart": "^1.1.8790",
+ "jquery": "^3.5.1",
+ "lottie-web": "^5.7.3",
+ "vconsole": "^3.14.6",
+ "wx-server-sdk": "^2.5.3"
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..7135f47
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,938 @@
+{
+ "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocati,n/pages
+
+ {
+ "path": "pages/index/new-index", // 首页
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "首页",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/sign", // 签到
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "签到",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/activity", // 活动
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "活动",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/webview", // 首页
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "客服",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/new-index-y", // 首页
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "首页",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/ranking", // 排行榜
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "排行榜",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/lastRanking", // 上期排行榜
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "上期排行榜",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/boxDetail", // 盲盒详情
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "详情",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/paySuc", //
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "支付",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/boxOrderConfirm",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "提交订单",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/boxPaySuccess",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "支付成功",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/draw",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "盲盒开奖",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/drawNine",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "盲盒开奖",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/drawFree",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "盲盒开奖",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/shop/index",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "商城",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/shop/detail",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "商品详情",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/shop/confirm",
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "提交订单",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/shop/search", // 搜索
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "搜索",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/shop/search-list", // 搜索
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "搜索",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/search/index", // 搜索
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "搜索",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/index", // 首页
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/card", // 提示卡
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "提示卡",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/index/order", // 盲盒购买订单
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/login/login", // 登录
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "登录",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/login/shut-down", // 封停
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "禁用",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/agreement/index", // 用户协议
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "用户协议",
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/agreement/privacy", // 隐私政策
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "隐私政策",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ // "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/login/bindPhone", // 绑定手机号
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/testPay/testPay", // 测试支付
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "支付",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/login/registerAndForget", // 忘记密码注册
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/shop/paySuccess", // 商城支付成功
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "支付成功",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none",
+ "scrollIndicator":"none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/index", // 我的
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/white", // 我的
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/virtual", // 商城支付成功
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "虚拟订单",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none",
+ "scrollIndicator":"none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/virtualDetail", // 商城支付成功
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "订单详情",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none",
+ "scrollIndicator":"none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/payVirtualSuccess", // 商城支付成功
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "兑换成功",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none",
+ "scrollIndicator":"none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/prompt", // 提示卡
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "提示卡",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/customer", // 我的
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "客服",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/editName", // 修改昵称
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "修改昵称",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/login/bind", // 绑定手机号
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/login/password", // 输入密码
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/search/search-list", // 搜索商品
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/order/confirm", //订单
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/order/index", //订单
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "onReachBottomDistance": 100,
+ "navigationBarTitleText": "我的订单",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/mine", //个人中心
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "个人中心",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/boxConfirm", //盲盒物品发货预览
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/boxOrder", //盲盒物品发货预览
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "盲盒购买订单",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/sign", //签到
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/point", //
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "积分使用记录",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/setting", //设置
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "设置",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/boxRecrd", //物品
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "我的物品",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+
+ {
+ "path": "pages/mine/collect", //收藏
+ "style": {
+ "navigationBarTextStyle": "white",
+ "navigationBarTitleText": "我的收藏",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/orderStatusDetail", //我的订单状态详情
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "订单详情",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/address", //收获地址
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "我的地址",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/addAddress", //新增地址
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "新增地址",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/notice", //公告
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/noticeDetail", //公告详情
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/about", //关于我们
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": true,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/coupon", //优惠券
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "我的优惠券",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/moreCoupon", //更多优惠券
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "更多优惠券",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/feedback", //意见反馈
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/topUp", //充值
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "充值",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/topUpOrder", //充值提交订单
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "提交订单",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/topUpSuc", //充值成功
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "充值成功",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+ {
+ "path": "pages/mine/orderBoxDetail", //盲盒订单详情
+ "style": {
+ "navigationBarTextStyle": "white",
+ "enablePullDownRefresh": false,
+ "navigationBarTitleText": "订单详情",
+ "app-plus": {
+ // 将回弹属性关掉
+ "bounce": "none"
+ }
+ }
+ },
+
+ // {
+ // "path" : "pages/index/index",
+ // "style" :
+ // {
+ // "navigationBarTitleText" : "",
+ // "enablePullDownRefresh" : false,
+ // "onReachBottomDistance": 100
+ // }
+ // },
+ {
+ "path" : "pages/index/detail",
+ "style" :
+ {
+ "navigationBarTitleText" : "",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/index/confirmOrder",
+ "style" :
+ {
+ "navigationBarTitleText" : "",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/index/prize",
+ "style" :
+ {
+ "navigationBarTitleText" : "",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/product/product",
+ "style" :
+ {
+ "navigationBarTitleText" : "",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/product/detail",
+ "style" :
+ {
+ "navigationBarTitleText" : "",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/agreement/nonage-rule",
+ "style" :
+ {
+ "navigationBarTitleText": "儿童个人信息保护规则",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/agreement/nonage",
+ "style" :
+ {
+ "navigationBarTitleText": "支付协议",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/agreement/total",
+ "style" :
+ {
+ "navigationBarTitleText": "协议",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/agreement/rule",
+ "style" :
+ {
+ "navigationBarTitleText": "规则",
+ "enablePullDownRefresh" : false
+ }
+ },
+ {
+ "path" : "pages/login/past-due",
+ "style" :
+ {
+ "navigationBarTitleText": "登录已过期",
+ "enablePullDownRefresh" : false
+ }
+ }
+
+
+ ],
+ "globalStyle": {
+ "navigationStyle": "custom",
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "妙趣盲盒",
+ "navigationBarBackgroundColor": "#FFFFFF",
+ "backgroundColor": "#F2F2F9"
+ },
+ "tabBar": {
+ "color": "#888888",
+ "selectedColor": "#333333",
+ "borderStyle": "white",
+ "backgroundColor": "#ffffff",
+ "iconWidth": "20px",
+ "list": [{
+ "pagePath": "pages/index/new-index",
+ "iconPath": "static/btnNavBarIcon/home.png",
+ "selectedIconPath": "static/btnNavBarIcon/home_active.png",
+ "text": "首页"
+ },
+ {
+ "pagePath": "pages/shop/index",
+ "iconPath": "static/btnNavBarIcon/shop.png",
+ "selectedIconPath": "static/btnNavBarIcon/shop_active.png",
+ "text": "商城"
+ },
+ {
+ "pagePath": "pages/mine/boxRecrd",
+ "iconPath": "static/btnNavBarIcon/qd.png",
+ "selectedIconPath": "static/btnNavBarIcon/qd_active.png",
+ "text": "仓库"
+ },
+ {
+ "pagePath": "pages/mine/mine",
+ "iconPath": "static/btnNavBarIcon/mine.png",
+ "selectedIconPath": "static/btnNavBarIcon/mine_acitve.png",
+ "text": "我的"
+ }
+ ]
+ },
+ "easycom": {
+ "autoscan": true,
+ "custom": {
+ "lb-picker": "@/components/lb-picker/index.vue",
+ "page-popup": "@/pages/components/pagePopUp.vue"
+ }
+ },
+ "condition": { //模式配置,仅开发期间生效
+ "current": 0, //当前激活的模式(list 的索引项)
+ "list": [{
+ "name": "", //模式名称
+ "path": "", //启动页面,必选
+ "query": "" //启动参数,在页面的onLoad函数里面得到
+ }]
+ }
+}
diff --git a/pages/agreement/index.vue b/pages/agreement/index.vue
new file mode 100644
index 0000000..77e3bff
--- /dev/null
+++ b/pages/agreement/index.vue
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+ 用户协议
+ 生效日期:2024年05月01日
+ 提示:请您认真阅读并充分理解本《用户协议》(简称“本协议”)全部内容,
+ 特别是免除或者限制妙趣盲盒平台(简称“本平台”)运营方责任的免责条款以及对用户的权利限制条款,该部分内容将以加粗形式提示您注意,请您重点阅读。
+ 请您在认真阅读并充分理解本协议内容之后决定是否接受本协议。
+ 如您是未成年人(未满18周岁)或因其他因素不具备完全民事行为能力的,须在法定监护人的陪同下阅读并决定是否接受本协议。仅在您及您的法定监护人完全接受本协议全部内容之后,您方可注册、及/或登录、及/或购买商品、及/或使用本平台提供的其他相关服务。您的注册、及/或登录、及/或订购商品、及/或使用本平台提供的其他相关服务的行为视为您及您的法定监护人对本协议全部内容的接受。
+ 本协议是您(下称“用户”)与妙趣盲盒平台合法运营方厦门正纯科技有限公司(简称“我们”)之间关于下载、安装、注册、登录、浏览妙趣盲盒平台以及使用妙趣盲盒平台购买商品及使用本平台提供的其他相关服务所订立的协议,本协议约定了我们与用户之间关于本平台服务方面的权利义务。“用户”是指下载、安装、注册、登录、浏览本平台或在本平台购买商品、使用本平台提供的其他相关服务的个人或组织。
+ 本协议内容可能根据本平台的业务调整而发生变更,用户可在本平台查阅最新版协议条款。更新后的协议条款一旦公布即代替原来的协议条款。协议条款更新后,如您不同意接受,您无法继续使用我们提供的服务。
+
+ 一、账号注册
+ .用户在使用本平台时由平台默认生成用户唯一妙趣盲盒账号,妙趣盲盒账号应当使用手机号码绑定注册,请用户使用尚未与妙趣盲盒账号绑定的手机号码,以及未被妙趣盲盒根据本协议封禁的手机号码注册妙趣盲盒账号。
+ .如果注册申请者有被妙趣盲盒封禁的先例或涉嫌虚假注册及滥用他人名义注册,及其他不能得到许可的理由,妙趣盲盒将拒绝其注册申请。
+ .用户不能修改系统自动分配给用户的ID。
+ .妙趣盲盒账号所有权属于本平台,在接受、同意本协议的前提下,本平台授予您账号使用权,以登录、浏览本平台以及使用本平台购买商品及使用本平台提供的其他相关服务。
+ .您应诚实地向本平台提供注册资料,并确认其提供的注册资料真实、准确、完整、合法有效,如用户注册资料需要变更的,请您及时更新。如果您提供的注册资料不合法、不真实或不准确的,您需承担因此引起的相应责任及后果,本平台保留拒绝您的注册申请及终止您使用本平台各项服务的权利。
+ .您应谨慎地保存、使用您的账号及密码,不应将您的账号及密码告知其他第三方。
+ .由于您的账户关联您的个人信息,为保障您的账户安全,您的账户仅限您本人使用,您不能通过任何有偿或无偿的方式将您的账号提供给第三方使用,包括但不限于赠与、借用、租用、转让、售卖等方式,否则由此导致的任何法律责任及法律后果均由您自行承担。
+ 二、使用规则
+ 1、用户充分理解并同意:本平台提供的服务是指本公司现在或将来向用户提供的包括但不限于购买商品(含“盲盒”)及“盲盒”功能相关的服务;用户必须为自己使用本产品项下发生一切行为负责,包括因您所传送至本平台的任何内容、信息等所导致的不利后果,该等不利后果包括但不限于赔偿、罚款、司法/仲裁程序费用、律师费、合理支出、给本平台造成的损害等。
+ 2、如用户在本平台上传信息的,需确保上传的所有信息的真实性、合法性、无害性、有效性等,我们不对用户上传的任何信息负有任何单独或连带之保证责任,用户因其所传播的信息而引发的相关法律责任由用户自行承担。
+ 3、用户充分理解并同意:因业务发展需要、突发情势等,我们可能会临时变更,暂停、限制或者终止本平台部分或全部服务,本平台将努力但不保证能做到事先通知。用户知悉并愿意承担该类风险。
+ 4、所有商品价格、数量、型号、规格、尺寸、颜色、介绍、是否有货等商品信息随时都有可能发生变动,任何变动本平台不作特别通知,请您至商品页面自行查看。本平台会尽最大努力保证您所浏览的商品信息的准确性;但由于商品种类繁多、商品信息的数量较大以及互联网技术因素等客观原因,商品信息页面显示可能会有一定的滞后性或差错,您对此表示知悉和理解。如您的订单涉及商品价格及商品信息显示滞后或差错的情况,您同意该种情况下已形成重大误解,本平台有权为您取消订单。
+ 5、如您选购“盲盒”,您可从该款“盲盒”的购买页面查看该“盲盒”的相关信息,包括但不限于打开“盲盒”后可能出现的物品(包括名称、型号、规格、尺寸、颜色、所属级别等物品介绍)及其所属级别的出现概率等,请您购买前仔细查看该款“盲盒”的全部信息。您知悉并同意,本平台展示的概率为该款“盲盒”内同一级别的各种物品的概率之和,且因显示限制,概率可能仅显示至小数点后三位。
+ 6、您可以通过付费方式购买代币,再使用代币进行盲盒的选购。具体方式为:用户通过微信支付、支付宝或其他本平台提供的付费途径支付一定数额的人民币购买本平台的虚拟货币--代币,然后根据本平台公布的资费标准以代币购买该盲盒。只有用户根据提示确认其同意按照签署支付方式支付费用并完成了支付行为,用户才能进行购买盲盒的操作。支付行为的完成以银行或第三方支付平台生成“支付已完成”的确认通知为准。所有收费服务支付完成后,不予退款。
+ 7、您通过打开“盲盒”获得的物品将会放置在仓库中,您可以在有效期内(具 体以仓库页面展示的期限为准)选择提货(指平台将用户打开“盲盒”得到的 物品寄送给用户)或将其兑换成本平台的积分。如选择提货,我们将根据您提供的收货信息以快递的方式向您邮寄“盲盒”开出的物品。如选择兑换为积分,本平台将会下发相应的积分至您的平台内积分账户中,兑换积分的数量将以兑换页面展示为准,请您兑换前仔细确认,一经选择兑换,我方提供的服务即视为完成,您不得要求我们提供退款或提货服务,因在该过程中,平台提供了商城维护等技术支持,平台将收取固定比例技术服务费。您知悉并同意,基于商品库存变动等因素考虑,如超出有效期的,商品可能作出一定调整,敬请谅解。
+ 8、积分无法通过购买或充值获得,其获取途径仅包括:① 用“盲盒”开出的物品兑换;②通过本平台可能随时举办的运营活动获取。积分无法兑换成人民币等真实货币,不可转让,仅可用于在商城内兑换商品及优惠券,不能再次购买“盲盒”。积分能够兑换的商品种类及其兑换价格以本平台商城页面展示为准,请您兑换前仔细确认。
+ 9、在您提交订单用积分兑换非“盲盒”商品时,请仔细确认所购商品的名称、价格、数量、型号、规格、尺寸、颜色(部分商品涉及到型号、规格、尺寸、颜色等但没有标明规格信息和提供选择,或标写“随机”或其他具有同等含义的词语时,由本平台随机配送);同时还须请您提供收货人的姓名、联系电话、收货地址等必要快递信息。若收货人并非您本人,收货人的行为和意思表示将视为您的行为和意思表示,您应对收货人的行为及意思表示产生的法律后果承担连带责任。您提交订单即表示对订单中所确认的订购商品、收货信息等内容的准确性负责。如果因为您填写的收货人姓名、联系电话、收货地址等信息错误,导致延期配送、不能配送、或商品交付给非您本意的收货人的,由此造成的损失需由您自行承担;因此造成任何损失或增加费用的,应由您完全独自承担。前述发货规则同样适用于提货。如因您未妥善选择商品的型号、规格、尺寸、颜色等,及/或您提供的地址信息不详或错误,导致无法发货的,本平台将通过平台信息推送等方式告知您,如您在本平台首次通知之日起3天内没有提供商品的型号、规格、尺寸、颜色等商品信息及/或提供确切可配送地址的,本平台有权为您取消订单。
+ 10、用户提货或用积分兑换非“盲盒”商品时,需据实支付运费(虚拟商品不需要支付运费),部分可能涉及运费减免的运营活动请以相关运营公告或订单页面为准。请您理解,无论是提货或用积分兑换非“盲盒”商品,因疫情、极端天气、库存等因素,部分地区可能无法提供寄送服务,具体寄送规则请查看相关运营公告或订单页面,您也可以选择咨询在线客服,还请您在充分了解寄送规则之后再行决定是否提货或用积分兑换非“盲盒”商品。如实际发生运费超过您已支付的运费,您同意补足运费后本平台方安排发货,本平台将通过平台信息推送等方式告知您,如您在本平台首次通知之日起3天内没有补足运费的,本平台有权为您取消订单。
+ 11、本平台将做出最大的努力保证所有上架商品的库存,但您知悉、理解并同意,由于市场变化及各种以合理商业努力难以控制因素的影响,无法避免的会出现您提交的订单信息中的商品出现缺货等情况,如您下单所购买的商品出现以上情况,本平台有权为您取消订单。
+ 12、您知悉并同意,如在购买时使用了任何形式的优惠券/抵用券/商品券等虚拟权益的,一旦订单取消,优惠券/抵用券/商品券等虚拟权益将不予返还。
+ 13、您充分理解并同意,本平台的相关页面如使用了相关品牌名称,目的仅为标识商品来源,除非有特别说明,本平台的正常运营及所有活动与包括但不限于苹果公司等品牌方无关。
+ 14、用户充分理解并同意:本平台提供的服务中可能包括广告。用户同意在使用服务过程中显示本平台和第三方供应商、合作伙伴提供的广告。同时,本平台有权添加网站logo(或名称)和时间的水印标志。本平台将尽力但不保证不影响您的使用体验。
+ 15、您使用本软件应当遵守宪法法律,遵守公共秩序,尊重社会公德,您不得利用本软件或使用本软件的服务实施下列行为:
+ (1)反对宪法所确定的基本原则;
+ (2)危害网络安全;
+ (3)危害国家安全、荣誉和利益;
+ (4)煽动颠覆国家政权、推翻社会主义制度;
+ (5)煽动分裂国家、破坏国家统一;
+ (6)泄露国家秘密;
+ (7)破坏国家宗教政策,宣扬恐怖主义、极端主义;宣扬邪教和封建迷信的;
+ (8)歪曲、丑化、亵渎、否定英雄烈士事迹和精神,以侮辱、诽谤或者其他方式侵害英雄烈士的姓名、肖像、名誉、荣誉的;
+ (9)宣扬民族仇恨、民族歧视、破坏民族团结的;
+ (10)传播暴力、淫秽色情信息;
+ (11)诱导未成年人违法犯罪和渲染暴力、色情、赌博、恐怖活动的;
+ (12)制作、发布、传播侵害儿童个人信息安全的信息;
+ (13)编造、传播虚假信息扰乱经济秩序和社会秩序;
+ (14)侵害他人名誉、隐私、知识产权和其他合法权益等活动;
+ (15)跟踪或以其他方式骚扰他人,非法侵入他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的行为;
+ (16)向他人提供专门用于从事侵入网络、干扰网络正常功能及防护措施、窃取网络数据等危害网络安全活动的程序、工具,或明知他人从事危害网络安全的活动的,为其提供技术支持、广告推广、支付结算等帮助的行为;
+ (17)用本公司提供的服务设立用于实施诈骗,传授犯罪方法,制作或者销售违禁物品、管制物品等违法犯罪活动的网站、通讯群组,或利用本公司的网络发布涉及实施诈骗,制作或者销售违禁物品、管制物品以及其他违法犯罪活动的信息;
+ (18)将有关干扰、破坏或限制任何计算机软件、硬件或通讯设备功能的软件病毒或其他计算机代码、档案和程序之资料,加以上载、张贴、发送电子邮件或以其他方式传送;
+ (19)不符合遵守法律法规、社会主义制度、国家利益、公民合法利益、公共秩序、社会道德风尚和信息真实性等“七条底线”要求的;
+ (20)含有法律、行政法规禁止的其他内容的信息;
+ (21)其他违反法律法规、政策及公序良俗、社会公德或干扰本软件正常运营和侵犯其他用户或第三方合法权益的信息。
+ 16、除非法律允许或本公司书面许可,您使用本平台过程中不得从事下列行为:
+ (1)诱导其他用户点击链接页面或分享信息的;
+ (2)未经本公司书面许可利用本软件和任何功能,以及第三方运营平台进行推广或互相推广的;
+ (3)发表、传送、传播骚扰、广告信息、过度营销信息及垃圾信息或含有任何性或性暗示的信息;
+ (4)制作、发布与以上行为相关的方法、工具,或对此类方法、工具进行运营或传播,无论这些行为是否为商业目的;
+ (5)其他干扰本软件正常运营或本公司未明示授权的行为。
+ 17、根据合理判断,本平台可以对违反法律法规、违反本协议约定,侵犯、妨害、威胁他人合法权利(包括但不限于知识产权、人身权等)的账号,依法采取中止服务、停止服务、封禁账号等措施以及依据法律法规保存有关信息并向有关部门报告等。
+ 18、用户权利及义务:
+ (1)用户应遵守本协议的各项条款,正确、适当地使用本服务,不得扰乱平台秩序。如用户违反本协议或其他平台规则的任何条款,本平台有权依据协议终止/暂停对违约用户提供全部或部分服务。
+ (2)用户在使用本平台提供的服务过程中,若发现涉政、涉枪、涉毒、涉暴、赌博、涉黄的内容,可以向本平台工作人员举报、投诉。本平台在收到举报、投诉后,将派专员及时处理。
+ (3)您不得利用本平台进行任何形式的洗钱活动。本平台将严密监控此类行为,并有权对多个定向账户中异常的、数额较大的虚拟资产流转进行调查,并有权配合主管机关的调查提交您的身份资料、有关账户的交易记录等信息。
+ 三、售后规则
+ 1、鉴于“盲盒”商品的特殊性,一经打开,不支持七天无理由退换货,您仅可选择提货或兑换为积分,对此您表示完全知悉、理解并同意。如您选择提货的,您无权拒收,收件后也无权要求我们履行七天无理由退换货义务。如您兑换积分的,平台可能就商品仓储管理及交易流转等过程中产生的成本费用收取一定手续费。
+ 2、您无正当理由拒绝签收不支持七天无理由退换货商品或性质不适宜拒签的商品的,商品拒收后,需由您承担商品毁损、灭失的风险及因此产生的额外运费等费用,且平台不进行退款处理。
+ 3、鉴于“盲盒”商品具有随机性的特点,如您多次购买同一款“盲盒”,可能使您得到多个重复的物品,这种情况不属于售后范围内,我们也建议您理性消费,用户对此完全了解并接受,且不持任何疑义。
+ 4、由于灯光、设备、显示器分辨率等因素,图片恐有色差,以实物为准,该问题不属于售后范围。
+ 5、如遇外箱严重破损等情况请拒签,缺件、断裂、发错等严重商品质量问题,请您在收到商品后的7天内明确商品问题并联系客服处理售后,7天后将不再接受任何售后处理。
+ 6、售后范围:发错/缺件/断件/严重瑕疵及非人为损坏;举证要求:证明问题的照片/视频或其他举证。
+ 7、因质量问题的售后处理流程:您需要在商品物流签收后7天内联系客服申请换货。如果商品符合换货条件且库存充足,本平台将为您提供换货服务。本平台会根据您提供的商品问题,证据进行判断,您应对证据的真实性、关联性、完整性、准确性和及时性负责。
+ ●商品寄回后,本平台签收商品前的风险由您承担。
+ ●您应在规定的换货时间内申请换货,并在被通知可寄回起3天内将商品寄回并提供物流单号至妙趣盲盒在线客服。您因超时寄出商品的,对同一问题或维权原因再次主张要求换货的,妙趣盲盒有权不予处理。
+ 8、对于不存在质量问题但属于法律规定且本协议约定可七天无理由退货的商品,如您要求退货的,退货产生的运费由您自行承担,退货流程参照因质量问题的售后处理流程。
+ 9、其他关于商品及售后问题,还请咨询在线客服了解相关情况。
+ 四、隐私保护
+ 1、用户知悉并同意:个人隐私信息是指能够对用户进行个人辨识或涉及个人通信的信息,包括用户真实姓名、身份证号、手机号码、银行账户、IP地址等。非个人隐私信息是指用户对本服务的操作状态以及使用习惯等一些明确且客观反映在本平台服务器端的基本记录信息和其他一切个人隐私信息范围外的普通信息,以及用户同意公开的上述隐私信息。
+ 2、本平台尊重用户个人隐私信息的私有性,本平台将会采取合理的措施保护用户的个人隐私信息,除法律或有法律赋予权限的政府部门要求或用户同意等原因外,本平台未经用户同意不向除合作单位以外的第三方公开、透露用户个人隐私信息。
+ 3、用户与本平台及合作单位之间就用户个人隐私信息公开或使用另有约定的,用户应自行承担因此可能产生的任何风险,本平台对此不承担责任。
+ 4、为了运营和改善本平台的技术和服务,便于本平台向用户提供更好的用户体验和提高本平台的服务质量,本平台将可能会自行收集使用或向第三方提供用户的非个人隐私信息。
+ 5、隐私保护相关内容具体请仔细阅读本平台的《隐私政策》。
+ 五、本平台商业标识信息
+ 1、本平台服务中所涉及的本平台图形、文字或其组成,以及其他本平台标志及产品、服务名称,均为本平台之商业标识(以下简称“本平台标识”)。未经我们事先书面同意,用户不得将本平台标识以任何方式展示、使用或申请注册商标、进行域名注册等,也不得实施向他人明示或暗示有权展示、使用、或其他有权处理本平台标识的行为。用户由于非法使用本平台标识给我们或他人造成损失的,由用户承担相关法律责任。
+ 六、知识产权
+ 1、本软件全部知识产权为厦门正纯科技有限公司或其许可人所有,包括受《中华人民共和国著作权法》、《中华人民共和国商标法》或《中华人民共和国专利法》及其实施条例等法律法规保护的一切智力成果。
+ 2、本软件或者提供服务中所涉及的图形、视频、文字或其组成,以及其他本公司标志及产品、服务名称,均为本公司之知识产权。未经本公司事先书面同意,您不得以营利为目的将本公司标识以任何方式展示或使用或作其他处理,也不得向他人表明有权展示、使用或者其他有权处理本公司标识的行为。
+ 3、本软件所涉及的一切著作权、商标权、专利权等知识产权,以及与本软件相关的所有商业秘密及信息内容(包括但不限于本软件相关文字、软件、脚本、代码、设计、版面框架、图片、声音、音乐、视频、应用、图片解析查询功能和所有其他内容)均受中华人民共和国法律法规和相应的国际条约保护,本公司对上述内容享有一切权利。
+ 4、未经本公司许可,您不得修改本平台的客户端程序;不得对本平台进行反向工程(reverse engineer)、反向编译(decompile)或反汇编(disassemble),不得破坏其完整性(包括程序代码、数据等),否则应承担相应的法律责任。
+ .未经本公司许可,您不得制作、传播有损本公司利益或扰乱软件正常使用秩序的任何第三方软件。
+ .在接受及遵守本协议的前提下,本平台将授予您关于妙趣盲盒客户端应用程序的一项个人的、不可转让、不可转授权、非排他性的许可,用户可以为非商业目的在单一台终端设备上安装、使用、显示、运行妙趣盲盒客户端应用程序。您可以通过我们或我们已授权的第三方等获取妙趣盲盒客户端应用程序。若您并非从我们或我们授权的第三方获取妙趣盲盒客户端应用程序的,我们无法保证非官方版本的软件能够正常使用,您因此遭受的损失与我们无关。
+ 七、法律责任及免责
+ 1、用户违反本协议或相关服务条款的约定,导致第三方向我们及合作公司、关联公司提出索赔等要求的,用户同意承担全部法律责任,包括但不限于赔偿金、罚金、和解费、诉讼仲裁费、合理的律师费支出等,并同意赔偿因此给本平台造成的全部损害。
+ 2、用户因第三方如电信部门的通讯线路故障、技术问题、网络、电脑故障、系统不稳定性及其他各种不可抗力原因而遭受的一切损失,我们及合作单位不承担责任。
+ 3、因技术故障等不可抗事件影响到服务的正常运行的,我们及合作单位承诺在第一时间内与相关单位配合,及时处理进行修复,但用户因此而遭受的一切损失,我们及其合作单位不承担责任。
+ 4、用户理解:本服务同其他互联网服务一样,用户在使用服务过程中会受到网络服务质量、社会环境、用户操作错误等诸多因素的影响,可能会受到各种问题的侵扰。用户下载安装的其它软件或访问的其他网站中含有“特洛伊木马”等病毒,威胁到用户的计算机信息和数据的安全,继而影响本服务的正常使用等等。用户应加强对信息安全及使用者资料的保护意识,以免遭受损失和骚扰,因使用本平台服务的风险由用户自行承担。
+ 5、用户理解:本软件涉及到Internet服务,可能会受到各个环节不稳定因素的影响。因此服务存在因上述非因本公司行为,病毒或黑客攻击、您终端系统不稳定、您所在位置、您关机以及其他任何技术、GSM网络、互联网络、通信线路原因等造成服务中断或不能满足您要求的风险。对因前述原因导致的服务之及时性、安全性、准确性所可能引发的风险,本公司特提请您注意您将自行承担以上风险,与本公司无关。
+ 6、在任何情况下,本平台对任何由于用户使用本平台而导致的间接性、后果性、惩罚性、偶然性、特殊性或刑罚性的损害,包括但不限于因用户使用本平台服务而遭受的各项损失均不承担责任(即使本平台已被告知该等损失发生的可能性)。尽管本协议中可能含有特殊约定,本平台对用户承担的全部责任,无论因何原因或何种行为导致,均不超过用户在使用本平台服务期内支付给本平台的费用(如有)。
+ 7、在任何情况下,您不应轻信借款、索要密码、验证码或其他涉及财产或财产利益的网络信息。涉及财产操作的,请一定先核实对方身份,并请经常留意本公司有关防范诈骗犯罪的提示。对于以本公司名义向您发出的此类信息或请求,您可在按照相应要求进行操作前,通过本协议列明的客服电话及时联系进行确认。
+ 8、“不可抗力”是指协议双方不能合理控制、不可预见或即使预见亦无法避免 的事件,该事件妨碍、影响或延误任何一方根据协议履行其全部或部分义务。该 事件包括但不限于政府行为、自然灾害、战争、疫情等类似事件。如果出现不可 抗力,双方义务在不可抗力影响范围及其持续期间内将中止履行,任何一方均不 会因此而承担责任。自您下单之日起十五日内,如因不可抗力导致无法履行的(包 括但不限于因疫情导致物流受限无法发货或正常派送),本平台有权为您取消订 单。
+ 八、其他条款
+ 1、特别提示:请用户使用本协议服务之前,认真阅读本协议中限制、免除本平台义务责任和加重用户义务责任的条款,并请自主考虑风险。如果您是未成年人(未满18周岁)或因其他因素不具备完全民事行为能力的,应在法定监护人的陪同下阅读本协议,并在充分理解本协议各项条款的情况下使用。同时,未成年人的任何注册、及/或登录、及/或购买商品、及/或使用本平台提供的其他相关服务行为将被本平台视为已取得法定监护人的同意。
+ 2、本协议条款部分或全部无效,不影响其它条款的效力。
+ 3、本协议解释、效力及纠纷的解决,适用中华人民共和国法律。
+ 4、用户和本平台之间发生任何纠纷或争议,首先应友好协商解决,协商不成的,用户同意凡因本协议所引起的或与之相关的任何争议、纠纷、分歧或索赔,包括本协议的存在、效力、解释、履行、违反或终止,或因本协议引起的或与之相关的任何非合同性争议,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+ 5、我们保留本协议修改权利。
+ 6、通知与送达:您向本平台提供的所有联系方式(包括您的电子邮件地址、联系电话、联系地址等)均视为真实有效,您的平台账号也将视为您的有效联系方式。本平台通过您提供的联系方式或通过站内信、系统消息、平台公告等方式向您送达的各类通知,自发出之日起即视为送达。此类通知的内容可能对您的权利义务产生重大的有利或不利影响,请您务必及时关注。您同意仲裁机构、司法机关、监管部门等亦可采取以上一种或多种联系方式向您送达法律文书等。
+
+
+
+
+
+
+
+
+
diff --git a/pages/agreement/nonage-rule.vue b/pages/agreement/nonage-rule.vue
new file mode 100644
index 0000000..0a4dd7e
--- /dev/null
+++ b/pages/agreement/nonage-rule.vue
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+
+
+ 儿童个人信息保护规则
+ 生效日期:2024年05月01日
+ 厦门正纯科技有限公司及其关联方(简称“我们”)致力于保护使用妙趣盲盒产品和服务的儿童的个人信息,本规则适用于我们作为运营者的妙趣盲盒产品或服务,包括妙趣盲盒网站和妙趣盲盒移动应用(简称“产品”)。本规则中“儿童”,是指不满14周岁的未成年人。
+ 《儿童个人信息保护规则》(以下简称“本规则”)和隐私政策旨在向监护人(以下简称“您”)和儿童说明我们如何收集、使用、存储和处理儿童的个人信息,以及我们为您与儿童提供的访问、更正、删除和保护这些信息的方式。
+ 除另有约定外,本规则所用术语和缩略词与用户协议、隐私政策中的术语和缩略词具有相同的涵义。
+ 儿童监护人特别说明:
+ 如果您是儿童的监护人(父母或其他监护人),请您仔细阅读和选择是否同意本规则。我们希望您与我们共同保护儿童的个人信息,教育引导儿童增强个人信息保护意识和能力。
+ 儿童特别说明:
+ 如果您是儿童,您需要和您的监护人(父母或其他监护人)共同仔细阅读本规则,并在征得监护人同意后,使用我们的产品、服务或向我们提供信息。
+ 请监护人和儿童在仔细阅读并充分理解隐私政策和本规则后,由监护人选择是否同意隐私政策、本规则以及是否同意儿童使用我们的产品和服务。如果监护人不同意隐私政策及/或本规则的内容或不同意提供服务所必要的信息,将可能导致我们的产品和服务无法正常运行,或者无法达到我们拟达到的服务效果,监护人和儿童可能无法正常使用我们的产品及服务。
+ 监护人点击“同意”即表示监护人同意我们按照隐私政策和本规则的约定收集、使用和处理监护人和儿童的信息。
+
+ 请您理解,我们提供的产品和服务中可能包括第三方提供的产品和服务,请您注意,该第三方可能收集、使用或处理儿童的相关信息,需要该第三方另行获得监护人的同意。我们建议监护人向儿童告知,在向第三方授权处理其个人信息之前需征得监护人的同意。
+
+ 我们提醒您,仔细阅读本规则并确认了解我们对儿童个人信息的处理规则,特别是采用粗体字进行标注提示的部分。
+
+ 如果您有任何疑问、意见或建议,请通过以下任意一种方式与我们取得联系:
+ 1.儿童个人信息保护负责人联系电话:15280116383;
+ 2.联系邮箱:648715275@qq.com;
+ 3.在线客服:您可在妙趣盲盒移动应用内点击「我的」-「联系客服」联系;
+ 4.注册地址及常用办公地址:福建省厦门市思明区前埔路506号502室之一。
+
+ 一、我们收集哪些信息
+
+ 我们严格遵守法律法规的规定及与用户的约定,根据用户选择产品和服务的具体情况,收集监护人和儿童的以下个人信息。
+
+ 当我们根据法律法规及行业管理要求,需要为儿童用户配置保护措施时,我们可能会提示您提供监护人的手机号码等方式,与我们建立联系。
+
+ 在儿童使用产品和服务过程中,我们会要求您提供相关必要的信息,具体请查阅隐私政策“我们如何收集和使用个人信息”一节。
+
+ 如果我们需要收集监护人或儿童的其他个人信息,我们将再次告知监护人和儿童,并征得监护人的同意。
+
+ 监护人可以选择是否填写或向我们提供特定的信息。
+ 请您理解,监护人如果不填写或不提供某些特定的信息,可能会导致我们的产品和服务无法正常运行,或者无法实现我们拟提供的服务效果,监护人和儿童可能无法正常使用我们的产品、服务或相关的具体业务功能。
+
+ 二、我们如何使用这些信息
+
+ 我们严格遵守法律法规的规定及与用户的约定,将收集的监护人和儿童的信息用于以下用途:
+
+ (1)验证儿童和监护人身份;
+ (2)提供必要的产品和服务、产品和服务的具体功能;
+ (3)用于优化产品和服务、安全保障;
+ (4)其他隐私政策“我们如何收集和使用个人信息”章节中载明的用途。
+
+ 如果我们需要超出上述用途使用监护人或儿童的个人信息,我们将再次告知监护人和儿童,并征得监护人的同意。
+
+ 三、管理、披露儿童个人信息
+
+ 我们遵照法律法规的规定,严格管理儿童的个人信息。
+ 我们仅在监护人事先同意并采取符合《个人信息保护法》等法律法规要求的相关合规措施的情况下,才可能与监护人共享儿童的个人信息:
+
+ 例如,我们会将部分儿童个人信息(如儿童用户名、账号、手机号、订单等)与监护人进行共享,监护人可以访问和管理相关个人信息;我们会将部分儿童个人信息与提供必要技术服务的合作方共享,该合作方以SDK自行采集的方式收集,具体见隐私政策“SDK技术”章节。
+
+ 四、发生合并、收购、资产转让等
+
+ 随着我们业务的持续发展,当发生合并、收购、资产转让等交易导致向第三方共享或转移监护人和儿童的个人信息时,我们将通过推送通知、公告等形式告知监护人和儿童相关情形,按照法律法规及不低于本规则所要求的标准继续保护或要求新的管理者继续保护监护人和儿童的个人信息。
+
+ 一般情况下,我们禁止披露儿童个人信息,但我们可能基于以下目的使用儿童的个人信息:
+ (1)遵守适用的法律法规等有关规定;
+ (2)遵守法院判决、裁定或其他法律程序的规定;
+ (3)遵守相关政府机关或其他法定授权组织的要
+ 求;
+ (4)我们有理由确信需要遵守法律法规等有关规
+ 定;
+ (5)为执行相关服务协议或本规则、维护社会公共利益,为保护我们的客户、我们或我们的关联公司、其他用户或雇员的人身财产安全或其他合法权益合理且必要的用途;
+ (6)其他隐私政策中载明可披露或免征得您的同意使用的情形,具体见隐私政策“如何披露个人信息”、“免征得同意共享、转让、公开披露的个人信息”章节。
+
+ 五、存储儿童个人信息
+
+ 我们会采取加密等技术措施存储儿童个人信息,确保信息安全。我们存储儿童个人信息,不会超过实现其收集、使用目的所必需的期限。请查阅隐私政策“我们如何存储个人信息”章节,详细了解我们如何存储和保护儿童个人信息。
+ 当我们的产品和服务发生停止运营的情形或监护人和儿童的个人信息存储期限届满时,我们将采取例如,推送通知、公告等形式通知监护人和儿童,并在合理的期限内删除或匿名化处理监护人和儿童的个人信息。
+
+ 六、访问、更正、删除儿童个人信息
+
+ 在儿童用户使用产品和服务期间,为了监护人和儿童可以更加便捷地访问、更正、删除相关个人信息,监护人可以通过我们提供的联系方式,来反馈和咨询相关信息。
+ 我们会在核实监护人反馈的问题后及时与监护人联系。请监护人理解,在核实过程中,我们可能需要监护人提供儿童账号、儿童身份信息、联系方式等个人信息,以便在完成身份验证和核实问题后继续响应监护人的需求。
+
+ 1、访问儿童个人信息
+ 监护人和儿童可以查看儿童在使用我们产品和服务中提供或产生的个人信息,包括但不限于用户名、密码、手机号等内容。
+ 2、更正儿童个人信息
+ 当监护人和儿童发现我们收集、使用和处理的儿童个人信息有错误时,可以联系我们进行更正。我们会在完成身份验证和核实问题后,及时采取措施予以更正。
+ 3、删除儿童个人信息
+ 如存在以下情况,监护人和儿童可以联系我们删除收集、使用和处理的儿童个人信息。我们会在完成身份验证和核实问题后,及时采取措施予以删除:
+ (1)我们违反法律、行政法规的规定或者双方的约定收集、存储、使用、转移、披露儿童个人信息;
+ (2)若我们超出目的范围或者必要期限收集、存储、使用、转移、披露儿童个人信息;
+ (3)若监护人撤回同意;
+ (4)若监护人或儿童通过注销等方式终止使用产品或者服务并提出注销账号申请的;
+ (5)若我们不再为您提供本平台或服务的。
+ 但请注意,若监护人和儿童要求我们删除特定儿童个人信息,可能导致该儿童用户无法继续使用我们的产品和服务或产品和服务中的某些具体业务功能。如监护人发现在未事先征得监护人同意的情况下收集了儿童的个人信息,请及时联系我们,我们会采取措施尽快删除相关数据。
+ 您可根据隐私政策及本规则载明的联系方式联系我们向我们反馈儿童个人信息访问、更正、删除需求,我们将在15个工作日内响应。
+ 本政策的全部条款属于用户协议及隐私政策的重要组成部分之一。本规则未规定之处,以隐私政策规定为准。
+ 在适用本规则的情况下,如本规则与隐私政策存在不一致的,以本规则为准。如因签署、履行本规则与我们产生任何争议的,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+
+
+
+
+
+
+
+
+
diff --git a/pages/agreement/nonage.vue b/pages/agreement/nonage.vue
new file mode 100644
index 0000000..544ff34
--- /dev/null
+++ b/pages/agreement/nonage.vue
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+ 支付服务协议
+
+
+ 一、服务说明
+ 用户在妙趣盲盒平台支付购买,应遵守本规则。用户开始使用及/或继续使用本服务,即视为用户同意或已接受本规则中全部内容。此后用户不得以未阅读/未同意本规则内容或类似理由提出任何形式的抗辩。
+ 二、选购及支付
+ 1、您的支付页面会显示您此次购买需要支付的金额以及本平台购买相关规则,请您仔细阅读。如您点击“确认支付”并完成支付的,即视为您已阅读、理解,并认同按本规则的相关规定。
+ 2、如您选购“盲盒”的,您可从该款“盲盒”的购买页面查看该“盲盒”的相关信息,包括但不限于打开“盲盒”后可能出现的物品(包括名称、型号、规格、尺寸、颜色、所属级别等物品介绍)及其所属级别的出现概率等,请您购买前仔细查看该款“盲盒”的全部信息。您知悉并同意,本平台展示的概率为该款“盲盒”内同一级别的各种物品的概率之和,且因显示限制,概率可能仅显示至小数点后三位。
+ 3、您购买并完成支付后,将立即打开“盲盒”。基于“盲盒”内含物品库存变动等因素,我们可能需要适时变更“盲盒”内的物品,您对此表示完全知悉、理解并同意。
+ 4、您知悉并同意,“盲盒”打开后对应的物品是随机出现的,请您理性购买。
+ 5、您通过打开“盲盒”获得的物品将会放置在仓库中,您可以在仓库内选择提货(指平台将用户打开“盲盒”得到的物品寄送给用户)。如选择提货,我们将根据您提供的收货信息以快递的方式向您邮寄“盲盒”开出的物品。您知悉并同意,基于商品库存变动等因素考虑,商品可能作出一定调整,敬请谅解。
+ 6、在您提货或提交订单时,请仔细确认所购商品的名称、价格、数量、型号、规格、尺寸、颜色(部分商品涉及到型号、规格、尺寸、颜色等但没有标明规格信息和提供选择,或标写“随机”或其他具有同等含义的词语时,由本平台随机配送);同时还须请您提供收货人的姓名、联系电话、收货地址等必要快递信息。若收货人并非您本人,收货人的行为和意思表示将视为您的行为和意思表示,您应对收货人的行为及意思表示产生的法律后果承担连带责任。您提交订单即表示对订单中所确认的订购商品、收货信息等内容的准确性负责。如果因为您填写的收货人姓名、联系电话、收货地址等信息错误,导致延期配送、不能配送或商品交付给非您本意的收货人的,由此造成的损失需由您自行承担;因此造成任何损失或增加费用的,应由您完全独自承担。如因您未妥善选择商品的型号、规格、尺寸、颜色等,及/或您提供的地址信息不详或错误,导致无法发货的,本平台将通过电话、短信等方式告知您,如您在本平台首次通知之日起3天内没有提供商品的型号、规格、尺寸、颜色等商品信息及/或提供确切可配送地址的,本平台有权为您取消订单。
+ 7、用户需据实支付运费(虚拟商品不需要支付运费),部分可能涉及运费减免的运营活动请以相关运营公告或订单页面为准。请您理解,因疫情、极端天气、库存等因素,部分地区可能无法提供寄送服务,具体寄送规则请查看相关运营公告或订单页面。如实际发生运费超过您已支付的运费,您同意补足运费后本平台方可安排发货,本平台将通过电话、短信等方式告知您,如您在本平台首次通知之日起3天内没有补足运费的,本平台有权为您取消订单。
+ 8、本平台将做出最大的努力保证所有上架商品的库存,但您知悉、理解并同意,由于市场变化及各种以合理商业努力难以控制的影响,无法避免的会出现您提交的订单信息中的商品出现缺货等情况,如您下单所购买的商品出现以上情况,本平台有权为您取消订单。
+ 9、所有商品价格、数量、型号、规则、尺寸、颜色、介绍、是否有货等商品信息随时都有可能发生变动,任何变动本平台不作特别通知,请您至商品页面自行查看。本平台会尽最大努力保证您所浏览的商品信息的准确性;但由于商品种类繁多、商品信息的数量较大以及互联网技术因素等客观原因,商品信息页面显示可能会有一定的滞后性或差错,您对此表示知悉和理解。如您的订单涉及商品价格及商品信息显示滞后或差错的情况,您同意该种情况下已形成重大误解,本平台有权为您取消订单。
+ 10、您知悉并同意,如在购买时使用了任何形式的优惠券/抵用券/商品券等虚拟权益的,一旦订单取消,优惠券/抵用券/商品券等虚拟权益将不予返还。
+ 三、售后处理
+ 1、鉴于“盲盒”商品的特殊性,一经打开,不支持七天无理由退换货,您仅可选择提货或兑换为积分,对此您表示完全知悉、理解并同意。
+ 2、您无正当理由拒绝签收不支持七天无理由退换货商品或性质不适宜拒签的商品的,商品拒收后,需由您承担商品毁损、灭失的风险及因此产生的额外运费等费用,且平台不进行退款处理。
+ 3、鉴于“盲盒”商品具有随机性的特点,如您多次购买同一款“盲盒”,可能使您得到多个重复的物品,这种情况不属于售后范围内,我们也建议您理性消费,用户对此完全了解并接受,且不持任何疑义。
+ 4、由于灯光、设备、显示器分辨率等因素,图片恐有色差,以实物为准,该问题不属于售后范围。
+ 5、如遇外箱严重破损等情况请拒签,缺件、断裂、发错等严重商品质量问题,请您在收到商品后的7天内明确商品问题并联系客服处理售后,7天后将不接受任何售后处理。
+ 6、售后范围:发错/缺件/断件/严重瑕疵及非人为损坏;举证要求:证明问题的照片/视频或其他举证。
+ 7、因质量问题的售后处理流程:您需要在商品物流签收后7天内联系客服申请换货。如果商品符合换货条件且库存充足,本平台将为您提供换货服务。本平台会根据您提供的商品问题,证据进行判断,您应对证据的真实性、关联性、完整性、准确性和及时性负责。
+ ●商品寄回后,本平台签收商品前的风险由您承担,
+ ●您应在规定的换货时间内申请换货,并在被通知可寄回起3天内将商品寄回并提供物流单号至妙趣盲盒在线客服。您因超时寄出商品的,对同一问题或维权原因再次主张要求换货的,妙趣盲盒有权不予处理。
+ 8、对于不存在质量问题但属于法律规定且本协议约定可七天无理由退货的商品,如您要求退货的,退货产生的运费由您自行承担,退货流程参照因质量问题的售后处理流程。
+ 9、其他关于商品及售后问题,还请及时咨询在线客服了解相关情况。
+ 四、积分兑换及使用
+ 1、如您不喜欢打开“盲盒”所获得的商品,您可将其兑换为本平台的积分。
+ 2、如您选择兑换为积分,本平台将会下发相应的积分至您的平台内积分账户中,兑换积分的数量将以兑换页面展示为准,请您兑换前仔细确认。积分兑换不可撤销,一经选择兑换,我方提供的服务即视为完成。您不得要求我们提供退款或提货服务。
+ 3、因商品在提供运营服务、仓储管理以及交易流转等过程中会产生一定成本费用,所以如您选择兑换积分的,本平台将收取部分手续费。
+ 4、积分无法通过购买或充值获得,其获取途径仅包括:① 用“盲盒”开出的物品兑换;②通过本平台可能随时举办的运营活动获取。积分无法兑换成人民币等真实货币,不可转让,仅可用于在商城内兑换商品,不能再次购买“盲盒”。积分能够兑换的商品种类及其兑换价格以本平台商城页面展示为准,请您兑换前仔细确认。
+ 5、您可在“仓库-已回收”查看兑换的情况。
+ 五、未成年人保护
+ 1、本平台禁止未成年人消费。
+ 2、我们非常重视对未成年人的保护,若您是18周岁以下的未成年人,使用妙趣盲盒服务前,应事先取得您的家长或法定监护人的书面同意。如果您阅读并签署了用户协议,且在本平台明确提示后,您仍然进行了用户注册和购买,则视为该等行为已经取得了法定监护人的同意或追认。
+ 3、如您为未成年人用户的监护人,您清楚知悉、未成年人的消费行为需由监护人陪同并监管,请您切实主动履行监护义务,避免您的被监护人出现沉迷、过度消费等有损身心健康的行为。对已出现的未成年人消费行为,您应及时联系我们的在线客服,并积极配合本平台处理。
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/agreement/privacy.vue b/pages/agreement/privacy.vue
new file mode 100644
index 0000000..19e16b0
--- /dev/null
+++ b/pages/agreement/privacy.vue
@@ -0,0 +1,378 @@
+
+
+
+
+
+
+
+
+
+ 隐私政策
+ 生效日期:2024年05月01日
+ 本《隐私政策》(简称“本政策”)仅适用于厦门正纯科技有限公司及其关联方(简称“我们”)作为运营者的妙趣盲盒产品或服务,包括妙趣盲盒网站和妙趣盲盒移动应用(简称“产品”),不适用于有单独的隐私权政策且未纳入本政策的第三方产品或服务。您使用我们的产品时,我们将于您同意本政策及《用户协议》后,按照本政策收集、使用、存储、传输、转让(如适用)及对外提供您的个人信息。同时,我们会通过本政策向您说明,我们如何为您提供访问、更新、管理和保护您的个人信息的服务。
+ 本政策与您使用我们的产品关系紧密,我们建议您仔细阅读并理解本政策全部内容,做出您认为适当的选择。如果您未明示同意本政策并开始使用,这将导致我们无法为您提供完整的产品和服务。我们努力用通俗易懂、简明扼要的文字表达,并对本政策中与您的权益存在重大关系的条款,采用粗体字进行标注以提示您注意。请您在使用我们的产品前仔细阅读本政策,确保对其内容特别是加粗内容的含义及相应法律后果已全部知晓并充分理解。您勾选或点击“同意”即视为您接受本政策;您同意本政策在您使用产品的整个过程中均有效。如果您有任何疑问、意见或建议,请通过以下任意一种方式与我们取得联系:
+ 1.信息保护负责人联系电话:15280116383;
+ 2.联系邮箱:648715275@qq.com;
+ 3.在线客服:您可在妙趣盲盒移动应用内点击「我的」-「联系客服」联系;
+ 4.注册地址及常用办公地址:福建省厦门市思明区前埔路506号502室之一。
+ 本政策将帮助您了解以下内容:
+ 一、我们如何收集和使用个人信息
+ 二、我们如何使用Cookie、同类技术和SDK技术
+ 三、我们如何共享、转让、公开披露个人信息
+ 四、我们如何保护个人信息
+ 五、您的权利
+ 六、我们如何处理未成年人的个人信息
+ 七、我们如何存储个人信息
+ 八、我们如何更新本政策
+ 九、联系我们
+ 十、其他
+ 我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将按业界成熟的安全标准,采取相应的安全保护措施来保护您的个人信息。特别需要指出的是,即使经过您的授权,我们获得了敏感权限,也不会在相关功能或服务不需要时而收集您的信息。请在使用我们的产品前,仔细阅读并了解本政策。
+ 一、我们如何收集和使用个人信息
+ (一)词语释义
+ (1)妙趣盲盒产品或服务是指:我们通过合法拥有并运营的、标注名称包含“妙趣盲盒”的客户端应用程序以及妙趣盲盒官方网站(以下简称“妙趣盲盒”或“本平台”)等,向您提供的产品与服务。关联方是指在现在、将来控制厦门正纯科技有限公司、受厦门正纯科技有限公司控制或与厦门正纯科技有限公司处于共同控制下的法人主体。控制指通过所有权、有投票权的股份、合同、实际运营关联或其他被依法认定的方式直接或间接地拥有影响被控制对象管理/经营的能力。
+ (2)个人信息是指:以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。本政策个人信息包括姓名、出生日期、身份证件号码、个人生物识别信息、住址、通信通讯联系方式、通信记录和内容、账号密码、财产信息、征信信息、行踪轨迹、住宿信息、健康生理信息、网络身份识别信息、 常用设备信息、交易信息等。
+ (3)个人敏感信息是指:一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息。本政策中的个人敏感信息包括身份证件号码、邮箱地址、各类密码(口令、保护答案、数字证书)、个人生物识别信息、通信记录和内容、个人健康生理信息、个人财产信息、银行账号、征信信息、行踪轨迹、住宿信息、交易信息、14岁周岁以下(含)儿童的个人信息等。
+ (4)身份要素是指:产品用于识别您身份的信息要素,例如:您的登录名、密码、短信校验码、电话号码、手机号码、证件号码及个人生物识别信息(例如:指纹信息、脸部信息)。
+ (5)非个人信息:通过对个人信息的技术处理(包括但不限于匿名化、去标识化等),使得处理后的信息无法单独或结合其他信息识别到您的个人身份, 且处理后的信息不能被复原,处理后的信息不属于法律意义上您的个人信息。但当个人信息与处理后的信息结合使用期间,这些结合信息将作为您的个人信息按照本政策处理与保护。
+ (二)收集和使用个人信息的场景、目的及所收集的信息
+ 我们仅会出于本政策所述的以下目的,在以下场景收集和使用您的个人信息:
+ (1)帮助您成为我们的用户及进行账户管理
+ 为注册成为用户并使用我们的产品和服务,您需要提供您手机当前的手机号码进行注册登录。如果您拒绝提供上述信息,您将无法注册妙趣盲盒平台账户,仅可以使用浏览、搜索服务。为了确保我们是在为您本人提供服务,我们可能会根据您提供的上述信息校验您的身份。
+ 您也可以选择使用第三方账号登录,如您使用微信账号登录的,我们会获取您的微信头像、微信昵称。但您使用第三方账号登录后,仍需要提供手机号进行绑定。
+ (2)帮助您完成下单及订单管理
+ 当您在本平台订购具体商品时,我们会通过系统为您生成购买该商品的订单。在下单过程中,您需至少提供您的收货人姓名、收货地址、收货人联系电话,对于部分特殊类型的商品您还需要提供该商品所必需的其他信息。
+ 同时该订单中会载明您所购买的商品信息、具体订单号、订单创建时间、您应支付的金额、您的备注信息。我们收集这些信息是为了帮助您顺利完成交易、保障您的交易安全、便于您查询订单信息、提供客服与售后服务及其他我们明确告知的目的。
+ 您可以通过妙趣盲盒为其他人订购商品,您需要提供该实际收货人的前述个人信息,并确保已取得该实际收货人的同意。
+ 为便于您了解、查询订单信息并对订单信息进行管理,我们会收集您在使用我们服务过程中产生的订单信息用于向您展示及便于您对订单进行管理。
+ 您可额外填写包括其他联系电话、收货时间在内的更多附加信息以确保商品或服务的准确送达。
+ 您可以通过「我的」-「我的订单」查看和管理您的订单信息。
+ (3)帮助您完成支付
+ 为完成订单支付,您可通过第三方支付(支付宝/微信)付款。我们会将您的妙趣盲盒平台账户用户名、订单支付相关信息、订单安全相关设备信息及其他反洗钱法律要求的必要信息通过在网站或客户端中嵌入的第三方支付软件工具开发包(软件工具开发包在本政策中简称“SDK”)与第三方支付公司共享。
+ 为使我们及时获悉并确认您的支付进度及状态,为您提供售后与争议解决服务,您同意我们可自第三方支付公司处收集与支付进度相关信息。
+ (4)帮助向您完成商品的交付
+ 为保证您购买的商品能够顺利、安全、准确送达、提供,我们会向为妙趣盲盒平台提供物流相关服务的供应商(包括但不限于提供发货服务、快递服务的公司)披露订单相关的配送信息。您知晓并同意相应物流配送主体不可避免地获知及使用您的配送信息,用于完成交付目的。
+ 为向您提供售后与争议解决服务之目的,我们需要及时获悉并确认交付进度及状态,您同意我们可自物流相关服务主体处收集与交付进度相关的信息。如售后涉及退换货的,您同意向我们提供退货相关物流信息及同意我们可自物流相关服务主体处收集与退货进度相关的信息。
+ (5)为您提供客服支持及争议处理
+ 当您与我们联系或提出售中、售后、争议纠纷处理申请时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息以核验您的用户身份。
+ 为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的沟通、通信/通话记录及相关内容(包括账户信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。如果您针对具体订单进行咨询、投诉或提供建议的,我们会使用您的账户信息和订单信息。
+ 为优化服务质量,我们可能会获取您的麦克风的权限,以便可以通过语音的方式沟通;我们还可能会获取您的相机及/或照片的权限,以便您向客服提供照片、视频资料。如果您不同意或拒绝授权提供,将无法使用此功能,但不影响您正常使用本平台的其他功能。
+ 为了提供服务及改进服务质量的合理需要,我们还可能使用的您的其他信息,包括您与客服联系时您提供的相关信息,您参与问卷调查时向我们发送的问卷答复信息。
+ (6)保障产品正常运行
+ 当您使用我们的产品时,为了保障产品基础功能及服务能够正常运行,您同意我们根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、苹果唯一设备标识符(IFDA)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)、OAID)、设备所在位置相关信息(如IP 地址、WLAN接入点、SSID、BSSID、蓝牙、基站、地理位置信息)。需要您注意,这些信息是我们提供服务和保障产品正常运行所必须收集的基本信息。
+ 我们在应用第一次启动时,将会请求您授权读写外置存储信息权限,以读写外置存储信息。我们必须申请此权限,用于存储您在产品使用过程中产生的数据,拒绝此权限将导致您无法正常使用。
+ (7)保障产品、服务及用户使用安全
+为帮助我们更好地实现了解产品运行情况、判断账户安全、进行身份验证、检测及防范安全事件的目的,我们可能记录网络日志信息、应用信息、正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据及应用来源等信息:
+ ① 日志信息:我们会收集您对产品或服务的详细使用情况,作为有关网络日志保存(例如,搜索查询内容、IP地址、浏览器的类型、电信运营商);
+ ② 其他信息:我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、总体安装使用情况、性能数据、应用来源,并可能使用或整合您的用户信息、交易信息、设备信息、有关网络日志信息,进而综合判断您账户及交易风险、进行身份验证、检测及防范安全事件,并依法采取必要的记录、分析措施。
+ (8)消息通知及市场推广
+ 我们会通过PUSH通知为您提供推荐商品、运营活动等资讯,及向您发出平台公告、平台通知等。为了实现上述目的所必需,确保应用处于关闭或后台运行状态下正常接收到PUSH 通知,我们可能会在合理频率范围内自启动。
+ 我们可能会通过短信等形式为向您提供商品、运营活动等资讯,如果您不希望接收上述资讯,您可随时根据短信提示或我们提供的其他方式进行退订。
+ 需要您注意的是,单独的设备信息、日志信息等是无法识别特定自然人身份的信息,属于非本政策所指“个人信息”。
+ (三)我们直接调用的权限
+ 我们承诺决不超范围、超频次搜集您的个人信息,决不搜集与使用本产品服务非必需或无合理应用场景的信息。
+ 您在使用本平台时,为提供给您服务之目的,本平台可能在您使用该应用某些场景下向您申请终端设备的如下权限,当然您可以拒绝开启以下权限,或在手机的设置中关闭以下权限,关闭以下权限不会影响您对其他功能的使用。
+ 我们直接调用的设备权限包括:
+ 1、 通知
+ 对应业务功能:全部功能
+ 调用权限目的:用于接收各类消息
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:用户无法接收推送通知
+ 2、 无线数据
+ 对应业务功能:全部功能
+ 调用权限目的:用于应用程序访问互联网
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+ 3、 WLAN
+ 对应业务功能:全部功能
+ 调用权限目的:用于应用程序访问互联网
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+ 4、外置存储
+ 对应业务功能:全部功能
+ 调用权限目的:用于写入存储用户信息,存储日志等信息,缓存用户图片数据
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:产品无法流畅使用
+ 5、相机
+ 对应业务功能:客服功能、更换头像功能
+ 调用权限目的:读写设备上的照片及文件,用于在客服功能及更换头像功能中上传照片或视频
+ 是否询问:用户使用相应服务时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:用户无法在客服功能及更换头像功能中上传照片或视频
+ 6、麦克风
+ 对应业务功能:客服功能
+ 调用权限目的:用于发送语音消息、实时语音通话
+ 是否询问:用户使用相应服务时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:用户无法使用麦克风与客服进行语音沟通
+ 7、 访问电话状态(仅适用于安卓)
+ 对应业务功能:全部功能及安全保障
+ 调用权限目的:获取设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)),用于保障用户的账户及使用安全、验证登录设备与账号是否匹配、一键登录账号
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中。
+ 8、 安装软件包(仅适用于安卓)
+ 对应业务功能:安装更新功能
+ 调用权限目的:用于本产品软件安装或更新
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:用户无法正常安装软件
+ 9、IFDA获取(仅适用于iOS)
+ 对应业务功能:全部功能及安全保障
+ 调用权限目的:获取苹果手机唯一设备标识符IFDA,用于保障用户账号及使用安全、验证登录设备与账号是否匹配、一键登录账号
+ 是否询问:用户首次打开移动客户端时会弹窗询问
+ 可否关闭权限:可以关闭
+ 如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中、用户无法使用“本机号码一键登录”功能
+ 当我们要将个人信息用于本政策未载明的其它用途时,会事先征求您的同意。当我们要将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。
+ (四)无需征得同意收集和使用的个人信息
+ 根据法律法规及相关国家标准,我们在下列任意一种或多种情形下收集和使用您的个人信息无需征得您的授权同意。
+ (1)与国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)为应对突发公共卫生事件,或出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您同意的;
+ (5)所收集的您的个人信息是您自行向社会公众公开的;
+ (6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
+ (7)根据您的要求签订或履行合同所必需的;
+ (8)用于维护产品的安全稳定运行所必需的,例如发现、处置产品故障;
+ (9)为合法的新闻报道所必需的;
+ (10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
+ (11)法律法规规定及相关国家标准的其他情形。
+ 二、我们如何使用Cookie、同类技术和SDK技术
+ (一)Cookie
+ 为使您获得更轻松的访问体验,您使用我们的产品时,我们可能会通过小型数据文件识别您的身份,这么做可帮您省去重复输入注册信息的步骤,或者帮助判断您的账号安全状态。这些数据文件可能是Cookie。Cookie通常包含标识符、站点名称以及一些号码和字符。您可根据自己的偏好管理或删除Cookie。有关详情,请参见AboutCookies.org。但请注意,如果停用Cookie,您可能无法享受最佳的服务体验,某些服务也可能无法正常使用。
+ (二)与Cookie同类技术
+ 除Cookie外,我们还会使用网站信标和像素标签等其他同类技术(例如Beacon、Proxy等),但我们不会将Cookie和同类技术用于本政策所述目的之外的任何用途。
+ (三)SDK技术
+ 为保证产品相关功能的实现与应用安全稳定的运行,我们可能会接入由第三方服务提供商提供的软件工具开发包(SDK)实现相关目的。我们会对合作获取信息的软件工具开发包(SDK)进行严格的安全监测,以保证数据安全。前述服务商收集和处理信息等行为遵守其自身的隐私条款,而不适用于本政策。为了最大程度保障您的信息安全,我们建议您在使用任何第三方SDK类服务前先行查看其用户协议及隐私条款。为保障您的合法权益,如您发现这等SDK或其他类似的应用程序存在风险时,建议您立即终止相关操作并及时与我们取得联系。
+ 我们接入的第三方SDK及信息收集目的、场景等包括:
+ 1、微信SDK(com.tencent.mm.opensdk)
+ 涉及个人信息:分享的图片或内容、微信包名信息
+ 使用目的:支持微信登录和分享
+ 使用场景:在用户使用微信登录或者分享时使用
+ 合作方主体:深圳市腾讯计算机系统有限公司
+ 收集方式:SDK自行采集
+ 官网链接:https://open.weixin.qq.com/
+ 合作方隐私政策:https://support.weixin.qq.com/cgi-bin/mmsupportacctnodeweb-bin/pages/RYiYJkLOrQwu0nb8
+ 2、Alipay(支付宝)SDK(com.alipay.sdk)
+ 涉及个人信息:设备标识符(Android如IMEI、MEID、IMSI、Android ID、硬件序列号/Serial、ICCID、OAID,iOS如IDFV、IDFA)、设备MAC地址、IP地址、WLAN接入点(如SSID、BSSID)、Wi-Fi列表、网络信息、设备信息、软件列表、读取存储信息、支付宝包名信息、传感器列表
+ 权限调用:存储权限、电话权限
+ 使用目的:帮助用户在应用内使用支付宝
+ 使用场景:在用户使用支付宝支付时使用
+ 合作方主体:支付宝(中国)网络技术有限公司
+ 收集方式:SDK自行采集
+ 官网链接:https://render.alipay.com/p/f/fd-iwwyijeh/index.html
+ 合作方隐私政策:https://docs.open.alipay.com/54
+ 3、数字联盟SDK(cn.shuzilm.core)
+ 涉及个人信息:设备制造商、设备型号、设备系统版本、应用版本、传感器(光传感器、磁场传感器、重力传感器、压力传感器、方向传感器、旋转矢量传感器、陀螺仪传感器、加速度传感器)、应用信息、通信状态、信号强度、蓝牙信息、设备网络状态信息【包括网络的接入形式、IP地址、WiFi信息(BSSID、SSID)、运营商类型及网络基站信息】、设备物理环境信息、IDFA(儿童类应用不收集)、IDFV、OAID、粗略位置信息、指定包名信息、Android ID、IMEI、IMSI、MEID、设备序列号设备MAC地址、WiFi列表
+ 权限调用:粗略位置权限
+ 使用目的:安全风控,识别反馈设备的真实性,其中传感器主要用于辅助识别模拟器,虚拟机等虚拟环境及辅助判断作弊场景
+ 使用场景:检测设备欺诈与作弊行为时使用
+ 合作方主体:北京数字联盟网络科技有限公司
+ 收集方式:SDK自行采集
+ 官方链接:https://www.shuzilm.cn/
+ 合作方隐私政策:https://www.shuzilm.cn/privacy
+ 4、LinkedMe SDK(com.microquation.linkedme)
+ 涉及个人信息:设备MAC地址、OAID、唯一设备识别码、IP、SD卡数据、指定包名信息、WiFi状态
+ 权限调用:粗略位置权限
+ 使用目的:推广统计和效果分析,保存分享的图片,识别用户来源
+ 使用场景:使用数据分析服务时使用
+ 合作方主体:北京微方程科技有限公司
+ 收集方式:SDK自行采集
+ 官方链接:https://www.linkedme.cc/index.html
+ 合作方隐私政策:https://www.linkedme.cc/privacy-policy.html
+ 22、Okio (okio)
+ 涉及个人信息:写入存储信息、IP地址
+ 权限获取:存储权限
+ 使用目的:用于配合OkHttp实现,对服务器API发送请求,下载网络文件,访问网页。
+ 使用场景: 网络请求,访问网页。
+ 合作方主体:square
+ 收集方式:SDK自行采集
+ 官网链接:https://square.github.io/okio/
+ 23、Fresco(com.facebook)
+ 涉及个人信息:读写存储信息
+ 权限获取:存储权限
+ 使用目的:用于图片加载显示
+ 使用场景: APP内的所有图片显示。
+ 合作方主体: facebook
+ 收集方式:SDK自行采集
+ 官网链接:https://frescolib.org/
+ 三、我们如何共享、转让、公开披露个人信息
+ (一)如何共享个人信息
+ 我们不会与产品服务相关提供者以外的公司、组织和个人共享您的个人信息。我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息,具体情况如下:
+ 1.在获取明确同意的情况下共享:在获得您的明确同意后,我们会与其他方共享您的个人信息。
+ 2.在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。
+ 3.为实现产品功能或服务的共享:您的个人信息可能会与我们的关联公司共享。我们只会共享必要的个人信息,且受本政策中所声明目的的约束。关联公司如要改变个人信息的处理目的,或使用信息的目的超越原授权同意范围,将再次征求您的授权同意。
+ 4.为实现产品安全与分析统计的共享:
+ (1)保障使用安全:为保障您和其他用户的财产安全,使您和我们的正当合法权益免受不法侵害,我们和关联方或服务提供商可能会共享必要的设备、应用、进程、性能、环境及日志等信息。
+ (2)分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与关联方或第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。
+ (3)学术研究与科研:为提升相关领域的科研能力,促进科技发展水平,我们在确保数据安全与目的正当的前提下,可能会与科研院所、高校等机构共享去标识化或匿名化的数据。
+ (二)如何转让个人信息
+ 我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
+ 1.在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;
+ 2.在涉及合并、收购、资产转让或破产清算时,如涉及到个人信息转让,我们会在要求新的持有您个人信息的公司、组织继续受本政策的约束,将按照法律法规及不低于本政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求该公司、组织重新向您征求授权同意。
+ (三)如何披露个人信息
+ 我们仅会在以下情况下,公开披露您的个人信息并会采用符合行业内标准的安全保护措施:
+ (1)获得您明确同意后;
+ (2)基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息;
+ (3)对违规、欺诈行为进行处罚公告。
+ (四)免征得同意共享、转让、公开披露的个人信息
+ 根据法律法规及国家标准,我们在下列情形中,共享、转让、公开披露您的个人信息无需征得您的授权同意:
+ (1)与国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)为应对突发公共卫生事件,或出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您的同意的;
+ (5)您自行向社会公众公开的个人信息;
+ (6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
+ 四、我们如何保护个人信息
+ 本政策提供的如下个人信息保护措施仅适用于我们的产品。一旦您离开我们的产品,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在我们的产品之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于我们的产品的链接或引导。
+ (一)为保障您的信息安全,我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露、毁损、误用、非授权访问、非授权披露和更改的风险。
+ 我们会采取一切合理可行的措施,保护您的个人信息。例如:
+ (1)在您的设备与“产品服务”之间交换数据(如银行信息)时受SSL加密保护;
+ (2)我们会使用加密技术确保数据的保密性;
+ (3)我们会使用受信赖的保护机制防止数据遭到恶意攻击;
+ (4)我们会部署访问控制机制,确保只有授权人员才可访问个人信息;
+ (5)我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识;
+ (6)我们认为其他的合理可行的保护措施。
+ (二)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
+ (三)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
+ (四)我们会采取一切合理可行的措施,确保未收集无关的个人信息。
+ (五)我们将不定期更新并公开安全风险、个人信息安全影响评估等报告的有关内容。
+ (六)尽管已经采取了上述合理有效措施,并已经遵守了相关法律法规要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
+ 您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人等。
+ (七)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、电话、推送通知等方式告知您, 难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。
+ 五、您的权利
+ (一)访问您的个人信息
+ 您有权访问您的个人信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:
+ 如果您希望访问您的账号中的个人资料信息,您可以通过本平台中点击右下方的「我的」查看;如果您希望访问您的账号中的收件地址信息,您可以通过本平台中点击右下方的「我的」-「地址管理」查看及编辑。
+ 如果您无法通过上述方式访问上述个人信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (二)更正您的个人信息
+ 一般情况下,您可以随时更正您的个人信息。
+ 但出于安全性、身份识别、交易安全的考虑,您不能随时自主修改手机号码信息、订单的收货信息及实名认证信息;如您确有必要修改该类信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (三)删除您的个人信息
+ 在以下情形中,您可以向我们提出删除个人信息的请求:
+ 1.如果我们处理个人信息的行为违反法律法规;
+ 2.如果我们收集、使用您的个人信息,却未征得您的同意;
+ 3.如果我们处理个人信息的行为违反了与您的约定;
+ 4.如果您不再使用本平台提供的服务并提出注销账号申请;
+ 5.如果我们不再为您提供本平台或服务。
+ 您可根据本政策载明的联系方式联系我们反馈您的删除个人信息的需求,我们将在15个工作日内响应。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。
+ 当您从我们的服务中删除信息后,我们可能不会立即在备份系统中删除相应的信息,但会在备份更新时删除这些信息。
+ (四)管理您的授权范围
+ 每个业务功能需要一些基本的个人信息才能得以完成。
+ 对于为优化用户体验额外收集的个人信息的收集和使用,您可以随时给予或收回您的授权同意。您可以通过以下方式自行操作:您可以通过删除个人信息、关闭设备功能、更改应用权限等方式,改变您在功能和服务中的授权范围。当您撤回同意后,我们无法继续为您提供撤回同意所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意的决定,不会影响我们此前基于您的同意而开展的个人信息处理。如您在撤回同意时遇到困难,您可以通过根据本政策载明的联系方式联系我们,我们将在15个工作日内回复您的撤回请求。
+ (五)账号注销
+ 本平台未提供在线的注销功能,请您直接根据本政策载明的联系方式与我们联系申请账号注销。
+ 在注销账号前,我们将验证您的个人身份、安全状态、设备信息、仓库状态、订单状态等。
+ 请确保您所申请注销的账号应当是您本人依照《用户协议》的约定创建并由我们提供给您本人的账号。
+ 建议您在注销前自行备份账号相关的所有信息,并请确认与账号相关的所有服务均已进行妥善处理。如您的账号目前仍有未完成订单(包括待发货订单、待收货订单、售后处理中的订单)或仓库未清空(即仓库中含有已购买但未开启的盲盒、或通过开启盲盒获取但未提货或未兑换为积分的物品)的,请您在订单完成后或清空仓库后再提起账号注销申请,否则将无法提交注销申请;如账号内有未使用的积分及其他虚拟权益等,账号注销申请的提交视为您已放弃其全部权益,注销后不得向本平台要求恢复。
+ 如果您的账号涉及争议纠纷,包括但不限于:投诉、举报、诉讼、仲裁、国家有权机关调查等,您理解并同意,我们有权自行决定是否终止账号的注销,而无需另行得到您的同意。
+ 考虑到存在用户因误操作账号注销的情形,我们将自用户提交注销申请之日起提供为期15个工作日的账号申诉期,申诉期间用户登录产品账号即可取消注销申请。如用户未在申诉期间取消注销申请,则申诉期届满后,账号将自动注销,注销过程不可逆的、不可恢复。
+ 您知悉并理解,账号注销后您将无法再使用该账号登录及使用本平台提供的所有服务。但注销账号并不代表账号注销前的账户行为和相关责任得到豁免或减轻。
+ 当注销账号后,我们将对您持有您的个人信息(包括但不限于账号信息、交易记录等)进行删除或匿名化处理,但法律法规另有规定的除外。
+ (六)我们如何响应您的请求
+ 为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
+ 我们将在十五个工作日内做出答复。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视具体情况收取一定成本费用。 对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。
+ 在以下情形中,按照法律法规要求,我们将无法响应您的请求:
+ (1)国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)有充分证据表明您存在主观恶意或滥用权利的;
+ (5)响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;
+ (6)涉及商业秘密的。
+ (七)投诉举报
+ 您可以按照我们公示的制度或联系我们进行投诉或举报。如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索,您可以通过本政策载明的联系方式进行举报,我们核查后会在十五个工作日内反馈您的投诉与举报。
+ (八)访问隐私政策
+ 您可以在本平台中点击右下方的「我的」-「设置」-「隐私政策」后,查看本政策的全部内容。
+ (九)停止运营向您告知权利
+ 如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
+ 六、我们如何处理未成年人的个人信息
+ (一)我们期望父母或监护人指导未成年人使用我们的服务
+ 若您是未满18周岁的未成年人,在使用我们的产品前,应在您的父母或其他监护人监护、指导下共同阅读并同意本政策。如果没有父母或监护人的同意,儿童(不满14周岁)不得私自使用。
+ (二)我们重视保护未成年人个人信息
+ 我们根据国家相关法律法规的规定保护未成年人的个人信息,对于经父母同意而收集未成年人个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享或公开披露此信息。
+ (三)自查与接收反馈
+ 如果我们发现自己在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关数据或对其进行匿名化处理,但法律法规另有规定的除外。同时我们建立了严格的未成年人信息收集使用规则,以保护儿童的个人信息安全,您可以通过阅读《儿童个人信息保护规则》了解更多信息。
+ 若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本政策公示的联系方式与我们联系。
+ 七、我们如何存储个人信息
+ (一)我们在中华人民共和国境内收集和产生的个人信息,将存储在中华人民共和国境内。我们不会将上述信息传输至境外(您通过互联网进行跨境购买商品等个人主动行为除外),如果部分产品涉及跨境业务,我们需要向境外机构传输境内收集的相关个人信息的,我们将会遵循国家相关规定, 征求您的同意,并按照法律法规和相关监管部门的规定执行,并通过签订协议、现场核查等有效措施,要求境外机构为所获得的您的个人信息保密。
+ (二)我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。我们仅在为提供产品服务之目的所必需的期间内保留您的个人信息。超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外,例如《中华人民共和国电子商务法》要求商品和服务信息、交易信息保存时间自交易完成之日起不少于三年,《中华人民共和国网络安全法》要求网络日志的留存时间不少于六个月。
+ 八、我们如何更新本政策
+ 为了给您提供更好的服务,我们会适时对本政策进行修订,该等修订构成本政策的一部分并具有等同于本政策的效力。 如该等修订会导致您在本政策项下权利的实质减损,我们将在变更生效前,通过在页面显著位置公示等方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的政策约束。
+ 九、联系我们
+ (一)我们提供本政策载明的联系渠道供用户向我们反馈处理与个人信息问题相关的投诉、建议、疑问等,我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。
+ (二)如果您对我们的回复不满意,或因签署、履行本政策与我们产生任何争议的,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+ 十、其他
+ (一)本政策中的标题仅为方便及阅读而设,并不影响本政策中任何规定的含义或解释。
+ (二)本政策中所述的我们的产品及相关服务有可能会根据您所使用的终端设备、手机型号、系统版本、软件应用程序版本等因素而有所不同。最终的产品和服务以您所使用的产品及相关服务为准。
+ (三)本政策的全部条款属于《用户协议》重要组成部分之一。
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/agreement/rule.vue b/pages/agreement/rule.vue
new file mode 100644
index 0000000..aa61a6e
--- /dev/null
+++ b/pages/agreement/rule.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+ 规则
+ 教您玩转妙趣盲盒~
+ 一、怎么抽取盲盒?
+ 1)在首页上方点击充值按钮进行代币充值;
+ 2)在首页滑动盲盒款式,点击图片可详细查看商品明细和抽取概率;
+ 3)选中一款心仪的盲盒,点击“立即开盒”即可进行抽取;
+ 4)抽取形式多样,一发入魂or霸气五连!霸气五连购买优惠力度更高哦~
+ | 一发入魂:一次抽取一个
+ | 欧气三连:一次抽取三个
+ | 霸气五连:一次抽取五个
+ 5)开盒100%获得商品,所抽中的商品将自动进入您的“仓库”,您可以在“仓库”页面中查看。
+ 二、没抽到心仪的商品怎么办?
+ 1)丝毫不用担心!如果没抽到心仪的盲盒商品,可选择兑换成积分前往商城兑换其他商品哦~
+ 2)兑换积分时,平台将收取部分手续费,最终积分数量将以兑换页面展示为准。
+ 三、怎么提货?是否包邮?
+ 1)进入我的仓库,选择要提货的商品并填写正确的收货信息,实物最快当日发货哦~
+ 2)单次提取≥{{detail.num}}件商品包邮({{detail.exclude.join(',')}}地区除外) 。
+ 四、特别说明
+ 本活动与苹果等品牌方公司无关。
+ 商品抽奖存在概率性,付费请谨慎。
+ 【关于退款】
+ 基于盲盒商品特殊属性,开盒后不支持7天无理由退换货和退款。
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/agreement/total.vue b/pages/agreement/total.vue
new file mode 100644
index 0000000..62feb0c
--- /dev/null
+++ b/pages/agreement/total.vue
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+ 用户协议
+
+
+
+
+
+
+ 隐私政策
+
+
+
+
+
+ 儿童个人信息保护规则
+
+
+
+
+
+ 支付服务协议
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/crop-statusbar-height/crop-statusbar-height.vue b/pages/components/crop-statusbar-height/crop-statusbar-height.vue
new file mode 100644
index 0000000..303c773
--- /dev/null
+++ b/pages/components/crop-statusbar-height/crop-statusbar-height.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
diff --git a/pages/components/customNavbarPage.vue b/pages/components/customNavbarPage.vue
new file mode 100644
index 0000000..9c74563
--- /dev/null
+++ b/pages/components/customNavbarPage.vue
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/components/customer.vue b/pages/components/customer.vue
new file mode 100644
index 0000000..22ed21c
--- /dev/null
+++ b/pages/components/customer.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/empyt.vue b/pages/components/empyt.vue
new file mode 100644
index 0000000..cd28c85
--- /dev/null
+++ b/pages/components/empyt.vue
@@ -0,0 +1,63 @@
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/floatWindow copy 1.vue b/pages/components/floatWindow copy 1.vue
new file mode 100644
index 0000000..946469e
--- /dev/null
+++ b/pages/components/floatWindow copy 1.vue
@@ -0,0 +1,321 @@
+
+
+
+
+
+
+
+ 每日优惠
+ {{ item.remainingTime || '00:00:00' }}
+
+
+
+
+ {{item.price.settlement || 0}}元
+ {{item.remainingTime || '00:00:00'}}
+
+
+
+
+
+ 0.01元
+ {{item.remainingTime || '00:00:00'}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/floatWindow copy.vue b/pages/components/floatWindow copy.vue
new file mode 100644
index 0000000..5f4b373
--- /dev/null
+++ b/pages/components/floatWindow copy.vue
@@ -0,0 +1,210 @@
+
+
+
+
+
+
+
+ {{ remainingTime }}
+
+
+
+
+
+
+ {{remainingTime}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/floatWindow.vue b/pages/components/floatWindow.vue
new file mode 100644
index 0000000..f21c3d2
--- /dev/null
+++ b/pages/components/floatWindow.vue
@@ -0,0 +1,549 @@
+
+
+
+
+
+ {{endTime}}
+
+
+
+
+
+
+
+ {{item.remainingTime || '00:00:00'}}
+
+
+
+
+
+ {{item.remainingTime || '00:00:00'}}
+
+
+
+
+
+ {{item.remainingTime || '00:00:00'}}
+
+
+
+ 每日优惠
+
+ {{ item.remainingTime || '00:00:00' }}
+
+
+
+
+ {{item.remainingTime || '00:00:00'}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/header.vue b/pages/components/header.vue
new file mode 100644
index 0000000..4fab1bc
--- /dev/null
+++ b/pages/components/header.vue
@@ -0,0 +1,67 @@
+
+
+
+ {{title}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/indexNavBarSkeletonPage.vue b/pages/components/indexNavBarSkeletonPage.vue
new file mode 100644
index 0000000..21a0eb6
--- /dev/null
+++ b/pages/components/indexNavBarSkeletonPage.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/isPayDlg.vue b/pages/components/isPayDlg.vue
new file mode 100644
index 0000000..e662619
--- /dev/null
+++ b/pages/components/isPayDlg.vue
@@ -0,0 +1,173 @@
+
+
+
+ 请您在新打开的支付页面内完成支付操作,为确保支付顺利,请保持页面开启直至支付完成。
+
+
+
+
+
+ 盲盒即将揭晓
+ 真的要放弃这个机会吗?
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/mixins/navBarPageMixin.js b/pages/components/mixins/navBarPageMixin.js
new file mode 100644
index 0000000..8dbd83b
--- /dev/null
+++ b/pages/components/mixins/navBarPageMixin.js
@@ -0,0 +1,88 @@
+/**
+ * 自定义导航栏的骨架页面的属性配置
+ */
+const navBarPageMixin = {
+ props: {
+ leftIcon: {
+ type: String,
+ default: ''
+ },
+ leftText: {
+ type: String,
+ default: ""
+ },
+ rightText: {
+ type: String,
+ default: ''
+ },
+ rightTextColor: {
+ type: String,
+ default: '#5FC48D'
+ },
+ backgroundColor: {
+ type: String,
+ default: "#FFFFFF"
+ },
+ title: {
+ type: String,
+ default: ''
+ },
+ // 标题字体颜色
+ color: {
+ type: String,
+ default: "#fff"
+ },
+ fixed: {
+ type: Boolean,
+ default: true
+ },
+ clickLeftFn: {
+ type: [Boolean, Function],
+ default: false
+ },
+ clickRightFn: {
+ type: [Boolean, Function],
+ default: false
+ },
+ // 右侧是否需要显示
+ rightShow: {
+ type: [String, Boolean],
+ default: true
+ },
+ // BottomNavBar配置
+ curKey: {
+ type: String,
+ default: 'mall'
+ },
+ // 是否需要增加平台状态栏高度
+ platformsHeight: {
+ type: [Boolean, String],
+ default: true
+ },
+ // 左侧icon的颜色配置
+ leftIconColor: {
+ type: String,
+ default: ""
+ }
+ },
+ methods: {
+ clickLeft () {
+ !this.clickLeftFn ? this.back() : this.clickLeftFn()
+ },
+ clickRight () {
+ this.clickRightFn && this.clickRightFn()
+ },
+ back(){
+ let pages = getCurrentPages()
+ if(pages.length == 1){
+ uni.reLaunch({
+ url:'/pages/home/index'
+ })
+ }else{
+ uni.navigateBack()
+ }
+ }
+ }
+}
+
+export default navBarPageMixin;
diff --git a/pages/components/nav.vue b/pages/components/nav.vue
new file mode 100644
index 0000000..361d04d
--- /dev/null
+++ b/pages/components/nav.vue
@@ -0,0 +1,54 @@
+
+
+
+ {{title}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/navBarSkeletonPage.vue b/pages/components/navBarSkeletonPage.vue
new file mode 100644
index 0000000..c1ba845
--- /dev/null
+++ b/pages/components/navBarSkeletonPage.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/components/pagePopUp.vue b/pages/components/pagePopUp.vue
new file mode 100644
index 0000000..98bc83f
--- /dev/null
+++ b/pages/components/pagePopUp.vue
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/components/paymentPassword.vue b/pages/components/paymentPassword.vue
new file mode 100644
index 0000000..91769fb
--- /dev/null
+++ b/pages/components/paymentPassword.vue
@@ -0,0 +1,104 @@
+
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
diff --git a/pages/components/quotationList.vue b/pages/components/quotationList.vue
new file mode 100644
index 0000000..a4a304b
--- /dev/null
+++ b/pages/components/quotationList.vue
@@ -0,0 +1,294 @@
+
+
+
+
+
+
+
+
+ USDT
+ /CNY
+
+ {{list.length > 0 ? parseFloat(list[0].usdtCost).toFixed(4) : ''}}
+
+
+
+
+
+
+
+ {{item.symbol.split('/')[1]}} /{{item.symbol.split('/')[0]}}
+ 24H量 {{item.statisticalDto.amount}}
+
+
+ {{item.price}}
+ ¥{{parseFloat(mathMulFun(item.usdtCost,item.price)).toFixed(2)}}
+
+ {{item.statisticalDto.quoteChange > 0 ? '+' : (item.statisticalDto.quoteChange < 0 ? '' : '') }}{{parseFloat(item.statisticalDto.quoteChange).toFixed(2)}}%
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/components/spine.vue b/pages/components/spine.vue
new file mode 100644
index 0000000..e1b4a0a
--- /dev/null
+++ b/pages/components/spine.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/activity.vue b/pages/index/activity.vue
new file mode 100644
index 0000000..6cec5ab
--- /dev/null
+++ b/pages/index/activity.vue
@@ -0,0 +1,1686 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{index+1}}.{{item.nickname}}
+ {{Number(item.period) + 1}}轮{{Number(item.periodNum) + 1}}关
+
+
+
+
+
+
+ {{Number(detailData.curPeriod) + 1}} 轮 {{Number(detailData.curPeriodNum) + 1}} 关
+ {{detailData.curTask.description}}
+
+
+
+
+
+
+
+
+
+
+
+ 第{{key}}名
+
+
+
+
+
+
+
+
+
+
+ {{childItem.info.abbreviation}}*{{childItem.num}}
+
+
+
+
+ 立减{{Number(childItem.info.amount)}}*{{childItem.num}}
+ {{Number(childItem.info.amount)}}折*{{childItem.num}}
+
+
+ {{typeObj[childItem.type]}}*{{childItem.num}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择收货地址,让快递到家~
+
+
+
+
+
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}}
+ {{address.address}}
+
+
+
+
+
+
+
+
+ 邮费
+ {{Number(previewData.deliveryFee)}}
+
+
+ 实际支付
+
+ {{previewData.points}} 积分
+ ¥{{Number(previewData.deliveryFee)}}
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+ 我已满18岁,已阅读并同意
+ 《用户协议》、
+ 《隐私政策》、
+ 《儿童个人信息保护规则》、
+ 《支付服务协议》
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/boxDetail.vue b/pages/index/boxDetail.vue
new file mode 100644
index 0000000..730328e
--- /dev/null
+++ b/pages/index/boxDetail.vue
@@ -0,0 +1,908 @@
+
+
+
+
+
+
+
+
+
+
+ 一发入魂
+
+
+
+
+
+
+ {{detailData.probability && detailData.probability['SUPREME'] || 0}}
+ %
+
+ 共{{countByGrade('SUPREME') || 0}}个
+
+
+ {{detailData.probability && detailData.probability['RARE'] || 0}}%
+ 共{{countByGrade('RARE') || 0}}个
+
+
+ {{detailData.probability && detailData.probability['HIDDEN'] || 0}}%
+ 共{{countByGrade('HIDDEN') || 0}}个
+
+
+ {{detailData.probability && detailData.probability['NORMAL'] || 0}}%
+ 共{{countByGrade('NORMAL') || 0}}个
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 售罄
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/boxOrderConfirm.vue b/pages/index/boxOrderConfirm.vue
new file mode 100644
index 0000000..9c88d17
--- /dev/null
+++ b/pages/index/boxOrderConfirm.vue
@@ -0,0 +1,590 @@
+
+
+
+
+
+
+
+ {{detailData.name}}
+
+ ¥ {{detailData.amount.sale}}
+ {{detailData.amount.sale}}代币
+ X {{numObj[detailData.type]}}
+
+
+
+
+
+ 优惠券
+
+ 无
+
+
+
+ {{detailData.couponName || "无"}}
+
+
+
+
+ 优惠金额
+
+ 0
+
+
+ {{detailData.discountAmount || 0}}
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/boxPaySuccess.vue b/pages/index/boxPaySuccess.vue
new file mode 100644
index 0000000..d6db93c
--- /dev/null
+++ b/pages/index/boxPaySuccess.vue
@@ -0,0 +1,291 @@
+
+
+
+
+
+ 支付成功
+
+
+ 我的盲盒
+
+
+
+
+
+
+
+ 立即开奖
+
+
+
+ 用户信息
+ {{nickName}}
+
+
+ 盲盒名称
+ {{name}}
+
+
+ 盲盒数量
+ {{statusObj[type]}}
+
+
+ 实付代币
+ {{sale}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/card copy 1.vue b/pages/index/card copy 1.vue
new file mode 100644
index 0000000..7d5fc0b
--- /dev/null
+++ b/pages/index/card copy 1.vue
@@ -0,0 +1,597 @@
+
+
+
+
+
+ 商品提示语
+
+ *使用后可提前获得该盲盒的商品提示语
+
+ 购买提示卡
+ 使用提示卡
+
+
+
+ {{isTxt ? prompt : ''}}
+
+
+
+ {{ item }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/card copy.vue b/pages/index/card copy.vue
new file mode 100644
index 0000000..fc27d5a
--- /dev/null
+++ b/pages/index/card copy.vue
@@ -0,0 +1,223 @@
+
+
+
+
+ 提示卡
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 使用提示卡
+
+
+
+
+
+
+
+ 拿在手上的那种
+
+ 再抽一次
+ 立即购买
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/card.vue b/pages/index/card.vue
new file mode 100644
index 0000000..253c694
--- /dev/null
+++ b/pages/index/card.vue
@@ -0,0 +1,798 @@
+
+
+
+
+
+ 商品提示语
+
+ *使用后可提前获得该盲盒的商品提示语
+
+
+
+ 购买提示卡
+ 使用提示卡
+
+
+
+
+
+
+ {{isTxt ? prompt : ''}}
+
+
+
+ {{ item }}
+
+
+
+ 离开页面后提示卡将失效哟~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/bgGuang copy.vue b/pages/index/components/bgGuang copy.vue
new file mode 100644
index 0000000..3a19c82
--- /dev/null
+++ b/pages/index/components/bgGuang copy.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/bgGuang.vue b/pages/index/components/bgGuang.vue
new file mode 100644
index 0000000..35acdf1
--- /dev/null
+++ b/pages/index/components/bgGuang.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index/components/box.vue b/pages/index/components/box.vue
new file mode 100644
index 0000000..65bb6f7
--- /dev/null
+++ b/pages/index/components/box.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/btn.vue b/pages/index/components/btn.vue
new file mode 100644
index 0000000..54b94e2
--- /dev/null
+++ b/pages/index/components/btn.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/index/components/bubble.vue b/pages/index/components/bubble.vue
new file mode 100644
index 0000000..a6ba5cd
--- /dev/null
+++ b/pages/index/components/bubble.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buy.vue b/pages/index/components/buy.vue
new file mode 100644
index 0000000..f79f3d5
--- /dev/null
+++ b/pages/index/components/buy.vue
@@ -0,0 +1,366 @@
+
+
+
+
+
+
+
+ 两件包邮/正品保障
+
+
+
+
+
+
+
+ 9折
+
+
+
+ 8折
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buyActivityBox copy.vue b/pages/index/components/buyActivityBox copy.vue
new file mode 100644
index 0000000..b078dd8
--- /dev/null
+++ b/pages/index/components/buyActivityBox copy.vue
@@ -0,0 +1,984 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buyActivityBox.vue b/pages/index/components/buyActivityBox.vue
new file mode 100644
index 0000000..72d4ba0
--- /dev/null
+++ b/pages/index/components/buyActivityBox.vue
@@ -0,0 +1,1213 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buyBox copy.vue b/pages/index/components/buyBox copy.vue
new file mode 100644
index 0000000..7cd7b02
--- /dev/null
+++ b/pages/index/components/buyBox copy.vue
@@ -0,0 +1,1238 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buyBox.vue b/pages/index/components/buyBox.vue
new file mode 100644
index 0000000..b4b5c7c
--- /dev/null
+++ b/pages/index/components/buyBox.vue
@@ -0,0 +1,1404 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buyBoxRun.vue b/pages/index/components/buyBoxRun.vue
new file mode 100644
index 0000000..6097e68
--- /dev/null
+++ b/pages/index/components/buyBoxRun.vue
@@ -0,0 +1,1569 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/buyFreeBox.vue b/pages/index/components/buyFreeBox.vue
new file mode 100644
index 0000000..66be037
--- /dev/null
+++ b/pages/index/components/buyFreeBox.vue
@@ -0,0 +1,608 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/coinDeficit.vue b/pages/index/components/coinDeficit.vue
new file mode 100644
index 0000000..64c470d
--- /dev/null
+++ b/pages/index/components/coinDeficit.vue
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+ 赠送{{item.gift}}代币
+
+
+ {{item.coin}}
+
+ ¥ {{item.price.settlement}}
+
+
+
+
+ 充值金额
+ {{list[listIndex].price.sale}} 元
+
+
+ 充值代币
+ {{list[listIndex].coin}} 代币
+
+
+ 充值奖励
+ {{list[listIndex].gift}} 代币
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+ 立即支付 ¥{{list[listIndex].price.sale}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/lihua copy.vue b/pages/index/components/lihua copy.vue
new file mode 100644
index 0000000..e5f924d
--- /dev/null
+++ b/pages/index/components/lihua copy.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/lihua.vue b/pages/index/components/lihua.vue
new file mode 100644
index 0000000..280e99c
--- /dev/null
+++ b/pages/index/components/lihua.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/line.vue b/pages/index/components/line.vue
new file mode 100644
index 0000000..8a6e885
--- /dev/null
+++ b/pages/index/components/line.vue
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/listBonus.vue b/pages/index/components/listBonus.vue
new file mode 100644
index 0000000..19bae7c
--- /dev/null
+++ b/pages/index/components/listBonus.vue
@@ -0,0 +1,377 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 第{{key}}名
+
+
+
+
+
+ {{typeObj[childItem.type]}}X{{childItem.num}}
+
+
+
+
+
+
+
+
+
+ {{childItem.info.name}}X{{childItem.num}}
+
+
+
+
+
+
+ ¥
+ {{Number(childItem.info.amount)}}
+
+
+
+ {{Number(childItem.info.amount)}}
+ 折
+
+
+
+
+ {{childItem.info.name}}X{{childItem.num}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/noOpen.vue b/pages/index/components/noOpen.vue
new file mode 100644
index 0000000..0eb0f18
--- /dev/null
+++ b/pages/index/components/noOpen.vue
@@ -0,0 +1,101 @@
+
+
+
+
+ 您有未开盲盒,去开奖!
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openBox copy.vue b/pages/index/components/openBox copy.vue
new file mode 100644
index 0000000..67f9c37
--- /dev/null
+++ b/pages/index/components/openBox copy.vue
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{row.productAbbreviation}}
+ 价值:¥ {{row.salePrice}}
+
+
+
+
+
+ 换成积分
+
+
+
+ 查看惊喜
+ 再来一次
+ 再来一次
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openBox.vue b/pages/index/components/openBox.vue
new file mode 100644
index 0000000..4ff7e8a
--- /dev/null
+++ b/pages/index/components/openBox.vue
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+ {{row.productAbbreviation}}
+
+
+
+
+ 换成积分
+
+
+ 查看惊喜
+ 返回活动
+ 再来一次
+ 再来一次
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openBoxFive.vue b/pages/index/components/openBoxFive.vue
new file mode 100644
index 0000000..2cef358
--- /dev/null
+++ b/pages/index/components/openBoxFive.vue
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+ 换成积分
+
+
+ 查看惊喜
+ 返回活动
+ 再来一次
+ 再来一次
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openBoxNine.vue b/pages/index/components/openBoxNine.vue
new file mode 100644
index 0000000..22320e1
--- /dev/null
+++ b/pages/index/components/openBoxNine.vue
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 换成积分
+
+ 查看惊喜
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openBoxThree.vue b/pages/index/components/openBoxThree.vue
new file mode 100644
index 0000000..c1cc1d5
--- /dev/null
+++ b/pages/index/components/openBoxThree.vue
@@ -0,0 +1,267 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 换成积分
+
+
+ 查看惊喜
+ 返回活动
+ 再来一次
+ 再来一次
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openFreeBox.vue b/pages/index/components/openFreeBox.vue
new file mode 100644
index 0000000..8b76f55
--- /dev/null
+++ b/pages/index/components/openFreeBox.vue
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+ {{row.productAbbreviation}}
+
+
+
+
+
+ 来发真的
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openFreeBoxFive.vue b/pages/index/components/openFreeBoxFive.vue
new file mode 100644
index 0000000..738ed87
--- /dev/null
+++ b/pages/index/components/openFreeBoxFive.vue
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+ 来发真的
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/openFreeBoxThree.vue b/pages/index/components/openFreeBoxThree.vue
new file mode 100644
index 0000000..8c978ff
--- /dev/null
+++ b/pages/index/components/openFreeBoxThree.vue
@@ -0,0 +1,264 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 来发真的
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/qp.vue b/pages/index/components/qp.vue
new file mode 100644
index 0000000..fd8e2a0
--- /dev/null
+++ b/pages/index/components/qp.vue
@@ -0,0 +1,389 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/raffle.vue b/pages/index/components/raffle.vue
new file mode 100644
index 0000000..e201ca8
--- /dev/null
+++ b/pages/index/components/raffle.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/rankNum.vue b/pages/index/components/rankNum.vue
new file mode 100644
index 0000000..edbac4c
--- /dev/null
+++ b/pages/index/components/rankNum.vue
@@ -0,0 +1,40 @@
+
+
+
+ {{rank < 10 ? '0' : ''}}{{ rank }}
+
+
+ {{ Math.floor(rank / 10) * 10 }}+
+
+
+ {{ Math.floor(rank / 100) * 100 }}+
+
+
+ 999+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/sign.vue b/pages/index/components/sign.vue
new file mode 100644
index 0000000..9aef904
--- /dev/null
+++ b/pages/index/components/sign.vue
@@ -0,0 +1,348 @@
+
+
+ 7日签到领大奖
+
+
+
+
+ 第{{convertToChinese(item.numDay)}}天
+
+
+
+
+
+
+
+
+
+ {{childItem.info.name}}X{{childItem.num}}
+
+
+
+
+
+ {{isSign ? '已签到' : '立即签到'}}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/tip.vue b/pages/index/components/tip.vue
new file mode 100644
index 0000000..93a37b9
--- /dev/null
+++ b/pages/index/components/tip.vue
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+ 商品提示语
+ 使用提示卡后可提前获得该盲盒的商品提示语
+
+
+
+
+ 立即使用
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/top.vue b/pages/index/components/top.vue
new file mode 100644
index 0000000..44e3478
--- /dev/null
+++ b/pages/index/components/top.vue
@@ -0,0 +1,180 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/components/trumpet.vue b/pages/index/components/trumpet.vue
new file mode 100644
index 0000000..845c08f
--- /dev/null
+++ b/pages/index/components/trumpet.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
+ {{item}}
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/confirmOrder.vue b/pages/index/confirmOrder.vue
new file mode 100644
index 0000000..13734c7
--- /dev/null
+++ b/pages/index/confirmOrder.vue
@@ -0,0 +1,482 @@
+
+
+
+
+ 确认订单
+
+
+
+
+
+
+
+ {{detailData.name}}
+ {{statusObj[detailData.type]}}
+
+ ¥
+ {{detailData.amount.sale}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+ 实付¥{{detailData.amount.sale}}
+
+
+
+
+ 买家需知
+ 1.商品抽奖存在概率性,付费请谨慎。
+ 2.本公司惊喜礼盒开箱概率已经过公证处鉴定(公证后台
+ 设置与app展示一致)。
+ 3.惊喜礼盒一经购买不支持退款(除商品质量问题),但可
+ 8折回收后自动兑换成繁豆用于兑换商品,繁豆为平台积
+ 分,暂不支持提现。
+ 4.本平台禁止未成年人消费。
+ 5.受疫情影响,部分地区物流公司暂时无法接单及派送,
+ 为此给您带来的不便我们深表歉意。请您耐心等待我们
+ 会在疫情解除的第一时间为您派件。
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/detail.vue b/pages/index/detail.vue
new file mode 100644
index 0000000..b97bad6
--- /dev/null
+++ b/pages/index/detail.vue
@@ -0,0 +1,1361 @@
+
+
+
+
+
+ {{detailData.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{priceTypeObj[item.type]}}
+
+
+ ¥{{item.sale}}
+
+
+
+
+
+
+
+ {{priceTypeObj[item.type]}}
+
+
+ ¥{{item.sale}}
+
+
+
+
+
+
+
+ {{priceTypeObj[item.type]}}
+
+
+ ¥{{item.sale}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 产出概率
+
+
+
+
+ {{detailData.probability && detailData.probability['NORMAL']*100 || 0}}%
+
+
+
+
+
+ {{detailData.probability && detailData.probability['HIDDEN']*100 || 0}}%
+
+
+
+
+
+ {{detailData.probability && detailData.probability['RARE']*100 || 0}}%
+
+
+
+
+
+ {{detailData.probability && detailData.probability['SUPREME']*100 || 0}}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+ {{item.ponit}}
+
+
+ ¥
+ {{item.sellPrice}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/draw copy.vue b/pages/index/draw copy.vue
new file mode 100644
index 0000000..5f88d8e
--- /dev/null
+++ b/pages/index/draw copy.vue
@@ -0,0 +1,671 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/draw.vue b/pages/index/draw.vue
new file mode 100644
index 0000000..69d4fdf
--- /dev/null
+++ b/pages/index/draw.vue
@@ -0,0 +1,736 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/drawFree.vue b/pages/index/drawFree.vue
new file mode 100644
index 0000000..cb4119e
--- /dev/null
+++ b/pages/index/drawFree.vue
@@ -0,0 +1,549 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/drawNine.vue b/pages/index/drawNine.vue
new file mode 100644
index 0000000..7913d03
--- /dev/null
+++ b/pages/index/drawNine.vue
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..01eb791
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,743 @@
+
+
+
+
+
+
+
+ {{notice.summary ? notice.summary : '暂无公告'}}
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+ ¥
+ {{item.price[0].sale}}
+
+
+
+
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/lastRanking.vue b/pages/index/lastRanking.vue
new file mode 100644
index 0000000..2df1a9e
--- /dev/null
+++ b/pages/index/lastRanking.vue
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.nickname | maskString }}
+ {{ item.points }}积分
+
+
+
+
+ {{childItem.info.abbreviation}}
+ 、
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 我的排名:
+ 999+
+
+
+
+
+
+ {{ selfData.points }}积分
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/new-index copy 1.vue b/pages/index/new-index copy 1.vue
new file mode 100644
index 0000000..b31278c
--- /dev/null
+++ b/pages/index/new-index copy 1.vue
@@ -0,0 +1,1837 @@
+
+
+
+
+
+
+
+
+
+
+ 排行
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看宝贝
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+ 您今日在本商城的消费已达到1000元。为了确保您的消费安全,请确认是否继续购买。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/new-index copy.vue b/pages/index/new-index copy.vue
new file mode 100644
index 0000000..eb84ad4
--- /dev/null
+++ b/pages/index/new-index copy.vue
@@ -0,0 +1,1826 @@
+
+
+
+
+
+
+
+
+
+ 排行榜
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看宝贝
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+ 您今日在本商城的消费已达到1000元。为了确保您的消费安全,请确认是否继续购买。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.title}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/new-index-y.vue b/pages/index/new-index-y.vue
new file mode 100644
index 0000000..6329d50
--- /dev/null
+++ b/pages/index/new-index-y.vue
@@ -0,0 +1,1292 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.settlement || '/'}}
+
+ 个/元
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/new-index.vue b/pages/index/new-index.vue
new file mode 100644
index 0000000..1bf2d2b
--- /dev/null
+++ b/pages/index/new-index.vue
@@ -0,0 +1,3120 @@
+
+
+
+
+ 免费试玩
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.nickName}}开启{{item.boxName}} 得到了{{item.productName}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看宝贝
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+ 您今日在本商城的消费已达到1000元。为了确保您的消费安全,请确认是否继续购买。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{prizeData.productName}}
+ 商城积分:{{prizeData.productMall}}
+
+
+
+
+ 来发试试
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 免费试玩
+
+
+
+
+
+
+
+
+
+
+ 请阅读并同意以下条款
+
+ 为保障您的合法权益,请您先阅读并同意《用户协议》 以及《隐私政策》
+
+
+
+
+
+
+
+
+
+
+
+
+ {{index+1}}.{{item.nickname}}
+ {{Number(item.period) + 1}}轮{{Number(item.periodNum) + 1}}关
+
+
+
+ 排名奖励:
+
+
+ {{childItem.info.abbreviation}}*{{childItem.num}}、
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/order.vue b/pages/index/order.vue
new file mode 100644
index 0000000..8ff8625
--- /dev/null
+++ b/pages/index/order.vue
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/paySuc.vue b/pages/index/paySuc.vue
new file mode 100644
index 0000000..aef51d6
--- /dev/null
+++ b/pages/index/paySuc.vue
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+
+
+
+
+
+ 是否支付成功?
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/prize.vue b/pages/index/prize.vue
new file mode 100644
index 0000000..633a7e0
--- /dev/null
+++ b/pages/index/prize.vue
@@ -0,0 +1,490 @@
+
+
+
+
+
+ 开奖
+
+
+
+
+
+
+
+
+ 本期盲盒奖池
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 开奖
+
+
+
+
+
+
+
+
+
+ 温馨提示
+ 未开完盲盒 请返回继续开盒
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/ranking.vue b/pages/index/ranking.vue
new file mode 100644
index 0000000..bcf8f94
--- /dev/null
+++ b/pages/index/ranking.vue
@@ -0,0 +1,1043 @@
+
+
+
+
+
+
+
+ 本期榜单
+
+ 距本场活动结束
+
+ {{expiredTime || '00时00分00秒'}}
+
+
+
+ 本期奖励
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.nickname | maskString }}
+ {{ item.points }}积分
+
+
+
+
+ {{childItem.info.abbreviation}}
+ 、
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 我的排名:
+ 999+
+
+
+
+
+
+ {{ selfData.points }}积分
+
+
+
+
+
+
+
+
+
+
+
+ 榜单说明
+ 活动时间:{{detail.startTime}}-{{detail.endTime}}
+
+
+
+ 确定
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/sign.vue b/pages/index/sign.vue
new file mode 100644
index 0000000..1e6e1d6
--- /dev/null
+++ b/pages/index/sign.vue
@@ -0,0 +1,349 @@
+
+
+
+
+
+ 本月累计签到
+
+ 天
+ {{dateValue}}
+
+
+
+ {{item.numDay}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.info.name}} *{{item.num}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/webview.vue b/pages/index/webview.vue
new file mode 100644
index 0000000..279ac52
--- /dev/null
+++ b/pages/index/webview.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/index/首页-zuiyou.vue b/pages/index/首页-zuiyou.vue
new file mode 100644
index 0000000..eac8178
--- /dev/null
+++ b/pages/index/首页-zuiyou.vue
@@ -0,0 +1,1099 @@
+
+
+
+
+
+
+
+
+ {{item}}
+
+
+
+
+
+ {{list[current].name}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{gradeObj[item.itemFirst.grade]}}
+
+ 无限量
+ 剩{{Number(item.itemFirst.curStock) || 0}}件
+
+
+
+
+
+
+
+
+
+ {{list[current].itemFirst.abbreviation}}
+
+
+
+
+
+
+ (就它了,现在抽,抽中概率更大呦)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/bind.vue b/pages/login/bind.vue
new file mode 100644
index 0000000..71f8c15
--- /dev/null
+++ b/pages/login/bind.vue
@@ -0,0 +1,179 @@
+
+
+
+
+
+ {{typeTxt[type]}}
+
+
+
+
+ {{ countTime === 0 ? '获取验证码' : countTime + 's' }}
+
+
+ 确认
+
+
+
+
+
+
+
+
diff --git a/pages/login/bindPhone.vue b/pages/login/bindPhone.vue
new file mode 100644
index 0000000..6683545
--- /dev/null
+++ b/pages/login/bindPhone.vue
@@ -0,0 +1,213 @@
+
+
+
+ 妙趣盲盒
+
+
+
+
+
+
+ {{ countTime === 0 ? '获取验证码' : countTime + 's' }}
+
+
+ 绑定手机号
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/get-weixin-code.html b/pages/login/get-weixin-code.html
new file mode 100755
index 0000000..1120153
--- /dev/null
+++ b/pages/login/get-weixin-code.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+ 微信登录
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/index.vue b/pages/login/index.vue
new file mode 100644
index 0000000..8b5c9e4
--- /dev/null
+++ b/pages/login/index.vue
@@ -0,0 +1,214 @@
+
+
+
+
+
+ 180****1927
+
+
+ 本机号码一键登录
+ 其他手机登录
+
+
+
+
+ 我已阅读并同意中国移动认证服务条款 和《用户协议》 、《隐私政策》
+
+
+
+ 微信登录
+
+
+
+
+
+
+
+
+
diff --git a/pages/login/login copy.vue b/pages/login/login copy.vue
new file mode 100644
index 0000000..a0e1e11
--- /dev/null
+++ b/pages/login/login copy.vue
@@ -0,0 +1,522 @@
+
+
+
+
+
+ 登录
+
+
+ 请输入手机号
+ 用{{type === 'password' ? '验证码' : '密码'}}登录
+
+
+ 请输入{{type === 'password' ? '密码' : '验证码'}}
+
+
+
+
+ {{ countTime === 0 ? '获取验证码' : countTime + 's' }}
+
+
+
+
+
+ 我已同意《用户协议》 和《隐私政策》
+
+ 登录
+
+ 如忘记密码,可点此找回
+
+ 注册账号
+
+
+
+ 微信登录
+
+
+
+
+
+
+
diff --git a/pages/login/login.vue b/pages/login/login.vue
new file mode 100644
index 0000000..f02b88e
--- /dev/null
+++ b/pages/login/login.vue
@@ -0,0 +1,344 @@
+
+
+
+ 妙趣盲盒
+
+
+
+
+
+
+ {{ countTime === 0 ? '获取验证码' : countTime + 's' }}
+
+
+ 登录
+
+
+
+ 未注册手机号将为您自动注册,注册或登录即为同意
+ 《服务协议》 、《隐私政策》 、《儿童个人信息保护规则》
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/password.vue b/pages/login/password.vue
new file mode 100644
index 0000000..be9d61e
--- /dev/null
+++ b/pages/login/password.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+ 输入密码
+
+
+
+
+
+
+
+
+
+ 我已同意《用户协议》 《隐私政策》
+
+ 注册
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/past-due.vue b/pages/login/past-due.vue
new file mode 100644
index 0000000..d0d84af
--- /dev/null
+++ b/pages/login/past-due.vue
@@ -0,0 +1,76 @@
+
+
+
+
+ 登录已过期,请退出重新打开页面!
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/login/registerAndForget.vue b/pages/login/registerAndForget.vue
new file mode 100644
index 0000000..4079809
--- /dev/null
+++ b/pages/login/registerAndForget.vue
@@ -0,0 +1,236 @@
+
+
+
+
+
+ {{typeTxt[type]}}
+
+
+
+
+ {{ countTime === 0 ? '获取验证码' : countTime + 's' }}
+
+
+
+
+ 确认
+ 立即登录
+
+
+
+
+
+
+
+
diff --git a/pages/login/shut-down.vue b/pages/login/shut-down.vue
new file mode 100644
index 0000000..90debe3
--- /dev/null
+++ b/pages/login/shut-down.vue
@@ -0,0 +1,88 @@
+
+
+
+
+ 您的账号已经暂停使用, 如有疑问点我联系客服 ,谢谢
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/about.vue b/pages/mine/about.vue
new file mode 100644
index 0000000..79ce137
--- /dev/null
+++ b/pages/mine/about.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+ 妙趣盲盒
+ v1.0
+ 时尚潮玩优质商品,尊享八面舒心生活。
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/addAddress copy.vue b/pages/mine/addAddress copy.vue
new file mode 100644
index 0000000..9888d37
--- /dev/null
+++ b/pages/mine/addAddress copy.vue
@@ -0,0 +1,367 @@
+
+
+
+
+
+
+
+
+ 收货人
+
+
+
+
+
+
+ 联系电话
+
+
+
+
+
+
+ 所在地区
+
+
+
+
+
+
+
+ 详细地址
+
+
+
+
+
+
+
+
+
+ 设为默认地址
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/addAddress.vue b/pages/mine/addAddress.vue
new file mode 100644
index 0000000..fe7f288
--- /dev/null
+++ b/pages/mine/addAddress.vue
@@ -0,0 +1,239 @@
+
+
+
+
+
+ 收货人
+
+
+
+ 联系电话
+
+
+
+ 所在地区
+
+
+
+
+ 详细地址
+
+
+
+
+
+ 设为默认地址
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/address copy.vue b/pages/mine/address copy.vue
new file mode 100644
index 0000000..97e3cd0
--- /dev/null
+++ b/pages/mine/address copy.vue
@@ -0,0 +1,352 @@
+
+
+
+
+ 收货地址
+
+
+
+
+
+
+
+
+
+ {{item.province}} {{item.city}} {{item.area}} {{item.address}}
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/address.vue b/pages/mine/address.vue
new file mode 100644
index 0000000..a68ed53
--- /dev/null
+++ b/pages/mine/address.vue
@@ -0,0 +1,269 @@
+
+
+
+
+
+
+
+
+
+ {{item.province}} {{item.city}} {{item.area}} {{item.address}}
+
+
+
+
+ 默认地址
+
+
+
+
+ 编辑
+
+
+
+ 删除
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/boxConfirm copy 1.vue b/pages/mine/boxConfirm copy 1.vue
new file mode 100644
index 0000000..9804c31
--- /dev/null
+++ b/pages/mine/boxConfirm copy 1.vue
@@ -0,0 +1,481 @@
+
+
+
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}} {{address.address}}
+
+
+
+ 选择地址
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ {{item.price.sale}}
+ X1
+
+
+
+
+
+
+ 商品数量
+ {{previewData.quantity}}
+
+
+ 邮费
+ {{previewData.deliveryFee}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/boxConfirm copy.vue b/pages/mine/boxConfirm copy.vue
new file mode 100644
index 0000000..d16cc6e
--- /dev/null
+++ b/pages/mine/boxConfirm copy.vue
@@ -0,0 +1,682 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 地址:{{address.province}} {{address.city}} {{address.area}} {{address.address}}
+
+
+
+
+
+
+
+ {{previewData.productName}}
+
+
+ ¥
+ {{previewData.price.sale}}
+
+ x{{previewData.quantity}}
+
+
+
+
+
+
+ 运费
+ ¥0
+
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 配送服务:
+
+ ¥ {{previewData.deliveryFee}}
+
+
+
+ 实付金额:
+
+ ¥ {{previewData.totalAmount}}
+
+
+
+ 实付积分:
+
+
+
+ {{detailData.mallPoint}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/boxConfirm.vue b/pages/mine/boxConfirm.vue
new file mode 100644
index 0000000..63e0177
--- /dev/null
+++ b/pages/mine/boxConfirm.vue
@@ -0,0 +1,483 @@
+
+
+
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}} {{address.address}}
+
+
+
+ 选择地址
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ {{item.price.sale}}
+ X1
+
+
+
+
+
+
+ 商品数量
+ {{previewData.quantity}}
+
+
+ 邮费
+ {{previewData.deliveryFee}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/boxOrder copy.vue b/pages/mine/boxOrder copy.vue
new file mode 100644
index 0000000..ee00f2d
--- /dev/null
+++ b/pages/mine/boxOrder copy.vue
@@ -0,0 +1,327 @@
+
+
+
+
+ 盲盒订单
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ ¥ {{item.totalAmount}}
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/boxOrder.vue b/pages/mine/boxOrder.vue
new file mode 100644
index 0000000..120b561
--- /dev/null
+++ b/pages/mine/boxOrder.vue
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ {{priceTypeObj[item.type]}}
+
+ ¥ {{Number(item.totalAmount)}}
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/boxRecrd copy.vue b/pages/mine/boxRecrd copy.vue
new file mode 100644
index 0000000..c9c7c63
--- /dev/null
+++ b/pages/mine/boxRecrd copy.vue
@@ -0,0 +1,1858 @@
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+ 发货截止时间:{{item.shipExpiredTime}}
+
+
+
+
+
+
+
+
+
+
+ {{item.recoveryPoint}} 积分
+
+
+
+
+
+
+
+
+ 没有更多了~
+
+
+ 猜你喜欢
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+ {{item.point.mall}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+ 回收积分:{{item.recoveryPoint}}
+ X1
+
+
+
+
+
+ 兑换积分数
+ {{totalPoint}}
+
+ 确认兑换
+
+
+
+
+
+
+
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}}
+ {{address.address}}
+
+
+
+
+
+
+
+
+ 选择收货地址,让快递到家~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+
+
+
+
+
+
+
+ 商品数量
+ {{previewData.quantity}}
+
+
+
+ 邮费
+ ¥{{Number(previewData.deliveryFee)}}
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+ 我已满18岁,已阅读并同意
+ 《用户协议》、
+ 《隐私政策》、
+ 《儿童个人信息保护规则》、
+ 《支付服务协议》
+
+ 确认发货 ¥{{Number(previewData.totalAmount)}}
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+ 是否确认将商品进行兑换? 确认后即将商品兑换成{{totalPoint}} 积分,无法再进行提货。
+
+
+
+
+
+
+ 单次提取≥{{detail.num}}件商品包邮({{detail.exclude.join(',')}}地区除外) 。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/boxRecrd.vue b/pages/mine/boxRecrd.vue
new file mode 100644
index 0000000..d1ce940
--- /dev/null
+++ b/pages/mine/boxRecrd.vue
@@ -0,0 +1,2118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+ 发货截止时间:{{item.shipExpiredTime}}
+
+
+
+
+ {{item.recoveryPoint}} 积分
+ {{item.recoveryPoint}} 积分
+
+
+
+
+
+
+
+
+ 没有更多了~
+
+ 猜你喜欢
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+ {{item.point.mall}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productAbbreviation}}
+
+
+
+ 回收积分:{{item.recoveryPoint}}
+ X1
+
+
+
+
+
+ 兑换积分数
+ {{totalPoint}}
+
+ 确认兑换
+
+
+
+
+
+
+
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}}
+ {{address.address}}
+
+
+
+
+
+
+
+
+ 选择收货地址,让快递到家~
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+
+
+
+
+
+ 商品数量
+ {{previewData.quantity}}
+
+
+
+ 邮费
+ ¥{{Number(previewData.deliveryFee)}}
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+ 我已满18岁,已阅读并同意
+ 《用户协议》、
+ 《隐私政策》、
+ 《儿童个人信息保护规则》、
+ 《支付服务协议》
+
+ 确认发货 ¥{{Number(previewData.totalAmount)}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{virtualDetail.productAbbreviation}}
+
+
+
+
+
+
+
+ 充值账号
+
+
+
+
+
+ {{virtualDetail.tips}}
+
+
+
+
+
+
+ 我已满18岁,已阅读并同意
+ 《用户协议》、
+ 《隐私政策》、
+ 《儿童个人信息保护规则》、
+ 《支付服务协议》
+
+ 确认发货
+
+
+
+
+
+
+
+
+
+ 支付成功
+
+
+
+
+
+ 是否确认将商品进行兑换? 确认后即将商品兑换成{{totalPoint}} 积分,无法再进行提货。
+
+
+
+
+
+
+ 单次提取≥{{detail.num}}件商品包邮({{detail.exclude.join(',')}}地区除外) 。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/collect copy.vue b/pages/mine/collect copy.vue
new file mode 100644
index 0000000..dada2ac
--- /dev/null
+++ b/pages/mine/collect copy.vue
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/collect.vue b/pages/mine/collect.vue
new file mode 100644
index 0000000..4e9188e
--- /dev/null
+++ b/pages/mine/collect.vue
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+ ¥ {{item.sellPrice}}
+
+
+
+ {{item.mallPoint}}
+
+
+ 取消收藏
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/components/countdow.vue b/pages/mine/components/countdow.vue
new file mode 100644
index 0000000..c63deba
--- /dev/null
+++ b/pages/mine/components/countdow.vue
@@ -0,0 +1,78 @@
+
+
+
+ {{ days }}天 {{ hours }}时 {{ minutes }}分 {{ seconds }}秒
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/coupon copy.vue b/pages/mine/coupon copy.vue
new file mode 100644
index 0000000..a1bcf8b
--- /dev/null
+++ b/pages/mine/coupon copy.vue
@@ -0,0 +1,183 @@
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+ 新人10元 大礼包
+
+ 新人入门大礼包,满30减10元,申购指定商品可用
+
+ {{tabList[tabIndex].label}}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/coupon.vue b/pages/mine/coupon.vue
new file mode 100644
index 0000000..45a5031
--- /dev/null
+++ b/pages/mine/coupon.vue
@@ -0,0 +1,261 @@
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+ 购物{{typeObj[item.type]}}券
+ {{item.name}}
+
+ {{item.tips}}
+
+ 有效期至{{item.expiredTime}}
+
+
+
+ {{Number(item.amount)}}
+ {{item.type === 'REDUCTION' ? '' : '折'}}
+
+ {{tabObj[item.used]}}
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/customer.vue b/pages/mine/customer.vue
new file mode 100644
index 0000000..ae0c179
--- /dev/null
+++ b/pages/mine/customer.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/editName copy.vue b/pages/mine/editName copy.vue
new file mode 100644
index 0000000..f7b5d37
--- /dev/null
+++ b/pages/mine/editName copy.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ 确定
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/editName.vue b/pages/mine/editName.vue
new file mode 100644
index 0000000..5ec1c4f
--- /dev/null
+++ b/pages/mine/editName.vue
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/feedback.vue b/pages/mine/feedback.vue
new file mode 100644
index 0000000..f781cae
--- /dev/null
+++ b/pages/mine/feedback.vue
@@ -0,0 +1,327 @@
+
+
+
+
+
+
+
+
+ {{from.content.length}}/200字
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 您的信息遵循隐藏保护协议,仅官方客服人员可见!
+ 提交
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/mine/index.vue b/pages/mine/index.vue
new file mode 100644
index 0000000..2de7133
--- /dev/null
+++ b/pages/mine/index.vue
@@ -0,0 +1,703 @@
+
+
+
+
+
+
+ {{infoDetail.points||0}}
+ 积分
+
+
+
+ 25
+ 优惠券
+
+
+
+ {{count||0}}
+ 物品
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue
new file mode 100644
index 0000000..bf9df5f
--- /dev/null
+++ b/pages/mine/mine.vue
@@ -0,0 +1,574 @@
+
+
+
+
+
+ {{infoDetail.points||0}}
+ 积分
+
+
+ {{total || 0}}
+ 优惠券
+
+
+ {{promptCount || 0}}
+ 提示卡
+
+
+ {{count||0}}
+ 仓库
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/moreCoupon copy.vue b/pages/mine/moreCoupon copy.vue
new file mode 100644
index 0000000..83ea54b
--- /dev/null
+++ b/pages/mine/moreCoupon copy.vue
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+ ¥ 20
+
+ 商城通用券
+
+
+ {{item.quantity}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/moreCoupon.vue b/pages/mine/moreCoupon.vue
new file mode 100644
index 0000000..c635add
--- /dev/null
+++ b/pages/mine/moreCoupon.vue
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+
+
+
+ {{Number(item.amount)}} {{item.type === 'REDUCTION' ? '' : '折'}}
+
+
+
+ {{item.name}}
+
+
+ {{typeObj[item.type]}}券
+ {{item.tips}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/notice.vue b/pages/mine/notice.vue
new file mode 100644
index 0000000..3e4c351
--- /dev/null
+++ b/pages/mine/notice.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{item.title}}
+ 发布时间:{{formatDateTime(item.createdAt)}}
+
+ {{item.summary}}
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/noticeDetail.vue b/pages/mine/noticeDetail.vue
new file mode 100644
index 0000000..e329396
--- /dev/null
+++ b/pages/mine/noticeDetail.vue
@@ -0,0 +1,121 @@
+
+
+
+
+
+ {{detailData.title}}
+ 发布时间:{{formatDateTime(detailData.createdAt)}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/orderBoxDetail.vue b/pages/mine/orderBoxDetail.vue
new file mode 100644
index 0000000..5f2ace4
--- /dev/null
+++ b/pages/mine/orderBoxDetail.vue
@@ -0,0 +1,528 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{detailData.name}}
+
+
+ ¥{{detailData.totalAmount}}
+ x{{typeObj[detailData.type]}}
+
+
+
+
+
+ 优惠
+ ¥{{Number(detailData.discountAmount)}}
+
+
+ 实付金额
+ ¥{{Number(detailData.totalAmount)}}
+
+
+ 实际支付
+ ¥{{Number(detailData.totalAmount)}}
+
+
+
+
+ 订单编号
+ {{detailData.no}}
+
+
+ 下单时间
+ {{detailData.paidAt ? formatDateTime(detailData.paidAt) : '-'}}
+
+
+ 订单状态
+ {{statusObj[detailData.status]}}
+
+
+ 支付方式
+ {{detailData.method ? paidWith[detailData.method] : '-'}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/orderStatusDetail copy.vue b/pages/mine/orderStatusDetail copy.vue
new file mode 100644
index 0000000..9b7b732
--- /dev/null
+++ b/pages/mine/orderStatusDetail copy.vue
@@ -0,0 +1,779 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/orderStatusDetail.vue b/pages/mine/orderStatusDetail.vue
new file mode 100644
index 0000000..0e1e63d
--- /dev/null
+++ b/pages/mine/orderStatusDetail.vue
@@ -0,0 +1,895 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{detailData.productName}}
+
+
+
+
+
+ {{detailData.points}}积分
+
+
+ x{{detailData.quantity}}
+
+
+
+
+ 运费
+ ¥ {{detailData.deliveryFee || 0}}
+
+
+ 实付积分
+ 0
+ {{detailData.points}}积分
+
+
+ 实际支付
+ ¥ {{detailData.deliveryFee || 0}}
+
+ {{detailData.totalPoints}}积分
+ ¥ {{detailData.deliveryFee}}
+
+ ¥ {{detailData.points}}
+
+
+
+
+
+
+
+ 订单编号
+ {{detailData.no}}
+
+
+ 下单时间
+ {{detailData.paidAt ? formatDateTime(detailData.paidAt) : '-'}}
+
+
+ 订单状态
+ {{statusObj[detailData.status]}}
+
+
+ 支付方式
+ {{detailData.method ? paidWith[detailData.method] : '-'}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示
+ 以下物品已超过发货时间,取消后将自动兑换为积分
+
+
+
+
+
+ {{item.productAbbreviation}}
+ 回收积分:{{item.recoveryPoint}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/payVirtualSuccess.vue b/pages/mine/payVirtualSuccess.vue
new file mode 100644
index 0000000..eb4885e
--- /dev/null
+++ b/pages/mine/payVirtualSuccess.vue
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+ 兑换成功
+
+
+ 再去逛逛
+ 查看订单
+
+
+
+ 用户信息
+ {{nickname}}
+
+
+ 商品名称
+ {{productName}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/point copy.vue b/pages/mine/point copy.vue
new file mode 100644
index 0000000..9541672
--- /dev/null
+++ b/pages/mine/point copy.vue
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+ 订单号:{{item.orderNo}}
+ 使用类型:{{typeObj[item.type]}}
+ 使用时间:{{formatDateTime(item.createdAt)}}
+
+
+ {{item.points}}
+
+
+
+ 没有更多了~
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/point.vue b/pages/mine/point.vue
new file mode 100644
index 0000000..8fda7de
--- /dev/null
+++ b/pages/mine/point.vue
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单号:{{item.orderNo}}
+
+ 使用时间:{{formatDateTime(item.createdAt)}}
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/prompt.vue b/pages/mine/prompt.vue
new file mode 100644
index 0000000..f4497ec
--- /dev/null
+++ b/pages/mine/prompt.vue
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+ 提示卡
+
+ 使用提示卡可提前揭示本次开盲盒中奖商品的一个特点
+
+ 有效期至{{item.expiredTime}}
+
+
+
+
+ 提示卡
+
+ {{tabObj[item.used]}}
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/setting copy.vue b/pages/mine/setting copy.vue
new file mode 100644
index 0000000..f7ab606
--- /dev/null
+++ b/pages/mine/setting copy.vue
@@ -0,0 +1,256 @@
+
+
+
+
+
+
+ 昵称
+
+ {{infoDetail.nickname}}
+
+
+
+
+ 手机号
+ {{infoDetail.phone ? infoDetail.phone : '未绑定手机'}}
+
+
+ ID
+ {{infoDetail.username}}
+
+
+
+
+ 服务协议
+
+
+
+
+
+ 隐私政策
+
+
+
+ 关于我们
+
+
+
+ 联系客服
+
+
+
+ 退出登录
+
+
+
+ 温馨提示
+ 确定要退出登录?
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/setting.vue b/pages/mine/setting.vue
new file mode 100644
index 0000000..1bdff9d
--- /dev/null
+++ b/pages/mine/setting.vue
@@ -0,0 +1,392 @@
+
+
+
+
+
+
+ 头像
+
+
+
+
+
+
+
+
+
+ 昵称
+
+ {{infoDetail.nickname}}
+
+
+
+
+
+ ID
+
+ {{infoDetail.id}}
+
+
+
+
+
+ 用户协议
+
+
+
+
+
+
+ 隐私政策
+
+
+
+
+
+ 儿童个人信息保护规则
+
+
+
+
+
+ 支付服务协议
+
+
+
+
+
+ 关于我们
+
+
+
+
+
+ 清除缓存
+
+
+
+
+
+ 联系客服
+
+
+
+
+
+ 退出登录
+
+
+
+
+ 确定要退出登录?
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/sign copy.vue b/pages/mine/sign copy.vue
new file mode 100644
index 0000000..cf87fa1
--- /dev/null
+++ b/pages/mine/sign copy.vue
@@ -0,0 +1,241 @@
+
+
+ 签到中心
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/sign.vue b/pages/mine/sign.vue
new file mode 100644
index 0000000..a71b87d
--- /dev/null
+++ b/pages/mine/sign.vue
@@ -0,0 +1,582 @@
+
+
+
+
+ 累计签到 {{total.length}} 天
+
+
+
+
+
+ +{{item.rewardVoList[0].num}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{isSign ? '已签到' : '签到领积分'}}
+
+
+
+
+
+
+ {{childItem.name}}
+ {{childItem.summary}}
+
+ {{statusObj[childItem.status]}}
+
+ {{statusObj[childItem.status]}}
+
+
+
+
+
+
+
+
+
+ {{childItem.name}}
+ {{childItem.summary}}
+
+ {{statusObj[childItem.status]}}
+
+ {{statusObj[childItem.status]}}
+
+
+
+
+
+
+
+
+
+ {{childItem.name}}
+ {{childItem.summary}}
+
+ {{statusObj[childItem.status]}}
+
+ {{statusObj[childItem.status]}}
+
+
+
+
+
+
+
+
+
+ {{childItem.name}}
+ {{childItem.summary}}
+
+ {{statusObj[childItem.status]}}
+
+ {{statusObj[childItem.status]}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/topUp copy.vue b/pages/mine/topUp copy.vue
new file mode 100644
index 0000000..1ff8d3b
--- /dev/null
+++ b/pages/mine/topUp copy.vue
@@ -0,0 +1,230 @@
+
+
+
+
+
+
+ {{infoDetail.nickname||''}}
+ 代币余额:10
+
+
+
+
+
+
+ 赠送{{item.give}}代币
+
+
+ {{item.price}}
+ 代币
+
+ ¥6
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/topUp.vue b/pages/mine/topUp.vue
new file mode 100644
index 0000000..26da742
--- /dev/null
+++ b/pages/mine/topUp.vue
@@ -0,0 +1,689 @@
+
+
+
+
+ 选择充值金额
+
+
+
+ 赠送{{item.gift}}代币
+
+
+ {{item.coin}}
+
+ ¥ {{item.price.settlement}}
+
+
+
+
+
+
+
+
+ 充值金额
+ {{list[listIndex].price.settlement}} 元
+
+
+ 充值代币
+ {{list[listIndex].coin}} 代币
+
+
+ 充值奖励
+ {{list[listIndex].gift}} 代币
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+ 立即支付 ¥{{list[listIndex].price.sale}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/topUpOrder copy.vue b/pages/mine/topUpOrder copy.vue
new file mode 100644
index 0000000..1d3cff2
--- /dev/null
+++ b/pages/mine/topUpOrder copy.vue
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+ 充值金额
+ ¥6
+
+
+ 充值代币
+ 120代币
+
+
+ 充值奖励
+ 0代币
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/topUpOrder.vue b/pages/mine/topUpOrder.vue
new file mode 100644
index 0000000..d834edf
--- /dev/null
+++ b/pages/mine/topUpOrder.vue
@@ -0,0 +1,277 @@
+
+
+
+
+
+
+ 充值金额
+ {{form.price}}元
+
+
+ 充值代币
+ {{form.coin}}代币
+
+
+ 充值奖励
+ {{form.gift}}代币
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/topUpSuc copy.vue b/pages/mine/topUpSuc copy.vue
new file mode 100644
index 0000000..4f212ec
--- /dev/null
+++ b/pages/mine/topUpSuc copy.vue
@@ -0,0 +1,270 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/topUpSuc.vue b/pages/mine/topUpSuc.vue
new file mode 100644
index 0000000..22889ce
--- /dev/null
+++ b/pages/mine/topUpSuc.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+ 充值成功
+
+ 去开盒
+
+
+ 用户信息
+ {{infoDetail.nickname}}
+
+
+ 充值代币
+ {{form.coin}}代币
+
+
+ 充值奖励
+ {{form.gift}}代币
+
+
+ 实付金额
+ ¥{{form.price}}
+
+
+ 账户代币余额
+ {{infoDetail.coins}}代币
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/virtual.vue b/pages/mine/virtual.vue
new file mode 100644
index 0000000..901c7e6
--- /dev/null
+++ b/pages/mine/virtual.vue
@@ -0,0 +1,812 @@
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示
+ 以下物品已超过发货时间,取消后将自动兑换为积分
+
+
+
+
+
+ {{item.productAbbreviation}}
+ 回收积分:{{item.recoveryPoint}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/virtualDetail.vue b/pages/mine/virtualDetail.vue
new file mode 100644
index 0000000..ce5a910
--- /dev/null
+++ b/pages/mine/virtualDetail.vue
@@ -0,0 +1,910 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{detailData.productName}}
+
+
+
+
+
+
+
+
+
+
+
+
+ 订单编号
+ {{detailData.no}}
+
+
+ 充值账号
+ {{detailData.account}}
+
+
+ 下单时间
+ {{detailData.createdAt ? formatDateTime(detailData.createdAt) : '-'}}
+
+
+ 订单状态
+ {{statusObj[detailData.status]}}
+
+
+ CDKEY
+ {{detailData.result}}
+
+
+
+ {{detailData.tips}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示
+ 以下物品已超过发货时间,取消后将自动兑换为积分
+
+
+
+
+
+ {{item.productAbbreviation}}
+ 回收积分:{{item.recoveryPoint}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/mine/white.vue b/pages/mine/white.vue
new file mode 100644
index 0000000..e122449
--- /dev/null
+++ b/pages/mine/white.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/order/confirm.vue b/pages/order/confirm.vue
new file mode 100644
index 0000000..e9b7431
--- /dev/null
+++ b/pages/order/confirm.vue
@@ -0,0 +1,593 @@
+
+
+
+
+
+ 提交订单
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 地址:{{address.province}} {{address.city}} {{address.area}} {{address.address}}
+
+
+
+
+
+
+
+
+ {{previewData.productName}}
+
+
+ ¥
+ {{previewData.price.sale}}
+
+ x{{previewData.quantity}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+ 配送服务:
+
+ ¥ {{previewData.deliveryFee}}
+
+
+
+ 实付金额:
+
+ ¥ {{previewData.totalAmount}}
+
+
+
+ 实付积分:
+
+
+
+ {{detailData.mallPoint}}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/order/index copy.vue b/pages/order/index copy.vue
new file mode 100644
index 0000000..56cd4c8
--- /dev/null
+++ b/pages/order/index copy.vue
@@ -0,0 +1,433 @@
+
+
+
+
+ 我的订单
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+
+ ¥ {{item.amount}}
+ x {{item.quantity}}
+
+
+
+
+
+
+ 实付金额
+ ¥{{item.totalAmount}}
+
+
+ 实付积分
+ {{item.points}}
+
+
+ 无需支付
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/order/index.vue b/pages/order/index.vue
new file mode 100644
index 0000000..677cd8b
--- /dev/null
+++ b/pages/order/index.vue
@@ -0,0 +1,818 @@
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+
+
+
+
+ {{item.points}}积分
+
+
+
+ x {{item.quantity}}
+
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 温馨提示
+ 以下物品已超过发货时间,取消后将自动兑换为积分
+
+
+
+
+
+ {{item.productAbbreviation}}
+ 回收积分:{{item.recoveryPoint}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/product/detail.vue b/pages/product/detail.vue
new file mode 100644
index 0000000..be1a537
--- /dev/null
+++ b/pages/product/detail.vue
@@ -0,0 +1,668 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{detailData.name||''}}
+
+
+
+
+
+ 商品详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/product/product.vue b/pages/product/product.vue
new file mode 100644
index 0000000..17b00ae
--- /dev/null
+++ b/pages/product/product.vue
@@ -0,0 +1,458 @@
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ ¥{{item.price.sale}}
+
+ 积分{{item.point.mall | numberFormat(item.point.mall)}}
+
+
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/search/index.vue b/pages/search/index.vue
new file mode 100644
index 0000000..2c04e06
--- /dev/null
+++ b/pages/search/index.vue
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+ 历史搜索
+
+
+
+
+ {{item}}
+
+
+
+
+
+
+
+
+
diff --git a/pages/search/search-list.vue b/pages/search/search-list.vue
new file mode 100644
index 0000000..320d6a4
--- /dev/null
+++ b/pages/search/search-list.vue
@@ -0,0 +1,228 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ ¥ {{item.price.sale}}
+
+
+ {{item.point.mall | numberFormat(item.point.mall)}}
+
+
+
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/cashier copy.vue b/pages/shop/cashier copy.vue
new file mode 100644
index 0000000..d181429
--- /dev/null
+++ b/pages/shop/cashier copy.vue
@@ -0,0 +1,494 @@
+
+
+
+
+ 支付方式
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+ 确认支付
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/confirm copy.vue b/pages/shop/confirm copy.vue
new file mode 100644
index 0000000..c266eb2
--- /dev/null
+++ b/pages/shop/confirm copy.vue
@@ -0,0 +1,447 @@
+
+
+
+
+
+
+
+ 新建收货地址,让快递到家~
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}} {{address.address}}
+
+
+
+
+
+
+
+
+
+ {{previewData.productName}}
+
+ {{previewData.price.sale}}
+ X{{previewData.quantity}}
+
+
+
+
+
+
+ 商品数量
+ {{previewData.quantity}}
+
+
+ 邮费
+ {{previewData.deliveryFee}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/confirm.vue b/pages/shop/confirm.vue
new file mode 100644
index 0000000..d1a6f37
--- /dev/null
+++ b/pages/shop/confirm.vue
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+ 新建收货地址,让快递到家~
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}} {{address.address}}
+
+
+
+
+
+
+
+
+
+ {{previewData.productName}}
+
+ {{previewData.price.sale}}
+ X{{previewData.quantity}}
+
+
+
+
+
+
+ 商品数量
+ {{previewData.quantity}}
+
+
+ 邮费
+ {{previewData.deliveryFee}}
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/detail copy.vue b/pages/shop/detail copy.vue
new file mode 100644
index 0000000..39cf6b8
--- /dev/null
+++ b/pages/shop/detail copy.vue
@@ -0,0 +1,567 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{detailData.name||''}}
+
+
+ {{detailData.mallPoint||''}}
+ ¥{{detailData.price.sale||0}}
+
+ {{feeRule}}
+
+
+ 详情介绍
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/detail.vue b/pages/shop/detail.vue
new file mode 100644
index 0000000..af38fc0
--- /dev/null
+++ b/pages/shop/detail.vue
@@ -0,0 +1,1406 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{detailData.name||''}}
+
+
+ {{detailData.mallPoint||''}}
+
+
+ {{feeRule}}
+
+
+ 详情介绍
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 选择收货地址,让快递到家~
+
+
+
+
+
+
+
+
+
+ {{address.receiver}}
+ {{address.phone}}
+
+ {{address.province}} {{address.city}} {{address.area}}
+ {{address.address}}
+
+
+
+
+
+
+
+
+ 邮费
+ {{Number(previewData.deliveryFee)}}
+
+
+ 实际支付
+
+ {{previewData.points}} 积分
+ ¥{{Number(previewData.deliveryFee)}}
+
+
+
+
+
+
+ {{item.label}}
+
+
+
+
+
+
+
+
+ 我已满18岁,已阅读并同意
+ 《用户协议》、
+ 《隐私政策》、
+ 《儿童个人信息保护规则》、
+ 《支付服务协议》
+
+
+
+
+
+
+
+
+
+
+
+ 实际支付
+
+ {{virtualDetail.points}} 积分
+ ¥{{Number(virtualDetail.deliveryFee)}}
+
+
+
+ 充值账号
+
+
+
+
+
+
+
+ {{virtualDetail.tips}}
+
+
+
+
+
+
+ 我已满18岁,已阅读并同意
+ 《用户协议》、
+ 《隐私政策》、
+ 《儿童个人信息保护规则》、
+ 《支付服务协议》
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/index copy.vue b/pages/shop/index copy.vue
new file mode 100644
index 0000000..6fdb2b5
--- /dev/null
+++ b/pages/shop/index copy.vue
@@ -0,0 +1,479 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+ {{item.point.mall}}
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/index.vue b/pages/shop/index.vue
new file mode 100644
index 0000000..903347b
--- /dev/null
+++ b/pages/shop/index.vue
@@ -0,0 +1,489 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.abbreviation}}
+
+
+ {{item.point.mall}}
+
+
+
+
+
+ 没有更多了~
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/paySuccess copy.vue b/pages/shop/paySuccess copy.vue
new file mode 100644
index 0000000..ffc10aa
--- /dev/null
+++ b/pages/shop/paySuccess copy.vue
@@ -0,0 +1,275 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/paySuccess.vue b/pages/shop/paySuccess.vue
new file mode 100644
index 0000000..6274a65
--- /dev/null
+++ b/pages/shop/paySuccess.vue
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+ {{type === 'record' ? '提取成功' : '支付成功'}}
+
+
+ 再去逛逛
+ 查看订单
+
+
+
+ 用户信息
+ {{nickname}}
+
+
+ 商品名称
+ {{productName}}
+
+
+ 商品数量
+ {{quantity}}
+
+
+ 实付积分
+ {{point}}
+
+
+ 实付金额
+ ¥ {{price}}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/search-list.vue b/pages/shop/search-list.vue
new file mode 100644
index 0000000..33f39eb
--- /dev/null
+++ b/pages/shop/search-list.vue
@@ -0,0 +1,263 @@
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+ {{item.name}}
+
+
+ {{item.point.mall | numberFormat(item.point.mall)}}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/shop/search.vue b/pages/shop/search.vue
new file mode 100644
index 0000000..0e3b0e2
--- /dev/null
+++ b/pages/shop/search.vue
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+ 搜索
+
+
+
+
+ {{item}}
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/testPay/testPay.vue b/pages/testPay/testPay.vue
new file mode 100644
index 0000000..0aa694d
--- /dev/null
+++ b/pages/testPay/testPay.vue
@@ -0,0 +1,869 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..ee19cd1
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,81 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+/* 主题 */
+$uni-color376AF5: #376AF5; //基本颜色
+$uni-color32C28C: #32C28C;
+$uni-colorFF6363: #FF6363;
+$uni-color404C69: #404C69;
+
+/* 行为相关颜色 */
+$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:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:24rpx;
+$uni-font-size-base:28rpx;
+$uni-font-size-lg:32rpx;
+
+/* 图片尺寸 */
+$uni-img-size-sm:40rpx;
+$uni-img-size-base:52rpx;
+$uni-img-size-lg:80rpx;
+
+/* 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: 10px;
+$uni-spacing-row-base: 20rpx;
+$uni-spacing-row-lg: 30rpx;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 8rpx;
+$uni-spacing-col-base: 16rpx;
+$uni-spacing-col-lg: 24rpx;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:40rpx;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:36rpx;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:30rpx;
\ No newline at end of file
diff --git a/uniCloud-aliyun/cloudfunctions/public/index.js b/uniCloud-aliyun/cloudfunctions/public/index.js
new file mode 100644
index 0000000..268b1f8
--- /dev/null
+++ b/uniCloud-aliyun/cloudfunctions/public/index.js
@@ -0,0 +1,26 @@
+// 云函数入口文件
+const cloud = require('wx-server-sdk')
+cloud.init()
+// 云函数入口函数
+exports.main = async (event, context) => {
+ const wxContext = cloud.getWXContext()
+ switch (event.action) {
+ case 'getUrlScheme': {
+ return getUrlScheme(event.options)//与官方文档区别:小程序页面接受的参数
+ }
+ }
+ return 'action not found'
+}
+async function getUrlScheme(options) {
+ //return options;
+ return cloud.openapi.urlscheme.generate({
+ jumpWxa: {
+ path: '/pages/pay/pay', // 调转到小程序要打开的页面路径,根据实际业务设置
+ query: options,//与官方文档区别:小程序页面接受的参数
+ },
+ // 如果想不过期则置为 false,并可以存到数据库
+ isExpire: false,
+ // 一分钟有效期
+ expireTime: parseInt(Date.now() / 1000 + 60),
+ })
+}
\ No newline at end of file
diff --git a/uniCloud-aliyun/cloudfunctions/public/package.json b/uniCloud-aliyun/cloudfunctions/public/package.json
new file mode 100644
index 0000000..d0f62be
--- /dev/null
+++ b/uniCloud-aliyun/cloudfunctions/public/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "public",
+ "dependencies": {},
+ "extensions": {
+ "uni-cloud-jql": {}
+ }
+}
\ No newline at end of file
diff --git a/uniCloud-aliyun/database/JQL查询.jql b/uniCloud-aliyun/database/JQL查询.jql
new file mode 100644
index 0000000..35d21de
--- /dev/null
+++ b/uniCloud-aliyun/database/JQL查询.jql
@@ -0,0 +1,12 @@
+// 本文件用于,使用JQL语法操作项目关联的uniCloud空间的数据库,方便开发调试和远程数据库管理
+// 编写clientDB的js API(也支持常规js语法,比如var),可以对云数据库进行增删改查操作。不支持uniCloud-db组件写法
+// 可以全部运行,也可以选中部分代码运行。点击工具栏上的运行按钮或者按下【F5】键运行代码
+// 如果文档中存在多条JQL语句,只有最后一条语句生效
+// 如果混写了普通js,最后一条语句需是数据库操作语句
+// 此处代码运行不受DB Schema的权限控制,移植代码到实际业务中注意在schema中配好permission
+// 不支持clientDB的action
+// 数据库查询有最大返回条数限制,详见:https://uniapp.dcloud.net.cn/uniCloud/cf-database.html#limit
+// 详细JQL语法,请参考:https://uniapp.dcloud.net.cn/uniCloud/jql.html
+
+// 下面示例查询uni-id-users表的所有数据
+db.collection('uni-id-users').get();
diff --git a/uni_modules/uni-config-center/changelog.md b/uni_modules/uni-config-center/changelog.md
new file mode 100644
index 0000000..57dbcb5
--- /dev/null
+++ b/uni_modules/uni-config-center/changelog.md
@@ -0,0 +1,6 @@
+## 0.0.3(2022-11-11)
+- 修复 config 方法获取根节点为数组格式配置时错误的转化为了对象的Bug
+## 0.0.2(2021-04-16)
+- 修改插件package信息
+## 0.0.1(2021-03-15)
+- 初始化项目
diff --git a/uni_modules/uni-config-center/package.json b/uni_modules/uni-config-center/package.json
new file mode 100644
index 0000000..bace866
--- /dev/null
+++ b/uni_modules/uni-config-center/package.json
@@ -0,0 +1,81 @@
+{
+ "id": "uni-config-center",
+ "displayName": "uni-config-center",
+ "version": "0.0.3",
+ "description": "uniCloud 配置中心",
+ "keywords": [
+ "配置",
+ "配置中心"
+],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+"dcloudext": {
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "",
+ "type": "unicloud-template-function"
+ },
+ "directories": {
+ "example": "../../../scripts/dist"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "u",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "u",
+ "Android Browser": "u",
+ "微信浏览器(Android)": "u",
+ "QQ浏览器(Android)": "u"
+ },
+ "H5-pc": {
+ "Chrome": "u",
+ "IE": "u",
+ "Edge": "u",
+ "Firefox": "u",
+ "Safari": "u"
+ },
+ "小程序": {
+ "微信": "u",
+ "阿里": "u",
+ "百度": "u",
+ "字节跳动": "u",
+ "QQ": "u"
+ },
+ "快应用": {
+ "华为": "u",
+ "联盟": "u"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "u"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-config-center/readme.md b/uni_modules/uni-config-center/readme.md
new file mode 100644
index 0000000..03f7fc2
--- /dev/null
+++ b/uni_modules/uni-config-center/readme.md
@@ -0,0 +1,93 @@
+# 为什么使用uni-config-center
+
+实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
+
+```bash
+cloudfunctions
+└─────common 公共模块
+ ├─plugin-a // 插件A对应的目录
+ │ ├─index.js
+ │ ├─config.json // plugin-a对应的配置文件
+ │ └─other-file.cert // plugin-a依赖的其他文件
+ └─plugin-b // plugin-b对应的目录
+ ├─index.js
+ └─config.json // plugin-b对应的配置文件
+```
+
+假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
+
+uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
+
+```bash
+cloudfunctions
+└─────common 公共模块
+ ├─plugin-a // 插件A对应的目录
+ │ └─index.js
+ ├─plugin-b // plugin-b对应的目录
+ │ └─index.js
+ └─uni-config-center
+ ├─index.js // config-center入口文件
+ ├─plugin-a
+ │ ├─config.json // plugin-a对应的配置文件
+ │ └─other-file.cert // plugin-a依赖的其他文件
+ └─plugin-b
+ └─config.json // plugin-b对应的配置文件
+```
+
+使用uni-config-center后的优势
+
+- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
+- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
+
+# 用法
+
+在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
+
+```js
+const createConfig = require('uni-config-center')
+
+const uniIdConfig = createConfig({
+ pluginId: 'uni-id', // 插件id
+ defaultConfig: { // 默认配置
+ tokenExpiresIn: 7200,
+ tokenExpiresThreshold: 600,
+ },
+ customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
+ // defaudltConfig 默认配置
+ // userConfig 用户配置
+ return Object.assign(defaultConfig, userConfig)
+ }
+})
+
+
+// 以如下配置为例
+// {
+// "tokenExpiresIn": 7200,
+// "passwordErrorLimit": 6,
+// "bindTokenToDevice": false,
+// "passwordErrorRetryTime": 3600,
+// "app-plus": {
+// "tokenExpiresIn": 2592000
+// },
+// "service": {
+// "sms": {
+// "codeExpiresIn": 300
+// }
+// }
+// }
+
+// 获取配置
+uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
+uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200
+uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300
+uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600
+
+// 获取文件绝对路径
+uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
+
+// 引用文件(require)
+uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
+
+// 判断是否包含某文件
+uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
+```
\ No newline at end of file
diff --git a/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
new file mode 100644
index 0000000..00ba62f
--- /dev/null
+++ b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
@@ -0,0 +1 @@
+"use strict";var t=require("fs"),r=require("path");function e(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var n=e(t),o=e(r),i="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};var u=function(t){var r={exports:{}};return t(r,r.exports),r.exports}((function(t,r){var e="__lodash_hash_undefined__",n=9007199254740991,o="[object Arguments]",u="[object Function]",c="[object Object]",a=/^\[object .+?Constructor\]$/,f=/^(?:0|[1-9]\d*)$/,s={};s["[object Float32Array]"]=s["[object Float64Array]"]=s["[object Int8Array]"]=s["[object Int16Array]"]=s["[object Int32Array]"]=s["[object Uint8Array]"]=s["[object Uint8ClampedArray]"]=s["[object Uint16Array]"]=s["[object Uint32Array]"]=!0,s[o]=s["[object Array]"]=s["[object ArrayBuffer]"]=s["[object Boolean]"]=s["[object DataView]"]=s["[object Date]"]=s["[object Error]"]=s[u]=s["[object Map]"]=s["[object Number]"]=s[c]=s["[object RegExp]"]=s["[object Set]"]=s["[object String]"]=s["[object WeakMap]"]=!1;var l="object"==typeof i&&i&&i.Object===Object&&i,h="object"==typeof self&&self&&self.Object===Object&&self,p=l||h||Function("return this")(),_=r&&!r.nodeType&&r,v=_&&t&&!t.nodeType&&t,d=v&&v.exports===_,y=d&&l.process,g=function(){try{var t=v&&v.require&&v.require("util").types;return t||y&&y.binding&&y.binding("util")}catch(t){}}(),b=g&&g.isTypedArray;function j(t,r,e){switch(e.length){case 0:return t.call(r);case 1:return t.call(r,e[0]);case 2:return t.call(r,e[0],e[1]);case 3:return t.call(r,e[0],e[1],e[2])}return t.apply(r,e)}var w,O,m,A=Array.prototype,z=Function.prototype,M=Object.prototype,x=p["__core-js_shared__"],C=z.toString,F=M.hasOwnProperty,U=(w=/[^.]+$/.exec(x&&x.keys&&x.keys.IE_PROTO||""))?"Symbol(src)_1."+w:"",S=M.toString,I=C.call(Object),P=RegExp("^"+C.call(F).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),T=d?p.Buffer:void 0,q=p.Symbol,E=p.Uint8Array,$=T?T.allocUnsafe:void 0,D=(O=Object.getPrototypeOf,m=Object,function(t){return O(m(t))}),k=Object.create,B=M.propertyIsEnumerable,N=A.splice,L=q?q.toStringTag:void 0,R=function(){try{var t=vt(Object,"defineProperty");return t({},"",{}),t}catch(t){}}(),G=T?T.isBuffer:void 0,V=Math.max,W=Date.now,H=vt(p,"Map"),J=vt(Object,"create"),K=function(){function t(){}return function(r){if(!xt(r))return{};if(k)return k(r);t.prototype=r;var e=new t;return t.prototype=void 0,e}}();function Q(t){var r=-1,e=null==t?0:t.length;for(this.clear();++r-1},X.prototype.set=function(t,r){var e=this.__data__,n=nt(e,t);return n<0?(++this.size,e.push([t,r])):e[n][1]=r,this},Y.prototype.clear=function(){this.size=0,this.__data__={hash:new Q,map:new(H||X),string:new Q}},Y.prototype.delete=function(t){var r=_t(this,t).delete(t);return this.size-=r?1:0,r},Y.prototype.get=function(t){return _t(this,t).get(t)},Y.prototype.has=function(t){return _t(this,t).has(t)},Y.prototype.set=function(t,r){var e=_t(this,t),n=e.size;return e.set(t,r),this.size+=e.size==n?0:1,this},Z.prototype.clear=function(){this.__data__=new X,this.size=0},Z.prototype.delete=function(t){var r=this.__data__,e=r.delete(t);return this.size=r.size,e},Z.prototype.get=function(t){return this.__data__.get(t)},Z.prototype.has=function(t){return this.__data__.has(t)},Z.prototype.set=function(t,r){var e=this.__data__;if(e instanceof X){var n=e.__data__;if(!H||n.length<199)return n.push([t,r]),this.size=++e.size,this;e=this.__data__=new Y(n)}return e.set(t,r),this.size=e.size,this};var it,ut=function(t,r,e){for(var n=-1,o=Object(t),i=e(t),u=i.length;u--;){var c=i[it?u:++n];if(!1===r(o[c],c,o))break}return t};function ct(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":L&&L in Object(t)?function(t){var r=F.call(t,L),e=t[L];try{t[L]=void 0;var n=!0}catch(t){}var o=S.call(t);n&&(r?t[L]=e:delete t[L]);return o}(t):function(t){return S.call(t)}(t)}function at(t){return Ct(t)&&ct(t)==o}function ft(t){return!(!xt(t)||function(t){return!!U&&U in t}(t))&&(zt(t)?P:a).test(function(t){if(null!=t){try{return C.call(t)}catch(t){}try{return t+""}catch(t){}}return""}(t))}function st(t){if(!xt(t))return function(t){var r=[];if(null!=t)for(var e in Object(t))r.push(e);return r}(t);var r=yt(t),e=[];for(var n in t)("constructor"!=n||!r&&F.call(t,n))&&e.push(n);return e}function lt(t,r,e,n,o){t!==r&&ut(r,(function(i,u){if(o||(o=new Z),xt(i))!function(t,r,e,n,o,i,u){var a=gt(t,e),f=gt(r,e),s=u.get(f);if(s)return void rt(t,e,s);var l=i?i(a,f,e+"",t,r,u):void 0,h=void 0===l;if(h){var p=Ot(f),_=!p&&At(f),v=!p&&!_&&Ft(f);l=f,p||_||v?Ot(a)?l=a:Ct(j=a)&&mt(j)?l=function(t,r){var e=-1,n=t.length;r||(r=Array(n));for(;++e-1&&t%1==0&&t0){if(++r>=800)return arguments[0]}else r=0;return t.apply(void 0,arguments)}}(pt);function jt(t,r){return t===r||t!=t&&r!=r}var wt=at(function(){return arguments}())?at:function(t){return Ct(t)&&F.call(t,"callee")&&!B.call(t,"callee")},Ot=Array.isArray;function mt(t){return null!=t&&Mt(t.length)&&!zt(t)}var At=G||function(){return!1};function zt(t){if(!xt(t))return!1;var r=ct(t);return r==u||"[object GeneratorFunction]"==r||"[object AsyncFunction]"==r||"[object Proxy]"==r}function Mt(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=n}function xt(t){var r=typeof t;return null!=t&&("object"==r||"function"==r)}function Ct(t){return null!=t&&"object"==typeof t}var Ft=b?function(t){return function(r){return t(r)}}(b):function(t){return Ct(t)&&Mt(t.length)&&!!s[ct(t)]};function Ut(t){return mt(t)?tt(t,!0):st(t)}var St,It=(St=function(t,r,e){lt(t,r,e)},ht((function(t,r){var e=-1,n=r.length,o=n>1?r[n-1]:void 0,i=n>2?r[2]:void 0;for(o=St.length>3&&"function"==typeof o?(n--,o):void 0,i&&function(t,r,e){if(!xt(e))return!1;var n=typeof r;return!!("number"==n?mt(e)&&dt(r,e.length):"string"==n&&r in e)&&jt(e[r],t)}(r[0],r[1],i)&&(o=n<3?void 0:o,n=1),t=Object(t);++ec.call(t,r);class f{constructor({pluginId:t,defaultConfig:r={},customMerge:e,root:n}){this.pluginId=t,this.defaultConfig=r,this.pluginConfigPath=o.default.resolve(n||__dirname,t),this.customMerge=e,this._config=void 0}resolve(t){return o.default.resolve(this.pluginConfigPath,t)}hasFile(t){return n.default.existsSync(this.resolve(t))}requireFile(t){try{return require(this.resolve(t))}catch(t){if("MODULE_NOT_FOUND"===t.code)return;throw t}}_getUserConfig(){return this.requireFile("config.json")}config(t,r){if(!this._config){const t=this._getUserConfig();this._config=Array.isArray(t)?t:(this.customMerge||u)(this.defaultConfig,t)}let e=this._config;return t?function(t,r,e){if("number"==typeof r)return t[r];if("symbol"==typeof r)return a(t,r)?t[r]:e;const n="string"!=typeof(o=r)?o:o.split(".").reduce(((t,r)=>(r.split(/\[([^}]+)\]/g).forEach((r=>r&&t.push(r))),t)),[]);var o;let i=t;for(let t=0;tparseInt(e)):void 0}function o(e,t){const n=r(e),i=r(t);return n?i?function(e,t){const n=Math.max(e.length,t.length);for(let i=0;ir)return 1;if(n=e)throw new Error("Config error, tokenExpiresThreshold should be less than tokenExpiresIn");t>e/2&&console.warn(`Please check whether the tokenExpiresThreshold configuration is set too large, tokenExpiresThreshold: ${t}, tokenExpiresIn: ${e}`)}get customToken(){return this.uniId.interceptorMap.get("customToken")}isTokenInDb(e){return o(e,"1.0.10")>=0}async getUserRecord(){if(this.userRecord)return this.userRecord;const e=await C.doc(this.uid).get();if(this.userRecord=e.data[0],!this.userRecord)throw{errCode:n.ACCOUNT_NOT_EXISTS};switch(this.userRecord.status){case void 0:case 0:break;case 1:throw{errCode:n.ACCOUNT_BANNED};case 2:throw{errCode:n.ACCOUNT_AUDITING};case 3:throw{errCode:n.ACCOUNT_AUDIT_FAILED};case 4:throw{errCode:n.ACCOUNT_CLOSED}}if(this.oldTokenPayload){if(this.isTokenInDb(this.oldTokenPayload.uniIdVersion)){if(-1===(this.userRecord.token||[]).indexOf(this.oldToken))throw{errCode:n.CHECK_TOKEN_FAILED}}if(this.userRecord.valid_token_date&&this.userRecord.valid_token_date>1e3*this.oldTokenPayload.iat)throw{errCode:n.TOKEN_EXPIRED}}return this.userRecord}async updateUserRecord(e){await C.doc(this.uid).update(e)}async getUserPermission(){if(this.userPermission)return this.userPermission;const e=(await this.getUserRecord()).role||[];if(0===e.length)return this.userPermission={role:[],permission:[]},this.userPermission;if(e.includes("admin"))return this.userPermission={role:e,permission:[]},this.userPermission;const t=await T.where({role_id:_.in(e)}).get(),n=(i=t.data.reduce((e,t)=>(t.permission&&e.push(...t.permission),e),[]),Array.from(new Set(i)));var i;return this.userPermission={role:e,permission:n},this.userPermission}async _createToken({uid:e,role:t,permission:i}={}){if(!t||!i){const e=await this.getUserPermission();t=e.role,i=e.permission}let r={uid:e,role:t,permission:i};if(this.uniId.interceptorMap.has("customToken")){const n=this.uniId.interceptorMap.get("customToken");if("function"!=typeof n)throw new Error("Invalid custom token file");r=await n({uid:e,role:t,permission:i})}const o=Date.now(),{tokenSecret:s,tokenExpiresIn:c,maxTokenLength:a=10}=this.config,u=g({...r,uniIdVersion:"1.0.17"},s,{expiresIn:c}),d=await this.getUserRecord(),l=(d.token||[]).filter(e=>{try{const t=this._checkToken(e);if(d.valid_token_date&&d.valid_token_date>1e3*t.iat)return!1}catch(e){if(e.errCode===n.TOKEN_EXPIRED)return!1}return!0});return l.push(u),l.length>a&&l.splice(0,l.length-a),await this.updateUserRecord({last_login_ip:this.clientInfo.clientIP,last_login_date:o,token:l}),{token:u,tokenExpired:o+1e3*c}}async createToken({uid:e,role:t,permission:i}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"uid"}};this.uid=e;const{token:r,tokenExpired:o}=await this._createToken({uid:e,role:t,permission:i});return{errCode:0,token:r,tokenExpired:o}}async refreshToken({token:e}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const t=this._checkToken(e);this.uid=t.uid,this.oldTokenPayload=t;const{uid:i}=t,{role:r,permission:o}=await this.getUserPermission(),{token:s,tokenExpired:c}=await this._createToken({uid:i,role:r,permission:o});return{errCode:0,token:s,tokenExpired:c}}_checkToken(e){const{tokenSecret:t}=this.config;let i;try{i=k(e,t)}catch(e){if("TokenExpiredError"===e.name)throw{errCode:n.TOKEN_EXPIRED};throw{errCode:n.CHECK_TOKEN_FAILED}}return i}async checkToken(e,{autoRefresh:t=!0}={}){if(!e)throw{errCode:n.PARAM_REQUIRED,errMsgValue:{param:"token"}};this.oldToken=e;const i=this._checkToken(e);this.uid=i.uid,this.oldTokenPayload=i;const{tokenExpiresThreshold:r}=this.config,{uid:o,role:s,permission:c}=i,a={role:s,permission:c};if(!s&&!c){const{role:e,permission:t}=await this.getUserPermission();a.role=e,a.permission=t}if(!r||!t){const e={code:0,errCode:0,...i,...a};return delete e.uniIdVersion,e}const u=Date.now();let d={};1e3*i.exp-u<1e3*r&&(d=await this._createToken({uid:o}));const l={code:0,errCode:0,...i,...a,...d};return delete l.uniIdVersion,l}}var E=Object.freeze({__proto__:null,checkToken:async function(e,{autoRefresh:t=!0}={}){return new m({uniId:this}).checkToken(e,{autoRefresh:t})},createToken:async function({uid:e,role:t,permission:n}={}){return new m({uniId:this}).createToken({uid:e,role:t,permission:n})},refreshToken:async function({token:e}={}){return new m({uniId:this}).refreshToken({token:e})}});const w=require("uni-config-center")({pluginId:"uni-id"});class x{constructor({context:e,clientInfo:t,config:n}={}){this._clientInfo=e?function(e){return{appId:e.APPID,platform:e.PLATFORM,locale:e.LOCALE,clientIP:e.CLIENTIP,deviceId:e.DEVICEID}}(e):t,this._config=n,this.config=this._getOriginConfig(),this.interceptorMap=new Map,w.hasFile("custom-token.js")&&this.setInterceptor("customToken",require(w.resolve("custom-token.js")));this._i18n=uniCloud.initI18n({locale:this._clientInfo.locale,fallbackLocale:"zh-Hans",messages:JSON.parse(JSON.stringify(d))}),d[this._i18n.locale]||this._i18n.setLocale("zh-Hans")}setInterceptor(e,t){this.interceptorMap.set(e,t)}_t(...e){return this._i18n.t(...e)}_parseOriginConfig(e){return Array.isArray(e)?e:e[0]?Object.values(e):e}_getOriginConfig(){if(this._config)return this._config;if(w.hasFile("config.json")){let e;try{e=w.config()}catch(e){throw new Error("Invalid uni-id config file\n"+e.message)}return this._parseOriginConfig(e)}try{return this._parseOriginConfig(require("uni-id/config.json"))}catch(e){throw new Error("Invalid uni-id config file")}}_getAppConfig(){const e=this._getOriginConfig();return Array.isArray(e)?e.find(e=>e.dcloudAppid===this._clientInfo.appId)||e.find(e=>e.isDefaultConfig):e}_getPlatformConfig(){const e=this._getAppConfig();if(!e)throw new Error(`Config for current app (${this._clientInfo.appId}) was not found, please check your config file or client appId`);let t;switch(["app-plus","app-android","app-ios"].indexOf(this._clientInfo.platform)>-1&&(this._clientInfo.platform="app"),"h5"===this._clientInfo.platform&&(this._clientInfo.platform="web"),this._clientInfo.platform){case"web":t="h5";break;case"app":t="app-plus"}const n=[{tokenExpiresIn:7200,tokenExpiresThreshold:1200,passwordErrorLimit:6,passwordErrorRetryTime:3600},e];t&&e[t]&&n.push(e[t]),n.push(e[this._clientInfo.platform]);const i=Object.assign(...n);return["tokenSecret","tokenExpiresIn"].forEach(e=>{if(!i||!i[e])throw new Error(`Config parameter missing, ${e} is required`)}),i}_getConfig(){return this._getPlatformConfig()}}for(const e in E)x.prototype[e]=E[e];function y(e){const t=new x(e);return new Proxy(t,{get(e,t){if(t in e&&0!==t.indexOf("_")){if("function"==typeof e[t])return(n=e[t],function(){let e;try{e=n.apply(this,arguments)}catch(e){if(a(e))return c.call(this,e),e;throw e}return i(e)?e.then(e=>(a(e)&&c.call(this,e),e),e=>{if(a(e))return c.call(this,e),e;throw e}):(a(e)&&c.call(this,e),e)}).bind(e);if("context"!==t&&"config"!==t)return e[t]}var n}})}x.prototype.createInstance=y;const A={createInstance:y};module.exports=A;
diff --git a/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/package.json b/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/package.json
new file mode 100644
index 0000000..3cf41f3
--- /dev/null
+++ b/uni_modules/uni-id-common/uniCloud/cloudfunctions/common/uni-id-common/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "uni-id-common",
+ "version": "1.0.17",
+ "description": "uni-id token生成、校验、刷新",
+ "main": "index.js",
+ "homepage": "https://uniapp.dcloud.io/uniCloud/uni-id-common.html",
+ "repository": {
+ "type": "git",
+ "url": "git+https://gitee.com/dcloud/uni-id-common.git"
+ },
+ "author": "DCloud",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-link/changelog.md b/uni_modules/uni-link/changelog.md
new file mode 100644
index 0000000..2cfbf59
--- /dev/null
+++ b/uni_modules/uni-link/changelog.md
@@ -0,0 +1,17 @@
+## 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-link](https://uniapp.dcloud.io/component/uniui/uni-link)
+## 1.1.7(2021-11-08)
+## 0.0.7(2021-09-03)
+- 修复 在 nvue 下不显示的 bug
+## 0.0.6(2021-07-30)
+- 新增 支持自定义插槽
+## 0.0.5(2021-06-21)
+- 新增 download 属性,H5平台下载文件名
+## 0.0.4(2021-05-12)
+- 新增 组件示例地址
+## 0.0.3(2021-03-09)
+- 新增 href 属性支持 tel:|mailto:
+
+## 0.0.2(2021-02-05)
+- 调整为uni_modules目录规范
diff --git a/uni_modules/uni-link/components/uni-link/uni-link.vue b/uni_modules/uni-link/components/uni-link/uni-link.vue
new file mode 100644
index 0000000..27c5468
--- /dev/null
+++ b/uni_modules/uni-link/components/uni-link/uni-link.vue
@@ -0,0 +1,128 @@
+
+
+ {{text}}
+
+
+
+ {{text}}
+
+
+
+
+ {{text}}
+
+
+
+
+
+
+
diff --git a/uni_modules/uni-link/package.json b/uni_modules/uni-link/package.json
new file mode 100644
index 0000000..77b1986
--- /dev/null
+++ b/uni_modules/uni-link/package.json
@@ -0,0 +1,87 @@
+{
+ "id": "uni-link",
+ "displayName": "uni-link 超链接",
+ "version": "1.0.0",
+ "description": "uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打",
+ "keywords": [
+ "uni-ui",
+ "uniui",
+ "link",
+ "超链接",
+ ""
+],
+ "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-link/readme.md b/uni_modules/uni-link/readme.md
new file mode 100644
index 0000000..7f09e94
--- /dev/null
+++ b/uni_modules/uni-link/readme.md
@@ -0,0 +1,11 @@
+
+
+## Link 链接
+> **组件名:uni-link**
+> 代码块: `uLink`
+
+
+uni-link是一个外部网页超链接组件,在小程序内复制url,在app内打开外部浏览器,在h5端打开新网页。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-link)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-scss/changelog.md b/uni_modules/uni-scss/changelog.md
new file mode 100644
index 0000000..b863bb0
--- /dev/null
+++ b/uni_modules/uni-scss/changelog.md
@@ -0,0 +1,8 @@
+## 1.0.3(2022-01-21)
+- 优化 组件示例
+## 1.0.2(2021-11-22)
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
+## 1.0.1(2021-11-22)
+- 修复 vue3中scss语法兼容问题
+## 1.0.0(2021-11-18)
+- init
diff --git a/uni_modules/uni-scss/index.scss b/uni_modules/uni-scss/index.scss
new file mode 100644
index 0000000..1744a5f
--- /dev/null
+++ b/uni_modules/uni-scss/index.scss
@@ -0,0 +1 @@
+@import './styles/index.scss';
diff --git a/uni_modules/uni-scss/package.json b/uni_modules/uni-scss/package.json
new file mode 100644
index 0000000..7cc0ccb
--- /dev/null
+++ b/uni_modules/uni-scss/package.json
@@ -0,0 +1,82 @@
+{
+ "id": "uni-scss",
+ "displayName": "uni-scss 辅助样式",
+ "version": "1.0.3",
+ "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
+ "keywords": [
+ "uni-scss",
+ "uni-ui",
+ "辅助样式"
+],
+ "repository": "https://github.com/dcloudio/uni-ui",
+ "engines": {
+ "HBuilderX": "^3.1.0"
+ },
+ "dcloudext": {
+ "category": [
+ "JS SDK",
+ "通用 SDK"
+ ],
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "无",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y"
+ },
+ "client": {
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y"
+ },
+ "快应用": {
+ "华为": "n",
+ "联盟": "n"
+ },
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ }
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/readme.md b/uni_modules/uni-scss/readme.md
new file mode 100644
index 0000000..b7d1c25
--- /dev/null
+++ b/uni_modules/uni-scss/readme.md
@@ -0,0 +1,4 @@
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/index.scss b/uni_modules/uni-scss/styles/index.scss
new file mode 100644
index 0000000..ffac4fe
--- /dev/null
+++ b/uni_modules/uni-scss/styles/index.scss
@@ -0,0 +1,7 @@
+@import './setting/_variables.scss';
+@import './setting/_border.scss';
+@import './setting/_color.scss';
+@import './setting/_space.scss';
+@import './setting/_radius.scss';
+@import './setting/_text.scss';
+@import './setting/_styles.scss';
diff --git a/uni_modules/uni-scss/styles/setting/_border.scss b/uni_modules/uni-scss/styles/setting/_border.scss
new file mode 100644
index 0000000..12a11c3
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_border.scss
@@ -0,0 +1,3 @@
+.uni-border {
+ border: 1px $uni-border-1 solid;
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_color.scss b/uni_modules/uni-scss/styles/setting/_color.scss
new file mode 100644
index 0000000..1ededd9
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_color.scss
@@ -0,0 +1,66 @@
+
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
+// @mixin get-styles($k,$c) {
+// @if $k == size or $k == weight{
+// font-#{$k}:#{$c}
+// }@else{
+// #{$k}:#{$c}
+// }
+// }
+$uni-ui-color:(
+ // 主色
+ primary: $uni-primary,
+ primary-disable: $uni-primary-disable,
+ primary-light: $uni-primary-light,
+ // 辅助色
+ success: $uni-success,
+ success-disable: $uni-success-disable,
+ success-light: $uni-success-light,
+ warning: $uni-warning,
+ warning-disable: $uni-warning-disable,
+ warning-light: $uni-warning-light,
+ error: $uni-error,
+ error-disable: $uni-error-disable,
+ error-light: $uni-error-light,
+ info: $uni-info,
+ info-disable: $uni-info-disable,
+ info-light: $uni-info-light,
+ // 中性色
+ main-color: $uni-main-color,
+ base-color: $uni-base-color,
+ secondary-color: $uni-secondary-color,
+ extra-color: $uni-extra-color,
+ // 背景色
+ bg-color: $uni-bg-color,
+ // 边框颜色
+ border-1: $uni-border-1,
+ border-2: $uni-border-2,
+ border-3: $uni-border-3,
+ border-4: $uni-border-4,
+ // 黑色
+ black:$uni-black,
+ // 白色
+ white:$uni-white,
+ // 透明
+ transparent:$uni-transparent
+) !default;
+@each $key, $child in $uni-ui-color {
+ .uni-#{"" + $key} {
+ color: $child;
+ }
+ .uni-#{"" + $key}-bg {
+ background-color: $child;
+ }
+}
+.uni-shadow-sm {
+ box-shadow: $uni-shadow-sm;
+}
+.uni-shadow-base {
+ box-shadow: $uni-shadow-base;
+}
+.uni-shadow-lg {
+ box-shadow: $uni-shadow-lg;
+}
+.uni-mask {
+ background-color:$uni-mask;
+}
diff --git a/uni_modules/uni-scss/styles/setting/_radius.scss b/uni_modules/uni-scss/styles/setting/_radius.scss
new file mode 100644
index 0000000..9a0428b
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_radius.scss
@@ -0,0 +1,55 @@
+@mixin radius($r,$d:null ,$important: false){
+ $radius-value:map-get($uni-radius, $r) if($important, !important, null);
+ // Key exists within the $uni-radius variable
+ @if (map-has-key($uni-radius, $r) and $d){
+ @if $d == t {
+ border-top-left-radius:$radius-value;
+ border-top-right-radius:$radius-value;
+ }@else if $d == r {
+ border-top-right-radius:$radius-value;
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == b {
+ border-bottom-left-radius:$radius-value;
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == l {
+ border-top-left-radius:$radius-value;
+ border-bottom-left-radius:$radius-value;
+ }@else if $d == tl {
+ border-top-left-radius:$radius-value;
+ }@else if $d == tr {
+ border-top-right-radius:$radius-value;
+ }@else if $d == br {
+ border-bottom-right-radius:$radius-value;
+ }@else if $d == bl {
+ border-bottom-left-radius:$radius-value;
+ }
+ }@else{
+ border-radius:$radius-value;
+ }
+}
+
+@each $key, $child in $uni-radius {
+ @if($key){
+ .uni-radius-#{"" + $key} {
+ @include radius($key)
+ }
+ }@else{
+ .uni-radius {
+ @include radius($key)
+ }
+ }
+}
+
+@each $direction in t, r, b, l,tl, tr, br, bl {
+ @each $key, $child in $uni-radius {
+ @if($key){
+ .uni-radius-#{"" + $direction}-#{"" + $key} {
+ @include radius($key,$direction,false)
+ }
+ }@else{
+ .uni-radius-#{$direction} {
+ @include radius($key,$direction,false)
+ }
+ }
+ }
+}
diff --git a/uni_modules/uni-scss/styles/setting/_space.scss b/uni_modules/uni-scss/styles/setting/_space.scss
new file mode 100644
index 0000000..3c89528
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_space.scss
@@ -0,0 +1,56 @@
+
+@mixin fn($space,$direction,$size,$n) {
+ @if $n {
+ #{$space}-#{$direction}: #{$size*$uni-space-root}px
+ } @else {
+ #{$space}-#{$direction}: #{-$size*$uni-space-root}px
+ }
+}
+@mixin get-styles($direction,$i,$space,$n){
+ @if $direction == t {
+ @include fn($space, top,$i,$n);
+ }
+ @if $direction == r {
+ @include fn($space, right,$i,$n);
+ }
+ @if $direction == b {
+ @include fn($space, bottom,$i,$n);
+ }
+ @if $direction == l {
+ @include fn($space, left,$i,$n);
+ }
+ @if $direction == x {
+ @include fn($space, left,$i,$n);
+ @include fn($space, right,$i,$n);
+ }
+ @if $direction == y {
+ @include fn($space, top,$i,$n);
+ @include fn($space, bottom,$i,$n);
+ }
+ @if $direction == a {
+ @if $n {
+ #{$space}:#{$i*$uni-space-root}px;
+ } @else {
+ #{$space}:#{-$i*$uni-space-root}px;
+ }
+ }
+}
+
+@each $orientation in m,p {
+ $space: margin;
+ @if $orientation == m {
+ $space: margin;
+ } @else {
+ $space: padding;
+ }
+ @for $i from 0 through 16 {
+ @each $direction in t, r, b, l, x, y, a {
+ .uni-#{$orientation}#{$direction}-#{$i} {
+ @include get-styles($direction,$i,$space,true);
+ }
+ .uni-#{$orientation}#{$direction}-n#{$i} {
+ @include get-styles($direction,$i,$space,false);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/uni-scss/styles/setting/_styles.scss b/uni_modules/uni-scss/styles/setting/_styles.scss
new file mode 100644
index 0000000..689afec
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_styles.scss
@@ -0,0 +1,167 @@
+/* #ifndef APP-NVUE */
+
+$-color-white:#fff;
+$-color-black:#000;
+@mixin base-style($color) {
+ color: #fff;
+ background-color: $color;
+ border-color: mix($-color-black, $color, 8%);
+ &:not([hover-class]):active {
+ background: mix($-color-black, $color, 10%);
+ border-color: mix($-color-black, $color, 20%);
+ color: $-color-white;
+ outline: none;
+ }
+}
+@mixin is-color($color) {
+ @include base-style($color);
+ &[loading] {
+ @include base-style($color);
+ &::before {
+ margin-right:5px;
+ }
+ }
+ &[disabled] {
+ &,
+ &[loading],
+ &:not([hover-class]):active {
+ color: $-color-white;
+ border-color: mix(darken($color,10%), $-color-white);
+ background-color: mix($color, $-color-white);
+ }
+ }
+
+}
+@mixin base-plain-style($color) {
+ color:$color;
+ background-color: mix($-color-white, $color, 90%);
+ border-color: mix($-color-white, $color, 70%);
+ &:not([hover-class]):active {
+ background: mix($-color-white, $color, 80%);
+ color: $color;
+ outline: none;
+ border-color: mix($-color-white, $color, 50%);
+ }
+}
+@mixin is-plain($color){
+ &[plain] {
+ @include base-plain-style($color);
+ &[loading] {
+ @include base-plain-style($color);
+ &::before {
+ margin-right:5px;
+ }
+ }
+ &[disabled] {
+ &,
+ &:active {
+ color: mix($-color-white, $color, 40%);
+ background-color: mix($-color-white, $color, 90%);
+ border-color: mix($-color-white, $color, 80%);
+ }
+ }
+ }
+}
+
+
+.uni-btn {
+ margin: 5px;
+ color: #393939;
+ border:1px solid #ccc;
+ font-size: 16px;
+ font-weight: 200;
+ background-color: #F9F9F9;
+ // TODO 暂时处理边框隐藏一边的问题
+ overflow: visible;
+ &::after{
+ border: none;
+ }
+
+ &:not([type]),&[type=default] {
+ color: #999;
+ &[loading] {
+ background: none;
+ &::before {
+ margin-right:5px;
+ }
+ }
+
+
+
+ &[disabled]{
+ color: mix($-color-white, #999, 60%);
+ &,
+ &[loading],
+ &:active {
+ color: mix($-color-white, #999, 60%);
+ background-color: mix($-color-white,$-color-black , 98%);
+ border-color: mix($-color-white, #999, 85%);
+ }
+ }
+
+ &[plain] {
+ color: #999;
+ background: none;
+ border-color: $uni-border-1;
+ &:not([hover-class]):active {
+ background: none;
+ color: mix($-color-white, $-color-black, 80%);
+ border-color: mix($-color-white, $-color-black, 90%);
+ outline: none;
+ }
+ &[disabled]{
+ &,
+ &[loading],
+ &:active {
+ background: none;
+ color: mix($-color-white, #999, 60%);
+ border-color: mix($-color-white, #999, 85%);
+ }
+ }
+ }
+ }
+
+ &:not([hover-class]):active {
+ color: mix($-color-white, $-color-black, 50%);
+ }
+
+ &[size=mini] {
+ font-size: 16px;
+ font-weight: 200;
+ border-radius: 8px;
+ }
+
+
+
+ &.uni-btn-small {
+ font-size: 14px;
+ }
+ &.uni-btn-mini {
+ font-size: 12px;
+ }
+
+ &.uni-btn-radius {
+ border-radius: 999px;
+ }
+ &[type=primary] {
+ @include is-color($uni-primary);
+ @include is-plain($uni-primary)
+ }
+ &[type=success] {
+ @include is-color($uni-success);
+ @include is-plain($uni-success)
+ }
+ &[type=error] {
+ @include is-color($uni-error);
+ @include is-plain($uni-error)
+ }
+ &[type=warning] {
+ @include is-color($uni-warning);
+ @include is-plain($uni-warning)
+ }
+ &[type=info] {
+ @include is-color($uni-info);
+ @include is-plain($uni-info)
+ }
+}
+/* #endif */
diff --git a/uni_modules/uni-scss/styles/setting/_text.scss b/uni_modules/uni-scss/styles/setting/_text.scss
new file mode 100644
index 0000000..a34d08f
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_text.scss
@@ -0,0 +1,24 @@
+@mixin get-styles($k,$c) {
+ @if $k == size or $k == weight{
+ font-#{$k}:#{$c}
+ }@else{
+ #{$k}:#{$c}
+ }
+}
+
+@each $key, $child in $uni-headings {
+ /* #ifndef APP-NVUE */
+ .uni-#{$key} {
+ @each $k, $c in $child {
+ @include get-styles($k,$c)
+ }
+ }
+ /* #endif */
+ /* #ifdef APP-NVUE */
+ .container .uni-#{$key} {
+ @each $k, $c in $child {
+ @include get-styles($k,$c)
+ }
+ }
+ /* #endif */
+}
diff --git a/uni_modules/uni-scss/styles/setting/_variables.scss b/uni_modules/uni-scss/styles/setting/_variables.scss
new file mode 100644
index 0000000..557d3d7
--- /dev/null
+++ b/uni_modules/uni-scss/styles/setting/_variables.scss
@@ -0,0 +1,146 @@
+// @use "sass:math";
+@import '../tools/functions.scss';
+// 间距基础倍数
+$uni-space-root: 2 !default;
+// 边框半径默认值
+$uni-radius-root:5px !default;
+$uni-radius: () !default;
+// 边框半径断点
+$uni-radius: map-deep-merge(
+ (
+ 0: 0,
+ // TODO 当前版本暂时不支持 sm 属性
+ // 'sm': math.div($uni-radius-root, 2),
+ null: $uni-radius-root,
+ 'lg': $uni-radius-root * 2,
+ 'xl': $uni-radius-root * 6,
+ 'pill': 9999px,
+ 'circle': 50%
+ ),
+ $uni-radius
+);
+// 字体家族
+$body-font-family: 'Roboto', sans-serif !default;
+// 文本
+$heading-font-family: $body-font-family !default;
+$uni-headings: () !default;
+$letterSpacing: -0.01562em;
+$uni-headings: map-deep-merge(
+ (
+ 'h1': (
+ size: 32px,
+ weight: 300,
+ line-height: 50px,
+ // letter-spacing:-0.01562em
+ ),
+ 'h2': (
+ size: 28px,
+ weight: 300,
+ line-height: 40px,
+ // letter-spacing: -0.00833em
+ ),
+ 'h3': (
+ size: 24px,
+ weight: 400,
+ line-height: 32px,
+ // letter-spacing: normal
+ ),
+ 'h4': (
+ size: 20px,
+ weight: 400,
+ line-height: 30px,
+ // letter-spacing: 0.00735em
+ ),
+ 'h5': (
+ size: 16px,
+ weight: 400,
+ line-height: 24px,
+ // letter-spacing: normal
+ ),
+ 'h6': (
+ size: 14px,
+ weight: 500,
+ line-height: 18px,
+ // letter-spacing: 0.0125em
+ ),
+ 'subtitle': (
+ size: 12px,
+ weight: 400,
+ line-height: 20px,
+ // letter-spacing: 0.00937em
+ ),
+ 'body': (
+ font-size: 14px,
+ font-weight: 400,
+ line-height: 22px,
+ // letter-spacing: 0.03125em
+ ),
+ 'caption': (
+ 'size': 12px,
+ 'weight': 400,
+ 'line-height': 20px,
+ // 'letter-spacing': 0.03333em,
+ // 'text-transform': false
+ )
+ ),
+ $uni-headings
+);
+
+
+
+// 主色
+$uni-primary: #2979ff !default;
+$uni-primary-disable:lighten($uni-primary,20%) !default;
+$uni-primary-light: lighten($uni-primary,25%) !default;
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37 !default;
+$uni-success-disable:lighten($uni-success,20%) !default;
+$uni-success-light: lighten($uni-success,25%) !default;
+
+$uni-warning: #f3a73f !default;
+$uni-warning-disable:lighten($uni-warning,20%) !default;
+$uni-warning-light: lighten($uni-warning,25%) !default;
+
+$uni-error: #e43d33 !default;
+$uni-error-disable:lighten($uni-error,20%) !default;
+$uni-error-light: lighten($uni-error,25%) !default;
+
+$uni-info: #8f939c !default;
+$uni-info-disable:lighten($uni-info,20%) !default;
+$uni-info-light: lighten($uni-info,25%) !default;
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a !default; // 主要文字
+$uni-base-color: #6a6a6a !default; // 常规文字
+$uni-secondary-color: #909399 !default; // 次要文字
+$uni-extra-color: #c7c7c7 !default; // 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0 !default;
+$uni-border-2: #EDEDED !default;
+$uni-border-3: #DCDCDC !default;
+$uni-border-4: #B9B9B9 !default;
+
+// 常规色
+$uni-black: #000000 !default;
+$uni-white: #ffffff !default;
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
+
+// 背景色
+$uni-bg-color: #f7f7f7 !default;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px !default;
+$uni-spacing-base: 15px !default;
+$uni-spacing-lg: 30px !default;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
diff --git a/uni_modules/uni-scss/styles/tools/functions.scss b/uni_modules/uni-scss/styles/tools/functions.scss
new file mode 100644
index 0000000..ac6f63e
--- /dev/null
+++ b/uni_modules/uni-scss/styles/tools/functions.scss
@@ -0,0 +1,19 @@
+// 合并 map
+@function map-deep-merge($parent-map, $child-map){
+ $result: $parent-map;
+ @each $key, $child in $child-map {
+ $parent-has-key: map-has-key($result, $key);
+ $parent-value: map-get($result, $key);
+ $parent-type: type-of($parent-value);
+ $child-type: type-of($child);
+ $parent-is-map: $parent-type == map;
+ $child-is-map: $child-type == map;
+
+ @if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
+ $result: map-merge($result, ( $key: $child ));
+ }@else {
+ $result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
+ }
+ }
+ @return $result;
+};
diff --git a/uni_modules/uni-scss/theme.scss b/uni_modules/uni-scss/theme.scss
new file mode 100644
index 0000000..80ee62f
--- /dev/null
+++ b/uni_modules/uni-scss/theme.scss
@@ -0,0 +1,31 @@
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+// 主色
+$uni-primary: #2979ff;
+// 辅助色
+$uni-success: #4cd964;
+// 警告色
+$uni-warning: #f0ad4e;
+// 错误色
+$uni-error: #dd524d;
+// 描述色
+$uni-info: #909399;
+// 中性色
+$uni-main-color: #303133;
+$uni-base-color: #606266;
+$uni-secondary-color: #909399;
+$uni-extra-color: #C0C4CC;
+// 背景色
+$uni-bg-color: #f5f5f5;
+// 边框颜色
+$uni-border-1: #DCDFE6;
+$uni-border-2: #E4E7ED;
+$uni-border-3: #EBEEF5;
+$uni-border-4: #F2F6FC;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
diff --git a/uni_modules/uni-scss/variables.scss b/uni_modules/uni-scss/variables.scss
new file mode 100644
index 0000000..1c062d4
--- /dev/null
+++ b/uni_modules/uni-scss/variables.scss
@@ -0,0 +1,62 @@
+@import './styles/setting/_variables.scss';
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+
+// 主色
+$uni-primary: #2979ff;
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
+$uni-primary-light: mix(#fff,$uni-primary,80%);
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37;
+$uni-success-disable:mix(#fff,$uni-success,50%);
+$uni-success-light: mix(#fff,$uni-success,80%);
+
+$uni-warning: #f3a73f;
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
+$uni-warning-light: mix(#fff,$uni-warning,80%);
+
+$uni-error: #e43d33;
+$uni-error-disable:mix(#fff,$uni-error,50%);
+$uni-error-light: mix(#fff,$uni-error,80%);
+
+$uni-info: #8f939c;
+$uni-info-disable:mix(#fff,$uni-info,50%);
+$uni-info-light: mix(#fff,$uni-info,80%);
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a; // 主要文字
+$uni-base-color: #6a6a6a; // 常规文字
+$uni-secondary-color: #909399; // 次要文字
+$uni-extra-color: #c7c7c7; // 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0;
+$uni-border-2: #EDEDED;
+$uni-border-3: #DCDCDC;
+$uni-border-4: #B9B9B9;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
+
+// 背景色
+$uni-bg-color: #f7f7f7;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px;
+$uni-spacing-base: 15px;
+$uni-spacing-lg: 30px;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4);
diff --git a/uni_modules/yaor-webview/changelog.md b/uni_modules/yaor-webview/changelog.md
new file mode 100644
index 0000000..6c27063
--- /dev/null
+++ b/uni_modules/yaor-webview/changelog.md
@@ -0,0 +1,4 @@
+
+## 1.0.1(2024-04-09)
+精简的webview 跳外链及分享
+小程序(点击广告或弹出)跳转外链,及外链分享
diff --git a/uni_modules/yaor-webview/components/yaor-webview/yaor-webview.vue b/uni_modules/yaor-webview/components/yaor-webview/yaor-webview.vue
new file mode 100644
index 0000000..9db2b1e
--- /dev/null
+++ b/uni_modules/yaor-webview/components/yaor-webview/yaor-webview.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/uni_modules/yaor-webview/package.json b/uni_modules/yaor-webview/package.json
new file mode 100644
index 0000000..9a6b305
--- /dev/null
+++ b/uni_modules/yaor-webview/package.json
@@ -0,0 +1,87 @@
+{
+ "id": "yaor-webview",
+ "displayName": "小程序webview跳转(及分享)H5外链",
+ "version": "1.0.1",
+ "description": "点击广告或者推广活动大图,完成H5外链跳转及分享",
+ "keywords": [
+ "webview",
+ "外链",
+ "H5",
+ "分享",
+ "广告推广活动"
+ ],
+ "repository": "",
+ "engines": {
+ "HBuilderX": "^3.96"
+ },
+ "dcloudext": {
+ "type": "component-vue",
+ "sale": {
+ "regular": {
+ "price": "0.00"
+ },
+ "sourcecode": {
+ "price": "0.00"
+ }
+ },
+ "contact": {
+ "qq": ""
+ },
+ "declaration": {
+ "ads": "是",
+ "data": "无",
+ "permissions": "无"
+ },
+ "npmurl": ""
+ },
+ "uni_modules": {
+ "dependencies": [],
+ "encrypt": [],
+ "platforms": {
+ "cloud": {
+ "tcb": "y",
+ "aliyun": "y",
+ "alipay": "y"
+ },
+ "client": {
+ "Vue": {
+ "vue2": "y",
+ "vue3": "y"
+ },
+ "App": {
+ "app-vue": "y",
+ "app-nvue": "u",
+ "app-uvue": "u"
+ },
+ "H5-mobile": {
+ "Safari": "y",
+ "Android Browser": "y",
+ "微信浏览器(Android)": "y",
+ "QQ浏览器(Android)": "y"
+ },
+ "H5-pc": {
+ "Chrome": "y",
+ "IE": "y",
+ "Edge": "y",
+ "Firefox": "y",
+ "Safari": "y"
+ },
+ "小程序": {
+ "微信": "y",
+ "阿里": "y",
+ "百度": "y",
+ "字节跳动": "y",
+ "QQ": "y",
+ "钉钉": "y",
+ "快手": "y",
+ "飞书": "y",
+ "京东": "y"
+ },
+ "快应用": {
+ "华为": "y",
+ "联盟": "y"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/uni_modules/yaor-webview/readme.md b/uni_modules/yaor-webview/readme.md
new file mode 100644
index 0000000..c964e6e
--- /dev/null
+++ b/uni_modules/yaor-webview/readme.md
@@ -0,0 +1 @@
+# 点击广告或者推广活动大图,完成H5外链跳转及分享
diff --git a/utils/filter/filterUtils.js b/utils/filter/filterUtils.js
new file mode 100644
index 0000000..d9311d5
--- /dev/null
+++ b/utils/filter/filterUtils.js
@@ -0,0 +1,33 @@
+import Vue from 'vue'
+// import { formatDate } from '@/utils/dateAndTimeUtils.js';
+
+
+Vue.filter("numberFormat",(value) => {
+ if(!value) value = 0;
+ var param = {};
+ var k = 10000,
+ sizes = ['', '万', '亿', '万亿'],
+ i;
+ if(value < k){
+ param.value =value
+ param.unit=''
+ }else{
+ i = Math.floor(Math.log(value) / Math.log(k));
+ param.value = ((value / Math.pow(k, i))).toFixed(2);
+ param.unit = sizes[i];
+ }
+ let str = param.value + param.unit;
+ return str;
+})
+
+
+// Vue.filter("formatDate",(data)=>{
+// const nDate=new Date(data);
+// const year = nDate.getFullYear().toString().padStart(2,0);
+// const month = nDate.getMonth().toString().padStart(2,0);
+// const day = nDate.getDay().toString().padStart(2,0);
+// const h = nDate.getHours().toString().padStart(2,0);
+// const mm = nDate.getMinutes().toString().padStart(2,0);
+// const s = nDate.getSeconds().toString().padStart(2,0);
+// return year +'-'+ month +'-'+ day + " " + h + ":" + mm + ":"+ s
+// })
\ No newline at end of file
diff --git a/utils/httpUtils.js b/utils/httpUtils.js
new file mode 100644
index 0000000..589fa5e
--- /dev/null
+++ b/utils/httpUtils.js
@@ -0,0 +1,117 @@
+/*
+ http 请求工具方法
+ */
+const querystring = require('querystring');
+const Signture = require('crypto')
+import { baseUrl } from '@/config/baseConfig.js'
+import msgUtils from '@/utils/msgUtils.js'
+
+// import store from '@/store/index.js'
+
+/*
+ * 格式化http url
+ * @params {String} url 请求地址
+ * @params {String} nameSpace 请求api的空间
+ */
+export function httpUrlFormat (url, nameSpace = 'exchange') {
+ return baseUrl(nameSpace) + url
+}
+
+/*
+ 发起异步请求
+ */
+export function ajaxSync(config) {
+ return new Promise(function(resolve, reject) {
+ const success = config.success;
+ const error = config.error;
+ // 发起请求
+ uni.request(Object.assign(config, {
+ success(data) {
+ if(data.header.authorization){
+ uni.setStorageSync('box-token',data.header.authorization)
+ }
+ // 401 未登录 或token已过期
+ // 403 没有相关权限
+ // 10000 登录失败
+ if(data.data.code === 11000 || data.data.code === 401){
+ msgUtils.msg(data.data.message);
+ uni.navigateTo({
+ url:`/pages/login/login?type=back`
+ })
+ }else if(data.data.code === 10001){
+ msgUtils.msg(data.data.message);
+ uni.reLaunch({
+ url:`/pages/login/past-due`
+ })
+ }else if(data.data.code === 11010){
+ msgUtils.msg(data.data.message);
+ uni.reLaunch({
+ url:`/pages/login/shut-down`
+ })
+ }
+ if(data.data.code === 403){
+ msgUtils.msg(data.data.message);
+ }
+ if(data.data.code === 10000){
+ msgUtils.msg(data.data.message);
+ }
+
+ // if(data.data.code === 401){
+ // msgUtils.msg("请登录");
+ // uni.navigateTo({
+ // url:`/pages/login/login?type='back'`
+ // })
+ // }
+ success && success(data.data);
+ resolve(data.data);
+ },
+ fail(data) {
+ // console.log(data)
+ // config.showTips && msgUtils.msg(data.data.msg);
+ error && error(data.data);
+ reject(data.data);
+ }
+ }));
+ });
+}
+
+/*
+ 发起row格式数据请求
+ */
+export function ajaxForRawData(config) {
+ config.header = Object.assign(config.header || {}, {
+ // 'Content-Type': 'application/json; charset=UTF-8'
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ });
+
+ if (typeof config.data === "object") {
+ config.data = JSON.stringify(config.data);
+ }
+ return ajaxSync(config);
+};
+
+/*
+ 发起需要携带校验凭证的请求:oauthAccessToken
+ */
+function getAuthorization(url, type, param) {
+ try {
+ // console.log("uni.getStorageSync('box-token'):",uni.getStorageSync('box-token'))
+ // return `Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTc2ODQ3OTg2MDAxMjk1MzYwMSwibmlja25hbWUiOiLojonov7jmjqPnjJznl4UiLCJ1c2VybmFtZSI6IjE1MjgwMTE2MzgzIiwicGFzc3dvcmQiOiJxd2VyMTIzNDUiLCJzdGF0dXMiOjF9.ahpZGI8CdmPYYkywF62tNrpGniVrYKSWWh1XXfISUN8`
+ return `${uni.getStorageSync('box-token')}`
+ } catch {
+ // 跳转登录页
+ // uni.navigateTo({
+ // url: '/pages/login/login?type=back'
+ // });
+ }
+}
+
+export function ajaxCarryAuthorization(config) {
+ config.header = Object.assign(config.header || {}, {
+ Authorization: getAuthorization(config.url, config.method, config.data)
+ });
+ if (config.isRawData) {
+ return ajaxForRawData(config);
+ }
+ return ajaxSync(config);
+}
\ No newline at end of file
diff --git a/utils/index copy 1.html b/utils/index copy 1.html
new file mode 100755
index 0000000..8e468d8
--- /dev/null
+++ b/utils/index copy 1.html
@@ -0,0 +1,1113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
隐私政策
+
+
+
+
+
+
+
生效日期:2024年05月01日
+
+ 本《隐私政策》(简称“本政策”)仅适用于厦门正纯科技有限公司及其关联方(简称“我们”)作为运营者的妙趣盲盒产品或服务,包括妙趣盲盒网站和妙趣盲盒移动应用(简称“产品”),不适用于有单独的隐私权政策且未纳入本政策的第三方产品或服务。您使用我们的产品时,我们将于您同意本政策及《用户协议》后,按照本政策收集、使用、存储、传输、转让(如适用)及对外提供您的个人信息。同时,我们会通过本政策向您说明,我们如何为您提供访问、更新、管理和保护您的个人信息的服务。
+
+
+ 本政策与您使用我们的产品关系紧密,我们建议您仔细阅读并理解本政策全部内容,做出您认为适当的选择。如果您未明示同意本政策并开始使用,这将导致我们无法为您提供完整的产品和服务。我们努力用通俗易懂、简明扼要的文字表达,并对本政策中与您的权益存在重大关系的条款,采用粗体字进行标注以提示您注意。请您在使用我们的产品前仔细阅读本政策,确保对其内容特别是加粗内容的含义及相应法律后果已全部知晓并充分理解。您勾选或点击“同意”即视为您接受本政策;您同意本政策在您使用产品的整个过程中均有效。如果您有任何疑问、意见或建议,请通过以下任意一种方式与我们取得联系:
+
+
1.信息保护负责人联系电话:15280116383;
+
2.联系邮箱:648715275@qq.com;
+
3.在线客服:您可在妙趣盲盒移动应用内点击「我的」-「联系客服」联系;
+
4.注册地址及常用办公地址:福建省厦门市思明区前埔路506号502室之一。
+
本政策将帮助您了解以下内容:
+
一、我们如何收集和使用个人信息
+
二、我们如何使用Cookie、同类技术和SDK技术
+
三、我们如何共享、转让、公开披露个人信息
+
四、我们如何保护个人信息
+
五、您的权利
+
六、我们如何处理未成年人的个人信息
+
七、我们如何存储个人信息
+
八、我们如何更新本政策
+
九、联系我们
+
十、其他
+
+ 我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将按业界成熟的安全标准,采取相应的安全保护措施来保护您的个人信息。特别需要指出的是,即使经过您的授权,我们获得了敏感权限,也不会在相关功能或服务不需要时而收集您的信息。请在使用我们的产品前,仔细阅读并了解本政策。
+
+
一、我们如何收集和使用个人信息
+
(一)词语释义
+
+ (1)妙趣盲盒产品或服务是指:我们通过合法拥有并运营的、标注名称包含“妙趣盲盒”的客户端应用程序以及妙趣盲盒官方网站(以下简称“妙趣盲盒”或“本平台”)等,向您提供的产品与服务。关联方是指在现在、将来控制厦门正纯科技有限公司、受厦门正纯科技有限公司控制或与厦门正纯科技有限公司处于共同控制下的法人主体。控制指通过所有权、有投票权的股份、合同、实际运营关联或其他被依法认定的方式直接或间接地拥有影响被控制对象管理/经营的能力。
+
+
+ (2)个人信息是指:以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。本政策个人信息包括姓名、出生日期、身份证件号码、个人生物识别信息、住址、通信通讯联系方式、通信记录和内容、账号密码、财产信息、征信信息、行踪轨迹、住宿信息、健康生理信息、网络身份识别信息、
+ 常用设备信息、交易信息等。
+
+ (3)个人敏感信息是指:一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息。本政策中的个人敏感信息包括身份证件号码、邮箱地址、各类密码(口令、保护答案、数字证书)、个人生物识别信息、通信记录和内容、个人健康生理信息、个人财产信息、银行账号、征信信息、行踪轨迹、住宿信息、交易信息、14岁周岁以下(含)儿童的个人信息等。
+
+
+ (4)身份要素是指:产品用于识别您身份的信息要素,例如:您的登录名、密码、短信校验码、电话号码、手机号码、证件号码及个人生物识别信息(例如:指纹信息、脸部信息)。
+
+ (5)非个人信息:通过对个人信息的技术处理(包括但不限于匿名化、去标识化等),使得处理后的信息无法单独或结合其他信息识别到您的个人身份,
+ 且处理后的信息不能被复原,处理后的信息不属于法律意义上您的个人信息。但当个人信息与处理后的信息结合使用期间,这些结合信息将作为您的个人信息按照本政策处理与保护。
+
(二)收集和使用个人信息的场景、目的及所收集的信息
+
我们仅会出于本政策所述的以下目的,在以下场景收集和使用您的个人信息:
+
(1)帮助您成为我们的用户及进行账户管理
+
+ 为注册成为用户并使用我们的产品和服务,您需要提供您手机当前的手机号码进行注册登录。如果您拒绝提供上述信息,您将无法注册妙趣盲盒平台账户,仅可以使用浏览、搜索服务。为了确保我们是在为您本人提供服务,我们可能会根据您提供的上述信息校验您的身份。
+
+
+ 您也可以选择使用第三方账号登录,如您使用微信账号登录的,我们会获取您的微信头像、微信昵称。但您使用第三方账号登录后,仍需要提供手机号进行绑定。
+
+
(2)帮助您完成下单及订单管理
+
+ 当您在本平台订购具体商品时,我们会通过系统为您生成购买该商品的订单。在下单过程中,您需至少提供您的收货人姓名、收货地址、收货人联系电话,对于部分特殊类型的商品您还需要提供该商品所必需的其他信息。
+
+
+ 同时该订单中会载明您所购买的商品信息、具体订单号、订单创建时间、您应支付的金额、您的备注信息。我们收集这些信息是为了帮助您顺利完成交易、保障您的交易安全、便于您查询订单信息、提供客服与售后服务及其他我们明确告知的目的。
+
+
您可以通过妙趣盲盒为其他人订购商品,您需要提供该实际收货人的前述个人信息,并确保已取得该实际收货人的同意。
+
+ 为便于您了解、查询订单信息并对订单信息进行管理,我们会收集您在使用我们服务过程中产生的订单信息用于向您展示及便于您对订单进行管理。
+
+
您可额外填写包括其他联系电话、收货时间在内的更多附加信息以确保商品或服务的准确送达。
+
您可以通过「我的」-「我的订单」查看和管理您的订单信息。
+
(3)帮助您完成支付
+
+ 为完成订单支付,您可通过第三方支付(支付宝/微信)付款。我们会将您的妙趣盲盒平台账户用户名、订单支付相关信息、订单安全相关设备信息及其他反洗钱法律要求的必要信息通过在网站或客户端中嵌入的第三方支付软件工具开发包(软件工具开发包在本政策中简称“SDK”)与第三方支付公司共享。
+
+
为使我们及时获悉并确认您的支付进度及状态,为您提供售后与争议解决服务,您同意我们可自第三方支付公司处收集与支付进度相关信息。
+
+
(4)帮助向您完成商品的交付
+
+ 为保证您购买的商品能够顺利、安全、准确送达、提供,我们会向为妙趣盲盒平台提供物流相关服务的供应商(包括但不限于提供发货服务、快递服务的公司)披露订单相关的配送信息。您知晓并同意相应物流配送主体不可避免地获知及使用您的配送信息,用于完成交付目的。
+
+
+ 为向您提供售后与争议解决服务之目的,我们需要及时获悉并确认交付进度及状态,您同意我们可自物流相关服务主体处收集与交付进度相关的信息。如售后涉及退换货的,您同意向我们提供退货相关物流信息及同意我们可自物流相关服务主体处收集与退货进度相关的信息。
+
+
(5)为您提供客服支持及争议处理
+
当您与我们联系或提出售中、售后、争议纠纷处理申请时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息以核验您的用户身份。
+
+
+ 为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的沟通、通信/通话记录及相关内容(包括账户信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。如果您针对具体订单进行咨询、投诉或提供建议的,我们会使用您的账户信息和订单信息。
+
+
+ 为优化服务质量,我们可能会获取您的麦克风的权限,以便可以通过语音的方式沟通;我们还可能会获取您的相机及/或照片的权限,以便您向客服提供照片、视频资料。如果您不同意或拒绝授权提供,将无法使用此功能,但不影响您正常使用本平台的其他功能。
+
+
+ 为了提供服务及改进服务质量的合理需要,我们还可能使用的您的其他信息,包括您与客服联系时您提供的相关信息,您参与问卷调查时向我们发送的问卷答复信息。
+
(6)保障产品正常运行
+
+ 当您使用我们的产品时,为了保障产品基础功能及服务能够正常运行,您同意我们根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、苹果唯一设备标识符(IFDA)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)、OAID)、设备所在位置相关信息(如IP
+ 地址、WLAN接入点、SSID、BSSID、蓝牙、基站、地理位置信息)。需要您注意,这些信息是我们提供服务和保障产品正常运行所必须收集的基本信息。
+
+ 我们在应用第一次启动时,将会请求您授权读写外置存储信息权限,以读写外置存储信息。我们必须申请此权限,用于存储您在产品使用过程中产生的数据,拒绝此权限将导致您无法正常使用。
+
(7)保障产品、服务及用户使用安全
+ 为帮助我们更好地实现了解产品运行情况、判断账户安全、进行身份验证、检测及防范安全事件的目的,我们可能记录网络日志信息、应用信息、正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据及应用来源等信息:
+
+
①
+ 日志信息:我们会收集您对产品或服务的详细使用情况,作为有关网络日志保存(例如,搜索查询内容、IP地址、浏览器的类型、电信运营商);
+
+
②
+ 其他信息:我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、总体安装使用情况、性能数据、应用来源,并可能使用或整合您的用户信息、交易信息、设备信息、有关网络日志信息,进而综合判断您账户及交易风险、进行身份验证、检测及防范安全事件,并依法采取必要的记录、分析措施。
+
+
(8)消息通知及市场推广
+
+ 我们会通过PUSH通知为您提供推荐商品、运营活动等资讯,及向您发出平台公告、平台通知等。为了实现上述目的所必需,确保应用处于关闭或后台运行状态下正常接收到PUSH
+ 通知,我们可能会在合理频率范围内自启动。
+
+ 我们可能会通过短信等形式为向您提供商品、运营活动等资讯,如果您不希望接收上述资讯,您可随时根据短信提示或我们提供的其他方式进行退订。
+
+
需要您注意的是,单独的设备信息、日志信息等是无法识别特定自然人身份的信息,属于非本政策所指“个人信息”。
+
(三)我们直接调用的权限
+
我们承诺决不超范围、超频次搜集您的个人信息,决不搜集与使用本产品服务非必需或无合理应用场景的信息。
+
+ 您在使用本平台时,为提供给您服务之目的,本平台可能在您使用该应用某些场景下向您申请终端设备的如下权限,当然您可以拒绝开启以下权限,或在手机的设置中关闭以下权限,关闭以下权限不会影响您对其他功能的使用。
+
+
我们直接调用的设备权限包括:
+
1、 通知
+
对应业务功能:全部功能
+
调用权限目的:用于接收各类消息
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法接收推送通知
+
2、 无线数据
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
3、 WLAN
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
4、外置存储
+
对应业务功能:全部功能
+
调用权限目的:用于写入存储用户信息,存储日志等信息,缓存用户图片数据
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法流畅使用
+
5、相机
+
对应业务功能:客服功能、更换头像功能
+
调用权限目的:读写设备上的照片及文件,用于在客服功能及更换头像功能中上传照片或视频
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法在客服功能及更换头像功能中上传照片或视频
+
6、麦克风
+
对应业务功能:客服功能
+
调用权限目的:用于发送语音消息、实时语音通话
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法使用麦克风与客服进行语音沟通
+
7、 访问电话状态(仅适用于安卓)
+
对应业务功能:全部功能及安全保障
+
+ 调用权限目的:获取设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)),用于保障用户的账户及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中。
+
8、 安装软件包(仅适用于安卓)
+
对应业务功能:安装更新功能
+
调用权限目的:用于本产品软件安装或更新
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法正常安装软件
+
9、IFDA获取(仅适用于iOS)
+
对应业务功能:全部功能及安全保障
+
调用权限目的:获取苹果手机唯一设备标识符IFDA,用于保障用户账号及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中、用户无法使用“本机号码一键登录”功能
+
+ 当我们要将个人信息用于本政策未载明的其它用途时,会事先征求您的同意。当我们要将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。
+
+
(四)无需征得同意收集和使用的个人信息
+
根据法律法规及相关国家标准,我们在下列任意一种或多种情形下收集和使用您的个人信息无需征得您的授权同意。
+
(1)与国家安全、国防安全直接相关的;
+
(2)与公共安全、公共卫生、重大公共利益直接相关的;
+
(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+
(4)为应对突发公共卫生事件,或出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您同意的;
+
(5)所收集的您的个人信息是您自行向社会公众公开的;
+
(6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
+
(7)根据您的要求签订或履行合同所必需的;
+
(8)用于维护产品的安全稳定运行所必需的,例如发现、处置产品故障;
+
(9)为合法的新闻报道所必需的;
+
+ (10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
+
+
(11)法律法规规定及相关国家标准的其他情形。
+
二、我们如何使用Cookie、同类技术和SDK技术
+
(一)Cookie
+
+ 为使您获得更轻松的访问体验,您使用我们的产品时,我们可能会通过小型数据文件识别您的身份,这么做可帮您省去重复输入注册信息的步骤,或者帮助判断您的账号安全状态。这些数据文件可能是Cookie。Cookie通常包含标识符、站点名称以及一些号码和字符。您可根据自己的偏好管理或删除Cookie。有关详情,请参见AboutCookies.org。但请注意,如果停用Cookie,您可能无法享受最佳的服务体验,某些服务也可能无法正常使用。
+
+
(二)与Cookie同类技术
+
+ 除Cookie外,我们还会使用网站信标和像素标签等其他同类技术(例如Beacon、Proxy等),但我们不会将Cookie和同类技术用于本政策所述目的之外的任何用途。
+
(三)SDK技术
+
+ 为保证产品相关功能的实现与应用安全稳定的运行,我们可能会接入由第三方服务提供商提供的软件工具开发包(SDK)实现相关目的。我们会对合作获取信息的软件工具开发包(SDK)进行严格的安全监测,以保证数据安全。前述服务商收集和处理信息等行为遵守其自身的隐私条款,而不适用于本政策。为了最大程度保障您的信息安全,我们建议您在使用任何第三方SDK类服务前先行查看其用户协议及隐私条款。为保障您的合法权益,如您发现这等SDK或其他类似的应用程序存在风险时,建议您立即终止相关操作并及时与我们取得联系。
+
+
我们接入的第三方SDK及信息收集目的、场景等包括:
+
1、微信SDK(com.tencent.mm.opensdk)
+
涉及个人信息:分享的图片或内容、微信包名信息
+
使用目的:支持微信登录和分享
+
使用场景:在用户使用微信登录或者分享时使用
+
合作方主体:深圳市腾讯计算机系统有限公司
+
收集方式:SDK自行采集
+
官网链接:https://open.weixin.qq.com/
+
+ 合作方隐私政策:https://support.weixin.qq.com/cgi-bin/mmsupportacctnodeweb-bin/pages/RYiYJkLOrQwu0nb8
+
+
2、Alipay(支付宝)SDK(com.alipay.sdk)
+
涉及个人信息:设备标识符(Android如IMEI、MEID、IMSI、Android
+ ID、硬件序列号/Serial、ICCID、OAID,iOS如IDFV、IDFA)、设备MAC地址、IP地址、WLAN接入点(如SSID、BSSID)、Wi-Fi列表、网络信息、设备信息、软件列表、读取存储信息、支付宝包名信息、传感器列表
+
+
权限调用:存储权限、电话权限
+
使用目的:帮助用户在应用内使用支付宝
+
使用场景:在用户使用支付宝支付时使用
+
合作方主体:支付宝(中国)网络技术有限公司
+
收集方式:SDK自行采集
+
官网链接:https://render.alipay.com/p/f/fd-iwwyijeh/index.html
+
合作方隐私政策:https://docs.open.alipay.com/54
+
3、数字联盟SDK(cn.shuzilm.core)
+
+ 涉及个人信息:设备制造商、设备型号、设备系统版本、应用版本、传感器(光传感器、磁场传感器、重力传感器、压力传感器、方向传感器、旋转矢量传感器、陀螺仪传感器、加速度传感器)、应用信息、通信状态、信号强度、蓝牙信息、设备网络状态信息【包括网络的接入形式、IP地址、WiFi信息(BSSID、SSID)、运营商类型及网络基站信息】、设备物理环境信息、IDFA(儿童类应用不收集)、IDFV、OAID、粗略位置信息、指定包名信息、Android
+ ID、IMEI、IMSI、MEID、设备序列号设备MAC地址、WiFi列表
+
权限调用:粗略位置权限
+
使用目的:安全风控,识别反馈设备的真实性,其中传感器主要用于辅助识别模拟器,虚拟机等虚拟环境及辅助判断作弊场景
+
使用场景:检测设备欺诈与作弊行为时使用
+
合作方主体:北京数字联盟网络科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.shuzilm.cn/
+
合作方隐私政策:https://www.shuzilm.cn/privacy
+
4、LinkedMe SDK(com.microquation.linkedme)
+
涉及个人信息:设备MAC地址、OAID、唯一设备识别码、IP、SD卡数据、指定包名信息、WiFi状态
+
权限调用:粗略位置权限
+
使用目的:推广统计和效果分析,保存分享的图片,识别用户来源
+
使用场景:使用数据分析服务时使用
+
合作方主体:北京微方程科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.linkedme.cc/index.html
+
合作方隐私政策:https://www.linkedme.cc/privacy-policy.html
+
22、Okio (okio)
+ 涉及个人信息:写入存储信息、IP地址
+ 权限获取:存储权限
+ 使用目的:用于配合OkHttp实现,对服务器API发送请求,下载网络文件,访问网页。
+ 使用场景: 网络请求,访问网页。
+ 合作方主体:square
+ 收集方式:SDK自行采集
+ 官网链接:https://square.github.io/okio/
+ 23、Fresco(com.facebook)
+ 涉及个人信息:读写存储信息
+ 权限获取:存储权限
+ 使用目的:用于图片加载显示
+ 使用场景: APP内的所有图片显示。
+ 合作方主体: facebook
+ 收集方式:SDK自行采集
+ 官网链接:https://frescolib.org/
+ 三、我们如何共享、转让、公开披露个人信息
+ (一)如何共享个人信息
+ 我们不会与产品服务相关提供者以外的公司、组织和个人共享您的个人信息。我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息,具体情况如下:
+ 1.在获取明确同意的情况下共享:在获得您的明确同意后,我们会与其他方共享您的个人信息。
+ 2.在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。
+ 3.为实现产品功能或服务的共享:您的个人信息可能会与我们的关联公司共享。我们只会共享必要的个人信息,且受本政策中所声明目的的约束。关联公司如要改变个人信息的处理目的,或使用信息的目的超越原授权同意范围,将再次征求您的授权同意。
+ 4.为实现产品安全与分析统计的共享:
+ (1)保障使用安全:为保障您和其他用户的财产安全,使您和我们的正当合法权益免受不法侵害,我们和关联方或服务提供商可能会共享必要的设备、应用、进程、性能、环境及日志等信息。
+ (2)分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与关联方或第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。
+ (3)学术研究与科研:为提升相关领域的科研能力,促进科技发展水平,我们在确保数据安全与目的正当的前提下,可能会与科研院所、高校等机构共享去标识化或匿名化的数据。
+ (二)如何转让个人信息
+ 我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
+ 1.在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;
+ 2.在涉及合并、收购、资产转让或破产清算时,如涉及到个人信息转让,我们会在要求新的持有您个人信息的公司、组织继续受本政策的约束,将按照法律法规及不低于本政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求该公司、组织重新向您征求授权同意。
+ (三)如何披露个人信息
+ 我们仅会在以下情况下,公开披露您的个人信息并会采用符合行业内标准的安全保护措施:
+ (1)获得您明确同意后;
+ (2)基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息;
+ (3)对违规、欺诈行为进行处罚公告。
+ (四)免征得同意共享、转让、公开披露的个人信息
+ 根据法律法规及国家标准,我们在下列情形中,共享、转让、公开披露您的个人信息无需征得您的授权同意:
+ (1)与国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)为应对突发公共卫生事件,或出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您的同意的;
+ (5)您自行向社会公众公开的个人信息;
+ (6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
+ 四、我们如何保护个人信息
+ 本政策提供的如下个人信息保护措施仅适用于我们的产品。一旦您离开我们的产品,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在我们的产品之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于我们的产品的链接或引导。
+ (一)为保障您的信息安全,我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露、毁损、误用、非授权访问、非授权披露和更改的风险。
+ 我们会采取一切合理可行的措施,保护您的个人信息。例如:
+ (1)在您的设备与“产品服务”之间交换数据(如银行信息)时受SSL加密保护;
+ (2)我们会使用加密技术确保数据的保密性;
+ (3)我们会使用受信赖的保护机制防止数据遭到恶意攻击;
+ (4)我们会部署访问控制机制,确保只有授权人员才可访问个人信息;
+ (5)我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识;
+ (6)我们认为其他的合理可行的保护措施。
+ (二)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
+ (三)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
+ (四)我们会采取一切合理可行的措施,确保未收集无关的个人信息。
+ (五)我们将不定期更新并公开安全风险、个人信息安全影响评估等报告的有关内容。
+ (六)尽管已经采取了上述合理有效措施,并已经遵守了相关法律法规要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
+ 您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人等。
+ (七)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、电话、推送通知等方式告知您,
+ 难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。
+ 五、您的权利
+ (一)访问您的个人信息
+ 您有权访问您的个人信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:
+ 如果您希望访问您的账号中的个人资料信息,您可以通过本平台中点击右下方的「我的」查看;如果您希望访问您的账号中的收件地址信息,您可以通过本平台中点击右下方的「我的」-「地址管理」查看及编辑。
+ 如果您无法通过上述方式访问上述个人信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (二)更正您的个人信息
+ 一般情况下,您可以随时更正您的个人信息。
+ 但出于安全性、身份识别、交易安全的考虑,您不能随时自主修改手机号码信息、订单的收货信息及实名认证信息;如您确有必要修改该类信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (三)删除您的个人信息
+ 在以下情形中,您可以向我们提出删除个人信息的请求:
+ 1.如果我们处理个人信息的行为违反法律法规;
+ 2.如果我们收集、使用您的个人信息,却未征得您的同意;
+ 3.如果我们处理个人信息的行为违反了与您的约定;
+ 4.如果您不再使用本平台提供的服务并提出注销账号申请;
+ 5.如果我们不再为您提供本平台或服务。
+ 您可根据本政策载明的联系方式联系我们反馈您的删除个人信息的需求,我们将在15个工作日内响应。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。
+ 当您从我们的服务中删除信息后,我们可能不会立即在备份系统中删除相应的信息,但会在备份更新时删除这些信息。
+ (四)管理您的授权范围
+ 每个业务功能需要一些基本的个人信息才能得以完成。
+ 对于为优化用户体验额外收集的个人信息的收集和使用,您可以随时给予或收回您的授权同意。您可以通过以下方式自行操作:您可以通过删除个人信息、关闭设备功能、更改应用权限等方式,改变您在功能和服务中的授权范围。当您撤回同意后,我们无法继续为您提供撤回同意所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意的决定,不会影响我们此前基于您的同意而开展的个人信息处理。如您在撤回同意时遇到困难,您可以通过根据本政策载明的联系方式联系我们,我们将在15个工作日内回复您的撤回请求。
+ (五)账号注销
+ 本平台未提供在线的注销功能,请您直接根据本政策载明的联系方式与我们联系申请账号注销。
+ 在注销账号前,我们将验证您的个人身份、安全状态、设备信息、仓库状态、订单状态等。
+ 请确保您所申请注销的账号应当是您本人依照《用户协议》的约定创建并由我们提供给您本人的账号。
+ 建议您在注销前自行备份账号相关的所有信息,并请确认与账号相关的所有服务均已进行妥善处理。如您的账号目前仍有未完成订单(包括待发货订单、待收货订单、售后处理中的订单)或仓库未清空(即仓库中含有已购买但未开启的盲盒、或通过开启盲盒获取但未提货或未兑换为积分的物品)的,请您在订单完成后或清空仓库后再提起账号注销申请,否则将无法提交注销申请;如账号内有未使用的积分及其他虚拟权益等,账号注销申请的提交视为您已放弃其全部权益,注销后不得向本平台要求恢复。
+ 如果您的账号涉及争议纠纷,包括但不限于:投诉、举报、诉讼、仲裁、国家有权机关调查等,您理解并同意,我们有权自行决定是否终止账号的注销,而无需另行得到您的同意。
+ 考虑到存在用户因误操作账号注销的情形,我们将自用户提交注销申请之日起提供为期15个工作日的账号申诉期,申诉期间用户登录产品账号即可取消注销申请。如用户未在申诉期间取消注销申请,则申诉期届满后,账号将自动注销,注销过程不可逆的、不可恢复。
+ 您知悉并理解,账号注销后您将无法再使用该账号登录及使用本平台提供的所有服务。但注销账号并不代表账号注销前的账户行为和相关责任得到豁免或减轻。
+ 当注销账号后,我们将对您持有您的个人信息(包括但不限于账号信息、交易记录等)进行删除或匿名化处理,但法律法规另有规定的除外。
+ (六)我们如何响应您的请求
+ 为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
+ 我们将在十五个工作日内做出答复。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视具体情况收取一定成本费用。
+ 对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。
+ 在以下情形中,按照法律法规要求,我们将无法响应您的请求:
+ (1)国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)有充分证据表明您存在主观恶意或滥用权利的;
+ (5)响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;
+ (6)涉及商业秘密的。
+ (七)投诉举报
+ 您可以按照我们公示的制度或联系我们进行投诉或举报。如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索,您可以通过本政策载明的联系方式进行举报,我们核查后会在十五个工作日内反馈您的投诉与举报。
+ (八)访问隐私政策
+ 您可以在本平台中点击右下方的「我的」-「设置」-「隐私政策」后,查看本政策的全部内容。
+ (九)停止运营向您告知权利
+ 如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
+ 六、我们如何处理未成年人的个人信息
+ (一)我们期望父母或监护人指导未成年人使用我们的服务
+ 若您是未满18周岁的未成年人,在使用我们的产品前,应在您的父母或其他监护人监护、指导下共同阅读并同意本政策。如果没有父母或监护人的同意,儿童(不满14周岁)不得私自使用。
+ (二)我们重视保护未成年人个人信息
+ 我们根据国家相关法律法规的规定保护未成年人的个人信息,对于经父母同意而收集未成年人个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享或公开披露此信息。
+ (三)自查与接收反馈
+ 如果我们发现自己在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关数据或对其进行匿名化处理,但法律法规另有规定的除外。同时我们建立了严格的未成年人信息收集使用规则,以保护儿童的个人信息安全,您可以通过阅读《儿童个人信息保护规则》了解更多信息。
+ 若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本政策公示的联系方式与我们联系。
+ 七、我们如何存储个人信息
+ (一)我们在中华人民共和国境内收集和产生的个人信息,将存储在中华人民共和国境内。我们不会将上述信息传输至境外(您通过互联网进行跨境购买商品等个人主动行为除外),如果部分产品涉及跨境业务,我们需要向境外机构传输境内收集的相关个人信息的,我们将会遵循国家相关规定,
+ 征求您的同意,并按照法律法规和相关监管部门的规定执行,并通过签订协议、现场核查等有效措施,要求境外机构为所获得的您的个人信息保密。
+ (二)我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。我们仅在为提供产品服务之目的所必需的期间内保留您的个人信息。超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外,例如《中华人民共和国电子商务法》要求商品和服务信息、交易信息保存时间自交易完成之日起不少于三年,《中华人民共和国网络安全法》要求网络日志的留存时间不少于六个月。
+ 八、我们如何更新本政策
+ 为了给您提供更好的服务,我们会适时对本政策进行修订,该等修订构成本政策的一部分并具有等同于本政策的效力。
+ 如该等修订会导致您在本政策项下权利的实质减损,我们将在变更生效前,通过在页面显著位置公示等方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的政策约束。
+ 九、联系我们
+ (一)我们提供本政策载明的联系渠道供用户向我们反馈处理与个人信息问题相关的投诉、建议、疑问等,我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。
+ (二)如果您对我们的回复不满意,或因签署、履行本政策与我们产生任何争议的,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+ 十、其他
+ (一)本政策中的标题仅为方便及阅读而设,并不影响本政策中任何规定的含义或解释。
+ (二)本政策中所述的我们的产品及相关服务有可能会根据您所使用的终端设备、手机型号、系统版本、软件应用程序版本等因素而有所不同。最终的产品和服务以您所使用的产品及相关服务为准。
+ (三)本政策的全部条款属于《用户协议》重要组成部分之一。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/index copy 2.html b/utils/index copy 2.html
new file mode 100755
index 0000000..8072999
--- /dev/null
+++ b/utils/index copy 2.html
@@ -0,0 +1,1128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
隐私政策
+
+
+
+
+
+
+
生效日期:2024年05月01日
+
+ 本《隐私政策》(简称“本政策”)仅适用于厦门正纯科技有限公司及其关联方(简称“我们”)作为运营者的妙趣盲盒产品或服务,包括妙趣盲盒网站和妙趣盲盒移动应用(简称“产品”),不适用于有单独的隐私权政策且未纳入本政策的第三方产品或服务。您使用我们的产品时,我们将于您同意本政策及《用户协议》后,按照本政策收集、使用、存储、传输、转让(如适用)及对外提供您的个人信息。同时,我们会通过本政策向您说明,我们如何为您提供访问、更新、管理和保护您的个人信息的服务。
+
+
+ 本政策与您使用我们的产品关系紧密,我们建议您仔细阅读并理解本政策全部内容,做出您认为适当的选择。如果您未明示同意本政策并开始使用,这将导致我们无法为您提供完整的产品和服务。我们努力用通俗易懂、简明扼要的文字表达,并对本政策中与您的权益存在重大关系的条款,采用粗体字进行标注以提示您注意。请您在使用我们的产品前仔细阅读本政策,确保对其内容特别是加粗内容的含义及相应法律后果已全部知晓并充分理解。您勾选或点击“同意”即视为您接受本政策;您同意本政策在您使用产品的整个过程中均有效。如果您有任何疑问、意见或建议,请通过以下任意一种方式与我们取得联系:
+
+
1.信息保护负责人联系电话:15280116383;
+
2.联系邮箱:648715275@qq.com;
+
3.在线客服:您可在妙趣盲盒移动应用内点击「我的」-「联系客服」联系;
+
4.注册地址及常用办公地址:福建省厦门市思明区前埔路506号502室之一。
+
本政策将帮助您了解以下内容:
+
一、我们如何收集和使用个人信息
+
二、我们如何使用Cookie、同类技术和SDK技术
+
三、我们如何共享、转让、公开披露个人信息
+
四、我们如何保护个人信息
+
五、您的权利
+
六、我们如何处理未成年人的个人信息
+
七、我们如何存储个人信息
+
八、我们如何更新本政策
+
九、联系我们
+
十、其他
+
+ 我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将按业界成熟的安全标准,采取相应的安全保护措施来保护您的个人信息。特别需要指出的是,即使经过您的授权,我们获得了敏感权限,也不会在相关功能或服务不需要时而收集您的信息。请在使用我们的产品前,仔细阅读并了解本政策。
+
+
一、我们如何收集和使用个人信息
+
(一)词语释义
+
+ (1)妙趣盲盒产品或服务是指:我们通过合法拥有并运营的、标注名称包含“妙趣盲盒”的客户端应用程序以及妙趣盲盒官方网站(以下简称“妙趣盲盒”或“本平台”)等,向您提供的产品与服务。关联方是指在现在、将来控制厦门正纯科技有限公司、受厦门正纯科技有限公司控制或与厦门正纯科技有限公司处于共同控制下的法人主体。控制指通过所有权、有投票权的股份、合同、实际运营关联或其他被依法认定的方式直接或间接地拥有影响被控制对象管理/经营的能力。
+
+
+ (2)个人信息是指:以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。本政策个人信息包括姓名、出生日期、身份证件号码、个人生物识别信息、住址、通信通讯联系方式、通信记录和内容、账号密码、财产信息、征信信息、行踪轨迹、住宿信息、健康生理信息、网络身份识别信息、
+ 常用设备信息、交易信息等。
+
+ (3)个人敏感信息是指:一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息。本政策中的个人敏感信息包括身份证件号码、邮箱地址、各类密码(口令、保护答案、数字证书)、个人生物识别信息、通信记录和内容、个人健康生理信息、个人财产信息、银行账号、征信信息、行踪轨迹、住宿信息、交易信息、14岁周岁以下(含)儿童的个人信息等。
+
+
+ (4)身份要素是指:产品用于识别您身份的信息要素,例如:您的登录名、密码、短信校验码、电话号码、手机号码、证件号码及个人生物识别信息(例如:指纹信息、脸部信息)。
+
+ (5)非个人信息:通过对个人信息的技术处理(包括但不限于匿名化、去标识化等),使得处理后的信息无法单独或结合其他信息识别到您的个人身份,
+ 且处理后的信息不能被复原,处理后的信息不属于法律意义上您的个人信息。但当个人信息与处理后的信息结合使用期间,这些结合信息将作为您的个人信息按照本政策处理与保护。
+
(二)收集和使用个人信息的场景、目的及所收集的信息
+
我们仅会出于本政策所述的以下目的,在以下场景收集和使用您的个人信息:
+
(1)帮助您成为我们的用户及进行账户管理
+
+ 为注册成为用户并使用我们的产品和服务,您需要提供您手机当前的手机号码进行注册登录。如果您拒绝提供上述信息,您将无法注册妙趣盲盒平台账户,仅可以使用浏览、搜索服务。为了确保我们是在为您本人提供服务,我们可能会根据您提供的上述信息校验您的身份。
+
+
+ 您也可以选择使用第三方账号登录,如您使用微信账号登录的,我们会获取您的微信头像、微信昵称。但您使用第三方账号登录后,仍需要提供手机号进行绑定。
+
+
(2)帮助您完成下单及订单管理
+
+ 当您在本平台订购具体商品时,我们会通过系统为您生成购买该商品的订单。在下单过程中,您需至少提供您的收货人姓名、收货地址、收货人联系电话,对于部分特殊类型的商品您还需要提供该商品所必需的其他信息。
+
+
+ 同时该订单中会载明您所购买的商品信息、具体订单号、订单创建时间、您应支付的金额、您的备注信息。我们收集这些信息是为了帮助您顺利完成交易、保障您的交易安全、便于您查询订单信息、提供客服与售后服务及其他我们明确告知的目的。
+
+
您可以通过妙趣盲盒为其他人订购商品,您需要提供该实际收货人的前述个人信息,并确保已取得该实际收货人的同意。
+
+ 为便于您了解、查询订单信息并对订单信息进行管理,我们会收集您在使用我们服务过程中产生的订单信息用于向您展示及便于您对订单进行管理。
+
+
您可额外填写包括其他联系电话、收货时间在内的更多附加信息以确保商品或服务的准确送达。
+
您可以通过「我的」-「我的订单」查看和管理您的订单信息。
+
(3)帮助您完成支付
+
+ 为完成订单支付,您可通过第三方支付(支付宝/微信)付款。我们会将您的妙趣盲盒平台账户用户名、订单支付相关信息、订单安全相关设备信息及其他反洗钱法律要求的必要信息通过在网站或客户端中嵌入的第三方支付软件工具开发包(软件工具开发包在本政策中简称“SDK”)与第三方支付公司共享。
+
+
为使我们及时获悉并确认您的支付进度及状态,为您提供售后与争议解决服务,您同意我们可自第三方支付公司处收集与支付进度相关信息。
+
+
(4)帮助向您完成商品的交付
+
+ 为保证您购买的商品能够顺利、安全、准确送达、提供,我们会向为妙趣盲盒平台提供物流相关服务的供应商(包括但不限于提供发货服务、快递服务的公司)披露订单相关的配送信息。您知晓并同意相应物流配送主体不可避免地获知及使用您的配送信息,用于完成交付目的。
+
+
+ 为向您提供售后与争议解决服务之目的,我们需要及时获悉并确认交付进度及状态,您同意我们可自物流相关服务主体处收集与交付进度相关的信息。如售后涉及退换货的,您同意向我们提供退货相关物流信息及同意我们可自物流相关服务主体处收集与退货进度相关的信息。
+
+
(5)为您提供客服支持及争议处理
+
当您与我们联系或提出售中、售后、争议纠纷处理申请时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息以核验您的用户身份。
+
+
+ 为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的沟通、通信/通话记录及相关内容(包括账户信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。如果您针对具体订单进行咨询、投诉或提供建议的,我们会使用您的账户信息和订单信息。
+
+
+ 为优化服务质量,我们可能会获取您的麦克风的权限,以便可以通过语音的方式沟通;我们还可能会获取您的相机及/或照片的权限,以便您向客服提供照片、视频资料。如果您不同意或拒绝授权提供,将无法使用此功能,但不影响您正常使用本平台的其他功能。
+
+
+ 为了提供服务及改进服务质量的合理需要,我们还可能使用的您的其他信息,包括您与客服联系时您提供的相关信息,您参与问卷调查时向我们发送的问卷答复信息。
+
(6)保障产品正常运行
+
+ 当您使用我们的产品时,为了保障产品基础功能及服务能够正常运行,您同意我们根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、苹果唯一设备标识符(IFDA)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)、OAID)、设备所在位置相关信息(如IP
+ 地址、WLAN接入点、SSID、BSSID、蓝牙、基站、地理位置信息)。需要您注意,这些信息是我们提供服务和保障产品正常运行所必须收集的基本信息。
+
+ 我们在应用第一次启动时,将会请求您授权读写外置存储信息权限,以读写外置存储信息。我们必须申请此权限,用于存储您在产品使用过程中产生的数据,拒绝此权限将导致您无法正常使用。
+
(7)保障产品、服务及用户使用安全
+ 为帮助我们更好地实现了解产品运行情况、判断账户安全、进行身份验证、检测及防范安全事件的目的,我们可能记录网络日志信息、应用信息、正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据及应用来源等信息:
+
+
①
+ 日志信息:我们会收集您对产品或服务的详细使用情况,作为有关网络日志保存(例如,搜索查询内容、IP地址、浏览器的类型、电信运营商);
+
+
②
+ 其他信息:我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、总体安装使用情况、性能数据、应用来源,并可能使用或整合您的用户信息、交易信息、设备信息、有关网络日志信息,进而综合判断您账户及交易风险、进行身份验证、检测及防范安全事件,并依法采取必要的记录、分析措施。
+
+
(8)消息通知及市场推广
+
+ 我们会通过PUSH通知为您提供推荐商品、运营活动等资讯,及向您发出平台公告、平台通知等。为了实现上述目的所必需,确保应用处于关闭或后台运行状态下正常接收到PUSH
+ 通知,我们可能会在合理频率范围内自启动。
+
+ 我们可能会通过短信等形式为向您提供商品、运营活动等资讯,如果您不希望接收上述资讯,您可随时根据短信提示或我们提供的其他方式进行退订。
+
+
需要您注意的是,单独的设备信息、日志信息等是无法识别特定自然人身份的信息,属于非本政策所指“个人信息”。
+
(三)我们直接调用的权限
+
我们承诺决不超范围、超频次搜集您的个人信息,决不搜集与使用本产品服务非必需或无合理应用场景的信息。
+
+ 您在使用本平台时,为提供给您服务之目的,本平台可能在您使用该应用某些场景下向您申请终端设备的如下权限,当然您可以拒绝开启以下权限,或在手机的设置中关闭以下权限,关闭以下权限不会影响您对其他功能的使用。
+
+
我们直接调用的设备权限包括:
+
1、 通知
+
对应业务功能:全部功能
+
调用权限目的:用于接收各类消息
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法接收推送通知
+
2、 无线数据
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
3、 WLAN
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
4、外置存储
+
对应业务功能:全部功能
+
调用权限目的:用于写入存储用户信息,存储日志等信息,缓存用户图片数据
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法流畅使用
+
5、相机
+
对应业务功能:客服功能、更换头像功能
+
调用权限目的:读写设备上的照片及文件,用于在客服功能及更换头像功能中上传照片或视频
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法在客服功能及更换头像功能中上传照片或视频
+
6、麦克风
+
对应业务功能:客服功能
+
调用权限目的:用于发送语音消息、实时语音通话
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法使用麦克风与客服进行语音沟通
+
7、 访问电话状态(仅适用于安卓)
+
对应业务功能:全部功能及安全保障
+
+ 调用权限目的:获取设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)),用于保障用户的账户及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中。
+
8、 安装软件包(仅适用于安卓)
+
对应业务功能:安装更新功能
+
调用权限目的:用于本产品软件安装或更新
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法正常安装软件
+
9、IFDA获取(仅适用于iOS)
+
对应业务功能:全部功能及安全保障
+
调用权限目的:获取苹果手机唯一设备标识符IFDA,用于保障用户账号及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中、用户无法使用“本机号码一键登录”功能
+
+ 当我们要将个人信息用于本政策未载明的其它用途时,会事先征求您的同意。当我们要将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。
+
+
(四)无需征得同意收集和使用的个人信息
+
根据法律法规及相关国家标准,我们在下列任意一种或多种情形下收集和使用您的个人信息无需征得您的授权同意。
+
(1)与国家安全、国防安全直接相关的;
+
(2)与公共安全、公共卫生、重大公共利益直接相关的;
+
(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+
(4)为应对突发公共卫生事件,或出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您同意的;
+
(5)所收集的您的个人信息是您自行向社会公众公开的;
+
(6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
+
(7)根据您的要求签订或履行合同所必需的;
+
(8)用于维护产品的安全稳定运行所必需的,例如发现、处置产品故障;
+
(9)为合法的新闻报道所必需的;
+
+ (10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
+
+
(11)法律法规规定及相关国家标准的其他情形。
+
二、我们如何使用Cookie、同类技术和SDK技术
+
(一)Cookie
+
+ 为使您获得更轻松的访问体验,您使用我们的产品时,我们可能会通过小型数据文件识别您的身份,这么做可帮您省去重复输入注册信息的步骤,或者帮助判断您的账号安全状态。这些数据文件可能是Cookie。Cookie通常包含标识符、站点名称以及一些号码和字符。您可根据自己的偏好管理或删除Cookie。有关详情,请参见AboutCookies.org。但请注意,如果停用Cookie,您可能无法享受最佳的服务体验,某些服务也可能无法正常使用。
+
+
(二)与Cookie同类技术
+
+ 除Cookie外,我们还会使用网站信标和像素标签等其他同类技术(例如Beacon、Proxy等),但我们不会将Cookie和同类技术用于本政策所述目的之外的任何用途。
+
(三)SDK技术
+
+ 为保证产品相关功能的实现与应用安全稳定的运行,我们可能会接入由第三方服务提供商提供的软件工具开发包(SDK)实现相关目的。我们会对合作获取信息的软件工具开发包(SDK)进行严格的安全监测,以保证数据安全。前述服务商收集和处理信息等行为遵守其自身的隐私条款,而不适用于本政策。为了最大程度保障您的信息安全,我们建议您在使用任何第三方SDK类服务前先行查看其用户协议及隐私条款。为保障您的合法权益,如您发现这等SDK或其他类似的应用程序存在风险时,建议您立即终止相关操作并及时与我们取得联系。
+
+
我们接入的第三方SDK及信息收集目的、场景等包括:
+
1、微信SDK(com.tencent.mm.opensdk)
+
涉及个人信息:分享的图片或内容、微信包名信息
+
使用目的:支持微信登录和分享
+
使用场景:在用户使用微信登录或者分享时使用
+
合作方主体:深圳市腾讯计算机系统有限公司
+
收集方式:SDK自行采集
+
官网链接:https://open.weixin.qq.com/
+
+ 合作方隐私政策:https://support.weixin.qq.com/cgi-bin/mmsupportacctnodeweb-bin/pages/RYiYJkLOrQwu0nb8
+
+
2、Alipay(支付宝)SDK(com.alipay.sdk)
+
涉及个人信息:设备标识符(Android如IMEI、MEID、IMSI、Android
+ ID、硬件序列号/Serial、ICCID、OAID,iOS如IDFV、IDFA)、设备MAC地址、IP地址、WLAN接入点(如SSID、BSSID)、Wi-Fi列表、网络信息、设备信息、软件列表、读取存储信息、支付宝包名信息、传感器列表
+
+
权限调用:存储权限、电话权限
+
使用目的:帮助用户在应用内使用支付宝
+
使用场景:在用户使用支付宝支付时使用
+
合作方主体:支付宝(中国)网络技术有限公司
+
收集方式:SDK自行采集
+
官网链接:https://render.alipay.com/p/f/fd-iwwyijeh/index.html
+
合作方隐私政策:https://docs.open.alipay.com/54
+
3、数字联盟SDK(cn.shuzilm.core)
+
+ 涉及个人信息:设备制造商、设备型号、设备系统版本、应用版本、传感器(光传感器、磁场传感器、重力传感器、压力传感器、方向传感器、旋转矢量传感器、陀螺仪传感器、加速度传感器)、应用信息、通信状态、信号强度、蓝牙信息、设备网络状态信息【包括网络的接入形式、IP地址、WiFi信息(BSSID、SSID)、运营商类型及网络基站信息】、设备物理环境信息、IDFA(儿童类应用不收集)、IDFV、OAID、粗略位置信息、指定包名信息、Android
+ ID、IMEI、IMSI、MEID、设备序列号设备MAC地址、WiFi列表
+
权限调用:粗略位置权限
+
使用目的:安全风控,识别反馈设备的真实性,其中传感器主要用于辅助识别模拟器,虚拟机等虚拟环境及辅助判断作弊场景
+
使用场景:检测设备欺诈与作弊行为时使用
+
合作方主体:北京数字联盟网络科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.shuzilm.cn/
+
合作方隐私政策:https://www.shuzilm.cn/privacy
+
4、LinkedMe SDK(com.microquation.linkedme)
+
涉及个人信息:设备MAC地址、OAID、唯一设备识别码、IP、SD卡数据、指定包名信息、WiFi状态
+
权限调用:粗略位置权限
+
使用目的:推广统计和效果分析,保存分享的图片,识别用户来源
+
使用场景:使用数据分析服务时使用
+
合作方主体:北京微方程科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.linkedme.cc/index.html
+
合作方隐私政策:https://www.linkedme.cc/privacy-policy.html
+
22、Okio (okio)
+ 涉及个人信息:写入存储信息、IP地址
+ 权限获取:存储权限
+ 使用目的:用于配合OkHttp实现,对服务器API发送请求,下载网络文件,访问网页。
+ 使用场景: 网络请求,访问网页。
+ 合作方主体:square
+ 收集方式:SDK自行采集
+ 官网链接:https://square.github.io/okio/
+ 23、Fresco(com.facebook)
+ 涉及个人信息:读写存储信息
+ 权限获取:存储权限
+ 使用目的:用于图片加载显示
+ 使用场景: APP内的所有图片显示。
+ 合作方主体: facebook
+ 收集方式:SDK自行采集
+ 官网链接:https://frescolib.org/
+ 三、我们如何共享、转让、公开披露个人信息
+ (一)如何共享个人信息
+ 我们不会与产品服务相关提供者以外的公司、组织和个人共享您的个人信息。我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息,具体情况如下:
+ 1.在获取明确同意的情况下共享:在获得您的明确同意后,我们会与其他方共享您的个人信息。
+ 2.在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。
+ 3.为实现产品功能或服务的共享:您的个人信息可能会与我们的关联公司共享。我们只会共享必要的个人信息,且受本政策中所声明目的的约束。关联公司如要改变个人信息的处理目的,或使用信息的目的超越原授权同意范围,将再次征求您的授权同意。
+ 4.为实现产品安全与分析统计的共享:
+ (1)保障使用安全:为保障您和其他用户的财产安全,使您和我们的正当合法权益免受不法侵害,我们和关联方或服务提供商可能会共享必要的设备、应用、进程、性能、环境及日志等信息。
+ (2)分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与关联方或第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。
+ (3)学术研究与科研:为提升相关领域的科研能力,促进科技发展水平,我们在确保数据安全与目的正当的前提下,可能会与科研院所、高校等机构共享去标识化或匿名化的数据。
+ (二)如何转让个人信息
+ 我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
+ 1.在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;
+ 2.在涉及合并、收购、资产转让或破产清算时,如涉及到个人信息转让,我们会在要求新的持有您个人信息的公司、组织继续受本政策的约束,将按照法律法规及不低于本政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求该公司、组织重新向您征求授权同意。
+ (三)如何披露个人信息
+ 我们仅会在以下情况下,公开披露您的个人信息并会采用符合行业内标准的安全保护措施:
+ (1)获得您明确同意后;
+ (2)基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息;
+ (3)对违规、欺诈行为进行处罚公告。
+ (四)免征得同意共享、转让、公开披露的个人信息
+ 根据法律法规及国家标准,我们在下列情形中,共享、转让、公开披露您的个人信息无需征得您的授权同意:
+ (1)与国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)为应对突发公共卫生事件,或出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您的同意的;
+ (5)您自行向社会公众公开的个人信息;
+ (6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
+ 四、我们如何保护个人信息
+ 本政策提供的如下个人信息保护措施仅适用于我们的产品。一旦您离开我们的产品,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在我们的产品之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于我们的产品的链接或引导。
+ (一)为保障您的信息安全,我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露、毁损、误用、非授权访问、非授权披露和更改的风险。
+ 我们会采取一切合理可行的措施,保护您的个人信息。例如:
+ (1)在您的设备与“产品服务”之间交换数据(如银行信息)时受SSL加密保护;
+ (2)我们会使用加密技术确保数据的保密性;
+ (3)我们会使用受信赖的保护机制防止数据遭到恶意攻击;
+ (4)我们会部署访问控制机制,确保只有授权人员才可访问个人信息;
+ (5)我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识;
+ (6)我们认为其他的合理可行的保护措施。
+ (二)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
+ (三)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
+ (四)我们会采取一切合理可行的措施,确保未收集无关的个人信息。
+ (五)我们将不定期更新并公开安全风险、个人信息安全影响评估等报告的有关内容。
+ (六)尽管已经采取了上述合理有效措施,并已经遵守了相关法律法规要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
+ 您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人等。
+ (七)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、电话、推送通知等方式告知您,
+ 难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。
+ 五、您的权利
+ (一)访问您的个人信息
+ 您有权访问您的个人信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:
+ 如果您希望访问您的账号中的个人资料信息,您可以通过本平台中点击右下方的「我的」查看;如果您希望访问您的账号中的收件地址信息,您可以通过本平台中点击右下方的「我的」-「地址管理」查看及编辑。
+ 如果您无法通过上述方式访问上述个人信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (二)更正您的个人信息
+ 一般情况下,您可以随时更正您的个人信息。
+ 但出于安全性、身份识别、交易安全的考虑,您不能随时自主修改手机号码信息、订单的收货信息及实名认证信息;如您确有必要修改该类信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (三)删除您的个人信息
+ 在以下情形中,您可以向我们提出删除个人信息的请求:
+ 1.如果我们处理个人信息的行为违反法律法规;
+ 2.如果我们收集、使用您的个人信息,却未征得您的同意;
+ 3.如果我们处理个人信息的行为违反了与您的约定;
+ 4.如果您不再使用本平台提供的服务并提出注销账号申请;
+ 5.如果我们不再为您提供本平台或服务。
+ 您可根据本政策载明的联系方式联系我们反馈您的删除个人信息的需求,我们将在15个工作日内响应。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。
+ 当您从我们的服务中删除信息后,我们可能不会立即在备份系统中删除相应的信息,但会在备份更新时删除这些信息。
+ (四)管理您的授权范围
+ 每个业务功能需要一些基本的个人信息才能得以完成。
+ 对于为优化用户体验额外收集的个人信息的收集和使用,您可以随时给予或收回您的授权同意。您可以通过以下方式自行操作:您可以通过删除个人信息、关闭设备功能、更改应用权限等方式,改变您在功能和服务中的授权范围。当您撤回同意后,我们无法继续为您提供撤回同意所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意的决定,不会影响我们此前基于您的同意而开展的个人信息处理。如您在撤回同意时遇到困难,您可以通过根据本政策载明的联系方式联系我们,我们将在15个工作日内回复您的撤回请求。
+ (五)账号注销
+ 本平台未提供在线的注销功能,请您直接根据本政策载明的联系方式与我们联系申请账号注销。
+ 在注销账号前,我们将验证您的个人身份、安全状态、设备信息、仓库状态、订单状态等。
+ 请确保您所申请注销的账号应当是您本人依照《用户协议》的约定创建并由我们提供给您本人的账号。
+ 建议您在注销前自行备份账号相关的所有信息,并请确认与账号相关的所有服务均已进行妥善处理。如您的账号目前仍有未完成订单(包括待发货订单、待收货订单、售后处理中的订单)或仓库未清空(即仓库中含有已购买但未开启的盲盒、或通过开启盲盒获取但未提货或未兑换为积分的物品)的,请您在订单完成后或清空仓库后再提起账号注销申请,否则将无法提交注销申请;如账号内有未使用的积分及其他虚拟权益等,账号注销申请的提交视为您已放弃其全部权益,注销后不得向本平台要求恢复。
+ 如果您的账号涉及争议纠纷,包括但不限于:投诉、举报、诉讼、仲裁、国家有权机关调查等,您理解并同意,我们有权自行决定是否终止账号的注销,而无需另行得到您的同意。
+ 考虑到存在用户因误操作账号注销的情形,我们将自用户提交注销申请之日起提供为期15个工作日的账号申诉期,申诉期间用户登录产品账号即可取消注销申请。如用户未在申诉期间取消注销申请,则申诉期届满后,账号将自动注销,注销过程不可逆的、不可恢复。
+ 您知悉并理解,账号注销后您将无法再使用该账号登录及使用本平台提供的所有服务。但注销账号并不代表账号注销前的账户行为和相关责任得到豁免或减轻。
+ 当注销账号后,我们将对您持有您的个人信息(包括但不限于账号信息、交易记录等)进行删除或匿名化处理,但法律法规另有规定的除外。
+ (六)我们如何响应您的请求
+ 为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
+ 我们将在十五个工作日内做出答复。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视具体情况收取一定成本费用。
+ 对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。
+ 在以下情形中,按照法律法规要求,我们将无法响应您的请求:
+ (1)国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)有充分证据表明您存在主观恶意或滥用权利的;
+ (5)响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;
+ (6)涉及商业秘密的。
+ (七)投诉举报
+ 您可以按照我们公示的制度或联系我们进行投诉或举报。如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索,您可以通过本政策载明的联系方式进行举报,我们核查后会在十五个工作日内反馈您的投诉与举报。
+ (八)访问隐私政策
+ 您可以在本平台中点击右下方的「我的」-「设置」-「隐私政策」后,查看本政策的全部内容。
+ (九)停止运营向您告知权利
+ 如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
+ 六、我们如何处理未成年人的个人信息
+ (一)我们期望父母或监护人指导未成年人使用我们的服务
+ 若您是未满18周岁的未成年人,在使用我们的产品前,应在您的父母或其他监护人监护、指导下共同阅读并同意本政策。如果没有父母或监护人的同意,儿童(不满14周岁)不得私自使用。
+ (二)我们重视保护未成年人个人信息
+ 我们根据国家相关法律法规的规定保护未成年人的个人信息,对于经父母同意而收集未成年人个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享或公开披露此信息。
+ (三)自查与接收反馈
+ 如果我们发现自己在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关数据或对其进行匿名化处理,但法律法规另有规定的除外。同时我们建立了严格的未成年人信息收集使用规则,以保护儿童的个人信息安全,您可以通过阅读《儿童个人信息保护规则》了解更多信息。
+ 若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本政策公示的联系方式与我们联系。
+ 七、我们如何存储个人信息
+ (一)我们在中华人民共和国境内收集和产生的个人信息,将存储在中华人民共和国境内。我们不会将上述信息传输至境外(您通过互联网进行跨境购买商品等个人主动行为除外),如果部分产品涉及跨境业务,我们需要向境外机构传输境内收集的相关个人信息的,我们将会遵循国家相关规定,
+ 征求您的同意,并按照法律法规和相关监管部门的规定执行,并通过签订协议、现场核查等有效措施,要求境外机构为所获得的您的个人信息保密。
+ (二)我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。我们仅在为提供产品服务之目的所必需的期间内保留您的个人信息。超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外,例如《中华人民共和国电子商务法》要求商品和服务信息、交易信息保存时间自交易完成之日起不少于三年,《中华人民共和国网络安全法》要求网络日志的留存时间不少于六个月。
+ 八、我们如何更新本政策
+ 为了给您提供更好的服务,我们会适时对本政策进行修订,该等修订构成本政策的一部分并具有等同于本政策的效力。
+ 如该等修订会导致您在本政策项下权利的实质减损,我们将在变更生效前,通过在页面显著位置公示等方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的政策约束。
+ 九、联系我们
+ (一)我们提供本政策载明的联系渠道供用户向我们反馈处理与个人信息问题相关的投诉、建议、疑问等,我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。
+ (二)如果您对我们的回复不满意,或因签署、履行本政策与我们产生任何争议的,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+ 十、其他
+ (一)本政策中的标题仅为方便及阅读而设,并不影响本政策中任何规定的含义或解释。
+ (二)本政策中所述的我们的产品及相关服务有可能会根据您所使用的终端设备、手机型号、系统版本、软件应用程序版本等因素而有所不同。最终的产品和服务以您所使用的产品及相关服务为准。
+ (三)本政策的全部条款属于《用户协议》重要组成部分之一。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/index copy.html b/utils/index copy.html
new file mode 100755
index 0000000..0ea5391
--- /dev/null
+++ b/utils/index copy.html
@@ -0,0 +1,1011 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
请阅读并同意以下条款
+
+ 为保障您的合法权益,请您先阅读并同意《用户协议》 以及《隐私政策》
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
隐私政策
+
+
+
+
+
生效日期:2024年05月01日
+
+ 本《隐私政策》(简称“本政策”)仅适用于厦门正纯科技有限公司及其关联方(简称“我们”)作为运营者的妙趣盲盒产品或服务,包括妙趣盲盒网站和妙趣盲盒移动应用(简称“产品”),不适用于有单独的隐私权政策且未纳入本政策的第三方产品或服务。您使用我们的产品时,我们将于您同意本政策及《用户协议》后,按照本政策收集、使用、存储、传输、转让(如适用)及对外提供您的个人信息。同时,我们会通过本政策向您说明,我们如何为您提供访问、更新、管理和保护您的个人信息的服务。
+
+
+ 本政策与您使用我们的产品关系紧密,我们建议您仔细阅读并理解本政策全部内容,做出您认为适当的选择。如果您未明示同意本政策并开始使用,这将导致我们无法为您提供完整的产品和服务。我们努力用通俗易懂、简明扼要的文字表达,并对本政策中与您的权益存在重大关系的条款,采用粗体字进行标注以提示您注意。请您在使用我们的产品前仔细阅读本政策,确保对其内容特别是加粗内容的含义及相应法律后果已全部知晓并充分理解。您勾选或点击“同意”即视为您接受本政策;您同意本政策在您使用产品的整个过程中均有效。如果您有任何疑问、意见或建议,请通过以下任意一种方式与我们取得联系:
+
+
1.信息保护负责人联系电话:15280116383;
+
2.联系邮箱:648715275@qq.com;
+
3.在线客服:您可在妙趣盲盒移动应用内点击「我的」-「联系客服」联系;
+
4.注册地址及常用办公地址:福建省厦门市思明区前埔路506号502室之一。
+
本政策将帮助您了解以下内容:
+
一、我们如何收集和使用个人信息
+
二、我们如何使用Cookie、同类技术和SDK技术
+
三、我们如何共享、转让、公开披露个人信息
+
四、我们如何保护个人信息
+
五、您的权利
+
六、我们如何处理未成年人的个人信息
+
七、我们如何存储个人信息
+
八、我们如何更新本政策
+
九、联系我们
+
十、其他
+
+ 我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将按业界成熟的安全标准,采取相应的安全保护措施来保护您的个人信息。特别需要指出的是,即使经过您的授权,我们获得了敏感权限,也不会在相关功能或服务不需要时而收集您的信息。请在使用我们的产品前,仔细阅读并了解本政策。
+
+
一、我们如何收集和使用个人信息
+
(一)词语释义
+
+ (1)妙趣盲盒产品或服务是指:我们通过合法拥有并运营的、标注名称包含“妙趣盲盒”的客户端应用程序以及妙趣盲盒官方网站(以下简称“妙趣盲盒”或“本平台”)等,向您提供的产品与服务。关联方是指在现在、将来控制厦门正纯科技有限公司、受厦门正纯科技有限公司控制或与厦门正纯科技有限公司处于共同控制下的法人主体。控制指通过所有权、有投票权的股份、合同、实际运营关联或其他被依法认定的方式直接或间接地拥有影响被控制对象管理/经营的能力。
+
+
+ (2)个人信息是指:以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。本政策个人信息包括姓名、出生日期、身份证件号码、个人生物识别信息、住址、通信通讯联系方式、通信记录和内容、账号密码、财产信息、征信信息、行踪轨迹、住宿信息、健康生理信息、网络身份识别信息、
+ 常用设备信息、交易信息等。
+
+ (3)个人敏感信息是指:一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息。本政策中的个人敏感信息包括身份证件号码、邮箱地址、各类密码(口令、保护答案、数字证书)、个人生物识别信息、通信记录和内容、个人健康生理信息、个人财产信息、银行账号、征信信息、行踪轨迹、住宿信息、交易信息、14岁周岁以下(含)儿童的个人信息等。
+
+
+ (4)身份要素是指:产品用于识别您身份的信息要素,例如:您的登录名、密码、短信校验码、电话号码、手机号码、证件号码及个人生物识别信息(例如:指纹信息、脸部信息)。
+
+ (5)非个人信息:通过对个人信息的技术处理(包括但不限于匿名化、去标识化等),使得处理后的信息无法单独或结合其他信息识别到您的个人身份,
+ 且处理后的信息不能被复原,处理后的信息不属于法律意义上您的个人信息。但当个人信息与处理后的信息结合使用期间,这些结合信息将作为您的个人信息按照本政策处理与保护。
+
(二)收集和使用个人信息的场景、目的及所收集的信息
+
我们仅会出于本政策所述的以下目的,在以下场景收集和使用您的个人信息:
+
(1)帮助您成为我们的用户及进行账户管理
+
+ 为注册成为用户并使用我们的产品和服务,您需要提供您手机当前的手机号码进行注册登录。如果您拒绝提供上述信息,您将无法注册妙趣盲盒平台账户,仅可以使用浏览、搜索服务。为了确保我们是在为您本人提供服务,我们可能会根据您提供的上述信息校验您的身份。
+
+
+ 您也可以选择使用第三方账号登录,如您使用微信账号登录的,我们会获取您的微信头像、微信昵称。但您使用第三方账号登录后,仍需要提供手机号进行绑定。
+
+
(2)帮助您完成下单及订单管理
+
+ 当您在本平台订购具体商品时,我们会通过系统为您生成购买该商品的订单。在下单过程中,您需至少提供您的收货人姓名、收货地址、收货人联系电话,对于部分特殊类型的商品您还需要提供该商品所必需的其他信息。
+
+
+ 同时该订单中会载明您所购买的商品信息、具体订单号、订单创建时间、您应支付的金额、您的备注信息。我们收集这些信息是为了帮助您顺利完成交易、保障您的交易安全、便于您查询订单信息、提供客服与售后服务及其他我们明确告知的目的。
+
+
您可以通过妙趣盲盒为其他人订购商品,您需要提供该实际收货人的前述个人信息,并确保已取得该实际收货人的同意。
+
+ 为便于您了解、查询订单信息并对订单信息进行管理,我们会收集您在使用我们服务过程中产生的订单信息用于向您展示及便于您对订单进行管理。
+
+
您可额外填写包括其他联系电话、收货时间在内的更多附加信息以确保商品或服务的准确送达。
+
您可以通过「我的」-「我的订单」查看和管理您的订单信息。
+
(3)帮助您完成支付
+
+ 为完成订单支付,您可通过第三方支付(支付宝/微信)付款。我们会将您的妙趣盲盒平台账户用户名、订单支付相关信息、订单安全相关设备信息及其他反洗钱法律要求的必要信息通过在网站或客户端中嵌入的第三方支付软件工具开发包(软件工具开发包在本政策中简称“SDK”)与第三方支付公司共享。
+
+
为使我们及时获悉并确认您的支付进度及状态,为您提供售后与争议解决服务,您同意我们可自第三方支付公司处收集与支付进度相关信息。
+
+
(4)帮助向您完成商品的交付
+
+ 为保证您购买的商品能够顺利、安全、准确送达、提供,我们会向为妙趣盲盒平台提供物流相关服务的供应商(包括但不限于提供发货服务、快递服务的公司)披露订单相关的配送信息。您知晓并同意相应物流配送主体不可避免地获知及使用您的配送信息,用于完成交付目的。
+
+
+ 为向您提供售后与争议解决服务之目的,我们需要及时获悉并确认交付进度及状态,您同意我们可自物流相关服务主体处收集与交付进度相关的信息。如售后涉及退换货的,您同意向我们提供退货相关物流信息及同意我们可自物流相关服务主体处收集与退货进度相关的信息。
+
+
(5)为您提供客服支持及争议处理
+
当您与我们联系或提出售中、售后、争议纠纷处理申请时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息以核验您的用户身份。
+
+
+ 为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的沟通、通信/通话记录及相关内容(包括账户信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。如果您针对具体订单进行咨询、投诉或提供建议的,我们会使用您的账户信息和订单信息。
+
+
+ 为优化服务质量,我们可能会获取您的麦克风的权限,以便可以通过语音的方式沟通;我们还可能会获取您的相机及/或照片的权限,以便您向客服提供照片、视频资料。如果您不同意或拒绝授权提供,将无法使用此功能,但不影响您正常使用本平台的其他功能。
+
+
+ 为了提供服务及改进服务质量的合理需要,我们还可能使用的您的其他信息,包括您与客服联系时您提供的相关信息,您参与问卷调查时向我们发送的问卷答复信息。
+
(6)保障产品正常运行
+
+ 当您使用我们的产品时,为了保障产品基础功能及服务能够正常运行,您同意我们根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、苹果唯一设备标识符(IFDA)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)、OAID)、设备所在位置相关信息(如IP
+ 地址、WLAN接入点、SSID、BSSID、蓝牙、基站、地理位置信息)。需要您注意,这些信息是我们提供服务和保障产品正常运行所必须收集的基本信息。
+
+ 我们在应用第一次启动时,将会请求您授权读写外置存储信息权限,以读写外置存储信息。我们必须申请此权限,用于存储您在产品使用过程中产生的数据,拒绝此权限将导致您无法正常使用。
+
(7)保障产品、服务及用户使用安全
+ 为帮助我们更好地实现了解产品运行情况、判断账户安全、进行身份验证、检测及防范安全事件的目的,我们可能记录网络日志信息、应用信息、正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据及应用来源等信息:
+
+
①
+ 日志信息:我们会收集您对产品或服务的详细使用情况,作为有关网络日志保存(例如,搜索查询内容、IP地址、浏览器的类型、电信运营商);
+
+
②
+ 其他信息:我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、总体安装使用情况、性能数据、应用来源,并可能使用或整合您的用户信息、交易信息、设备信息、有关网络日志信息,进而综合判断您账户及交易风险、进行身份验证、检测及防范安全事件,并依法采取必要的记录、分析措施。
+
+
(8)消息通知及市场推广
+
+ 我们会通过PUSH通知为您提供推荐商品、运营活动等资讯,及向您发出平台公告、平台通知等。为了实现上述目的所必需,确保应用处于关闭或后台运行状态下正常接收到PUSH
+ 通知,我们可能会在合理频率范围内自启动。
+
+ 我们可能会通过短信等形式为向您提供商品、运营活动等资讯,如果您不希望接收上述资讯,您可随时根据短信提示或我们提供的其他方式进行退订。
+
+
需要您注意的是,单独的设备信息、日志信息等是无法识别特定自然人身份的信息,属于非本政策所指“个人信息”。
+
(三)我们直接调用的权限
+
我们承诺决不超范围、超频次搜集您的个人信息,决不搜集与使用本产品服务非必需或无合理应用场景的信息。
+
+ 您在使用本平台时,为提供给您服务之目的,本平台可能在您使用该应用某些场景下向您申请终端设备的如下权限,当然您可以拒绝开启以下权限,或在手机的设置中关闭以下权限,关闭以下权限不会影响您对其他功能的使用。
+
+
我们直接调用的设备权限包括:
+
1、 通知
+
对应业务功能:全部功能
+
调用权限目的:用于接收各类消息
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法接收推送通知
+
2、 无线数据
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
3、 WLAN
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
4、外置存储
+
对应业务功能:全部功能
+
调用权限目的:用于写入存储用户信息,存储日志等信息,缓存用户图片数据
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法流畅使用
+
5、相机
+
对应业务功能:客服功能、更换头像功能
+
调用权限目的:读写设备上的照片及文件,用于在客服功能及更换头像功能中上传照片或视频
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法在客服功能及更换头像功能中上传照片或视频
+
6、麦克风
+
对应业务功能:客服功能
+
调用权限目的:用于发送语音消息、实时语音通话
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法使用麦克风与客服进行语音沟通
+
7、 访问电话状态(仅适用于安卓)
+
对应业务功能:全部功能及安全保障
+
+ 调用权限目的:获取设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)),用于保障用户的账户及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中。
+
8、 安装软件包(仅适用于安卓)
+
对应业务功能:安装更新功能
+
调用权限目的:用于本产品软件安装或更新
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法正常安装软件
+
9、IFDA获取(仅适用于iOS)
+
对应业务功能:全部功能及安全保障
+
调用权限目的:获取苹果手机唯一设备标识符IFDA,用于保障用户账号及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中、用户无法使用“本机号码一键登录”功能
+
+ 当我们要将个人信息用于本政策未载明的其它用途时,会事先征求您的同意。当我们要将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。
+
+
(四)无需征得同意收集和使用的个人信息
+
根据法律法规及相关国家标准,我们在下列任意一种或多种情形下收集和使用您的个人信息无需征得您的授权同意。
+
(1)与国家安全、国防安全直接相关的;
+
(2)与公共安全、公共卫生、重大公共利益直接相关的;
+
(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+
(4)为应对突发公共卫生事件,或出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您同意的;
+
(5)所收集的您的个人信息是您自行向社会公众公开的;
+
(6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
+
(7)根据您的要求签订或履行合同所必需的;
+
(8)用于维护产品的安全稳定运行所必需的,例如发现、处置产品故障;
+
(9)为合法的新闻报道所必需的;
+
+ (10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
+
+
(11)法律法规规定及相关国家标准的其他情形。
+
二、我们如何使用Cookie、同类技术和SDK技术
+
(一)Cookie
+
+ 为使您获得更轻松的访问体验,您使用我们的产品时,我们可能会通过小型数据文件识别您的身份,这么做可帮您省去重复输入注册信息的步骤,或者帮助判断您的账号安全状态。这些数据文件可能是Cookie。Cookie通常包含标识符、站点名称以及一些号码和字符。您可根据自己的偏好管理或删除Cookie。有关详情,请参见AboutCookies.org。但请注意,如果停用Cookie,您可能无法享受最佳的服务体验,某些服务也可能无法正常使用。
+
+
(二)与Cookie同类技术
+
+ 除Cookie外,我们还会使用网站信标和像素标签等其他同类技术(例如Beacon、Proxy等),但我们不会将Cookie和同类技术用于本政策所述目的之外的任何用途。
+
(三)SDK技术
+
+ 为保证产品相关功能的实现与应用安全稳定的运行,我们可能会接入由第三方服务提供商提供的软件工具开发包(SDK)实现相关目的。我们会对合作获取信息的软件工具开发包(SDK)进行严格的安全监测,以保证数据安全。前述服务商收集和处理信息等行为遵守其自身的隐私条款,而不适用于本政策。为了最大程度保障您的信息安全,我们建议您在使用任何第三方SDK类服务前先行查看其用户协议及隐私条款。为保障您的合法权益,如您发现这等SDK或其他类似的应用程序存在风险时,建议您立即终止相关操作并及时与我们取得联系。
+
+
我们接入的第三方SDK及信息收集目的、场景等包括:
+
1、微信SDK(com.tencent.mm.opensdk)
+
涉及个人信息:分享的图片或内容、微信包名信息
+
使用目的:支持微信登录和分享
+
使用场景:在用户使用微信登录或者分享时使用
+
合作方主体:深圳市腾讯计算机系统有限公司
+
收集方式:SDK自行采集
+
官网链接:https://open.weixin.qq.com/
+
+ 合作方隐私政策:https://support.weixin.qq.com/cgi-bin/mmsupportacctnodeweb-bin/pages/RYiYJkLOrQwu0nb8
+
+
2、Alipay(支付宝)SDK(com.alipay.sdk)
+
涉及个人信息:设备标识符(Android如IMEI、MEID、IMSI、Android
+ ID、硬件序列号/Serial、ICCID、OAID,iOS如IDFV、IDFA)、设备MAC地址、IP地址、WLAN接入点(如SSID、BSSID)、Wi-Fi列表、网络信息、设备信息、软件列表、读取存储信息、支付宝包名信息、传感器列表
+
+
权限调用:存储权限、电话权限
+
使用目的:帮助用户在应用内使用支付宝
+
使用场景:在用户使用支付宝支付时使用
+
合作方主体:支付宝(中国)网络技术有限公司
+
收集方式:SDK自行采集
+
官网链接:https://render.alipay.com/p/f/fd-iwwyijeh/index.html
+
合作方隐私政策:https://docs.open.alipay.com/54
+
3、数字联盟SDK(cn.shuzilm.core)
+
+ 涉及个人信息:设备制造商、设备型号、设备系统版本、应用版本、传感器(光传感器、磁场传感器、重力传感器、压力传感器、方向传感器、旋转矢量传感器、陀螺仪传感器、加速度传感器)、应用信息、通信状态、信号强度、蓝牙信息、设备网络状态信息【包括网络的接入形式、IP地址、WiFi信息(BSSID、SSID)、运营商类型及网络基站信息】、设备物理环境信息、IDFA(儿童类应用不收集)、IDFV、OAID、粗略位置信息、指定包名信息、Android
+ ID、IMEI、IMSI、MEID、设备序列号设备MAC地址、WiFi列表
+
权限调用:粗略位置权限
+
使用目的:安全风控,识别反馈设备的真实性,其中传感器主要用于辅助识别模拟器,虚拟机等虚拟环境及辅助判断作弊场景
+
使用场景:检测设备欺诈与作弊行为时使用
+
合作方主体:北京数字联盟网络科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.shuzilm.cn/
+
合作方隐私政策:https://www.shuzilm.cn/privacy
+
4、LinkedMe SDK(com.microquation.linkedme)
+
涉及个人信息:设备MAC地址、OAID、唯一设备识别码、IP、SD卡数据、指定包名信息、WiFi状态
+
权限调用:粗略位置权限
+
使用目的:推广统计和效果分析,保存分享的图片,识别用户来源
+
使用场景:使用数据分析服务时使用
+
合作方主体:北京微方程科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.linkedme.cc/index.html
+
合作方隐私政策:https://www.linkedme.cc/privacy-policy.html
+
22、Okio (okio)
+ 涉及个人信息:写入存储信息、IP地址
+ 权限获取:存储权限
+ 使用目的:用于配合OkHttp实现,对服务器API发送请求,下载网络文件,访问网页。
+ 使用场景: 网络请求,访问网页。
+ 合作方主体:square
+ 收集方式:SDK自行采集
+ 官网链接:https://square.github.io/okio/
+ 23、Fresco(com.facebook)
+ 涉及个人信息:读写存储信息
+ 权限获取:存储权限
+ 使用目的:用于图片加载显示
+ 使用场景: APP内的所有图片显示。
+ 合作方主体: facebook
+ 收集方式:SDK自行采集
+ 官网链接:https://frescolib.org/
+ 三、我们如何共享、转让、公开披露个人信息
+ (一)如何共享个人信息
+ 我们不会与产品服务相关提供者以外的公司、组织和个人共享您的个人信息。我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息,具体情况如下:
+ 1.在获取明确同意的情况下共享:在获得您的明确同意后,我们会与其他方共享您的个人信息。
+ 2.在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。
+ 3.为实现产品功能或服务的共享:您的个人信息可能会与我们的关联公司共享。我们只会共享必要的个人信息,且受本政策中所声明目的的约束。关联公司如要改变个人信息的处理目的,或使用信息的目的超越原授权同意范围,将再次征求您的授权同意。
+ 4.为实现产品安全与分析统计的共享:
+ (1)保障使用安全:为保障您和其他用户的财产安全,使您和我们的正当合法权益免受不法侵害,我们和关联方或服务提供商可能会共享必要的设备、应用、进程、性能、环境及日志等信息。
+ (2)分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与关联方或第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。
+ (3)学术研究与科研:为提升相关领域的科研能力,促进科技发展水平,我们在确保数据安全与目的正当的前提下,可能会与科研院所、高校等机构共享去标识化或匿名化的数据。
+ (二)如何转让个人信息
+ 我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
+ 1.在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;
+ 2.在涉及合并、收购、资产转让或破产清算时,如涉及到个人信息转让,我们会在要求新的持有您个人信息的公司、组织继续受本政策的约束,将按照法律法规及不低于本政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求该公司、组织重新向您征求授权同意。
+ (三)如何披露个人信息
+ 我们仅会在以下情况下,公开披露您的个人信息并会采用符合行业内标准的安全保护措施:
+ (1)获得您明确同意后;
+ (2)基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息;
+ (3)对违规、欺诈行为进行处罚公告。
+ (四)免征得同意共享、转让、公开披露的个人信息
+ 根据法律法规及国家标准,我们在下列情形中,共享、转让、公开披露您的个人信息无需征得您的授权同意:
+ (1)与国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)为应对突发公共卫生事件,或出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您的同意的;
+ (5)您自行向社会公众公开的个人信息;
+ (6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
+ 四、我们如何保护个人信息
+ 本政策提供的如下个人信息保护措施仅适用于我们的产品。一旦您离开我们的产品,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在我们的产品之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于我们的产品的链接或引导。
+ (一)为保障您的信息安全,我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露、毁损、误用、非授权访问、非授权披露和更改的风险。
+ 我们会采取一切合理可行的措施,保护您的个人信息。例如:
+ (1)在您的设备与“产品服务”之间交换数据(如银行信息)时受SSL加密保护;
+ (2)我们会使用加密技术确保数据的保密性;
+ (3)我们会使用受信赖的保护机制防止数据遭到恶意攻击;
+ (4)我们会部署访问控制机制,确保只有授权人员才可访问个人信息;
+ (5)我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识;
+ (6)我们认为其他的合理可行的保护措施。
+ (二)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
+ (三)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
+ (四)我们会采取一切合理可行的措施,确保未收集无关的个人信息。
+ (五)我们将不定期更新并公开安全风险、个人信息安全影响评估等报告的有关内容。
+ (六)尽管已经采取了上述合理有效措施,并已经遵守了相关法律法规要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
+ 您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人等。
+ (七)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、电话、推送通知等方式告知您,
+ 难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。
+ 五、您的权利
+ (一)访问您的个人信息
+ 您有权访问您的个人信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:
+ 如果您希望访问您的账号中的个人资料信息,您可以通过本平台中点击右下方的「我的」查看;如果您希望访问您的账号中的收件地址信息,您可以通过本平台中点击右下方的「我的」-「地址管理」查看及编辑。
+ 如果您无法通过上述方式访问上述个人信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (二)更正您的个人信息
+ 一般情况下,您可以随时更正您的个人信息。
+ 但出于安全性、身份识别、交易安全的考虑,您不能随时自主修改手机号码信息、订单的收货信息及实名认证信息;如您确有必要修改该类信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (三)删除您的个人信息
+ 在以下情形中,您可以向我们提出删除个人信息的请求:
+ 1.如果我们处理个人信息的行为违反法律法规;
+ 2.如果我们收集、使用您的个人信息,却未征得您的同意;
+ 3.如果我们处理个人信息的行为违反了与您的约定;
+ 4.如果您不再使用本平台提供的服务并提出注销账号申请;
+ 5.如果我们不再为您提供本平台或服务。
+ 您可根据本政策载明的联系方式联系我们反馈您的删除个人信息的需求,我们将在15个工作日内响应。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。
+ 当您从我们的服务中删除信息后,我们可能不会立即在备份系统中删除相应的信息,但会在备份更新时删除这些信息。
+ (四)管理您的授权范围
+ 每个业务功能需要一些基本的个人信息才能得以完成。
+ 对于为优化用户体验额外收集的个人信息的收集和使用,您可以随时给予或收回您的授权同意。您可以通过以下方式自行操作:您可以通过删除个人信息、关闭设备功能、更改应用权限等方式,改变您在功能和服务中的授权范围。当您撤回同意后,我们无法继续为您提供撤回同意所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意的决定,不会影响我们此前基于您的同意而开展的个人信息处理。如您在撤回同意时遇到困难,您可以通过根据本政策载明的联系方式联系我们,我们将在15个工作日内回复您的撤回请求。
+ (五)账号注销
+ 本平台未提供在线的注销功能,请您直接根据本政策载明的联系方式与我们联系申请账号注销。
+ 在注销账号前,我们将验证您的个人身份、安全状态、设备信息、仓库状态、订单状态等。
+ 请确保您所申请注销的账号应当是您本人依照《用户协议》的约定创建并由我们提供给您本人的账号。
+ 建议您在注销前自行备份账号相关的所有信息,并请确认与账号相关的所有服务均已进行妥善处理。如您的账号目前仍有未完成订单(包括待发货订单、待收货订单、售后处理中的订单)或仓库未清空(即仓库中含有已购买但未开启的盲盒、或通过开启盲盒获取但未提货或未兑换为积分的物品)的,请您在订单完成后或清空仓库后再提起账号注销申请,否则将无法提交注销申请;如账号内有未使用的积分及其他虚拟权益等,账号注销申请的提交视为您已放弃其全部权益,注销后不得向本平台要求恢复。
+ 如果您的账号涉及争议纠纷,包括但不限于:投诉、举报、诉讼、仲裁、国家有权机关调查等,您理解并同意,我们有权自行决定是否终止账号的注销,而无需另行得到您的同意。
+ 考虑到存在用户因误操作账号注销的情形,我们将自用户提交注销申请之日起提供为期15个工作日的账号申诉期,申诉期间用户登录产品账号即可取消注销申请。如用户未在申诉期间取消注销申请,则申诉期届满后,账号将自动注销,注销过程不可逆的、不可恢复。
+ 您知悉并理解,账号注销后您将无法再使用该账号登录及使用本平台提供的所有服务。但注销账号并不代表账号注销前的账户行为和相关责任得到豁免或减轻。
+ 当注销账号后,我们将对您持有您的个人信息(包括但不限于账号信息、交易记录等)进行删除或匿名化处理,但法律法规另有规定的除外。
+ (六)我们如何响应您的请求
+ 为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
+ 我们将在十五个工作日内做出答复。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视具体情况收取一定成本费用。
+ 对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。
+ 在以下情形中,按照法律法规要求,我们将无法响应您的请求:
+ (1)国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)有充分证据表明您存在主观恶意或滥用权利的;
+ (5)响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;
+ (6)涉及商业秘密的。
+ (七)投诉举报
+ 您可以按照我们公示的制度或联系我们进行投诉或举报。如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索,您可以通过本政策载明的联系方式进行举报,我们核查后会在十五个工作日内反馈您的投诉与举报。
+ (八)访问隐私政策
+ 您可以在本平台中点击右下方的「我的」-「设置」-「隐私政策」后,查看本政策的全部内容。
+ (九)停止运营向您告知权利
+ 如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
+ 六、我们如何处理未成年人的个人信息
+ (一)我们期望父母或监护人指导未成年人使用我们的服务
+ 若您是未满18周岁的未成年人,在使用我们的产品前,应在您的父母或其他监护人监护、指导下共同阅读并同意本政策。如果没有父母或监护人的同意,儿童(不满14周岁)不得私自使用。
+ (二)我们重视保护未成年人个人信息
+ 我们根据国家相关法律法规的规定保护未成年人的个人信息,对于经父母同意而收集未成年人个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享或公开披露此信息。
+ (三)自查与接收反馈
+ 如果我们发现自己在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关数据或对其进行匿名化处理,但法律法规另有规定的除外。同时我们建立了严格的未成年人信息收集使用规则,以保护儿童的个人信息安全,您可以通过阅读《儿童个人信息保护规则》了解更多信息。
+ 若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本政策公示的联系方式与我们联系。
+ 七、我们如何存储个人信息
+ (一)我们在中华人民共和国境内收集和产生的个人信息,将存储在中华人民共和国境内。我们不会将上述信息传输至境外(您通过互联网进行跨境购买商品等个人主动行为除外),如果部分产品涉及跨境业务,我们需要向境外机构传输境内收集的相关个人信息的,我们将会遵循国家相关规定,
+ 征求您的同意,并按照法律法规和相关监管部门的规定执行,并通过签订协议、现场核查等有效措施,要求境外机构为所获得的您的个人信息保密。
+ (二)我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。我们仅在为提供产品服务之目的所必需的期间内保留您的个人信息。超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外,例如《中华人民共和国电子商务法》要求商品和服务信息、交易信息保存时间自交易完成之日起不少于三年,《中华人民共和国网络安全法》要求网络日志的留存时间不少于六个月。
+ 八、我们如何更新本政策
+ 为了给您提供更好的服务,我们会适时对本政策进行修订,该等修订构成本政策的一部分并具有等同于本政策的效力。
+ 如该等修订会导致您在本政策项下权利的实质减损,我们将在变更生效前,通过在页面显著位置公示等方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的政策约束。
+ 九、联系我们
+ (一)我们提供本政策载明的联系渠道供用户向我们反馈处理与个人信息问题相关的投诉、建议、疑问等,我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。
+ (二)如果您对我们的回复不满意,或因签署、履行本政策与我们产生任何争议的,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+ 十、其他
+ (一)本政策中的标题仅为方便及阅读而设,并不影响本政策中任何规定的含义或解释。
+ (二)本政策中所述的我们的产品及相关服务有可能会根据您所使用的终端设备、手机型号、系统版本、软件应用程序版本等因素而有所不同。最终的产品和服务以您所使用的产品及相关服务为准。
+ (三)本政策的全部条款属于《用户协议》重要组成部分之一。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/index.html b/utils/index.html
new file mode 100755
index 0000000..8e468d8
--- /dev/null
+++ b/utils/index.html
@@ -0,0 +1,1113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
隐私政策
+
+
+
+
+
+
+
生效日期:2024年05月01日
+
+ 本《隐私政策》(简称“本政策”)仅适用于厦门正纯科技有限公司及其关联方(简称“我们”)作为运营者的妙趣盲盒产品或服务,包括妙趣盲盒网站和妙趣盲盒移动应用(简称“产品”),不适用于有单独的隐私权政策且未纳入本政策的第三方产品或服务。您使用我们的产品时,我们将于您同意本政策及《用户协议》后,按照本政策收集、使用、存储、传输、转让(如适用)及对外提供您的个人信息。同时,我们会通过本政策向您说明,我们如何为您提供访问、更新、管理和保护您的个人信息的服务。
+
+
+ 本政策与您使用我们的产品关系紧密,我们建议您仔细阅读并理解本政策全部内容,做出您认为适当的选择。如果您未明示同意本政策并开始使用,这将导致我们无法为您提供完整的产品和服务。我们努力用通俗易懂、简明扼要的文字表达,并对本政策中与您的权益存在重大关系的条款,采用粗体字进行标注以提示您注意。请您在使用我们的产品前仔细阅读本政策,确保对其内容特别是加粗内容的含义及相应法律后果已全部知晓并充分理解。您勾选或点击“同意”即视为您接受本政策;您同意本政策在您使用产品的整个过程中均有效。如果您有任何疑问、意见或建议,请通过以下任意一种方式与我们取得联系:
+
+
1.信息保护负责人联系电话:15280116383;
+
2.联系邮箱:648715275@qq.com;
+
3.在线客服:您可在妙趣盲盒移动应用内点击「我的」-「联系客服」联系;
+
4.注册地址及常用办公地址:福建省厦门市思明区前埔路506号502室之一。
+
本政策将帮助您了解以下内容:
+
一、我们如何收集和使用个人信息
+
二、我们如何使用Cookie、同类技术和SDK技术
+
三、我们如何共享、转让、公开披露个人信息
+
四、我们如何保护个人信息
+
五、您的权利
+
六、我们如何处理未成年人的个人信息
+
七、我们如何存储个人信息
+
八、我们如何更新本政策
+
九、联系我们
+
十、其他
+
+ 我们深知个人信息对您的重要性,并会尽全力保护您的个人信息安全可靠。我们致力于维持您对我们的信任,恪守以下原则,保护您的个人信息:权责一致原则、目的明确原则、选择同意原则、最少够用原则、确保安全原则、主体参与原则、公开透明原则等。同时,我们承诺将按业界成熟的安全标准,采取相应的安全保护措施来保护您的个人信息。特别需要指出的是,即使经过您的授权,我们获得了敏感权限,也不会在相关功能或服务不需要时而收集您的信息。请在使用我们的产品前,仔细阅读并了解本政策。
+
+
一、我们如何收集和使用个人信息
+
(一)词语释义
+
+ (1)妙趣盲盒产品或服务是指:我们通过合法拥有并运营的、标注名称包含“妙趣盲盒”的客户端应用程序以及妙趣盲盒官方网站(以下简称“妙趣盲盒”或“本平台”)等,向您提供的产品与服务。关联方是指在现在、将来控制厦门正纯科技有限公司、受厦门正纯科技有限公司控制或与厦门正纯科技有限公司处于共同控制下的法人主体。控制指通过所有权、有投票权的股份、合同、实际运营关联或其他被依法认定的方式直接或间接地拥有影响被控制对象管理/经营的能力。
+
+
+ (2)个人信息是指:以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。本政策个人信息包括姓名、出生日期、身份证件号码、个人生物识别信息、住址、通信通讯联系方式、通信记录和内容、账号密码、财产信息、征信信息、行踪轨迹、住宿信息、健康生理信息、网络身份识别信息、
+ 常用设备信息、交易信息等。
+
+ (3)个人敏感信息是指:一旦泄露、非法提供或滥用可能危害人身和财产安全,极易导致个人名誉、身心健康受到损害或歧视性待遇等的个人信息。本政策中的个人敏感信息包括身份证件号码、邮箱地址、各类密码(口令、保护答案、数字证书)、个人生物识别信息、通信记录和内容、个人健康生理信息、个人财产信息、银行账号、征信信息、行踪轨迹、住宿信息、交易信息、14岁周岁以下(含)儿童的个人信息等。
+
+
+ (4)身份要素是指:产品用于识别您身份的信息要素,例如:您的登录名、密码、短信校验码、电话号码、手机号码、证件号码及个人生物识别信息(例如:指纹信息、脸部信息)。
+
+ (5)非个人信息:通过对个人信息的技术处理(包括但不限于匿名化、去标识化等),使得处理后的信息无法单独或结合其他信息识别到您的个人身份,
+ 且处理后的信息不能被复原,处理后的信息不属于法律意义上您的个人信息。但当个人信息与处理后的信息结合使用期间,这些结合信息将作为您的个人信息按照本政策处理与保护。
+
(二)收集和使用个人信息的场景、目的及所收集的信息
+
我们仅会出于本政策所述的以下目的,在以下场景收集和使用您的个人信息:
+
(1)帮助您成为我们的用户及进行账户管理
+
+ 为注册成为用户并使用我们的产品和服务,您需要提供您手机当前的手机号码进行注册登录。如果您拒绝提供上述信息,您将无法注册妙趣盲盒平台账户,仅可以使用浏览、搜索服务。为了确保我们是在为您本人提供服务,我们可能会根据您提供的上述信息校验您的身份。
+
+
+ 您也可以选择使用第三方账号登录,如您使用微信账号登录的,我们会获取您的微信头像、微信昵称。但您使用第三方账号登录后,仍需要提供手机号进行绑定。
+
+
(2)帮助您完成下单及订单管理
+
+ 当您在本平台订购具体商品时,我们会通过系统为您生成购买该商品的订单。在下单过程中,您需至少提供您的收货人姓名、收货地址、收货人联系电话,对于部分特殊类型的商品您还需要提供该商品所必需的其他信息。
+
+
+ 同时该订单中会载明您所购买的商品信息、具体订单号、订单创建时间、您应支付的金额、您的备注信息。我们收集这些信息是为了帮助您顺利完成交易、保障您的交易安全、便于您查询订单信息、提供客服与售后服务及其他我们明确告知的目的。
+
+
您可以通过妙趣盲盒为其他人订购商品,您需要提供该实际收货人的前述个人信息,并确保已取得该实际收货人的同意。
+
+ 为便于您了解、查询订单信息并对订单信息进行管理,我们会收集您在使用我们服务过程中产生的订单信息用于向您展示及便于您对订单进行管理。
+
+
您可额外填写包括其他联系电话、收货时间在内的更多附加信息以确保商品或服务的准确送达。
+
您可以通过「我的」-「我的订单」查看和管理您的订单信息。
+
(3)帮助您完成支付
+
+ 为完成订单支付,您可通过第三方支付(支付宝/微信)付款。我们会将您的妙趣盲盒平台账户用户名、订单支付相关信息、订单安全相关设备信息及其他反洗钱法律要求的必要信息通过在网站或客户端中嵌入的第三方支付软件工具开发包(软件工具开发包在本政策中简称“SDK”)与第三方支付公司共享。
+
+
为使我们及时获悉并确认您的支付进度及状态,为您提供售后与争议解决服务,您同意我们可自第三方支付公司处收集与支付进度相关信息。
+
+
(4)帮助向您完成商品的交付
+
+ 为保证您购买的商品能够顺利、安全、准确送达、提供,我们会向为妙趣盲盒平台提供物流相关服务的供应商(包括但不限于提供发货服务、快递服务的公司)披露订单相关的配送信息。您知晓并同意相应物流配送主体不可避免地获知及使用您的配送信息,用于完成交付目的。
+
+
+ 为向您提供售后与争议解决服务之目的,我们需要及时获悉并确认交付进度及状态,您同意我们可自物流相关服务主体处收集与交付进度相关的信息。如售后涉及退换货的,您同意向我们提供退货相关物流信息及同意我们可自物流相关服务主体处收集与退货进度相关的信息。
+
+
(5)为您提供客服支持及争议处理
+
当您与我们联系或提出售中、售后、争议纠纷处理申请时,为了保障您的账户及系统安全,我们需要您提供必要的个人信息以核验您的用户身份。
+
+
+ 为便于与您联系、尽快帮助您解决问题或记录相关问题的处理方案及结果,我们可能会保存您与我们的沟通、通信/通话记录及相关内容(包括账户信息、订单信息、您为了证明相关事实提供的其他信息,或您留下的联系方式信息)。如果您针对具体订单进行咨询、投诉或提供建议的,我们会使用您的账户信息和订单信息。
+
+
+ 为优化服务质量,我们可能会获取您的麦克风的权限,以便可以通过语音的方式沟通;我们还可能会获取您的相机及/或照片的权限,以便您向客服提供照片、视频资料。如果您不同意或拒绝授权提供,将无法使用此功能,但不影响您正常使用本平台的其他功能。
+
+
+ 为了提供服务及改进服务质量的合理需要,我们还可能使用的您的其他信息,包括您与客服联系时您提供的相关信息,您参与问卷调查时向我们发送的问卷答复信息。
+
(6)保障产品正常运行
+
+ 当您使用我们的产品时,为了保障产品基础功能及服务能够正常运行,您同意我们根据您在软件安装及使用中授予的具体权限,接收并记录您所使用的设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、苹果唯一设备标识符(IFDA)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)、OAID)、设备所在位置相关信息(如IP
+ 地址、WLAN接入点、SSID、BSSID、蓝牙、基站、地理位置信息)。需要您注意,这些信息是我们提供服务和保障产品正常运行所必须收集的基本信息。
+
+ 我们在应用第一次启动时,将会请求您授权读写外置存储信息权限,以读写外置存储信息。我们必须申请此权限,用于存储您在产品使用过程中产生的数据,拒绝此权限将导致您无法正常使用。
+
(7)保障产品、服务及用户使用安全
+ 为帮助我们更好地实现了解产品运行情况、判断账户安全、进行身份验证、检测及防范安全事件的目的,我们可能记录网络日志信息、应用信息、正在运行的进程信息、应用程序的总体运行、使用情况与频率、应用崩溃情况、总体安装使用情况、性能数据及应用来源等信息:
+
+
①
+ 日志信息:我们会收集您对产品或服务的详细使用情况,作为有关网络日志保存(例如,搜索查询内容、IP地址、浏览器的类型、电信运营商);
+
+
②
+ 其他信息:我们会收集安装的应用信息或正在运行的进程信息、应用程序的总体运行、使用情况与频率、总体安装使用情况、性能数据、应用来源,并可能使用或整合您的用户信息、交易信息、设备信息、有关网络日志信息,进而综合判断您账户及交易风险、进行身份验证、检测及防范安全事件,并依法采取必要的记录、分析措施。
+
+
(8)消息通知及市场推广
+
+ 我们会通过PUSH通知为您提供推荐商品、运营活动等资讯,及向您发出平台公告、平台通知等。为了实现上述目的所必需,确保应用处于关闭或后台运行状态下正常接收到PUSH
+ 通知,我们可能会在合理频率范围内自启动。
+
+ 我们可能会通过短信等形式为向您提供商品、运营活动等资讯,如果您不希望接收上述资讯,您可随时根据短信提示或我们提供的其他方式进行退订。
+
+
需要您注意的是,单独的设备信息、日志信息等是无法识别特定自然人身份的信息,属于非本政策所指“个人信息”。
+
(三)我们直接调用的权限
+
我们承诺决不超范围、超频次搜集您的个人信息,决不搜集与使用本产品服务非必需或无合理应用场景的信息。
+
+ 您在使用本平台时,为提供给您服务之目的,本平台可能在您使用该应用某些场景下向您申请终端设备的如下权限,当然您可以拒绝开启以下权限,或在手机的设置中关闭以下权限,关闭以下权限不会影响您对其他功能的使用。
+
+
我们直接调用的设备权限包括:
+
1、 通知
+
对应业务功能:全部功能
+
调用权限目的:用于接收各类消息
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法接收推送通知
+
2、 无线数据
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
3、 WLAN
+
对应业务功能:全部功能
+
调用权限目的:用于应用程序访问互联网
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法连接网络,影响正常使用
+
4、外置存储
+
对应业务功能:全部功能
+
调用权限目的:用于写入存储用户信息,存储日志等信息,缓存用户图片数据
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:产品无法流畅使用
+
5、相机
+
对应业务功能:客服功能、更换头像功能
+
调用权限目的:读写设备上的照片及文件,用于在客服功能及更换头像功能中上传照片或视频
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法在客服功能及更换头像功能中上传照片或视频
+
6、麦克风
+
对应业务功能:客服功能
+
调用权限目的:用于发送语音消息、实时语音通话
+
是否询问:用户使用相应服务时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法使用麦克风与客服进行语音沟通
+
7、 访问电话状态(仅适用于安卓)
+
对应业务功能:全部功能及安全保障
+
+ 调用权限目的:获取设备相关信息(包括设备序列号、设备硬件型号、操作系统版本号、国际移动设备识别码(IMEI)、国际移动用户识别码(IMSI)、网络设备硬件地址(MAC)、Android设备唯一标识(AndroidID)、移动设备识别码(MEID)),用于保障用户的账户及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中。
+
8、 安装软件包(仅适用于安卓)
+
对应业务功能:安装更新功能
+
调用权限目的:用于本产品软件安装或更新
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户无法正常安装软件
+
9、IFDA获取(仅适用于iOS)
+
对应业务功能:全部功能及安全保障
+
调用权限目的:获取苹果手机唯一设备标识符IFDA,用于保障用户账号及使用安全、验证登录设备与账号是否匹配、一键登录账号
+
+
是否询问:用户首次打开移动客户端时会弹窗询问
+
可否关闭权限:可以关闭
+
如果关闭权限会影响用户什么功能:用户的设备与账号可能处于风险之中、用户无法使用“本机号码一键登录”功能
+
+ 当我们要将个人信息用于本政策未载明的其它用途时,会事先征求您的同意。当我们要将基于特定目的收集而来的信息用于其他目的时,会事先征求您的同意。
+
+
(四)无需征得同意收集和使用的个人信息
+
根据法律法规及相关国家标准,我们在下列任意一种或多种情形下收集和使用您的个人信息无需征得您的授权同意。
+
(1)与国家安全、国防安全直接相关的;
+
(2)与公共安全、公共卫生、重大公共利益直接相关的;
+
(3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+
(4)为应对突发公共卫生事件,或出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到您同意的;
+
(5)所收集的您的个人信息是您自行向社会公众公开的;
+
(6)从合法公开披露的信息中收集的您的个人信息的,如合法的新闻报道、政府信息公开等渠道;
+
(7)根据您的要求签订或履行合同所必需的;
+
(8)用于维护产品的安全稳定运行所必需的,例如发现、处置产品故障;
+
(9)为合法的新闻报道所必需的;
+
+ (10)学术研究机构基于公共利益开展统计或学术研究所必要,且对外提供学术研究或描述的结果时,对结果中所包含的个人信息进行去标识化处理的;
+
+
(11)法律法规规定及相关国家标准的其他情形。
+
二、我们如何使用Cookie、同类技术和SDK技术
+
(一)Cookie
+
+ 为使您获得更轻松的访问体验,您使用我们的产品时,我们可能会通过小型数据文件识别您的身份,这么做可帮您省去重复输入注册信息的步骤,或者帮助判断您的账号安全状态。这些数据文件可能是Cookie。Cookie通常包含标识符、站点名称以及一些号码和字符。您可根据自己的偏好管理或删除Cookie。有关详情,请参见AboutCookies.org。但请注意,如果停用Cookie,您可能无法享受最佳的服务体验,某些服务也可能无法正常使用。
+
+
(二)与Cookie同类技术
+
+ 除Cookie外,我们还会使用网站信标和像素标签等其他同类技术(例如Beacon、Proxy等),但我们不会将Cookie和同类技术用于本政策所述目的之外的任何用途。
+
(三)SDK技术
+
+ 为保证产品相关功能的实现与应用安全稳定的运行,我们可能会接入由第三方服务提供商提供的软件工具开发包(SDK)实现相关目的。我们会对合作获取信息的软件工具开发包(SDK)进行严格的安全监测,以保证数据安全。前述服务商收集和处理信息等行为遵守其自身的隐私条款,而不适用于本政策。为了最大程度保障您的信息安全,我们建议您在使用任何第三方SDK类服务前先行查看其用户协议及隐私条款。为保障您的合法权益,如您发现这等SDK或其他类似的应用程序存在风险时,建议您立即终止相关操作并及时与我们取得联系。
+
+
我们接入的第三方SDK及信息收集目的、场景等包括:
+
1、微信SDK(com.tencent.mm.opensdk)
+
涉及个人信息:分享的图片或内容、微信包名信息
+
使用目的:支持微信登录和分享
+
使用场景:在用户使用微信登录或者分享时使用
+
合作方主体:深圳市腾讯计算机系统有限公司
+
收集方式:SDK自行采集
+
官网链接:https://open.weixin.qq.com/
+
+ 合作方隐私政策:https://support.weixin.qq.com/cgi-bin/mmsupportacctnodeweb-bin/pages/RYiYJkLOrQwu0nb8
+
+
2、Alipay(支付宝)SDK(com.alipay.sdk)
+
涉及个人信息:设备标识符(Android如IMEI、MEID、IMSI、Android
+ ID、硬件序列号/Serial、ICCID、OAID,iOS如IDFV、IDFA)、设备MAC地址、IP地址、WLAN接入点(如SSID、BSSID)、Wi-Fi列表、网络信息、设备信息、软件列表、读取存储信息、支付宝包名信息、传感器列表
+
+
权限调用:存储权限、电话权限
+
使用目的:帮助用户在应用内使用支付宝
+
使用场景:在用户使用支付宝支付时使用
+
合作方主体:支付宝(中国)网络技术有限公司
+
收集方式:SDK自行采集
+
官网链接:https://render.alipay.com/p/f/fd-iwwyijeh/index.html
+
合作方隐私政策:https://docs.open.alipay.com/54
+
3、数字联盟SDK(cn.shuzilm.core)
+
+ 涉及个人信息:设备制造商、设备型号、设备系统版本、应用版本、传感器(光传感器、磁场传感器、重力传感器、压力传感器、方向传感器、旋转矢量传感器、陀螺仪传感器、加速度传感器)、应用信息、通信状态、信号强度、蓝牙信息、设备网络状态信息【包括网络的接入形式、IP地址、WiFi信息(BSSID、SSID)、运营商类型及网络基站信息】、设备物理环境信息、IDFA(儿童类应用不收集)、IDFV、OAID、粗略位置信息、指定包名信息、Android
+ ID、IMEI、IMSI、MEID、设备序列号设备MAC地址、WiFi列表
+
权限调用:粗略位置权限
+
使用目的:安全风控,识别反馈设备的真实性,其中传感器主要用于辅助识别模拟器,虚拟机等虚拟环境及辅助判断作弊场景
+
使用场景:检测设备欺诈与作弊行为时使用
+
合作方主体:北京数字联盟网络科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.shuzilm.cn/
+
合作方隐私政策:https://www.shuzilm.cn/privacy
+
4、LinkedMe SDK(com.microquation.linkedme)
+
涉及个人信息:设备MAC地址、OAID、唯一设备识别码、IP、SD卡数据、指定包名信息、WiFi状态
+
权限调用:粗略位置权限
+
使用目的:推广统计和效果分析,保存分享的图片,识别用户来源
+
使用场景:使用数据分析服务时使用
+
合作方主体:北京微方程科技有限公司
+
收集方式:SDK自行采集
+
官方链接:https://www.linkedme.cc/index.html
+
合作方隐私政策:https://www.linkedme.cc/privacy-policy.html
+
22、Okio (okio)
+ 涉及个人信息:写入存储信息、IP地址
+ 权限获取:存储权限
+ 使用目的:用于配合OkHttp实现,对服务器API发送请求,下载网络文件,访问网页。
+ 使用场景: 网络请求,访问网页。
+ 合作方主体:square
+ 收集方式:SDK自行采集
+ 官网链接:https://square.github.io/okio/
+ 23、Fresco(com.facebook)
+ 涉及个人信息:读写存储信息
+ 权限获取:存储权限
+ 使用目的:用于图片加载显示
+ 使用场景: APP内的所有图片显示。
+ 合作方主体: facebook
+ 收集方式:SDK自行采集
+ 官网链接:https://frescolib.org/
+ 三、我们如何共享、转让、公开披露个人信息
+ (一)如何共享个人信息
+ 我们不会与产品服务相关提供者以外的公司、组织和个人共享您的个人信息。我们可能会与合作伙伴共享您的某些个人信息,以提供更好的客户服务和用户体验。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息,具体情况如下:
+ 1.在获取明确同意的情况下共享:在获得您的明确同意后,我们会与其他方共享您的个人信息。
+ 2.在法定情形下的共享:我们可能会根据法律法规规定、诉讼争议解决需要,或按行政、司法机关依法提出的要求,对外共享您的个人信息。
+ 3.为实现产品功能或服务的共享:您的个人信息可能会与我们的关联公司共享。我们只会共享必要的个人信息,且受本政策中所声明目的的约束。关联公司如要改变个人信息的处理目的,或使用信息的目的超越原授权同意范围,将再次征求您的授权同意。
+ 4.为实现产品安全与分析统计的共享:
+ (1)保障使用安全:为保障您和其他用户的财产安全,使您和我们的正当合法权益免受不法侵害,我们和关联方或服务提供商可能会共享必要的设备、应用、进程、性能、环境及日志等信息。
+ (2)分析产品使用情况:为分析我们服务的使用情况,提升用户使用的体验,可能会与关联方或第三方共享产品使用情况(崩溃、闪退)的统计性数据,这些数据难以与其他信息结合识别您的个人身份。
+ (3)学术研究与科研:为提升相关领域的科研能力,促进科技发展水平,我们在确保数据安全与目的正当的前提下,可能会与科研院所、高校等机构共享去标识化或匿名化的数据。
+ (二)如何转让个人信息
+ 我们不会将您的个人信息转让给任何公司、组织和个人,但以下情况除外:
+ 1.在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的个人信息;
+ 2.在涉及合并、收购、资产转让或破产清算时,如涉及到个人信息转让,我们会在要求新的持有您个人信息的公司、组织继续受本政策的约束,将按照法律法规及不低于本政策所要求的安全标准继续保护或要求个人信息的继受方继续保护您的个人信息,否则我们将要求该公司、组织重新向您征求授权同意。
+ (三)如何披露个人信息
+ 我们仅会在以下情况下,公开披露您的个人信息并会采用符合行业内标准的安全保护措施:
+ (1)获得您明确同意后;
+ (2)基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们可能会公开披露您的个人信息;
+ (3)对违规、欺诈行为进行处罚公告。
+ (四)免征得同意共享、转让、公开披露的个人信息
+ 根据法律法规及国家标准,我们在下列情形中,共享、转让、公开披露您的个人信息无需征得您的授权同意:
+ (1)与国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)为应对突发公共卫生事件,或出于维护您或其他个人的生命、财产等重大合法权益但又很难得到您的同意的;
+ (5)您自行向社会公众公开的个人信息;
+ (6)从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
+ 四、我们如何保护个人信息
+ 本政策提供的如下个人信息保护措施仅适用于我们的产品。一旦您离开我们的产品,浏览或使用其他网站、服务及内容资源,我们即没有能力及义务保护您在我们的产品之外的软件、网站提交的任何个人信息,无论您登录、浏览或使用上述软件、网站是否基于我们的产品的链接或引导。
+ (一)为保障您的信息安全,我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露、毁损、误用、非授权访问、非授权披露和更改的风险。
+ 我们会采取一切合理可行的措施,保护您的个人信息。例如:
+ (1)在您的设备与“产品服务”之间交换数据(如银行信息)时受SSL加密保护;
+ (2)我们会使用加密技术确保数据的保密性;
+ (3)我们会使用受信赖的保护机制防止数据遭到恶意攻击;
+ (4)我们会部署访问控制机制,确保只有授权人员才可访问个人信息;
+ (5)我们会举办安全和隐私保护培训课程,加强员工对于保护个人信息重要性的认识;
+ (6)我们认为其他的合理可行的保护措施。
+ (二)我们会建立专门的安全部门、安全管理制度、数据安全流程保障您的个人信息安全。我们采取严格的数据使用和访问制度,确保只有授权人员才可访问您的个人信息,并适时对数据和技术进行安全审计。
+ (三)我们会使用不低于行业同行的加密技术、匿名化处理等合理可行的手段保护您的个人信息,并使用安全保护机制防止您的个人信息遭到恶意攻击。
+ (四)我们会采取一切合理可行的措施,确保未收集无关的个人信息。
+ (五)我们将不定期更新并公开安全风险、个人信息安全影响评估等报告的有关内容。
+ (六)尽管已经采取了上述合理有效措施,并已经遵守了相关法律法规要求的标准,但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全,我们将尽力确保或担保您发送给我们的任何信息的安全性。如果我们的物理、技术、或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改、或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
+ 您知悉并理解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。因此,我们强烈建议您采取积极措施保护个人信息的安全,包括但不限于使用复杂密码、定期修改密码、不将自己的账号密码及相关个人信息透露给他人等。
+ (七)在不幸发生个人信息安全事件后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们将及时将事件相关情况以邮件、电话、推送通知等方式告知您,
+ 难以逐一告知个人信息主体时,我们会采取合理、有效的方式发布公告。我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况。
+ 五、您的权利
+ (一)访问您的个人信息
+ 您有权访问您的个人信息,法律法规规定的例外情况除外。如果您想行使数据访问权,可以通过以下方式自行访问:
+ 如果您希望访问您的账号中的个人资料信息,您可以通过本平台中点击右下方的「我的」查看;如果您希望访问您的账号中的收件地址信息,您可以通过本平台中点击右下方的「我的」-「地址管理」查看及编辑。
+ 如果您无法通过上述方式访问上述个人信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (二)更正您的个人信息
+ 一般情况下,您可以随时更正您的个人信息。
+ 但出于安全性、身份识别、交易安全的考虑,您不能随时自主修改手机号码信息、订单的收货信息及实名认证信息;如您确有必要修改该类信息,请您根据本政策载明的联系方式联系我们,我们将在15个工作日内响应。
+ (三)删除您的个人信息
+ 在以下情形中,您可以向我们提出删除个人信息的请求:
+ 1.如果我们处理个人信息的行为违反法律法规;
+ 2.如果我们收集、使用您的个人信息,却未征得您的同意;
+ 3.如果我们处理个人信息的行为违反了与您的约定;
+ 4.如果您不再使用本平台提供的服务并提出注销账号申请;
+ 5.如果我们不再为您提供本平台或服务。
+ 您可根据本政策载明的联系方式联系我们反馈您的删除个人信息的需求,我们将在15个工作日内响应。若我们决定响应您的删除请求,我们还将同时通知从我们获得您的个人信息的实体,要求其及时删除,除非法律法规另有规定,或这些实体获得您的独立授权。
+ 当您从我们的服务中删除信息后,我们可能不会立即在备份系统中删除相应的信息,但会在备份更新时删除这些信息。
+ (四)管理您的授权范围
+ 每个业务功能需要一些基本的个人信息才能得以完成。
+ 对于为优化用户体验额外收集的个人信息的收集和使用,您可以随时给予或收回您的授权同意。您可以通过以下方式自行操作:您可以通过删除个人信息、关闭设备功能、更改应用权限等方式,改变您在功能和服务中的授权范围。当您撤回同意后,我们无法继续为您提供撤回同意所对应的功能和服务,也不再处理您相应的个人信息。但您撤回同意的决定,不会影响我们此前基于您的同意而开展的个人信息处理。如您在撤回同意时遇到困难,您可以通过根据本政策载明的联系方式联系我们,我们将在15个工作日内回复您的撤回请求。
+ (五)账号注销
+ 本平台未提供在线的注销功能,请您直接根据本政策载明的联系方式与我们联系申请账号注销。
+ 在注销账号前,我们将验证您的个人身份、安全状态、设备信息、仓库状态、订单状态等。
+ 请确保您所申请注销的账号应当是您本人依照《用户协议》的约定创建并由我们提供给您本人的账号。
+ 建议您在注销前自行备份账号相关的所有信息,并请确认与账号相关的所有服务均已进行妥善处理。如您的账号目前仍有未完成订单(包括待发货订单、待收货订单、售后处理中的订单)或仓库未清空(即仓库中含有已购买但未开启的盲盒、或通过开启盲盒获取但未提货或未兑换为积分的物品)的,请您在订单完成后或清空仓库后再提起账号注销申请,否则将无法提交注销申请;如账号内有未使用的积分及其他虚拟权益等,账号注销申请的提交视为您已放弃其全部权益,注销后不得向本平台要求恢复。
+ 如果您的账号涉及争议纠纷,包括但不限于:投诉、举报、诉讼、仲裁、国家有权机关调查等,您理解并同意,我们有权自行决定是否终止账号的注销,而无需另行得到您的同意。
+ 考虑到存在用户因误操作账号注销的情形,我们将自用户提交注销申请之日起提供为期15个工作日的账号申诉期,申诉期间用户登录产品账号即可取消注销申请。如用户未在申诉期间取消注销申请,则申诉期届满后,账号将自动注销,注销过程不可逆的、不可恢复。
+ 您知悉并理解,账号注销后您将无法再使用该账号登录及使用本平台提供的所有服务。但注销账号并不代表账号注销前的账户行为和相关责任得到豁免或减轻。
+ 当注销账号后,我们将对您持有您的个人信息(包括但不限于账号信息、交易记录等)进行删除或匿名化处理,但法律法规另有规定的除外。
+ (六)我们如何响应您的请求
+ 为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
+ 我们将在十五个工作日内做出答复。对于您合理的请求,我们原则上不收取费用,但对多次重复、超出合理限度的请求,我们将视具体情况收取一定成本费用。
+ 对于那些无端重复、需要过多技术手段(例如,需要开发新系统或从根本上改变现行惯例)、给他人合法权益带来风险或者非常不切实际的请求,我们可能会予以拒绝。
+ 在以下情形中,按照法律法规要求,我们将无法响应您的请求:
+ (1)国家安全、国防安全直接相关的;
+ (2)与公共安全、公共卫生、重大公共利益直接相关的;
+ (3)与犯罪侦查、起诉、审判和判决执行等直接相关的;
+ (4)有充分证据表明您存在主观恶意或滥用权利的;
+ (5)响应您的请求将导致您或其他个人、组织的合法权益受到严重损害的;
+ (6)涉及商业秘密的。
+ (七)投诉举报
+ 您可以按照我们公示的制度或联系我们进行投诉或举报。如果您认为您的个人信息权利可能受到侵害,或者发现侵害个人信息权利的线索,您可以通过本政策载明的联系方式进行举报,我们核查后会在十五个工作日内反馈您的投诉与举报。
+ (八)访问隐私政策
+ 您可以在本平台中点击右下方的「我的」-「设置」-「隐私政策」后,查看本政策的全部内容。
+ (九)停止运营向您告知权利
+ 如我们停止运营,我们将及时停止收集您个人信息的活动,将停止运营的通知以逐一送达或公告的形式通知您,并对所持有的您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外。
+ 六、我们如何处理未成年人的个人信息
+ (一)我们期望父母或监护人指导未成年人使用我们的服务
+ 若您是未满18周岁的未成年人,在使用我们的产品前,应在您的父母或其他监护人监护、指导下共同阅读并同意本政策。如果没有父母或监护人的同意,儿童(不满14周岁)不得私自使用。
+ (二)我们重视保护未成年人个人信息
+ 我们根据国家相关法律法规的规定保护未成年人的个人信息,对于经父母同意而收集未成年人个人信息的情况,我们只会在受到法律允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享或公开披露此信息。
+ (三)自查与接收反馈
+ 如果我们发现自己在未事先获得可证实的父母同意的情况下收集了未成年人的个人信息,则会设法尽快删除相关数据或对其进行匿名化处理,但法律法规另有规定的除外。同时我们建立了严格的未成年人信息收集使用规则,以保护儿童的个人信息安全,您可以通过阅读《儿童个人信息保护规则》了解更多信息。
+ 若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过本政策公示的联系方式与我们联系。
+ 七、我们如何存储个人信息
+ (一)我们在中华人民共和国境内收集和产生的个人信息,将存储在中华人民共和国境内。我们不会将上述信息传输至境外(您通过互联网进行跨境购买商品等个人主动行为除外),如果部分产品涉及跨境业务,我们需要向境外机构传输境内收集的相关个人信息的,我们将会遵循国家相关规定,
+ 征求您的同意,并按照法律法规和相关监管部门的规定执行,并通过签订协议、现场核查等有效措施,要求境外机构为所获得的您的个人信息保密。
+ (二)我们只会在达成本政策所述目的所需的期限内保留您的个人信息,除非需要延长保留期或受到法律的允许。我们仅在为提供产品服务之目的所必需的期间内保留您的个人信息。超出必要期限后,我们将对您的个人信息进行删除或匿名化处理,但法律法规另有规定的除外,例如《中华人民共和国电子商务法》要求商品和服务信息、交易信息保存时间自交易完成之日起不少于三年,《中华人民共和国网络安全法》要求网络日志的留存时间不少于六个月。
+ 八、我们如何更新本政策
+ 为了给您提供更好的服务,我们会适时对本政策进行修订,该等修订构成本政策的一部分并具有等同于本政策的效力。
+ 如该等修订会导致您在本政策项下权利的实质减损,我们将在变更生效前,通过在页面显著位置公示等方式通知您。在该种情况下,若您继续使用我们的服务,即表示同意受经修订的政策约束。
+ 九、联系我们
+ (一)我们提供本政策载明的联系渠道供用户向我们反馈处理与个人信息问题相关的投诉、建议、疑问等,我们将尽快审核所涉问题,并在验证您的用户身份后的十五个工作日内回复。
+ (二)如果您对我们的回复不满意,或因签署、履行本政策与我们产生任何争议的,您同意提交厦门仲裁委员会按照本会仲裁规则进行仲裁。仲裁裁决是终局的,对双方均有约束力。
+ 十、其他
+ (一)本政策中的标题仅为方便及阅读而设,并不影响本政策中任何规定的含义或解释。
+ (二)本政策中所述的我们的产品及相关服务有可能会根据您所使用的终端设备、手机型号、系统版本、软件应用程序版本等因素而有所不同。最终的产品和服务以您所使用的产品及相关服务为准。
+ (三)本政策的全部条款属于《用户协议》重要组成部分之一。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/jq.js b/utils/jq.js
new file mode 100644
index 0000000..450a1a8
--- /dev/null
+++ b/utils/jq.js
@@ -0,0 +1,9814 @@
+/*!
+ * jQuery JavaScript Library v2.2.4
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-05-20T17:23Z
+ */
+
+(function( global, factory ) {
+
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // For CommonJS and CommonJS-like environments where a proper `window`
+ // is present, execute the factory and get jQuery.
+ // For environments that do not have a `window` with a `document`
+ // (such as Node.js), expose a factory as module.exports.
+ // This accentuates the need for the creation of a real `window`.
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket #14549 for more info.
+ module.exports = global.document ?
+ factory( global, true ) :
+ function( w ) {
+ if ( !w.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+ }
+ return factory( w );
+ };
+ } else {
+ factory( global );
+ }
+
+// Pass this if window is not defined yet
+}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Support: Firefox 18+
+// Can't be in strict mode, several libs including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+//"use strict";
+var arr = [];
+
+var document = window.document;
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var support = {};
+
+
+
+var
+ version = "2.2.4",
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Support: Android<4.1
+ // Make sure we trim BOM and NBSP
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+ // Matches dashed string for camelizing
+ rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([\da-z])/gi,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn = jQuery.prototype = {
+
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // Start with an empty selector
+ selector: "",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ toArray: function() {
+ return slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num != null ?
+
+ // Return just the one element from the set
+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+
+ // Return all the elements in a clean array
+ slice.call( this );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+ ret.context = this.context;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ each: function( callback ) {
+ return jQuery.each( this, callback );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ } ) );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor();
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[ 0 ] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+
+ // Skip the boolean and the target
+ target = arguments[ i ] || {};
+ i++;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+ target = {};
+ }
+
+ // Extend jQuery itself if only one argument is passed
+ if ( i === length ) {
+ target = this;
+ i--;
+ }
+
+ for ( ; i < length; i++ ) {
+
+ // Only deal with non-null/undefined values
+ if ( ( options = arguments[ i ] ) != null ) {
+
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
+
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray( src ) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject( src ) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend( {
+
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ noop: function() {},
+
+ isFunction: function( obj ) {
+ return jQuery.type( obj ) === "function";
+ },
+
+ isArray: Array.isArray,
+
+ isWindow: function( obj ) {
+ return obj != null && obj === obj.window;
+ },
+
+ isNumeric: function( obj ) {
+
+ // parseFloat NaNs numeric-cast false positives (null|true|false|"")
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+ // subtraction forces infinities to NaN
+ // adding 1 corrects loss of precision from parseFloat (#15100)
+ var realStringObj = obj && obj.toString();
+ return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
+ },
+
+ isPlainObject: function( obj ) {
+ var key;
+
+ // Not plain objects:
+ // - Any object or value whose internal [[Class]] property is not "[object Object]"
+ // - DOM nodes
+ // - window
+ if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call( obj, "constructor" ) &&
+ !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ var name;
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ type: function( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android<4.0, iOS<6 (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+ },
+
+ // Evaluates a script in a global context
+ globalEval: function( code ) {
+ var script,
+ indirect = eval;
+
+ code = jQuery.trim( code );
+
+ if ( code ) {
+
+ // If the code includes a valid, prologue position
+ // strict mode pragma, execute code by injecting a
+ // script tag into the document.
+ if ( code.indexOf( "use strict" ) === 1 ) {
+ script = document.createElement( "script" );
+ script.text = code;
+ document.head.appendChild( script ).parentNode.removeChild( script );
+ } else {
+
+ // Otherwise, avoid the DOM node creation, insertion
+ // and removal by using an indirect global eval
+
+ indirect( code );
+ }
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Support: IE9-11+
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+ },
+
+ each: function( obj, callback ) {
+ var length, i = 0;
+
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // Support: Android<4.1
+ trim: function( text ) {
+ return text == null ?
+ "" :
+ ( text + "" ).replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArrayLike( Object( arr ) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, invert ) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ callbackInverse = !callback( elems[ i ], i );
+ if ( callbackInverse !== callbackExpect ) {
+ matches.push( elems[ i ] );
+ }
+ }
+
+ return matches;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var length, value,
+ i = 0,
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ var tmp, args, proxy;
+
+ if ( typeof context === "string" ) {
+ tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ args = slice.call( arguments, 2 );
+ proxy = function() {
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ now: Date.now,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+} );
+
+// JSHint would error on this code due to the Symbol not being defined in ES5.
+// Defining this global in .jshintrc would create a danger of using the global
+// unguarded in another place, it seems safer to just disable JSHint for these
+// three lines.
+/* jshint ignore: start */
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+/* jshint ignore: end */
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+ // Support: iOS 8.2 (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = jQuery.type( obj );
+
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.2.1
+ * http://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-10-17
+ */
+(function( window ) {
+
+var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ tokenize,
+ compile,
+ select,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+
+ // Instance-specific data
+ expando = "sizzle" + 1 * new Date(),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ },
+
+ // General-purpose constants
+ MAX_NEGATIVE = 1 << 31,
+
+ // Instance methods
+ hasOwn = ({}).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ push_native = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf as it's faster than native
+ // http://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
+ var i = 0,
+ len = list.length;
+ for ( ; i < len; i++ ) {
+ if ( list[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+ // Regular expressions
+
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+ "*\\]",
+
+ pseudos = ":(" + identifier + ")(?:\\((" +
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+ // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+ // 3. anything else (capture 2)
+ ".*" +
+ ")\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rnative = /^[^{]+\{\s*\[native \w/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rsibling = /[+~]/,
+ rescape = /'|\\/g,
+
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+ funescape = function( _, escaped, escapedWhitespace ) {
+ var high = "0x" + escaped - 0x10000;
+ // NaN means non-codepoint
+ // Support: Firefox<24
+ // Workaround erroneous numeric interpretation of +"0x"
+ return high !== high || escapedWhitespace ?
+ escaped :
+ high < 0 ?
+ // BMP codepoint
+ String.fromCharCode( high + 0x10000 ) :
+ // Supplemental Plane codepoint (surrogate pair)
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
+ };
+
+// Optimize for push.apply( _, NodeList )
+try {
+ push.apply(
+ (arr = slice.call( preferredDoc.childNodes )),
+ preferredDoc.childNodes
+ );
+ // Support: Android<4.0
+ // Detect silently failing push.apply
+ arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+ push = { apply: arr.length ?
+
+ // Leverage slice if possible
+ function( target, els ) {
+ push_native.apply( target, slice.call(els) );
+ } :
+
+ // Support: IE<9
+ // Otherwise append directly
+ function( target, els ) {
+ var j = target.length,
+ i = 0;
+ // Can't trust NodeList.length
+ while ( (target[j++] = els[i++]) ) {}
+ target.length = j - 1;
+ }
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ var m, i, elem, nid, nidselect, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
+
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+
+ results = results || [];
+
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+ return results;
+ }
+
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+ // ID selector
+ if ( (m = match[1]) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( (elem = context.getElementById( m )) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && (elem = newContext.getElementById( m )) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
+
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Type selector
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Class selector
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !compilerCache[ selector + " " ] &&
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+ if ( nodeType !== 1 ) {
+ newContext = context;
+ newSelector = selector;
+
+ // qSA looks outside Element context, which is not what we want
+ // Thanks to Andrew Dupont for this workaround technique
+ // Support: IE <=8
+ // Exclude object elements
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( (nid = context.getAttribute( "id" )) ) {
+ nid = nid.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", (nid = expando) );
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
+ while ( i-- ) {
+ groups[i] = nidselect + " " + toSelector( groups[i] );
+ }
+ newSelector = groups.join( "," );
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var keys = [];
+
+ function cache( key, value ) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return (cache[ key + " " ] = value);
+ }
+ return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return !!fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if ( div.parentNode ) {
+ div.parentNode.removeChild( div );
+ }
+ // release memory in IE
+ div = null;
+ }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+ var arr = attrs.split("|"),
+ i = arr.length;
+
+ while ( i-- ) {
+ Expr.attrHandle[ arr[i] ] = handler;
+ }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
+ ( ~a.sourceIndex || MAX_NEGATIVE );
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( (cur = cur.nextSibling) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+ var hasCompare, parent,
+ doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // Return early if doc is invalid or already selected
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Update global variables
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
+
+ // Support: IE 9-11, Edge
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ if ( (parent = document.defaultView) && parent.top !== parent ) {
+ // Support: IE 11
+ if ( parent.addEventListener ) {
+ parent.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
+ } else if ( parent.attachEvent ) {
+ parent.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+ support.attributes = assert(function( div ) {
+ div.className = "i";
+ return !div.getAttribute("className");
+ });
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert(function( div ) {
+ div.appendChild( document.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ });
+
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert(function( div ) {
+ docElem.appendChild( div ).id = expando;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
+ });
+
+ // ID find and filter
+ if ( support.getById ) {
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var m = context.getElementById( id );
+ return m ? [ m ] : [];
+ }
+ };
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ } else {
+ // Support: IE6/7
+ // getElementById is not reliable as a find shortcut
+ delete Expr.find["ID"];
+
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
+ }
+ } :
+
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Class
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See http://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ docElem.appendChild( div ).innerHTML = " " +
+ "" +
+ " ";
+
+ // Support: IE8, Opera 11-12.16
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ // The test attribute must be unknown in Opera but "safe" for WinRT
+ // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+ if ( div.querySelectorAll("[msallowcapture^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push("~=");
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibing-combinator selector` fails
+ if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push(".#.+[+~]");
+ }
+ });
+
+ assert(function( div ) {
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = document.createElement("input");
+ input.setAttribute( "type", "hidden" );
+ div.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( div.querySelectorAll("[name=d]").length ) {
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ div.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+ docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( div, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ });
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+ /* Contains
+ ---------------------------------------------------------------------- */
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+ // Element contains another
+ // Purposefully self-exclusive
+ // As in, an element does not contain itself
+ contains = hasCompare || rnative.test( docElem.contains ) ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ));
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ /* Sorting
+ ---------------------------------------------------------------------- */
+
+ // Document order sorting
+ sortOrder = hasCompare ?
+ function( a, b ) {
+
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
+
+ // Calculate position if both inputs belong to the same document
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
+
+ // Otherwise we know they are disconnected
+ 1;
+
+ // Disconnected nodes
+ if ( compare & 1 ||
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+ // Choose the first element that is related to our preferred document
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ return -1;
+ }
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } :
+ function( a, b ) {
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Parentless nodes are either documents or disconnected
+ if ( !aup || !bup ) {
+ return a === document ? -1 :
+ b === document ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( (cur = cur.parentNode) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( (cur = cur.parentNode) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[i] === bp[i] ) {
+ i++;
+ }
+
+ return i ?
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[i], bp[i] ) :
+
+ // Otherwise nodes in our document sort first
+ ap[i] === preferredDoc ? -1 :
+ bp[i] === preferredDoc ? 1 :
+ 0;
+ };
+
+ return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ if ( support.matchesSelector && documentIsHTML &&
+ !compilerCache[ expr + " " ] &&
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch (e) {}
+ }
+
+ return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+ // Set document vars if needed
+ if ( ( context.ownerDocument || context ) !== document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ fn( elem, name, !documentIsHTML ) :
+ undefined;
+
+ return val !== undefined ?
+ val :
+ support.attributes || !documentIsHTML ?
+ elem.getAttribute( name ) :
+ (val = elem.getAttributeNode(name)) && val.specified ?
+ val.value :
+ null;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice( 0 );
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem === results[ i ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+ sortInput = null;
+
+ return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+ // If no nodeType, this is expected to be an array
+ while ( (node = elem[i++]) ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ attrHandle: {},
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
+ // nth-* requires argument
+ if ( !match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[6] && match[2];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[3] ) {
+ match[2] = match[4] || match[5] || "";
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ match[0] = match[0].slice( 0, excess );
+ match[2] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeNameSelector ) {
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+ return nodeNameSelector === "*" ?
+ function() { return true; } :
+ function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+ classCache( className, function( elem ) {
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+ });
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, what, argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, context, xml ) {
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( (node = node[ dir ]) ) {
+ if ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) {
+
+ return false;
+ }
+ }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+
+ // Seek `elem` from a previously-cached index
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ } else {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) &&
+ ++diff ) {
+
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ uniqueCache[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ // Don't keep the element (issue #299)
+ input[0] = null;
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ text = text.replace( runescape, funescape );
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+ // lang value must be a valid identifier
+ if ( !ridentifier.test(lang || "") ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( (elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ return false;
+ };
+ }),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+
+ // Boolean properties
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+
+ // Support: IE<8
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo(function() {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[0].length ) || soFar;
+ }
+ groups.push( (tokens = []) );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace( rtrim, " " )
+ });
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match ))) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ type: type,
+ matches: match
+ });
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[i].value;
+ }
+ return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ checkNonElements = base && dir === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, uniqueCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+ if ( xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+ if ( (oldCache = uniqueCache[ dir ]) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+ // Assign to newCache so results back-propagate to previous elements
+ return (newCache[ 2 ] = oldCache[ 2 ]);
+ } else {
+ // Reuse newcache so results back-propagate to previous elements
+ uniqueCache[ dir ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results );
+ }
+ return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( (elem = temp[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( (matcherIn[i] = elem) );
+ }
+ }
+ postFinder( null, (matcherOut = []), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) &&
+ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ } else {
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+ ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+ len = elems.length;
+
+ if ( outermost ) {
+ outermostContext = context === document || context || outermost;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+ if ( !context && elem.ownerDocument !== document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context || document, xml) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( (matcher = setMatchers[j++]) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !match ) {
+ match = tokenize( selector );
+ }
+ i = match.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( match[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+ // Save selector and tokenization
+ cached.selector = selector;
+ }
+ return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+ results = results || [];
+
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
+
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ support.getById && context.nodeType === 9 && documentIsHTML &&
+ Expr.relative[ tokens[1].type ] ) {
+
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ if ( !context ) {
+ return results;
+
+ // Precompiled matchers will still verify ancestry, so step up a level
+ } else if ( compiled ) {
+ context = context.parentNode;
+ }
+
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( runescape, funescape ),
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+ ( compiled || compile( selector, match ) )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+ // Should return 1, but returns 4 (following)
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+ div.innerHTML = " ";
+ return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+ div.innerHTML = " ";
+ div.firstChild.setAttribute( "value", "" );
+ return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+ addHandle( "value", function( elem, name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+ return div.getAttribute("disabled") == null;
+}) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return elem[ name ] === true ? name.toLowerCase() :
+ (val = elem.getAttributeNode( name )) && val.specified ?
+ val.value :
+ null;
+ }
+ });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+
+var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+};
+
+
+var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ /* jshint -W018 */
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+
+ }
+
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+
+ }
+
+ if ( typeof qualifier === "string" ) {
+ if ( risSimple.test( qualifier ) ) {
+ return jQuery.filter( qualifier, elements, not );
+ }
+
+ qualifier = jQuery.filter( qualifier, elements );
+ }
+
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 && elem.nodeType === 1 ?
+ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+};
+
+jQuery.fn.extend( {
+ find: function( selector ) {
+ var i,
+ len = this.length,
+ ret = [],
+ self = this;
+
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ } ) );
+ }
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ // Needed because $( selector, context ) becomes $( context ).find( selector )
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+ ret.selector = this.selector ? this.selector + " " + selector : selector;
+ return ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], false ) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], true ) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
+
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+} );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+ init = jQuery.fn.init = function( selector, context, root ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[ 0 ] === "<" &&
+ selector[ selector.length - 1 ] === ">" &&
+ selector.length >= 3 ) {
+
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && ( match[ 1 ] || !context ) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
+
+ // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[ 1 ],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+
+ // Properties of context are called as methods if possible
+ if ( jQuery.isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[ 2 ] );
+
+ // Support: Blackberry 4.6
+ // gEBID returns nodes no longer in the document (#6963)
+ if ( elem && elem.parentNode ) {
+
+ // Inject the element directly into the jQuery object
+ this.length = 1;
+ this[ 0 ] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || root ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this.context = this[ 0 ] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return root.ready !== undefined ?
+ root.ready( selector ) :
+
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ if ( selector.selector !== undefined ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
+ }
+ }
+ } );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( pos ?
+ pos.index( cur ) > -1 :
+
+ // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+ matched.push( cur );
+ break;
+ }
+ }
+ }
+
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+ },
+
+ // Determine the position of an element within the set
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // Index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter( selector )
+ );
+ }
+} );
+
+function sibling( cur, dir ) {
+ while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+ return cur;
+}
+
+jQuery.each( {
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return elem.contentDocument || jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
+
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
+ }
+
+ if ( this.length > 1 ) {
+
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.uniqueSort( matched );
+ }
+
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack( matched );
+ };
+} );
+var rnotwhite = ( /\S+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+ var object = {};
+ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+ object[ flag ] = true;
+ } );
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ?
+ createOptions( options ) :
+ jQuery.extend( {}, options );
+
+ var // Flag to know if list is currently firing
+ firing,
+
+ // Last fire value for non-forgettable lists
+ memory,
+
+ // Flag to know if list was already fired
+ fired,
+
+ // Flag to prevent firing
+ locked,
+
+ // Actual callback list
+ list = [],
+
+ // Queue of execution data for repeatable lists
+ queue = [],
+
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+
+ // Fire callbacks
+ fire = function() {
+
+ // Enforce single-firing
+ locked = options.once;
+
+ // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+ fired = firing = true;
+ for ( ; queue.length; firingIndex = -1 ) {
+ memory = queue.shift();
+ while ( ++firingIndex < list.length ) {
+
+ // Run callback and check for early termination
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+ options.stopOnFalse ) {
+
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
+ }
+ }
+
+ // Forget the data if we're done with it
+ if ( !options.memory ) {
+ memory = false;
+ }
+
+ firing = false;
+
+ // Clean up if we're done firing for good
+ if ( locked ) {
+
+ // Keep an empty list if we have data for future add calls
+ if ( memory ) {
+ list = [];
+
+ // Otherwise, this object is spent
+ } else {
+ list = "";
+ }
+ }
+ },
+
+ // Actual Callbacks object
+ self = {
+
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+
+ // If we have memory from a past run, we should fire after adding
+ if ( memory && !firing ) {
+ firingIndex = list.length - 1;
+ queue.push( memory );
+ }
+
+ ( function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ if ( jQuery.isFunction( arg ) ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
+
+ // Inspect recursively
+ add( arg );
+ }
+ } );
+ } )( arguments );
+
+ if ( memory && !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Remove a callback from the list
+ remove: function() {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+
+ // Handle firing indexes
+ if ( index <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ } );
+ return this;
+ },
+
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function( fn ) {
+ return fn ?
+ jQuery.inArray( fn, list ) > -1 :
+ list.length > 0;
+ },
+
+ // Remove all callbacks from the list
+ empty: function() {
+ if ( list ) {
+ list = [];
+ }
+ return this;
+ },
+
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
+ disable: function() {
+ locked = queue = [];
+ list = memory = "";
+ return this;
+ },
+ disabled: function() {
+ return !list;
+ },
+
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
+ lock: function() {
+ locked = queue = [];
+ if ( !memory ) {
+ list = memory = "";
+ }
+ return this;
+ },
+ locked: function() {
+ return !!locked;
+ },
+
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( !locked ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ queue.push( args );
+ if ( !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!fired;
+ }
+ };
+
+ return self;
+};
+
+
+jQuery.extend( {
+
+ Deferred: function( func ) {
+ var tuples = [
+
+ // action, add listener, listener list, final state
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
+ [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+ return jQuery.Deferred( function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
+ deferred[ tuple[ 1 ] ]( function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise()
+ .progress( newDefer.notify )
+ .done( newDefer.resolve )
+ .fail( newDefer.reject );
+ } else {
+ newDefer[ tuple[ 0 ] + "With" ](
+ this === promise ? newDefer.promise() : this,
+ fn ? [ returned ] : arguments
+ );
+ }
+ } );
+ } );
+ fns = null;
+ } ).promise();
+ },
+
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
+ }
+ },
+ deferred = {};
+
+ // Keep pipe for back-compat
+ promise.pipe = promise.then;
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 3 ];
+
+ // promise[ done | fail | progress ] = list.add
+ promise[ tuple[ 1 ] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add( function() {
+
+ // state = [ resolved | rejected ]
+ state = stateString;
+
+ // [ reject_list | resolve_list ].disable; progress_list.lock
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+ }
+
+ // deferred[ resolve | reject | notify ]
+ deferred[ tuple[ 0 ] ] = function() {
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
+ return this;
+ };
+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+ } );
+
+ // Make the deferred a promise
+ promise.promise( deferred );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( subordinate /* , ..., subordinateN */ ) {
+ var i = 0,
+ resolveValues = slice.call( arguments ),
+ length = resolveValues.length,
+
+ // the count of uncompleted subordinates
+ remaining = length !== 1 ||
+ ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+ // the master Deferred.
+ // If resolveValues consist of only a single Deferred, just use that.
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+ // Update function for both resolve and progress values
+ updateFunc = function( i, contexts, values ) {
+ return function( value ) {
+ contexts[ i ] = this;
+ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+ if ( values === progressValues ) {
+ deferred.notifyWith( contexts, values );
+ } else if ( !( --remaining ) ) {
+ deferred.resolveWith( contexts, values );
+ }
+ };
+ },
+
+ progressValues, progressContexts, resolveContexts;
+
+ // Add listeners to Deferred subordinates; treat others as resolved
+ if ( length > 1 ) {
+ progressValues = new Array( length );
+ progressContexts = new Array( length );
+ resolveContexts = new Array( length );
+ for ( ; i < length; i++ ) {
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+ resolveValues[ i ].promise()
+ .progress( updateFunc( i, progressContexts, progressValues ) )
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
+ .fail( deferred.reject );
+ } else {
+ --remaining;
+ }
+ }
+ }
+
+ // If we're not waiting on anything, resolve the master
+ if ( !remaining ) {
+ deferred.resolveWith( resolveContexts, resolveValues );
+ }
+
+ return deferred.promise();
+ }
+} );
+
+
+// The deferred used on DOM ready
+var readyList;
+
+jQuery.fn.ready = function( fn ) {
+
+ // Add the callback
+ jQuery.ready.promise().done( fn );
+
+ return this;
+};
+
+jQuery.extend( {
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+
+ // Abort if there are pending holds or we're already ready
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+ return;
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ jQuery( document ).off( "ready" );
+ }
+ }
+} );
+
+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed );
+ window.removeEventListener( "load", completed );
+ jQuery.ready();
+}
+
+jQuery.ready.promise = function( obj ) {
+ if ( !readyList ) {
+
+ readyList = jQuery.Deferred();
+
+ // Catch cases where $(document).ready() is called
+ // after the browser event has already occurred.
+ // Support: IE9-10 only
+ // Older IE sometimes signals "interactive" too soon
+ if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+ } else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+ }
+ }
+ return readyList.promise( obj );
+};
+
+// Kick off the DOM ready check even if the user does not
+jQuery.ready.promise();
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( jQuery.type( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !jQuery.isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < len; i++ ) {
+ fn(
+ elems[ i ], key, raw ?
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
+ }
+ }
+ }
+
+ return chainable ?
+ elems :
+
+ // Gets
+ bulk ?
+ fn.call( elems ) :
+ len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+var acceptData = function( owner ) {
+
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ /* jshint -W018 */
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+ register: function( owner, initial ) {
+ var value = initial || {};
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable, non-writable property
+ // configurability must be true to allow the property to be
+ // deleted with the delete operator
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ writable: true,
+ configurable: true
+ } );
+ }
+ return owner[ this.expando ];
+ },
+ cache: function( owner ) {
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( !acceptData( owner ) ) {
+ return {};
+ }
+
+ // Check if the owner object already has a cache
+ var value = owner[ this.expando ];
+
+ // If not, create one
+ if ( !value ) {
+ value = {};
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( acceptData( owner ) ) {
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ configurable: true
+ } );
+ }
+ }
+ }
+
+ return value;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ cache = this.cache( owner );
+
+ // Handle: [ owner, key, value ] args
+ if ( typeof data === "string" ) {
+ cache[ data ] = value;
+
+ // Handle: [ owner, { properties } ] args
+ } else {
+
+ // Copy the properties one-by-one to the cache object
+ for ( prop in data ) {
+ cache[ prop ] = data[ prop ];
+ }
+ }
+ return cache;
+ },
+ get: function( owner, key ) {
+ return key === undefined ?
+ this.cache( owner ) :
+ owner[ this.expando ] && owner[ this.expando ][ key ];
+ },
+ access: function( owner, key, value ) {
+ var stored;
+
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+ stored = this.get( owner, key );
+
+ return stored !== undefined ?
+ stored : this.get( owner, jQuery.camelCase( key ) );
+ }
+
+ // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
+
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i, name, camel,
+ cache = owner[ this.expando ];
+
+ if ( cache === undefined ) {
+ return;
+ }
+
+ if ( key === undefined ) {
+ this.register( owner );
+
+ } else {
+
+ // Support array or space separated string of keys
+ if ( jQuery.isArray( key ) ) {
+
+ // If "name" is an array of keys...
+ // When data is initially created, via ("key", "val") signature,
+ // keys will be converted to camelCase.
+ // Since there is no way to tell _how_ a key was added, remove
+ // both plain key and camelCase key. #12786
+ // This will only penalize the array argument path.
+ name = key.concat( key.map( jQuery.camelCase ) );
+ } else {
+ camel = jQuery.camelCase( key );
+
+ // Try the string as a key before any manipulation
+ if ( key in cache ) {
+ name = [ key, camel ];
+ } else {
+
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ name = camel;
+ name = name in cache ?
+ [ name ] : ( name.match( rnotwhite ) || [] );
+ }
+ }
+
+ i = name.length;
+
+ while ( i-- ) {
+ delete cache[ name[ i ] ];
+ }
+ }
+
+ // Remove the expando if there's no more data
+ if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+ // Support: Chrome <= 35-45+
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://code.google.com/p/chromium/issues/detail?id=378607
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = undefined;
+ } else {
+ delete owner[ this.expando ];
+ }
+ }
+ },
+ hasData: function( owner ) {
+ var cache = owner[ this.expando ];
+ return cache !== undefined && !jQuery.isEmptyObject( cache );
+ }
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+// Implementation Summary
+//
+// 1. Enforce API surface and semantic compatibility with 1.9.x branch
+// 2. Improve the module's maintainability by reducing the storage
+// paths to a single mechanism.
+// 3. Use the same single mechanism to support "private" and "user" data.
+// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+// 5. Avoid exposing implementation details on user objects (eg. expando properties)
+// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
+
+function dataAttr( elem, key, data ) {
+ var name;
+
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+
+ // Only convert to a number if it doesn't change the string
+ +data + "" === data ? +data :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch ( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ dataUser.set( elem, key, data );
+ } else {
+ data = undefined;
+ }
+ }
+ return data;
+}
+
+jQuery.extend( {
+ hasData: function( elem ) {
+ return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return dataUser.access( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ dataUser.remove( elem, name );
+ },
+
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return dataPriv.access( elem, name, data );
+ },
+
+ _removeData: function( elem, name ) {
+ dataPriv.remove( elem, name );
+ }
+} );
+
+jQuery.fn.extend( {
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = dataUser.get( elem );
+
+ if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
+
+ // Support: IE11+
+ // The attrs elements can be null (#14894)
+ if ( attrs[ i ] ) {
+ name = attrs[ i ].name;
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.slice( 5 ) );
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ }
+ dataPriv.set( elem, "hasDataAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each( function() {
+ dataUser.set( this, key );
+ } );
+ }
+
+ return access( this, function( value ) {
+ var data, camelKey;
+
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
+
+ // Attempt to get data from the cache
+ // with the key as-is
+ data = dataUser.get( elem, key ) ||
+
+ // Try to find dashed key if it exists (gh-2779)
+ // This is for 2.2.x only
+ dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
+
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ camelKey = jQuery.camelCase( key );
+
+ // Attempt to get data from the cache
+ // with the key camelized
+ data = dataUser.get( elem, camelKey );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, camelKey, undefined );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
+
+ // Set the data...
+ camelKey = jQuery.camelCase( key );
+ this.each( function() {
+
+ // First, attempt to store a copy or reference of any
+ // data that might've been store with a camelCased key.
+ var data = dataUser.get( this, camelKey );
+
+ // For HTML5 data-* attribute interop, we have to
+ // store property names with dashes in a camelCase form.
+ // This might not apply to all properties...*
+ dataUser.set( this, camelKey, value );
+
+ // *... In the case of properties that might _actually_
+ // have dashes, we need to also store a copy of that
+ // unchanged property.
+ if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
+ dataUser.set( this, key, value );
+ }
+ } );
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each( function() {
+ dataUser.remove( this, key );
+ } );
+ }
+} );
+
+
+jQuery.extend( {
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = dataPriv.get( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || jQuery.isArray( data ) ) {
+ queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+ } else {
+ queue.push( data );
+ }
+ }
+ return queue || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks( elem, type ),
+ next = function() {
+ jQuery.dequeue( elem, type );
+ };
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ if ( fn ) {
+
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ // Clear up the last queue stop function
+ delete hooks.stop;
+ fn.call( elem, next, hooks );
+ }
+
+ if ( !startLength && hooks ) {
+ hooks.empty.fire();
+ }
+ },
+
+ // Not public - generate a queueHooks object, or return the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
+ dataPriv.remove( elem, [ type + "queue", key ] );
+ } )
+ } );
+ }
+} );
+
+jQuery.fn.extend( {
+ queue: function( type, data ) {
+ var setter = 2;
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if ( arguments.length < setter ) {
+ return jQuery.queue( this[ 0 ], type );
+ }
+
+ return data === undefined ?
+ this :
+ this.each( function() {
+ var queue = jQuery.queue( this, type, data );
+
+ // Ensure a hooks for this queue
+ jQuery._queueHooks( this, type );
+
+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ } );
+ },
+ dequeue: function( type ) {
+ return this.each( function() {
+ jQuery.dequeue( this, type );
+ } );
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, obj ) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ };
+
+ if ( typeof type !== "string" ) {
+ obj = type;
+ type = undefined;
+ }
+ type = type || "fx";
+
+ while ( i-- ) {
+ tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+ if ( tmp && tmp.empty ) {
+ count++;
+ tmp.empty.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise( obj );
+ }
+} );
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHidden = function( elem, el ) {
+
+ // isHidden might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+ return jQuery.css( elem, "display" ) === "none" ||
+ !jQuery.contains( elem.ownerDocument, elem );
+ };
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+ var adjusted,
+ scale = 1,
+ maxIterations = 20,
+ currentValue = tween ?
+ function() { return tween.cur(); } :
+ function() { return jQuery.css( elem, prop, "" ); },
+ initial = currentValue(),
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ rcssNum.exec( jQuery.css( elem, prop ) );
+
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+ // Trust units reported by jQuery.css
+ unit = unit || initialInUnit[ 3 ];
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
+
+ // Iteratively approximate from a nonzero starting point
+ initialInUnit = +initial || 1;
+
+ do {
+
+ // If previous iteration zeroed out, double until we get *something*.
+ // Use string for doubling so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ initialInUnit = initialInUnit / scale;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // Break the loop if scale is unchanged or perfect, or if we've just had enough.
+ } while (
+ scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
+ );
+ }
+
+ if ( valueParts ) {
+ initialInUnit = +initialInUnit || +initial || 0;
+
+ // Apply relative offset (+=/-=) if specified
+ adjusted = valueParts[ 1 ] ?
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+ +valueParts[ 2 ];
+ if ( tween ) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+ return adjusted;
+}
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([\w:-]+)/ );
+
+var rscriptType = ( /^$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+ // Support: IE9
+ option: [ 1, "", " " ],
+
+ // XHTML parsers do not magically insert elements in the
+ // same way that tag soup parsers do. So we cannot shorten
+ // this by omitting or other required elements.
+ thead: [ 1, "" ],
+ col: [ 2, "" ],
+ tr: [ 2, "" ],
+ td: [ 3, "" ],
+
+ _default: [ 0, "", "" ]
+};
+
+// Support: IE9
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+ // Support: IE9-11+
+ // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+ var ret = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( tag || "*" ) :
+ typeof context.querySelectorAll !== "undefined" ?
+ context.querySelectorAll( tag || "*" ) :
+ [];
+
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+ jQuery.merge( [ context ], ret ) :
+ ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ dataPriv.set(
+ elems[ i ],
+ "globalEval",
+ !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+ var elem, tmp, tag, wrap, contains, j,
+ fragment = context.createDocumentFragment(),
+ nodes = [],
+ i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( jQuery.type( elem ) === "object" ) {
+
+ // Support: Android<4.1, PhantomJS<2
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+ // Convert non-html into a text node
+ } else if ( !rhtml.test( elem ) ) {
+ nodes.push( context.createTextNode( elem ) );
+
+ // Convert html into DOM nodes
+ } else {
+ tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+ // Descend through wrappers to the right content
+ j = wrap[ 0 ];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Support: Android<4.1, PhantomJS<2
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Remember the top-level container
+ tmp = fragment.firstChild;
+
+ // Ensure the created nodes are orphaned (#12392)
+ tmp.textContent = "";
+ }
+ }
+ }
+
+ // Remove wrapper from fragment
+ fragment.textContent = "";
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( fragment.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( ( elem = tmp[ j++ ] ) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ return fragment;
+}
+
+
+( function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) ),
+ input = document.createElement( "input" );
+
+ // Support: Android 4.0-4.3, Safari<=5.1
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
+
+ // Support: Safari<=5.1, Android<4.2
+ // Older WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE<=11+
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+
+
+var
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+// Support: IE9
+// See #13393 for more info
+function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ if ( data == null && fn == null ) {
+
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ global: {},
+
+ add: function( elem, types, handler, data, selector ) {
+
+ var handleObjIn, eventHandle, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.get( elem );
+
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
+ if ( !elemData ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ if ( !( events = elemData.events ) ) {
+ events = elemData.events = {};
+ }
+ if ( !( eventHandle = elemData.handle ) ) {
+ eventHandle = elemData.handle = function( e ) {
+
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+ jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ };
+ }
+
+ // Handle multiple events separated by a space
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // There *must* be a type, no attaching namespace-only handlers
+ if ( !type ) {
+ continue;
+ }
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend( {
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+ namespace: namespaces.join( "." )
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ if ( !( handlers = events[ type ] ) ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener if the special events handler returns false
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var j, origCount, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+ if ( !elemData || !( events = elemData.events ) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+ handlers = events[ type ] || [];
+ tmp = tmp[ 2 ] &&
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+ // Remove matching events
+ origCount = j = handlers.length;
+ while ( j-- ) {
+ handleObj = handlers[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector ||
+ selector === "**" && handleObj.selector ) ) {
+ handlers.splice( j, 1 );
+
+ if ( handleObj.selector ) {
+ handlers.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( origCount && !handlers.length ) {
+ if ( !special.teardown ||
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove data and the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ dataPriv.remove( elem, "handle events" );
+ }
+ },
+
+ dispatch: function( event ) {
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix( event );
+
+ var i, j, ret, matched, handleObj,
+ handlerQueue = [],
+ args = slice.call( arguments ),
+ handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+ special = jQuery.event.special[ event.type ] || {};
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[ 0 ] = event;
+ event.delegateTarget = this;
+
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+ return;
+ }
+
+ // Determine handlers
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+ // Run delegates first; they may want to stop propagation beneath us
+ i = 0;
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+ event.currentTarget = matched.elem;
+
+ j = 0;
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
+ !event.isImmediatePropagationStopped() ) {
+
+ // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+ // a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+ handleObj.handler ).apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ if ( ( event.result = ret ) === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ // Call the postDispatch hook for the mapped type
+ if ( special.postDispatch ) {
+ special.postDispatch.call( this, event );
+ }
+
+ return event.result;
+ },
+
+ handlers: function( event, handlers ) {
+ var i, matches, sel, handleObj,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Support (at least): Chrome, IE9
+ // Find delegate handlers
+ // Black-hole SVG instance trees (#13180)
+ //
+ // Support: Firefox<=42+
+ // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
+ if ( delegateCount && cur.nodeType &&
+ ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
+
+ for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+ // Don't check non-elements (#13208)
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+ if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
+ matches = [];
+ for ( i = 0; i < delegateCount; i++ ) {
+ handleObj = handlers[ i ];
+
+ // Don't conflict with Object.prototype properties (#13203)
+ sel = handleObj.selector + " ";
+
+ if ( matches[ sel ] === undefined ) {
+ matches[ sel ] = handleObj.needsContext ?
+ jQuery( sel, this ).index( cur ) > -1 :
+ jQuery.find( sel, this, null, [ cur ] ).length;
+ }
+ if ( matches[ sel ] ) {
+ matches.push( handleObj );
+ }
+ }
+ if ( matches.length ) {
+ handlerQueue.push( { elem: cur, handlers: matches } );
+ }
+ }
+ }
+ }
+
+ // Add the remaining (directly-bound) handlers
+ if ( delegateCount < handlers.length ) {
+ handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
+ }
+
+ return handlerQueue;
+ },
+
+ // Includes some event props shared by KeyEvent and MouseEvent
+ props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
+ "metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
+
+ fixHooks: {},
+
+ keyHooks: {
+ props: "char charCode key keyCode".split( " " ),
+ filter: function( event, original ) {
+
+ // Add which for key events
+ if ( event.which == null ) {
+ event.which = original.charCode != null ? original.charCode : original.keyCode;
+ }
+
+ return event;
+ }
+ },
+
+ mouseHooks: {
+ props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
+ "screenX screenY toElement" ).split( " " ),
+ filter: function( event, original ) {
+ var eventDoc, doc, body,
+ button = original.button;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && original.clientX != null ) {
+ eventDoc = event.target.ownerDocument || document;
+ doc = eventDoc.documentElement;
+ body = eventDoc.body;
+
+ event.pageX = original.clientX +
+ ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
+ ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+ event.pageY = original.clientY +
+ ( doc && doc.scrollTop || body && body.scrollTop || 0 ) -
+ ( doc && doc.clientTop || body && body.clientTop || 0 );
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && button !== undefined ) {
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+ }
+
+ return event;
+ }
+ },
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // Create a writable copy of the event object and normalize some properties
+ var i, prop, copy,
+ type = event.type,
+ originalEvent = event,
+ fixHook = this.fixHooks[ type ];
+
+ if ( !fixHook ) {
+ this.fixHooks[ type ] = fixHook =
+ rmouseEvent.test( type ) ? this.mouseHooks :
+ rkeyEvent.test( type ) ? this.keyHooks :
+ {};
+ }
+ copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+ event = new jQuery.Event( originalEvent );
+
+ i = copy.length;
+ while ( i-- ) {
+ prop = copy[ i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Support: Cordova 2.5 (WebKit) (#13255)
+ // All events should have a target; Cordova deviceready doesn't
+ if ( !event.target ) {
+ event.target = document;
+ }
+
+ // Support: Safari 6.0+, Chrome<28
+ // Target should not be a text node (#504, #13143)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+ },
+
+ special: {
+ load: {
+
+ // Prevent triggered image.load events from bubbling to window.load
+ noBubble: true
+ },
+ focus: {
+
+ // Fire native event if possible so blur/focus sequence is correct
+ trigger: function() {
+ if ( this !== safeActiveElement() && this.focus ) {
+ this.focus();
+ return false;
+ }
+ },
+ delegateType: "focusin"
+ },
+ blur: {
+ trigger: function() {
+ if ( this === safeActiveElement() && this.blur ) {
+ this.blur();
+ return false;
+ }
+ },
+ delegateType: "focusout"
+ },
+ click: {
+
+ // For checkbox, fire native event so checked state will be right
+ trigger: function() {
+ if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
+ this.click();
+ return false;
+ }
+ },
+
+ // For cross-browser consistency, don't fire native .click() on links
+ _default: function( event ) {
+ return jQuery.nodeName( event.target, "a" );
+ }
+ },
+
+ beforeunload: {
+ postDispatch: function( event ) {
+
+ // Support: Firefox 20+
+ // Firefox doesn't alert if the returnValue field is not set.
+ if ( event.result !== undefined && event.originalEvent ) {
+ event.originalEvent.returnValue = event.result;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+
+ // This "if" is needed for plain objects
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle );
+ }
+};
+
+jQuery.Event = function( src, props ) {
+
+ // Allow instantiation without the 'new' keyword
+ if ( !( this instanceof jQuery.Event ) ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = src.defaultPrevented ||
+ src.defaultPrevented === undefined &&
+
+ // Support: Android<4.0
+ src.returnValue === false ?
+ returnTrue :
+ returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // Create a timestamp if incoming event doesn't have one
+ this.timeStamp = src && src.timeStamp || jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ constructor: jQuery.Event,
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse,
+ isSimulated: false,
+
+ preventDefault: function() {
+ var e = this.originalEvent;
+
+ this.isDefaultPrevented = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.preventDefault();
+ }
+ },
+ stopPropagation: function() {
+ var e = this.originalEvent;
+
+ this.isPropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopPropagation();
+ }
+ },
+ stopImmediatePropagation: function() {
+ var e = this.originalEvent;
+
+ this.isImmediatePropagationStopped = returnTrue;
+
+ if ( e && !this.isSimulated ) {
+ e.stopImmediatePropagation();
+ }
+
+ this.stopPropagation();
+ }
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://code.google.com/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+jQuery.each( {
+ mouseenter: "mouseover",
+ mouseleave: "mouseout",
+ pointerenter: "pointerover",
+ pointerleave: "pointerout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ delegateType: fix,
+ bindType: fix,
+
+ handle: function( event ) {
+ var ret,
+ target = this,
+ related = event.relatedTarget,
+ handleObj = event.handleObj;
+
+ // For mouseenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+ if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply( this, arguments );
+ event.type = fix;
+ }
+ return ret;
+ }
+ };
+} );
+
+jQuery.fn.extend( {
+ on: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn );
+ },
+ one: function( types, selector, data, fn ) {
+ return on( this, types, selector, data, fn, 1 );
+ },
+ off: function( types, selector, fn ) {
+ var handleObj, type;
+ if ( types && types.preventDefault && types.handleObj ) {
+
+ // ( event ) dispatched jQuery.Event
+ handleObj = types.handleObj;
+ jQuery( types.delegateTarget ).off(
+ handleObj.namespace ?
+ handleObj.origType + "." + handleObj.namespace :
+ handleObj.origType,
+ handleObj.selector,
+ handleObj.handler
+ );
+ return this;
+ }
+ if ( typeof types === "object" ) {
+
+ // ( types-object [, selector] )
+ for ( type in types ) {
+ this.off( type, selector, types[ type ] );
+ }
+ return this;
+ }
+ if ( selector === false || typeof selector === "function" ) {
+
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ }
+ return this.each( function() {
+ jQuery.event.remove( this, types, fn, selector );
+ } );
+ }
+} );
+
+
+var
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
+
+ // Support: IE 10-11, Edge 10240+
+ // In IE/Edge using regex groups here causes severe slowdowns.
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
+ rnoInnerhtml = /