Repository: anyup/uView-Pro Branch: master Commit: 59af59f5ea16 Files: 633 Total size: 3.4 MB Directory structure: gitextract_x38b8_sy/ ├── .changelogrc.js ├── .copilot.md ├── .cz-config.js ├── .czrc ├── .editorconfig ├── .eslintignore ├── .gitee/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── feature_request.yml │ └── PULL_REQUEST_TEMPLATE.md ├── .github/ │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ ├── feature_request.md │ └── pull_request_template.md ├── .gitignore ├── .hbuilderx/ │ └── launch.json ├── .husky/ │ ├── commit-msg │ └── pre-commit ├── .lintstagedrc ├── .nvmrc ├── .prettierignore ├── .prettierrc.js ├── .vscode/ │ ├── extensions.json │ ├── settings.json │ └── uview-pro.code-snippets ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README-pnpm.md ├── README.en.md ├── README.md ├── commitlint.config.js ├── edgeone.json ├── harmony-configs/ │ └── build-profile.json5 ├── index.html ├── package.json ├── scripts/ │ ├── README.md │ ├── contributors-map.json │ ├── contributors-usage.md │ ├── fix-empty-css.js │ ├── generate-changelog.js │ ├── listColors.mjs │ ├── release.bat │ ├── release.js │ ├── release.ps1 │ ├── release.sh │ ├── replaceColors.mjs │ ├── test-npm-cleanup.js │ ├── test-npm-package.js │ └── update-date.js ├── shims-uni.d.ts ├── src/ │ ├── App.ku.vue │ ├── App.vue │ ├── api/ │ │ └── index.ts │ ├── common/ │ │ ├── classify.data.ts │ │ ├── constant.ts │ │ ├── demo-experience.config.json │ │ ├── demo.scss │ │ ├── http.interceptor.ts │ │ ├── iconfont.css │ │ ├── index.list.ts │ │ ├── request.ts │ │ ├── share.ts │ │ ├── useExperience.ts │ │ ├── useExperienceCenter.ts │ │ ├── useHooks.ts │ │ └── util.ts │ ├── components/ │ │ ├── demo-animation/ │ │ │ ├── animation.css │ │ │ └── demo-animation.vue │ │ ├── demo-card/ │ │ │ └── demo-card.vue │ │ ├── demo-guide/ │ │ │ └── demo-guide.vue │ │ ├── demo-guide-use/ │ │ │ └── demo-guide-use.vue │ │ ├── demo-page/ │ │ │ └── demo-page.vue │ │ ├── page-nav/ │ │ │ └── page-nav.vue │ │ └── wx-tips/ │ │ └── wx-tips.vue │ ├── env.d.ts │ ├── locales/ │ │ ├── index.ts │ │ └── langs/ │ │ ├── en.json │ │ └── zh-Hans.json │ ├── main.ts │ ├── manifest.json │ ├── pages/ │ │ ├── componentsA/ │ │ │ ├── avatar/ │ │ │ │ └── index.vue │ │ │ ├── avatarCropper/ │ │ │ │ └── index.vue │ │ │ ├── backTop/ │ │ │ │ └── index.vue │ │ │ ├── calendar/ │ │ │ │ └── index.vue │ │ │ ├── empty/ │ │ │ │ └── index.vue │ │ │ ├── field/ │ │ │ │ └── index.vue │ │ │ ├── form/ │ │ │ │ └── index.vue │ │ │ ├── fullScreen/ │ │ │ │ └── index.vue │ │ │ ├── icon/ │ │ │ │ └── index.vue │ │ │ ├── indexList/ │ │ │ │ └── index.vue │ │ │ ├── input/ │ │ │ │ └── index.vue │ │ │ ├── keyboard/ │ │ │ │ └── index.vue │ │ │ ├── lazyLoad/ │ │ │ │ └── index.vue │ │ │ ├── modal/ │ │ │ │ └── index.vue │ │ │ ├── navbar/ │ │ │ │ └── index.vue │ │ │ ├── noNetwork/ │ │ │ │ └── index.vue │ │ │ ├── select/ │ │ │ │ └── index.vue │ │ │ ├── slider/ │ │ │ │ └── index.vue │ │ │ ├── tabs/ │ │ │ │ └── index.vue │ │ │ ├── tag/ │ │ │ │ └── index.vue │ │ │ ├── test/ │ │ │ │ └── index.vue │ │ │ ├── textarea/ │ │ │ │ └── index.vue │ │ │ ├── timeLine/ │ │ │ │ └── index.vue │ │ │ ├── toast/ │ │ │ │ └── index.vue │ │ │ ├── topTips/ │ │ │ │ └── index.vue │ │ │ └── verificationCode/ │ │ │ └── index.vue │ │ ├── componentsB/ │ │ │ ├── card/ │ │ │ │ └── index.vue │ │ │ ├── checkbox/ │ │ │ │ └── index.vue │ │ │ ├── divider/ │ │ │ │ └── index.vue │ │ │ ├── dropdown/ │ │ │ │ └── index.vue │ │ │ ├── image/ │ │ │ │ └── index.vue │ │ │ ├── line/ │ │ │ │ └── index.vue │ │ │ ├── loading/ │ │ │ │ └── index.vue │ │ │ ├── loadingPopup/ │ │ │ │ └── index.vue │ │ │ ├── noticeBar/ │ │ │ │ └── index.vue │ │ │ ├── picker/ │ │ │ │ └── index.vue │ │ │ ├── radio/ │ │ │ │ └── index.vue │ │ │ ├── rate/ │ │ │ │ └── index.vue │ │ │ ├── readMore/ │ │ │ │ └── index.vue │ │ │ ├── search/ │ │ │ │ ├── index.vue │ │ │ │ └── types.ts │ │ │ ├── skeleton/ │ │ │ │ └── index.vue │ │ │ ├── steps/ │ │ │ │ └── index.vue │ │ │ ├── sticky/ │ │ │ │ └── index.vue │ │ │ ├── swipeAction/ │ │ │ │ └── index.vue │ │ │ ├── swiper/ │ │ │ │ ├── image.ts │ │ │ │ └── index.vue │ │ │ ├── switch/ │ │ │ │ └── index.vue │ │ │ ├── tabbar/ │ │ │ │ └── index.vue │ │ │ ├── table/ │ │ │ │ └── index.vue │ │ │ ├── transition/ │ │ │ │ └── index.vue │ │ │ ├── upload/ │ │ │ │ └── index.vue │ │ │ └── waterfall/ │ │ │ └── index.vue │ │ ├── componentsC/ │ │ │ ├── actionSheet/ │ │ │ │ └── index.vue │ │ │ ├── alertTips/ │ │ │ │ └── index.vue │ │ │ ├── badge/ │ │ │ │ └── index.vue │ │ │ ├── button/ │ │ │ │ └── index.vue │ │ │ ├── cell/ │ │ │ │ └── index.vue │ │ │ ├── circleProgress/ │ │ │ │ └── index.vue │ │ │ ├── collapse/ │ │ │ │ └── index.vue │ │ │ ├── color/ │ │ │ │ └── index.vue │ │ │ ├── countDown/ │ │ │ │ └── index.vue │ │ │ ├── countTo/ │ │ │ │ └── index.vue │ │ │ ├── fab/ │ │ │ │ └── index.vue │ │ │ ├── gap/ │ │ │ │ └── index.vue │ │ │ ├── grid/ │ │ │ │ └── index.vue │ │ │ ├── layout/ │ │ │ │ └── index.vue │ │ │ ├── link/ │ │ │ │ └── index.vue │ │ │ ├── loadmore/ │ │ │ │ └── index.vue │ │ │ ├── mask/ │ │ │ │ └── index.vue │ │ │ ├── messageInput/ │ │ │ │ └── index.vue │ │ │ ├── numberBox/ │ │ │ │ └── index.vue │ │ │ ├── pagination/ │ │ │ │ └── index.vue │ │ │ ├── popup/ │ │ │ │ └── index.vue │ │ │ ├── progress/ │ │ │ │ └── index.vue │ │ │ ├── section/ │ │ │ │ └── index.vue │ │ │ ├── subsection/ │ │ │ │ └── index.vue │ │ │ └── text/ │ │ │ └── index.vue │ │ ├── example/ │ │ │ ├── about/ │ │ │ │ ├── about-me.vue │ │ │ │ ├── contributors.vue │ │ │ │ ├── faq.vue │ │ │ │ ├── guide.vue │ │ │ │ ├── license.vue │ │ │ │ ├── settings.vue │ │ │ │ └── version.vue │ │ │ ├── about.vue │ │ │ ├── components.config.ts │ │ │ ├── components.vue │ │ │ ├── experienceMap.vue │ │ │ ├── fullScreen.vue │ │ │ ├── js.config.ts │ │ │ ├── js.vue │ │ │ ├── template.config.ts │ │ │ └── template.vue │ │ ├── hooks/ │ │ │ ├── useModal/ │ │ │ │ └── index.vue │ │ │ └── useToast/ │ │ │ └── index.vue │ │ ├── index/ │ │ │ └── index.vue │ │ ├── library/ │ │ │ ├── color/ │ │ │ │ └── index.vue │ │ │ ├── colorSwitch/ │ │ │ │ └── index.vue │ │ │ ├── debounce/ │ │ │ │ └── index.vue │ │ │ ├── deepClone/ │ │ │ │ └── index.vue │ │ │ ├── deepMerge/ │ │ │ │ └── index.vue │ │ │ ├── getRect/ │ │ │ │ └── index.vue │ │ │ ├── guid/ │ │ │ │ └── index.vue │ │ │ ├── http/ │ │ │ │ └── index.vue │ │ │ ├── md5/ │ │ │ │ └── index.vue │ │ │ ├── mpShare/ │ │ │ │ └── index.vue │ │ │ ├── queryParams/ │ │ │ │ └── index.vue │ │ │ ├── random/ │ │ │ │ └── index.vue │ │ │ ├── randomArray/ │ │ │ │ └── index.vue │ │ │ ├── route/ │ │ │ │ ├── index.vue │ │ │ │ └── routeTo.vue │ │ │ ├── test/ │ │ │ │ └── index.vue │ │ │ ├── timeFormat/ │ │ │ │ └── index.vue │ │ │ ├── timeFrom/ │ │ │ │ └── index.vue │ │ │ └── trim/ │ │ │ └── index.vue │ │ ├── other/ │ │ │ ├── locale/ │ │ │ │ └── index.vue │ │ │ └── theme/ │ │ │ └── index.vue │ │ ├── scenes/ │ │ │ ├── dashboard/ │ │ │ │ └── index.vue │ │ │ ├── favorites/ │ │ │ │ └── index.vue │ │ │ ├── index.vue │ │ │ ├── notes/ │ │ │ │ └── index.vue │ │ │ └── todo/ │ │ │ └── index.vue │ │ └── template/ │ │ ├── address/ │ │ │ ├── addSite.vue │ │ │ └── index.vue │ │ ├── citySelect/ │ │ │ └── index.vue │ │ ├── comment/ │ │ │ ├── index.vue │ │ │ └── reply.vue │ │ ├── coupon/ │ │ │ └── index.vue │ │ ├── detail/ │ │ │ └── index.vue │ │ ├── keyboardPay/ │ │ │ └── index.vue │ │ ├── login/ │ │ │ ├── code.vue │ │ │ └── index.vue │ │ ├── mallMenu/ │ │ │ ├── index1.vue │ │ │ └── index2.vue │ │ ├── order/ │ │ │ └── index.vue │ │ ├── submitBar/ │ │ │ └── index.vue │ │ └── wxCenter/ │ │ └── index.vue │ ├── pages.json │ ├── shime-uni.d.ts │ ├── static/ │ │ ├── app/ │ │ │ └── markdown/ │ │ │ ├── actionSheet.md │ │ │ ├── addQQGroup.md │ │ │ ├── alertTips.md │ │ │ ├── avatar.md │ │ │ ├── avatarCropper.md │ │ │ ├── backTop.md │ │ │ ├── badge.md │ │ │ ├── button.md │ │ │ ├── calendar.md │ │ │ ├── card.md │ │ │ ├── cell.md │ │ │ ├── changeGuide.md │ │ │ ├── changelog.md │ │ │ ├── chatGroup.md │ │ │ ├── checkbox.md │ │ │ ├── circleProgress.md │ │ │ ├── collapse.md │ │ │ ├── color.md │ │ │ ├── colorSwitch.md │ │ │ ├── colorjs.md │ │ │ ├── common.md │ │ │ ├── countDown.md │ │ │ ├── countTo.md │ │ │ ├── debounce.md │ │ │ ├── deepClone.md │ │ │ ├── deepMerge.md │ │ │ ├── divider.md │ │ │ ├── downloadSetting.md │ │ │ ├── dropdown.md │ │ │ ├── empty.md │ │ │ ├── fastUse.md │ │ │ ├── feature.md │ │ │ ├── field.md │ │ │ ├── form.md │ │ │ ├── fullScreen.md │ │ │ ├── gap.md │ │ │ ├── getRect.md │ │ │ ├── grid.md │ │ │ ├── guid.md │ │ │ ├── http.md │ │ │ ├── icon.md │ │ │ ├── image.md │ │ │ ├── indexList.md │ │ │ ├── input.md │ │ │ ├── install.md │ │ │ ├── intro copy.md │ │ │ ├── intro.md │ │ │ ├── keyboard.md │ │ │ ├── layout.md │ │ │ ├── lazyLoad.md │ │ │ ├── line.md │ │ │ ├── lineProgress.md │ │ │ ├── link.md │ │ │ ├── loadMore.md │ │ │ ├── loading.md │ │ │ ├── mask.md │ │ │ ├── md5.md │ │ │ ├── messageInput.md │ │ │ ├── modal.md │ │ │ ├── mpShare.md │ │ │ ├── navbar.md │ │ │ ├── noNetwork.md │ │ │ ├── noticeBar.md │ │ │ ├── npmSetting.md │ │ │ ├── numberBox.md │ │ │ ├── nvue.md │ │ │ ├── parse.md │ │ │ ├── picker.md │ │ │ ├── popup.md │ │ │ ├── queryParams.md │ │ │ ├── quickstart.md │ │ │ ├── radio.md │ │ │ ├── random.md │ │ │ ├── randomArray.md │ │ │ ├── rate.md │ │ │ ├── read.md │ │ │ ├── readMore.md │ │ │ ├── request.md │ │ │ ├── resource.md │ │ │ ├── route.md │ │ │ ├── safeAreaInset.md │ │ │ ├── search.md │ │ │ ├── section.md │ │ │ ├── select.md │ │ │ ├── setting.md │ │ │ ├── settingDesc.md │ │ │ ├── skeleton.md │ │ │ ├── slider.md │ │ │ ├── steps.md │ │ │ ├── sticky.md │ │ │ ├── subsection.md │ │ │ ├── swipeAction.md │ │ │ ├── swiper.md │ │ │ ├── switch.md │ │ │ ├── tabbar.md │ │ │ ├── table.md │ │ │ ├── tabs.md │ │ │ ├── tabsSwiper.md │ │ │ ├── tag.md │ │ │ ├── test.md │ │ │ ├── time.md │ │ │ ├── timeLine.md │ │ │ ├── toast.md │ │ │ ├── topTips.md │ │ │ ├── trim.md │ │ │ ├── uniModulesSetting.md │ │ │ ├── upload.md │ │ │ ├── verificationCode.md │ │ │ ├── vueUse.md │ │ │ ├── vuexDetail.md │ │ │ └── waterfall.md │ │ └── common/ │ │ └── js/ │ │ └── touch-emulator.js │ ├── theme.json │ ├── uni.scss │ ├── uni_modules/ │ │ ├── uview-pro/ │ │ │ ├── .npmignore │ │ │ ├── changelog.md │ │ │ ├── components/ │ │ │ │ ├── u-action-sheet/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-action-sheet.vue │ │ │ │ ├── u-action-sheet-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-action-sheet-item.vue │ │ │ │ ├── u-alert-tips/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-alert-tips.vue │ │ │ │ ├── u-avatar/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-avatar.vue │ │ │ │ ├── u-avatar-cropper/ │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── u-avatar-cropper.vue │ │ │ │ │ ├── weCropper.d.ts │ │ │ │ │ ├── weCropper.js │ │ │ │ │ └── weCropper.ts │ │ │ │ ├── u-back-top/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-back-top.vue │ │ │ │ ├── u-badge/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-badge.vue │ │ │ │ ├── u-button/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-button.vue │ │ │ │ ├── u-calendar/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-calendar.vue │ │ │ │ ├── u-car-keyboard/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-car-keyboard.vue │ │ │ │ ├── u-card/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-card.vue │ │ │ │ ├── u-cell-group/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-cell-group.vue │ │ │ │ ├── u-cell-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-cell-item.vue │ │ │ │ ├── u-checkbox/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-checkbox.vue │ │ │ │ ├── u-checkbox-group/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-checkbox-group.vue │ │ │ │ ├── u-circle-progress/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-circle-progress.vue │ │ │ │ ├── u-city-select/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-city-select.vue │ │ │ │ ├── u-col/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-col.vue │ │ │ │ ├── u-collapse/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-collapse.vue │ │ │ │ ├── u-collapse-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-collapse-item.vue │ │ │ │ ├── u-column-notice/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-column-notice.vue │ │ │ │ ├── u-config-provider/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-config-provider.vue │ │ │ │ ├── u-count-down/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-count-down.vue │ │ │ │ ├── u-count-to/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-count-to.vue │ │ │ │ ├── u-divider/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-divider.vue │ │ │ │ ├── u-dropdown/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-dropdown.vue │ │ │ │ ├── u-dropdown-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-dropdown-item.vue │ │ │ │ ├── u-empty/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-empty.vue │ │ │ │ ├── u-fab/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-fab.vue │ │ │ │ ├── u-field/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-field.vue │ │ │ │ ├── u-form/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-form.vue │ │ │ │ ├── u-form-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-form-item.vue │ │ │ │ ├── u-full-screen/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-full-screen.vue │ │ │ │ ├── u-gap/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-gap.vue │ │ │ │ ├── u-grid/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-grid.vue │ │ │ │ ├── u-grid-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-grid-item.vue │ │ │ │ ├── u-icon/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-icon.vue │ │ │ │ ├── u-image/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-image.vue │ │ │ │ ├── u-index-anchor/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-index-anchor.vue │ │ │ │ ├── u-index-list/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-index-list.vue │ │ │ │ ├── u-input/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-input.vue │ │ │ │ ├── u-keyboard/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-keyboard.vue │ │ │ │ ├── u-lazy-load/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-lazy-load.vue │ │ │ │ ├── u-line/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-line.vue │ │ │ │ ├── u-line-progress/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-line-progress.vue │ │ │ │ ├── u-link/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-link.vue │ │ │ │ ├── u-loading/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-loading.vue │ │ │ │ ├── u-loading-popup/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-loading-popup.vue │ │ │ │ ├── u-loadmore/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-loadmore.vue │ │ │ │ ├── u-mask/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-mask.vue │ │ │ │ ├── u-message-input/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-message-input.vue │ │ │ │ ├── u-modal/ │ │ │ │ │ ├── service.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-modal.vue │ │ │ │ ├── u-navbar/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-navbar.vue │ │ │ │ ├── u-no-network/ │ │ │ │ │ ├── image.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-no-network.vue │ │ │ │ ├── u-notice-bar/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-notice-bar.vue │ │ │ │ ├── u-number-box/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-number-box.vue │ │ │ │ ├── u-number-keyboard/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-number-keyboard.vue │ │ │ │ ├── u-pagination/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-pagination.vue │ │ │ │ ├── u-picker/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-picker.vue │ │ │ │ ├── u-popup/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-popup.vue │ │ │ │ ├── u-radio/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-radio.vue │ │ │ │ ├── u-radio-group/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-radio-group.vue │ │ │ │ ├── u-rate/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-rate.vue │ │ │ │ ├── u-read-more/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-read-more.vue │ │ │ │ ├── u-root-portal/ │ │ │ │ │ └── u-root-portal.vue │ │ │ │ ├── u-row/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-row.vue │ │ │ │ ├── u-row-notice/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-row-notice.vue │ │ │ │ ├── u-safe-bottom/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-safe-bottom.vue │ │ │ │ ├── u-search/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-search.vue │ │ │ │ ├── u-section/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-section.vue │ │ │ │ ├── u-select/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-select.vue │ │ │ │ ├── u-skeleton/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-skeleton.vue │ │ │ │ ├── u-slider/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-slider.vue │ │ │ │ ├── u-status-bar/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-status-bar.vue │ │ │ │ ├── u-step/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-step.vue │ │ │ │ ├── u-steps/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-steps.vue │ │ │ │ ├── u-sticky/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-sticky.vue │ │ │ │ ├── u-subsection/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-subsection.vue │ │ │ │ ├── u-swipe-action/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-swipe-action.vue │ │ │ │ ├── u-swiper/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-swiper.vue │ │ │ │ ├── u-switch/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-switch.vue │ │ │ │ ├── u-tabbar/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-tabbar.vue │ │ │ │ ├── u-table/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-table.vue │ │ │ │ ├── u-tabs/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-tabs.vue │ │ │ │ ├── u-tabs-swiper/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-tabs-swiper.vue │ │ │ │ ├── u-tag/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-tag.vue │ │ │ │ ├── u-td/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-td.vue │ │ │ │ ├── u-text/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-text.vue │ │ │ │ ├── u-textarea/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-textarea.vue │ │ │ │ ├── u-th/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-th.vue │ │ │ │ ├── u-time-line/ │ │ │ │ │ └── u-time-line.vue │ │ │ │ ├── u-time-line-item/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-time-line-item.vue │ │ │ │ ├── u-toast/ │ │ │ │ │ ├── service.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-toast.vue │ │ │ │ ├── u-top-tips/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-top-tips.vue │ │ │ │ ├── u-tr/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-tr.vue │ │ │ │ ├── u-transition/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-transition.vue │ │ │ │ ├── u-upload/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-upload.vue │ │ │ │ ├── u-verification-code/ │ │ │ │ │ ├── types.ts │ │ │ │ │ └── u-verification-code.vue │ │ │ │ └── u-waterfall/ │ │ │ │ ├── types.ts │ │ │ │ └── u-waterfall.vue │ │ │ ├── iconfont.css │ │ │ ├── index.scss │ │ │ ├── index.ts │ │ │ ├── libs/ │ │ │ │ ├── config/ │ │ │ │ │ ├── color.ts │ │ │ │ │ ├── config.ts │ │ │ │ │ ├── theme-tokens.ts │ │ │ │ │ └── zIndex.ts │ │ │ │ ├── css/ │ │ │ │ │ ├── color.scss │ │ │ │ │ ├── common.scss │ │ │ │ │ ├── style.components.scss │ │ │ │ │ ├── style.h5.scss │ │ │ │ │ ├── style.mp.scss │ │ │ │ │ ├── style.nvue.scss │ │ │ │ │ ├── style.theme.scss │ │ │ │ │ └── style.vue.scss │ │ │ │ ├── function/ │ │ │ │ │ ├── $parent.ts │ │ │ │ │ ├── addUnit.ts │ │ │ │ │ ├── clipboard.ts │ │ │ │ │ ├── color.ts │ │ │ │ │ ├── colorGradient.ts │ │ │ │ │ ├── debounce.ts │ │ │ │ │ ├── deepClone.ts │ │ │ │ │ ├── deepMerge.ts │ │ │ │ │ ├── getParent.ts │ │ │ │ │ ├── getRect.ts │ │ │ │ │ ├── guid.ts │ │ │ │ │ ├── md5.ts │ │ │ │ │ ├── parent.ts │ │ │ │ │ ├── queryParams.ts │ │ │ │ │ ├── random.ts │ │ │ │ │ ├── randomArray.ts │ │ │ │ │ ├── route.ts │ │ │ │ │ ├── styleUtils.ts │ │ │ │ │ ├── sys.ts │ │ │ │ │ ├── test.ts │ │ │ │ │ ├── throttle.ts │ │ │ │ │ ├── timeFormat.ts │ │ │ │ │ ├── timeFrom.ts │ │ │ │ │ ├── toast.ts │ │ │ │ │ ├── trim.ts │ │ │ │ │ └── type2icon.ts │ │ │ │ ├── hooks/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useColor.ts │ │ │ │ │ ├── useCompRelation.ts │ │ │ │ │ ├── useDebounce.ts │ │ │ │ │ ├── useEmitter.ts │ │ │ │ │ ├── useLocale.ts │ │ │ │ │ ├── useModal.ts │ │ │ │ │ ├── useRect.ts │ │ │ │ │ ├── useRouter.ts │ │ │ │ │ ├── useTheme.ts │ │ │ │ │ ├── useThrottle.ts │ │ │ │ │ └── useToast.ts │ │ │ │ ├── index.ts │ │ │ │ ├── request/ │ │ │ │ │ ├── auto-http.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── store/ │ │ │ │ │ └── index.ts │ │ │ │ └── util/ │ │ │ │ ├── area.ts │ │ │ │ ├── async-validator.d.ts │ │ │ │ ├── async-validator.js │ │ │ │ ├── calendar.d.ts │ │ │ │ ├── calendar.js │ │ │ │ ├── canvas-2d.ts │ │ │ │ ├── city.ts │ │ │ │ ├── config-provider.ts │ │ │ │ ├── emitter.ts │ │ │ │ ├── mitt.ts │ │ │ │ ├── province.ts │ │ │ │ └── system-theme.ts │ │ │ ├── locale/ │ │ │ │ ├── index.ts │ │ │ │ └── lang/ │ │ │ │ ├── en-US.ts │ │ │ │ └── zh-CN.ts │ │ │ ├── package.json │ │ │ ├── readme.md │ │ │ ├── theme.scss │ │ │ └── types/ │ │ │ ├── components.d.ts │ │ │ ├── global.d.ts │ │ │ ├── ignore-errors.d.ts │ │ │ ├── index.d.ts │ │ │ └── uni-app.d.ts │ │ └── zero-markdown-view/ │ │ ├── changelog.md │ │ ├── components/ │ │ │ ├── mp-html/ │ │ │ │ ├── highlight/ │ │ │ │ │ ├── config.js │ │ │ │ │ └── index.js │ │ │ │ ├── latex/ │ │ │ │ │ └── index.js │ │ │ │ ├── markdown/ │ │ │ │ │ └── index.js │ │ │ │ ├── mp-html.vue │ │ │ │ ├── node/ │ │ │ │ │ └── node.vue │ │ │ │ ├── parser.js │ │ │ │ └── style/ │ │ │ │ ├── index.js │ │ │ │ └── parser.js │ │ │ └── zero-markdown-view/ │ │ │ └── zero-markdown-view.vue │ │ ├── package.json │ │ └── readme.md │ └── uview-pro.theme.ts ├── tsconfig.json └── vite.config.ts ================================================ FILE CONTENTS ================================================ ================================================ FILE: .changelogrc.js ================================================ module.exports = { preset: 'conventionalcommits', releaseCount: 0, outputUnreleased: true, lernaPackage: false, tagPrefix: 'v', issuePrefixes: ['#'], commitUrlFormat: '{{host}}/{{owner}}/{{repository}}/commit/{{hash}}', compareUrlFormat: '{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}', issueUrlFormat: '{{host}}/{{owner}}/{{repository}}/issues/{{id}}', userUrlFormat: '{{host}}/{{user}}', // 自定义类型和 emoji types: [ { type: 'feat', section: '✨ Features | 新功能' }, { type: 'fix', section: '🐛 Bug Fixes | Bug 修复' }, { type: 'docs', section: '📝 Documentation | 文档' }, { type: 'style', section: '💄 Styles | 风格' }, { type: 'refactor', section: '♻️ Code Refactoring | 代码重构' }, { type: 'perf', section: '⚡ Performance Improvements | 性能优化' }, { type: 'test', section: '✅ Tests | 测试' }, { type: 'build', section: '📦‍ Build System | 打包构建' }, { type: 'ci', section: '👷 Continuous Integration | CI 配置' }, { type: 'chore', section: '🚀 Chore | 构建/工程依赖/工具' }, { type: 'revert', section: '⏪ Revert | 回退' } ] }; ================================================ FILE: .copilot.md ================================================ 项目说明: 本项目为 uView Pro 组件库,基于 uni-app、Vue3、TypeScript、Composition API 语法,重构自 uView UI 1.8.8。 目录规范: - 每个组件目录下包含:组件名.vue、types.ts(Props、emit等类型定义) - 组件代码路径:src/uni_modules/uview-pro/components/组件名/ - 示例代码路径:src/pages/ 开发建议: - 组件开发请统一使用 Vue3 + TS +
================================================ FILE: package.json ================================================ { "name": "uview-pro-demo", "version": "0.6.0-beta.1", "scripts": { "dev": "uni", "dev:custom": "uni -p", "dev:h5": "uni", "dev:h5:ssr": "uni --ssr", "dev:app": "uni -p app", "dev:app-android": "uni -p app-android", "dev:app-ios": "uni -p app-ios", "dev:mp-alipay": "uni -p mp-alipay", "dev:mp-baidu": "uni -p mp-baidu", "dev:mp-jd": "uni -p mp-jd", "dev:mp-kuaishou": "uni -p mp-kuaishou", "dev:mp-lark": "uni -p mp-lark", "dev:mp-qq": "uni -p mp-qq", "dev:mp-toutiao": "uni -p mp-toutiao", "dev:mp-weixin": "uni -p mp-weixin", "dev:mp-xhs": "uni -p mp-xhs", "dev:mp-dingtalk": "uni -p mp-dingtalk", "dev:quickapp-webview": "uni -p quickapp-webview", "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei", "dev:quickapp-webview-union": "uni -p quickapp-webview-union", "build": "node scripts/update-date.js && uni build", "postbuild": "node scripts/fix-empty-css.js", "build:custom": "node scripts/update-date.js && uni build -p", "build:h5": "node scripts/update-date.js && uni build", "build:h5:ssr": "uni build --ssr", "build:app": "uni build -p app", "build:app-android": "uni build -p app-android", "build:app-ios": "uni build -p app-ios", "build:mp-alipay": "uni build -p mp-alipay", "build:mp-baidu": "uni build -p mp-baidu", "build:mp-jd": "uni build -p mp-jd", "build:mp-kuaishou": "uni build -p mp-kuaishou", "build:mp-lark": "uni build -p mp-lark", "build:mp-qq": "uni build -p mp-qq", "build:mp-toutiao": "uni build -p mp-toutiao", "build:mp-weixin": "node scripts/update-date.js && uni build -p mp-weixin", "build:mp-xhs": "uni build -p mp-xhs", "build:mp-dingtalk": "uni build -p mp-dingtalk", "build:quickapp-webview": "uni build -p quickapp-webview", "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei", "build:quickapp-webview-union": "uni build -p quickapp-webview-union", "type-check": "vue-tsc --noEmit", "commit": "git-cz", "commit:lint": "commitlint --edit", "changelog": "node scripts/generate-changelog.js", "changelog:first": "node scripts/generate-changelog.js", "changelog:emoji": "node scripts/generate-changelog.js --emoji", "changelog:plain": "node scripts/generate-changelog.js --plain", "changelog:current": "node scripts/generate-changelog.js --emoji --current", "changelog:current:plain": "node scripts/generate-changelog.js --plain --current", "changelog:current:no-unreleased": "node scripts/generate-changelog.js --emoji --current --no-unreleased", "changelog:current:plain:no-unreleased": "node scripts/generate-changelog.js --plain --current --no-unreleased", "changelog:last": "node scripts/generate-changelog.js --emoji --last", "changelog:last:plain": "node scripts/generate-changelog.js --plain --last", "changelog:all": "node scripts/generate-changelog.js --emoji --all", "changelog:all:plain": "node scripts/generate-changelog.js --plain --all", "release": "node scripts/release.js", "release:changelog": "npm run changelog && git add CHANGELOG.md && git commit -m 'docs: update changelog' && git push", "release:patch": "node scripts/release.js patch", "release:minor": "node scripts/release.js minor", "release:major": "node scripts/release.js major", "release:beta": "node scripts/release.js prerelease beta", "release:alpha": "node scripts/release.js prerelease alpha", "release:rc": "node scripts/release.js prerelease rc", "release:push": "node scripts/release.js push", "release:undo": "node scripts/release.js undo", "publish": "cd src/uni_modules/uview-pro && npm publish --access public && cd ../../..", "prepare": "husky", "format": "prettier --write . --ignore-path .prettierignore", "test:npm": "node scripts/test-npm-package.js", "test:npm:cleanup": "node scripts/test-npm-cleanup.js" }, "config": { "commitizen": { "path": "./node_modules/cz-git" } }, "dependencies": { "@dcloudio/uni-app": "3.0.0-4080720251210001", "@dcloudio/uni-app-harmony": "3.0.0-4080720251210001", "@dcloudio/uni-app-plus": "3.0.0-4080720251210001", "@dcloudio/uni-components": "3.0.0-4080720251210001", "@dcloudio/uni-h5": "3.0.0-4080720251210001", "@dcloudio/uni-mp-alipay": "3.0.0-4080720251210001", "@dcloudio/uni-mp-baidu": "3.0.0-4080720251210001", "@dcloudio/uni-mp-harmony": "3.0.0-4080720251210001", "@dcloudio/uni-mp-jd": "3.0.0-4080720251210001", "@dcloudio/uni-mp-kuaishou": "3.0.0-4080720251210001", "@dcloudio/uni-mp-lark": "3.0.0-4080720251210001", "@dcloudio/uni-mp-qq": "3.0.0-4080720251210001", "@dcloudio/uni-mp-toutiao": "3.0.0-4080720251210001", "@dcloudio/uni-mp-weixin": "3.0.0-4080720251210001", "@dcloudio/uni-mp-xhs": "3.0.0-4080720251210001", "@dcloudio/uni-quickapp-webview": "3.0.0-4080720251210001", "vue": "^3.4.21", "vue-i18n": "9.1.9" }, "devDependencies": { "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@dcloudio/types": "^3.4.8", "@dcloudio/uni-automator": "3.0.0-4080720251210001", "@dcloudio/uni-cli-shared": "3.0.0-4080720251210001", "@dcloudio/uni-stacktracey": "3.0.0-4080720251210001", "@dcloudio/vite-plugin-uni": "3.0.0-4080720251210001", "@uni-ku/root": "^1.4.1", "@vue/runtime-core": "3.4.21", "@vue/tsconfig": "^0.8.1", "commitizen": "^4.3.1", "cz-git": "^1.12.0", "husky": "^9.1.7", "prettier": "^3.6.2", "sass": "1.63.2", "sass-loader": "10.4.1", "typescript": "^5.5.4", "vite": "5.2.8", "vue-tsc": "^3.0.5" }, "lint-staged": { "*.{js,ts,vue,scss,md,json}": "prettier --write --ignore-path .prettierignore" }, "uni-app": { "scripts": { "mp-dingtalk": { "title": "钉钉小程序", "env": { "UNI_PLATFORM": "mp-alipay" }, "define": { "MP-DINGTALK": true } } } }, "volta": { "node": "20.13.1" }, "buildDate": "2026-04-17", "releaseDate": "2026-05-08" } ================================================ FILE: scripts/README.md ================================================ # 发布脚本使用说明 本项目提供了多个版本的发布脚本,以确保在不同操作系统上都能正常运行。 ## 脚本文件说明 - `release.sh` - Bash 脚本 (适用于 Linux/macOS) - `release.ps1` - PowerShell 脚本 (适用于 Windows) - `release.bat` - 批处理脚本 (适用于 Windows) - `release.js` - Node.js 脚本 (适用于所有平台,推荐使用) ## 使用方法 ### 1. 推荐方式 (跨平台) 使用 Node.js 脚本,在所有平台上都能运行: ```bash # 发布补丁版本 npm run release:patch # 发布次要版本 npm run release:minor # 发布主要版本 npm run release:major # 发布指定版本 npm run release 0.5.1 ``` 或者直接使用: ```bash node scripts/release.js patch node scripts/release.js minor node scripts/release.js major node scripts/release.js 0.5.1 ``` ### 2. Windows PowerShell 方式 ```powershell # 发布补丁版本 npm run release:patch:win # 发布次要版本 npm run release:minor:win # 发布主要版本 npm run release:major:win ``` 或者直接使用: ```powershell powershell -ExecutionPolicy Bypass -File scripts/release.ps1 patch ``` ### 3. Windows 批处理方式 ```cmd # 发布补丁版本 npm run release:patch:bat # 发布次要版本 npm run release:minor:bat # 发布主要版本 npm run release:major:bat ``` 或者直接使用: ```cmd scripts\release.bat patch ``` ### 4. Linux/macOS 方式 ```bash # 发布补丁版本 npm run release:patch # 发布次要版本 npm run release:minor # 发布主要版本 npm run release:major ``` 或者直接使用: ```bash ./scripts/release.sh patch ``` ## 版本类型说明 - `patch` - 补丁版本 (修复 bug,如 1.0.0 → 1.0.1) - `minor` - 次要版本 (新功能,如 1.0.0 → 1.1.0) - `major` - 主要版本 (破坏性更新,如 1.0.0 → 2.0.0) - `0.5.1` - 指定版本 (自定义更新,如 1.0.0 → 1.5.1) ## 脚本功能 所有脚本都会执行以下操作: 1. ✅ 检查 Git 状态 (确保没有未提交的更改) 2. ✅ 检查当前分支 (建议在 main/master 分支上发布) 3. ✅ 更新根目录 package.json 中的版本号 4. ✅ 更新 uview-pro 模块 package.json 中的版本号 5. ✅ 生成 CHANGELOG.md 6. ✅ 提交所有更改 7. ✅ 创建 Git 标签 8. ✅ 推送到远程仓库 ## 注意事项 - 确保已安装 Node.js 和 npm - 确保 Git 已配置并可以推送到远程仓库 - 确保有足够的权限执行脚本 - 在 Windows 上使用 PowerShell 时,可能需要调整执行策略 ## 故障排除 ### Windows PowerShell 执行策略问题 如果遇到执行策略错误,可以运行: ```powershell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser ``` ### 权限问题 确保脚本文件有执行权限: ```bash chmod +x scripts/release.sh ``` ### Git 配置问题 确保 Git 已正确配置: ```bash git config --global user.name "Your Name" git config --global user.email "your.email@example.com" ``` ## 发布平台令牌(GitHub / Gitee) 发布脚本支持在推送标签后自动创建 Release,并将当前版本的 changelog 作为 Release 描述。需要为对应平台配置令牌(Token): ### GitHub Token 1. 创建 Token: - GitHub → Settings → Developer settings → Personal access tokens - 任选其一: - classic:勾选 `repo`(至少包含 repo:status、repo_deployment、public_repo) - fine-grained:选择当前仓库,权限建议:`Contents: Read and write`、`Metadata: Read-only` 2. 设置环境变量(Windows PowerShell): - 仅当前会话: ```powershell $env:GITHUB_TOKEN = "你的token" ``` - 永久生效(新开终端生效): ```powershell setx GITHUB_TOKEN "你的token" ``` - 亦可使用 `GH_TOKEN`: ```powershell $env:GH_TOKEN = "你的token"; setx GH_TOKEN "你的token" ``` ### Gitee Token 1. 创建 Token: - Gitee → 头像 → 设置 → 私人令牌(或 安全设置 → 私人令牌) - 新建令牌,授予仓库相关权限(至少包含发布 Release 所需权限) 2. 设置环境变量(Windows PowerShell): - 仅当前会话: ```powershell $env:GITEE_TOKEN = "你的token" ``` - 永久生效(新开终端生效): ```powershell setx GITEE_TOKEN "你的token" ``` ### 验证 重新打开 PowerShell,执行: ```powershell echo $env:GITHUB_TOKEN echo $env:GH_TOKEN echo $env:GITEE_TOKEN ``` 能看到值即已生效。随后正常执行: ```bash pnpm release:patch | pnpm release:minor | pnpm release:major ``` 脚本会自动识别远程仓库: - GitHub 仓库使用 `GITHUB_TOKEN`/`GH_TOKEN` 创建 Release - Gitee 仓库使用 `GITEE_TOKEN` 创建 Release ================================================ FILE: scripts/contributors-map.json ================================================ { "nameToGithub": { "前端梦工厂": "anyup", "不爱说话郭德纲": "elkelkelkelkelk", "xiaozuoovo": "zuo-wentao", "lime": "limes-cloud", "张淇": "zakicheung" }, "ignore": ["前端梦工厂"], "note": "此文件用于将作者名映射到 GitHub 用户名。如果自动推断的用户名头像不显示,可以在此配置。ignore 数组中的作者名将不会显示头像。" } ================================================ FILE: scripts/contributors-usage.md ================================================ # Contributors 配置使用说明 ## 📋 配置文件 `scripts/contributors-map.json` 用于配置贡献者信息。 ## 🎯 配置项说明 ### 1. nameToGithub(映射配置) 将作者名映射到 GitHub 用户名。 ```json { "nameToGithub": { "前端梦工厂": "anyup", "John Doe": "johndoe" } } ``` **使用场景**: - 自动推断的 GitHub 用户名不正确 - 作者名与 GitHub 用户名不一致 - 需要指定特定的 GitHub 用户名 ### 2. ignore(忽略配置) 忽略某些贡献者,不显示他们的头像。 ```json { "ignore": ["bot", "dependabot", "某些用户"] } ``` **使用场景**: - 机器人账号(如 dependabot) - 头像不显示的用户 - 不想显示的贡献者 ## 📝 完整配置示例 ```json { "nameToGithub": { "前端梦工厂": "anyup", "John Doe": "johndoe", "李四": "lisi" }, "ignore": ["bot", "dependabot", "某些用户"], "note": "此文件用于将作者名映射到 GitHub 用户名。如果自动推断的用户名头像不显示,可以在此配置。ignore 数组中的作者名将不会显示头像。" } ``` ## 🔧 使用方法 ### 添加映射 编辑 `scripts/contributors-map.json`,在 `nameToGithub` 中添加映射: ```json { "nameToGithub": { "作者名": "github用户名" } } ``` ### 忽略贡献者 编辑 `scripts/contributors-map.json`,在 `ignore` 数组中添加要忽略的作者名: ```json { "ignore": ["要忽略的作者名"] } ``` ## 🚀 重新生成 Changelog 修改配置后,需要重新生成 changelog: ```bash # 生成所有版本 pnpm changelog:all # 生成当前版本 pnpm changelog:current:no-unreleased ``` ## 📊 优先级说明 1. **ignore 配置**:最高优先级,如果在 ignore 列表中,直接跳过 2. **nameToGithub 映射**:如果配置了映射,使用映射的 GitHub 用户名 3. **自动推断**:将作者名转换为小写并移除空格作为 GitHub 用户名 ## ❓ 常见问题 ### Q: 如何查看贡献者列表? A: 运行以下命令查看所有贡献者: ```bash git log --format="%an" | sort -u ``` ### Q: 如何忽略机器人账号? A: 在 `ignore` 数组中添加机器人名称: ```json { "ignore": ["dependabot[bot]", "renovate[bot]"] } ``` ### Q: 如何为中文作者名配置映射? A: 直接在 `nameToGithub` 中配置: ```json { "nameToGithub": { "前端梦工厂": "anyup", "张三": "zhangsan" } } ``` ## 📚 相关文件 - `scripts/contributors-map.json` - 配置文件 - `scripts/generate-changelog.js` - 生成脚本 - `CHANGELOG.md` - 生成的变更日志 ================================================ FILE: scripts/fix-empty-css.js ================================================ #!/usr/bin/env node /* Ensure non-empty CSS assets in dist to avoid hosts stripping zero-byte files Usage: runs automatically via npm postbuild */ const fs = require('fs'); const path = require('path'); const DIST_DIR = path.resolve(process.cwd(), 'dist'); function walk(dir, handler) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const full = path.join(dir, entry.name); if (entry.isDirectory()) walk(full, handler); else handler(full); } } function ensureCssNotEmpty(filePath) { try { const stat = fs.statSync(filePath); if (stat.size === 0) { fs.writeFileSync( filePath, '/* keep: prevent hosting from stripping empty CSS; referenced by JS chunk */\n', 'utf8' ); // eslint-disable-next-line no-console console.log(`fixed empty css: ${path.relative(process.cwd(), filePath)}`); } } catch (e) { // eslint-disable-next-line no-console console.warn(`skip css check: ${filePath}`, e?.message); } } function run() { if (!fs.existsSync(DIST_DIR)) return; walk(DIST_DIR, full => { if (full.endsWith('.css')) ensureCssNotEmpty(full); }); } run(); ================================================ FILE: scripts/generate-changelog.js ================================================ #!/usr/bin/env node const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); // 解析命令行参数 const args = process.argv.slice(2); const useEmoji = args.includes('--emoji'); const usePlain = args.includes('--plain'); const onlyCurrent = args.includes('--current'); const sinceLastTag = args.includes('--last') || args.includes('--since-last-tag'); const generateAll = args.includes('--all') || args.includes('--by-tags'); const noUnreleased = args.includes('--no-unreleased'); // 如果没有指定参数,默认使用 emoji const shouldUseEmoji = useEmoji || (!usePlain && !useEmoji); // Emoji 映射 const emojiMap = { feat: '✨', fix: '🐛', docs: '📝', style: '💄', refactor: '♻️', perf: '⚡', test: '✅', build: '📦‍', ci: '👷', chore: '🚀', revert: '⏪' }; // 类型名称映射(带 emoji) const typeNamesWithEmoji = { feat: '✨ Features | 新功能', fix: '🐛 Bug Fixes | Bug 修复', docs: '📝 Documentation | 文档', style: '💄 Styles | 风格', refactor: '♻️ Code Refactoring | 代码重构', perf: '⚡ Performance Improvements | 性能优化', test: '✅ Tests | 测试', build: '📦‍ Build System | 打包构建', ci: '👷 Continuous Integration | CI 配置', chore: '🚀 Chore | 构建/工程依赖/工具', revert: '⏪ Revert | 回退' }; // 类型名称映射(不带 emoji) const typeNamesPlain = { feat: 'Features | 新功能', fix: 'Bug Fixes | Bug 修复', docs: 'Documentation | 文档', style: 'Styles | 风格', refactor: 'Code Refactoring | 代码重构', perf: 'Performance Improvements | 性能优化', test: 'Tests | 测试', build: 'Build System | 打包构建', ci: 'Continuous Integration | CI 配置', chore: 'Chore | 构建/工程依赖/工具', revert: 'Revert | 回退' }; // 根据设置选择类型名称 const typeNames = shouldUseEmoji ? typeNamesWithEmoji : typeNamesPlain; function safeExec(cmd) { try { return execSync(cmd, { encoding: 'utf8' }).trim(); } catch (e) { return ''; } } function resolveRange() { // --current: 以 package.json 的 version 为标签 vX.Y.Z,取上一个标签..当前标签 if (onlyCurrent) { const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); const currentTag = `v${pkg.version}`; // 上一个标签(当前标签的前一个) const prevTag = safeExec(`git describe --tags --abbrev=0 ${currentTag}^`); if (prevTag) return `${prevTag}..${currentTag}`; // 兜底:若当前标签不存在,则取最近一个标签..HEAD const lastTag = safeExec('git describe --tags --abbrev=0'); if (lastTag) return `${lastTag}..HEAD`; return ''; } // --last / --since-last-tag: 最近一个标签..HEAD if (sinceLastTag) { const lastTag = safeExec('git describe --tags --abbrev=0'); if (lastTag) return `${lastTag}..HEAD`; return ''; } // 默认:全量 return ''; } function buildSectionHeader({ version, date }) { return `## ${version} - ${date}`; } function collectCommits(range) { const rangeArg = range ? ` ${range}` : ''; const lines = execSync(`git log${rangeArg} --pretty=format:"%H|%s|%an|%ae" --reverse`, { encoding: 'utf8' }) .split('\n') .filter(line => line.trim()); return lines.map(line => { const [hash, subject, authorName, authorEmail] = line.split('|'); return { hash, subject, authorName, authorEmail }; }); } function groupCommitsByType(commits) { const commitsByType = {}; commits.forEach(commit => { if (!commit.subject) return; const match = commit.subject.match(/^(\w+)(?:\(([^)]+)\))?:\s*(.+)/); if (match) { const [, type, scope, description] = match; if (!emojiMap[type]) return; if (!commitsByType[type]) commitsByType[type] = []; commitsByType[type].push({ ...commit, scope: scope || '', description: description.trim() }); } }); return commitsByType; } function collectContributors(commits) { const contributorsMap = new Map(); const seenUsernames = new Set(); // 用于去重 GitHub 用户名 // 读取贡献者映射配置 let nameToGithub = {}; let ignoreList = []; try { const configPath = path.join(__dirname, 'contributors-map.json'); if (fs.existsSync(configPath)) { const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); nameToGithub = config.nameToGithub || {}; ignoreList = config.ignore || []; } } catch (e) { // 忽略配置文件读取错误 } commits.forEach(commit => { if (!commit.authorName || !commit.authorEmail) return; // 检查是否在忽略列表中 if (ignoreList.includes(commit.authorName)) { return; } const key = `${commit.authorName}|${commit.authorEmail}`; if (!contributorsMap.has(key)) { let githubUsername = ''; // 1. 优先使用配置文件中的映射 if (nameToGithub[commit.authorName]) { githubUsername = nameToGithub[commit.authorName]; } else { // 2. 使用作者名称推断 GitHub 用户名 // 将作者名转换为小写并移除空格 githubUsername = commit.authorName.toLowerCase().replace(/\s+/g, ''); } // 3. 检查 GitHub 用户名是否已存在,避免重复 if (!seenUsernames.has(githubUsername)) { seenUsernames.add(githubUsername); contributorsMap.set(key, { name: commit.authorName, email: commit.authorEmail, githubUsername: githubUsername }); } } }); return Array.from(contributorsMap.values()); } function renderContributors(contributors) { if (!contributors || contributors.length === 0) return ''; let section = '### 👥 Contributors\n\n'; contributors.forEach(contributor => { if (contributor.githubUsername) { // 使用 GitHub 头像 section += `${contributor.name} `; } else { // 没有 GitHub 用户名,显示姓名 section += `**${contributor.name}** `; } }); section += '\n\n'; return section; } function renderBodyFromGroups(commitsByType, contributors = null) { let body = ''; Object.keys(commitsByType).forEach(type => { if (commitsByType[type].length === 0) return; const typeName = typeNames[type]; body += `### ${typeName}\n\n`; commitsByType[type].forEach(commit => { const scope = commit.scope ? `**${commit.scope}:** ` : ''; const shortHash = commit.hash.substring(0, 7); body += `- ${scope}${commit.description} ([${shortHash}](https://github.com/anyup/uView-Pro/commit/${commit.hash}))\n`; }); body += '\n'; }); // 添加 Contributors 部分 if (contributors && contributors.length > 0) { body += renderContributors(contributors); } return body; } function renderFallbackBody() { if (shouldUseEmoji) { return `### ✨ Features | 新功能\n\n- Initial project setup with commitizen, cz-git, and conventional changelog\n\n### 🐛 Bug Fixes | Bug 修复\n\n### 📝 Documentation | 文档\n\n### 💄 Styles | 风格\n\n### ♻️ Code Refactoring | 代码重构\n\n### ⚡ Performance Improvements | 性能优化\n\n### ✅ Tests | 测试\n\n### 📦‍ Build System | 打包构建\n\n### 👷 Continuous Integration | CI 配置\n\n### 🚀 Chore | 构建/工程依赖/工具\n\n### ⏪ Revert | 回退\n\n`; } return `### Features | 新功能\n\n- Initial project setup with commitizen, cz-git, and conventional changelog\n\n### Bug Fixes | Bug 修复\n\n### Documentation | 文档\n\n### Styles | 风格\n\n### Code Refactoring | 代码重构\n\n### Performance Improvements | 性能优化\n\n### Tests | 测试\n\n### Build System | 打包构建\n\n### Continuous Integration | CI 配置\n\n### Chore | 构建/工程依赖/工具\n\n### Revert | 回退\n\n`; } function generateChangelog() { try { const range = resolveRange(); console.log( `🔄 Generating changelog... ${shouldUseEmoji ? 'with emoji' : 'without emoji'}${range ? ` (range: ${range})` : ''}` ); // 解析提交 const commits = collectCommits(range); const commitsByType = groupCommitsByType(commits); // 收集贡献者信息 const contributors = collectContributors(commits); const hasExisting = fs.existsSync('CHANGELOG.md'); const existingContent = hasExisting ? fs.readFileSync('CHANGELOG.md', 'utf8') : ''; // 标准化头部(可选移除 Unreleased) const baseHeader = `# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n`; const standardHeader = noUnreleased ? baseHeader : baseHeader + '## [Unreleased]\n\n'; let changelogBody = renderBodyFromGroups(commitsByType, contributors); // 如果没有找到任何符合规范的提交,添加默认内容 if (Object.keys(commitsByType).length === 0) { changelogBody += renderFallbackBody(); } let finalContent = ''; if (generateAll) { // 基于标签重建所有版本区块 const tagsOutput = safeExec('git tag --list --sort=-v:refname'); const tags = tagsOutput ? tagsOutput.split('\n').filter(Boolean) : []; let sections = ''; for (let i = 0; i < tags.length; i++) { const tag = tags[i]; const prev = tags[i + 1]; const tagDate = safeExec(`git show -s --format=%ad --date=format:%Y-%m-%d ${tag}`) || ''; const rangeExp = prev ? `${prev}..${tag}` : `${tag}`; const tagCommits = collectCommits(rangeExp); const groups = groupCommitsByType(tagCommits); const tagContributors = collectContributors(tagCommits); let body = renderBodyFromGroups(groups, tagContributors); if (!body) body = renderFallbackBody(); const header = buildSectionHeader({ version: tag.replace(/^v/, ''), date: tagDate }); sections += `${header}\n\n${body}`; } const headerIdx = existingContent.indexOf('## [Unreleased]'); const base = headerIdx !== -1 ? existingContent.slice(0, existingContent.indexOf('\n', headerIdx) + 1) : standardHeader; finalContent = base + '\n' + sections.trim() + '\n'; } else if (onlyCurrent) { // 将当前范围内容生成到版本段落,并插入到 Unreleased 之后 const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); const version = pkg.version; const today = new Date(); const yyyy = today.getFullYear(); const mm = String(today.getMonth() + 1).padStart(2, '0'); const dd = String(today.getDate()).padStart(2, '0'); const dateStr = `${yyyy}-${mm}-${dd}`; const sectionHeader = buildSectionHeader({ version, date: dateStr }); const newSection = `${sectionHeader}\n\n${changelogBody}`; if (hasExisting) { if (noUnreleased) { // 不保留 Unreleased 模式:找到第一个版本区块(跳过 ## [Unreleased]),在其前插入新版本 let firstVersionIndex = existingContent.indexOf('\n## '); // 如果找到的是 ## [Unreleased],则继续找下一个 if (firstVersionIndex !== -1) { const lineEnd = existingContent.indexOf('\n', firstVersionIndex + 1); const headerLine = existingContent.slice(firstVersionIndex, lineEnd); if (headerLine.includes('[Unreleased]')) { firstVersionIndex = existingContent.indexOf('\n## ', lineEnd); } } if (firstVersionIndex !== -1) { finalContent = existingContent.slice(0, firstVersionIndex) + '\n' + newSection + '\n' + existingContent.slice(firstVersionIndex); } else { // 没有版本区块,直接追加 finalContent = existingContent + '\n' + newSection + '\n'; } } else { // 保留 Unreleased 模式:找到 Unreleased 段落,在其后插入新版本 const unreleasedIndex = existingContent.indexOf('## [Unreleased]'); if (unreleasedIndex !== -1) { // 找到 Unreleased 段落的结束位置(下一个 "## " 标题或文件末尾) const afterUnreleased = existingContent.indexOf( '\n## ', unreleasedIndex + '## [Unreleased]'.length ); if (afterUnreleased !== -1) { finalContent = existingContent.slice(0, afterUnreleased) + '\n' + newSection + '\n' + existingContent.slice(afterUnreleased); } else { finalContent = existingContent + '\n' + newSection + '\n'; } } else { // 不存在 Unreleased,则在头部后插入 finalContent = standardHeader + newSection + '\n' + existingContent; } } } else { // 初次生成,包含标准头和新版本段 finalContent = standardHeader + newSection + '\n'; } } else { // 默认行为:写入标准头和将本次统计结果放在 Unreleased 下 finalContent = standardHeader + changelogBody; } // 彻底清理重复内容(防止多次运行导致重复) if (finalContent.includes('# Changelog')) { // 找到第一个头部结束位置 const headerEndIndex = finalContent.indexOf('\n\n## '); if (headerEndIndex !== -1) { const header = finalContent.slice(0, headerEndIndex); const body = finalContent.slice(headerEndIndex); // 移除所有重复的头部和重复的版本区块 let cleanBody = body; // 移除重复的头部 cleanBody = cleanBody.replace( /# Changelog\n\nAll notable changes to this project will be documented in this file\.\n\nThe format is based on \[Keep a Changelog\].*?and this project adheres to \[Semantic Versioning\].*?\n\n/g, '' ); // 移除重复的版本区块(保留第一个) const versionBlocks = cleanBody.split('\n## '); if (versionBlocks.length > 1) { const firstBlock = versionBlocks[0]; const otherBlocks = versionBlocks.slice(1); // 去重:只保留唯一的版本区块 const uniqueBlocks = []; const seenVersions = new Set(); otherBlocks.forEach(block => { // 跳过 Unreleased 区块 if (block.startsWith('[Unreleased]')) { return; } const versionMatch = block.match(/^(\[?\d+\.\d+\.\d+)/); if (versionMatch && !seenVersions.has(versionMatch[1])) { seenVersions.add(versionMatch[1]); uniqueBlocks.push('## ' + block); } }); cleanBody = firstBlock + (uniqueBlocks.length > 0 ? '\n' + uniqueBlocks.join('\n') : ''); } finalContent = header + cleanBody; } } // 统一调整版本间隔为1行(清理多余的空行) if (finalContent.includes('## ')) { // 清理头部后的多余空行,只保留1行间隔(匹配 ## [Unreleased] 或 ## 版本号) finalContent = finalContent.replace(/(# Changelog[\s\S]*?)\n\n\n+## /, '$1\n\n## '); // 清理版本区块之间的多余空行,只保留1行间隔 finalContent = finalContent.replace(/\n\n\n+## /g, '\n\n## '); // 清理文件末尾的多余空行 finalContent = finalContent.replace(/\n+$/, '\n'); } // 写入主 CHANGELOG.md 文件 fs.writeFileSync('CHANGELOG.md', finalContent); console.log(`✅ Changelog generated successfully ${shouldUseEmoji ? 'with emoji icons' : 'without emoji'}!`); // 如果是 current 模式且 no-unreleased,同时更新组件库的 changelog.md if (onlyCurrent && noUnreleased) { try { const componentChangelogPath = 'src/uni_modules/uview-pro/changelog.md'; if (fs.existsSync(componentChangelogPath)) { const componentContent = fs.readFileSync(componentChangelogPath, 'utf8'); // 提取当前版本的内容(兼容带方括号和不带方括号的格式) const currentVersion = JSON.parse(fs.readFileSync('package.json', 'utf8')).version; const currentSectionMatch = finalContent.match( new RegExp(`## \\[?${currentVersion}\\]?[\\s\\S]*?(?=\\n## |$)`) ); if (currentSectionMatch) { let currentSection = currentSectionMatch[0]; // 转换为组件库 changelog 的格式(去掉 emoji,调整日期格式) currentSection = currentSection .replace(/## \[?(\d+\.\d+\.\d+[^\s]*)\]? - (\d{4}-\d{2}-\d{2})/, '## $1($2)') .replace(/### 🚀 Chore \| 构建\/工程依赖\/工具/, '### 🚀 Chore | 构建/工程依赖/工具') .replace(/### 🐛 Bug Fixes \| Bug 修复/, '### 🐛 Bug Fixes | Bug 修复') .replace(/### ✨ Features \| 新功能/, '### ✨ Features | 新功能') .replace(/### ♻️ Code Refactoring \| 代码重构/, '### ♻️ Code Refactoring | 代码重构') .replace(/### 📝 Documentation \| 文档/, '### 📝 Documentation | 文档') .replace(/### 💄 Styles \| 风格/, '### 💄 Styles | 风格') .replace( /### ⚡ Performance Improvements \| 性能优化/, '### ⚡ Performance Improvements | 性能优化' ) .replace(/### ✅ Tests \| 测试/, '### ✅ Tests | 测试') .replace(/### 📦‍ Build System \| 打包构建/, '### 📦‍ Build System | 打包构建') .replace( /### 👷 Continuous Integration \| CI 配置/, '### 👷 Continuous Integration | CI 配置' ) .replace(/### ⏪ Revert \| 回退/, '### ⏪ Revert | 回退') .replace(/### 👥 Contributors/, '### 👥 Contributors'); // 检查是否已经存在该版本 const versionExists = new RegExp(`## ${currentVersion}(`).test(componentContent); if (!versionExists) { // 在文件开头插入新版本,只保留1行间隔 // 清理 currentSection 末尾的多余空行 const cleanSection = currentSection.replace(/\n+$/, ''); const newContent = cleanSection + '\n\n' + componentContent; fs.writeFileSync(componentChangelogPath, newContent); console.log(`✅ Component changelog updated: ${componentChangelogPath}`); } else { console.log(`ℹ️ Version ${currentVersion} already exists in component changelog`); } } } else { console.log(`⚠️ Component changelog file not found: ${componentChangelogPath}`); } } catch (error) { console.log(`⚠️ Failed to update component changelog: ${error.message}`); } } // 显示统计信息 Object.keys(commitsByType).forEach(type => { const emoji = shouldUseEmoji ? emojiMap[type] + ' ' : ''; console.log(`${emoji}${typeNamesPlain[type]}: ${commitsByType[type].length} commits`); }); // 显示使用说明 console.log('\n📖 Usage:'); console.log(' pnpm changelog:emoji - Generate changelog with emoji (full history)'); console.log(' pnpm changelog:plain - Generate changelog without emoji (full history)'); console.log(' pnpm changelog:current - Generate current version changelog (emoji)'); console.log(' pnpm changelog:current:plain - Generate current version changelog (plain)'); console.log(' pnpm changelog:last - Generate since last tag changelog (emoji)'); console.log(' pnpm changelog:last:plain - Generate since last tag changelog (plain)'); console.log(' pnpm changelog:all - Rebuild all version sections from git tags (emoji)'); console.log(' pnpm changelog:all:plain - Rebuild all version sections from git tags (plain)'); } catch (error) { console.error('❌ Error generating changelog:', error.message); process.exit(1); } } generateChangelog(); ================================================ FILE: scripts/listColors.mjs ================================================ import fs from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const root = join(__dirname, '..', 'src', 'uni_modules', 'uview-pro', 'components'); const pattern = /#([0-9a-fA-F]{3,6})/g; const counts = {}; function walk(dir) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = join(dir, entry.name); if (entry.isDirectory()) { walk(fullPath); } else if (entry.isFile()) { let text; try { text = fs.readFileSync(fullPath, 'utf8'); } catch (e) { text = fs.readFileSync(fullPath, { encoding: 'utf8', flag: 'r' }); } let match; while ((match = pattern.exec(text)) !== null) { const hex = match[0].toLowerCase(); counts[hex] = (counts[hex] || 0) + 1; } } } } walk(root); Object.keys(counts) .sort() .forEach(hex => { console.log(`${hex} ${counts[hex]}`); }); ================================================ FILE: scripts/release.bat ================================================ @echo off setlocal enabledelayedexpansion REM 发布脚本 (批处理版本) REM 使用方法: scripts\release.bat [patch|minor|major] if "%~1"=="" ( echo 请指定版本类型: patch, minor, 或 major echo 使用方法: scripts\release.bat [patch^|minor^|major] exit /b 1 ) set VERSION_TYPE=%~1 REM 验证版本类型 if not "%VERSION_TYPE%"=="patch" if not "%VERSION_TYPE%"=="minor" if not "%VERSION_TYPE%"=="major" ( echo 错误: 版本类型必须是 patch, minor, 或 major exit /b 1 ) echo 开始发布 %VERSION_TYPE% 版本... REM 检查是否有未提交的更改 git status --porcelain >nul 2>&1 if %errorlevel% neq 0 ( echo 错误: 有未提交的更改,请先提交或暂存 git status --porcelain exit /b 1 ) REM 检查当前分支 for /f "tokens=*" %%i in ('git branch --show-current') do set CURRENT_BRANCH=%%i if not "%CURRENT_BRANCH%"=="main" if not "%CURRENT_BRANCH%"=="master" ( echo 警告: 当前分支是 %CURRENT_BRANCH%,建议在 main 或 master 分支上发布 set /p CONTINUE="是否继续? (y/N): " if /i not "!CONTINUE!"=="y" exit /b 1 ) REM 更新版本号 echo 更新版本号... call npm version %VERSION_TYPE% --no-git-tag-version REM 获取新版本号 for /f "tokens=*" %%i in ('node -p "require('./package.json').version"') do set NEW_VERSION=%%i echo 新版本: %NEW_VERSION% REM 同时更新uview-pro模块的版本号 echo 更新uview-pro模块版本号... set UVEW_PRO_PACKAGE_PATH=src\uni_modules\uview-pro\package.json if exist "%UVEW_PRO_PACKAGE_PATH%" ( node -e "const pkg = require('./%UVEW_PRO_PACKAGE_PATH%'); pkg.version = '%NEW_VERSION%'; require('fs').writeFileSync('./%UVEW_PRO_PACKAGE_PATH%', JSON.stringify(pkg, null, 4) + '\n');" echo ✅ uview-pro模块版本已更新为: %NEW_VERSION% ) else ( echo ⚠️ 未找到uview-pro模块的package.json文件 ) REM 生成 changelog echo 生成 changelog... call npm run changelog REM 提交更改 echo 提交更改... git add package.json src/uni_modules/uview-pro/package.json CHANGELOG.md git commit -m "chore(release): bump version to %NEW_VERSION% - Update package.json version - Update uview-pro module version - Generate changelog for %NEW_VERSION%" REM 创建标签 echo 创建标签 v%NEW_VERSION%... git tag -a "v%NEW_VERSION%" -m "Release version %NEW_VERSION%" REM 推送更改和标签 echo 推送更改和标签... git push origin HEAD git push origin "v%NEW_VERSION%" echo ✅ 版本 %NEW_VERSION% 发布成功! echo 📝 Changelog 已更新 echo 🏷️ 标签 v%NEW_VERSION% 已创建并推送 echo. echo 下一步: echo 1. 在 GitHub/GitLab 上创建 Release echo 2. 将 CHANGELOG.md 中的内容复制到 Release 描述中 echo 3. 上传构建产物 (如果需要) ================================================ FILE: scripts/release.js ================================================ #!/usr/bin/env node /** * 发布脚本 (Node.js版本) * 使用方法: * node scripts/release.js [patch|minor|major] # 语义化版本(默认不推送) * node scripts/release.js prerelease [alpha|beta|rc] # 预览版本(默认不推送) * node scripts/release.js 0.5.1 # 直接指定版本号(默认不推送) * node scripts/release.js patch --push # 提交并推送 * node scripts/release.js push # 推送上次未推送的发布 * node scripts/release.js undo # 撤销本地发布(仅未推送时) * 在所有平台上都能运行 */ const { execSync, spawn } = require('child_process'); const fs = require('fs'); const path = require('path'); // 获取命令行参数 const args = process.argv.slice(2); // 特殊命令:push - 用于推送之前未 push 的发布 if (args[0] === 'push') { console.log('🚀 开始推送发布标签和提交...'); try { // 获取当前版本 const packageJsonPath = path.join(process.cwd(), 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const version = packageJson.version; // 推送提交和标签 console.log('📤 推送提交...'); execSync('git push origin HEAD', { stdio: 'inherit' }); console.log(`📤 推送标签 v${version}...`); execSync(`git push origin "v${version}"`, { stdio: 'inherit' }); console.log(`✅ 版本 ${version} 推送成功!`); process.exit(0); } catch (error) { console.error('❌ 推送失败:', error.message); process.exit(1); } } // 特殊命令:undo - 用于撤销本地的发布(仅支持未推送的情况) if (args[0] === 'undo') { console.log('↩️ 开始撤销本地发布...'); try { // 获取当前版本 const packageJsonPath = path.join(process.cwd(), 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const version = packageJson.version; const tagName = `v${version}`; // 检查是否有未推送的提交 console.log('🔍 检查提交状态...'); try { const unpushedCommits = execSync('git log origin/HEAD..HEAD --oneline', { encoding: 'utf8' }).trim(); if (!unpushedCommits) { console.error('❌ 错误:没有未推送的提交,或者当前分支没有远程跟踪分支'); console.error('💡 该命令仅用于撤销未推送的本地发布'); process.exit(1); } } catch (e) { // 如果没有远程分支,git log 会报错,这也是可以撤销的情况 } // 检查标签是否存在 console.log(`🔍 检查标签 ${tagName}...`); let tagExists = false; try { execSync(`git rev-parse ${tagName}`, { stdio: 'pipe' }); tagExists = true; } catch (e) { console.log(`⚠️ 标签 ${tagName} 不存在`); } // 获取最后一次提交信息 const lastCommitMsg = execSync('git log -1 --pretty=%B', { encoding: 'utf8' }).trim(); const isReleaseCommit = lastCommitMsg.includes('chore(release): bump version to'); if (!isReleaseCommit) { console.error('❌ 错误:最后一次提交不是发布提交'); console.error('💡 最后一次提交信息:', lastCommitMsg.substring(0, 50) + '...'); console.error('💡 请手动检查并撤销'); process.exit(1); } console.log(''); console.log('⚠️ 即将执行以下操作:'); console.log(` 1. 删除本地标签: ${tagName}`); console.log(' 2. 撤销最后一次提交(保留修改到暂存区)'); console.log(' 3. 恢复 package.json 和 changelog 文件'); console.log(''); console.log('💡 撤销后版本号需要手动修改回之前的版本'); console.log(''); // 由于是命令行工具,直接执行而不询问 // 删除本地标签 if (tagExists) { console.log(`🗑️ 删除本地标签 ${tagName}...`); execSync(`git tag -d ${tagName}`, { stdio: 'inherit' }); } // 撤销最后一次提交,保留修改 console.log('↩️ 撤销最后一次提交...'); execSync('git reset --soft HEAD~1', { stdio: 'inherit' }); // 恢复 package.json 文件 console.log('📄 恢复 package.json...'); execSync('git checkout -- package.json', { stdio: 'inherit' }); // 恢复 uview-pro 模块的 package.json const uviewProPackagePath = 'src/uni_modules/uview-pro/package.json'; if (fs.existsSync(uviewProPackagePath)) { console.log('📄 恢复 uview-pro package.json...'); try { execSync(`git checkout -- ${uviewProPackagePath}`, { stdio: 'inherit' }); } catch (e) { console.log('⚠️ 未找到 uview-pro package.json 或无需恢复'); } } // 恢复 changelog console.log('📄 恢复 changelog...'); execSync('git checkout -- CHANGELOG.md', { stdio: 'inherit' }); try { execSync('git checkout -- src/uni_modules/uview-pro/changelog.md', { stdio: 'inherit' }); } catch (e) { console.log('⚠️ 未找到 uview-pro changelog 或无需恢复'); } console.log(''); console.log('✅ 本地发布撤销成功!'); console.log(''); console.log('📋 当前状态:'); console.log(` • 标签 ${tagName} 已删除`); console.log(' • 提交已撤销,修改已保留在暂存区'); console.log(' • package.json 和 changelog 已恢复'); console.log(''); console.log('💡 如需修改版本号,请手动编辑 package.json'); console.log('💡 如需重新发布,运行: npm run release:patch (或其他版本类型)'); process.exit(0); } catch (error) { console.error('❌ 撤销失败:', error.message); process.exit(1); } } // 检查是否有 --push 参数(默认不推送) const shouldPush = args.includes('--push'); const versionInput = args.find(arg => !arg.startsWith('--')); // 验证版本号格式 (支持 x.y.z 格式,如 0.5.1, 1.0.0, 2.3.4-beta.1) function isValidVersion(version) { if (!version || typeof version !== 'string') return false; // 匹配语义化版本号: x.y.z 或 x.y.z-prerelease const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/; return semverRegex.test(version); } // 判断是语义化版本类型还是直接指定版本号 const isSemverType = ['patch', 'minor', 'major', 'prerelease'].includes(versionInput); const isDirectVersion = isValidVersion(versionInput); // 验证参数 if (!versionInput || (!isSemverType && !isDirectVersion)) { console.error('❌ 请指定版本类型或版本号'); console.error('使用方法:'); console.error(' node scripts/release.js [patch|minor|major] # 语义化版本(默认不推送)'); console.error(' node scripts/release.js prerelease [alpha|beta|rc] # 预览版本(默认不推送)'); console.error(' node scripts/release.js 0.5.1 # 直接指定版本号(默认不推送)'); console.error(''); console.error('选项:'); console.error(' --push # 提交并推送'); console.error(''); console.error('其他命令:'); console.error(' node scripts/release.js push # 推送上次未推送的发布'); console.error(' node scripts/release.js undo # 撤销本地发布(仅未推送时)'); process.exit(1); } // 处理 prerelease 类型和标识 let prereleaseId = ''; if (versionInput === 'prerelease') { prereleaseId = args[1] || 'beta'; // 默认使用 beta } const versionType = isSemverType ? versionInput : null; const targetVersion = isDirectVersion ? versionInput : null; // 显示发布信息 const releaseTypeText = targetVersion ? targetVersion : versionType === 'prerelease' ? `${prereleaseId} 预览版` : versionType; const isPrereleaseType = versionType === 'prerelease' || (targetVersion && targetVersion.includes('-')); console.log(`${isPrereleaseType ? '🧪' : '🚀'} 开始发布 ${releaseTypeText} 版本...`); // 执行命令的辅助函数 function execCommand(command, options = {}) { try { const result = execSync(command, { encoding: 'utf8', stdio: 'inherit', ...options }); return result; } catch (error) { console.error(`❌ 命令执行失败: ${command}`); console.error(error.message); process.exit(1); } } // 检查是否有未提交的更改 console.log('📋 检查Git状态...'); const gitStatus = execCommand('git status --porcelain', { stdio: 'pipe' }); if (gitStatus.trim()) { console.error('❌ 有未提交的更改,请先提交或暂存'); console.log(gitStatus); process.exit(1); } // 检查当前分支 console.log('🌿 检查当前分支...'); const currentBranch = execCommand('git branch --show-current', { stdio: 'pipe' }).trim(); if (currentBranch !== 'main' && currentBranch !== 'master') { console.warn(`⚠️ 警告: 当前分支是 ${currentBranch},建议在 main 或 master 分支上发布`); // 在Node.js中实现交互式输入 const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('是否继续? (y/N): ', answer => { rl.close(); if (!/^[Yy]$/.test(answer)) { console.log('❌ 操作已取消'); process.exit(1); } continueRelease(); }); } else { continueRelease(); } function continueRelease() { try { const packageJsonPath = path.join(process.cwd(), 'package.json'); const currentDate = new Date().toISOString().split('T')[0]; // YYYY-MM-DD格式 let newVersion; const isPrerelease = versionType === 'prerelease' || (targetVersion && targetVersion.includes('-')); // 更新版本号 if (targetVersion) { // 直接指定版本号 console.log(`📦 更新版本号为 ${targetVersion}...`); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); packageJson.version = targetVersion; // 更新发布日期 packageJson.releaseDate = currentDate; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); newVersion = targetVersion; } else if (versionType === 'prerelease') { // 预览版本 console.log(`📦 更新版本号为 ${prereleaseId} 预览版本...`); execCommand(`npm version prerelease --preid=${prereleaseId} --no-git-tag-version`); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); newVersion = packageJson.version; // 更新发布日期 packageJson.releaseDate = currentDate; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); } else { // 语义化版本类型 console.log('📦 更新版本号...'); execCommand(`npm version ${versionType} --no-git-tag-version`); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); newVersion = packageJson.version; // 更新发布日期 packageJson.releaseDate = currentDate; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); } console.log(`✨ 新版本: ${newVersion}`); console.log(`✅ 发布日期: ${currentDate}`); // 同时更新uview-pro模块的版本号 console.log('📦 更新uview-pro模块版本号...'); const uviewProPackagePath = path.join(process.cwd(), 'src', 'uni_modules', 'uview-pro', 'package.json'); if (fs.existsSync(uviewProPackagePath)) { const uviewProPackage = JSON.parse(fs.readFileSync(uviewProPackagePath, 'utf8')); uviewProPackage.version = newVersion; fs.writeFileSync(uviewProPackagePath, JSON.stringify(uviewProPackage, null, 4) + '\n'); console.log(`✅ uview-pro模块版本已更新为: ${newVersion}`); } else { console.warn('⚠️ 未找到uview-pro模块的package.json文件'); } // 生成 changelog(按当前版本生成版本化条目,可配置是否保留 Unreleased) console.log('📝 生成 changelog...'); execCommand('npm run changelog:current:no-unreleased'); // 提交更改 console.log('💾 提交更改...'); execCommand( 'git add package.json src/uni_modules/uview-pro/package.json CHANGELOG.md src/uni_modules/uview-pro/changelog.md' ); execCommand(`git commit -m "chore(release): bump version to ${newVersion} - Update package.json version - Update uview-pro module version - Generate changelog for ${newVersion} - Update uview-pro component changelog"`); // 创建标签 console.log(`🏷️ 创建标签 v${newVersion}...`); execCommand(`git tag -a "v${newVersion}" -m "Release version ${newVersion}"`); // 推送更改和标签 if (shouldPush) { console.log('🚀 推送更改和标签...'); execCommand('git push origin HEAD'); execCommand(`git push origin "v${newVersion}"`); } console.log(`${isPrerelease ? '🎉 预览版本' : '✅ 版本'} ${newVersion} 发布成功!`); console.log('📝 Changelog 已更新'); if (shouldPush) { console.log(`🏷️ 标签 v${newVersion} 已创建并推送`); } else { console.log(`🏷️ 标签 v${newVersion} 已创建(未推送)`); console.log('💡 如需推送,运行: npm run release:push'); console.log(` 或: git push origin HEAD && git push origin "v${newVersion}"`); } if (isPrerelease) { console.log(''); console.log('⚠️ 这是一个预览版本,仅供测试使用'); } console.log(''); console.log('📋 下一步:'); if (!shouldPush) { console.log('1. 检查无误后,运行 npm run release:push 推送发布'); console.log('2. 如需创建 GitHub/Gitee Release,请手动前往仓库创建'); } else { console.log('如需创建 GitHub/Gitee Release,请手动前往仓库创建'); } } catch (error) { console.error('❌ 发布过程中出现错误:', error.message); process.exit(1); } } ================================================ FILE: scripts/release.ps1 ================================================ # 发布脚本 (PowerShell版本) # 使用方法: .\scripts\release.ps1 [patch|minor|major] param( [Parameter(Mandatory=$true)] [ValidateSet("patch", "minor", "major")] [string]$VersionType ) # 设置错误处理 $ErrorActionPreference = "Stop" Write-Host "开始发布 $VersionType 版本..." -ForegroundColor Green # 检查是否有未提交的更改 $gitStatus = git status --porcelain if ($gitStatus) { Write-Host "错误: 有未提交的更改,请先提交或暂存" -ForegroundColor Red Write-Host $gitStatus exit 1 } # 检查当前分支 $currentBranch = git branch --show-current if ($currentBranch -ne "main" -and $currentBranch -ne "master") { Write-Host "警告: 当前分支是 $currentBranch,建议在 main 或 master 分支上发布" -ForegroundColor Yellow $continue = Read-Host "是否继续? (y/N)" if ($continue -notmatch "^[Yy]$") { exit 1 } } # 更新版本号 Write-Host "更新版本号..." -ForegroundColor Cyan npm version $VersionType --no-git-tag-version # 获取新版本号 $packageJson = Get-Content "package.json" | ConvertFrom-Json $newVersion = $packageJson.version Write-Host "新版本: $newVersion" -ForegroundColor Green # 同时更新uview-pro模块的版本号 Write-Host "更新uview-pro模块版本号..." -ForegroundColor Cyan $uviewProPackagePath = "src\uni_modules\uview-pro\package.json" if (Test-Path $uviewProPackagePath) { $uviewProPackage = Get-Content $uviewProPackagePath | ConvertFrom-Json $uviewProPackage.version = $newVersion $uviewProPackage | ConvertTo-Json -Depth 10 | Set-Content $uviewProPackagePath Write-Host "✅ uview-pro模块版本已更新为: $newVersion" -ForegroundColor Green } else { Write-Host "⚠️ 未找到uview-pro模块的package.json文件" -ForegroundColor Yellow } # 生成 changelog Write-Host "生成 changelog..." -ForegroundColor Cyan npm run changelog # 提交更改 Write-Host "提交更改..." -ForegroundColor Cyan git add package.json src/uni_modules/uview-pro/package.json CHANGELOG.md git commit -m "chore(release): bump version to $newVersion - Update package.json version - Update uview-pro module version - Generate changelog for $newVersion" # 创建标签 Write-Host "创建标签 v$newVersion..." -ForegroundColor Cyan git tag -a "v$newVersion" -m "Release version $newVersion" # 推送更改和标签 Write-Host "推送更改和标签..." -ForegroundColor Cyan git push origin HEAD git push origin "v$newVersion" Write-Host "✅ 版本 $newVersion 发布成功!" -ForegroundColor Green Write-Host "📝 Changelog 已更新" -ForegroundColor Green Write-Host "🏷️ 标签 v$newVersion 已创建并推送" -ForegroundColor Green Write-Host "" Write-Host "下一步:" -ForegroundColor Yellow Write-Host "1. 在 GitHub/GitLab 上创建 Release" -ForegroundColor White Write-Host "2. 将 CHANGELOG.md 中的内容复制到 Release 描述中" -ForegroundColor White Write-Host "3. 上传构建产物 (如果需要)" -ForegroundColor White ================================================ FILE: scripts/release.sh ================================================ #!/bin/bash # 发布脚本 # 使用方法: ./scripts/release.sh [patch|minor|major] set -e # 检查参数 if [ $# -eq 0 ]; then echo "请指定版本类型: patch, minor, 或 major" echo "使用方法: ./scripts/release.sh [patch|minor|major]" exit 1 fi VERSION_TYPE=$1 # 验证版本类型 if [[ ! "$VERSION_TYPE" =~ ^(patch|minor|major)$ ]]; then echo "错误: 版本类型必须是 patch, minor, 或 major" exit 1 fi echo "开始发布 $VERSION_TYPE 版本..." # 检查是否有未提交的更改 if [ -n "$(git status --porcelain)" ]; then echo "错误: 有未提交的更改,请先提交或暂存" git status --porcelain exit 1 fi # 检查当前分支 CURRENT_BRANCH=$(git branch --show-current) if [ "$CURRENT_BRANCH" != "main" ] && [ "$CURRENT_BRANCH" != "master" ]; then echo "警告: 当前分支是 $CURRENT_BRANCH,建议在 main 或 master 分支上发布" read -p "是否继续? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi # 更新版本号 echo "更新版本号..." npm version $VERSION_TYPE --no-git-tag-version # 获取新版本号 NEW_VERSION=$(node -p "require('./package.json').version") echo "新版本: $NEW_VERSION" # 生成 changelog echo "生成 changelog..." npm run changelog # 提交更改 echo "提交更改..." git add package.json CHANGELOG.md git commit -m "chore(release): bump version to $NEW_VERSION - Update package.json version - Generate changelog for $NEW_VERSION" # 创建标签 echo "创建标签 v$NEW_VERSION..." git tag -a "v$NEW_VERSION" -m "Release version $NEW_VERSION" # 推送更改和标签 echo "推送更改和标签..." git push origin HEAD git push origin "v$NEW_VERSION" echo "✅ 版本 $NEW_VERSION 发布成功!" echo "📝 Changelog 已更新" echo "🏷️ 标签 v$NEW_VERSION 已创建并推送" echo "" echo "下一步:" echo "1. 在 GitHub/GitLab 上创建 Release" echo "2. 将 CHANGELOG.md 中的内容复制到 Release 描述中" echo "3. 上传构建产物 (如果需要)" ================================================ FILE: scripts/replaceColors.mjs ================================================ import fs from 'fs'; import path from 'path'; const rootDir = path.join('src', 'uni_modules', 'uview-pro', 'components'); const replacements = new Map( Object.entries({ '#ffffff': 'var(--u-white-color)', '#fefefe': 'var(--u-white-color)', '#000000': 'var(--u-black-color)', '#303133': 'var(--u-main-color)', '#323233': 'var(--u-main-color)', '#333333': 'var(--u-main-color)', '#585858': 'var(--u-content-color)', '#606266': 'var(--u-content-color)', '#909399': 'var(--u-tips-color)', '#969799': 'var(--u-tips-color)', '#888992': 'var(--u-tips-color)', '#888888': 'var(--u-tips-color)', '#8799a3': 'var(--u-tips-color)', '#8f8d8e': 'var(--u-tips-color)', '#b2b2b2': 'var(--u-light-color)', '#b7b7b7': 'var(--u-light-color)', '#c0c4cc': 'var(--u-light-color)', '#c7c7c7': 'var(--u-light-color)', '#c8c9cc': 'var(--u-type-info-disabled)', '#cccccc': 'var(--u-light-color)', '#d4d4d4': 'var(--u-divider-color)', '#dcdfe6': 'var(--u-border-color)', '#dddddd': 'var(--u-divider-color)', '#e1e1e1': 'var(--u-divider-color)', '#e4e4e4': 'var(--u-divider-color)', '#e4e7ed': 'var(--u-border-color)', '#e5e5e5': 'var(--u-divider-color)', '#e7e6eb': 'var(--u-divider-color)', '#eaeef1': 'var(--u-bg-gray-light)', '#ebedf0': 'var(--u-bg-gray-light)', '#ebeef5': 'var(--u-bg-gray-light)', '#ececec': 'var(--u-divider-color)', '#eeeeef': 'var(--u-divider-color)', '#f2f2f2': 'var(--u-bg-gray-light)', '#f2f3f5': 'var(--u-bg-gray-light)', '#f3f4f6': 'var(--u-bg-color)', '#f7f7f7': 'var(--u-bg-gray-light)', '#f7f8fa': 'var(--u-bg-gray-light)', '#f56c6c': 'var(--u-type-error)', '#fa3534': 'var(--u-type-error)', '#fde2e2': 'var(--u-type-error-light)', '#faecd8': 'var(--u-type-warning-light)', '#ff9900': 'var(--u-type-warning)', '#19be6b': 'var(--u-type-success)', '#00c777': 'var(--u-type-success)', '#04b00f': 'var(--u-type-success-dark)', '#bef5c8': 'var(--u-type-success-light)', '#2979ff': 'var(--u-type-primary)', '#fff': 'var(--u-white-color)', '#000': 'var(--u-black-color)', '#333': 'var(--u-main-color)', '#bbb': 'var(--u-light-color)', '#eee': 'var(--u-divider-color)', '#ddd': 'var(--u-divider-color)' }) ); const filesUpdated = []; function replaceInFile(filePath) { let content = fs.readFileSync(filePath, 'utf8'); let replaced = false; replacements.forEach((value, key) => { const pattern = new RegExp(key.replace('#', '\\#'), 'gi'); if (pattern.test(content)) { content = content.replace(pattern, value); replaced = true; } }); if (replaced) { fs.writeFileSync(filePath, content, 'utf8'); filesUpdated.push(filePath); } } function walk(dir) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { walk(fullPath); } else if (entry.isFile()) { replaceInFile(fullPath); } } } walk(rootDir); console.log(`Updated ${filesUpdated.length} files.`); ================================================ FILE: scripts/test-npm-cleanup.js ================================================ #!/usr/bin/env node const fs = require('fs'); const path = require('path'); const { spawnSync } = require('child_process'); const root = path.resolve(__dirname, '..'); const packageDir = path.join(root, 'src', 'uni_modules', 'uview-pro'); const nodeModulesPath = path.join(root, 'node_modules', 'uview-pro'); function log(...args) { console.log('[test-npm-cleanup]', ...args); } // 删除 node_modules/uview-pro(若存在) try { if (fs.existsSync(nodeModulesPath)) { fs.rmSync(nodeModulesPath, { recursive: true, force: true }); log('Removed', nodeModulesPath); } else { log('No npm node_modules/uview-pro found.'); } } catch (e) { console.error('Error removing node_modules/uview-pro:', e); } // 删除打包产物 *.tgz try { if (fs.existsSync(packageDir)) { const files = fs.readdirSync(packageDir); files.forEach(f => { if (/^uview-pro-.*\\.tgz$/.test(f)) { const p = path.join(packageDir, f); try { fs.unlinkSync(p); log('Removed', p); } catch (e) {} } }); } } catch (e) { // ignore } log('Cleanup finished. Note: vite.config.ts/pages.json/src/main.ts 的修改需要手动恢复或使用 git checkout。'); ================================================ FILE: scripts/test-npm-package.js ================================================ #!/usr/bin/env node /** * 简化版自动化脚本(用于 test:local) * 功能: * 1) 打包 src/uni_modules/uview-pro(pnpm 优先,fallback npm) * 2) 使用 pnpm/add 或 npm 安装生成的 tgz 到项目(不修改源码,不创建备份) * 3) 修改 vite.config.ts 注释掉本地 alias(根据你的要求) * 4) 修改 src/pages.json 的 easycom 映射为 "uview-pro/..." * * 注意:本脚本不会启动 dev,也不会创建 bak 或自动恢复,所有改动请你自行恢复或使用 cleanup 脚本。 */ const fs = require('fs'); const path = require('path'); const { spawnSync } = require('child_process'); const root = path.resolve(__dirname, '..'); const packageDir = path.join(root, 'src', 'uni_modules', 'uview-pro'); const viteConfigPath = path.join(root, 'vite.config.ts'); const pagesJsonPath = path.join(root, 'src', 'pages.json'); const mainTsPath = path.join(root, 'src', 'main.ts'); function log(...args) { console.log('[test-npm-package]', ...args); } // 简化处理:不使用包管理器 add/tgz 安装,直接拷贝源码到 node_modules/uview-pro function copyDirSync(src, dest) { if (!fs.existsSync(src)) throw new Error('源目录不存在: ' + src); // 删除目标如果存在 if (fs.existsSync(dest)) { fs.rmSync(dest, { recursive: true, force: true }); } fs.mkdirSync(dest, { recursive: true }); const entries = fs.readdirSync(src, { withFileTypes: true }); for (const entry of entries) { const srcPath = path.join(src, entry.name); const destPath = path.join(dest, entry.name); if (entry.isDirectory()) { copyDirSync(srcPath, destPath); } else if (entry.isFile()) { fs.copyFileSync(srcPath, destPath); } } } function installByCopy() { const nodeModulesTarget = path.join(root, 'node_modules', 'uview-pro'); try { log('将源码拷贝到', nodeModulesTarget, '用于本地测试(不会修改 package.json 或 lockfile)'); copyDirSync(packageDir, nodeModulesTarget); log('拷贝完成。'); } catch (e) { console.error('拷贝安装失败:', e); process.exit(1); } } function modifyViteConfig() { try { if (!fs.existsSync(viteConfigPath)) { log('vite.config.ts 未找到,跳过修改'); return; } let content = fs.readFileSync(viteConfigPath, 'utf8'); const lines = content.split(/\r?\n/); let changed = false; const newLines = lines.map(ln => { const trimmed = ln.trim(); // 如果行已经被注释,跳过 if (trimmed.startsWith('//')) return ln; // 如果包含 alias 指向 src/uni_modules/uview-pro 的字符串,将其注释 if (ln.includes('src/uni_modules/uview-pro')) { changed = true; return `// ${ln}`; } return ln; }); if (changed) { fs.writeFileSync(viteConfigPath, newLines.join('\n'), 'utf8'); log('已修改 vite.config.ts(注释包含 uview-pro alias 的行)。'); } else { log('vite.config.ts 中未找到需注释的 uview-pro alias 行,跳过。'); } } catch (e) { console.error('修改 vite.config.ts 失败:', e); } } function modifyPagesJson() { try { if (!fs.existsSync(pagesJsonPath)) { log('src/pages.json 未找到,跳过修改'); return; } let content = fs.readFileSync(pagesJsonPath, 'utf8'); // 将 easycom 的映射从 "@/uni_modules/uview-pro/..." 改为 "uview-pro/..." content = content.replace( /"@\/uni_modules\/uview-pro\/components\/u-\$1\/u-\$1\.vue"/g, `"uview-pro/components/u-$1/u-$1.vue"` ); // 也尝试不带 quotes 的老格式 content = content.replace( /@\/uni_modules\/uview-pro\/components\/u-\$1\/u-\$1\.vue/g, `uview-pro/components/u-$1/u-$1.vue` ); fs.writeFileSync(pagesJsonPath, content, 'utf8'); log('已修改 src/pages.json(easycom 映射改为 uview-pro)。'); } catch (e) { console.error('修改 src/pages.json 失败:', e); } } function ensureMainImport() { try { if (!fs.existsSync(mainTsPath)) { log('src/main.ts 未找到,跳过 import 替换'); return; } let content = fs.readFileSync(mainTsPath, 'utf8'); if (content.indexOf("from 'uview-pro'") === -1 && content.indexOf('from "uview-pro"') === -1) { // 替换 "@/uni_modules/uview-pro" 为 "uview-pro" content = content.replace(/from\s+['"]@\/uni_modules\/uview-pro['"]/g, `from 'uview-pro'`); fs.writeFileSync(mainTsPath, content, 'utf8'); log("已替换 src/main.ts 的导入为 from 'uview-pro'。"); } else { log("src/main.ts 已使用 from 'uview-pro',无需修改。"); } } catch (e) { console.error('处理 src/main.ts 失败:', e); } } function main() { log('开始执行 test-npm 步骤(不会启动 dev,且不会创建 bak/自动恢复)。'); // 1. 直接把 src/uni_modules/uview-pro 拷贝到 node_modules/uview-pro(不改 package.json / lockfile) installByCopy(); // 3. 修改 vite.config.ts 注释 alias modifyViteConfig(); // 4. 修改 pages.json 替换 easycom 映射 modifyPagesJson(); // 5. 确保 main.ts 导入使用 'uview-pro' ensureMainImport(); log( '全部步骤完成。请手动运行 dev(例如:pnpm run dev 或 npm run dev),并在测试完成后手动清理或使用 npm run test:npm:cleanup。' ); } main(); ================================================ FILE: scripts/update-date.js ================================================ #!/usr/bin/env node /** * 更新发布日期脚本 * 用于在package.json中添加或更新发布日期字段 * 使用方法: * node scripts/update-date.js [package.json路径] * 如果不指定路径,默认更新当前目录的package.json */ const fs = require('fs'); const path = require('path'); // 获取命令行参数 const args = process.argv.slice(2); const packageJsonPath = args[0] || path.join(process.cwd(), 'package.json'); // 获取当前日期 (YYYY-MM-DD格式) function getCurrentDate() { const now = new Date(); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } // 检查文件是否存在 if (!fs.existsSync(packageJsonPath)) { console.error(`❌ 文件不存在: ${packageJsonPath}`); process.exit(1); } try { // 读取package.json const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); // 获取当前日期 const currentDate = getCurrentDate(); // 添加或更新编译日期 packageJson.buildDate = currentDate; // 写回文件,保持格式化 fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); console.log(`✅ 编译日期已更新: ${currentDate}`); console.log(`📄 文件: ${packageJsonPath}`); } catch (error) { console.error('❌ 更新发布日期失败:', error.message); process.exit(1); } ================================================ FILE: shims-uni.d.ts ================================================ /// import 'vue'; declare module '@vue/runtime-core' { type Hooks = App.AppInstance & Page.PageInstance; interface ComponentCustomOptions extends Hooks {} } ================================================ FILE: src/App.ku.vue ================================================ ================================================ FILE: src/App.vue ================================================ ================================================ FILE: src/api/index.ts ================================================ import { Request } from 'uview-pro'; export const http = new Request(); http.setConfig({ baseUrl: '/static/app' }); http.interceptor.response = async (response: any) => { const { statusCode, data: rawData, errMsg } = response as any; return rawData; }; export function getJson(id: string) { return loadJSON(`/${id}.json`); } export function getMarkdown(id: string) { return loadJSON(`/markdown/${id}.md`); } function loadJSON(path: string) { // 动态读取本地 json 文件,path 需以 /app/ 开头 // #ifdef APP-HARMONY return new Promise((resolve, reject) => { const fs = uni.getFileSystemManager(); const filePath = path.startsWith('/') ? `/static/app${path}` : `/static/app/${path}`; fs.readFile({ filePath, encoding: 'utf-8', success: res => { try { // res.data 可能为 string 或 ArrayBuffer const data = typeof res.data === 'string' ? res.data : ''; resolve(data); } catch (e) { console.error(e); reject(e); } }, fail: err => { reject(err); } }); }); // #endif // #ifndef APP-HARMONY return http.get(path, { t: Date.now() }, { meta: { loading: false } }); // #endif } ================================================ FILE: src/common/classify.data.ts ================================================ export default [ { name: '女装', foods: [ { name: 'A字裙', key: 'A字裙', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/1.png', cat: 10 }, { name: 'T恤', key: 'T恤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/2.png', cat: 10 }, { name: '半身裙', key: '半身裙', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/3.png', cat: 10 }, { name: '衬衫', key: '衬衫', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/4.png', cat: 10 }, { name: '短裙', key: '短裙', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/5.png', cat: 10 }, { name: '阔腿裤', key: '阔腿裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/6.png', cat: 10 }, { name: '连衣裙', key: '连衣裙', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/7.png', cat: 10 }, { name: '妈妈装', key: '妈妈装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/8.png', cat: 10 }, { name: '牛仔裤', key: '牛仔裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/9.png', cat: 10 }, { name: '情侣装', key: '情侣装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/10.png', cat: 10 }, { name: '休闲裤', key: '休闲裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/11.png', cat: 10 }, { name: '雪纺衫', key: '雪纺衫', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/12.png', cat: 10 }, { name: '防晒衣', key: '防晒衣', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/13.png', cat: 10 }, { name: '礼服/婚纱', key: '礼服婚纱', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/1/14.png', cat: 10 } ] }, { name: '美食', foods: [ { name: '火锅', key: '火锅', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/1.png', cat: 6 }, { name: '糕点饼干', key: '糕点饼干', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/2.png', cat: 6 }, { name: '坚果果干', key: '坚果果干', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/3.png', cat: 6 }, { name: '酒类', key: '酒类', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/4.png', cat: 6 }, { name: '辣条', key: '辣条', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/5.png', cat: 6 }, { name: '大礼包', key: '大礼包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/6.png', cat: 6 }, { name: '精品茗茶', key: '茶', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/7.png', cat: 6 }, { name: '休闲食品', key: '休闲食品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/8.png', cat: 6 }, { name: '糖果巧克力', key: '糖果巧克力', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/9.png', cat: 6 }, { name: '方便速食', key: '方便速食', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/10.png', cat: 6 }, { name: '营养代餐', key: '营养代餐', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/11.png', cat: 6 }, { name: '粮油副食', key: '粮油', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/12.png', cat: 6 }, { name: '生鲜水果', key: '水果', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/13.png', cat: 6 }, { name: '饮品', key: '饮品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/2/14.png', cat: 6 } ] }, { name: '美妆', foods: [ { name: '化妆刷', key: '化妆刷', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/1.png', cat: 3 }, { name: '粉底', key: '粉底', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/2.png', cat: 3 }, { name: '洗发护发', key: '洗发护发', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/3.png', cat: 3 }, { name: '美容工具', key: '美容工具', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/4.png', cat: 3 }, { name: '眼部护理', key: '眼部护理', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/5.png', cat: 3 }, { name: '眉妆', key: '眉妆', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/6.png', cat: 3 }, { name: '卸妆品', key: '卸妆品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/7.png', cat: 3 }, { name: '基础护肤', key: '基础护肤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/8.png', cat: 3 }, { name: '眼妆', key: '眼妆', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/9.png', cat: 3 }, { name: '唇妆', key: '唇妆', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/10.png', cat: 3 }, { name: '面膜', key: '面膜', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/11.png', cat: 3 }, { name: '沐浴用品', key: '沐浴用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/12.png', cat: 3 }, { name: '护肤套装', key: '护肤套装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/13.png', cat: 3 }, { name: '防晒品', key: '防晒品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/14.png', cat: 3 }, { name: '美甲', key: '美甲', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/3/15.png', cat: 3 } ] }, { name: '居家日用', foods: [ { name: '垃圾袋', key: '垃圾袋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/1.png', cat: 4 }, { name: '纸巾', key: '纸巾', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/2.png', cat: 4 }, { name: '驱蚊用品', key: '驱蚊用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/3.png', cat: 4 }, { name: '收纳神器', key: '收纳神器', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/4.png', cat: 4 }, { name: '厨房用品', key: '厨房用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/5.png', cat: 4 }, { name: '厨房烹饪', key: '烹饪', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/6.png', cat: 4 }, { name: '衣物晾晒', key: '衣物晾晒', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/7.png', cat: 4 }, { name: '衣物护理', key: '衣物护理', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/8.png', cat: 4 }, { name: '宠物用品', key: '宠物用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/9.png', cat: 4 }, { name: '医药保健', key: '医药', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/10.png', cat: 4 }, { name: '日用百货', key: '百货', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/11.png', cat: 4 }, { name: '清洁用品', key: '清洁', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/12.png', cat: 4 }, { name: '绿植园艺', key: '绿植', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/4/13.png', cat: 4 } ] }, { name: '男装', foods: [ { name: '爸爸装', key: '爸爸装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/1.png', cat: 12 }, { name: '牛仔裤', key: '牛仔裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/2.png', cat: 12 }, { name: '衬衫', key: '衬衫', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/3.png', cat: 12 }, { name: '休闲裤', key: '休闲裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/4.png', cat: 12 }, { name: '外套', key: '外套', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/5.png', cat: 12 }, { name: 'T恤', key: 'T恤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/6.png', cat: 12 }, { name: '套装', key: '套装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/7.png', cat: 12 }, { name: '运动裤', key: '运动裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/8.png', cat: 12 }, { name: '马甲/背心', key: '马甲背心', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/9.png', cat: 12 }, { name: 'POLO衫', key: 'POLO衫', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/10.png', cat: 12 }, { name: '商务装', key: '商务装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/5/11.png', cat: 12 } ] }, { name: '鞋品', foods: [ { name: '单鞋', key: '单鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/1.png', cat: 5 }, { name: '皮鞋', key: '皮鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/2.png', cat: 5 }, { name: '帆布鞋', key: '帆布鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/3.png', cat: 5 }, { name: '北京老布鞋', key: '北京老布鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/4.png', cat: 5 }, { name: '运动鞋', key: '运动鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/5.png', cat: 5 }, { name: '拖鞋', key: '拖鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/6.png', cat: 5 }, { name: '凉鞋', key: '凉鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/7.png', cat: 5 }, { name: '休闲鞋', key: '休闲鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/8.png', cat: 5 }, { name: '高跟鞋', key: '高跟鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/9.png', cat: 5 }, { name: '老人鞋', key: '老人鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/10.png', cat: 5 }, { name: '懒人鞋', key: '懒人鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/6/11.png', cat: 5 } ] }, { name: '数码家电', foods: [ { name: '数据线', key: '数据线', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/1.png', cat: 8 }, { name: '耳机', key: '耳机', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/2.png', cat: 8 }, { name: '生活家电', key: '家电', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/3.png', cat: 8 }, { name: '电风扇', key: '电风扇', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/4.png', cat: 8 }, { name: '电吹风', key: '电吹风', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/5.png', cat: 8 }, { name: '手机壳', key: '手机壳', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/6.png', cat: 8 }, { name: '榨汁机', key: '榨汁机', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/7.png', cat: 8 }, { name: '小家电', key: '小家电', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/8.png', cat: 8 }, { name: '数码电子', key: '数码', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/9.png', cat: 8 }, { name: '电饭锅', key: '电饭锅', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/10.png', cat: 8 }, { name: '手机支架', key: '手机支架', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/11.png', cat: 8 }, { name: '剃须刀', key: '剃须刀', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/12.png', cat: 8 }, { name: '充电宝', key: '充电宝', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/13.png', cat: 8 }, { name: '手机配件', key: '手机配件', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/7/14.png', cat: 8 } ] }, { name: '母婴', foods: [ { name: '婴童服饰', key: '衣服', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/1.png', cat: 2 }, { name: '玩具乐器', key: '玩具乐器', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/2.png', cat: 2 }, { name: '尿不湿', key: '尿不湿', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/3.png', cat: 2 }, { name: '安抚牙胶', key: '安抚牙胶', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/4.png', cat: 2 }, { name: '奶瓶奶嘴', key: '奶瓶奶嘴', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/5.png', cat: 2 }, { name: '孕妈用品', key: '孕妈用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/6.png', cat: 2 }, { name: '宝宝用品', key: '宝宝用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/7.png', cat: 2 }, { name: '婴童湿巾', key: '湿巾', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/8.png', cat: 2 }, { name: '喂养洗护', key: '洗护', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/9.png', cat: 2 }, { name: '婴童鞋靴', key: '童鞋', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/10.png', cat: 2 }, { name: '口水巾', key: '口水巾', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/11.png', cat: 2 }, { name: '营养辅食', key: '营养', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/12.png', cat: 2 }, { name: '婴幼书籍', key: '书籍', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/13.png', cat: 2 }, { name: '婴儿车', key: '婴儿车', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/8/14.png', cat: 2 } ] }, { name: '箱包', foods: [ { name: '单肩包', key: '单肩包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/1.png', cat: 0 }, { name: '斜挎包', key: '斜挎包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/2.png', cat: 0 }, { name: '女包', key: '女包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/3.png', cat: 0 }, { name: '男包', key: '男包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/4.png', cat: 0 }, { name: '双肩包', key: '双肩包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/5.png', cat: 0 }, { name: '小方包', key: '小方包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/6.png', cat: 0 }, { name: '钱包', key: '钱包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/7.png', cat: 0 }, { name: '旅行箱包', key: '旅行箱包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/8.png', cat: 0 }, { name: '零钱包', key: '零钱包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/9.png', cat: 0 }, { name: '手提包', key: '手提包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/10.png', cat: 0 }, { name: '胸包', key: '胸包', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/9/11.png', cat: 0 } ] }, { name: '内衣', foods: [ { name: '袜子', key: '袜子', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/1.png', cat: 11 }, { name: '吊带背心', key: '吊带背心', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/2.png', cat: 11 }, { name: '抹胸', key: '抹胸', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/3.png', cat: 11 }, { name: '内裤', key: '内裤', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/4.png', cat: 11 }, { name: '文胸', key: '文胸', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/5.png', cat: 11 }, { name: '文胸套装', key: '文胸套装', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/6.png', cat: 11 }, { name: '打底塑身', key: '打底塑身', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/7.png', cat: 11 }, { name: '家居服', key: '家居服', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/8.png', cat: 11 }, { name: '船袜', key: '船袜', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/9.png', cat: 11 }, { name: '情侣睡衣', key: '情侣睡衣', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/10.png', cat: 11 }, { name: '丝袜', key: '丝袜', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/10/11.png', cat: 11 } ] }, { name: '文娱车品', foods: [ { name: '车市车品', key: '车市车品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/1.png', cat: 7 }, { name: '办公文具', key: '办公文具', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/2.png', cat: 7 }, { name: '考试必备', key: '考试必备', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/3.png', cat: 7 }, { name: '笔记本', key: '笔记本', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/4.png', cat: 7 }, { name: '艺术礼品', key: '礼品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/5.png', cat: 7 }, { name: '书写工具', key: '书写工具', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/6.png', cat: 7 }, { name: '车载电器', key: '车载电器', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/7.png', cat: 7 }, { name: '图书音像', key: '图书音像', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/8.png', cat: 7 }, { name: '画具画材', key: '画具画材', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/11/9.png', cat: 7 } ] }, { name: '配饰', foods: [ { name: '太阳镜', key: '太阳镜', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/1.png', cat: 0 }, { name: '皮带', key: '皮带', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/2.png', cat: 0 }, { name: '棒球帽', key: '棒球帽', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/3.png', cat: 0 }, { name: '手表', key: '手表', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/4.png', cat: 0 }, { name: '发饰', key: '发饰', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/5.png', cat: 0 }, { name: '项链', key: '项链', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/6.png', cat: 0 }, { name: '手饰', key: '手饰', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/7.png', cat: 0 }, { name: '耳环', key: '耳环', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/8.png', cat: 0 }, { name: '帽子丝巾', key: '帽子丝巾', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/9.png', cat: 0 }, { name: '眼镜墨镜', key: '眼镜墨镜', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/10.png', cat: 0 }, { name: '发带发箍', key: '发带发箍', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/12/11.png', cat: 0 } ] }, { name: '家装家纺', foods: [ { name: '家居饰品', key: '家居饰品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/1.png', cat: 0 }, { name: '凉席', key: '凉席', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/2.png', cat: 0 }, { name: '背枕靠枕', key: '靠枕', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/3.png', cat: 0 }, { name: '床上用品', key: '床上用品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/4.png', cat: 0 }, { name: '摆件', key: '摆件', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/5.png', cat: 0 }, { name: '四件套', key: '四件套', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/6.png', cat: 0 }, { name: '装饰品', key: '装饰品', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/7.png', cat: 0 }, { name: '卫浴用品', key: '卫浴', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/8.png', cat: 0 }, { name: '家居家装', key: '家具', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/9.png', cat: 0 }, { name: '蚊帐', key: '蚊帐', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/10.png', cat: 0 }, { name: '墙纸贴纸', key: '墙纸', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/11.png', cat: 0 }, { name: '空调被', key: '空调被', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/13/12.png', cat: 0 } ] }, { name: '户外运动', foods: [ { name: '游泳装备', key: '游泳', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/1.png', cat: 0 }, { name: '泳镜', key: '泳镜', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/2.png', cat: 0 }, { name: '户外装备', key: '户外', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/3.png', cat: 0 }, { name: '健身服饰', key: '健身', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/4.png', cat: 0 }, { name: '泳衣', key: '泳衣', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/5.png', cat: 0 }, { name: '瑜伽垫', key: '瑜伽垫', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/6.png', cat: 0 }, { name: '瑜伽用品', key: '瑜伽', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/7.png', cat: 0 }, { name: '健身装备', key: '健身', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/8.png', cat: 0 }, { name: '球迷用品', key: '球迷', icon: 'https://ik.imagekit.io/anyup/uview-pro/template/classify/14/9.png', cat: 0 } ] } ]; ================================================ FILE: src/common/constant.ts ================================================ import { versionName as appVersion } from '../manifest.json'; import { version as uViewProVersion, buildDate, releaseDate } from '../../package.json'; export const APP_INFO: { name: string; version: string; buildTime: string; platform: string; } = { name: 'uViewPro(跨平台UI组件库)', version: appVersion, buildTime: buildDate, platform: getPlatform() }; export const UVIEW_PRO_INFO = { name: 'uview-pro', version: uViewProVersion, buildTime: releaseDate }; function getPlatform() { let platform = uni.getSystemInfoSync().platform; if (platform) { return platform; } // #ifdef H5 platform = 'H5'; // #endif // #ifdef MP-WEIXIN platform = '微信小程序'; // #endif // #ifdef MP-ALIPAY platform = '支付宝小程序'; // #endif // #ifdef APP-PLUS platform = 'App'; // #endif // #ifdef APP-HARMONY platform = 'HarmonyOS'; // #endif platform = '未知平台'; return platform; } type PlatformType = 'H5' | 'weixin' | 'alipay' | 'toutiao' | 'App' | 'HarmonyOS'; export function isPlatform(value: PlatformType | PlatformType[]): boolean { let platform = ''; // #ifdef H5 platform = 'H5'; // #endif // #ifdef MP-WEIXIN platform = 'weixin'; // #endif // #ifdef MP-ALIPAY platform = 'alipay'; // #endif // #ifdef MP-TOUTIAO platform = 'toutiao'; // #endif // #ifdef APP-PLUS platform = 'App'; // #endif // #ifdef APP-HARMONY platform = 'HarmonyOS'; // #endif return Array.isArray(value) ? value.some(v => v.toLowerCase() === platform.toLowerCase()) : platform.toLowerCase() === value.toLowerCase(); } export const ONBOARDING_STORAGE_BASE_KEY = `guide-onboarded-${APP_INFO.version}`; export const GUIDE_TABS_KEY = `guide-page-tabs-${APP_INFO.version}`; export const GUIDE_FAB_KEY = `guide-page-fab-${APP_INFO.version}`; export const GUIDE_TABBAR_KEY = `guide-page-tabbar-${APP_INFO.version}`; export const GUIDE_THEME_SWITCHER_KEY = `guide-theme-switcher-${APP_INFO.version}`; export const GUIDE_EXPERIENCE_KEY = `guide-experience-entry-${APP_INFO.version}`; ================================================ FILE: src/common/demo-experience.config.json ================================================ { "component-image": { "tasks": [ { "key": "status", "title": "切换不同加载状态", "desc": "体验加载成功 / 加载中 / 加载失败三种反馈效果" }, { "key": "slot", "title": "自定义占位反馈", "desc": "启用自定义加载中与错误插槽,观察差异" }, { "key": "shape", "title": "调整图片形状", "desc": "在方形与圆形样式之间切换,感受视觉变化" }, { "key": "source", "title": "切换资源来源", "desc": "在网络图片与本地图片之间切换,体验加载表现" } ] }, "component-button": { "tasks": [ { "key": "type", "title": "切换按钮主题", "desc": "体验 primary / error / warning / success 不同主题风格" }, { "key": "size", "title": "调整按钮尺寸", "desc": "在默认 / 中等 / 迷你之间切换,感受占位变化" }, { "key": "shape", "title": "改变按钮形状", "desc": "在直角与圆角之间切换,观察视觉差异" }, { "key": "plain", "title": "体验镂空样式", "desc": "在是否镂空之间切换,体验不同信息层级" }, { "key": "ripple", "title": "水波纹动效体验", "desc": "开启/关闭水波纹,再点击按钮观察动效" }, { "key": "hairLine", "title": "细边框显示", "desc": "打开或关闭细边框,感受边界勾勒效果" }, { "key": "loading", "title": "加载状态反馈", "desc": "切换按钮加载状态,体验“执行中”反馈样式" } ] }, "component-avatar": { "tasks": [ { "key": "mode", "title": "切换头像形态", "desc": "在圆形与圆角方形之间来回体验" }, { "key": "sex", "title": "调整性别标识", "desc": "切换男 / 女 / 不显示三种性别标识" }, { "key": "level", "title": "显示/隐藏等级", "desc": "控制等级角标的显示与否,感受信息密度变化" }, { "key": "content", "title": "自定义头像内容", "desc": "在图片头像与纯文字头像之间切换" }, { "key": "size", "title": "调整头像尺寸", "desc": "尝试 large / default / mini / 自定义像素四种尺寸" } ] } } ================================================ FILE: src/common/demo.scss ================================================ page { background-color: $u-bg-white; width: 100%; height: 100vh; } /* #ifndef APP-NVUE */ view, text { box-sizing: border-box; } /* #endif */ /* start--演示页面使用的统一样式--start */ .u-demo { padding: 10px 20px 25px 20px; } .u-demo-wrap { border-width: 1px; border-color: $u-border-color; border-style: dashed; background-color: $u-bg-white; padding: 20px 10px; transition: background-color 0.3s ease, border-color 0.3s ease; } .u-demo-area { text-align: center; } .u-no-demo-here { color: $u-tips-color; font-size: 13px; } .u-demo-result-line { border-width: 1px; border-color: $u-border-color; border-style: dashed; padding: 5px 20px; margin-top: 30px; border-radius: 5px; background-color: rgba(var(--u-border-color-rgb), 0.2); color: $u-content-color; font-size: 16px; /* #ifndef APP-NVUE */ word-break: break-word; display: inline-block; /* #endif */ text-align: left; } .u-demo-title, .u-config-title { text-align: center; font-size: 16px; font-weight: bold; margin-bottom: 20px; color: $u-main-color; } .u-config-item { margin-top: 25px; } .u-config-title { margin-top: 20px; padding-bottom: 5px; } .u-item-title { position: relative; font-size: 15px; padding-left: 8px; line-height: 1; margin-bottom: 11px; color: $u-main-color; } .u-item-title:after { position: absolute; width: 4px; top: -1px; height: 16px; /* #ifndef APP-NVUE */ content: ''; /* #endif */ left: 0; border-radius: 10px; background-color: $u-content-color; } .u-block { padding: 14px; &__section { margin-bottom: 10px; } &__title { margin-top: 10px; font-size: 15px; color: $u-content-color; margin-bottom: 10px; } &__flex { /* #ifndef APP-NVUE */ display: flex; /* #endif */ } } // 使用了cell组件的icon图片样式 .u-cell-icon { width: 36rpx; height: 36rpx; margin-right: 8rpx; } .u-page { padding: 15px 15px 40px 15px; } .u-demo-block { flex: 1; margin-bottom: 23px; &__content { @include vue-flex(column); } &__title { font-size: 14px; color: $u-tips-color; margin-bottom: 8px; @include vue-flex; } } /* end--演示页面使用的统一样式--end */ ================================================ FILE: src/common/http.interceptor.ts ================================================ import type { RequestConfig, RequestInterceptor, RequestMeta, RequestOptions } from 'uview-pro'; // 示例:演示如何使用token const token = ''; // 演示 let baseUrl = 'https://env-00jxty5jnvo5-static.normal.cloudstatic.cn'; // #ifdef APP // baseUrl = '/static/app'; // #endif // 演示 function logout() { return new Promise(resolve => { setTimeout(() => { resolve(true); }, 1000); }); } // 全局配置 const httpRequestConfig: RequestConfig = { baseUrl, header: { 'content-type': 'application/json' }, timeout: 50000, meta: { originalData: true, toast: true, loading: true } }; // 请求/响应拦截器 const httpInterceptor: RequestInterceptor = { // 请求拦截器 request: (config: RequestOptions) => { // console.log('请求拦截器', config); const meta: RequestMeta = config.meta || {}; meta.loading && showLoading(); if (token) { config.header.Authorization = `Bearer ${token}`; } return config; }, // 响应拦截器 response: async (response: any) => { // console.log('响应拦截器', response); const meta: RequestMeta = response.config?.meta || {}; meta.loading && hideLoading(); const { statusCode, data: rawData, errMsg } = response as any; // 网络错误 if (errMsg && errMsg.includes('Failed to connect')) { meta.toast && showToast('网络错误', 'error'); throw new Error('网络错误'); } if (errMsg && errMsg.includes('request:fail')) { meta.toast && showToast('请求错误:未知', 'error'); throw new Error('请求错误:未知'); } // 请求错误 if (!(statusCode >= 200 && statusCode < 300)) { const errorMessage = `请求错误[${statusCode}]`; meta.toast && showToast(errorMessage, 'error'); throw new Error(`${errorMessage}:${errMsg}`); } // 业务逻辑错误:登录过期/状态码不正确 // 这里仅为演示,根据实际业务确定 // const { code, msg } = rawData as any; // if (code === 403 || code === 401) { // meta.toast && showToast('登录已过期', 'error'); // await logout(); // setTimeout(() => { // uni.reLaunch({ url: '/pages/login/login' }); // }, 1000); // throw new Error(`请求错误[${code}]:${msg}`); // } else if (!(code >= 200 && code < 300)) { // meta.toast && showToast(msg, 'error', { duration: 2500 }); // throw new Error(`请求错误[${code}]:${msg}`); // } return rawData; } }; // 显示加载中,可以替换为uview-pro的u-loading-popup组件 function showLoading() { uni.showLoading({ title: '加载中...', mask: true }); } // 隐藏加载中,可以替换为uview-pro的u-loading-popup组件 function hideLoading() { // 代码示例使用settimeout,仅为演示,实际开发中去掉 setTimeout(() => { uni.hideLoading(); }, 1000); } // 显示toast,可以替换为uview-pro的u-toast组件 function showToast( title = '', icon: 'success' | 'error' | 'none' = 'none', options: { duration: number } = { duration: 2000 } ) { if (title.length === 0) { return; } // 代码示例使用settimeout,仅为演示,实际开发中去掉 setTimeout(() => { uni.showToast({ title, icon: title.length && title.length > 7 ? 'none' : icon, duration: options.duration || 2000 }); }, 1000); } // 导出 export { httpInterceptor, httpRequestConfig }; ================================================ FILE: src/common/iconfont.css ================================================ @font-face { font-family: 'custom-icon'; /* Project id 5067119 */ src: url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'); } .custom-icon { font-family: 'custom-icon' !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .custom-icon-map-route:before { content: '\e660'; } .custom-icon-compass:before { content: '\e731'; } .custom-icon-guide:before { content: '\e617'; } .custom-icon-levels:before { content: '\e60d'; } .custom-icon-eye:before { content: '\e68e'; } .custom-icon-target:before { content: '\ee64'; } .custom-icon-sparkles:before { content: '\ea28'; } .custom-icon-file-text:before { content: '\ea2e'; } .custom-icon-hand-sparkles:before { content: '\eb43'; } .custom-icon-magic-sparkles:before { content: '\eb67'; } .custom-icon-map-circle-fill:before { content: '\ebff'; } .custom-icon-map-circle:before { content: '\ec00'; } .custom-icon-sun:before { content: '\e712'; } .custom-icon-theme-fill:before { content: '\e615'; } .custom-icon-theme:before { content: '\e60c'; } .custom-icon-star:before { content: '\fb33'; } .custom-icon-template-fill:before { content: '\eac3'; } .custom-icon-tool-fill:before { content: '\e785'; } .custom-icon-about-fill:before { content: '\e79f'; } .custom-icon-component-fill:before { content: '\e605'; } .custom-icon-about:before { content: '\e7a8'; } .custom-icon-template:before { content: '\e60f'; } .custom-icon-component:before { content: '\e759'; } .custom-icon-tool:before { content: '\e78e'; } .custom-icon-auto:before { content: '\e772'; } .custom-icon-moon:before { content: '\e609'; } .custom-icon-layouts:before { content: '\e66e'; } .custom-icon-input:before { content: '\e6fd'; } .custom-icon-textarea:before { content: '\e871'; } .custom-icon-pagination:before { content: '\e681'; } .custom-icon-fab:before { content: '\e656'; } .custom-icon-github:before { content: '\e885'; } .custom-icon-rocket:before { content: '\e651'; } .custom-icon-share1:before { content: '\e655'; } .custom-icon-qq-circle-fill:before { content: '\e887'; } .custom-icon-message:before { content: '\e66f'; } .custom-icon-weixin:before { content: '\e608'; } .custom-icon-gitee:before { content: '\e618'; } .custom-icon-menu1:before { content: '\e706'; } .custom-icon-order:before { content: '\e626'; } .custom-icon-comment:before { content: '\e60a'; } .custom-icon-address:before { content: '\e63e'; } .custom-icon-login:before { content: '\e72a'; } .custom-icon-keyboard:before { content: '\e64b'; } .custom-icon-onekey:before { content: '\e607'; } .custom-icon-usercenter:before { content: '\e678'; } .custom-icon-city:before { content: '\e61d'; } .custom-icon-order2:before { content: '\e603'; } .custom-icon-coupon:before { content: '\e643'; } .custom-icon-menu2:before { content: '\e604'; } .custom-icon-tools:before { content: '\e6cf'; } .custom-icon-clone:before { content: '\e692'; } .custom-icon-color:before { content: '\e601'; } .custom-icon-time:before { content: '\e606'; } .custom-icon-switch:before { content: '\e6c0'; } .custom-icon-throttle:before { content: '\e64a'; } .custom-icon-share:before { content: '\e64c'; } .custom-icon-from:before { content: '\e60b'; } .custom-icon-rect:before { content: '\e92f'; } .custom-icon-network:before { content: '\e99b'; } .custom-icon-route:before { content: '\e65e'; } .custom-icon-http:before { content: '\e616'; } .custom-icon-test:before { content: '\e636'; } .custom-icon-array:before { content: '\e659'; } .custom-icon-merge:before { content: '\e75f'; } .custom-icon-id:before { content: '\e648'; } .custom-icon-random:before { content: '\e650'; } .custom-icon-md5:before { content: '\e600'; } .custom-icon-params:before { content: '\e625'; } .custom-icon-trim:before { content: '\e602'; } ================================================ FILE: src/common/index.list.ts ================================================ export default { list: [ { letter: 'A', data: [ { name: '阿拉斯加', mobile: '13588889999', keyword: '阿拉斯加ABA13588889999' }, { name: '阿克苏', mobile: '0551-4386721', keyword: '阿克苏AKESU0551-4386721' }, { name: '阿拉善', mobile: '4008009100', keyword: '阿拉善ALASHAN4008009100' }, { name: '阿勒泰', mobile: '13588889999', keyword: '阿勒泰ALETAI13588889999' }, { name: '阿里', mobile: '13588889999', keyword: '阿里ALI13588889999' }, { name: '安阳', mobile: '13588889999', keyword: '13588889999安阳ANYANG' } ] }, { letter: 'B', data: [ { name: '白城', mobile: '该主子没有留电话~', keyword: '白城BAICHENG' }, { name: '白山', mobile: '13588889999', keyword: '白山BAISHAN13588889999' }, { name: '白银', mobile: '13588889999', keyword: '白银BAIYIN13588889999' }, { name: '保定', mobile: '13588889999', keyword: '保定BAODING13588889999' } ] }, { letter: 'C', data: [ { name: '沧州', mobile: '13588889999', keyword: '沧州CANGZHOU13588889999' }, { name: '长春', mobile: '13588889999', keyword: '长春CHANGCHUN13588889999' } ] }, { letter: 'D', data: [ { name: '大理', mobile: '13588889999', keyword: '大理DALI13588889999' }, { name: '大连', mobile: '13588889999', keyword: '大连DALIAN13588889999' } ] }, { letter: 'E', data: [ { name: '鄂尔多斯', mobile: '13588889999', keyword: '鄂尔多斯EERDUOSI13588889999' }, { name: '恩施', mobile: '13588889999', keyword: '恩施ENSHI13588889999' }, { name: '鄂州', mobile: '13588889999', keyword: '鄂州EZHOU13588889999' } ] }, { letter: 'F', data: [ { name: '防城港', mobile: '该主子没有留电话~', keyword: '防城港FANGCHENGGANG' }, { name: '抚顺', mobile: '13588889999', keyword: '抚顺FUSHUN13588889999' }, { name: '阜新', mobile: '13588889999', keyword: '阜新FUXIN13588889999' }, { name: '阜阳', mobile: '13588889999', keyword: '阜阳FUYANG13588889999' }, { name: '抚州', mobile: '13588889999', keyword: '抚州FUZHOU13588889999' }, { name: '福州', mobile: '13588889999', keyword: '福州FUZHOU13588889999' } ] }, { letter: 'G', data: [ { name: '甘南', mobile: '13588889999', keyword: '甘南GANNAN13588889999' }, { name: '赣州', mobile: '13588889999', keyword: '赣州GANZHOU13588889999' }, { name: '甘孜', mobile: '13588889999', keyword: '甘孜GANZI13588889999' } ] }, { letter: 'H', data: [ { name: '哈尔滨', mobile: '13588889999', keyword: '哈尔滨HAERBIN13588889999' }, { name: '海北', mobile: '13588889999', keyword: '海北HAIBEI13588889999' }, { name: '海东', mobile: '13588889999', keyword: '海东HAIDONG13588889999' }, { name: '海口', mobile: '13588889999', keyword: '海口HAIKOU13588889999' } ] }, { letter: 'I', data: [ { name: 'ice', mobile: '13588889999', keyword: '佳木斯JIAMUSI13588889999' } ] }, { letter: 'J', data: [ { name: '佳木斯', mobile: '13588889999', keyword: '佳木斯JIAMUSI13588889999' }, { name: '吉安', mobile: '13588889999', keyword: '吉安JIAN13588889999' }, { name: '江门', mobile: '13588889999', keyword: '江门JIANGMEN13588889999' } ] }, { letter: 'K', data: [ { name: '开封', mobile: '13588889999', keyword: '开封KAIFENG13588889999' }, { name: '喀什', mobile: '13588889999', keyword: '喀什KASHI13588889999' }, { name: '克拉玛依', mobile: '13588889999', keyword: '克拉玛依KELAMAYI13588889999' } ] }, { letter: 'L', data: [ { name: '来宾', mobile: '13588889999', keyword: '来宾LAIBIN13588889999' }, { name: '兰州', mobile: '13588889999', keyword: '兰州LANZHOU13588889999' }, { name: '拉萨', mobile: '13588889999', keyword: '拉萨LASA13588889999' }, { name: '乐山', mobile: '13588889999', keyword: '乐山LESHAN13588889999' }, { name: '凉山', mobile: '13588889999', keyword: '凉山LIANGSHAN13588889999' }, { name: '连云港', mobile: '13588889999', keyword: '连云港LIANYUNGANG13588889999' }, { name: '聊城', mobile: '18322223333', keyword: '聊城LIAOCHENG18322223333' }, { name: '辽阳', mobile: '18322223333', keyword: '辽阳LIAOYANG18322223333' }, { name: '辽源', mobile: '18322223333', keyword: '辽源LIAOYUAN18322223333' }, { name: '丽江', mobile: '18322223333', keyword: '丽江LIJIANG18322223333' }, { name: '临沧', mobile: '18322223333', keyword: '临沧LINCANG18322223333' }, { name: '临汾', mobile: '18322223333', keyword: '临汾LINFEN18322223333' }, { name: '临夏', mobile: '18322223333', keyword: '临夏LINXIA18322223333' }, { name: '临沂', mobile: '18322223333', keyword: '临沂LINYI18322223333' }, { name: '林芝', mobile: '18322223333', keyword: '林芝LINZHI18322223333' }, { name: '丽水', mobile: '18322223333', keyword: '丽水LISHUI18322223333' } ] }, { letter: 'M', data: [ { name: '眉山', mobile: '15544448888', keyword: '眉山MEISHAN15544448888' }, { name: '梅州', mobile: '15544448888', keyword: '梅州MEIZHOU15544448888' }, { name: '绵阳', mobile: '15544448888', keyword: '绵阳MIANYANG15544448888' }, { name: '牡丹江', mobile: '15544448888', keyword: '牡丹江MUDANJIANG15544448888' } ] }, { letter: 'N', data: [ { name: '南昌', mobile: '15544448888', keyword: '南昌NANCHANG15544448888' }, { name: '南充', mobile: '15544448888', keyword: '南充NANCHONG15544448888' }, { name: '南京', mobile: '15544448888', keyword: '南京NANJING15544448888' }, { name: '南宁', mobile: '15544448888', keyword: '南宁NANNING15544448888' }, { name: '南平', mobile: '15544448888', keyword: '南平NANPING15544448888' } ] }, { letter: 'O', data: [ { name: '欧阳', mobile: '15544448888', keyword: '欧阳ouyang15544448888' } ] }, { letter: 'P', data: [ { name: '盘锦', mobile: '15544448888', keyword: '盘锦PANJIN15544448888' }, { name: '攀枝花', mobile: '15544448888', keyword: '攀枝花PANZHIHUA15544448888' }, { name: '平顶山', mobile: '15544448888', keyword: '平顶山PINGDINGSHAN15544448888' }, { name: '平凉', mobile: '15544448888', keyword: '平凉PINGLIANG15544448888' }, { name: '萍乡', mobile: '15544448888', keyword: '萍乡PINGXIANG15544448888' }, { name: '普洱', mobile: '15544448888', keyword: '普洱PUER15544448888' }, { name: '莆田', mobile: '15544448888', keyword: '莆田PUTIAN15544448888' }, { name: '濮阳', mobile: '15544448888', keyword: '濮阳PUYANG15544448888' } ] }, { letter: 'Q', data: [ { name: '黔东南', mobile: '15544448888', keyword: '黔东南QIANDONGNAN15544448888' }, { name: '黔南', mobile: '15544448888', keyword: '黔南QIANNAN15544448888' }, { name: '黔西南', mobile: '15544448888', keyword: '黔西南QIANXINAN15544448888' } ] }, { letter: 'R', data: [ { name: '日喀则', mobile: '15544448888', keyword: '日喀则RIKAZE15544448888' }, { name: '日照', mobile: '15544448888', keyword: '日照RIZHAO15544448888' } ] }, { letter: 'S', data: [ { name: '三门峡', mobile: '15544448888', keyword: '三门峡SANMENXIA15544448888' }, { name: '三明', mobile: '15544448888', keyword: '三明SANMING15544448888' }, { name: '三沙', mobile: '15544448888', keyword: '三沙SANSHA15544448888' } ] }, { letter: 'T', data: [ { name: '塔城', mobile: '15544448888', keyword: '塔城TACHENG15544448888' }, { name: '漯河', mobile: '15544448888', keyword: '漯河TAHE15544448888' }, { name: '泰安', mobile: '15544448888', keyword: '泰安TAIAN15544448888' } ] }, { letter: 'W', data: [ { name: '潍坊', mobile: '15544448888', keyword: '潍坊WEIFANG15544448888' }, { name: '威海', mobile: '15544448888', keyword: '威海WEIHAI15544448888' }, { name: '渭南', mobile: '15544448888', keyword: '渭南WEINAN15544448888' }, { name: '文山', mobile: '15544448888', keyword: '文山WENSHAN15544448888' } ] }, { letter: 'X', data: [ { name: '厦门', mobile: '15544448888', keyword: '厦门XIAMEN15544448888' }, { name: '西安', mobile: '15544448888', keyword: '西安XIAN15544448888' }, { name: '湘潭', mobile: '15544448888', keyword: '湘潭XIANGTAN15544448888' } ] }, { letter: 'Y', data: [ { name: '雅安', mobile: '15544448888', keyword: '雅安YAAN15544448888' }, { name: '延安', mobile: '15544448888', keyword: '延安YANAN15544448888' }, { name: '延边', mobile: '15544448888', keyword: '延边YANBIAN15544448888' }, { name: '盐城', mobile: '15544448888', keyword: '盐城YANCHENG15544448888' } ] }, { letter: 'Z', data: [ { name: '枣庄', mobile: '15544448888', keyword: '枣庄ZAOZHUANG15544448888' }, { name: '张家界', mobile: '15544448888', keyword: '张家界ZHANGJIAJIE15544448888' }, { name: '张家口', mobile: '15544448888', keyword: '张家口ZHANGJIAKOU15544448888' } ] }, { letter: '#', data: [ { name: '其他', mobile: '16666666666', keyword: 'echo16666666666' } ] } ] }; ================================================ FILE: src/common/request.ts ================================================ import { deepMerge } from 'uview-pro'; /** * 请求配置项Meta类型定义 */ export interface RequestMeta { toast?: boolean; loading?: boolean; originalData?: boolean; [key: string]: any; } /** * 请求配置项类型定义 */ export interface RequestConfig { baseUrl?: string; header?: Record; method?: string; dataType?: string; responseType?: string; timeout?: number; meta?: RequestMeta; [key: string]: any; } /** * 忽略的请求参数类型定义 */ const IGNORE_REQUEST_KEYS = ['baseUrl', 'meta']; /** * 请求拦截器类型定义 */ export interface RequestInterceptor { request?: ((options: RequestOptions) => RequestOptions | false) | null; response?: ((response: any) => any | false) | null; } /** * 请求参数类型定义 */ export interface RequestOptions { url: string; header: Record; method: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT'; data?: any; dataType?: string; responseType?: string; params?: Record; complete?: (response: any) => void; meta?: RequestMeta; [key: string]: any; } export class Request { public config: RequestConfig; public interceptor: RequestInterceptor; public options?: RequestOptions; // per-request storage to avoid concurrent overwrites of instance-level `options` private _requestMap: Map = new Map(); private _taskMap: Map = new Map(); // store uni.request task for abort private _rejectMap: Map void> = new Map(); private _reqId = 0; constructor() { this.config = { baseUrl: '', // 请求的根域名 header: {}, // 默认的请求头 method: 'POST', // 请求方式 dataType: 'json', // 设置为json,返回后uni.request会对数据进行一次JSON.parse responseType: 'text', // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可 timeout: 60000, meta: { originalData: true, // 是否在拦截器中返回服务端的原始数据,见文档说明 toast: false, // 是否在请求出错时,弹出toast loading: false // 是否显示加载中 } }; this.interceptor = { request: null, response: null }; } /** * 返回当前未完成请求的快照(用于调试) * 返回数组,元素为 { id, options } 的浅拷贝,不会暴露内部 Map 引用 */ public getPendingRequestOptions(): Array<{ id: number; options: RequestOptions }> { const result: Array<{ id: number; options: RequestOptions }> = []; for (const [id, opts] of this._requestMap.entries()) { result.push({ id, options: { ...opts } }); } return result; } /** * 按 id 取消请求(如果还在 pending) * 返回取消结果和是否已发送(sent) */ public cancelRequestById(id: number): { cancelled: boolean; sent: boolean } { const task = this._taskMap.get(id); const reject = this._rejectMap.get(id); let cancelled = false; let sent = false; try { if (task) { sent = true; if (typeof task.abort === 'function') { task.abort(); cancelled = true; } } } catch (e) { // ignore abort errors but still attempt reject/cleanup } if (reject) { try { reject(new Error('Request cancelled by id')); } catch (e) { // swallow } cancelled = true; } // cleanup maps this._taskMap.delete(id); this._rejectMap.delete(id); this._requestMap.delete(id); return { cancelled, sent }; } /** * 取消所有未完成的请求,返回每个请求的取消结果 */ public cancelAllPendingRequests(): Array<{ id: number; cancelled: boolean; sent: boolean }> { const results: Array<{ id: number; cancelled: boolean; sent: boolean }> = []; const ids = Array.from(this._requestMap.keys()); for (const id of ids) { const res = this.cancelRequestById(id); results.push({ id, cancelled: res.cancelled, sent: res.sent }); } return results; } /** * 根据 URL 或正则取消匹配的未完成请求 * @param urlOrRegex 字符串或 RegExp,字符串支持精确匹配或作为子串匹配 * @returns 每个被尝试取消请求的结果数组 */ public cancelRequestsByUrl( urlOrRegex: string | RegExp ): Array<{ id: number; url: string; cancelled: boolean; sent: boolean }> { const results: Array<{ id: number; url: string; cancelled: boolean; sent: boolean }> = []; const matcher = typeof urlOrRegex === 'string' ? (u: string) => u === urlOrRegex || u.endsWith(urlOrRegex) || u.indexOf(urlOrRegex) !== -1 : (u: string) => (urlOrRegex as RegExp).test(u); for (const [id, opts] of this._requestMap.entries()) { const u = opts?.url || ''; try { if (matcher(u)) { const res = this.cancelRequestById(id); results.push({ id, url: u, cancelled: res.cancelled, sent: res.sent }); } } catch (e) { results.push({ id, url: u, cancelled: false, sent: Boolean(this._taskMap.get(id)) }); } } return results; } /** * 将全局配置合并到本次请求的 options 中 * - 忽略 IGNORE_REQUEST_KEYS 中的字段(如 meta) * - 对 header 使用深合并(全局 header 为默认,options.header 优先) * - 对对象类型的字段尝试深合并,基础类型以 options 值优先 * - 处理 baseUrl:若存在全局 baseUrl 且 options.url 非完整 url(非 http 开头),则合并成完整 URL */ private mergeGlobalConfigToOptions(options: RequestOptions): RequestOptions { const mergedOptions: RequestOptions = { ...options }; for (const key of Object.keys(this.config)) { if (IGNORE_REQUEST_KEYS.includes(key)) { continue; } const cfgVal = this.config[key]; const optVal = options[key]; // 跳过未设置的全局配置 if (cfgVal === undefined) continue; // header 需要做深合并,且以 options.header 为准覆盖同名属性 if (key === 'header') { mergedOptions.header = deepMerge(cfgVal || {}, optVal || {}); continue; } // 针对 method 等枚举字符串,优先使用 options 中的值,否则使用全局配置 if (typeof cfgVal === 'string' || typeof cfgVal === 'number' || typeof cfgVal === 'boolean') { mergedOptions[key] = optVal !== undefined ? optVal : cfgVal; continue; } // 对对象类型的配置(如自定义扩展)尝试做深合并 if (typeof cfgVal === 'object' && !Array.isArray(cfgVal)) { mergedOptions[key] = deepMerge(cfgVal || {}, optVal || {}); continue; } // 其他类型,若 options 未传入则使用全局配置 if (optVal === undefined) { mergedOptions[key] = cfgVal; } } // 如果存在 baseUrl,并且 options.url 为相对地址,则拼接成完整 url const baseUrl = this.config.baseUrl; if ( baseUrl && mergedOptions.url && typeof mergedOptions.url === 'string' && mergedOptions.url.indexOf('http') !== 0 ) { mergedOptions.url = baseUrl + (mergedOptions.url.indexOf('/') === 0 ? mergedOptions.url : `/${mergedOptions.url}`); } // 确保 url 存在,且为 string if (!mergedOptions.url) { mergedOptions.url = ''; } return mergedOptions; } /** * 验证并规范化 RequestOptions,返回规范化后的对象 * - 确保 url 为 string * - 确保 method 为大写且在允许集合内;否则使用全局默认 method * - 确保 header 为对象 */ private validateOptions(options: RequestOptions): RequestOptions { const normalized: RequestOptions = { ...options }; // url normalized.url = normalized.url == null ? '' : String(normalized.url); // header if (!normalized.header || typeof normalized.header !== 'object' || Array.isArray(normalized.header)) { normalized.header = {}; } // method const allowedMethods = new Set(['GET', 'POST', 'OPTIONS', 'HEAD', 'PUT', 'DELETE', 'TRACE', 'CONNECT']); if (normalized.method) { const m = String(normalized.method).toUpperCase(); normalized.method = (allowedMethods.has(m) ? m : String(this.config.method || 'POST')) as any; } else { normalized.method = (String(this.config.method || 'POST').toUpperCase() as any) || 'POST'; } // meta default if (!normalized.meta || typeof normalized.meta !== 'object') { normalized.meta = normalized.meta || {}; } return normalized; } /** * 设置全局默认配置 * @param customConfig 自定义配置 */ setConfig(customConfig: Partial): void { this.config = deepMerge(this.config, customConfig); } /** * 主要请求部分 * @param options 请求参数 */ request(options: RequestOptions): Promise { // 合并 meta 配置,优先级:单次请求 > 全局 const mergedMeta: RequestMeta = { ...this.config.meta, ...(options.meta || {}) }; // 让 options.meta 传递到拦截器 options.meta = mergedMeta; options.url = options.url || ''; options.params = options.params || {}; // 将全局配置合并到本次请求 options 中(注意忽略一些特殊字段如 baseUrl/meta) options = this.mergeGlobalConfigToOptions(options); // 对合并后的 options 做一次规范化校验 options = this.validateOptions(options); if (this.interceptor.request && typeof this.interceptor.request === 'function') { const interceptorRequest = this.interceptor.request(options); // 保持兼容:原逻辑中若返回 falsy 则视为取消请求,返回一个 pending Promise if (!interceptorRequest) { return new Promise(() => {}); } // 若返回对象,则校验并使用拦截器返回的 options if (typeof interceptorRequest === 'object') { const validated = this.validateOptions(interceptorRequest as RequestOptions); options = validated; } else { // 若返回非对象且非 false,则视为拦截器实现错误,reject return Promise.reject(new Error('Interceptor must return false or a RequestOptions object')); } } // 为避免并发写入实例级 `options`,使用 per-request id 存储本次请求参数(供调试/排查) const reqId = ++this._reqId; this._requestMap.set(reqId, options); return new Promise((resolve, reject) => { // 保存 reject 以便外部 cancel 使用 this._rejectMap.set(reqId, reject); options.complete = (response: any) => { // 清理对应请求的存储 this._requestMap.delete(reqId); this._taskMap.delete(reqId); this._rejectMap.delete(reqId); // 读取 meta 配置 const meta = options.meta || this.config.meta || {}; const originalData = meta.originalData ?? false; // 拦截器处理,加入request的配置参数 response.config = options; if (originalData) { // 判断是否存在拦截器 if (this.interceptor.response && typeof this.interceptor.response === 'function') { const resInterceptors = this.interceptor.response(response); // 如果拦截器不返回false,就将拦截器返回的内容给请求的then回调 if (resInterceptors !== false) { resolve(resInterceptors); } else { // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调 reject(response); } } else { // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据 resolve(response); } } else { if (response.statusCode === 200) { if (this.interceptor.response && typeof this.interceptor.response === 'function') { const resInterceptors = this.interceptor.response(response.data); if (resInterceptors !== false) { resolve(resInterceptors); } else { reject(response.data); } } else { // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调 resolve(response.data); } } else { reject(response); } } }; try { const task = uni.request(options); // 保存 request task 以便 cancel this._taskMap.set(reqId, task); } catch (err) { // 捕获同步抛出的异常并 reject // 清理 maps this._requestMap.delete(reqId); this._taskMap.delete(reqId); this._rejectMap.delete(reqId); reject(err); } }); } get( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ method: 'GET', url, data, header: options.header, meta: options.meta }); } post( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ url, method: 'POST', data, header: options.header, meta: options.meta }); } put( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ url, method: 'PUT', data, header: options.header, meta: options.meta }); } delete( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ url, method: 'DELETE', data, header: options.header, meta: options.meta }); } } // 插件化导出,支持 app.use(http, { interceptor }) const httpInstance = new Request(); interface HttpPluginOptions { requestConfig?: Partial; interceptor?: RequestInterceptor; } // 全局导出,支持 import { httpPlugin } from 'uview-pro' const httpPlugin = { install(app: any, options: HttpPluginOptions = {}) { if (options.interceptor) { const { request, response } = options.interceptor; if (request) httpInstance.interceptor.request = request; if (response) httpInstance.interceptor.response = response; } if (options.requestConfig) { httpInstance.setConfig(options.requestConfig); } app.config.globalProperties.$http = httpInstance; } }; // 全局导出,支持 import { http } from 'uview-pro' export { httpInstance as http }; // 插件化导出,支持 app.use(http, { interceptor }) export default httpPlugin; ================================================ FILE: src/common/share.ts ================================================ function getCurrentPageUrl() { const pages = getCurrentPages(); // 页面栈中的最后一个即为项为当前页面,route属性为页面路径 const pageUrl = pages[pages.length - 1].route as string; return `/${pageUrl}`; } export default { // 发送给朋友 onShareAppMessage(res) { return { title: 'uView Pro', desc: '多平台快速开发 UI 组件库', path: getCurrentPageUrl() }; }, //分享到朋友圈 onShareTimeline(res) { return { title: 'uView Pro', desc: '多平台快速开发 UI 组件库', path: getCurrentPageUrl() }; } }; ================================================ FILE: src/common/useExperience.ts ================================================ import { ref, computed, type Ref } from 'vue'; // @ts-ignore import config from './demo-experience.config.json'; import { useExperienceCenter } from './useExperienceCenter'; export interface ExperienceTaskConfig { key: string; title: string; desc: string; } export interface ExperiencePageConfig { tasks?: ExperienceTaskConfig[]; } export interface ExperienceTask extends ExperienceTaskConfig { done: boolean; } export interface Mission { id: string; title: string; desc: string; reward: number; componentKey: string; hint: string; } export const missionPool: Mission[] = [ { id: 'image-shape', title: '体验图片组件形态', desc: '前往 Image 示例,切换一次圆形和方形展示,并完成一次状态切换。', reward: 25, componentKey: 'Image 图片', hint: 'Image 组件 - 任务体验' }, { id: 'theme', title: '探索主题切换', desc: '在首页主题切换区体验至少 2 套不同主题,感受配色变化。', reward: 20, componentKey: 'Theme 主题', hint: '组件首页 - 主题按钮' }, { id: 'slider-move', title: '体验滑块组件', desc: '前往 Slider 示例,拖动滑块并查看数值变化,完成一次完整交互。', reward: 30, componentKey: 'Slider 滑块', hint: 'Slider 组件 - 互动反馈' }, { id: 'transition', title: '预览过渡动画', desc: '前往 Transition 示例,切换不同的动画效果,体验至少 3 种过渡动画。', reward: 35, componentKey: 'Transition 过渡', hint: 'Transition 组件 - 组件演示' }, { id: 'button', title: '点击按钮组件', desc: '前往 Button 示例,点击不同主题按钮,并查看反馈效果,完成一次点击交互。', reward: 15, componentKey: 'Button 按钮', hint: 'Button 组件 - 组件演示' }, { id: 'cell', title: '使用单元格导航', desc: '前往 Cell 示例,点击任意单元格进行导航,体验列表交互。', reward: 20, componentKey: 'Cell 单元格', hint: 'Cell 组件 - 组件演示' }, { id: 'rate', title: '体验评分组件', desc: '前往 Rate 示例,进行评分操作,体验至少 3 次评分变化。', reward: 25, componentKey: 'Rate 评分', hint: 'Rate 组件 - 互动反馈' }, { id: 'popup', title: '打开弹出层', desc: '前往 Popup 示例,打开至少 2 个不同方向的弹出层,体验弹出效果。', reward: 30, componentKey: 'Popup 弹出层', hint: 'Popup 组件 - 组件演示' }, { id: 'form', title: '提交表单数据', desc: '前往 Form 示例,填写表单并提交,完成一次表单交互。', reward: 40, componentKey: 'Form 表单', hint: 'Form 组件 - 组件演示' }, { id: 'tabs', title: '切换标签页', desc: '前往 Tabs 示例,切换至少 3 个不同的标签页,体验标签切换。', reward: 20, componentKey: 'Tabs 标签页', hint: 'Tabs 组件 - 组件演示' }, { id: 'template', title: '浏览模板场景', desc: '打开模板示例页,浏览任意一个模板详情,了解组件组合用法。', reward: 25, componentKey: 'Template 模板', hint: '模板示例 - 场景浏览' }, { id: 'tools', title: '浏览工具场景', desc: '在体验地图页面查看自己的等级和统计数据,了解体验进度。', reward: 15, componentKey: 'Tools 工具', hint: '工具示例 - 场景浏览' } ]; interface ExperienceState { tasks: Ref; logs: Ref; } type ExperienceConfigMap = Record; const experienceConfig = config as ExperienceConfigMap; const stateMap: Record = {}; function createInitialTasks(pageKey: string): ExperienceTask[] { const pageConfig = experienceConfig[pageKey]; const tasks = pageConfig?.tasks || []; return tasks.map(task => ({ ...task, done: false })); } function getStorageKeys(pageKey: string) { const base = `uview-demo-experience-${pageKey}`; return { task: `${base}-tasks`, log: `${base}-logs` }; } function restoreState(pageKey: string): ExperienceState { const tasks = ref(createInitialTasks(pageKey)); const logs = ref([]); try { if (typeof uni !== 'undefined') { const keys = getStorageKeys(pageKey); const taskCache = uni.getStorageSync(keys.task); const logCache = uni.getStorageSync(keys.log); if (Array.isArray(taskCache) && taskCache.length) { tasks.value = taskCache as ExperienceTask[]; } if (Array.isArray(logCache)) { logs.value = logCache as string[]; } } } catch (error) { console.warn('restoreState error', error); } return { tasks, logs }; } function persistState(pageKey: string, state: ExperienceState) { try { if (typeof uni === 'undefined') return; const keys = getStorageKeys(pageKey); uni.setStorageSync(keys.task, state.tasks.value); uni.setStorageSync(keys.log, state.logs.value); } catch (error) { console.warn('persistState error', error); } } export function useExperience(pageKey: string) { if (!stateMap[pageKey]) { stateMap[pageKey] = restoreState(pageKey); } const state = stateMap[pageKey]; const center = useExperienceCenter(); center.registerComponent(pageKey); const taskProgress = computed(() => { if (!state.tasks.value.length) return 0; const finished = state.tasks.value.filter(task => task.done).length; return Math.round((finished / state.tasks.value.length) * 100); }); const completeTask = (key: string, xpBonus = 12) => { const task = state.tasks.value.find(item => item.key === key); if (task && !task.done) { task.done = true; persistState(pageKey, state); center.gainExperience(pageKey, xpBonus, `完成任务 · ${task.title}`, { type: 'task' }); } }; const toggleTask = (index: number, value: boolean) => { if (!state.tasks.value[index]) return; state.tasks.value[index].done = value; persistState(pageKey, state); }; const recordAction = (message: string, xpBonus = 4) => { const date = new Date(); const time = `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`; state.logs.value.unshift(`${time} · ${message}`); state.logs.value = state.logs.value.slice(0, 6); persistState(pageKey, state); if (typeof uni !== 'undefined' && typeof uni.vibrateShort === 'function') { uni.vibrateShort(); } center.gainExperience(pageKey, xpBonus, message, { type: 'interaction' }); }; const resetExperience = () => { state.tasks.value = createInitialTasks(pageKey); state.logs.value = []; persistState(pageKey, state); }; return { tasks: state.tasks, logs: state.logs, taskProgress, completeTask, toggleTask, recordAction, resetExperience }; } // 任务领取状态管理 const MISSION_STORAGE_KEY = 'uview-experience-assigned-missions'; const COMPLETED_MISSIONS_KEY = 'uview-experience-completed-missions'; const assignedMissionIds = ref([]); const completedMissionIds = ref([]); // 已完成但未领取积分的任务 // 加载已领取的任务 function loadAssignedMissions() { try { if (typeof uni === 'undefined') return; const cache = uni.getStorageSync(MISSION_STORAGE_KEY); if (Array.isArray(cache)) { assignedMissionIds.value = cache; } } catch (error) { console.warn('loadAssignedMissions error', error); } } // 保存已领取的任务 function saveAssignedMissions() { try { if (typeof uni === 'undefined') return; uni.setStorageSync(MISSION_STORAGE_KEY, assignedMissionIds.value); } catch (error) { console.warn('saveAssignedMissions error', error); } } // 加载已完成的任务 function loadCompletedMissions() { try { if (typeof uni === 'undefined') return; const cache = uni.getStorageSync(COMPLETED_MISSIONS_KEY); if (Array.isArray(cache)) { completedMissionIds.value = cache; } } catch (error) { console.warn('loadCompletedMissions error', error); } } // 保存已完成的任务 function saveCompletedMissions() { try { if (typeof uni === 'undefined') return; uni.setStorageSync(COMPLETED_MISSIONS_KEY, completedMissionIds.value); } catch (error) { console.warn('saveCompletedMissions error', error); } } // 初始化时加载 loadAssignedMissions(); loadCompletedMissions(); /** * 取消任务(从已领取列表中移除) * @param missionId 任务ID * @returns 是否成功取消任务 */ export function unassignMission(missionId: string): boolean { if (!assignedMissionIds.value.includes(missionId)) { return false; } assignedMissionIds.value = assignedMissionIds.value.filter(id => id !== missionId); saveAssignedMissions(); return true; } /** * 领取任务 * @param missionId 任务ID * @param force 是否强制领取(如果任务已领取,先取消再领取) * @returns 是否成功领取任务 */ export function assignMission(missionId: string, force = false): boolean { const mission = missionPool.find(m => m.id === missionId); if (!mission) { console.warn(`Mission not found: ${missionId}`); return false; } // 如果任务已经领取且不强制,返回 false if (assignedMissionIds.value.includes(missionId) && !force) { return false; } // 如果强制领取且任务已存在,先移除 if (force && assignedMissionIds.value.includes(missionId)) { assignedMissionIds.value = assignedMissionIds.value.filter(id => id !== missionId); } // 添加任务到已领取列表 assignedMissionIds.value.push(missionId); saveAssignedMissions(); return true; } /** * 完成任务(通过任务ID)- 只标记为完成,不直接给积分 * @param missionId 任务ID * @returns 是否成功完成任务 */ export function completeMission(missionId: string): boolean { const mission = missionPool.find(m => m.id === missionId); if (!mission) { console.warn(`Mission not found: ${missionId}`); return false; } // 检查任务是否已领取 if (!assignedMissionIds.value.includes(missionId)) { console.warn(`Mission not assigned: ${missionId}`); return false; } // 如果任务已经完成,不再重复完成 if (completedMissionIds.value.includes(missionId)) { return false; } // 标记任务为已完成(但未领取积分) completedMissionIds.value.push(missionId); saveCompletedMissions(); if (typeof uni !== 'undefined') { uni.showToast({ title: '任务已完成,请前往体验地图领取积分', icon: 'success', duration: 2000 }); } return true; } /** * 领取任务积分(在体验地图中调用) * @param missionId 任务ID * @returns 是否成功领取积分 */ export function claimMissionReward(missionId: string): boolean { const mission = missionPool.find(m => m.id === missionId); if (!mission) { console.warn(`Mission not found: ${missionId}`); return false; } // 检查任务是否已完成 if (!completedMissionIds.value.includes(missionId)) { console.warn(`Mission not completed: ${missionId}`); if (typeof uni !== 'undefined') { uni.showToast({ title: '任务尚未完成', icon: 'none' }); } return false; } // 发放积分 const center = useExperienceCenter(); center.gainExperience(mission.componentKey, mission.reward, `体验任务 · ${mission.title}`, { type: 'task' }); if (typeof uni !== 'undefined') { uni.showToast({ title: `领取积分 +${mission.reward}XP`, icon: 'success' }); } // 从已完成列表中移除(已领取积分) completedMissionIds.value = completedMissionIds.value.filter(id => id !== missionId); saveCompletedMissions(); // 从已领取列表中移除 assignedMissionIds.value = assignedMissionIds.value.filter(id => id !== missionId); saveAssignedMissions(); return true; } /** * 获取已领取的任务ID列表 */ export function getAssignedMissionIds(): string[] { return [...assignedMissionIds.value]; } /** * 获取已完成但未领取积分的任务ID列表 */ export function getCompletedMissionIds(): string[] { return [...completedMissionIds.value]; } /** * 检查任务是否已领取 */ export function isMissionAssigned(missionId: string): boolean { return assignedMissionIds.value.includes(missionId); } /** * 检查任务是否已完成(但未领取积分) */ export function isMissionCompleted(missionId: string): boolean { return completedMissionIds.value.includes(missionId); } ================================================ FILE: src/common/useExperienceCenter.ts ================================================ import { ref, computed } from 'vue'; interface ComponentStat { key: string; xp: number; visits: number; interactions: number; tasksCompleted: number; lastAction?: string; lastUpdated?: number; } interface ExperienceLog { message: string; timestamp: number; } interface AtlasNode { id: string; title: string; tip: string; threshold: number; } interface PersistedState { xp: number; totalInteractions: number; componentStats: Record; logs: ExperienceLog[]; } const STORAGE_KEY = 'uview-experience-center'; const atlas: AtlasNode[] = [ { id: 'start', title: '起步探索', tip: '完成任意组件的首次交互', threshold: 0 }, { id: 'interact', title: '交互达人', tip: '累计体验值达到 200 点', threshold: 200 }, { id: 'scene', title: '场景高手', tip: '累计体验值达到 500 点', threshold: 500 }, { id: 'mentor', title: '体验导师', tip: '累计体验值达到 1000 点', threshold: 1000 }, { id: 'master', title: '体验大师', tip: '累计体验值达到 2000 点', threshold: 2000 }, { id: 'legend', title: '体验传说', tip: '累计体验值达到 5000 点', threshold: 5000 } ]; const xp = ref(0); const totalInteractions = ref(0); const componentStats = ref>({}); const logs = ref([]); const lastGain = ref<{ amount: number; source: string; componentKey: string; timestamp: number } | null>(null); let initialized = false; function loadState() { if (initialized) return; initialized = true; try { if (typeof uni === 'undefined') return; const cache = uni.getStorageSync(STORAGE_KEY); if (cache) { const parsed = cache as PersistedState; xp.value = parsed.xp || 0; totalInteractions.value = parsed.totalInteractions || 0; componentStats.value = parsed.componentStats || {}; logs.value = parsed.logs || []; } } catch (error) { console.warn('useExperienceCenter loadState error', error); } } function persistState() { try { if (typeof uni === 'undefined') return; const payload: PersistedState = { xp: xp.value, totalInteractions: totalInteractions.value, componentStats: componentStats.value, logs: logs.value }; uni.setStorageSync(STORAGE_KEY, payload); } catch (error) { console.warn('useExperienceCenter persistState error', error); } } function ensureRegistered(key: string) { if (!componentStats.value[key]) { componentStats.value = { ...componentStats.value, [key]: { key, xp: 0, visits: 0, interactions: 0, tasksCompleted: 0 } }; } } export function useExperienceCenter() { loadState(); const levelInfo = computed(() => { let current = atlas[0]; for (const node of atlas) { if (xp.value >= node.threshold) { current = node; } else { break; } } return current; }); const nextLevel = computed(() => { const currentIndex = atlas.findIndex(node => node.id === levelInfo.value.id); return atlas[currentIndex + 1] || null; }); const levelProgress = computed(() => { const next = nextLevel.value; if (!next) { return 100; } const currentThreshold = levelInfo.value.threshold; const span = next.threshold - currentThreshold; if (span <= 0) return 100; return Math.min(100, Math.round(((xp.value - currentThreshold) / span) * 100)); }); const mapSteps = computed(() => { return atlas.map((node, index) => { const reached = xp.value >= node.threshold; const next = atlas[index + 1]; let status: 'finish' | 'process' | 'wait' = 'wait'; if (reached && (!next || xp.value >= next.threshold)) { status = 'finish'; } else if (reached) { status = 'process'; } return { ...node, status, percent: status === 'process' && next ? Math.min( 100, Math.round(((xp.value - node.threshold) / (next.threshold - node.threshold)) * 100) ) : status === 'finish' ? 100 : 0 }; }); }); const recentLogs = computed(() => logs.value.slice(0, 6)); const componentSummary = computed(() => { const keys = Object.keys(componentStats.value); const stats = keys.map(key => componentStats.value[key]); const tasksCompleted = stats.reduce((sum, item) => sum + item.tasksCompleted, 0); const totalXP = stats.reduce((sum, item) => sum + item.xp, 0); const mostActive = stats.sort((a, b) => b.xp - a.xp)[0]; return { components: keys.length, tasksCompleted, totalXP, mostActive }; }); const registerComponent = (key: string) => { if (!key) return; ensureRegistered(key); componentStats.value[key] = { ...componentStats.value[key], visits: componentStats.value[key].visits + 1, lastUpdated: Date.now() }; persistState(); }; const gainExperience = ( componentKey: string, amount = 4, source = '交互体验', payload?: { type?: 'task' | 'interaction' } ) => { if (!componentKey || amount <= 0) return; ensureRegistered(componentKey); xp.value += amount; totalInteractions.value += 1; const stat = componentStats.value[componentKey]; stat.xp += amount; stat.interactions += 1; if (payload?.type === 'task') { stat.tasksCompleted += 1; } stat.lastAction = source; stat.lastUpdated = Date.now(); componentStats.value = { ...componentStats.value, [componentKey]: { ...stat } }; const timestamp = Date.now(); logs.value = [{ message: `${source} +${amount}XP`, timestamp }, ...logs.value].slice(0, 12); lastGain.value = { amount, source, componentKey, timestamp }; persistState(); }; return { xp, totalInteractions, levelInfo, nextLevel, levelProgress, mapSteps, recentLogs, componentSummary, componentStats, lastGain, registerComponent, gainExperience }; } ================================================ FILE: src/common/useHooks.ts ================================================ import { useLocale } from 'uview-pro'; import { useI18n } from 'vue-i18n'; export function useLang() { const { locale } = useI18n(); const { setLocale } = useLocale(); function switchLang(payload: any) { // 切换uniapp语言 uni.setLocale(payload.locale); uni.setStorageSync('UNI_LOCALE', payload.locale); // 切换vue-i18n语言 locale.value = payload.locale; // 切换uView Pro语言 setLocale(payload.name); } return { switchLang }; } /** * 获取标题(中英文) */ export function useTitle(index: number) { const { t, locale } = useI18n(); const titles = ['nav.components', 'nav.js', 'nav.experience', 'nav.template', 'nav.about']; function getTitle(key: string, item: any = null) { if (!item) return key; return locale.value === 'zh-Hans' ? item[key] : item[`${key}_en`]; } function setTitle() { uni?.setNavigationBarTitle({ title: t(titles[index]) }); // titles.forEach((text, index) => { // uni?.setTabBarItem({ // index, // text: t(text) // }); // }); } return { getTitle, setTitle }; } ================================================ FILE: src/common/util.ts ================================================ import { useI18n } from 'vue-i18n'; /** * 生成随机背景颜色 */ export function getRandomColor(): string { const colors = [ '#39b54a', // green '#f39c12', // orange '#3498db', // blue '#e74c3c', // red '#9b59b6', // purple '#16a085', // teal '#e67e22', // carrot '#2ecc71', // emerald '#1abc9c', // turquoise '#34495e', // wet asphalt '#2980b9', '#8e44ad', '#2c3e50', '#c0392b', '#d35400', '#27ae60', '#f1c40f', '#7f8c8d', '#e84393', '#00b894', '#fdcb6e', '#6c5ce7', '#0984e3', '#00cec9', '#fab1a0', '#ff7675', '#55efc4' ]; return colors[Math.floor(Math.random() * colors.length)]; } ================================================ FILE: src/components/demo-animation/animation.css ================================================ /** * Animation 微动画 */ /* css 滤镜 控制黑白底色gif的 */ .gif-black { mix-blend-mode: screen; } .gif-white { mix-blend-mode: multiply; } /* Animation css */ [class*='animation-'] { animation-duration: 0.5s; animation-timing-function: ease-out; animation-fill-mode: both; } .animation-fade { animation-name: fade; animation-duration: 0.8s; animation-timing-function: linear; } .animation-scale-up { animation-name: scale-up; } .animation-scale-down { animation-name: scale-down; } .animation-slide-top { animation-name: slide-top; } .animation-slide-bottom { animation-name: slide-bottom; } .animation-slide-left { animation-name: slide-left; } .animation-slide-right { animation-name: slide-right; } .animation-shake { animation-name: shake; } .animation-reverse { animation-direction: reverse; } @keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes scale-up { 0% { opacity: 0; transform: scale(0.2); } 100% { opacity: 1; transform: scale(1); } } @keyframes scale-down { 0% { opacity: 0; transform: scale(1.8); } 100% { opacity: 1; transform: scale(1); } } @keyframes slide-top { 0% { opacity: 0; transform: translateY(-100%); } 100% { opacity: 1; transform: translateY(0); } } @keyframes slide-bottom { 0% { opacity: 0; transform: translateY(100%); } 100% { opacity: 1; transform: translateY(0); } } @keyframes shake { 0%, 100% { transform: translateX(0); } 10% { transform: translateX(-9px); } 20% { transform: translateX(8px); } 30% { transform: translateX(-7px); } 40% { transform: translateX(6px); } 50% { transform: translateX(-5px); } 60% { transform: translateX(4px); } 70% { transform: translateX(-3px); } 80% { transform: translateX(2px); } 90% { transform: translateX(-1px); } } @keyframes slide-left { 0% { opacity: 0; transform: translateX(-100%); } 100% { opacity: 1; transform: translateX(0); } } @keyframes slide-right { 0% { opacity: 0; transform: translateX(100%); } 100% { opacity: 1; transform: translateX(0); } } ================================================ FILE: src/components/demo-animation/demo-animation.vue ================================================ ================================================ FILE: src/components/demo-card/demo-card.vue ================================================ ================================================ FILE: src/components/demo-guide/demo-guide.vue ================================================ ================================================ FILE: src/components/demo-guide-use/demo-guide-use.vue ================================================ ================================================ FILE: src/components/demo-page/demo-page.vue ================================================ ================================================ FILE: src/components/page-nav/page-nav.vue ================================================ ================================================ FILE: src/components/wx-tips/wx-tips.vue ================================================ ================================================ FILE: src/env.d.ts ================================================ /// declare module '*.vue' { import { DefineComponent } from 'vue'; // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any>; export default component; } ================================================ FILE: src/locales/index.ts ================================================ import { createI18n } from 'vue-i18n'; import en from './langs/en.json'; // 英文 import zhHans from './langs/zh-Hans.json'; // 简体中文 const messages = { en, 'zh-Hans': zhHans }; // 安全获取locale,避免在SSR环境下出现问题 export const getSafeLocale = () => { try { return uni.getStorageSync('UNI_LOCALE') || uni.getLocale() || 'zh-Hans'; } catch (e) { return 'zh-Hans'; } }; export const getDefaultLocale = () => { switch (getSafeLocale()) { case 'en': return 'en-US'; default: return 'zh-CN'; } }; const i18n = createI18n({ locale: getSafeLocale(), fallbackLocale: 'zh-Hans', messages, allowComposition: true, legacy: false, globalInjection: true }); export default i18n; ================================================ FILE: src/locales/langs/en.json ================================================ { "components": { "find": "Found", "matchingComponent": "matching components", "clear": "Clear", "searchComponent": "Search components...", "search": "Search", "notFound": "No matching component was found.", "theme": "Switch Theme", "desc": "uView Pro is a high-quality, cross-platform UI component library for multiple platforms. It includes 80+ built-in components and a rich utility library to help efficiently develop Mini Programs, H5, Apps, HarmonyOS, and more." }, "js": { "desc": "Numerous intimate gadgets are a weapon that you can call upon during the development process, allowing you to dart in your hand and pierce the Yang with a hundred steps." }, "template": { "desc": "Collection of many commonly used pages and layouts, reducing the repetitive work of developers, allowing you to focus on logic and get twice the result with half the effort." }, "nav": { "components": "Components", "js": "Tools", "template": "Template", "about": "About", "experience": "Experience" }, "common": { "intro": "UI framework for rapid development of multiple platforms", "title": "uView Pro", "tryit": "Try-it", "experienceMap": "Experience Map", "experienceMapDesc": "View component experience levels and task completion status", "scene": "Scene", "sceneDesc": "Experience business scenarios and feel the use of components in applications" }, "theme": { "uviewpro": "Default", "purple": "Purple", "green": "Green", "orange": "Orange", "dark": "DarkBlue" } } ================================================ FILE: src/locales/langs/zh-Hans.json ================================================ { "components": { "find": "找到", "matchingComponent": "个匹配组件", "clear": "清空", "searchComponent": "搜索组件...", "search": "搜索", "notFound": "未找到匹配的组件", "theme": "切换主题", "desc": "uView Pro 是一套高质量、跨平台的多端 UI 组件库,内置 80+ 组件与丰富工具库,助力高效开发小程序、H5、App、HarmonyOS 等应用!" }, "js": { "desc": "uView Pro 提供了众多的贴心小工具,是你开发过程中召之即来的利器,让你飞镖在手,百步穿杨!" }, "template": { "desc": "uView Pro 收集了众多的常用页面和布局,减少开发者的重复工作,让你专注逻辑,事半功倍!" }, "nav": { "components": "组件", "js": "工具", "template": "模板", "about": "关于", "experience": "体验地图" }, "common": { "intro": "多平台快速开发的UI框架", "title": "uView UI", "tryit": "试一试", "experienceMap": "体验地图", "experienceMapDesc": "查看组件体验等级与任务完成情况", "scene": "实用场景", "sceneDesc": "体验完整的业务场景,感受组件在实际应用中的使用" }, "theme": { "uviewpro": "官方蓝", "purple": "霞光紫", "green": "清翠绿", "orange": "暖阳橙", "dark": "深邃蓝" } } ================================================ FILE: src/main.ts ================================================ import { createSSRApp } from 'vue'; import App from './App.vue'; import themes from '@/uview-pro.theme'; import uViewPro, { httpPlugin } from '@/uni_modules/uview-pro'; import { httpInterceptor, httpRequestConfig } from './common/http.interceptor'; import i18n from '@/locales'; // #ifdef MP import share from './common/share'; // #endif export function createApp() { const app = createSSRApp(App); app.use(i18n); // 引入uView Pro 主库 app.use(uViewPro, { theme: { themes: themes, // 主题对象数组,至少需要包含一个主题对象,且每个对象必须包含 name 和 color 字段 defaultTheme: 'green', // 默认主题名称,需与 themes 中的 name 字段对应 defaultDarkMode: 'auto', // 默认暗黑模式跟随系统,支持 'auto' | 'light' | 'dark' isForce: false // 是否初始化强制使用默认主题,如果为true,则会覆盖用户之前选择的主题;如果为false,则会优先使用用户之前选择的主题 }, locale: { // 部分覆盖内置语言包 locales: [ { name: 'zh-CN', uModal: { confirmText: '好的', cancelText: '算了' } }, { name: 'en-US', uModal: { confirmText: 'OK', cancelText: 'Cancel' } } ], defaultLocale: 'zh-CN' // 默认语言环境,需与 locales 中的 name 字段对应 }, debugMode: false // 是否开启日志和警告 }); // 引入uView Pro 的http插件 app.use(httpPlugin, { interceptor: httpInterceptor, requestConfig: httpRequestConfig }); // #ifdef MP // @ts-ignore app.mixin(share); // #endif return { app }; } ================================================ FILE: src/manifest.json ================================================ { "name": "uViewPro(跨平台UI组件库)", "appid": "__UNI__9E7D9A9", "description": "uView Pro 是一套高质量、跨平台的多端 UI 组件库,内置 80+ 组件与丰富工具库,助力高效开发小程序、H5、App、HarmonyOS 等应用。", "versionName": "1.0.9", "versionCode": 12, "transformPx": false, /* 5+App特有相关 */ "app-plus": { "darkmode": true, "themeLocation": "theme.json", "usingComponents": true, "nvueStyleCompiler": "uni-app", "compilerVersion": 3, "splashscreen": { "alwaysShowBeforeRender": true, "waiting": true, "autoclose": true, "delay": 0 }, /* 模块配置 */ "modules": {}, /* 应用发布信息 */ "distribute": { /* android打包配置 */ "android": { "permissions": [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ], "abiFilters": ["armeabi-v7a", "arm64-v8a"], "targetSdkVersion": 31, "minSdkVersion": 22 }, /* ios打包配置 */ "ios": { "dSYMs": false }, /* SDK配置 */ "sdkConfigs": { "ad": {} }, "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" } } } }, "safearea": { //iOS平台的安全区域 "background": "#ffffff", "backgroundDark": "#2f0508", "bottom": { "offset": "none" } } }, /* 快应用特有相关 */ "quickapp": {}, /* 小程序特有相关 */ "mp-weixin": { "appid": "wxf2f98f5b731ecd20", "setting": { "urlCheck": false }, "usingComponents": true, "darkmode": true, "themeLocation": "theme.json" }, "mp-alipay": { "appid": "2021005198657329", "usingComponents": true, "component2": true }, "mp-baidu": { "usingComponents": true }, "mp-toutiao": { "usingComponents": true }, "h5": { "title": "uView Pro", "router": { "mode": "hash", "base": "./" }, "optimization": { "treeShaking": { "enable": true } }, "darkmode": true, "themeLocation": "theme.json" }, "uniStatistics": { "enable": false }, "vueVersion": "3", "app-harmony": { "darkmode": true, "themeLocation": "theme.json", "safearea": { "background": "#ffffff", "backgroundDark": "#2f0508", "bottom": { "offset": "none" } }, "distribute": { "bundleName": "cn.anyup.uviewpro", "icons": { "foreground": "unpackage/res/icons/1024x1024.png", "background": "unpackage/res/icons/1024x1024.png" }, "splashScreens": { "startWindowBackground": "#FFFFFF", "startWindowIcon": "unpackage/res/icons/1024x1024.png" }, "signingConfigs": { "default": { "certpath": "c:\\Users\\admin\\AppData\\Roaming\\HBuilder X\\extensions\\launcher\\agc-certs\\1762910225094.cer", "keyAlias": "debugKey", "keyPassword": "0000001B48EFEBC254AA9F73E27F2C1699BE1EFB8B45851575CECD07D2DBE82C0D76B7907E487F23F84D54", "profile": "c:\\Users\\admin\\AppData\\Roaming\\HBuilder X\\extensions\\launcher\\agc-certs\\1762910225094.p7b", "signAlg": "SHA256withECDSA", "storeFile": "c:\\Users\\admin\\AppData\\Roaming\\HBuilder X\\extensions\\launcher\\agc-certs\\1762910225094.p12", "storePassword": "0000001B48EFEBC254AA9F73E27F2C1699BE1EFB8B45851575CECD07D2DBE82C0D76B7907E487F23F84D54" }, "release": { "certpath": "D:/workspace/anyup/uView-Pro/docs/uviewpro.cer", "keyAlias": "uviewpro", "keyPassword": "0000001E6691C890BDB30353B4C0D59375D5FFB9C11A3ED0CA390CAA12302677A354AB61C7795AD6D2BCD04DBBC6", "profile": "D:/workspace/anyup/uView-Pro/docs/uviewpro_prodRelease.p7b", "signAlg": "SHA256withECDSA", "storeFile": "D:/workspace/anyup/uView-Pro/docs/uviewpro.p12", "storePassword": "0000001E0E5E7477F66639990B845220FC4082AAEA6D6837F481E2E9A13ECA4F3376D378019C37B059E1A410F512" } } } } } ================================================ FILE: src/pages/componentsA/avatar/index.vue ================================================ ================================================ FILE: src/pages/componentsA/avatarCropper/index.vue ================================================ ================================================ FILE: src/pages/componentsA/backTop/index.vue ================================================ ================================================ FILE: src/pages/componentsA/calendar/index.vue ================================================ ================================================ FILE: src/pages/componentsA/empty/index.vue ================================================ ================================================ FILE: src/pages/componentsA/field/index.vue ================================================ ================================================ FILE: src/pages/componentsA/form/index.vue ================================================ ================================================ FILE: src/pages/componentsA/fullScreen/index.vue ================================================ ================================================ FILE: src/pages/componentsA/icon/index.vue ================================================ ================================================ FILE: src/pages/componentsA/indexList/index.vue ================================================ ================================================ FILE: src/pages/componentsA/input/index.vue ================================================ ================================================ FILE: src/pages/componentsA/keyboard/index.vue ================================================ ================================================ FILE: src/pages/componentsA/lazyLoad/index.vue ================================================ ================================================ FILE: src/pages/componentsA/modal/index.vue ================================================ ================================================ FILE: src/pages/componentsA/navbar/index.vue ================================================ ================================================ FILE: src/pages/componentsA/noNetwork/index.vue ================================================ ================================================ FILE: src/pages/componentsA/select/index.vue ================================================ ================================================ FILE: src/pages/componentsA/slider/index.vue ================================================ ================================================ FILE: src/pages/componentsA/tabs/index.vue ================================================ ================================================ FILE: src/pages/componentsA/tag/index.vue ================================================ ================================================ FILE: src/pages/componentsA/test/index.vue ================================================ ================================================ FILE: src/pages/componentsA/textarea/index.vue ================================================ ================================================ FILE: src/pages/componentsA/timeLine/index.vue ================================================ ================================================ FILE: src/pages/componentsA/toast/index.vue ================================================ ================================================ FILE: src/pages/componentsA/topTips/index.vue ================================================ ================================================ FILE: src/pages/componentsA/verificationCode/index.vue ================================================ ================================================ FILE: src/pages/componentsB/card/index.vue ================================================ ================================================ FILE: src/pages/componentsB/checkbox/index.vue ================================================ ================================================ FILE: src/pages/componentsB/divider/index.vue ================================================ ================================================ FILE: src/pages/componentsB/dropdown/index.vue ================================================ ================================================ FILE: src/pages/componentsB/image/index.vue ================================================ ================================================ FILE: src/pages/componentsB/line/index.vue ================================================ ================================================ FILE: src/pages/componentsB/loading/index.vue ================================================ ================================================ FILE: src/pages/componentsB/loadingPopup/index.vue ================================================ ================================================ FILE: src/pages/componentsB/noticeBar/index.vue ================================================ ================================================ FILE: src/pages/componentsB/picker/index.vue ================================================ ================================================ FILE: src/pages/componentsB/radio/index.vue ================================================ ================================================ FILE: src/pages/componentsB/rate/index.vue ================================================ ================================================ FILE: src/pages/componentsB/readMore/index.vue ================================================ ================================================ FILE: src/pages/componentsB/search/index.vue ================================================ ================================================ FILE: src/pages/componentsB/search/types.ts ================================================ import { type ComponentPublicInstance, type ExtractPropTypes } from 'vue'; // 定义组件 Props export const Props = {}; // 将 Props 转换为类型 export type Props = ExtractPropTypes; // 暴露的组件实例方法和属性 export type Expose = {}; // 导出组件实例类型 export type Instance = ComponentPublicInstance; ================================================ FILE: src/pages/componentsB/skeleton/index.vue ================================================ ================================================ FILE: src/pages/componentsB/steps/index.vue ================================================ ================================================ FILE: src/pages/componentsB/sticky/index.vue ================================================ ================================================ FILE: src/pages/componentsB/swipeAction/index.vue ================================================ ================================================ FILE: src/pages/componentsB/swiper/image.ts ================================================ export const img1 = 'data:image/jpeg;base64,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'; export const img2 = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAu4AAAERCAMAAAAT79KpAAADAFBMVEX//Pksc90iYs08kfEnbtkdW8UkaNMxhOgslO3///8kZdAkZ9MobtkdXMYsc97yvXofXsgrcdwhYcsladUma9b0uwojYs76/P8dKoAnbNj2+f8/kfHw9v9kkfvr8/8td+Dm7//7iBY9jvAvRNEcWcNWa/Yve+P51KM6iu43h+vzwYAyfub616jh7P/d5PL0xoo1hOlAlPLW5f//7eAhK2Hd6f/N3/8sle08lfI6kPD0xIUPlfj40p72yo8rkOvW3+/3z5kzgegPgOEPh+nS4v/WZSMdYckoiebZ6P8jd9oQTaUumO8vm/A+mvQPedg2i+4QWrUeZcwgcNXwt3Akft/SVhP/2KEQbMkaXMQaV8D3zZQSHFceadApjOkfbNIbX8bH3P8hc9ghZdHTWxno7fYketwPj/EnheMlgeEVXtDVYR+Vvfg1jeMQYLthdfnx9Pkvft0QZcEPcc/C2P80h932y4eLm/8BQqUQVK7ocABGec/kkE9zh/0AS7ETWMv63reBkP8EScEAYclwoOfm5ubE2PMGTsgibt0tdv/ghUMAV74BjPwAOs4AeugAhPKMs/AWY9cGWdYZJHP/igX9wAIAct3sqGclhuQAS9L936iiwe9CWvZ9qebonFu1z/JLYvZBbt3T4vdtm/8Ba9Oqy/KXvO7efTpAfd1/w/cAJ5D905MSV79EX9g/WdfA0f4AN5yfu+BVjeEBEVwmdeUCJ8mYrNbYbSuuuftWjtBJh+Jtndb9mQ02TdT6hBTbdTIwZrk1b9IzgM9SjP61yOT8eQBlk+BPgNjz5uGIo9D32rLOSwiUpP8FEXJasvUHW+MoQpUjI1Gx2vtqu/ldfcCDjbH+5K0CRLsbdP//xW8mUaxGsP2QseRHdL/k298yo/dUgu3/86zvfxP1sw1cYaPix6WmZC1zkMmUz/tMnuUbM83kuYUZN+mZhYz/5pl2aHdVm/IqVM7MsZH/zYFUT3FTdKDT0uCroJSrgGn3mji7ta7+6siRZlS2cUDHrVHHhE40WutylT4xAAAACXRSTlP88vLy8vLy8vLIsUFaAACF3UlEQVR42tydTYsrRRiFVfxMTyTpNJGIiIvZiSCCjitBkLkGdTHiYgackQSGGVEwC1eCgghudTcg4k5cCO7dzUZ/givxt3iq3qo6Vf1Wd6WT8fPUR7pz49XRx8Opt6pz73vo8KE70AO6m/YAxn9XD9+5HoyuHvwH9PA2euCB+x/dV4+gS0O3ukJHu37knUc2m839vjk9eH/rnxPd6wEzIlm0hursoYc+/f2xj4D74RmE+TDVOK9JRsfpbW378fFxPalrjKRNzLy95oM0ci/dbR+t12t3VfnXXs1ms6bBhBfTjGZya7VYNGju8qBDUxlKpY/id+TlIvp7zSB5EVXUCN1oPrp848030Y3esDo6wujSK+ii80T3zu/dw7C6ubm5uoGujd5Bpy4vl5dLp5XV20YXRu/GOhEdO70HnQYdYhiUT89S/SgD+u2Tx+4D7iKNusxF1rP8Q7XSToRvCzwxd1xj3KWAOmmvzFTUjIoha0SLRB0Er2SUiefH9dsLqhHiW7hT9ifFv7krizsmR7s0dFx3I0954CHibmV5J+rokKAO2DEgA3sb95Mg0h6AJ/OA95TEU/24oxVhH3fTXu8M+8nJ/GRe+7Y95tLZFOx72zp6oq1ob0xvtsM9GYSdBJfkPr4q4d7k7Z24j+bVFb39yE8QgVew44W0oxN32juQR/e4k/el1wqD9g7cfQPv6GAdw+Gugbfsnp4dFnAfEGPKqnc09vkuIuXSY+7vQJVplvchqDPKKHPvwV0DL1L8dvI/lWna/q20vTe9vEPz5lxwF393wBP5rMG37B0DwKM53MXgMWjvl3Yy8qxjAu3EHboI/o5uYEcH7XaiiLxVAfeStU+2lYZ9sh3rYucn22CfAI5O0Hl9V6iv0eR2GO6zCwd3FSgn94Q9wr3J8Lu0/Cqqb/EmmtJqekB7XywAu0inGUxBCndovnpFcAfvbXeHet0dMqznEg3jjNAuYpwR4ok7UMfAFCUa4C7SuFOHW+JedvY++HdJMUMj+qiV0ZMgw76fhPV387+0jRzqMjVl3K0adk/tUrOOF5mnOYuXtxuLe4e9u3+Ibtyh+fIN+nuio874LqjbV9BO1sm7ju+xv9PdrYi7sG4a/V3ZO4k/A+7oh924nzrYd7X2Gm1wZD9xpKNtbejku8W5jDvx9grdTuvkXcV6mfamQutI7mVzX4HcFvG3wrOZ7I2CfZWkn4V7iaSrM1U2zsxdeSbCnNKst3g/53pV8X4tStwdorsTd8hHeLAe8gx6yd/PDNEld9+5HFPvUIvxrIP6PpHp2NU5pTeK972gH55jmGW8sWPCZRF3AZ7DSoBXof2Wdxr4JVF3Np/yTtzz6b3ylvKO2Ls2d1mv6kiTivXIUpwxrDPQGNxXKe/B3iEz9eN+JvMZy5IduHfFmMB8B/uK9clWrBeSemA5LbcwpCvkbdtB61jMMtCutEMSZOSyiHuTXXuiaeJvcW/6rdypUiS0tJjLBCnce+ydK/P56NqVZ2jvuGGCB+GY6O9QQD3hXdcjQ/Gd2d10Ft+dv1OMMya8F9z9DF1aN+46yujUfmeFR/H1EuwqqJPq/damRFzz3s7po11wp7tXpF3hTvngziGZRICnpi6eBNanaCq7i5po1mlm1rFaHQWh/K7Tu4DP3l6wxqtVzfsVeU9xt6TLvIpwt8BjJu9Ox15JeKdKuO9eexwQYwaVF2O4VWAfbucEvCQ6O9UNdm8ZEkN4L+B+oNQ4m14lQEtRxgV4M5RW6BLhY9iJO5erfZtNIpbfvXRJss27E9P7PYw27tcuv6dLVQaayN0d8pDFHT0f3vWWEzp5V7hLG0z7IGOXLSQz9Uj7t5CteB+md+neWhVrj3ngqyFyFUhpM2PxRXdn+rCDmgrCWreefvQ0/1AkfhGrsNdE4OvqHnHXwOfiO5iPgFelSBAvuIsc7vR3od0DL7A74pnfae/tHScKZ2IM80PcXcWYorMD/z3cnVlcXWqXl3lnVbo57uWyFGLKWaZxbcswQ9hlbgi7jiu3nJWWfrnaxHmmF3e9WhXN69m9P970Dq9NHkMvVvEisJN2dBq8KMFdFG2sEndpXK2ia947q+8duI8zsX3vDVTNecHWk9UnrZyj6OBomNdZoIP0mxU5l14pyofTXrnmGSftWdyphslE4KWY2xe+H/Sr6Tk5UypGQvXs3NGObhrF8I5B3ME7aUdPazM3rhbpgG9V3tFFincCj0HcKcJOneVxz50HK56PqdMN1Ekv7DgJ07s0TSDXzk78i2IaUT006fwwgeeF3OymCyFblqrShCuFO9VE3s6Lqcza4BfT24Wds/tMK/Q0Fi301mq+GMnyjPP35hz+/jIzjXBPkXbIuTuVK87EuFMWd/IuuJN24Z15RiFP3CmwrXHvgn3cQ3s9ILP3mzqjSRrYyX+3mevTLGSdE7uI7NPVCfvuqOvoLu6e5IYu3Mm5GazOTP3RL8314hburpR+svFd4w6VcCfvkCeeWZ7nJIl7ssF67lXcW720uNPemd4d8thoCnGGu02qRpPSHkTcO1P7uAt1nmXfSoS9XFVXZ73yWpfSOLNJRL3K6MkvUvvjfiEs4crF9yLuemOVwJcCizZ3F96p4biLyDuBlznWkRaXqx1bTWqxKry3cQ+06zQjsKMVeD9DOwy4Z4vtBW1Ne09kD8e7kpVpGfb1uwnuVZt2gk2sRYQ8NPKuQd/f3BlnSrjrjVVKkC9Jf3bFlaodfaVISOO+jterJF3tPcmrt3Xv8kI7gfe6Au6Kd6gPd+fvlPi7qPfAmHL3wdV2hvYy6vmaI6EOiG95CGDt40ulWlRMFJF4Ik6++WvuZX/R3IVyH2W2w117u2gKgAcQ70/ZTPn77LNYFd5Rj3zrzZYEdCKv6+8BeC9n7inv8cH3OMyQd4t7/tGmWvydvFMKeLp7V/nRdOh4p8MxRD1n7CRbXeRTug7nOpGkb9jZXVNZd79L3Fl0z7t7d3qnmoUndcWNUkxlxcfKSvYObcu721+NRNJziYbuTtrj8C6SJ/mi+K5wJ/BoiO9crgbVBnfSTrUCfN7d+529Bu9b+bp4uxa9nJMPNhiKc78iJdJZ2u0laSb+Ld0JziXYpQyJbm5KuDfSvMHzTFd7p3SFqSiestFaxAqcU1WqeI1Uj67E31WYkYu2vXOxKu0ecb+R8C7y7k7eeZQAI8QZK3fwnfbOAB/jPoZO7cV78ghrH+6FQjv6tpunaErq4aOOLVUq5+pqJaoKMdI6cB/ZjnHn4joVLIH2kGasSHtPeiebwZ15ZGC6pbtjoqtL78S9KeIumXPz5h9t3s3EqmTH8Xdt70I7cUcH6553KHpIm7L2Hou0Y8je6gRDkDesv3d4apvCPRtktOrtYO8QndzKv1k1B9PlJmhpTvNVcYFRWXpymdRbymUW+1Hpf4lmlXF3wdx28JQeiAzEa3fnln8rdi9llBP8FM1bfKomj7tOM9QoVm3Pv6e8m8m0I2mpmN0xiLvmHUoe00Yn7zwrhtk9u2rF4+9Wqb2/Z5vx9rHQXsK9E/ZJGfZazD0Vl6JkvTqYbjYff/zxh7Fwb6hfgfl5jDBa1/JTJuZyUv73C+buV6kjOxN3p57w3hB4xbHP4xp4lXrkU6rIMxD3lm3M6+Ur9PdYeruJgYaRJg7vpF3kDB5NgCftNPhoc9VOpL1GOwlnZybg3eFecnfaek41WpH1zlIMgR/Zdw4e3wTQyTqayEA/bQixXCn+q6QW+c9LojvsXeqQ/DaCzvTeBHtvb6lKmEcPvo56erfDT+NFLTdVs2GGvJfOiVF1fXDewzuU0E6dS++x9yS9Q5b3ZWLv0i3vMps0s26VIyfHhnbHu03xp+NxBndau3/Z6egjjN0Br2lPWd9sPsyijskJ71jio7zikndq8dC/DHc+t8eNJoV7Ib2by/ieEGfE8zXB3Uk6rxTuTcHdq5DeWYD/o5N37e5oBL5VmyHuGnhVnfHIw0gg4m4HaRd/n0zemwD2iY0zpmdwL5dkuLU06bZ2zXr7cADeaTZgWcEulo5hGqkXjyfdYar+NYjHst6OiTmmlGZo77gUJ9akchU6dZum02xqx/t8gE/lmRzuxXPACe94wEnxbgO8B57Mx+4uI+Gdxfc0vjPOQK3lasOj7xTjuxXDjMEdrSO7954IM6iXlK/G+BSDDllj17BbK5fZ6lWMZzFEm2VDzh3r/z7QPe6sRM78iUgeeM/5u1Durpk+eBGJHK8M9mGgm3f4EUJO6DO4D4szxswuj/r9HbPD3bUQZ/TXinUefQftrfIMReDz5UiefgfuKM9kcS+fGuhV8VENI3O/FNaVfJAx0/Me9s3HVxsRHP7fFltyEtLRJc/Q4OnuWX83XUbKKK8Iu4MbHdduEHYGe71WHYo7TEXzXi/O/8gZPEXcI52n8f3G8K6qM6KoGLnUy9U27gSegQa8S6AZj6VAY/V5Fvdx+RmODOzZYkx6+AW30xzsFnH/Is7+vMCOJIMZDX3Z/COUz4biLsDbNCObq4p3XX3HTOCJZ9bfGeK5NF25l6lEmVX7L2x6srs+N0Npewfvk+qKgSYHfBLfg7un/g7YMYi7lbL3S+CuEo1fsCrga4c7iDV5xvDuBNZP6e4p7eO++uOka1upe0eJpccDLk818yqzo8PbKQA/lPe/nXYb3entdHeoF/fG0w4R1kZT73CeYhZHDzcH2aPC/OuG4z7SuBtNUIHv83eHunTt7k6JvdPg6e4i4s7T7zrNSDUyOSs2sbUZR3wrzOz+5DVXqLWGPamzzwi7zu3SrbmjC+zO2yMdVP9yeWu3r+5EZOWY70/vHOA9lVq8MsF44FvfE6yifyNTCXcNvJL9b12v7CNOKfPqrJilHT0pRqYPepD4BHduNuUDfCvN9Hw/wZgi7r20FwuQc+3uQJzAQwzteeJdtynm6mMMQ/s1UafBV/9mg4e7iy5ie6+E9j57p7v7+kzq6gvt1VMJL4K6PxW2UscQVB1S4w4NwV0CjarQZE+/p7xjxLX3LO7knf5O3JnfI97Xwd+Pe3Bndt/nadR5VinsuGs2vajrHJMGmaVrMPi/k/cZ2iAFZ5cLX3qnuxd4B+n2xXGuF50E/u30dPtSfZY3/lX2svRSFRqGO3g3W6wK+NxRMemq+C7Ei/JPait7z5dnlLkT95R4j/suFRkqE2N4bl2klqga+OeF91fh688a4KWJLon943bf6e/UMOBndHewnm6s9qR35nffHaEcVPFxPXUnsw9Ng3CvNO8e+JlZsaKrE/BHmvf00SbC3sm7xp3EJ/urqvLezbvg3rdKLTx7XXjKWoSjMZs+1LmxdBXcvZ1hTJ9upks4/OXyoFpXf5cuhgEvru7LM4DIIM+N1WJ8j+1XUctRVMMcxNklJdJO3HsOAXfzPl8epQaf+Ybg2N3jL+Ig7mHFqqrvCveWu5N3lmdyvI9PRQH3sR26JHOcg52KH1bq5r/uXKNK87oymF9JirlGs5IfGsckgTomGYv1P6zK9CrboYvqXQxMWfPnjVID8gL4ZFXxTZK1Go5U/H9K4z6jKiWFu9dESpJo6WPb6mAkaQ+8izzurWe1dXnGi8QT967d1URjDLp7XoWKDPVZny6u3Sk4NH+hTkzon1P/mNTF+/8vfR2E6xm5zGLMUC5dXUPcnA2vC/6JZKS9hTsuFOxK9DEYfEjwlEszyW6TzOfqi2eYZiD1pLZIgdDY5WqQxv0kw3sZ9+N+c49gr3794tuvuvTBLvr+ezMFffNX6Pud9NVfqi9++WH9/ox1yTSMk+VCWl+0f5Gm7mahnbhXQrt29x7cgYUt0agIbzM8q+9xenfiZhNxV9+zRN79H1FmBtQQd36ZXogz0R9n04X7eGdvn3x5++13r70uegHCJDd8r1fy6RdFz4meifS00VNWT1JPPPnEcD0Z66mWnkbv1zNGz4lehNTPuJPsX/3aa6+9JPrpq5+//tpjGWyaQxXUk0Mx+f8JoupPYu7a3cvhPXkCzfjgn8ydzWsTQRjGz4kGYhrapojmkGs8hCbePImteKp4sPhVi1J78tB7IIjJUfAkUoRCQUTw4OJBT720R5OTEDwK/h2+8/HuM7PvbCdrW/GZ2dnZSVKL/e2Td2ZnZx+vKNghRbq/NgGid35gk+iuStwBvIzfg/ZedtcHpkysq03iXnyl0/Q+1HK/f7jT7l7vzS56r/rjXs/Kxd8KJwGkgGv+pdquuhDAjZ6n+H17qTZOrh3SJ6Wdjesbry5sE7kceQjvbuCAi/B78BpG9hG4I5bhhSxzg5nNkLvXKGmDLz9FRBMegGfeATzmzpDg72F3Z4H3OiWm/RzxXrYWD5nZBKogUSFwL+TtaxzIVF812xJbKWAMnAE11JZqnrJymAf7gn7720vywf7JZIEn5An6jc7++22wSegytgJzCI11ae48oK8yaBcdVT2Js6C7m4jmztUQ74HBdwW73lYcbYlwBu5Ou+zwDE8oqIvovbxWxvIEnlQA8wO4F54Ayd7+qtlhwsEu1I6rOSPRl3RxIuVhL/FvyzNAqnMKSs8W9nilzqf327jMigtF4N5pE41ivQ3bTeVC4o5nvwZx95YmdGGnbIGvP8M0Gl6gIOzulOXz+CiD96C7P2aHv42AJtRb3UR/1cO90lrPxX2WeQNKtf4u0W5Jz+CdQnUswZTUnnaczly5Xp9Pf953gCpOpA6fMhniO/sNE7+baAbTCuLDkXXZ4E0zPs7dYwPvDDyEdc5vb93yFimQvF9l2hl4CLgr4cbVFHviXCUrF3cxgcbKpx2L5hXwdjEAeXR9tUe4r4J0yTQBdlogXzSJMieb41K9XUG9IP9Y+runrdVVk9POKoBf3UU4A4+n7BbC4F1Xtxk/QBcidLf7+vkkSeplQ/tcHHcE7wx8Zf582me17h5ZVcyJZjAXeMsOTBvQM+PSCGnksz0yE2g82O86KwAXDdsxa6Bae9sl2rWx+6jPSi9tSgbgf6JLGejBfUH85cmQ7rptp9ANXXVEeyRXlngOahTuGxsUzsipNA1G2S0haeyYlUBJ0s7mniTnWtPxtNwYjZLEbI25CO5s7wDeG6TJX2iJNsH7FmW4u1z43bi7yp6/B25vCsyObK0Xxh1yzb1HIyzK28F60I7/mZbUtkQ7XaGUJ2APma+h49UuqvgnDPps8cx7R9t7PTOxK9Q9lY/9QIO+OguDzzH3UbI+fj2ZjM8njdp0OiZNp63yKBnNMe0xe+eQZp6AT5XFHQqEM+zuqWw8A96DtzcBd3k7H2AP4x6PZLiHwpF7l2l3UJ81vFgyZGosqWIoPXvFwJdqnpUyzBvg7TBNb//CJpu7xt4iS9KH0t/9mg5/6k4cI+N2xj0pL04mk+Vq0hovLk+slpcXx+sNim+CEu7OvFfWTAwP3AF8aJVU0M4C7ix7pckH3ozPPDSF5J2Br4jHGRQab1eJVZ1/u6pwd2mXoBuWgzpVvBdib8A/GPZ9Du49+ptnzz2AJ4e3IbyKZr5ue0uM1S3zHNQAbjlMSW+grD/A3xCg3cihvbo8WZ68bk1fa8pZ6mBxei4JGnzA3RHS3L5zNRjOgHbaRAAv1hWD4O7gXU4HJmXDmUrgQZOz0z7vq3/wqUO4W9ozrC/9Ay1QXtB7SrxD4pdyJJmXrk9bQSEqco5Mpo277VLs8Dag2dnoHdrOqt9lJXJ1UlDbmo5XNNE6KVfHx7hZXGDS0t6+rCAfL6asQ9Q0HTWI7v5mbGwGonm1958+YN4d4AMzgUO8g3ashG2B5/kESlHc4ez5uN+Id1KB+/sdCt3J3H3YC3i2IXKBmGSpFq6drgB+MepBf1HkZ2li9NvN1OGJdxXPXH+R4l63kLNJg3orHaNb00dzenXJCYoE7aPzrw3mppTAj0eN+c2D7aFHPGCXuKtB7urmYxPTuLyLJ8jLeGZF477l8y6WjszHHbzfwDMmQ7jH43awLnB3afdx/k+VA75JcfJNonxKahqxwRPvjDsJdp66O0ITJOd9XDObOZCRTH00GpG5j8F5UMT7m8PSy92D4XA75u5VyzsBX6nN3TEWn+Pu8hHyjDtJ4O7OjwTuOcCv3XgE2CXuoD0yAbImce+sttug/cwxL5miZAu9oc6J8oyS4Ifdn4pTFU4aKwBPvDPuqTMDYMszb0LeMA5oB+zA/VztXKID9xjv39+VSqWFdy/mhsP5uLuT9DX7VpW6rVe9HuvxT5DP3NfkdVZZIN6D3eUdxh7BPd5LDeLebDLtJ4CdCXaSzWbPNVLKt2q3zaZuSypAPs4HiTolgX0MfVNCJz8PXN493OcE75phcKwPkGDp8rWstzfOjwnlqTR3ifu99V5J6/nbo/6wL0feJe61qga+Urt/c8uZDXzNH46Us4FJrr8z8gZy0E7KG41ExB7BPRLJZFXWuFNPFbhnYQe6qkBzSGCaX2fgQT0fQvr9+ByXgSqfA2Hol1CPI+/WKaMVlYvYcwnJkMmbX+zibsTEymEaafC2lZJ/lrAQyqxPSGOK3KO8L+6UWHsv5hXw8zF7J39n4h/e3LpmHycvbmwK4o6bfiALuse7vJ2PjJ3ZjuAev5Yqlhog3DsGd0k7BM8Fo/ByVEAnjm1j6GW8BeeG+CDqJuNLJCQwT9AXIh+I4wgbXkQ2bZJ3xr0H3CXxCmmEMwcics86PuT2UrWxU47r85cS9OTnwbAv3D1k70x8tbb5+Nk1dngMvUPAnUqFOyYTGNgF7uzvlCz0xPojBXsrV4x7LG5H1O7efQ3cuZvqWzsEaHUKCmYtG1ELvq6T1ELej17AqVFES7rAAD+qJxKIt7x3uwr3Xge4S+Z1XYNOmXVgbD9Mu7wtPKksz6h7v/z/yrcAHu4uh2fu9unhGezxm7fvrMinevi46zI8mwC86w32rgqP9fW7ecnD/bglILOLtpcpCdzh7a6zMuoCW9B7pvJ/B9g+S0RbMeLl8RL6AfpCAFp0UpmHW7kugAfvZO80NBPGHSRjp/Zok4F8Hu2NJFmczIj7671SFvgBgIfATn8wGFbpSuTHwaCigW9VqmsPbz57AOIf+NeaoOxCeno+ASQeZnN/jQZiDOsEtSa7FSod3GNXl2rC28O4I2wvjqUwY52La6FAI/q+pgi7vvMJCJSD+zyVnH3J7kwbAw/cu6vs7gZMKYTwtAPogvasPG8fVSropkb0+Xcpo6Wf1UGtLIBn6Af9w/29K6S9t0eDgV3VRYU1CvkVOf4ucPf8/RnsXW2piHUah6FTCb6exzrcveDVJSwik4s73FQiVxzXkyuOPGNvNp2RBO65UP+FYO/S3QGnlDPsiBQlHbTXFhG3RzX5sFHK6snhcChwZ2v/dunJ/u7h0dHh7ruLewc/KtxzJTQJ+fu3n26tPGDgBe6Y++7F75f9wUiFuvqBIlon7MMl437jRtzYQXu+uyOWcdz9D2/nF9NWFQZw49ulNiFA6CCE9EHjg+KDQveA8U9ZGMZB4gth4cFpTB2R4MMSHhYkbRzlAVuHyc1kIWymJanyVmOmeyLZnCZYRmtGMhaxRhJ4YDVNDYnRB7/z73739jvt5QL6O7f39pxzT+9h+/Xbd28va357S7J9yfBAftdGRlFAcsCWne2MISmIhsKLOexB2gu5Amdr15FVUV3pzzCg7Zc/dshlyjk65VyH4Qjv4lwVdUdHjwF9ldlmD7KD7p+19RiEmdXYmE53f+y6sciyGSC22XTHuC18R+X9/U2t4PxFS/rqC/DCdlgs7F+t/Q7L1SFBQtVdQd2J7eRiO81k6uruDKOF5JwiaHigF8Z5I5lTPveKhu1Qr+zZMmx0kAE44/a8hjOFOUUmlKdc4MLjj+qB3k6q+wBGdxvHsB1RdXK53Y3NqzMGIbAYj2t0jz0yGkBweTEyvvmt8WjTL1RH5Vky3/8WBPo3wHpQ3NJdbED3awATHX+hT4re75f5C+JJ9zonqU7w/2uvoztg2Nie6xXMbQW73H6XrYOM88BcwRB09s6JA/bAE/7MqbtsxQEofJdeSgvap95MTHfvU96G6M6opztyIrIDbbOnvOm+8XB9Om1QlvrjRPfYPWM1Jm4lEIBmtzeb0Hd0HvD7+8F60P4dyMvhtPR9B0xzSFzYtZd3wfNGEtI96/5k3UuQUIjurV6i+xkvCiR3T0T3LqV70IPuMGsc6gn5j8RRdafJjNIdVUW8mo7Ymmb5XZDespmr8UcG5b3LMVDEjn+659EmbNH3q598F3j9c16p+gYwhnRxBLr6gbcc9DPEaS7znJruXfemOrYLqOuHz913k70WoNJcpM5j7ni6J5W9LyoNIcyjkPnebYk1AltUch88qu4BnrcdM7oHndEdhUXQYjfLnYMdPUz3jQ1Pvp86P/b5x4aG72P9Dt9jiy/Ep20frfav+3+/Xy7fnx9rJPjtoJfcbG43MfzkdG90Ce7E9zrX3ZEcKhCBwjb0EZG9Dt2TR9b9QjIi6h29ERRyN5GUWAeOJBU51F124gYKQmZtj+7ep3wOozteiETd0V+Cm+4IbX/KBzd+PfQW3zdOnfrpz4BB+Zj7jsH9vdsx+50E66W7nL/HhO/47b186waR1n9Curvm7TJtp7pz31F3AxZMHJIRRS9u+FPaYdf9HAxMCh8RHJGkJJR2ebFfMhOQryx0hzeBKHhY1ZC08qCklohC15nYsnSP0Dnjz6obGum0onsnw3ndXSMxgk2kXy870ua7f558yuQu/MaXz72n9d0Z3GMrIyPsS+/eHgHWf78rKa1DlaUtHLmBhvM1eRqd91vlyPhRd53s2rwdFlfdle1onh6iPNEd6T19mv26gFV/c4uRExQ4mUIeDypfLZJ06F4TK0B3ZAoZwu6WNbSwS7sLaaU7mTLMGRu26ZwLmXYa3VF3jtZ4d/jutQb6mmf5PTN2KqNiO1opZWudsM43fKHLZ9D3lZUXFuPinkmxXv/77m+cu/+st2ppqkXjyMoKGA+LglvrKF6oq3sTzdtpdD9TfYtYde6eSTgCI0Y4VRPNkoRN9y64kb7q3mIjKPXFaExBsZODOXXoN3MZSGbcddeDQ5Mhow6dfMr8j0P9gQSMnJryOf2nXHU/VUV3PUuPu+tGtMHFyIcO3UdL+1mp+U4lq7W9298Wn54xKJfjwpn+ldbvb01FJyejUxZRiymvTPy6en4FJMdCBfcfrtTXvVV/4wA8iO4DGt3xL3aQOkZ5k6/7UPdaBE5LdxKFw9iZtA7elxgUrX1qEVuxQHfONnowV0VhEA4rhmwVqju3QkZdcgk55XNGDd0xugeduvuIv8jhVK8F65ltcto8ulPuzmZHR7uzB8XurP73+OAvPb5kEF5tnGbSjPT/OrkWnVybdKg9IZnyDrzOKgR4HUr0w+OPUd31iQwTXR/dQ3bd0XfFQJ8EhAoEdXQFDSOT7AMisBPqfqmQoRRgH05yMKPr7lH/pMjXg4dA6M4a1AIrXCJ23XPriWr4AD4kQUkbki6YMuVcUk75tHbKecMtuutVdkdveQsvfKm6+J6tFBcOKqB9dnRnoZIF82FRpgPd95ubW5nv14nuT3wTZ7Y3RNfWJnlon3hGxw1Y+EassF37ACYmotGb3HcSrjmHD++MWrqj6vq03V13JfwHljrrNQN3Z07K59C9ACMJKCx4RzHzcmwCZY+wgroLUHiJ0B1HUyJQtCTyhiRvJjTggXS96wWue7uL7hSPotOUxudTybvK2bP7xeKDZ3fK5YNysVguVSqVkszn7wMPG9uY7cz3ZaL7S5fjYDvEdWE7ynxspiZvroz4CdxhrLlRX3f0ndiu1135HlDnqlCqEoMuQ0swB0YwUHeM0B5JXFL5A+3aM3YtG23NEpPqTnHT/dJRppyxR/cg0f3YtPjsz6E0iwc7W31apTEijlcOHgwPLzwoFosLwwtgPqz2s/ya+9ezQJsyYJp84PThS3fi029PWbYDJ+o78fxp/gwrTtx0p7a7y/5uwxj+arY+eXenI5Mww30W5geou3kM3U2d7h0XQpyBS30J2fhHV0hwocemu3lE3Wf+E91bSIj2CIwRjostlJYG/oWx6laC8s7BQXnnNfB8mAOag/dMeqk75OwOpmOPqnS/8sPl2D2wHQDbT5boVOOKPrqLDS01ILpT2aXo3Hmn7bV1x+w9kE/n7aRnDAe7fSZTJAyFLaaZtuseVh206DsS8uX3zL7qfnPP9h4D3fkL2GO6XXc5Hcw+rENiE6vwh1137Wx1G5yX0r1Tr3sLCusuuxAan8uhPl648L5ViOvW1yOLazOj5SLLXUql/Zel7q/tV1ist3R/6NQd83fU/Ykf41EZ3CdO1vYbExjeqfQoPxZYtEWvu0P4BvxW4CrZGyzdgzWje2fCrGLvgmGRPmsmwow+vjLNV0BX1B2axKItAGky5fhBPlbuIlYO3a8lxEFr6c5HwpIfCHGCBesFd7tkU0Y1mXbdw7XniTV7J+iOwV2ju7TVHqnVVlsAfKZMt2UxPlUYcG1mAy7FHBThzLRSgscCt71YypYO4KR15wHoPgppTlOL0/ZW8H3GqftLd25Ougb3G/WoF95HlNcUGs/1vuuiu/4UVUZ3Qt3oHhBimWEnIHxIynHaNB09YZG4o+5eUboHXpFjbQeYHzcCMD+GEQTdAa57u6QjgLqr0deCqmnXeqEQnpdCrUp3r1OWujs/ZbLrDtIKT2U5TEqDbw01lm/4eJSd0/z1qdFKN5yhvra/AxF+p6yi+8tFVt1h0b20v/HTrK/BAYgRXw0YyJUrP/zy8aRrcJ+qR+03yVS0YcV/AlDd6U0yus+X3nWcqvYI3emFSNSdCv/FXpXsZqHdsLM4bwL2HdzrqTwelemaT6vO8ZmezrPhaxIchS0zdt0le4rxsGIcm4ju+ZT3Kc8vVkX3Lm10B19ppHas6DtDrFUTH4+6C2Y/2mehvDgMyTo7S1W5O4/yUCuW4Rr8V3/OO2XnxGzpzBNXgLWoi+43orc+qM2tqZrxfSJ68z/RXXv1URRHImPX/QzRnSN1v6gLeCkzt2imHLKn9gYMJ18sp9NL6fCQ3OFsGlhaDqvIu5fn9SHVP87q14MihQqbos3okPubfxhGkOlFjFOkUPfFFPaSEbTJXDIkweswh/y46hla5nNUdfNaGsD6UPj6Ujq9HLLpHiTRXSishBXS8lan5cpzGdQxoquRwnBpOjL/Y7G4L3IYPQ+6S3CJ5ud5ontTfMaey0B4v+Wq+9RaPf5X3WlsR8+rzlGrkhmlO6DVfSg85FygpFKgqaqA7GfzhpYlU+wXTn3K6+0XTVlflCelKahAMS8GcVTPENsLdAfFxf6pPZCRj4UFZ8SLWEyH7kO0wKIvXHek05rinpoi1MV0OMtQFwPT4lPV+tFd6lpVRHIuK9jmwxa1bYAV8xx2J7ZfXX3+8eNytnsYfOcBHjUvym25/NVXj/+aJ/8davyePZehuuu9rQN0/5+607RdeK6eUHxjGN3p50xQDBZd/yXuXEKWiMIw3HaUICoSoiKoaFMuui2isEVEbcIuJFQEhVBBZQ5BIBnNmC5mUy6KNDNk/jYtukFkblKiC7TsQmBRi4gWFV0oatfnmXN858yZGbO0nhl1PDOjIz6+/3eOY20EXDJJfcLeeEkL4IDt7HdmI8/trfzx7ALv7dIGDOY/p+E0kW9zaU/C0Z32dZ4Qz40FSXd+kACbS40Mm+uOvXn7BNddvIYDMfG3h29wwJFdSnfpBOBpPLfbrmyXKxbR6JIezrP9mOzkOaIdlN8+ff5827KvTPSP3+F75fP3Cve9smVL5U17fwQ44T4h1TK/p/vFkOkf6x5y3oCf7dFINIpixpvu/aizy7abjSq2XZilBVCnHWC3qjtxxOYNW1H6F23h+GJJd2oOxIbuhf52Z2xnogY08Tb2wKrus8Sz2Htjsu72kZh4fDznTIY0MCOfM7OLJpqnI7blJdz1rqKxdR7rqNgV3V9/Obvt85sKZft3FvLc9jU7brzh8i96/rzyJuLRPWK4wz19Uq3dL46G8emupntAHzWKYsZfdxgfm6ByFrzbqFJoaIG8Mz0yztlge3S/1N+kik+JS3cbum8YpDvymbPvCGfrRsFWNPnqfknsbNa0AN0bfd3fyemu6s4jeZqj8a52dBpderGNqFc0nzYtMp3tIlRHrktQUzlX2fb8Mn2d5NH96ZsbNz475czChV9WUTEzQw7348cb3nD/xmznul88f2g0nL84Bt3Fv34muY5gV4gO1D0grXV9I4NuRCgv1gJp2Db+7Du6k75sd7OAFmETxvO544W+7uYg3XV3upv8EamC4lRNZbO6zZugu/TXRl8ufWZ1R3e0ELbd0AJ0XwvdHVnR1eSj56Q9ZhHnsBv7MeX92VP++WGb4P1nZvvlL714f/9eNK/a9uFDruyp3I2aN9yX3j0E3S8uuEKvaQTMvDX6dPevYwguPaIdvtMcDardUbzLNN7Z+kY2ke06uyEJ7HeB8X7PMB1KVSG3Llru9eUsiaYJDYmv02TWqNNqs0Wmu27aMs6x0Kzbtll3687W2Bsb2hyGdsrcyNvqoqlq6/0mMFFSDvB2ibfsjolPitjIuIeeqpLu65nuQl70NSE0W4sZeotpENPK0Tfcd9FVrXz5cZm0p/MJBB+2PS57SplSTpPDnXRvvcKXqudvaaPi0flR6z7DA2SnCaOPnoCXdSe8XVUPcwumqZNcuNDcuzIxCOmheuoSh9flKI6qK/qPKzaqieAlOfUePd1121kk3ecc1jfI6Lr40NGyO911vgagRWky3boXa/xoTq3vN4lDrisvrFYl3XE+pJruAsQ1JvdCwIrBlKM/P/SEB6u/XJbu/3zSdpUyzI9eKQOY7Q9ORg65dL9C7fFEPJFIZLQ/IpPoQW/7La47+3UrTSPQ3Xf4EcD2KGx36z43aCAyNpOjzarZph6AbZqU8GLTmPbX1Ep2j9IpSXctJqMldI7ZpSPVZN0Z+DsAlCbo/ieglvGt3QG0Hzz9PpFyOccKGuAZhG+fk7uphNF1i8l0pxPej8m6xx8+fJhIJ779oe7xHjGX7gzH+CmY/jLdkekywna4ruqupnvN7nB0U7I9ZaY8d/sbiqpw8ZHOkeHYXJd9NavQ/bqm0tBTfd0BdB+Eqvu9DUeGg14t0t1H9/ET2XPuMXRX+PBmBmz3G5WZxMO97dU98fDhzYwWS8T+LAXiaZo8ukN4eP43upPo/skOotA9tKvKfC8YpkBnbqWc2dr8zrTQwoTnGC0ho2mZw2FURX3TiPdozNLiuhmie8rRPeXV3WLNONz+rbjrNPEWl+4dY9hDvq6FpvsoCUj9yOlpqN8VMCiDwn1G2lvK0PmQxuQTsu7pmzdv9sqZUaU7QK4j6X9ngu6IdjaH6I5sF+kunxEJ34malWKQF3Qlli3z3hwtccQyU6KF0PnFEkMucYr84bCqGpAfxPLX3eQ7yrq3npkKeopjKlgTGJYZ+pCpr/p/053iC8MzT1eerdBN5ezKitDde/5AZEqprgy5L/12/Fntygm5dicV0ul07E9r94BihmYGVB863RHtkF0hShO7BWEnAMegu4xlHXE6OvXNhmLH2HRvatqsbk2i2+or3OzWCnGU/mbHy66UYLO6rgjdrT/THelOSF3VcRMhyrl+2b7ywranNF3YXkG4h41BZl6yUmbS/WftzC1J9xEh6x7kPF8Iuai6+4+z75EGH2UG/ryjoLz9prEZ4XApZWQVAVrj0j2dNSwZHJVlPcNhqf8rgdbl22bNohbyr7p3htddrt3nKAORYyXCwOg75frZbZVVF7b0wz2njEHeV7qp1E81jMTEq0dj1x2mYwmyh0tPM3T3L2VQyERRswOfdCc8umfd07OsVDdkWpaVlTaB7g1rMFl512u+utMqR3dH/Sy7sNk9WUUthEvihZDuoNm536OTKgjdn1mDkJ/XaiLd5YHI8esuRh6oD7ZHVO+VbWcvnHXZ/uSc2wZv4R7jtlMpU8gcnz123ScHOy8P1MwfWMxEAk+QcURXZWe6L/HRHV8yteS3/5nVynh9bFp5y03+nhiZ6Qyi2cwSqSyDlH42oerOVzq6W2L7FJ9x6eseK/qQbllZzrW4aGwUs8/462qKkZldnXDu39uVBSkr31LT/V8UMxHAyxnhe2X7yssVlDL7w37E5Ni+9EHbmDHznnHi36Y7TUHOiyXnRtwi3SOM4MLdV3ZH97XQXT2JoJprSiQ0lXpTooOIHkSsdRDqWPldZLuquyXpHgR0X2z5gSeSkhofpt/lWvZgX/aD+WxtljIy8y91j/Z9f0y+C+H72f5zf1nOdnnE/SQv3O+VjImiMeXY+HUnb4XLwdJjDeobSXfXS1KKdriuwHVfvth/3H3cFDflswIyBx8TH93zv617mvYYlvzv6p5u5i3sZbXmaPK3qsz38RczappRvntHIz9Itu90RtyvS9kuvmAycjPbxtQx6w4Cc94V5X5w3SNhoGZXgO5B6V7LUry3at1rE/ViI52ZqY2OWa18vue5M6WuBfgF3Z3lg0GTS/eATQjf/X9f966VP8geg13xwg7pTpDsc8c8EBkB7mgr7/kp677qLSqZnTM+9YrcUtv1DqZfOrbfPU4VTtWY8g90R4Hi319VxuYx01WQ7nuUgXZfAosZpHvraF7QKwjudLj91XoxEZ8TC61Uas1WGJvyB4GVu1ajtmZXY9xt9ccaxQadWj2TtQ4Gk4fuB4dF6H4t9JBrubzlOuRN3S5rXq65avcxpzveUiyILmv53M8P7m9TI+dmQPZ58z7txKkybtsTU0ul+3Pax9eNX3foHF67y97jGroHf4kaBnRnttPb5vG9BSeTVtLKAysp7G8x+xvxtJz9Mw8ezYciCZdkTUfvaIzmVWWr5NXcrKT3Ed27H63z8ic/PEdzeN5Bhwx4Y1GT0n2s4+78LfUkO4YjL/Ozw/jv9SA7EVlXqsoD7sRSOnlgqlGfMKb66p4JRY43zkxGJhNTdYfcobW7WtWEpzsI131wMdOCbgclkoRkAuyvc93v5IdP2Q6e1ieBr3WvuanWkkmx7u61bpqnVg7da/9FtaXTwvMOSTKZ0MbcVR0c7NAdkO5UrgvZiU9GQbV96f3S1OPtNF376h5PhBBnlqfjXvjqjKo75KZl0W9FKxQH7H5wug9OdjAtQHf43jqa5DDBAelPqqEV9l9t9nVPDkv+hdDOZ11O7cf213WlnMG5mWIRy0DTXCvxvMOi6j7q2l3uh0F1dhct+3+xd+4gT0NxFHcS7lcVX1gt4uJsBz907ebQSWdFRbI4SMcGwUjB1sVBNxURBUUqrYmP4oNChVDJ4FYdpJ0LHQQVHHTyn/vo8ebmJo2vyZM0vUlv2qi/HM/9N22vfXsIffx89qznrRHsSovHGu2qKBP/XEets9WGuxV4eoj34G0xiYaC3tFxh3mf0hBOye4I+DnujneV8rQjVq67z7tNHiAKYNB8tQLu53BPNxP35kq415avqeF+/uiI6+gLFlJTtG+zF3EbOldlo3Oi6UYMr5tz0OfsuJuVGa/0m0opO6Ctj9COXJ8/1PTuytnpm8V+4N42aX/VoR9t7NwOWtutuDuVRqqWuFcNWXCHeQNrhb8QEM/N7vZqjJX2nRbcAXxI/9PPZqNzR9044XJx/F23EO75ysc9ztfTczOu0SuBuzqMJvEKjWTE92cs9FU6D9nM1/N6jV1QHV8A96Jy3X+EO4rKYtJpP9u5Nv+i4/4lOlAlyoH7c22UStow7Zzdtd3bfpc83hpmbNU4O+41mk3cJdnK4JHLaS6U3TcmcsyOEmRF3XD3vRruTFfDqbUpHkevOP2jmP7mUkQ/SZDnAvejftMi6kZzjHdTly+HqnPeRXaTt+aMcPRVP+DupuC+PEHCpjwswv2FxrJ7ocaOXsAZyjXpNi1Sh0HPlFRbCzN/DHewrucZMZ8hYeOZY6XxQfb+i0b7DcbGzzjow35/uH//s3GS9qDj0e8qeeed857d3W0C7tTEbHd3nWqkdgANyrOy+0ZzbErLTNR3ijmBe8UoRIZRELarDZZQRdE/l/S7MbiCRWWV5TBIVxi5UvEIU9M0VLi7SkfljeMeEHbx1Bxxz6m6F0SnJO5yK7m7bMa4T6gNCdxFc4l7exBYNFJdZ8Yfy/mTuK/ZhcROCy3HnDjm8ZrLxS8/0X6RsdsyyvR7vd5w/6JfRpIB7ds7j6trwL14dje9nW4WdwfdsHqcAGLDKVxMgLijuTsi+yohxuLutuxOlFDqnU1ezF8R/CGluTKD5Oic6A+iaP5iMqMgnKP2BcVgwBIyXXZJfXfElvQ2jzbiM5HOmwK4z3Tr9mtMnS3+K5YjPOeLlE/v/TncTb511EWK0fucXCv1h3cOMNL3L18k7F++02pP4D7s9fu9vgrvDfVmashpJ9zHd7dvtYeZBiunqSJxdwpkd1wLA4s/tdyeyC5APyu757G+k99y3B2VGd913boCxOf+XVf0R4MghPevrna9LtkZWHqE0UCIiK6LrqNBSHsK6Gibw0Zdf2nX/iq4R6PJT5rNnLIrH/XnLEfl5XNOUuvMNtzP/CrrZj2mpFg/k4D905Dce/+wxkjrN75w3VinlVsUZeDuMryXl7R7gnZy97trXlHcWfkn3FPnfHdHgMGNT4j3dLNk99KKtk6cq+9rs7k7wszcd3XVY3H2hRL0m97vhEm1Bwp3f8DyVJVI+hyzmtyzTuPMma/Qt+HOh6qu3CFglYSYY8G9bB5yuHxOgTv/+Atox1C1OO62t0vQXE6mCHaZzReL24wD//3ixe/rjHQzph3ZncL7lLZqtHN5b5zXvx5m7O5eNd0dFHPfBtvwcRlrRFsHHriv6OtYcNozszsTuNd1uWJCQ4ef6OdBGAppa1JuXWgV3OtN3lVgRoCKPZttwl0eEd0SuMtOHPflgY8ScqtMPVsC90bdPGR6GRwHl2buv+zua6uEdd4wrw05wWGXIt6n+pv3CxFloMWYRxlJe4do5/J23X3c+Y2hqkWGu8PMsQDc0Ga9Zbo7Co9Zg1PFeomzDtxt7q6yO0cKc5668wTukinztCmOe+ODAjQUuLv8uZK4+xru4riT/Pp+TeDumrh/8OuG5PPA3RXuZf16dwP3YqjbC4+SdRRjdu74pNP8rIfKOiUZRTs69BjTRqlSnfa0lRFmsguRFadKcnQ1nEajwkx314w9teKuCjYYvmIf4J6fYfCbKQJ1WhphxvyV+Ij+4YV1w75z5Cdxt/YsjjtIDjjuUpm420R5qG66O06qNMHdEWZ+yd0tZJsBRm6WqEOed/7OUKd5uP/Z4s1z7qnVoE9JxsB9WNlg0E5qTdudDNzLlVRJ3O2yXTNjLMC2VoaxuvsqVUdSid8p1EnZ2R0F9zAuutDobvThQ50Hl24X9P9T3BXj3cFv4+5n4O5n4g7a4e4G7oezcLejjtUSauxGb/py9mlfZXJoSNXG/b3xuEfgq8yu4b5vA38vdarRToV3Cu+Fs3tR3MF1Ms5gq9kBm+DudtTh7KWdqiYjUad7hJl9luxu1Nt5wX0Q0z8T9PukLmmJf/dv4j5RuEca7t1fxF09W3HcOezWoSpwLzgwhaVjYVh76WznFqsuVMUFitf3L0hY1x+vrse0R5J2Pc0cOVIsuxfF3agr4hIC8Qg6qPVTK7o7MOdevszqsYTFi3ZWmEkD3qy3C/rngn6iwfffTnTcu3a9jVieaqrrSOD+Vq5O2Ig35eqcQeUP2CdAJ0M1plqJQ2746TvgOMrgHe6eH2bygzosXQ5O07od6dwnEMmsqZ7+M87aOurtUK+2fmmdrpPxtutq3brbAe6FLiIoN+yqpH5W1VKZoZbYpBs7357t7hJ0RbpgHRGG7oV0dwfu+BqxYqo0YvoHof63Eg2simosT41IaB6Ik2cuV0MW8KZcbTMGBWpzkPXqUYMN1O76IZeDjL1C0SWeihUiLXRDJX2WC1O7+E9e7xsuDPfOXf+6vr7+QtEOeWvO447N3R0LzAJ3J+cCYeDOAQbncs1s641Tme4OX+ffhs8jDHydsw7t2XPV4u4C9v+yK4adFXL31Xwd8xlb39aYe0t/YWR3yzr0dcOl853tplr3brdsuGfjXK5Y1SgncNdRRpCRC9zhjEDkSXN3RToBXqKJM478Atb3EOqxrma6+3/kLaTD3SvS3bmsuK8VRD0LdvG1SLhCoIAWw/VaiWg31aHBaseW3Z2qkzIXzu7wccU5HF1vG4PYVHeXREvgRVpHhAHrHHWJ+8vT2lBV4P7f3ldhPju7HxSfZlqzFR0LWjvk7XJ+GfdecAy0a2q177d+KbtXeNYxFmKp4W6gDQc/pbUV3ajKG9ldSzE0EdzgXCcd2rnp8oNHFndn/3nPdfe8uvvB8dkdZgA3q+uqicmmXWtnl99nSp/cKKqh5+2y4P7qkOdZsrtFxbM7YN8sptSrI43G5mR2V1AnfN3M6jrt254e3R0eErj/z+4FYM90d+B+aNK9vMcOO6IL6uwoPFp4pxKkgfvqGX7rdotOba6OW8WzO6mcoQTuqC+a1Ri0MWO8qru7YF2WYLh+NnSArmnT0y31J8dvH9BwF7T/9/eV3b2S4e4HJk/8PZsMxI0Eg2J7rvCbSuqjG6TVKzQ/2DtzUCeiKAxb2LjGDZU0FooDMhpwaWTEaWKtSFIkgmJSpUmnYMQFNwIWaiGMqCCohQuoqIjI80FQNAgWzynEgBYSUBBUsNDKM/fO9Z/JOTPZrPT99+YuybxMiF+O/5y5ySxK1NELl48OH937S47uWPvLlv6yzwNsPHDXFiaknPkXSQtXz15evneOcBe9+6zpI9V0seAuRfd795bPOZUa2KPc99ehbVcE3AfLv6fjfvL5utmjePd6NVHJ3t10GEUfFIy7/nAA9zkAHLAnoj537twVq7efKyfjTpqGfdDormCXcS+Xly+dHwGZRXMzmMQWaVbmWmQN2F+N7gsObX32Xs7MjOzdq+nRXQurBzDmxp2bGSWATlUmnURGZu7rcrl8rhd3Ah6JmenwLsPOoju8O8f9XvncqoVz5MgO0260F1NJJ+/Ogt7dH9q7f92R4mZaF96P4t3TJUd3IE41zj3OK4F6AK9x14T39S9zjeav3r38Xjkpuk/H9r7E60IC7Alm5hy9z9tPLdYYc9Oup7LkHCRwHzozk477xcvvk86qVoUygncHz+i4rdEtjlF5dO+x6wLnYJ0Gp87svxfq1VWNO45Up2P7gMKaSPnaTHv2EO5a+8/M4V9PMo2+SfmYpb1W5kIMo7+L+8lHJw7uG8G7r0sWMzNxswKQkbGhKbYB9fHoLtp1kG5QD/uFk683bjxHWr783OvLm66s30RODOt6sjOmNZiWzcgq1Y2qWms3bVp/hbSpS28zaePGt0s00rAwsDSc9jmAPSp1GW+o9Zdxf771iIR7QG21Rd8aPlGfVeUrIqvD4I6VvEi6o0nNzOgfeY+YmQT3AoXzU/N/fv74Ry/H1mGqQZlWKHozQn0M9S3XPQsbg/g+yc6vpgR3WscV/4J74poZCPORcd9arb94+/YprXd92l1XH2O9u/SNVMY6z8yYK1KqYnCXUQfkkTvOTL784Bt5xaITlzuoHNeJy/r3ZVuDqVgsWkWnWPRCfXlzVjyvJPj2XYZ12cpAWwdcETmmmanXO2/vVIMLRz7ovG3NyhoTUB9xzQyDmTUwOeA8KCa6z0yJ6jzIn1r40bMjiv4bOlQgRzemYMBlT4vLCuU4CnegHo30sm9fSlXMykDrCGdSNL/ebz57+EPVdfXOFFZWv30Q8+74IQJJLBEZBZwtmIm5+BBz0yjJuAv2JRF3Ky6HWBZkqZtuotvE2LeDkqaXbIwu1subYZi6Lb9bfn5M5f1hR/zRQWSBdZLCXUMO6NnP2M7htPOsDFQNonf0dFL/+VIZ9wX6tOodCfdlU09xOEq/EPRglpn0P83EcGdfTOWcI9tOLUBXHwDgzkGXUF8YFMK92IP56IoFe/u/D/KWKvyNJdxxmAovo1qmpapQFU8wAfcnn54omiFhfntA7z7v0AnpNFP9ztutVfj1Za39rfrIeXdQzjIzaEK2IVxqFbgjkINzBrsWcHcEuVTjJZSjbigJrt3WharpoyBggi7oMYPwx+zv2MZWeMOU7xZ/Is/xQmIPWuK+dYdClSlyNBQxMyBelAJdNeIid2hG9fbQqZlFO1KOVK+IF6vpvJgVi9cvOpF5nyVisnfXnezdYdUR0o2AO5BOI30u1RB3Drk7gqLQD3JIZ/Oh/fcOGO0+m48vG72qunBFPaGrdINwN7BPYtHApJSTWcrdDC6qBNqPHx96wTvMDNfROxekJWI/Or1p984djIddAMzPIcHJIIoHAvDUoGrc4V0E+6JkBjTSuCOSjykQn0qZPRhG6aDa41FsD7PtqLsRg8gNRHd4eDm2o0RE307tEf2iwK2/GN3pN96fS7h3u+y6slMYa+9elwtbIoagrnqAryem6ArieXRPgF1hDtJhZm64gkqm9JfaTCLe8+XEjfIH48uxff+w5/QD2Qar6ft1LJ9kOyO8ElOCMVUuFyqVCHe4GMAO9nUCcgfxjsqX/ULBZZWef+L59fR5SnA/duLkPAH3zgnlXSDKS7b0XaNeVxXIm4ykQlr30AIArytwZyGdKuyLHgD3+cCdwb3FVGqCohoMzWPUGkWR9zIZn4AXFBCpByjAZFBZuUxmZ87qudPzPceOHT27AcOBTLi18aqiL8F2M6SSbRCmmrBj8a6Ugx8lvMOhmQHxcgZSpn3pIlzYHRckAO4DrohMw33ByRMXpatmn5jK9i4Ry3an6pH1jsuyyVomeXf2bSWUONygHmOGuyEciOMe4G5w1t3I6kHeK9UKzZ0up8BeMzHxsGE7ruVFRaS6zjDyL7Ur7aYP5GxC3cqdb+Y3++aZiPWdteb5nPr0Pbw+0SQqfes8oR0+bPue0S+3VqgU1vzCS/KtQV+RqxsXo16VIER32cfsijgZwco8Bui4IMGM7qch17sjMcPPMV1ZdFPA/UF3Vm9evX6nU9V5yPoo3h3QK8LRMLb1FAMW3UE1ojsUxV2mN6erLqpSUQPMwy6oRsbfWN71Qq1dK9lur7xModBu2o69s9lAaUxcL/mukZ2sPyR55wv0gfKCoUVo+lYpc74xkacnn7Ats5HjNdu0N89xvZ00yLuWlbvebvjhBtb5xh9dauRrtVrzUgPK2O6Ywv+ZiCYmuk/GU+5zpMiumvjqgXoP7fqCqLeAe080pynPv6fhfvTyu6MLBNy7D5axhTBbO60qziJlB/9ZJUM6BMTVKDm4c9wRyamRND/sTs3//F3BbcrIAvMlUoBZPl/LrzEIQ3amRpjaQXQuxJTf6RiWc2s2K63R7RoaqI76UgT3fIh7LnP+UuP6wwo9SY32GnyYzM5ytVq+sNNzCfdKrTLh2ltq7TzxrjfwrrejL4BUiKh93h+fc2gLcEeiHetl2Mkl1JTVA8vURfM2PDrN8u2p8xTcDx24MnlIwn2qVVdkR2/ZqRdZ4J4q+UKTMC8I64CdieOOiA7UOe7z6UYKcM+la3NuM1VqVBdMgnES9Fqu11C0Vyo7fbdkjnyjuFsqOofKK7UnQtwd53ohL6vyMGcZ3C8FuNs0shuFgPRKLV9TxD9sbnFC5Pxgo+B5De6OdYl2276kQfaavbhXYrh7+qXHKcZQrL1iJvG7zswA9MSkjKrpqweOB6Ifevy6cnClf7vj6LsLRxcJuFen1vEVj9luNztmdEcChkPeH/ffvJ1biNxUGMf10RtZixYfrFpYupBaBxRfwgTnJYsIPkjIYIOgGF/Mi76kotFVH1zJo0wJrhgV0QiDPkmjuDQW3VYdoT7UFRcVb1XwVhZXu4vWy/87l36TTdyd7e76T+ZckswF+jtf/+fL2ZnzBexrgq5Qb8DdkhuBPapatFeJbxHtxF4IetL5tl/RWdzhvYXCwoFwrNPW7r/0wmZ5TmtC2SXGfSLxHE16Hqdm51oN3YTvBI6XzdDbCtzlMMHrpBMdOp8mMcvBZx7uJ4Z4r0aC+UTtdD2iQ6gYd87MNC9wJ8abrDun3HmaKn9Y6d467ue4/veSsSfenNa4f3jgsbO434SZqvTpuoDuO3TiPsZ9w96d43vFwmwE97W8i5CsGHerQSa3uKqpdkIC3/YTDxYid8MAvMcTE7Y/pAmBe9vvWK6QaSahQ9ddO2Ez7oFUKCIuC7i3iaJ2d2KezAxcOJR4IDVPstRowccDZC2gDd7t9hDuPsai5wwKEYdtmuAqzXccXGHN6z5SNB3bX182V6q29dYgxp2tDOPOKyCZ9mFNP9swTb3hd3yv46Zx54nqc2OXSNw//PDhYy+8+urzz98lcuzfYyGYYp3N+7sn0CHcN5iZ0RPUapJxJI2vhbsM5rJELR6s1+9XuJsVoTuS+FLGvtW2Sg8muLDnXS+Ak87tGf6Xx+TRCGiKCX8hk93dGFB7HowDm/88LJQcqGA5pUWXtbM8ScrQgW9J8rgdexTC2zSPrTDWtgH7IPtqApo3AHN+7QxamEXH7Zm2vCQrcy0HyhPVKRO7Y2+Z9Lwfe8XM8B901Jx7k5U5UrubCtrfOzJ9IXAfJd++Pu7wMi8/vkPg/uGXi4uLr+HxwwkKze8D97puOoG56rl4d47s0AaBv72Ou0adA3qDLn0d0d3cKlkkv5M6gvZWu9V1Q2o6brdtK5mmnVJ0ty2zJUy+UchLMCRYLaVOTHHb8FfPDibIcwfCAnmDkK7CcKkR5ndxIijNlORmIaK7apaum7m+fqVgIOVAqhl4gwLhefOQ6wdnuFo6umNvXvXLLqZKO37AvWGaet7R6Z07dy6Olm9fF/exqWfoV7PvvPPAgcWPThwQZuafY58fvRKJmQturmnfvhMvXYX6+qs2jDvQ3phhH1c7wd6MO/FeY/1qemBXZuZTc1QZtK+tVt9MKKR7ud3Bv2zXJPQDL7G6fosAbCEkCyFsGx2728kCj87b3Qol2hZ3E+JVefqO2AU97WSgZrgYOoXAPevWUOum5KlSA0DDBgXsi5wCOCfiCW0aULm06uzdkxBvS7hzQpYfXNQalewtVxVVvLvc6t5d2femb/tl6d923wHcx0bJt1dwn2zOyxx57qGpyck7L3x48c/ZlZWVPM+TJF1ZWnSXf/40FXKhH5VOdr49PXESevSPP24gnSc0SmZG0T4q6xzYq9Gd8a5wrhBn2K+GYGYE7gY2sQ9vBh2gli70JVD1Yi3LtzLHC4lf37eEjbdzmrR6TuZ37RZwLzzhx0NAZ8x0jZLGRuHOz7e7Qm3FilYZOPD5qzCWkHKyxq/jToy1W06ANzIMj/M/ohQ9vKzCHZd8Rd7dJ+9uUvMrCy2Bu5h580Y9Rrl+SKKtSwadzurjEeEOaeT/M7rXV7nvqxl3+RuRJOTbCWcW9xvXu49NNgf3h146AtwnL9x/YranNdeb/e6KpTNzDeqd+q6H6jBptxQGye7OeriDcmJ9RN2udoadca8Szg3dhKgQDcLd0DiLutLmXYrPQIy7bBLsoJlCaNaxLWVH/Fgc8srUB1+Muxe6ZhJ41I7dNFNKK7HQNwvgHrfr+U68ZSumoWDhc3QSMjPzPqtj48kdkc4MXHfgQdr7aA3y9lm7VEq37kCqSdGdPwqL+T13cXSnir07mnxLVe4s9B7/rOn+0oXTFwrcEb7XXt/Ofca9rqljz+y8ZHLy7kdee2N3bzdr9swnJfdZvVN/9nYf1pqjjeReQ9+1hAckWqsWAFdXrm/AsY/XojurEtexkbihoztg1SSvJfM/e4p3Ny4kU7nRtqOoJcNsp+sKA+N5ZYYBkWPiKWefeRZ6OFGBcOBokGwf6hohDHfa9ZVsxs1XicgZH0oI2WRIZdpptXEUClJLGJQsJ4QzzjKmvsbd8di7y6bnMO5bIZXdRQH9+vFxwfY60Z1pb14atg+68pq9Tx+X+mmDOt6sqYeewbfx7bjklocl7sz70tJsE+5/Avea5tLrG/OQjPvYxkDHPl4hvhl3wTZKqhh0FuG+BtrVkcAl1yzLcAAMJduRLRlWnOMozQKLlm3xVNVqUQKnqiDX01SD1MoCOI/UEh0X70jcQKKC7QfuxCxwF/eHWIO46yO9LnFv00RA3pWKyaqomYANBPFciu5xSv+xZE6om7GM7vxmkMBVtfmEpQ5AKOpqVVuMO/POuK/BO3+59R+wydCj9L0Pf5xe+E3p2w3qt2Y9ffG7MDN3Lyy8eEjizmEc4b0J91NNuGc3r87g3Lcqup9bZEdDG5tmM6NAZ9IbcTfrwI8mky+NzMLzwpLIC4YF7IoCDrmwiHG74xLuHdjmVFmMYEAlNTHDVeSU6FUFAhPfYvkCd7rraQP3qryYTBSeQ7h35OU0680MTLXMYS598u7uDN1+ajkhbLxoGuTdGdDR1eK9if9qdIfW8u7NXyxjzvUuZ31zcIu1/NTLx3CXaWH/LoU7c43wPjLucQ33e2pmZkOwo+DAXo/u2rjUOa/jvnmZknc3KN10+A5RqIF34VzcvmlBHN3NPM+SACE9RRkiHULRWlFTeDy91Bo04N5340xE93D4PQdxp2WX6BLuvrwBVuI9UlojgwMsMSqKkkQmi5tncTfXv7vGMtfoqK0xussDI/w19g2YFn7DuB/cci28+Nn0zv0LYzXcT51ZagjvvTONuK/cfCOvr2nCfWNiyw5TQxG+hjs2gP5/4M4yU7OfOk03iIyum0aWCTHuJtCfEcH1K5Shn3oadwi4a9oDDb4X+wob4GvPpGKSGQ4Kn8ZM7CJFlssGWi18kkEeo59J3I0Cr4MLQvDP8Fk+ZfC1YYeoScMmGDhWS1+mdl1Ri/uiyTt1tbg1/GTgzvNUtbEaaec/Ybph92Hgvl3C8Hn7SaRmFhZuq+P+9alTs6PinlwH3Dm0bxJ3tjL16F5D+v/DHX6G0c8p+LZ0z4xsU0riHglc+m6AFH3fcKiMPQJaoVGGYsjwmJG4a3QiI8Xck8YCmaQkoNtMfh9petHw+xGBlxuZR7iLd3UxZAojDyjcm6xWmtTWzJS4Ms4yRSezTEWNb25Wrh8eEKvEZkbuuoLuqPFem6euzB2evXzbdPCvHU8/+9n0wv7JOu7lmaWRo/vXN90oMce++ejOll3E9nHR2Rjue67eg2KLcYfOAkm4xzpYm6xI4i4jfS5u/2dUClZjPSgMWk2TOiEOWdR00QwydTZyyyKE15cZzcBIKGbbOJ7QCzHNGEH6SXYWkD8RuNtDtNv9rtK87QQiBe9Sdj4xupG5PfpU487MN8xVq12+n+puM+7Hp8ZeOvrAeJOZ6cHNjIr7F8CdY/vmo3u9wbhXqeaKD+2hGtpq3CHpWBXufY27AYIZ90Di3ifO8wjQh47bF3NJzRgZ534akPem1/CNKu6BzmGGtASyhE9JI427phmjiXGnJgZZSbgzx1bTisikCGninFi22SBDVfXDBrdZ9asY98afpmHam9f92nOHd1++bTq4fHzH9CuHFqYvqeO+PLt0ZkTcDz/4O+O++eiugzqH+fWj+x69aaG5Hbi7UgaRlZiqx3elVHT3bcvw3QDku30XB3I7yiXufKM2Eitm3EiNER2XcRLXBuLuVWlYdp/CcegO4a5fIzqLu4VUD51SuOsL7JjXu6tVBqqGvSrcqHIfTW4Q9aiqbGLndvNGZzTuxDoH+TW1c4oXyzy6vbifOj42NrX/+2OP7zrU6w0DPHv00GyDee8t4+5rA+4nb9SmfZPeXeMNaeRB/1refU9V3N8G3E3y7FUJKtnUy+huxqVpOgHZF+QRiWSK0UBRjQtSRCcKwxJPogkrzkoB00JmcvqmeEGMCsvQuBtKCvdIPz9wVXTnzxIPgiER7Qy/5+HKGrIG15Wtme+mixj3yl9oV/3MzobvUdr+uerBy99+enx86oHPX34TuFd18gPkImtkz528eWWuCfd9Wxbd9foBjvNUMe4czZnwZm2Hdy8rS1SEvGKID19MGgsviMuArAzFeK+0IkqdOAiovCjHlBdQP4LtEUirKOmmhnBCSUTnwDAGj8adGWXcRau0TI27JYdVlDmlkFjxmztOEidQDBWel7tWw4IKVVSP1fp4NO/CzFSiOS8TW+dXmLZ/rnpw5ciTl1126cInr3x24P2vSTqI9+ZmZ3vFUm+15lZ+RdmM+02b8+4M+7hsMOrj4yhXRXfFeR317Y3uhfIHIS8PGDiGqQNuZMYYCtgdD2wWOJCjRpYSliQoCGgtOoLoHxkaVwwaDtwmKFe4x4p7EykagbuWxp3u+IqJs6FwN9M0inTKKMLDtqMoRUamdPsRyf7FKuPIMrZDjPtFF3GMX8O+37vzugtY6Xbi/tc7u3btevHtF1CSjkJvfS/1MfQ2FT8P6fTp5eXl03/3mqM7E795745dQ696CvdG19KsvcO4u5Vy1KKmWM3+CkBdihaOKFBNN0uKQK2TyctBaUSRnK4Kd65ND7se0Mq4UwRnRbHE3bTEpHhN3G00yAsp3MkmJalhCr+TuLZLEd3KPFwtZg9QGsdoSJm1kmXWK12YTSdMibsCfTj7voZzf2j4l4Ks/wH3L18k2N+hraJFPOq69fs67j8S7gz8OeHORgYFe3fCnaM7Y74O6nv27t37+iubjO515q1IyJaZGdmxNH/ZQC4b8II8s9wEF7thQKZa2JUg/5e98wmZKQrDuJ2w+MqfjYWwkfG37E4JSdnqpmRpbMzGimJKCZO7I7q7W0ijhJKaBZFG/m4pComFhQgLlIU857z3eOY4Z+Y639xrwTznzrn3++73zUz63ed73/e+ZxBoCWBsvK5SfVaFcMcfAXtVEHc3dseLtCQsIu6406u07bceoU8G7e+tZGeClSbIouH3qM9L5E6+eci4hBNPhunnXnDXorFbf/daCdg/QK2sMVc9/bWvORfcAwqf6L9lOOPgTuLHC2a412GMHYL7SMQ55CsH94pTVqHREcrnTW3svXZmYoiGwmImsWYJSZQBWWSq5j110Rwj4rEXT8PFXa4KEwUNcXelNMfNjLirVOcJjeJVuxJHNfbhokKNSGXZRbPGdaq+YEaL7k7mg+ocGcT9+83actXTpx+Mwh22fy944u5rD/dMYndsY7o781PMsskowR1wu8jrqVLcAcyA6O4iSTlxz77VzacKv1d6WSvyVKSEqBTaQD1v50a6y6WXi3otuLs5agNTMf8C91TinKG479TZgTb3qQL3i/pPjw6cMHr6G+gzNomBwk+29aWV5rd4sdaEO4FnecavzvgLsmcgV60L9wVHSnA/Ezzx6nfcXxvcoTF7Zoi6Q7rsfNzJtt3xG1qbLO5JJY6e5BmlyepmVG7cNN/STtQvg26A9ibKMWrfRcBrjBfUbfGS3cHjR1Jq2SeVGR0N2YQ2jHum718VXq10bT/N8vYW7eI2JdBPAbNfjwhsX3LxIi6BR7cy02lPe68Ld2aplvddQXevtTTD0F3wjcW93/Vwz1dV0zOzg6V3i7sTzMwk5P7AZhWK3RPOUWKw3RSxO5GyHLLeoZIeaAOP7VtmoWhTxxdiwcPVkspKqltbtAGrro1lwri32qAddMtFYsiH5ApBdqoPcJ9Kp9V4SmzyvF1YPO29LtxZoGEMTw37LKWkRtz7o3G/HMb9+A8vmGlX1jMjoGNPZ5dR4L4iBLwvuntQSeQk4UWLEjgpAOemflIKAb06gQV3Bi9x9+ZwbcfzmJ/BbxhUm+QyjHsPE+uZ8r7wurhC9Mpa3BNAOX5wfYjOLnI0MDRZP60Ld1YiR/F+6LbzuZAb68lVmanG4/7Nc/d03J4Zws5oJuzuYt2uwsxXlqqy7jJMEoS47cKof7S0V5vmXGBb5IZpNx2hbqaE2xZ4TFQj6223N0rh9AI2cdcl/d52XA9FlQQvad5NUcpptPWBynqGcxGOujqHRj5dNenEnSLhjN9dzT107LdcdUk9wfvpJxZ3TCHcP10K4v7Ux73rdgCP3RHp0j6Iu3DN8GWUNlWBO/ltj5BNMSmFSF66BvRKjF6aFKA21EjZPLV3K02UWUSFLDSMe4rPxM4/ZE2hHWoU7zHPVFGrTMwvIj3misM014lvMlXjbaYhvPPuaiB4ZxsBc9WKM9XrGvf+/scPwu6+/8XBMO7vPdxfr3ajmXjcWXUXvs3Dd3dBvUybMBjMVObvozTlS2FIW1kWS1eS2N9QU78uJLOyY/D6y3NkyA1sv71FvlZDZv2thkhJEUlhourHndV3T4dmr6o9V2Wm2j/35Q6w94QTL7/IUTnubgfwmKkqRNI93Ecwjk0OZEd390Lxv6MG/TySLkWE5Sj0PErqnyri/dQv4u4jz+qMZ+8156rMVGHv9HCX9yvn+9G4j+fukqX6hZkRuJNuO1as3SS6tna4uyfejJ0///tKOHmPiLPluNvZ432PE73vrAN3ZqrA2od65ImnTzzcDxjcWZjZsHfa7u6z7rs7oJa54Ns9wqMQcZ+2/hvs63R3P4RxiO/cXjjLaXn/s+D9zQ3oTWSmGq+nj33cv2zdMCAxd+IeD7vMfqoqtEMAe60FG4cF3nxgE9wnKlHNuPtVSTp8qPa+7g/bCN4UH+91IyJTrQb3AwcOPHT/b4NZ08LdpqhC/fDYXRAXvj2t1cNognus6sedBRqnoeDw9dhcFbAb9sh7Ce5vCHAk7heWnPJwn+UoHneu0pMJClZmLOiYKA04QYewxzbBvVT140754Qx57xyJa3m/cZM3Od9EZKrTwX2FbZphMLNsTNwJuWSqtHX3rioJF8qF9AJxu6O7Tz2jkonq0zMr4j4snAn2v2/r3I1peX8D2rnQtFbc+0+Pdz13X1OBu3NJNkXeiTtoFsxFFnmKJz6/+/xLayaqS2rNr3/nd8Q9xuHh7/eKEHgZctUacP86PdzP9Z8+TT3cp6pyd4HeDOardHfB3EU9JI//a1e/vNS6//L+gNZN9Ce6v+6+o5d6WH2BXl7fM09EsmMDms7sY2x5Lw/dY3Bns3u8gPsPD/ekAneHiDlJd9xdQMbDh5vk85Cx/ealgjtJn7AexbvD/FHy/uWlxv3uyROF5swrBx5zQIc6z9nyXmrvlneULSOa3ePdPYh7Nn3cibdF3g1qXNxLtVw2OVyOTbQJ7i5y3H1CfSnoMsrdfb4RLT7a4efs6dxb5ZZmyuuQpL20hWDa7u72iN0E7vmixbshrLLFDEXeZmKLOzF3v3Rwdy1+uSUcg3xD8h1Bf8XHY6sheXNaM/bOmIHHRH+gvTKMdg9qNXT2LD7P/wiCGSoCeLck2TmET+F4RtxL7jJBbyJaCKrD/Sd7ZxM6QxjHceU03tfbsm1ryYGDyNuZclguDkrJRXJxorjg4LDGODy1M0hPGpPRIMdhU5tyUKQIRUmUiJtQFCH5PW++O/vsmp214uD7zD4vu9tj1We+/+/z/J9/e6hW20UixPcUxR3Am1ZX2Uwz0N010bLSfKPIikS472g01iyr12pVoYpQWckpO//VV2VRtCpCVaUaqU5atmxNo7Fyw9q1DeA+m4pQLu7UgHcEmouNrVirjvMIwei4v7Fw/zxqmMGJX9WCcSR5y927LFwhnS+B+0rCXfMO3B1R/hNvo64uwE6qVjTsRHtN475S4y5BB/M28L3jjMGD+KP3Hp1AQhnfYfeRcT/2+NG4cTeZXQd3M5JtBncrp4gC8HNwbwD3Lt7/2/sA3g3wwL0K3Os27kQ41ZOpBe827lDfRDM5WPzixKhH3sd/hODcsWOPH1q4vxDoQL3fmj21qLBozbq7IVxcytfBOoZWz8K9ijDz391/DbtjuXtf3GcrwiXtopIaPsFDvn/hBML7+A67j+zuhPuJXtyP1GnhgrInizspn3Aq2JQRbR93x2o0R0sGujvsvZv2/8RbKujualuGHop2AD808ztVfe/TH8Ad5l5Q5O63Fp7InCEgrQIv6AF3qSLmPiC7W7D353+JeMhiuF/fhfv/teqwy1Rk93KeuxPgQtLhkeB/Mi8raL7nefPnU03N7FnAXejeWwrv/8pKlXDXZ8Tg7qQvOV8SX4B4RHfb3TXaqKAlANzuGtyXSdxh7xr2/+b+++6ueZfGjkgjpaK7bGTX8+j7wO4LPXmybcbc2d40b/6syQb5ex+Jrpf/yEqVsjvOiMHdD+fgXoh4oG5ld3AOyvtU2S4VjXuvvf9frA7mnEohd58F4hXoVPXLNJ63+P6840bz5s27f3/Tk6mzvSuCeYH7s4W0Vv03VqrC3XFGDLi/qu7qlpXdsxryb7RNP4O7QpgER4eTywrXz2oz4b5yZWONtTWj5IxDtWp23Fijnq47fVSJa1TX4/KoPMaY1la96pTHE2gKZHcTYYSkw1NBtgHtk+9LyiHN/f0nUyfNv3LF82aNb62Kw+5/BXeoUI4H7qDaZhyEY2gq4G65+7gWqn6pZ+zJphN0z732fFm1LKT6Jl/mjKaINTPj7C3rN10e/dl9dxt3hTUcnpDPStE+dx5Y72Z+O0kwv22uXKv+IytVwv3Y4+8W7utywszvEQ/cpauDdyoQ9UF+VnB3Ze/gHcCPgny9U5oyrVTyzjuO2+440M1Q417mmbug2Z5Sd6LEbbF0beRe5KfdJKr0nbnuQJVlve+pcb/c/e4gdLoUXHQutlsYZ6cqxLszjLuvpI1IrS6Hxya8It+i3SJe6dLXa38U93P99CvcP1m4L8/HfXTk4e4gOwM5ZMy+VxJ39WtVeytydHOPeeCR2E3HCZnrQPysxj1i56mGWoyHuxnjAWeiZiRx9uJ8ae+CvXv3eqk2b4/zjWa+ajNgQbOH0rSdse8pbI0DeQvoxgqqgu6OmHbvAv+0gh1T5Wuwu5N63B24a5ltGoW80XzvPmi3dXy1wP0yfWH7OMP7SbMxo8F+fuug0bNnz2R76zm9WAD36cVxB/J0FcBd0ozUnifgvoFwH7RWpWs03BPR+GTss3gzbAqdl+Yb6nBzkyUNVypS2d4NWmulu7sJuft5N0kqkl4uxOare6LNOvsZ04hOafup316Q/YTJgrh7uIzRR4hPJ1KR70VR1HTF85ypiVtyqpKcqlQZgvWC2X027StmiNcJnjoEvDlicOXJANqR4wn3B+Jc77WXL+eMqZy4/U5z/uzJfXlPQcfNymHAtxkI3N9YuG8ZBXfwbsqMX+M+EXwX1Argbtt7+TfcPXKSNQL3hBFTQu2L8vmbru8npyuOz+QLATXarSVrDWm3La9mzJqdd9aQ6irYc2I5YlyObrZTqjttGdbjBXsvKqUd1XpNnZJceidTCsQ/x87KD+LV6zRvo6relMpbq1mA9mHDzHyhHo83XWPwUyYjygwm/vL2F9fEn16PSycW3nx+kEDXnENEOW6zu/MO2ryfG4D7qV/hThjna6p5iGsw7sUFdzfh3cbdGdHgY2KYNR0/dabwtbU4jhtxIHBPuGSuHUcsjEuBG/JWymMTTsh/k/P0UHUiSLyIKCQAbyk4Q6obPKjLRsLvcqNAt+yimpTNopVvFLuuu7axN4hcN1or3k8vI+HzYJlw/IBTMyTwwJ2UhzvJ4h0DmHuO7r6+dm3h+HTi+nEgDtat2+zus3N93T17RuyA0Jk8dydiB5OegR1GXwT3ReoyJfuacfcGwjt4h7uPhrvILc3EOGaZdwSpPInI3d164DtOkDrneTkUjNUkssxk9yCgSoK+gMcAzVeDiE0TqV44srT30+I1+vxiGsVcxans2qX3P8ObhHtF3y+B+Q9FLHW0MFVKUxXK7vbxX+C+AbhrgXEQr46PTZHJPV+XPnxbeI0YG4+uvb6cw7px+Fvn+rr7Q8vdP+fgDuJzHR7dIXFXeNuQA33gbqcZ/KppdNy9/e+5czqIpYOmclNSPZrthGJO5FwMnJQTp7dEhq6SAzcSHlYintapLxj1gxomZZ5s9wS8rq2eFLabhtrQfFQ3dTPL1yD2eRCwsMWrjlsSHyfpDi5NPVWrfXM4cy9T0+PuNSxVlynckd27ZO/TkKbMBFs5vF9a/XXhNYo0Y8H9axb31ccHxaj7lr3buB8YFncDvQW5ukwF7rW6cQfJuEimxdO2u9u4C2XcvTyqu6dRQp65zOAet0O57x4JO73IHYenRDxhnfht3/2Z+iuB3iyknu+GaTNSjmwCiMddEXMSOTjNzEbn2Xb8M/U8zeK+rNUMw5tui60httdIQ2+6adpS4aWjp4pYZwjY7Y0ZK7vD3X2QDuDBvGqmIcsMAfy8ry/Gk2mufbicZ+yGdxHfbXe/pY9Ewt1f5OMOmPsIbk49wA4Z3G2a8RxVuFBosJlw32Bwt87NAPlRcRf4BAuUNTfJv8O1EvdKGMsnIuKs5CuTpv2W051OZ28wLe0EJeoJxmtyA6XNOlUBtgkgC1hEzDMXN4E2Z3OXlHicwd2EmfMsdmZNUT8TRLxv8/N6Pj3V3oJ/zFQId5t3DTyi+5DAf7g+FuAfXM5j3eD+5Jzt7jgjBnd/MWFId1c4w7XNc3nKhhlDtBA1EIbZFza/2ydxx1oV9g7Yy7+Bu8uSyl5Ft5JfqoeniUG2RnJI9EvtEqYcQO1QklpKKmXy/o7EOXXgxiWNOxiNjTk3+DQn6+6V1oJp0xa4LnMrauvR9W7GTr3JaCbcOS7z8n+9BHPP2nttAO5TpkwB6v0zzTRE9yGJpxB/4ndD/LWrlxFicnCf17sbeeMx4b7+RQZ3dQLY1h0Ld5v5jPMr+DGgh407rNs0uoMheuaNSwXuGwTu4B24j0Z8WeH+g71zC22kCsCwr2lr2bRLu41xW8UrWvHWQp9EEFl9EX0QBdEa9KEIa6EgKEtVQtoVCpnsvsQaol0Sg6KF2nqJoJa1rYrrFrUiZYVVVn3xhnjDC+h/bv1n5kxmMr14/8+ZM2dOktnu7pd//zlzNiko3LNAGqjnsDpA4ekUpsBtDjk5Vawlugt01CzMN18cwDRLDsiWuAhgpjBV5hWlyjGTxUEf7t1OIaUvPfFao3IZV6ipxWKtNpVNTZWrU33MZ0g2SbR857QH/ka7Q5fMpKNwh8J5TxL3GMB/hhC/JcHcaewRvK8E4M5FM8T9De0AVGL23Mct3G3u5c6gbnbse3HXlm3aYHdH0T0OKXdXaabhQoIw4kvFgk/Fqnb3vMS9IJAvAHcMp6r14kLRySJqOMW9sOuKzPRS/WWBu3x3VJFFBoA7JabEmdLbAT8Z5ZTinBji3gQb4J5w8PraHCaDMDdK4X1UvDyRGJ0q81R5+zeU1795NESdCyIjcSfxgcz3xMSdIf6zrQi0c4adigrvDDNcNEPcP99v6XHQ3tRdVaJvD/pwB8E+40aNloV70LrIUHef7q37NFqWuHcXKwL1CtAr16f6c8jmiOILvXmn10wfFgoIHibkTC/k8sC9tlCVd336PbiXMEIflxOSdZxQvU4BzPCeLjj8aQewkGF0UuFeB9h4H7rlgHQxAcmr3spo3afeitfcAbzf3Ik7Z2YGiXso8AwzsYF/6thzWxBDTGzcjxz04/6Kwv39xx73CbDbuEfMvXsnZNgPc/fmccdtVeJufwCHqK7wSvGAMjE6N1O8REy89Ew5RdQTZemg5Rm1IrIm3LoKOuH6ebO6JVWa6sNUTLFcLwBlC3fkGyctDvoLhTRnD7NMLjlcy3onGdWSHaemcZd3Yj1yBP4lfQrsI5O7h3Y38BL2MNyDM038S1V7/Vh8McRsyd1/8uO+tAa6LVm4N0W9KqhKHtyp+LgP4lqV4d3NO0XSsWNtpDQsutidyM2kHKeen0nU61VgxwXAdVCXLo6InA2yDaPZqb2lqf7sXLGM+6CI/lRdgtiOc8in1mVbQ6uSCJdDWlnGcXCHazmRLMzVp+bkQ+m9fDSHW7PMQzWeyoJd007YfSsIODFj4d6DLdTi50/fFOlcPxZblrHHze4HdxZ3Yk9tB+4XunEn7744Q3NDacrewVi2NIm9Wlfbhzub+4i76x5mVrOZlLk9O7UsJ+QHnLzAPT2nQ3WxOKM9nvdRHbxSOHoPf44RcR2aLk7yx6vg3wCRo9qKyclkriJmYmaS/YnKcrf+Gebcp3IavIk52a5aJndeqTbAXRKOLQz4Nt5V/VMs/lDs86+eGYj7lxbuX24r7rzVZApxP8NiWWabIVFZUDFs6pDb3WnvAfldg4DWU1ADigwR6bJ7pftoMS0eIe5V+SjY3msSOHBfrqXRrSZS6lI1tzCVnUnvrRZh/XhtygG8ejalG0ndwfymI9g3GpyRJ65ypIYbsCVMeRZwAlxH1Ap1ePkMQk3ndH96H9ZbzoifqSpP1YkX6rhiF3bJOmmHBOyBuJPxhsQzzew88Lg6ja1jmHffOu7XbgL2UHcf2kyYGdS4Q7a9k3dSj0316Hg+CVCX9YSgemaqMKlfZda7L8jlAX3FpCAp7YBBOL2A7/JqSq7QzcpZywXcZwL06jy5wgKOnH3yANxjQaV6I/RnS0LT06VSvqeYzYuDbCWhbt86nbiY6BNvqSTWHSfyBbwii1tMeLGT85+qWXH9gGXuXtxJeOMY38a5ma0Cf2XIFjfEcNHMyWDc14j7Jwr3n0Jw7+jo2BUX+dhhBq5/hqpmC8Ld2Lvt7wTeS3TIkAD9CfN/LcRRaXoO+BN3DAlfrYwud8KvMTgtHgaLgwn15sjNTANxccrpud7e5ZzmEDeG2ttLe/UBZnwm62XxkPhnYEPAWEqQXink5HwNnpyqL7R34xraKcyJw32lerKWT7tPVbFoTwSDjgrR3Jncjbn7cCfj3kOmd/5npp1yeBp7fHN/jbR7cH8/Du63dGwI0F97LZoOlO3BnZCjq6razBBxHxYzkVacAe10+HjCRWWPpHBgeQY7ud58csCQVXBETq7nwBjYXFbhIQ+bxfPQQojnxYI2XiWeWcg6SOwt26rMqBSCe6oJ8RTkGBxWF6Zm7BPzoAmR9bQvuNPcw3G3iZ+/lSjuxFUrjT2+nls90hD3w74w81sk7mT+WjCPdjO4k3Atws4xPmL2wH12cFjau04zBJ7Ix+c9DcLABRCSngz4tI8CwEoZXfVI3wCGhVmqjDRTMcY9kBtIEUVfmKLJ0n4TQVJPSA+onyXVrQJRzvwkvhN7eA5EXAZ2SsFu026Wuw+7cE/emWxrIGnvbYjvOwn8FmY6j/E61TsPyc8Ro7v/dm6zuBN7QI9Kq4/GXZCrCdfFJTPoa6SA+7DG3Y4zKRR6PIpqxEbiOMoCzlMkJ8WYrw4UTSk5rqKBanCkHtKPCLlmuMVObRuv2MCQs+AeWuWAPhN26tc050FDkrHnEaUHiHq3DTtp9+E+7HV3Ah8wOUnetz/TXLkV2Pd8RG/3ujs/WIm4v9AQ90XgHiUBfXO4E3glP9kUMzyKwf1yiTt5B/BGqf/lVVp7gU17v4JdRneB+zXAPSmLEizejzuPMfsOLLcfeJx0C7C/Rmu33J2LZiJxP3Cg6/SOGGpAe4fC3Y8xCofc6PNtQXcf89o7eTcW/z/yYNwUoZQFO2kH7iq6G9wl7agm1bQFC7x3rh7aPuC3buyHDq1+FPxBBEdi4/7QyVv8QIewjqLUyN059xItur/EfUzibvNOg6fIvavHncGAXIidGfrXiax7vV1mGeJOf49Q7/z69hg8P44p2r+1Dlmw71lfIeyWu3PRTDO4H2CWscAOwd7r9+KqdkLjToyboJzeL3E39s48Q+LJvGLYKJjjlKqmy5epzVet7k7XyIejxSUDFuykXWUZiTtoV8DLNiLGJ8/bfT042x5FnkhQvmf11Nram8+vndrjBv4Qxj86SdZtdw/GHVoJmJp5fP99NPcwvKPtfmKFuMcX3P3dsdkx/MV4eCfwGvn/gvZaA4TbyzhR5wWqG3Zt7nCRZUdQrqoqnhxP3GnwHduUaKJdffXUm6/fldC6aw2My0cg8eEyhD3E3X+ycH8/APf99x249o4YqIc8a4u4D50xPSzjjMkz/eSdxHuVRvEYHVrVaEbUc9QDljiabvRI2tMPER79q9RHeVAH64Bd0j42PFYH7vR3WSCafFCCn9+1ikizkxKufurNH3yzt5esHhOs74lkHe4eB/f9Bw6cOz4xPo40Im4uoRGK4loXakvuzjSTH5y1eQfwFEzsP68+VFEsbZBO1CXsoH1ssNLeCdAV7qrjv3K90zcDr4DvWGcU2W5XV7Z+ScLWvavP7Vn/iKw34e5cNHO/1tq5+7068NDbLy4/sNjS1TFutEs0ExMPT0yg3wB2IXucuG86zYyNSd4916skntBr8v8h8Pdx05V7FgjN5uT3dEiSDg1L2mevyW9Ed1+mIfFJP+4S+PNaAfy2Ey+uSFfXnv8h0UA/0Ncjv2aSi2a87r525CGvDpys5mbwNbNe5XK5SrWUXWkB9Lu6OprVlnEfGrpH2Lvi3QAP4qm+/9XXr+CmBgznJB3SqAN2aFZmGcLOltgTeZ/az2tTX26wXZyjgas/f1UiTJWjzX53h8b9fb+7L3198AmvWu64Y7xl8YGV5eVstgRlpUonTlQrOXB/1fTy+MPXdm0K98vOuCxQGA+39zHFuwAexAN5Lf1Xa6tPFFQUMoHKveqxoMYosV62IxpA1Y06RFHaZygn5yCdqCvNzl6edzTebo/XhRbP+XiPyyfn5zvXVwWpW4b962+//m7PsdXXuxMRGiPuUWGmIe7H7zC6Bbrjjo6uro4REV78evjhifGWlVJ54K7sxK6YuF/WpLzODp0xhPQ+NmuAV8RL5qmBv7n6re6mtU9sXhFtAzgQNxoE5wp0oq5pl8mdoseTeu/Fq8afkzXt807ph7VVkbe3hPuXH3/86KffvnXFaVG4DzeL+0GN+wOHD/tw//V4i1FXhLBoAO+Ch8ez6RMT8XC/rHnZ9j50D3gH8JJ4IC+ZpyT/ehetfa4uKgsHVYPWekb4CTmyA7pGUqy6lgYN1RQpN6BT8k9zcBZRhiL2TPK6CVk8Jv8H41XPn1o9Bm0a9x8/vvnmRz+++emnr4jAvRIX99pZNu6ZpnAn8hMLy3s7xrti436GrvZmy8/78KzQmELeSP59yjoIof0bCNztnIYVwoMoURoThXyjioIq9C5or5B2nzhPs+hCHtWkGs7Ij9TNVeSbCvlNZflPP7hZ6ukPInB/OybuXCP2iht3WxbkI+M634x3PXDirtJ4B8Y8T4nEHflcVf8GBVHv4v2G92Zh8Epjogi5DYsD6i96WOz+YRpjRzQs/K3Gl+JbM46CnYR9OF8j7cH+rlryziTPbmvPAJcz//D8GrJ8XOYR2m9+VOP+aDjtAwA5Hu4HLdx/C8RdRxctwL24uDK3jEvXE5Vcrrwy0bFBuSoRuEukUU3DwlFsPrl4/yb/7gYOzXjsX6aQOMKOu2eymOuJ26ZG/0jM3jM3ydweHmnUjuHGOyNfqPruBb2+dioe87hSRZZpyt3vORob9ydduH/yicS9lYjLq1SlkS5MzwDxZczJTE+Lr1OZhqonsnOLExN2xvEZvelET0QSeRJvAT90ww2XvZO/539tKO8rvm7jZ+bzpWy9zWlrbwfH2BqJ7s6+LnT4pFNLWVR2X/V8HOZxpWpwf3BbzJ24c9HMK6BdQf+1kwHkQoBUIA7GX84CcqharZ7AVOTy8srKYmeXcHukmV1doaLto20Gdy/xkId3Ag8NQehthy4M0KUeXd1YF119kUvnic2v+fn58+Z75y15htqN8L2kO6geb9fZncQviU00IczT3Zlq/Jev/LidBsxHQ//tBwb3X7aW3CmJuth+Iu74OpDDhz9ZeqGnbXGxJiDXM+3gG4DPCcJbeGcVdi9kJfsIWbhrhil3pjeF8k1MUmeHST/nAog9t7zkm4Kqi+ctgE3palQUtNj5RfrJf5B63ZrX1aP23nYh7EyxpRidTEaJsKJomTOgXCdaNMHiC7nSwLvOINlZqCRsMdu8+X6E0R/7Dsm9Gdxnj8b7EuGj2IC7ual6GHrkycNLr9brc0Lge6W2uNja0jUyogHvIOGBioP7ZX75aUdhn+LC4EiFvwN8xxc0FGi/AMBfcGGgLlWN5p4i9UaiSwWjz17TaldF9WMqqVqFutZ1OFKFCrV6FijpOOVEuFK4hhXQHxJqmGWg0InIgaPN4y5IP/MIdlg0o/TKK0/+9OX7B79cWnq1p7MlA8SlbuzqymRamlVXNPFh8+7kHQdoyL5LcdaT8aM7InRBpC40ReiGSxXppghZtDPnoLg5V7DrPkqw5YsaSrmq7nJ3Q6zxqAU6i9JoMomKQ2Hv16FBP8zjuaPpS95H8okmdFXXreurq+DbR/2hT5uK7qkjTdMO0CXtRwD8A6e+//77U+u/Hj78DD4MVeD+m5PxE56Raop3n2LhDm1kd2aZRsAPRcLOj++IgB01hHN+l73ZbHcn5gw43livO+epTWGOxjJ3tTe0oxMMOzsoozgE7GgE2eihRWVRzAfxzgKhHUVVDwvssWvS3U2Ol3mmnouk/fL6JK5Vkrtbdq1L6g9Jic8R+Pn8r776StD+dMhd1e77jh5pXkcPAvWTJ+u1xcnj0Dfv/bh0/7OP7T93/xOvvdaiZmZs3LFDN8rdfSM+4FuIe0PeNeKsaOL7u4TdlGhzx9YA9htc5u6mXRu73lO+KIPqcXe6OnaKd7UbtdzdhzoNv52+DtJZkiEGz/Dvo54mb5CHywuv50AY8uww148U5qYvCWH93lx2ZERGn2RvL67Wkz1d56yvXy+wX+08vvulN3++OPyearnWXhOqi1I/qUqY6r1trTfeeGMG32+fGcklzl9aevYxLP0F/U5LqwQ+CPuY9m4rEncyzp48iIW7ZJywRyiAdQ6RddVY3o7Nh7qVZSASLzDXZVTRTk9nR8OOJlSGeGwW6r2sHtDZYWznXkcauYPPq1gTKro7r12dQk99rpHq7SOFzjZKUC/npXpaWtuTnc7x45N3nXZFQ9pTlXphPGN0222ZEVkyIzfehpK5TRfINOKxDFBXyuz+8OulpWe+eOyx329rpTZwZ9dSRokDW8adU5CmQn7Yz47OMoQddZPJ3Xx9PVFHS8jVHjsP64QdIufu4K4KKrag3B7Burk2bRBZTJaxxOGgJE/uZZo3zG/EmnAReN3sdkLU0xYo/FJtPVCnk2uE+sx0NlkouL7X2LTYURJf3ZEHZkz2M8cF7r//3nobcA9VC2UbP7Hforuj0dAH0n52c6CrGqkIa79BuzuJp0A2WivIkHc7yBD2WoOLVFUCNerO7Sqy09uJsW3vBF0fNMg0jDUqxas4rwZQooH3dVBcIuRRGpmb8StXnj5RWq45hYLT2bPbJ4W/h/ndKJY09JOv/fbrTbfffntrk7KCTmb7cJeSe6LPhw3tQ5HEs0QoxNtJOpO7mZVR7m6jTtYhRhlNOnm3MA+L7WaAUzI1yewo/R0ycUYZvCUX80HAk3jl8XIniR+VnWjiybk5IPbx5Ditjk8jBchp5bfYB0jYPB0/iHbZtiAvAfy4iqY7k4mHu8GVGd6ivakQEzu3nx3MO2SCu6Zcil3L11EM7laWIetu4kc3NQWpTd3K7XfTxq2qRnmkh5IW9rpqm5ehRnbUcCTx3DPPqx11Jw5Q/erRO5tUQNxjKxB6bF7cxZjqEPytKjjaY3MH/PHmcHelGdvcUYeaIx4KJ56Ys+MiXXu64Z0SgV03jVYacE6GoJP0mt/b2Yu4NmV8J/GyoXjEDvvcobFAZ+F0jdiMzaOE2rzt7pyi5OqaxkvmA0ej5ePdxBlFvqgacsvyN497lNtH4+6B3Z5zj2ntqomecCfldpahudu5PdDdqcDc7jV23en1sm4Rz5F22dTUThfl7Wg09Gxp5fRzPoNdjzhRwyRv3F1iH8W8ld/1EfEn72Q/Wk3zbi5dFe6oHleXm51xNunuhJ59KvNHe+eyc0MQReEICQmRiJEYSIwMmTE0NJD/CQwFiYQn8E6GZh7HY1hVe2+fbW9d3e1nZNX1NI5LvrOyqrr6KLj3MAM6AugtZdY1dJgvY3uQjrlrIMxoaIx9VFDH2yEdd0/WrkqSWbm76myxRkVCHpL77J4/BhV4Anym3maTdEx+3/K1nq6JDtCZAvcp8pPHuwx8j/YF9j/2+lPuXmm3UmBfob4vyeQTZpygId047VYI6z4BeGCXgL14e79K/ZjPyeDuLeg0A95IJbcDexPeQZtx5fEq8D9tPrK8335dEo/B51RPoq/I/7nZd4HeWvTxMdhP/anYA+7LjALsFmygfW3tATt4P/29BLxaCM9nq322DPvvbqXC++Pp8LCOtat22oId4FWcdNjF1jt8AZt1KimHvs00cE+CURs9h2zWytnm65zA/AHA86UDeX7IJ9bNctNLIxhndg73Fev1WzjWMsy9w8Th/OXLXzFXnYpB5SHcO/Q1tauoJtC95j1IBOu/Oyezvn3K3aWPefOxUJ4ye7+U5fXqWgZ/NtuTD5sf406b9x71T31v/A8i4H7S6BFG7xqvRtf7/al8T3YH9EL62QOQXpz0gNzU2roRrsEmWRfPHnEsPkinwDuou2A95XaAh3U6UnuHOpuPwfHkrg8yPbWAT76PjkC/4J1NefWzsU+p8kLzpTB1gK/EQ33UNfn3Fup5d9NX0SxKZj06TP6Qu8PoAveDrIelTysP0FU61FUh/KkRfx/Yh7v/ZPEXBJruTiq8D9IBHti7m6kPvIG6hgp7jGI9utd31JFRQLhle6e7824ZdUinzg7Y3e/nz7R6AHwmGhz9taB9gfx6Oct2DryTcJqEfwm416UrIK/EPswTDF2Yj0KKqch7Ke5+EcMk3fRI5SKAz0EmxxhrqqtDYQ9UuY26I8VAYnPrNHt2D3L5bHjNtr/b5eOFRo/yhJo9K1imXPUqmbWf1gbvvzKf8c9nEbyudAD36umqB2SojzcZpIP6kNGuLmMeldCeYJ/dhWh33KHegS+xPdTBDu1pSwbkgb1JMTGB++ziWDnXE8vR7bR33rRTQI7p5ygfL9YO3xw0IN0zv7XI9Avtd3pUrZ5jOFvawH1h6kcf0Rtv8xIJb0ce0F9W2lNqf5iBV+MxVmMd7ifuCNYhvcBebqSqkNqta5Hn9qkndnAuhC/DO0NO8vlzQbfBO8HG0LYenx8/uB/6fJiYudPu5J/UYebj7hTUY/KaEnS2nB/cIT2zflSW1UHdKB8Vd6+wk2XuT9Y1PAR1YJ8qtEvZ4bO1pyc6+jUqgvJOeStG9Q6c9oiTRmpdHi8o70mQr8gX7tV4HGrOptmD/Fqdu1vHxcvPN2uvH8XHbh27oU9f+ttM+aG7/bCDOnQzh3Mkvgky6jVvQruaox0jtAt3Vzo5kDmvJyBV60HfrSRjHfRx1xQSbbKw9Zru+ZRUp6/4qzSCdGbm8Zw00MhDgLuFuwM8rAf3/8rqOWqp6uhLnDqzla1KTTzvprufTunoIaxn3tmMIcykFDME6F1ot87QRjj7UIy4e8kxgTxrVGAP4pf3k7LD1gBTIGRcsc9Y3Z10A/KLOG+FT4Lb/Oz1VBRx/oiAveg88Gxj7saeo5VcYkrSieRjg+MOtedIN9Z/4ZwUA+sSrMeY7izdL8BHkgFxmzjtiD0a7iypquHupHZWqGR2qQB/m6oueSxjNES82Cgog57x9q5NPe3nK9s80Av19ExUfJXNEZUvO2i+mBidZP9sygH8xD03bS27P/TIovEE6lKxdXbZHfuS2K3D1a0fE0K79WMSOSbHmPD0uiGJtbenH8tmu4NeYVchtBfmuAZpOVZQuuqlUl/MnWqUL1JT//v4vo0fspFk8mqsbY9BD/tk/C3Ht+xz2exDfxXcjxLZvUf5yT7U8XX0lIHFaYox1gz0iXyri8jslfbYdQ/mWa1m5DnbTkEA38LurM9OnghcxdDBqWOceaqMRVvRHUF6B3z9raR4JkrIj2rJJoK+dNzsEXeoKB3hcbmifQm8w/cA3F/59F2LuzL8HtC7tSnEY+lWNMuwq4tpi7qVcQh+bLkXa8fVK+1EmlBl/SPbj1vnHr3AF5M+MPcW3qcahlnAmFm7L+nVxNUoKP+ZYqamXgPPvk7mx+Rwqq+w97neN+23rfwU9WC/0F1wP7Yoja9JitCCnsB7svQCu4iOFy3qHJQhtCfaN2F/Lo0unRrofH1jl53YDoMZKO7Sa8K1huw721GDKi336+vPqfEe1VjlvUPPc4ADeUs3qiongGfA4bnMle38cjbboEvAPTw9ZpV1SE/bMQjYre9kqJu1z3upmqQUA+ykdpWGdunnNWojXL3uxUSMSfvelSM3Q1xUevDVOiaQzbHd1uRhERvPIy+k/rlXrm6Tnzfo9cq6kepl86qnrb49ZM/rPdgfhX7N/27c47QXJ7+ebrDeoQ7wwXrdfGSBOuOLmvQsO3usUC82rV2dCYPvdtpTZu+WqKQFEMxbHrjy1wejqfJSd6LmDz7QxY8D+jHeGQNQY/IxR/vcnTyz2NNMN6HK+sHBVrTnb+bfQXw+3ViJK7yOLulvow/uq/jipo6xb/k6xFfYIR7Wq8zTMXe8vQvto2TagV11CM7Zffw97KR22DLzDD7h58HEWIyI7I8EHD4UEY+DxK82+2q/9E6TsVOOLxWQ85Sh5hyEq3e7pQH2x4j1FuqH04/ZKbMH9XqRHzvF+DH2cffGyxGmDuxNaPdlaWW93lmKHZkO+Im3wY4eeXwHdljvnthDLFVdLE/bKDPArg4anEcSIRZoPMaAY+ZvGU5vbwWKzLJqjMkLiwQ+7G8Iu08n6OMPhIbPe7C3n/JC9SjzufSfAvZvLkGb7h7xXDPauIJEdSdAV4fqVowlGFXvSOzcQX3mIUZ9ijEhkC9fgtqxDu8gr7J1wrcaJQiSPXqcqdZQetDOsrKjJKPnQ8RAjO/cnTmok+Gbc8i8CcrRpi6jXfqjMuUzefxGVXX3LvBImp/fs0c/4/7ZcMfQw8j7L6d+hLNnPVFhfVokskNGuQ2wztEY4/tZXqKSYlS2Ukw5IebEvxld2o7pZKQnTnKCiVbR5gIC+IC3ysCXw3vcb29TdYJhlC+AOBfWJp+LKn/6OWMuecC3yl9WYjx+zp4LTIsW+HdRx90dzFWC82cZ9M31Kbmd9emTEth5Mq84u7XYi1EZeIdiCuiZdjsaRmbv/9OCN27sfYyZWGDrAJJii5RIPyjcnddlF9OpojqFEKxSsOZSb+EEm1SXytnKBi5my49d+/MRv3+kKp/B35t0wB2Zu8Mz2gs7wR3W1T0x4IkyGXUVSI8EYyFGqLvFz469GGDXDGf3YzLsPbJADWN/o46tSGJMszgFD1DHyn5y9D8V72Hv7uHGulToUMW65vrKdeWbBfla6eOH9fvUvrnSf8zs3oL+Weq3F7qeblR2C9zPw46xw3qAjjjgW074Rq8vDnNHD+rz4RjLMkCfH8h22PF2DzKRYtQ44b7xRF7hhrS+RvyFd7TuYm/zfBdexHgIAy5UMPfKvPy4Snk80LTT7clYjDgC09HPYeZ6SztlObOCvYfcOc+ZH7vfh/tp2J+o+vo0UEeYepfXIT6KZJP3ZHYPMaqALjnor/pnmEjtjvrbci6s4R1YGH/2Vmy94fy8OJ9llFh+Z2d+K8ZDLZcWP45Y1a5/xVr1kar8g5Hv70ydO3Bfn7Pi6SrKZeD+tLd0fN1q0v0fqR3gO9YfqbirO9/h6xh7v9GOiDH1e0/fNA90VNxLYCdC4Et/Tazu0p+kEATyheySzlH7DZWp83pZymms3+aPER2AH9QRxE/+O/lS9epSL2f9dvVydMM603VVvbJenZrmUa7fuG6jt+O6MpqqlSENqn+ma6oHitX/OqFr/Gur2rBdVGMmqQ/J3T98B9De9ondhbziAAAAAElFTkSuQmCC'; export const img3 = 'data:image/jpeg;base64,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'; ================================================ FILE: src/pages/componentsB/swiper/index.vue ================================================ ================================================ FILE: src/pages/componentsB/switch/index.vue ================================================ ================================================ FILE: src/pages/componentsB/tabbar/index.vue ================================================ ================================================ FILE: src/pages/componentsB/table/index.vue ================================================ ================================================ FILE: src/pages/componentsB/transition/index.vue ================================================ ================================================ FILE: src/pages/componentsB/upload/index.vue ================================================ ================================================ FILE: src/pages/componentsB/waterfall/index.vue ================================================ ================================================ FILE: src/pages/componentsC/actionSheet/index.vue ================================================ ================================================ FILE: src/pages/componentsC/alertTips/index.vue ================================================ ================================================ FILE: src/pages/componentsC/badge/index.vue ================================================ ================================================ FILE: src/pages/componentsC/button/index.vue ================================================ ================================================ FILE: src/pages/componentsC/cell/index.vue ================================================ ================================================ FILE: src/pages/componentsC/circleProgress/index.vue ================================================ ================================================ FILE: src/pages/componentsC/collapse/index.vue ================================================ ================================================ FILE: src/pages/componentsC/color/index.vue ================================================ ================================================ FILE: src/pages/componentsC/countDown/index.vue ================================================ ================================================ FILE: src/pages/componentsC/countTo/index.vue ================================================ ================================================ FILE: src/pages/componentsC/fab/index.vue ================================================ ================================================ FILE: src/pages/componentsC/gap/index.vue ================================================ ================================================ FILE: src/pages/componentsC/grid/index.vue ================================================ ================================================ FILE: src/pages/componentsC/layout/index.vue ================================================ ================================================ FILE: src/pages/componentsC/link/index.vue ================================================ ================================================ FILE: src/pages/componentsC/loadmore/index.vue ================================================ ================================================ FILE: src/pages/componentsC/mask/index.vue ================================================ ================================================ FILE: src/pages/componentsC/messageInput/index.vue ================================================ ================================================ FILE: src/pages/componentsC/numberBox/index.vue ================================================ ================================================ FILE: src/pages/componentsC/pagination/index.vue ================================================ ================================================ FILE: src/pages/componentsC/popup/index.vue ================================================ ================================================ FILE: src/pages/componentsC/progress/index.vue ================================================ ================================================ FILE: src/pages/componentsC/section/index.vue ================================================ ================================================ FILE: src/pages/componentsC/subsection/index.vue ================================================ ================================================ FILE: src/pages/componentsC/text/index.vue ================================================ ================================================ FILE: src/pages/example/about/about-me.vue ================================================ ================================================ FILE: src/pages/example/about/contributors.vue ================================================ ================================================ FILE: src/pages/example/about/faq.vue ================================================ ================================================ FILE: src/pages/example/about/guide.vue ================================================ ================================================ FILE: src/pages/example/about/license.vue ================================================ ================================================ FILE: src/pages/example/about/settings.vue ================================================ ================================================ FILE: src/pages/example/about/version.vue ================================================ ================================================ FILE: src/pages/example/about.vue ================================================ ================================================ FILE: src/pages/example/components.config.ts ================================================ export default [ { groupName: '基础组件', groupName_en: 'Basic components', icon: 'basics', list: [ { path: '/pages/componentsC/color/index', icon: 'color', title: 'Color 色彩', title_en: 'Color', desc: '提供主题与配色示例,便于统一项目色彩方案。', desc_en: 'Provides theme and color examples to help unify project colors.' }, { path: '/pages/componentsA/icon/index', icon: 'icon', title: 'Icon 图标', title_en: 'Icon', desc: '常用图标集合,支持自定义尺寸与颜色,便于界面装饰与操作提示。', desc_en: 'Common icon set supporting custom size and color for UI decoration and cues.' }, { path: '/pages/componentsB/image/index', icon: 'image', title: 'Image 图片', title_en: 'Image', desc: '图片展示组件,支持懒加载、占位图与自适应显示。', desc_en: 'Image display with lazy-load, placeholders and responsive modes.' }, { path: '/pages/componentsC/button/index', icon: 'button', title: 'Button 按钮', title_en: 'Button', desc: '基础按钮,支持多种样式、尺寸、禁用与加载态。', desc_en: 'Basic button supporting multiple styles, sizes, disabled and loading states.' }, { path: '/pages/componentsC/layout/index', icon: 'layout', title: 'Layout 布局', title_en: 'Layout', desc: '布局容器与工具类,帮助快速搭建响应式栅格与间距。', desc_en: 'Layout containers and utilities to build responsive grids and spacing.' }, { path: '/pages/componentsC/cell/index', icon: 'cell', title: 'Cell 单元格', title_en: 'Cell', desc: '列表与表单中的单元格项,常用于信息展示与跳转入口。', desc_en: 'Cell items for lists and forms, commonly used for info display and navigation.' }, { path: '/pages/componentsC/badge/index', icon: 'badge', title: 'Badge 徽标数', title_en: 'Badge', desc: '徽标与角标显示,用于提示数量或状态标识。', desc_en: 'Badge and corner mark display used to indicate counts or statuses.' }, { path: '/pages/componentsA/tag/index', icon: 'tag', title: 'Tag 标签', title_en: 'Tag', desc: '标签组件,用于表示分类、状态或筛选条件。', desc_en: 'Tag component for categories, statuses or filter labels.' }, { path: '/pages/componentsC/text/index', icon: 'text', title: 'Text 文本', title_en: 'Text', desc: '文本展示与格式化组件,支持省略、换行与样式控制。', desc_en: 'Text display and formatting with ellipsis, wrapping and style controls.' }, { path: '/pages/componentsC/fab/index', icon: 'fab', title: 'Fab 悬浮按钮', title_en: 'Fab', desc: '悬浮操作按钮,便于快速触发主要操作或快捷入口。', desc_en: 'Floating action button for quick access to primary operations.' } ] }, { groupName: '表单组件', groupName_en: 'Form components', icon: 'forms', list: [ { path: '/pages/componentsA/form/index', icon: 'form', title: 'Form 表单', title_en: 'Form', desc: '表单容器,支持字段校验、布局与统一提交处理。', desc_en: 'Form container supporting validation, layout and unified submit handling.' }, { path: '/pages/componentsA/input/index', icon: 'input', title: 'Input 输入框', title_en: 'Input', desc: '单行输入框,支持类型、限制与常用交互事件。', desc_en: 'Single-line input with type, constraints and common interaction events.' }, { path: '/pages/componentsA/textarea/index', icon: 'textarea', title: 'Textarea 输入框', title_en: 'Textarea', desc: '多行文本输入,支持自适应高度与字数统计限制。', desc_en: 'Multi-line textarea supporting auto-height and character count limits.' }, { path: '/pages/componentsA/calendar/index', icon: 'calendar', title: 'Calendar 日历', title_en: 'Calendar', desc: '日历选择器,支持单选、范围选择与多种显示模式。', desc_en: 'Calendar picker supporting single, range selection and multiple display modes.' }, { path: '/pages/componentsA/select/index', icon: 'select', title: 'Select 列选择器', title_en: 'Select', desc: '列选择器,适用于多列联动与层级选择场景。', desc_en: 'Column picker suitable for multi-column linkage and hierarchical selection.' }, { path: '/pages/componentsA/keyboard/index', icon: 'keyboard', title: 'Keyboard 键盘', title_en: 'Keyboard', desc: '自定义键盘组件,适用于特殊格式输入或密码场景。', desc_en: 'Custom keyboard for special format inputs or password entry scenarios.' }, { path: '/pages/componentsB/picker/index', icon: 'picker', title: 'Picker 选择器', title_en: 'Picker', desc: '滚轮选择器,支持多列配置与联动数据。', desc_en: 'Wheel picker supporting multi-column configuration and linked data.' }, { path: '/pages/componentsB/rate/index', icon: 'rate', title: 'Rate 评分', title_en: 'Rate', desc: '评分组件,支持半星、可交互或只读样式。', desc_en: 'Rating component supporting half-stars, interactive and read-only modes.' }, { path: '/pages/componentsB/search/index', icon: 'search', title: 'Search 搜索', title_en: 'Search', desc: '搜索输入与建议组件,支持联想与清除历史。', desc_en: 'Search input with suggestions, supporting autocomplete and history clearing.' }, { path: '/pages/componentsC/numberBox/index', icon: 'numberBox', title: 'NumberBox 步进器', title_en: 'NumberBox', desc: '步进器组件,用于数量选择与数值调整。', desc_en: 'Stepper component for quantity selection and numeric adjustments.' }, { path: '/pages/componentsB/upload/index', icon: 'upload', title: 'Upload 上传', title_en: 'Upload', desc: '文件/图片上传,支持预览、限制大小与并发上传。', desc_en: 'File/image upload with preview, size limits and concurrent uploads support.' }, { path: '/pages/componentsA/verificationCode/index', icon: 'verificationCode', title: 'VerificationCode 验证码倒计时', title_en: 'VerificationCode', desc: '验证码倒计时控件,常用于获取验证码的防重发处理。', desc_en: 'Verification code countdown control to prevent repeated requests.' }, { path: '/pages/componentsA/field/index', icon: 'field', title: 'Field 输入框', title_en: 'Field', desc: '表单字段封装,包含标签、输入与校验提示。', desc_en: 'Form field wrapper including label, input and validation hints.' }, { path: '/pages/componentsB/checkbox/index', icon: 'checkbox', title: 'Checkbox 复选框', title_en: 'Checkbox', desc: '复选框组件,支持多选、全选与禁用状态。', desc_en: 'Checkbox supporting multiple selection, select-all and disabled states.' }, { path: '/pages/componentsB/radio/index', icon: 'radio', title: 'Radio 单选框', title_en: 'Radio', desc: '单选组件,适用于互斥选项的选择场景。', desc_en: 'Radio component for mutually exclusive option selection.' }, { path: '/pages/componentsB/switch/index', icon: 'switch', title: 'Switch 开关选择器', title_en: 'Switch', desc: '开关组件,用于二元状态切换与即时交互。', desc_en: 'Switch component for binary state toggling and instant interactions.' }, { path: '/pages/componentsA/slider/index', icon: 'slider', title: 'Slider 滑动选择器', title_en: 'Slider', desc: '滑动条,用于数值范围选择与微调交互。', desc_en: 'Slider for selecting numeric ranges and fine adjustments.' } ] }, { groupName: '数据组件', groupName_en: 'Data components', icon: 'datas', list: [ { path: '/pages/componentsC/progress/index', icon: 'progress', title: 'Progress 进度条', title_en: 'Progress', desc: '进度条组件,支持动画、分段与环形/直线样式。', desc_en: 'Progress bar with animation, segmented and circular/linear styles.' }, { path: '/pages/componentsB/table/index', icon: 'table', title: 'Table 表格', title_en: 'Table', desc: '表格组件,适用于展示大量结构化数据的场景。', desc_en: 'Table component for displaying structured data.' }, { path: '/pages/componentsC/countDown/index', icon: 'countDown', title: 'CountDown 倒计时', title_en: 'CountDown', desc: '倒计时显示组件,适用于活动倒计时或延时提示。', desc_en: 'Countdown display component for events or delay prompts.' }, { path: '/pages/componentsC/countTo/index', icon: 'countTo', title: 'CountTo 数字滚动', title_en: 'CountTo', desc: '数字动画组件,用于展示增长数据的滚动效果。', desc_en: 'Number animation component for showcasing incremental data with rolling effect.' } ] }, { groupName: '反馈组件', groupName_en: 'Feedback components', icon: 'feedbacks', list: [ { path: '/pages/componentsC/actionSheet/index', icon: 'actionSheet', title: 'ActionSheet 操作菜单', title_en: 'ActionSheet', desc: '底部弹出操作菜单,用于提供多个快速操作选项。', desc_en: 'Bottom action sheet offering multiple quick operation choices.' }, { path: '/pages/componentsC/alertTips/index', icon: 'alertTips', title: 'AlertTips 警告提示', title_en: 'AlertTips', desc: '用于展示警告或重要提示的非模态/模态消息。', desc_en: 'Alert tips for showing warnings or important messages in modal/non-modal form.' }, { path: '/pages/componentsA/toast/index', icon: 'toast', title: 'Toast 消息提示', title_en: 'Toast', desc: '轻量级短时提示,用于反馈用户操作结果。', desc_en: 'Lightweight transient toast for feedback on user actions.' }, { path: '/pages/componentsB/noticeBar/index', icon: 'noticeBar', title: 'NoticeBar 滚动通知', title_en: 'NoticeBar', desc: '滚动通知栏,用于展示重要消息或公告。', desc_en: 'Scrolling notice bar for important messages or announcements.' }, { path: '/pages/componentsA/topTips/index', icon: 'topTips', title: 'TopTips 顶部提示', title_en: 'TopTips', desc: '顶部提示条,适用于短时警示或成功提示。', desc_en: 'Top tip bar suitable for brief warnings or success messages.' }, { path: '/pages/componentsB/swipeAction/index', icon: 'swipeAction', title: 'SwipeAction 滑动单元格', title_en: 'SwipeAction', desc: '滑动操作行,支持左右滑出操作按钮(删除/更多)。', desc_en: 'Swipe action rows supporting left/right action buttons like delete or more.' }, { path: '/pages/componentsC/collapse/index', icon: 'collapse', title: 'Collapse 折叠面板', title_en: 'Collapse', desc: '折叠/展开面板,用于节省空间展示可折叠内容。', desc_en: 'Collapsible panels for saving space when showing expandable content.' }, { path: '/pages/componentsC/popup/index', icon: 'popup', title: 'Popup 弹出层', title_en: 'Popup', desc: '浮层弹窗组件,支持自定义位置与动画。', desc_en: 'Popup layer supporting custom positions and animations.' }, { path: '/pages/componentsA/modal/index', icon: 'modal', title: 'Modal 模态框', title_en: 'Modal', desc: '模态对话框,用于确认或重要信息的交互。', desc_en: 'Modal dialog for confirmations or important interactive messages.' }, { path: '/pages/componentsA/fullScreen/index', icon: 'pressingScreen', title: 'fullScreen 压窗屏', title_en: 'fullScreen', desc: '全屏展示组件,适用于沉浸式内容或应用更新提示。', desc_en: 'Full-screen display for immersive content or media playback.' } ] }, { groupName: '布局组件', groupName_en: 'Layout components', icon: 'layouts', list: [ { path: '/pages/componentsB/line/index', icon: 'line', title: 'Line 线条', title_en: 'Line', desc: '线条分隔组件,用于视觉上分割内容区域。', desc_en: 'Line divider used to visually separate content areas.' }, { path: '/pages/componentsB/card/index', icon: 'card', title: 'Card 卡片', title_en: 'Card', desc: '卡片容器,用于信息块的分组展示与布局美化。', desc_en: 'Card container for grouping information blocks and enhancing layout.' }, { path: '/pages/componentsC/mask/index', icon: 'mask', title: 'Mask 遮罩层', title_en: 'Mask', desc: '遮罩层组件,常与弹窗或交互遮挡背景配合使用。', desc_en: 'Mask overlay commonly used with popups to obscure the background.' }, // #ifndef MP-TOUTIAO { path: '/pages/componentsA/noNetwork/index', icon: 'noNetwork', title: 'NoNetwork 无网络提示', title_en: 'NoNetwork', desc: '网络断开时的提示组件,提供重试或离线指引。', desc_en: 'No-network hint component providing retry or offline guidance.' }, // #endif { path: '/pages/componentsC/grid/index', icon: 'grid', title: 'Grid 宫格布局', title_en: 'Grid', desc: '宫格布局,适合图文导航与九宫格样式展示。', desc_en: 'Grid layout suitable for image/text navigation and nine-grid displays.' }, { path: '/pages/componentsB/swiper/index', icon: 'swiper', title: 'Swiper 轮播图', title_en: 'Swiper', desc: '轮播图组件,支持自动轮播、指示器与手势滑动。', desc_en: 'Carousel supporting auto-play, indicators and touch swipe.' }, { path: '/pages/componentsA/timeLine/index', icon: 'timeLine', title: 'TimeLine 时间轴', title_en: 'TimeLine', desc: '时间轴组件,用于展示事件序列与时间节点。', desc_en: 'Timeline component for displaying sequences of events and time nodes.' }, { path: '/pages/componentsB/skeleton/index', icon: 'skeleton', title: 'Skeleton 骨架屏', title_en: 'Skeleton', desc: '骨架屏占位展示,改善加载时的视觉体验。', desc_en: 'Skeleton placeholder to improve visual experience during loading.' }, { path: '/pages/componentsB/sticky/index', icon: 'sticky', title: 'Sticky 吸顶', title_en: 'Sticky', desc: '吸顶组件,实现元素在滚动时固定在顶部。', desc_en: 'Sticky component to keep elements fixed at the top during scroll.' }, // #ifndef MP-TOUTIAO { path: '/pages/componentsB/waterfall/index', icon: 'waterfall', title: 'Waterfall 瀑布流', title_en: 'Waterfall', desc: '瀑布流布局,适合不规则图片列表与瀑布展示。', desc_en: 'Waterfall layout for irregular image lists and masonry-style displays.' }, // #endif { path: '/pages/componentsB/divider/index', icon: 'divider', title: 'Divider 分割线', title_en: 'Divider', desc: '分割线组件,提供可定制的横向分隔样式。', desc_en: 'Divider component providing customizable horizontal separation styles.' } ] }, { groupName: '导航组件', groupName_en: 'Navigation components', icon: 'navs', list: [ { path: '/pages/componentsB/dropdown/index', icon: 'dropdown', title: 'Dropdown 下拉菜单', title_en: 'Dropdown', desc: '下拉菜单,提供层级或操作选择的浮动列表。', desc_en: 'Dropdown menu offering hierarchical or action choice floating lists.' }, { path: '/pages/componentsB/tabbar/index', icon: 'tabbar', title: 'Tabbar 底部导航栏', title_en: 'Tabbar', desc: '应用底部导航,支持图标、文字及选中态。', desc_en: 'Bottom navigation bar supporting icons, text and selected states.' }, { path: '/pages/componentsA/backTop/index', icon: 'backTop', title: 'BackTop 返回顶部', title_en: 'BackTop', desc: '返回顶部快捷按钮,便于长页面快速回到顶部。', desc_en: 'Quick back-to-top button useful for long pages.' }, { path: '/pages/componentsA/navbar/index', icon: 'navbar', title: 'Navbar 导航栏', title_en: 'Navbar', desc: '顶部导航栏,包含返回、标题与操作项。', desc_en: 'Top navigation bar including back, title and action items.' }, { path: '/pages/componentsA/tabs/index', icon: 'tabs', title: 'Tabs 标签', title_en: 'Tabs', desc: '选项卡组件,用于切换不同内容视图。', desc_en: 'Tabs component for switching between different content views.' }, // #ifndef MP-ALIPAY { path: '/pages/template/order/index', icon: 'tabsSwiper', title: 'TabsSwiper 全屏选项卡', title_en: 'TabsSwiper', desc: '全屏选项卡,支持手势滑动与整页切换。', desc_en: 'Full-screen tabs supporting gesture swipe and full-page switching.' }, // #endif { path: '/pages/componentsC/subsection/index', icon: 'subsection', title: 'Subsection 分段器', title_en: 'Subsection', desc: '分段器,用于在一行内选择多个项或风格切换。', desc_en: 'Subsection control for selecting multiple items or style switches in one line.' }, { path: '/pages/componentsA/indexList/index', icon: 'indexList', title: 'IndexList 索引列表', title_en: 'IndexList', desc: '带字母索引的长列表,便于快速跳转至分组项。', desc_en: 'Indexed list with letters for quick navigation to grouped items.' }, { path: '/pages/componentsB/steps/index', icon: 'steps', title: 'Steps 步骤条', title_en: 'Steps', desc: '步骤条,用于展现多步骤流程与当前进度。', desc_en: 'Steps bar to show multi-step processes and current progress.' }, { path: '/pages/componentsA/empty/index', icon: 'empty', title: 'Empty 内容为空', title_en: 'Empty', desc: '空状态占位组件,用于无数据时的友好提示。', desc_en: 'Empty state placeholder for friendly messaging when no data exists.' }, { path: '/pages/componentsC/section/index', icon: 'section', title: 'Section 查看更多', title_en: 'Section', desc: '分段展开组件,支持查看更多与折叠收起长内容。', desc_en: 'Section component supporting expand/collapse for long content.' }, { path: '/pages/componentsC/pagination/index', icon: 'pagination', title: 'Pagination 分页', title_en: 'Pagination', desc: '分页组件,控制页数跳转与当前页展示。', desc_en: 'Pagination component to control page jumps and show current page.' } ] }, { groupName: '其他组件', groupName_en: 'Other components', icon: 'others', list: [ { path: '/pages/componentsC/messageInput/index', icon: 'messageInput', title: 'MessageInput 验证码输入', title_en: 'MessageInput', desc: '分段输入组件,常用于验证码/短信输入体验,支持粘贴与校验。', desc_en: 'Segmented input for codes, supporting paste and validation.' }, // { // path: '/pages/componentsC/citySelect/index', // icon: 'citySelect', // title: 'CitySelect 城市选择', // title_en: 'CitySelect', // desc: '城市选择组件,支持多级联动选择。', // desc_en: 'City selection component supporting multi-level linkage selection.' // }, // { // path: '/pages/componentsA/avatarCropper/index', // icon: 'avatarCropper', // title: 'AvatarCropper 头像裁剪', // title_en: 'AvatarCropper' // }, { path: '/pages/componentsC/loadmore/index', icon: 'loadmore', title: 'Loadmore 加载更多', title_en: 'Loadmore', desc: '加载更多占位与触发器,通常用于下拉或滚动分页加载。', desc_en: 'Load-more placeholder and trigger commonly used for pull/scroll pagination.' }, { path: '/pages/componentsB/readMore/index', icon: 'readMore', title: 'ReadMore 展开阅读更多', title_en: 'ReadMore', desc: '长文本收起与展开组件,提高长内容的可读性。', desc_en: 'Read-more control to collapse/expand long text for better readability.' }, { path: '/pages/componentsA/lazyLoad/index', icon: 'lazyLoad', title: 'LazyLoad 懒加载', title_en: 'LazyLoad', desc: '按需加载图片或资源,减少首次渲染流量与性能开销。', desc_en: 'Lazy load images/resources to reduce initial load and improve performance.' }, { path: '/pages/componentsC/gap/index', icon: 'gap', title: 'Gap 间隔槽', title_en: 'Gap', desc: '间隔组件,提供统一的间距帮助布局排版。', desc_en: 'Gap component providing consistent spacing for layout and typography.' }, { path: '/pages/componentsA/avatar/index', icon: 'avatar', title: 'Avatar 头像', title_en: 'Avatar', desc: '用于展示用户头像、等级、性别等信息,支持多种形态和自定义内容。', desc_en: 'Displays user avatar, level, gender etc., with multiple shapes and custom content.' }, { path: '/pages/componentsC/link/index', icon: 'link', title: 'Link 超链接', title_en: 'Link', desc: '超链接组件,支持跳转、外链与样式定制。', desc_en: 'Link component supporting navigation, external links and style customization.' }, { path: '/pages/componentsB/loading/index', icon: 'loading', title: 'Loading 加载动画', title_en: 'Loading', desc: '加载动画组件,常用于等待态提示与占位效果。', desc_en: 'Loading animation component for wait states and placeholders.' }, { path: '/pages/componentsB/loadingPopup/index', icon: 'loadingPopup', title: 'Loading 加载弹窗', title_en: 'Loading Popup', desc: '阻塞式加载弹窗,用于覆盖页面并提示加载中状态。', desc_en: 'Blocking loading popup to overlay the page and indicate loading status.' }, { path: '/pages/componentsB/transition/index', icon: 'loadingPopup', title: 'Transition 动画', title_en: 'Loading Popup', desc: '阻塞式加载弹窗,用于覆盖页面并提示加载中状态。', desc_en: 'Blocking loading popup to overlay the page and indicate loading status.' } ] } ]; ================================================ FILE: src/pages/example/components.vue ================================================ ================================================ FILE: src/pages/example/experienceMap.vue ================================================ ================================================ FILE: src/pages/example/fullScreen.vue ================================================ ================================================ FILE: src/pages/example/js.config.ts ================================================ export default [ { groupName: '网络', groupName_en: 'Network', icon: 'network', list: [ { path: 'http', icon: 'http', title: 'Http 请求', title_en: 'Http', desc: '统一封装的网络请求,支持拦截器和全局配置', desc_en: 'Unified network request wrapper supporting interceptors and global configuration' } ] }, { groupName: '工具库', groupName_en: 'Tool library', icon: 'tools', list: [ { path: 'debounce', icon: 'throttle', title: 'Throttle | Debounce 节流防抖', title_en: 'Throttle | Debounce', desc: '高频事件优化,防止重复触发', desc_en: 'Optimizes high-frequency events to prevent repeated triggers' }, { path: 'deepMerge', icon: 'merge', title: 'DeepMerge 对象深度合并', title_en: 'DeepMerge', desc: '对象深度合并,常用于配置和主题', desc_en: 'Deep merge objects, commonly used for configuration and themes' }, // #ifndef APP-HARMONY { path: 'deepClone', icon: 'clone', title: 'DeepClone 对象深度克隆', title_en: 'DeepClone', desc: '对象/数组深度克隆,避免引用混乱', desc_en: 'Deep clone objects/arrays to avoid reference issues' }, // #endif { path: 'timeFormat', icon: 'time', title: 'TimeFormat 时间格式化', title_en: 'TimeFormat', desc: '时间格式化,支持多种格式', desc_en: 'Time formatting, supports multiple formats' }, { path: 'timeFrom', icon: 'from', title: 'TimeFrom 多久之前', title_en: 'TimeFrom', desc: '多久之前,友好时间显示', desc_en: "Friendly 'time ago' display" }, { path: 'guid', icon: 'id', title: 'Guid 全局唯一id', title_en: 'Guid', desc: '全局唯一 id 生成', desc_en: 'Generate globally unique IDs' }, { path: 'route', icon: 'route', title: 'Route 路由跳转', title_en: 'Route', desc: '页面路由跳转,参数传递', desc_en: 'Page navigation and parameter passing' }, { path: 'randomArray', icon: 'array', title: 'RandomArray 数组乱序', title_en: 'RandomArray', desc: '数组乱序,抽奖/洗牌', desc_en: 'Shuffle arrays, useful for lotteries/shuffling' }, { path: 'colorSwitch', icon: 'switch', title: 'ColorSwitch 颜色转换', title_en: 'ColorSwitch', desc: '颜色值格式转换 HEX/RGB/HSL', desc_en: 'Color value format conversion between HEX/RGB/HSL' }, { path: 'color', icon: 'color', title: 'Color 颜色值', title_en: 'Color', desc: '主题色、辅助色获取', desc_en: 'Retrieve theme and auxiliary colors' }, { path: 'queryParams', icon: 'params', title: 'QueryParams 对象转URL参数', title_en: 'QueryParams', desc: '对象转 URL 参数字符串', desc_en: 'Convert objects to URL query strings' }, { path: 'test', icon: 'test', title: 'Test 规则校验', title_en: 'Test', desc: '表单/数据规则校验', desc_en: 'Form/data validation rules' }, { path: 'md5', icon: 'md5', title: 'Md5 md5加密', title_en: 'Md5', desc: 'md5 加密/签名', desc_en: 'MD5 hashing/signing' }, { path: 'random', icon: 'random', title: 'Random 随机数值', title_en: 'Random', desc: '生成随机数', desc_en: 'Generate random numbers' }, { path: 'trim', icon: 'trim', title: 'Trim 去除空格', title_en: 'Trim', desc: '去除字符串空格', desc_en: 'Trim whitespace from strings' }, { path: 'getRect', icon: 'rect', title: 'GetRect 节点信息', title_en: 'GetRect', desc: '获取节点尺寸/位置信息', desc_en: 'Get node size and position information' }, // #ifndef APP-HARMONY { path: 'mpShare', icon: 'share', title: 'MpShare 小程序分享', title_en: 'MpShare', desc: '小程序分享能力', desc_en: 'Mini Program sharing capability' } // #endif ] } ]; ================================================ FILE: src/pages/example/js.vue ================================================ ================================================ FILE: src/pages/example/template.config.ts ================================================ export default [ { groupName: '部件', groupName_en: 'Parts', list: [ { path: 'coupon', icon: 'coupon', title: 'Coupon 优惠券', title_en: 'Coupon', desc: '卡券展示与领取,支持多种样式', desc_en: 'Display and claim coupons; supports multiple styles', isHot: true, downloadCount: 1250, rating: 4.8, shareLink: 'https://uviewpro.cn/zh/layout/coupon.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/coupon/index.vue' } ] }, { groupName: '页面', groupName_en: 'Page', list: [ { path: '/pages/template/wxCenter/index', icon: 'wxCenter', title: 'WxCenter 仿微信个人中心', title_en: 'WxCenter', desc: '用户信息、菜单、订单等个人中心页面', desc_en: 'User information, menus, orders and other personal center features', isHot: true, isNew: false, downloadCount: 3200, rating: 4.9, shareLink: 'https://uviewpro.cn/zh/layout/wxCenter.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/wxCenter/index.vue' }, { path: '/pages/template/keyboardPay/index', icon: 'keyboardPay', title: 'KeyboardPay 自定义键盘支付模板', title_en: 'KeyboardPay', desc: '安全支付,金额输入自定义键盘', desc_en: 'Secure payments with a custom keyboard for amount input', isNew: true, downloadCount: 890, rating: 4.6, shareLink: 'https://uviewpro.cn/zh/layout/keyboardPay.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/keyboardPay/index.vue' }, { path: '/pages/template/mallMenu/index1', icon: 'mallMenu', title: 'MallMenu 垂直分类(左右独立)', title_en: 'MallMenu 1', desc: '商品多级分类,左右独立滚动', desc_en: 'Multi-level product categories with independent left/right scrolling', downloadCount: 2100, rating: 4.7, shareLink: 'https://uviewpro.cn/zh/layout/menu.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/mallMenu/index1.vue' }, { path: '/pages/template/mallMenu/index2', icon: 'mallMenu', title: 'MallMenu 垂直分类(左右联动)', title_en: 'MallMenu 2', desc: '商品多级分类,左右联动高亮', desc_en: 'Multi-level product categories with linked left/right highlighting', isHot: true, downloadCount: 2800, rating: 4.8, shareLink: 'https://uviewpro.cn/zh/layout/menu.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/mallMenu/index2.vue' }, { path: 'submitBar', icon: 'submitBar', title: 'SubmitBar 提交订单栏', title_en: 'SubmitBar', desc: '下单结算栏,价格与操作按钮', desc_en: 'Order checkout bar showing price and action buttons', downloadCount: 1500, rating: 4.5, shareLink: 'https://uviewpro.cn/zh/layout/submitBar.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/submitBar/index.vue' }, { path: 'comment', icon: 'comment', title: 'Comment 评论列表', title_en: 'Comment', desc: '多级评论、点赞、回复展示', desc_en: 'Display of multi-level comments, likes, and replies', isHot: true, downloadCount: 1900, rating: 4.7, shareLink: 'https://uviewpro.cn/zh/layout/comment.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/comment/index.vue' }, { path: 'order', icon: 'order', title: 'Order 订单列表', title_en: 'Order', desc: '订单状态、操作、物流信息', desc_en: 'Order status, actions, and logistics information', isHot: true, downloadCount: 2400, rating: 4.8, shareLink: 'https://uviewpro.cn/zh/layout/order.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/order/index.vue' }, { path: 'login', icon: 'login', title: 'Login 登录界面', title_en: 'Login', desc: '多方式登录,验证码/密码', desc_en: 'Multiple login methods: verification code or password', downloadCount: 3100, rating: 4.9, shareLink: 'https://uviewpro.cn/zh/layout/login.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/login/index.vue' }, { path: 'address', icon: 'address', title: 'Address 收货地址', title_en: 'Address', desc: '地址管理、选择、编辑', desc_en: 'Address management, selection, and editing', downloadCount: 1800, rating: 4.6, shareLink: 'https://uviewpro.cn/zh/layout/address.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/address/index.vue' }, { path: 'citySelect', icon: 'citySelect', title: 'CitySelect 城市选择', title_en: 'CitySelect', desc: '省市区三级联动、搜索定位', desc_en: 'Province-city-district three-level linkage, with search and location', isNew: true, downloadCount: 1200, rating: 4.7, shareLink: 'https://uviewpro.cn/zh/layout/citySelect.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/template/citySelect/index.vue' } ] }, { groupName: '场景', groupName_en: 'Scenes', list: [ { path: '/pages/scenes/todo/index', icon: 'todo', title: '待办事项', title_en: 'Todo', desc: '任务管理,提高工作效率', desc_en: 'Task management to boost productivity', isHot: true, downloadCount: 820, rating: 4.7, shareLink: 'https://uviewpro.cn/zh/scenes/todo.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/todo/index.vue' }, { path: '/pages/scenes/notes/index', icon: 'note', title: '我的笔记', title_en: 'Notes', desc: '记录想法,随时查看', desc_en: 'Capture ideas and review anytime', downloadCount: 760, rating: 4.6, shareLink: 'https://uviewpro.cn/zh/scenes/notes.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/notes/index.vue' }, { path: '/pages/scenes/dashboard/index', icon: 'dashboard', title: '数据统计', title_en: 'Dashboard', desc: '使用数据一目了然', desc_en: 'Usage stats at a glance', isNew: true, downloadCount: 680, rating: 4.5, shareLink: 'https://uviewpro.cn/zh/scenes/dashboard.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/dashboard/index.vue' }, { path: '/pages/scenes/favorites/index', icon: 'favorite', title: '我的收藏', title_en: 'Favorites', desc: '收藏喜欢的组件', desc_en: 'Bookmark your favorite components', downloadCount: 540, rating: 4.5, shareLink: 'https://uviewpro.cn/zh/scenes/favorites.html', codeLink: 'https://github.com/anyup/uView-Pro/blob/master/src/pages/scenes/favorites/index.vue' } ] } ]; ================================================ FILE: src/pages/example/template.vue ================================================ ================================================ FILE: src/pages/hooks/useModal/index.vue ================================================ ================================================ FILE: src/pages/hooks/useToast/index.vue ================================================ ================================================ FILE: src/pages/index/index.vue ================================================ ================================================ FILE: src/pages/library/color/index.vue ================================================ ================================================ FILE: src/pages/library/colorSwitch/index.vue ================================================ ================================================ FILE: src/pages/library/debounce/index.vue ================================================ ================================================ FILE: src/pages/library/deepClone/index.vue ================================================ ================================================ FILE: src/pages/library/deepMerge/index.vue ================================================ ================================================ FILE: src/pages/library/getRect/index.vue ================================================ ================================================ FILE: src/pages/library/guid/index.vue ================================================ ================================================ FILE: src/pages/library/http/index.vue ================================================ ================================================ FILE: src/pages/library/md5/index.vue ================================================ ================================================ FILE: src/pages/library/mpShare/index.vue ================================================ ================================================ FILE: src/pages/library/queryParams/index.vue ================================================ ================================================ FILE: src/pages/library/random/index.vue ================================================ ================================================ FILE: src/pages/library/randomArray/index.vue ================================================ ================================================ FILE: src/pages/library/route/index.vue ================================================ ================================================ FILE: src/pages/library/route/routeTo.vue ================================================ ================================================ FILE: src/pages/library/test/index.vue ================================================ ================================================ FILE: src/pages/library/timeFormat/index.vue ================================================ ================================================ FILE: src/pages/library/timeFrom/index.vue ================================================ ================================================ FILE: src/pages/library/trim/index.vue ================================================ ================================================ FILE: src/pages/other/locale/index.vue ================================================ ================================================ FILE: src/pages/other/theme/index.vue ================================================ ================================================ FILE: src/pages/scenes/dashboard/index.vue ================================================ ================================================ FILE: src/pages/scenes/favorites/index.vue ================================================ ================================================ FILE: src/pages/scenes/index.vue ================================================ ================================================ FILE: src/pages/scenes/notes/index.vue ================================================ ================================================ FILE: src/pages/scenes/todo/index.vue ================================================ ================================================ FILE: src/pages/template/address/addSite.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-th/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; /** * ThProps th props 类型定义 * @description 表格表头单元格组件,支持宽度自定义 */ export const ThProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 宽度,百分比或者具体带单位的值,如30%, 200rpx等,一般使用百分比 */ width: { type: [Number, String] as PropType, default: 'auto' } }; export type ThProps = ExtractPropTypes; ================================================ FILE: src/uni_modules/uview-pro/components/u-th/u-th.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-time-line/u-time-line.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-time-line-item/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; /** * TimeLineItemProps 时间轴节点 props 类型定义 * @description 时间轴节点组件,支持自定义节点颜色、位置 */ export const TimeLineItemProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 节点的背景颜色 */ bgColor: { type: String, default: 'var(--u-bg-white)' }, /** 节点左边图标绝对定位的top值,单位rpx */ nodeTop: { type: [String, Number] as PropType, default: '' } }; export type TimeLineItemProps = ExtractPropTypes; ================================================ FILE: src/uni_modules/uview-pro/components/u-time-line-item/u-time-line-item.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-toast/service.ts ================================================ /** * u-toast 函数式调用事件名(全平台) * @description * - useToast() 通过 uni.$emit 派发事件 * - 通过 uni.$on 监听事件并转调自身 show/hide */ import type { ToastProps } from './types'; // 普通(页面级)toast 事件 export const U_TOAST_EVENT_SHOW = 'uview-pro:u-toast:show:'; export const U_TOAST_EVENT_HIDE = 'uview-pro:u-toast:hide:'; // 全局(App 根部)toast 事件,供 useToast() 使用 export const U_TOAST_GLOBAL_EVENT_SHOW = 'uview-pro:u-toast:global:show'; export const U_TOAST_GLOBAL_EVENT_HIDE = 'uview-pro:u-toast:global:hide'; // 根据当前页面获取事件名 export function getEventWithCurrentPage(event: string, page?: string | boolean) { if (page && typeof page === 'string' && page !== '') { return event + page; } return event + getCurrentPage(); } // 获取当前页面路由 function getCurrentPage() { try { const pages = getCurrentPages(); const currentPage = pages[pages.length - 1].route as string; return currentPage || ''; } catch (error) { return ''; } } export type ToastPayload = Partial & { /** 文案(兼容 toast.show('xxx')) */ title?: string; }; ================================================ FILE: src/uni_modules/uview-pro/components/u-toast/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; import type { ThemeType, ToastPosition } from '../../types/global'; import zIndex from '../../libs/config/zIndex'; /** * ToastProps toast props 类型定义 * @description 消息提示组件,支持 z-index 及多种配置项 */ export const ToastProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 层级 z-index */ zIndex: { type: [Number, String] as PropType, default: zIndex.toast }, /** 提示类型,success/warning/error/loading 等 */ type: { type: String as PropType, default: '' }, /** 显示时长,单位ms。设为 0 表示不自动关闭,需手动调用 hide/close 方法 */ duration: { type: Number, default: 2000 }, /** 是否显示图标 */ icon: { type: Boolean, default: true }, /** 显示位置,center/top/bottom */ position: { type: String as PropType, default: 'center' }, /** 关闭时的回调函数 */ callback: { type: Function as unknown as PropType<(() => void) | null>, default: null }, /** 是否返回上一页 */ back: { type: Boolean, default: false }, /** 是否为tab页面跳转 */ isTab: { type: Boolean, default: false }, /** 跳转的url */ url: { type: String, default: '' }, /** 跳转参数对象 */ params: { type: Object as PropType>, default: () => ({}) }, /** 是否作为全局根部 toast(通常放在 App.vue 中,给 useToast() 使用) */ global: { type: Boolean, default: false }, /** 是否作为页面级 toast(通常放在页面中,给 useToast({ page: true }) 使用) */ page: { type: [Boolean, String] as PropType, default: false }, /** 是否为loading “常驻” */ loading: { type: Boolean, default: false } }; export type ToastProps = ExtractPropTypes; export type ToastExpose = { show: (options: Record) => void; hide: () => void; close: () => void; }; ================================================ FILE: src/uni_modules/uview-pro/components/u-toast/u-toast.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-top-tips/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; import zIndex from '../../libs/config/zIndex'; /** * TopTipsProps top-tips props 类型定义 * @description 顶部提示组件,支持导航栏高度、z-index */ export const TopTipsProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 导航栏高度,用于提示的初始化 */ navbarHeight: { type: [Number, String] as PropType, default: 0 }, /** z-index值 */ zIndex: { type: [Number, String] as PropType, default: zIndex.topTips } }; export type TopTipsProps = ExtractPropTypes; ================================================ FILE: src/uni_modules/uview-pro/components/u-top-tips/u-top-tips.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-tr/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; /** * TrProps tr props 类型定义 * @description 表格行组件,无特殊 props */ export const TrProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' } }; export type TrProps = ExtractPropTypes; ================================================ FILE: src/uni_modules/uview-pro/components/u-tr/u-tr.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-transition/types.ts ================================================ import type { PropType } from 'vue'; import type { TransitionDuration, TransitionPreset } from '../../types/global'; export const TransitionProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, show: { type: Boolean, default: true }, name: { type: String as PropType, default: 'fade' }, mode: { type: String as PropType<'out-in' | 'in-out' | ''>, default: '' }, duration: { type: [Number, Object] as PropType, default: 300 }, timingFunction: { type: String, default: 'cubic-bezier(0.2, 0.8, 0.2, 1)' }, delay: { type: Number, default: 0 }, appear: { type: Boolean, default: false } }; ================================================ FILE: src/uni_modules/uview-pro/components/u-transition/u-transition.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-upload/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; import type { ImgMode, UploadSizeType, UploadSourceType, UploadAcceptType, UploadFileItem } from '../../types/global'; import { useLocale } from '../../'; const { t } = useLocale(); /** * UploadProps upload props 类型定义 * @description 文件上传组件,支持多种自定义参数 */ export const UploadProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 选择器宽度,单位rpx */ width: { type: [Number, String] as PropType, default: 200 }, /** 选择器高度,单位rpx */ height: { type: [Number, String] as PropType, default: 200 }, /** 最大上传数量 */ maxCount: { type: [Number, String] as PropType, default: 52 }, /** 是否可删除 */ deletable: { type: Boolean, default: true }, /** * 上传组件的展示模式 * @description grid-网格模式(默认), list-列表模式 * @default 'grid' */ mode: { type: String as PropType<'grid' | 'list'>, default: 'grid' }, /** 是否显示上传列表 */ showUploadList: { type: Boolean, default: true }, /** 是否显示上传进度 */ showProgress: { type: Boolean, default: true }, /** 删除按钮背景色 */ delBgColor: { type: String, default: 'var(--u-type-error)' }, /** 删除按钮图标 */ delIcon: { type: String, default: 'close' }, /** 删除按钮颜色 */ delColor: { type: String, default: 'var(--u-white-color)' }, /** 图片裁剪模式 */ imageMode: { type: String as PropType, default: 'aspectFill' }, /** 是否自定义上传按钮 */ customBtn: { type: Boolean, default: false }, /** 上传按钮文字 */ uploadText: { type: String, default: () => t('uUpload.uploadText') }, /** 上传地址 */ action: { type: String, default: '' }, /** 是否禁用 */ disabled: { type: Boolean, default: false }, /** 索引值,在各个回调事件中的最后一个参数返回,用于区别是哪一个组件的事件 */ index: { type: [String, Number] as PropType, default: '' }, /** 请求头对象 */ header: { type: Object as PropType>, default: () => ({}) }, /** formData对象 */ formData: { type: Object as PropType>, default: () => ({}) }, /** 文件字段名 */ name: { type: String, default: 'file' }, /** 压缩/原图,微信小程序有效 */ sizeType: { type: Array as PropType, default: () => ['original', 'compressed'] }, /** 来源,相册/相机 */ sourceType: { type: Array as PropType, default: () => ['album', 'camera'] }, /** 是否可预览大图 */ previewFullImage: { type: Boolean, default: true }, /** 是否可预览文件 */ previewFile: { type: Boolean, default: true }, /** 是否支持多选 */ multiple: { type: Boolean, default: true }, /** 单个文件最大大小,单位B(byte),默认不限制 */ maxSize: { type: [Number, String] as PropType, default: Number.MAX_VALUE }, /** * 文件列表(v-model 双向绑定) * @description 推荐使用 v-model 替代 :file-list */ modelValue: { type: Array as PropType, default: () => [] }, /** * 文件列表(初始值,向后兼容) * @deprecated 请使用 v-model */ fileList: { type: Array as PropType, default: () => [] }, /** 限制文件类型 */ /** 允许上传的文件后缀 */ /** 支付宝小程序真机选择图片的后缀为"image" */ /** https://opendocs.alipay.com/mini/api/media-image */ limitType: { type: Array as PropType, default: () => [] }, /** 是否自动上传 */ autoUpload: { type: Boolean, default: true }, /** 是否显示提示 */ showTips: { type: Boolean, default: true }, /** 是否显示确认弹窗 */ showConfirm: { type: Boolean, default: true }, /** 上传前钩子,返回true或Promise */ beforeUpload: { type: Function as unknown as PropType< ((index: number, files: UploadFileItem[]) => boolean | Promise) | null >, default: null }, /** 删除前钩子,返回true或Promise */ beforeRemove: { type: Function as unknown as PropType< ((index: number, files: UploadFileItem[]) => boolean | Promise) | null >, default: null }, /** 如果上传后的返回值为json字符串,是否转为json格式 */ toJson: { type: Boolean, default: true }, /** * 接受上传的文件类型 * @description image-图片(默认), video-视频, file-文件, media-媒体(图片+视频), all-所有文件 * @default 'image' */ accept: { type: String as PropType, default: 'image' }, /** * 是否显示文件名 * @default true */ showFileName: { type: Boolean, default: true }, /** * 是否显示文件大小 * @default false */ showFileSize: { type: Boolean, default: false }, /** * 文件类型图标映射配置 * @description 用于自定义不同文件类型的图标 */ fileIconMap: { type: Object as PropType>, default: () => ({}) }, /** * 选择视频时是否压缩 * @default true */ compressed: { type: Boolean, default: true }, /** * 选择视频时拍摄最长时长,单位秒 * @default 60 */ maxDuration: { type: Number, default: 60 }, /** * 选择视频时,是前置还是后置摄像头 * @default 'back' */ camera: { type: String as PropType<'front' | 'back'>, default: 'back' }, /** * 选择文件时的扩展名过滤 * @description 仅在 accept='file' 或 accept='all' 时有效 */ extension: { type: Array as PropType, default: () => [] }, /** * 图片/图标展示形状 * @description 可选值:square-方形(默认), circle-圆形。在 grid 模式下作用于图片和添加按钮,在 list 模式下作用于图标 * @default 'square' */ imageShape: { type: String as PropType<'square' | 'circle'>, default: 'square' }, /** * 是否使用自定义选择文件 * @description 设置为 true 时,点击选择文件会触发 on-choose 事件,不会调用默认的文件选择 API,用户可自行处理文件选择逻辑,然后通过 addFiles 方法将文件添加到列表 * @default false */ customChoose: { type: Boolean, default: false } }; export type UploadProps = ExtractPropTypes; // 重新导出全局类型,方便从组件入口导入 export type { UploadAcceptType, UploadFileItem } from '../../types/global'; ================================================ FILE: src/uni_modules/uview-pro/components/u-upload/u-upload.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-verification-code/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; import { useLocale } from '../../'; const { t } = useLocale(); /** * VerificationCodeProps 验证码输入框 props 类型定义 * @description 验证码输入倒计时组件 */ export const VerificationCodeProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 倒计时时长,单位秒 */ seconds: { type: [String, Number] as PropType, default: 60 }, /** 开始时按钮文字 */ startText: { type: String, default: () => t('uVerificationCode.startText') }, /** 倒计时进行中按钮文字,X为剩余秒数 */ changeText: { type: String, default: () => t('uVerificationCode.changeText') }, /** 结束时按钮文字 */ endText: { type: String, default: () => t('uVerificationCode.endText') }, /** 是否保持倒计时不中断(如页面切换) */ keepRunning: { type: Boolean, default: false }, /** 唯一标识key,用于区分多个验证码组件 */ uniqueKey: { type: String, default: '' } }; export type VerificationCodeProps = ExtractPropTypes; ================================================ FILE: src/uni_modules/uview-pro/components/u-verification-code/u-verification-code.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/components/u-waterfall/types.ts ================================================ import type { ExtractPropTypes, PropType } from 'vue'; /** * WaterfallProps waterfall props 类型定义 * @description 瀑布流组件,支持数据、间隔、idKey */ export const WaterfallProps = { /** 自定义根节点样式 */ customStyle: { type: [String, Object] as PropType>, default: () => ({}) }, /** 自定义根节点样式类 */ customClass: { type: String as unknown as PropType, default: '' }, /** 瀑布流数据数组,必填 */ modelValue: { type: Array as PropType, required: true, default: () => [] }, /** 新增数据的动画间隔,单位ms */ addTime: { type: [Number, String] as PropType, default: 200 }, /** 数据项的唯一标识key */ idKey: { type: String, default: 'id' } }; export type WaterfallProps = ExtractPropTypes; ================================================ FILE: src/uni_modules/uview-pro/components/u-waterfall/u-waterfall.vue ================================================ ================================================ FILE: src/uni_modules/uview-pro/iconfont.css ================================================ /* #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_k4s6di1d1.eot?t=1596960292384'); /* IE9 */ src: url('//at.alicdn.com/t/font_1529455_k4s6di1d1.eot?t=1596960292384#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_k4s6di1d1.woff?t=1596960292384') format('woff'), url('//at.alicdn.com/t/font_1529455_k4s6di1d1.ttf?t=1596960292384') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('//at.alicdn.com/t/font_1529455_k4s6di1d1.svg?t=1596960292384#iconfont') format('svg'); } /* #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-en:before { content: '\e70a'; } .uicon-zh:before { content: '\e692'; } .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'; } ================================================ FILE: src/uni_modules/uview-pro/index.scss ================================================ // 引入公共基础类 @import './libs/css/style.theme.scss'; @import './libs/css/common.scss'; @import './libs/css/color.scss'; // 非nvue的样式 /* #ifndef APP-NVUE */ @import './libs/css/style.vue.scss'; /* #endif */ // nvue的特有样式 /* #ifdef APP-NVUE */ @import './libs/css/style.nvue.scss'; /* #endif */ // 小程序特有的样式 /* #ifdef MP */ @import './libs/css/style.mp.scss'; /* #endif */ // H5特有的样式 /* #ifdef H5 */ @import './libs/css/style.h5.scss'; /* #endif */ @import './libs/css/style.components.scss'; ================================================ FILE: src/uni_modules/uview-pro/index.ts ================================================ import { $u, type RequestOptions, initTheme, configProvider } from './libs'; import type { UViewProOptions, Theme } from './types/global'; import { defaultThemes } from './libs/config/theme-tokens'; import { setConfig } from './libs/config/config'; declare const uni: { [key: string]: any; $u?: typeof $u; createSelectorQuery: () => any; hideLoading: () => void; showLoading: (options: any) => void; request: (options: RequestOptions) => any; }; // $u挂载到uni对象上 const install = (app: any, options?: UViewProOptions): void => { try { if (options) { // 配置主题:统一使用 useTheme 的 initTheme 初始化,避免重复初始化 if (options?.theme) { const optTheme = options.theme as any; // 1.如果是数组,则为多主题配置 if (Array.isArray(optTheme)) { initTheme(optTheme); } else if (typeof optTheme === 'object' && optTheme.themes) { // 2.如果为对象且有themes,则为多主题配置+设置默认主题 initTheme( optTheme.themes, { defaultTheme: optTheme.defaultTheme, defaultDarkMode: optTheme.defaultDarkMode }, optTheme.isForce ); } else { // 3.兼容之前只有一套样式的情况,需要覆盖默认主题,默认系统主题(uviewpro) const defaultTheme = defaultThemes[0]; if (defaultTheme) { // 创建新主题对象,用用户的 theme 覆盖默认主题的 color const mergedTheme: Theme = { ...defaultTheme, color: { ...defaultTheme.color, ...optTheme } }; // 初始化主题(只包含覆盖后的默认主题) initTheme([mergedTheme], defaultTheme.name); } } } else { // 默认初始化系统主题 initTheme(); } // 初始化国际化(如果提供 options.locale 或使用内置语言包) try { // options.locale 可以是 string(默认语言名) | any[](locale 列表) | { locales: any[], defaultLocale?: string } if (options?.locale) { const optLocale: any = options.locale as any; if (typeof optLocale === 'string') { configProvider.initLocales(undefined, optLocale); } else if (Array.isArray(optLocale)) { configProvider.initLocales(optLocale); } else if (optLocale && typeof optLocale === 'object') { configProvider.initLocales(optLocale.locales, optLocale.defaultLocale, optLocale.isForce); } else { configProvider.initLocales(); } } else { // 无 locale 配置,仍然初始化内置语言包以保证可用 configProvider.initLocales(); } } catch (e) { console.error('[install locales] Error:', e); } // 设置调试模式 setConfig({ debugMode: options?.debugMode ?? false }); } else { // 默认初始化系统主题 initTheme(); // 默认初始化内置语言包以保证可用 configProvider.initLocales(); } } catch (error) { console.error('[install options] Error:', error); } uni.$u = $u; // 可扩展更多配置项 app.config.globalProperties.$u = $u; }; export default { install }; export * from './libs'; export type { UViewProOptions }; ================================================ FILE: src/uni_modules/uview-pro/libs/config/color.ts ================================================ import { reactive } from 'vue'; import { lightPalette } from './theme-tokens'; import type { ThemeColor } from '../../types/global'; // 使用 reactive 包装颜色对象,使其在运行时可被响应式读取与更新 // 这个对象会被 configProvider 在主题切换时更新 export const color = reactive({ ...lightPalette }); export default color; ================================================ FILE: src/uni_modules/uview-pro/libs/config/config.ts ================================================ /** * 组件库配置项类型定义 */ import { reactive } from 'vue'; import { version } from '../../package.json'; import type { DarkMode, DebugMode } from '../../types/global'; export type AppConfig = { /** 版本号 */ v: string; /** 版本号(冗余字段) */ version: string; /** 主题名称列表 */ type: string[]; /** 默认主题名称 */ defaultTheme: string; /** 默认暗黑主题 */ defaultDarkMode: DarkMode; /** 默认语言 */ defaultLocale: string; /** 是否开启调试模式 */ debugMode?: boolean | DebugMode | DebugMode[]; }; export const config = reactive({ v: version, version: version, // 主题名称 type: ['primary', 'success', 'info', 'error', 'warning'], // 默认为官方主题名称 defaultTheme: 'uviewpro', // 默认为亮色模式 defaultDarkMode: 'light', // 默认为中文 defaultLocale: 'zh-CN', // 默认不开启调试模式 debugMode: false }); export const isDebugMode = (debug: DebugMode = 'log'): boolean => { if (config.debugMode === false) return false; if (config.debugMode === true) return true; if (Array.isArray(config.debugMode)) return config.debugMode.includes(debug); return config.debugMode === debug; }; export const setConfig = (options: Partial) => { try { Object.keys(options).forEach(key => { if (key in config) { (config as any)[key] = options[key as keyof AppConfig]; } }); } catch (e) { if (isDebugMode('error')) console.error('Failed to set config:', e); } }; export default config; ================================================ FILE: src/uni_modules/uview-pro/libs/config/theme-tokens.ts ================================================ import type { Theme, ThemeColor } from '../../types/global'; import config from './config'; export const lightPalette: ThemeColor = { primary: '#2979ff', primaryDark: '#2b85e4', primaryDisabled: '#a0cfff', primaryLight: '#ecf5ff', success: '#19be6b', successDark: '#18b566', successDisabled: '#71d5a1', successLight: '#dbf1e1', warning: '#ff9900', warningDark: '#f29100', warningDisabled: '#fcbd71', warningLight: '#fdf6ec', error: '#fa3534', errorDark: '#dd6161', errorDisabled: '#fab6b6', errorLight: '#fef0f0', info: '#909399', infoDark: '#82848a', infoDisabled: '#c8c9cc', infoLight: '#f4f4f5', whiteColor: '#ffffff', blackColor: '#000000', mainColor: '#303133', contentColor: '#606266', tipsColor: '#909399', lightColor: '#c0c4cc', borderColor: '#dcdfe6', dividerColor: '#e4e7ed', maskColor: 'rgba(0, 0, 0, 0.4)', shadowColor: 'rgba(0, 0, 0, 0.1)', bgColor: '#f3f4f6', bgWhite: '#ffffff', bgGrayLight: '#f1f1f1', bgGrayDark: '#2f343c', bgBlack: '#000000' }; export const darkPalette: ThemeColor = { primary: '#8ab4ff', primaryDark: '#5f8dff', primaryDisabled: '#3d4f74', primaryLight: '#1d273f', success: '#4ade80', successDark: '#1f9d57', successDisabled: '#2f4d3d', successLight: '#10291f', warning: '#fbbf24', warningDark: '#c88f00', warningDisabled: '#4a3b17', warningLight: '#2b1f05', error: '#ff6b6b', errorDark: '#d83a3a', errorDisabled: '#4f2323', errorLight: '#2d1414', info: '#a0a7b8', infoDark: '#7c8394', infoDisabled: '#3b3f4c', infoLight: '#1d2029', whiteColor: '#f5f6f7', blackColor: '#f5f6f7', mainColor: '#f5f6f7', contentColor: '#cfd3dc', tipsColor: '#9aa1af', lightColor: '#6b7082', borderColor: '#3a4251', dividerColor: '#3a4251', maskColor: 'rgba(0, 0, 0, 0.6)', shadowColor: 'rgba(0, 0, 0, 0.3)', bgColor: '#111827', bgWhite: '#000000', bgGrayLight: '#1a1a1a', bgGrayDark: '#f5f7fa', bgBlack: '#ffffff' }; const lightCss: Record = { '--u-background': '#ffffff', '--u-surface': '#f7f8fa', '--u-text': '#303133' }; const darkCss: Record = { '--u-background': '#0f1115', '--u-surface': '#1c2233', '--u-text': '#f5f6f7' }; export const defaultThemes: Theme[] = [ { name: config.defaultTheme, label: '默认蓝', description: 'uView Pro 默认主题,支持亮色与暗黑模式', color: lightPalette, darkColor: darkPalette, css: lightCss, darkCss: darkCss } ]; ================================================ FILE: src/uni_modules/uview-pro/libs/config/zIndex.ts ================================================ /** * 组件库 z-index 配置项类型定义 */ export interface ZIndexConfig { toast: number; noNetwork: number; /** popup包含popup,actionSheet,keyboard,picker的值 */ popup: number; mask: number; navbar: number; topTips: number; sticky: number; indexListSticky: number; tabbar: number; } const zIndex: ZIndexConfig = { toast: 10090, noNetwork: 10080, // popup包含popup,actionSheet,keyboard,picker的值 popup: 10075, mask: 10070, navbar: 980, topTips: 975, sticky: 970, indexListSticky: 965, tabbar: 998 }; export default zIndex; ================================================ FILE: src/uni_modules/uview-pro/libs/css/color.scss ================================================ .u-type-primary-light { color: $u-type-primary-light; } .u-type-warning-light { color: $u-type-warning-light; } .u-type-success-light { color: $u-type-success-light; } .u-type-error-light { color: $u-type-error-light; } .u-type-info-light { color: $u-type-info-light; } .u-type-primary-light-bg { background-color: $u-type-primary-light; } .u-type-warning-light-bg { background-color: $u-type-warning-light; } .u-type-success-light-bg { background-color: $u-type-success-light; } .u-type-error-light-bg { background-color: $u-type-error-light; } .u-type-info-light-bg { background-color: $u-type-info-light; } .u-type-primary-dark { color: $u-type-primary-dark; } .u-type-warning-dark { color: $u-type-warning-dark; } .u-type-success-dark { color: $u-type-success-dark; } .u-type-error-dark { color: $u-type-error-dark; } .u-type-info-dark { color: $u-type-info-dark; } .u-type-primary-dark-bg { background-color: $u-type-primary-dark; } .u-type-warning-dark-bg { background-color: $u-type-warning-dark; } .u-type-success-dark-bg { background-color: $u-type-success-dark; } .u-type-error-dark-bg { background-color: $u-type-error-dark; } .u-type-info-dark-bg { background-color: $u-type-info-dark; } .u-type-primary-disabled { color: $u-type-primary-disabled; } .u-type-warning-disabled { color: $u-type-warning-disabled; } .u-type-success-disabled { color: $u-type-success-disabled; } .u-type-error-disabled { color: $u-type-error-disabled; } .u-type-info-disabled { color: $u-type-info-disabled; } .u-type-primary { color: $u-type-primary; } .u-type-warning { color: $u-type-warning; } .u-type-success { color: $u-type-success; } .u-type-error { color: $u-type-error; } .u-type-info { color: $u-type-info; } .u-type-primary-bg { background-color: $u-type-primary; } .u-type-warning-bg { background-color: $u-type-warning; } .u-type-success-bg { background-color: $u-type-success; } .u-type-error-bg { background-color: $u-type-error; } .u-type-info-bg { background-color: $u-type-info; } .u-main-color { color: $u-main-color; } .u-content-color { color: $u-content-color; } .u-tips-color { color: $u-tips-color; } .u-light-color { color: $u-light-color; } ================================================ FILE: src/uni_modules/uview-pro/libs/css/common.scss ================================================ .u-relative, .u-rela { position: relative; } .u-absolute, .u-abso { position: absolute; } // nvue不能用标签命名样式,不能放在微信组件中,否则微信开发工具会报警告,无法使用标签名当做选择器 /* #ifndef APP-NVUE */ image { display: inline-block; } // 在weex,也即nvue中,所有元素默认为border-box view, text { box-sizing: border-box; } /* #endif */ .u-font-xs { font-size: 22rpx; } .u-font-sm { font-size: 26rpx; } .u-font-md { font-size: 28rpx; } .u-font-lg { font-size: 30rpx; } .u-font-xl { font-size: 34rpx; } .u-flex { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: row; align-items: center; } .u-flex-wrap { flex-wrap: wrap; } .u-flex-nowrap { flex-wrap: nowrap; } .u-col-center { align-items: center; } .u-col-top { align-items: flex-start; } .u-col-bottom { align-items: flex-end; } .u-row-center { justify-content: center; } .u-row-left { justify-content: flex-start; } .u-row-right { justify-content: flex-end; } .u-row-between { justify-content: space-between; } .u-row-around { justify-content: space-around; } .u-text-left { text-align: left; } .u-text-center { text-align: center; } .u-text-right { text-align: right; } .u-flex-col { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: column; } .u-hidden { opacity: 0; visibility: hidden; } // 定义flex等分 @for $i from 0 through 12 { .u-flex-#{$i} { flex: $i; } } // 定义字体(px)单位,小于20都为px单位字体 @for $i from 9 to 20 { .u-font-#{$i} { font-size: $i + px; } } // 定义字体(rpx)单位,大于或等于20的都为rpx单位字体 @for $i from 20 through 40 { .u-font-#{$i} { font-size: $i + rpx; } } // 定义内外边距,历遍1-80 @for $i from 0 through 80 { // 只要双数和能被5除尽的数 @if $i % 2 == 0 or $i % 5 == 0 { // 得出:u-margin-30或者u-m-30 .u-margin-#{$i}, .u-m-#{$i} { margin: $i + rpx !important; } // 得出:u-padding-30或者u-p-30 .u-padding-#{$i}, .u-p-#{$i} { padding: $i + rpx !important; } @each $short, $long in l left, t top, r right, b bottom { // 缩写版,结果如: u-m-l-30 // 定义外边距 .u-m-#{$short}-#{$i} { margin-#{$long}: $i + rpx !important; } // 定义内边距 .u-p-#{$short}-#{$i} { padding-#{$long}: $i + rpx !important; } // 完整版,结果如:u-margin-left-30 // 定义外边距 .u-margin-#{$long}-#{$i} { margin-#{$long}: $i + rpx !important; } // 定义内边距 .u-padding-#{$long}-#{$i} { padding-#{$long}: $i + rpx !important; } } } } // 重置nvue的默认关于flex的样式 .u-reset-nvue { flex-direction: row; align-items: center; } ================================================ FILE: src/uni_modules/uview-pro/libs/css/style.components.scss ================================================ // 定义混入指令,用于在非nvue环境下的flex定义,因为nvue没有display属性,会报错 @mixin vue-flex($direction: row) { /* #ifndef APP-NVUE */ display: flex; flex-direction: $direction; /* #endif */ } // 通过scss的mixin功能,把原来需要写4行的css,变成一行 // 目的是保持代码干净整洁,不至于在nvue下,到处都要写display:flex的条件编译 @mixin flex($direction: row) { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: $direction; } ================================================ FILE: src/uni_modules/uview-pro/libs/css/style.h5.scss ================================================ /* H5的时候,隐藏滚动条 */ ::-webkit-scrollbar { display: none; width: 0 !important; height: 0 !important; -webkit-appearance: none; background: transparent; } ================================================ FILE: src/uni_modules/uview-pro/libs/css/style.mp.scss ================================================ /* start--微信小程序编译后页面有组件名的元素,特别处理--start */ /* #ifdef MP-WEIXIN || MP-QQ */ u-td, u-th { flex: 1; align-self: stretch; } u-icon { display: inline-flex; align-items: center; } // 各家小程序宫格组件外层设置为100%,避免受到父元素display: flex;的影响 u-grid { width: 100%; flex: 0 0 100%; } // 避免小程序线条组件因为父组件display: flex;而失效 u-line { flex: 1; } u-switch { display: inline-flex; align-items: center; } u-dropdown { flex: 1; } /* #endif */ /* end-微信小程序编译后页面有组件名的元素,特别处理--end */ /* #ifdef MP-QQ || MP-TOUTIAO */ // 需要做这一切额外的兼容,都是因为TX的无能 u-icon { line-height: 0; } /* #endif */ /* start--头条小程序编译后页面有组件名的元素,特别处理--start */ // 由于头条小程序不支持直接组件名形式写样式,目前只能在写组件的时候给组件加上对应的类名 /* #ifdef MP-TOUTIAO */ .u-td, .u-th, .u-tr { flex: 1; align-self: stretch; } .u-row, .u-col { flex: 1; align-self: stretch; } // 避免小程序线条组件因为父组件display: flex;而失效 .u-line { flex: 1; } .u-dropdown { flex: 1; } /* #endif */ /* end-头条小程序编译后页面有组件名的元素,特别处理--end */ ================================================ FILE: src/uni_modules/uview-pro/libs/css/style.nvue.scss ================================================ .nvue { font-size: 24rpx; } view, scroll-view, swiper-item { display: flex; flex-direction: column; flex-shrink: 0; flex-grow: 0; flex-basis: auto; align-items: stretch; align-content: flex-start; } ================================================ FILE: src/uni_modules/uview-pro/libs/css/style.theme.scss ================================================ /* #ifdef H5 */ :root { color-scheme: light; } :root.u-theme-dark, :root[data-u-theme-mode='dark'] { color-scheme: dark; } /* #endif */ page { color: $u-main-color; background-color: $u-bg-color; font-size: 28rpx; } page.u-theme-dark, :root.u-theme-dark page, :root[data-u-theme-mode='dark'] page { background-color: $u-bg-color; color: $u-main-color; } .u-config-provider { color: $u-main-color; background-color: var(--u-bg-white, #ffffff); } .u-config-provider.u-theme-dark { background-color: var(--u-bg-white, #0f1115); color: $u-main-color; } // picker-view遮罩层背景色 .u-picker-view-mask, .uni-picker-view-mask { background-image: linear-gradient(180deg, rgba(var(--u-bg-white-rgb), 0.95), rgba(var(--u-bg-white-rgb), 0.6)), linear-gradient(0deg, rgba(var(--u-bg-white-rgb), 0.95), rgba(var(--u-bg-white-rgb), 0.6)) !important; } .u-picker-view-indicator { border: rgba(var(--u-bg-white-rgb), 0.6) !important; } // picker-view指示器边框色 .u-picker-view-indicator::before, .uni-picker-view-indicator::before { border-top: 1px solid var(--u-border-color) !important; } .u-picker-view-indicator::after, .uni-picker-view-indicator::after { border-bottom: 1px solid var(--u-border-color) !important; } ================================================ FILE: src/uni_modules/uview-pro/libs/css/style.vue.scss ================================================ page { color: $u-main-color; font-size: 28rpx; } /* start--去除webkit的默认样式--start */ .u-fix-ios-appearance { -webkit-appearance: none; } /* end--去除webkit的默认样式--end */ /* start--icon图标外层套一个view,让其达到更好的垂直居中的效果--start */ .u-icon-wrap { display: flex; align-items: center; } /* end-icon图标外层套一个view,让其达到更好的垂直居中的效果--end */ /* start--iPhoneX底部安全区定义--start */ @each $d in top, right, bottom, left { .safe-area-inset-#{$d} { padding-#{$d}: 0; padding-#{$d}: constant(safe-area-inset-#{$d}); padding-#{$d}: env(safe-area-inset-#{$d}); } } /* end-iPhoneX底部安全区定义--end */ /* start--各种hover点击反馈相关的类名-start */ .u-hover-class { // background-color: #f7f8f9!important; opacity: 0.6; } .u-cell-hover { background-color: $u-bg-gray-light !important; } /* end--各种hover点击反馈相关的类名--end */ /* start--文本行数限制--start */ // 超出行数,自动显示行尾省略号,最多5行 // 来自uView的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】 @for $i from 1 through 5 { .u-line-#{$i} { /* #ifdef APP-NVUE */ // nvue下,可以直接使用lines属性,这是weex特有样式 lines: $i; text-overflow: ellipsis; overflow: hidden; flex: 1; /* #endif */ /* #ifndef APP-NVUE */ // vue下,单行和多行显示省略号需要单独处理 @if $i == 1 { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } @else { display: -webkit-box; overflow: hidden; text-overflow: ellipsis; word-break: break-all; -webkit-line-clamp: $i; -webkit-box-orient: vertical; } /* #endif */ } } .u-line-force { display: -webkit-box !important; -webkit-box-orient: vertical !important; } /* end--文本行数限制--end */ /* start--Retina 屏幕下的 1px 边框--start */ .u-border, .u-border-bottom, .u-border-left, .u-border-right, .u-border-top, .u-border-top-bottom { position: relative; } .u-border-bottom:after, .u-border-left:after, .u-border-right:after, .u-border-top-bottom:after, .u-border-top:after, .u-border:after { /* #ifndef APP-NVUE */ content: ' '; /* #endif */ position: absolute; left: 0; top: 0; pointer-events: none; box-sizing: border-box; -webkit-transform-origin: 0 0; transform-origin: 0 0; // 多加0.1%,能解决有时候边框缺失的问题 width: 199.8%; height: 199.7%; transform: scale(0.5, 0.5); border: 0 solid $u-border-color; z-index: 2; } .u-border-top:after { border-top-width: 1px; } .u-border-left:after { border-left-width: 1px; } .u-border-right:after { border-right-width: 1px; } .u-border-bottom:after { border-bottom-width: 1px; } .u-border-top-bottom:after { border-width: 1px 0; } .u-border:after { border-width: 1px; } /* end--Retina 屏幕下的 1px 边框--end */ /* start--clearfix--start */ .u-clearfix:after, .clearfix:after { /* #ifndef APP-NVUE */ content: ''; /* #endif */ display: table; clear: both; } /* end--clearfix--end */ /* start--高斯模糊tabbar底部处理--start */ .u-blur-effect-inset { width: 750rpx; height: var(--window-bottom); background-color: #ffffff; } /* end--高斯模糊tabbar底部处理--end */ /* start--提升H5端uni.toast()的层级,避免被uView的modal等遮盖--start */ /* #ifdef H5 */ uni-toast { z-index: 10090; } uni-toast .uni-toast { z-index: 10090; } /* #endif */ /* end--提升H5端uni.toast()的层级,避免被uView的modal等遮盖--end */ /* start--去除button的所有默认样式--start */ // 去除button的所有默认样式,让其表现跟普通的view、text元素一样 .u-reset-button { padding: 0; margin: 0; background-color: transparent; /* #ifndef APP-PLUS */ font-size: inherit; line-height: inherit; color: inherit; /* #endif */ /* #ifdef APP-NVUE */ border-width: 0; /* #endif */ } /* #ifndef APP-NVUE */ .u-reset-button::after { border: none; } /* #endif */ /* end--去除button的所有默认样式--end */ ================================================ FILE: src/uni_modules/uview-pro/libs/function/$parent.ts ================================================ // 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 // this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx // 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name // 值(默认为undefined),就是查找最顶层的$parent import { type ComponentInternalInstance, getCurrentInstance } from 'vue'; export default function $parent( componentName?: string, _instance: ComponentInternalInstance | null | undefined = null ) { const instance: ComponentInternalInstance | null | undefined = _instance || getCurrentInstance(); let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined); if (!componentName) return parent; while (parent) { const name = (parent.type as any)?.name as string | undefined; if (name === componentName) { return parent; } parent = parent.parent; } return null; } ================================================ FILE: src/uni_modules/uview-pro/libs/function/addUnit.ts ================================================ import validation from './test'; /** * 添加单位,支持以下场景: * 1. 单值:如果有rpx、%、px等单位结尾或者值为auto,直接返回,否则加上rpx单位结尾 * 2. 多值(空格分隔):分别处理每个值,如 "10 20" => "10rpx 20rpx" * * @example * ```ts * addUnit(10) => "10rpx" * addUnit('10px') => "10px" * addUnit('auto') => "auto" * addUnit('10 20') => "10rpx 20rpx" * addUnit('10rpx 20') => "10rpx 20rpx" * ``` * * @param value 输入值,可以为字符串或数字,默认'auto'。支持空格分隔的多值(用于 padding、margin 等) * @param unit 单位,默认'rpx' * @returns 添加单位后的字符串 */ export default function addUnit(value: string | number = 'auto', unit: string = 'rpx'): string { // 若传入 number 类型,转为 string const strValue = String(value); // 如果是空值,直接返回 if (!strValue) return ''; // auto 直接返回 if (strValue === 'auto') return strValue; // 检查是否包含空格(多值场景) if (strValue.includes(' ')) { // 分割每个值并单独处理 return strValue .split(' ') .map(s => { // 如果当前值已有单位或为 auto,直接返回 if (s === 'auto' || /^-?\d*\.?\d+(%|px|rpx|em|rem|vh|vw)$/.test(s)) return s; // 数字类型的值添加单位 return validation.number(s) ? `${s}${unit}` : s; }) .join(' '); } // 单值场景:如果已有单位或为 auto,直接返回 if (/^-?\d*\.?\d+(%|px|rpx|em|rem|vh|vw)$/.test(strValue)) return strValue; // 用 uView 内置验证规则判断是否为数值,是则加上单位 return validation.number(strValue) ? `${strValue}${unit}` : strValue; } ================================================ FILE: src/uni_modules/uview-pro/libs/function/clipboard.ts ================================================ function H5Copy(text: string, config: TClipboardOptions) { const success = (result: string) => { if (config.showToast) { uni.showToast({ title: '复制成功', icon: 'none' }); } config.success?.(result); config.complete?.(result); }; const fail = (err: string) => { if (config.showToast) { uni.showToast({ title: '复制失败', icon: 'none' }); } config.fail?.(err); config.complete?.(err); }; const textarea = document.createElement('textarea'); textarea.value = text; textarea.readOnly = true; textarea.style.position = 'absolute'; textarea.style.left = '-9999px'; document.body.appendChild(textarea); textarea.select(); textarea.setSelectionRange(0, text.length); try { const result = document.execCommand('copy'); if (result) { success('复制成功'); } else { // console.error(`复制失败,可能不是用户主动触发点击的方式调用,因web安全性,不能js直接调用!`); fail('复制失败,可能不是用户主动触发点击的方式调用,因browser安全性,不能js直接调用!'); } } catch (err) { // console.error('【Clipboard Error】:', err); fail(String(err)); } finally { document.body.removeChild(textarea); } } function UniCopy(text: string, config: TClipboardOptions) { const opt = Object.assign({ data: text }, config); uni.setClipboardData(opt); } type TClipboardOptions = Omit; export function clipboard(content: string, options?: TClipboardOptions) { const text = String(content); const defaultOpt = { showToast: true, success: () => {}, fail: () => {}, complete: () => {} }; const config = Object.assign(defaultOpt, options); // #ifdef H5 H5Copy(text, config); // #endif // #ifndef H5 UniCopy(text, config); // #endif } ================================================ FILE: src/uni_modules/uview-pro/libs/function/color.ts ================================================ import type { ColorType, ThemeColor } from '../../types/global'; import { color } from '../config/color'; import { lightPalette } from '../config/theme-tokens'; import configProvider from '../util/config-provider'; /** * 获取颜色值(响应式) * 优先从 configProvider 获取当前主题颜色,否则返回默认值 * @param name 颜色名称 * @returns 颜色值 */ export function getColor(name: ColorType): string { // 从响应式 color 对象获取(会被 configProvider 更新) if (color[name]) { return color[name] as string; } // 兜底返回默认值 return lightPalette[name] || ''; } export function setColor(theme: Partial | undefined) { if (theme) { configProvider.setThemeColor(theme); } } export default color; ================================================ FILE: src/uni_modules/uview-pro/libs/function/colorGradient.ts ================================================ /** * 求两个颜色之间的渐变值 * @param startColor 开始的颜色 * @param endColor 结束的颜色 * @param step 颜色等分的份额 * @returns 渐变色数组 */ function colorGradient( startColor: string = 'rgb(0, 0, 0)', endColor: string = 'rgb(255, 255, 255)', step: number = 10 ): string[] { const startRGB = hexToRgb(startColor, false) as [number, number, number]; // 转换为rgb数组模式 const [startR, startG, startB] = startRGB; const endRGB = hexToRgb(endColor, false) as [number, number, number]; const [endR, endG, endB] = endRGB; const sR = (endR - startR) / step; // 总差值 const sG = (endG - startG) / step; const sB = (endB - startB) / step; const colorArr: string[] = []; for (let i = 0; i < step; i++) { // 计算每一步的hex值 const hex = rgbToHex( `rgb(${Math.round(sR * i + startR)},${Math.round(sG * i + startG)},${Math.round(sB * i + startB)})` ); colorArr.push(hex as string); } return colorArr; } /** * 将hex表示方式转换为rgb表示方式(返回rgb数组或字符串) * @param sColor hex或rgb字符串 * @param str 是否返回字符串 * @returns rgb数组或字符串 */ function hexToRgb(sColor: string, str: boolean = true): [number, number, number] | string { const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; sColor = sColor.toLowerCase(); if (sColor && reg.test(sColor)) { if (sColor.length === 4) { let sColorNew = '#'; for (let i = 1; i < 4; i += 1) { sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)); } sColor = sColorNew; } // 处理六位的颜色值 const sColorChange: [number, number, number] = [ parseInt('0x' + sColor.slice(1, 3)), parseInt('0x' + sColor.slice(3, 5)), parseInt('0x' + sColor.slice(5, 7)) ]; if (!str) { return sColorChange; } else { return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`; } } else if (/^(rgb|RGB)/.test(sColor)) { const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(','); return arr.map(val => Number(val)) as [number, number, number]; } else { return sColor; } } /** * rgb转hex * @param rgb rgb字符串或hex字符串 * @returns hex字符串 */ function rgbToHex(rgb: string): string | undefined { const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; if (/^(rgb|RGB)/.test(rgb)) { const aColor = rgb.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(','); let strHex = '#'; for (let i = 0; i < aColor.length; i++) { let hex = Number(aColor[i]).toString(16); hex = hex.length == 1 ? '0' + hex : hex; // 保证每个rgb的值为2位 strHex += hex; } if (strHex.length !== 7) { strHex = rgb; } return strHex; } else if (reg.test(rgb)) { const aNum = rgb.replace(/#/, '').split(''); if (aNum.length === 6) { return rgb; } else if (aNum.length === 3) { let numHex = '#'; for (let i = 0; i < aNum.length; i += 1) { numHex += aNum[i] + aNum[i]; } return numHex; } } else { return rgb; } // 默认返回原始值 return rgb; } /** * JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串 * @param color 十六进制色值或rgb字符串 * @param alpha 透明度 * @returns rgba字符串 */ function colorToRgba(color: string, alpha: number = 0.3): string { color = rgbToHex(color) as string; // 确保是hex格式 const reg = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/; let sColor = color.toLowerCase(); if (sColor && reg.test(sColor)) { if (sColor.length === 4) { let sColorNew = '#'; for (let i = 1; i < 4; i += 1) { sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)); } sColor = sColorNew; } const sColorChange: [number, number, number] = [ parseInt('0x' + sColor.slice(1, 3)), parseInt('0x' + sColor.slice(3, 5)), parseInt('0x' + sColor.slice(5, 7)) ]; return `rgba(${sColorChange.join(',')},${alpha})`; } else { return sColor; } } export default { colorGradient, hexToRgb, rgbToHex, colorToRgba }; ================================================ FILE: src/uni_modules/uview-pro/libs/function/debounce.ts ================================================ let timeout: ReturnType | null = null; /** * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数 * @param func 要执行的回调函数 * @param wait 延时的时间,单位ms,默认500 * @param immediate 是否立即执行,默认false * @returns void */ function debounce(func: () => void, wait: number = 500, immediate: boolean = false): void { // 清除定时器 if (timeout !== null) clearTimeout(timeout); // 立即执行,此类情况一般用不到 if (immediate) { const callNow = !timeout; timeout = setTimeout(() => { timeout = null; }, wait); if (callNow) typeof func === 'function' && func(); } else { // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 timeout = setTimeout(() => { typeof func === 'function' && func(); }, wait); } } export default debounce; ================================================ FILE: src/uni_modules/uview-pro/libs/function/deepClone.ts ================================================ // 判断arr是否为一个数组,返回一个bool值 function isArray(arr: any): arr is any[] { return Object.prototype.toString.call(arr) === '[object Array]'; } /** * 深度克隆 * @param obj 需要克隆的对象 * @param cache 用于处理循环引用的 WeakMap * @returns 克隆后的对象 */ function deepClone(obj: T, cache: WeakMap = new WeakMap()): T { if (obj === null || typeof obj !== 'object') return obj; if (cache.has(obj)) return cache.get(obj); let clone: any; if (obj instanceof Date) { clone = new Date(obj.getTime()); } else if (obj instanceof RegExp) { clone = new RegExp(obj); } else if (obj instanceof Map) { clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)])); } else if (obj instanceof Set) { clone = new Set(Array.from(obj, value => deepClone(value, cache))); } else if (Array.isArray(obj)) { clone = obj.map(value => deepClone(value, cache)); } else if (Object.prototype.toString.call(obj) === '[object Object]') { clone = Object.create(Object.getPrototypeOf(obj)); cache.set(obj, clone); for (const [key, value] of Object.entries(obj)) { clone[key] = deepClone(value, cache); } } else { clone = Object.assign({}, obj); } cache.set(obj, clone); return clone; } export default deepClone; ================================================ FILE: src/uni_modules/uview-pro/libs/function/deepMerge.ts ================================================ import deepClone from './deepClone'; /** * JS对象深度合并 * @param target 目标对象 * @param source 源对象 * @returns 合并后的对象 */ function deepMerge(target: T = {} as T, source: S = {} as S): T & S { target = deepClone(target); if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target as T & S; const merged: any = Array.isArray(target) ? target.slice() : Object.assign({}, target); for (const prop in source) { if (!Object.prototype.hasOwnProperty.call(source, prop)) continue; const sourceValue = (source as any)[prop]; const targetValue = merged[prop]; if (sourceValue instanceof Date) { merged[prop] = new Date(sourceValue); } else if (sourceValue instanceof RegExp) { merged[prop] = new RegExp(sourceValue); } else if (sourceValue instanceof Map) { merged[prop] = new Map(sourceValue); } else if (sourceValue instanceof Set) { merged[prop] = new Set(sourceValue); } else if (typeof sourceValue === 'object' && sourceValue !== null) { merged[prop] = deepMerge(targetValue, sourceValue); } else { merged[prop] = sourceValue; } } return merged as T & S; } export default deepMerge; ================================================ FILE: src/uni_modules/uview-pro/libs/function/getParent.ts ================================================ // 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法 // this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx interface VueInstance { $parent?: VueInstance; $options?: { name?: string }; [key: string]: any; } /** * 获取父组件参数 * @param this 当前组件实例 * @param name 父组件name * @param keys 需要获取的参数名数组或对象 * @returns 父组件参数对象 */ export default function getParent( this: VueInstance, name: string, keys: string[] | Record ): Record { let parent = this.$parent; // 通过while历遍,这里主要是为了H5需要多层解析的问题 while (parent) { // 父组件 if (parent.$options?.name !== name) { // 如果组件的name不相等,继续上一级寻找 parent = parent.$parent; } else { const data: Record = {}; // 判断keys是否数组,如果传过来的是一个数组,那么直接使用数组元素值当做键值去父组件寻找 if (Array.isArray(keys)) { keys.forEach(val => { data[val] = parent?.[val] ? parent[val] : ''; }); } else { // 历遍传过来的对象参数 for (const i in keys) { // 如果子组件有此值则用,无此值则用父组件的值 // 判断是否空数组,如果是,则用父组件的值,否则用子组件的值 if (Array.isArray(keys[i])) { if (keys[i].length) { data[i] = keys[i]; } else { data[i] = parent[i]; } } else if (keys[i] && keys[i].constructor === Object) { // 判断是否对象,如果是对象,且有属性,那么使用子组件的值,否则使用父组件的值 if (Object.keys(keys[i]).length) { data[i] = keys[i]; } else { data[i] = parent[i]; } } else { // 只要子组件有传值,即使是false值,也是“传值”了,也需要覆盖父组件的同名参数 data[i] = keys[i] || keys[i] === false ? keys[i] : parent[i]; } } } return data; } } return {}; } ================================================ FILE: src/uni_modules/uview-pro/libs/function/getRect.ts ================================================ /** * 获取元素的位置信息 * @param {any} selector 选择器 * @param {boolean} all 是否获取所有匹配元素 * @returns {Promise} 返回一个 Promise,解析为元素的位置信息 */ import { getCurrentInstance } from 'vue'; export default function (selector: any, _instance: any = null, all: boolean = false): Promise { const instance = _instance || getCurrentInstance(); return new Promise(resolve => { uni.createSelectorQuery() .in(instance?.proxy) [all ? 'selectAll' : 'select'](selector) .boundingClientRect((rect: any) => { if (all && Array.isArray(rect) && rect.length) { resolve(rect); } if (!all && rect) { resolve(rect); } }) .exec(); }); } ================================================ FILE: src/uni_modules/uview-pro/libs/function/guid.ts ================================================ /** * 本算法来源于简书开源代码,详见:https://www.jianshu.com/p/fdbf293d0a85 * 全局唯一标识符(uuid,Globally Unique Identifier),也称作 uuid(Universally Unique IDentifier) * 一般用于多个组件之间,给它一个唯一的标识符,或者v-for循环的时候,如果使用数组的index可能会导致更新列表出现问题 * 最可能的情况是左滑删除item或者对某条信息流"不喜欢"并去掉它的时候,会导致组件内的数据可能出现错乱 * v-for的时候,推荐使用后端返回的id而不是循环的index * @param len uuid的长度,默认32 * @param firstU 将返回的首字母置为"u",默认true * @param radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制 * @returns 生成的uuid字符串 */ function guid(len: number = 32, firstU: boolean = true, radix?: number): string { const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); const uuid: string[] = []; const base = radix || chars.length; if (len) { // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * base)]; } else { let r: number; // rfc4122标准要求返回的uuid中,某些位为固定的字符 uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; uuid[14] = '4'; for (let i = 0; i < 36; i++) { if (!uuid[i]) { r = 0 | (Math.random() * 16); uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]; } } } // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guid不能用作id或者class if (firstU) { uuid.shift(); return 'u' + uuid.join(''); } else { return uuid.join(''); } } export default guid; ================================================ FILE: src/uni_modules/uview-pro/libs/function/md5.ts ================================================ /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ /* * Configurable variables. You may need to tweak these to be compatible with * the server-side, but the defaults work in most cases. */ let hexcase: number = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ let b64pad: string = ''; /* base-64 pad character. "=" for strict RFC compliance */ /** * 这些是通常需要调用的函数 * @param s 输入字符串 * @returns 十六进制/BASE64/任意编码的MD5字符串 */ function hex_md5(s: string): string { return rstr2hex(rstr_md5(str2rstr_utf8(s))); } function b64_md5(s: string): string { return rstr2b64(rstr_md5(str2rstr_utf8(s))); } function any_md5(s: string, e: string): string { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); } function hex_hmac_md5(k: string, d: string): string { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } function b64_hmac_md5(k: string, d: string): string { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } function any_hmac_md5(k: string, d: string, e: string): string { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); } /** * 执行简单自测,判断 VM 是否正常 * @returns 是否通过测试 */ function md5_vm_test(): boolean { return hex_md5('abc').toLowerCase() == '900150983cd24fb0d6963f7d28e17f72'; } /** * 计算原始字符串的 MD5 * @param s 原始字符串 * @returns MD5 结果字符串 */ function rstr_md5(s: string): string { return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); } /** * 计算 HMAC-MD5 * @param key 密钥 * @param data 数据 * @returns HMAC-MD5 结果字符串 */ function rstr_hmac_md5(key: string, data: string): string { let bkey: number[] = rstr2binl(key); if (bkey.length > 16) bkey = binl_md5(bkey, key.length * 8); const ipad: number[] = Array(16), opad: number[] = Array(16); for (let i = 0; i < 16; i++) { ipad[i] = bkey[i] ^ 0x36363636; opad[i] = bkey[i] ^ 0x5c5c5c5c; } const hash: number[] = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); } /** * 原始字符串转十六进制字符串 * @param input 输入字符串 * @returns 十六进制字符串 */ function rstr2hex(input: string): string { try { hexcase; } catch (e) { hexcase = 0; } const hex_tab: string = hexcase ? '0123456789ABCDEF' : '0123456789abcdef'; let output = ''; let x: number; for (let i = 0; i < input.length; i++) { x = input.charCodeAt(i); output += hex_tab.charAt((x >>> 4) & 0x0f) + hex_tab.charAt(x & 0x0f); } return output; } /** * 原始字符串转 BASE64 字符串 * @param input 输入字符串 * @returns BASE64 字符串 */ function rstr2b64(input: string): string { try { b64pad; } catch (e) { b64pad = ''; } const tab: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; let output = ''; const len: number = input.length; for (let i = 0; i < len; i += 3) { const triplet: number = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0); for (let j = 0; j < 4; j++) { if (i * 8 + j * 6 > input.length * 8) output += b64pad; else output += tab.charAt((triplet >>> (6 * (3 - j))) & 0x3f); } } return output; } /** * 原始字符串转任意编码字符串 * @param input 输入字符串 * @param encoding 编码表 * @returns 编码后的字符串 */ function rstr2any(input: string, encoding: string): string { const divisor: number = encoding.length; let i: number, j: number, q: number, x: number, quotient: number[]; /* Convert to an array of 16-bit big-endian values, forming the dividend */ let dividend: number[] = Array(Math.ceil(input.length / 2)); for (i = 0; i < dividend.length; i++) { dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); } /* * Repeatedly perform a long division. The binary array forms the dividend, * the length of the encoding is the divisor. Once computed, the quotient * forms the dividend for the next step. All remainders are stored for later * use. */ const full_length: number = Math.ceil((input.length * 8) / (Math.log(encoding.length) / Math.log(2))); const remainders: number[] = Array(full_length); for (j = 0; j < full_length; j++) { quotient = []; x = 0; for (i = 0; i < dividend.length; i++) { x = (x << 16) + dividend[i]; q = Math.floor(x / divisor); x -= q * divisor; if (quotient.length > 0 || q > 0) quotient[quotient.length] = q; } remainders[j] = x; dividend = quotient; } /* Convert the remainders to the output string */ let output = ''; for (i = remainders.length - 1; i >= 0; i--) output += encoding.charAt(remainders[i]); return output; } /** * 字符串转 UTF-8 编码 * @param input 输入字符串 * @returns UTF-8 编码字符串 */ function str2rstr_utf8(input: string): string { let output = ''; let i = -1; let x: number, y: number; while (++i < input.length) { /* Decode utf-16 surrogate pairs */ x = input.charCodeAt(i); y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; if (0xd800 <= x && x <= 0xdbff && 0xdc00 <= y && y <= 0xdfff) { x = 0x10000 + ((x & 0x03ff) << 10) + (y & 0x03ff); i++; } /* Encode output as utf-8 */ if (x <= 0x7f) output += String.fromCharCode(x); else if (x <= 0x7ff) output += String.fromCharCode(0xc0 | ((x >>> 6) & 0x1f), 0x80 | (x & 0x3f)); else if (x <= 0xffff) output += String.fromCharCode(0xe0 | ((x >>> 12) & 0x0f), 0x80 | ((x >>> 6) & 0x3f), 0x80 | (x & 0x3f)); else if (x <= 0x1fffff) output += String.fromCharCode( 0xf0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3f), 0x80 | ((x >>> 6) & 0x3f), 0x80 | (x & 0x3f) ); } return output; } /** * 字符串转 UTF-16LE 编码 * @param input 输入字符串 * @returns UTF-16LE 编码字符串 */ function str2rstr_utf16le(input: string): string { let output = ''; for (let i = 0; i < input.length; i++) output += String.fromCharCode(input.charCodeAt(i) & 0xff, (input.charCodeAt(i) >>> 8) & 0xff); return output; } /** * 字符串转 UTF-16BE 编码 * @param input 输入字符串 * @returns UTF-16BE 编码字符串 */ function str2rstr_utf16be(input: string): string { let output = ''; for (let i = 0; i < input.length; i++) output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xff, input.charCodeAt(i) & 0xff); return output; } /** * 原始字符串转小端字数组 * @param input 输入字符串 * @returns 小端字数组 */ function rstr2binl(input: string): number[] { const output: number[] = Array(input.length >> 2); for (let i = 0; i < output.length; i++) output[i] = 0; for (let i = 0; i < input.length * 8; i += 8) output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32; return output; } /** * 小端字数组转字符串 * @param input 小端字数组 * @returns 字符串 */ function binl2rstr(input: number[]): string { let output = ''; for (let i = 0; i < input.length * 32; i += 8) output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff); return output; } /** * 计算小端字数组的 MD5 * @param x 小端字数组 * @param len 位长度 * @returns MD5 结果数组 */ function binl_md5(x: number[], len: number): number[] { /* append padding */ x[len >> 5] |= 0x80 << len % 32; x[(((len + 64) >>> 9) << 4) + 14] = len; let a = 1732584193; let b = -271733879; let c = -1732584194; let d = 271733878; for (let i = 0; i < x.length; i += 16) { const olda = a; const oldb = b; const oldc = c; const oldd = d; a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936); d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302); a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222); c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844); d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return [a, b, c, d]; } /** * 四种基本操作 */ function md5_cmn(q: number, a: number, b: number, x: number, s: number, t: number): number { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); } function md5_ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number { return md5_cmn((b & c) | (~b & d), a, b, x, s, t); } function md5_gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number { return md5_cmn((b & d) | (c & ~d), a, b, x, s, t); } function md5_hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number { return md5_cmn(b ^ c ^ d, a, b, x, s, t); } function md5_ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number): number { return md5_cmn(c ^ (b | ~d), a, b, x, s, t); } /** * 安全整数加法,防止溢出 * @param x 整数 * @param y 整数 * @returns 加法结果 */ function safe_add(x: number, y: number): number { const lsw: number = (x & 0xffff) + (y & 0xffff); const msw: number = (x >> 16) + (y >> 16) + (lsw >> 16); return (msw << 16) | (lsw & 0xffff); } /** * 左移位操作 * @param num 数字 * @param cnt 位数 * @returns 结果 */ function bit_rol(num: number, cnt: number): number { return (num << cnt) | (num >>> (32 - cnt)); } /** * 计算字符串的 MD5 值 * @param str 输入字符串 * @returns MD5 十六进制字符串 */ function md5(str: string): string { return hex_md5(str); } export default { md5 }; ================================================ FILE: src/uni_modules/uview-pro/libs/function/parent.ts ================================================ import { type ComponentInternalInstance, getCurrentInstance } from 'vue'; export function parent(componentName?: string, _instance: ComponentInternalInstance | null | undefined = null) { const instance = _instance || getCurrentInstance(); let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined); while (parent) { const name = (parent.type as any)?.name as string | undefined; if (name === componentName) { return parent; } parent = parent.parent; } return null; } export function parentData(componentName?: string, _instance: ComponentInternalInstance | null | undefined = null) { const instance = _instance || getCurrentInstance(); const findParent = parent(componentName, instance); return findParent ? findParent.exposed : null; } ================================================ FILE: src/uni_modules/uview-pro/libs/function/queryParams.ts ================================================ /** * 对象转url参数 * @param data 对象参数 * @param isPrefix 是否自动加上"?",默认true * @param arrayFormat 数组参数格式,indices/brackets/repeat/comma,默认brackets * @returns url参数字符串 */ function queryParams( data: Record = {}, isPrefix: boolean = true, arrayFormat: 'indices' | 'brackets' | 'repeat' | 'comma' = 'brackets' ): string { const prefix = isPrefix ? '?' : ''; const _result: string[] = []; if (!['indices', 'brackets', 'repeat', 'comma'].includes(arrayFormat)) arrayFormat = 'brackets'; for (const key in data) { const value = data[key]; // 去掉为空的参数 if (['', undefined, null].includes(value)) { continue; } // 如果值为数组,另行处理 if (Array.isArray(value)) { // e.g. {ids: [1, 2, 3]} switch (arrayFormat) { case 'indices': // 结果: ids[0]=1&ids[1]=2&ids[2]=3 for (let i = 0; i < value.length; i++) { _result.push(`${key}[${i}]=${value[i]}`); } break; case 'brackets': // 结果: ids[]=1&ids[]=2&ids[]=3 value.forEach((_value: any) => { _result.push(`${key}[]=${_value}`); }); break; case 'repeat': // 结果: ids=1&ids=2&ids=3 value.forEach((_value: any) => { _result.push(`${key}=${_value}`); }); break; case 'comma': // 结果: ids=1,2,3 let commaStr = ''; value.forEach((_value: any) => { commaStr += (commaStr ? ',' : '') + _value; }); _result.push(`${key}=${commaStr}`); break; default: value.forEach((_value: any) => { _result.push(`${key}[]=${_value}`); }); } } else { _result.push(`${key}=${value}`); } } return _result.length ? prefix + _result.join('&') : ''; } export default queryParams; ================================================ FILE: src/uni_modules/uview-pro/libs/function/random.ts ================================================ /** * 生成指定范围的随机整数 * @param min 最小值(包含) * @param max 最大值(包含) * @returns 随机整数 */ function random(min: number, max: number): number { if (min >= 0 && max > 0 && max >= min) { const gab = max - min + 1; return Math.floor(Math.random() * gab + min); } else { return 0; } } export default random; ================================================ FILE: src/uni_modules/uview-pro/libs/function/randomArray.ts ================================================ /** * 打乱数组顺序 * @param array 需要打乱的数组 * @returns 打乱后的新数组 */ function randomArray(array: T[] = []): T[] { // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.5大于或者小于0 return array.sort(() => Math.random() - 0.5); } export default randomArray; ================================================ FILE: src/uni_modules/uview-pro/libs/function/route.ts ================================================ /** * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷 * 并且带有路由拦截功能 */ interface RouterConfig { type?: string; url?: string; delta?: number; params?: Record; animationType?: string; animationDuration?: number; intercept?: boolean; } declare const uni: any; // 声明uni对象,避免ts报错 class Router { config: RouterConfig; // route: (options?: string | RouterConfig, params?: Record) => Promise; constructor() { // 原始属性定义 this.config = { type: 'navigateTo', url: '', delta: 1, // navigateBack页面后退时,回退的层数 params: {}, // 传递的参数 animationType: 'pop-in', // 窗口动画,只在APP有效 animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效 intercept: false // 是否需要拦截 }; // 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文 // 这里在构造函数中进行this绑定 this.route = this.route.bind(this); } // 判断url前面是否有"/",如果没有则加上,否则无法跳转 addRootPath(url: string): string { return url[0] === '/' ? url : `/${url}`; } // 整合路由参数 mixinParam(url: string, params: Record): string { url = url && this.addRootPath(url); // 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary" // 如果有url中有get参数,转换后无需带上"?" let query = ''; if (/.*\/.*\?.*=.*/.test(url)) { // object对象转为get类型的参数 query = uni.$u.queryParams(params, false); // 因为已有get参数,所以后面拼接的参数需要带上"&"隔开 return url + '&' + query; } else { // 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号 query = uni.$u.queryParams(params); return url + query; } } /** * 路由跳转主方法 * @param options 跳转配置或url字符串 * @param params 跳转参数 */ async route(options: string | RouterConfig = {}, params: Record = {}): Promise { let mergeConfig: RouterConfig = {}; if (typeof options === 'string') { // 如果options为字符串,则为route(url, params)的形式 mergeConfig.url = this.mixinParam(options, params); mergeConfig.type = 'navigateTo'; } else { mergeConfig = uni.$u.deepMerge(this.config, options); // 否则正常使用mergeConfig中的url和params进行拼接 mergeConfig.url = this.mixinParam(options.url || '', options.params || {}); } if (params.intercept) { this.config.intercept = params.intercept; } // params参数也带给拦截器 mergeConfig.params = params; // 合并内外部参数 mergeConfig = uni.$u.deepMerge(this.config, mergeConfig); // 判断用户是否定义了拦截器 if (uni.$u.routeIntercept && typeof uni.$u.routeIntercept === 'function') { // 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转 const isNext = await new Promise(resolve => { uni.$u.routeIntercept(mergeConfig, resolve); }); // 如果isNext为true,则执行路由跳转 isNext && this.openPage(mergeConfig); } else { this.openPage(mergeConfig); } } // 执行路由跳转 openPage(config: RouterConfig): void { const { url = '', type = '', delta = 1, animationDuration = 300 } = config; if (type == 'navigateTo' || type == 'to') { uni.navigateTo({ url, animationDuration }); } if (type == 'redirectTo' || type == 'redirect') { uni.redirectTo({ url }); } if (type == 'switchTab' || type == 'tab') { uni.switchTab({ url }); } if (type == 'reLaunch' || type == 'launch') { uni.reLaunch({ url }); } if (type == 'navigateBack' || type == 'back') { uni.navigateBack({ delta }); } } } export default new Router().route; ================================================ FILE: src/uni_modules/uview-pro/libs/function/styleUtils.ts ================================================ import type { CSSProperties } from 'vue'; import trim from './trim'; import test from './test'; function isValidValue(value: any): boolean { if (test.isEmpty(value)) return false; if (typeof value === 'string') { const trimmed = trim(value).toLowerCase(); return trimmed !== 'null' && trimmed !== 'undefined' && trimmed !== ''; } return true; } /** * 将 CSS 字符串解析为对象 */ function cssStrToObj(str: string): object { const result = {}; if (!isValidValue(str)) return result; const styleStr = trim(String(str)); if (!isValidValue(styleStr)) return result; const declarations = styleStr.split(';'); declarations.forEach(decl => { const [prop, ...values] = decl.split(':').map(s => s.trim()); const value = values.join(':'); if (prop && value) { const camelProp = prop.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase()); (result as Record)[camelProp] = value; } }); return result; } /** * 将 CSS 对象转换为 CSS 字符串 */ function cssObjToStr(obj: object): string { if (!isValidValue(obj) || typeof obj !== 'object') return ''; return ( Object.entries(obj) .map(([key, value]) => { if (!isValidValue(value)) return ''; // 驼峰转短横线 const kebab = key.replace(/([A-Z])/g, '-$1').toLowerCase(); return `${kebab}: ${value}`; }) .filter(Boolean) .join('; ') + ';' ); } /** * 合并多个 CSS 输入(对象或字符串),返回一个 CSS 对象 */ export function mergeStyles(...args: (object | string)[]): CSSProperties { const result = {} as Record; for (let i = 0; i < args.length; i++) { const arg = args[i]; if (!isValidValue(arg)) return result as CSSProperties; if (typeof arg === 'string') { Object.assign(result, cssStrToObj(arg)); } else if (test.object(arg)) { const cleanedObj: Record = {}; Object.keys(arg).forEach(key => { const value = (arg as Record)[key]; if (isValidValue(value)) { // 有效 cleanedObj[key] = value; } }); Object.assign(result, cleanedObj); } } return result; } /** * 合并为 CSS 字符串 */ export function mergeCssStrings(...args: (object | string)[]): string { const obj = mergeStyles(...args); return cssObjToStr(obj); } ================================================ FILE: src/uni_modules/uview-pro/libs/function/sys.ts ================================================ /** * 获取当前操作系统平台 * @returns 平台字符串,如 'ios'、'android'、'windows' 等 */ export function os(): string { return uni.getSystemInfoSync().platform; } /** * 获取系统信息 * @returns uniapp 系统信息对象 */ export function sys(): UniApp.GetSystemInfoResult { return uni.getSystemInfoSync(); } ================================================ FILE: src/uni_modules/uview-pro/libs/function/test.ts ================================================ /** * 验证电子邮箱格式 */ function email(value: string): boolean { return /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/.test( value ); } /** * 验证手机格式 */ function mobile(value: string): boolean { return /^1[3-9]\d{9}$/.test(value); } /** * 验证URL格式 */ function url(value: string): boolean { return /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/.test(value); } /** * 验证日期格式 */ function date(value: string): boolean { return !/Invalid|NaN/.test(new Date(value).toString()); } /** * 验证ISO类型的日期格式 */ function dateISO(value: string): boolean { return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value); } /** * 验证十进制数字 */ function number(value: string): boolean { return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value); } /** * 验证整数 */ function digits(value: string): boolean { return /^\d+$/.test(value); } /** * 验证身份证号码 */ function idCard(value: string): boolean { return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value); } /** * 是否车牌号 */ function carNo(value: string): boolean { // 新能源车牌 const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/; // 旧车牌 const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/; if (value.length === 7) { return creg.test(value); } else if (value.length === 8) { return xreg.test(value); } else { return false; } } /** * 金额,只允许2位小数 */ function amount(value: string): boolean { //金额,只允许保留两位小数 return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value); } /** * 中文 */ function chinese(value: string): boolean { let reg = /^[\u4e00-\u9fa5]+$/gi; return reg.test(value); } /** * 只能输入字母 */ function letter(value: string): boolean { return /^[a-zA-Z]*$/.test(value); } /** * 只能是字母或者数字 */ function enOrNum(value: string): boolean { //英文或者数字 let reg = /^[0-9a-zA-Z]*$/g; return reg.test(value); } /** * 验证是否包含某个值 */ function contains(value: string, param: string): boolean { return value.indexOf(param) >= 0; } /** * 验证一个值范围[min, max] */ function range(value: number, param: [number, number]): boolean { return value >= param[0] && value <= param[1]; } /** * 验证一个长度范围[min, max] */ function rangeLength(value: string, param: [number, number]): boolean { return value.length >= param[0] && value.length <= param[1]; } /** * 是否固定电话 */ function landline(value: string): boolean { let reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/; return reg.test(value); } /** * 判断是否为空 */ function empty(value: any): boolean { switch (typeof value) { case 'undefined': return true; case 'string': if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true; break; case 'boolean': if (!value) return true; break; case 'number': if (0 === value || isNaN(value)) return true; break; case 'object': if (null === value || value.length === 0) return true; for (var i in value) { return false; } return true; } return false; } /** * 是否json字符串 */ function jsonString(value: string): boolean { if (typeof value == 'string') { try { var obj = JSON.parse(value); if (typeof obj == 'object' && obj) { return true; } else { return false; } } catch (e) { return false; } } return false; } /** * 是否数组 */ function array(value: any): boolean { if (typeof Array.isArray === 'function') { return Array.isArray(value); } else { return Object.prototype.toString.call(value) === '[object Array]'; } } /** * 是否对象 */ function object(value: any): boolean { return Object.prototype.toString.call(value) === '[object Object]'; } /** * 是否短信验证码 */ function code(value: string, len: number = 6): boolean { return new RegExp(`^\\d{${len}}$`).test(value); } /** * 是否函数方法 * @param {Object} value */ function func(value: any) { return typeof value === 'function'; } /** * 是否promise对象 * @param {Object} value */ function promise(value: any) { return object(value) && func(value.then) && func(value.catch); } /** 是否图片格式 * @param {Object} value */ function image(value: any) { const newValue = value.split('?')[0]; const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i; return IMAGE_REGEXP.test(newValue); } /** * 是否视频格式 * @param {Object} value */ function video(value: any) { const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i; return VIDEO_REGEXP.test(value); } /** * 是否为正则对象 * @param {Object} * @return {Boolean} */ function regExp(o: any) { return o && Object.prototype.toString.call(o) === '[object RegExp]'; } /** * 验证字符串 */ function string(value: any) { return typeof value === 'string'; } export default { email, mobile, url, date, dateISO, number, digits, idCard, carNo, amount, chinese, letter, enOrNum, contains, range, rangeLength, empty, isEmpty: empty, jsonString, landline, object, array, code, func, promise, video, image, regExp, string }; ================================================ FILE: src/uni_modules/uview-pro/libs/function/throttle.ts ================================================ let timer: ReturnType | undefined; let flag: boolean | undefined; /** * 节流原理:在一定时间内,只能触发一次 * @param func 要执行的回调函数 * @param wait 延时的时间,单位ms,默认500 * @param immediate 是否立即执行,默认true * @returns void */ function throttle(func: () => void, wait: number = 500, immediate: boolean = true): void { if (immediate) { if (!flag) { flag = true; // 如果是立即执行,则在wait毫秒内开始时执行 typeof func === 'function' && func(); timer = setTimeout(() => { flag = false; }, wait); } } else { if (!flag) { flag = true; // 如果是非立即执行,则在wait毫秒内的结束处执行 timer = setTimeout(() => { flag = false; typeof func === 'function' && func(); }, wait); } } } export default throttle; ================================================ FILE: src/uni_modules/uview-pro/libs/function/timeFormat.ts ================================================ // padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序 // 所以这里做一个兼容polyfill的兼容处理 if (!String.prototype.padStart) { // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 String.prototype.padStart = function (this: string, maxLength: number, fillString: string = ' '): string { if (Object.prototype.toString.call(fillString) !== '[object String]') throw new TypeError('fillString must be String'); let str = this; if (str.length >= maxLength) return String(str); let fillLength = maxLength - str.length, times = Math.ceil(fillLength / fillString.length); while ((times >>= 1)) { fillString += fillString; if (times === 1) { fillString += fillString; } } return fillString.slice(0, fillLength) + str; }; } /** * 时间格式化 * @param dateTime 时间戳、Date对象或null,默认当前时间 * @param fmt 格式化字符串,默认 'yyyy-mm-dd' * @returns 格式化后的时间字符串 */ function timeFormat(dateTime: number | string | Date | null = null, fmt: string = 'yyyy-mm-dd'): string { // 如果为null,则格式化当前时间 if (!dateTime) dateTime = Number(new Date()); // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 if (typeof dateTime === 'number' || typeof dateTime === 'string') { if (dateTime.toString().length == 10) dateTime = Number(dateTime) * 1000; } const date = new Date(dateTime); let ret: RegExpExecArray | null; const opt: Record = { 'y+': date.getFullYear().toString(), // 年 'm+': (date.getMonth() + 1).toString(), // 月 'd+': date.getDate().toString(), // 日 'h+': date.getHours().toString(), // 时 'M+': date.getMinutes().toString(), // 分 's+': date.getSeconds().toString() // 秒 // 有其他格式化字符需求可以继续添加,必须转化成字符串 }; for (const k in opt) { ret = new RegExp('(' + k + ')').exec(fmt); if (ret) { fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0')); } } return fmt; } export default timeFormat; ================================================ FILE: src/uni_modules/uview-pro/libs/function/timeFrom.ts ================================================ import timeFormat from './timeFormat'; /** * 时间戳转为多久之前 * @param dateTime 时间戳、Date对象或null,默认当前时间 * @param format 时间格式字符串或false,超出范围时返回指定格式,否则返回多久以前 * @returns 格式化后的时间字符串 */ function timeFrom(dateTime: number | string | Date | null = null, format: string | false = 'yyyy-mm-dd'): string { // 如果为null,则格式化当前时间 if (!dateTime) dateTime = Number(new Date()); // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 if (typeof dateTime === 'number' || typeof dateTime === 'string') { if (dateTime.toString().length == 10) dateTime = Number(dateTime) * 1000; } const timestamp = +new Date(Number(dateTime)); const timer = (Number(new Date()) - timestamp) / 1000; // 如果小于5分钟,则返回"刚刚",其他以此类推 let tips = ''; switch (true) { case timer < 300: tips = '刚刚'; break; case timer >= 300 && timer < 3600: tips = parseInt(String(timer / 60)) + '分钟前'; break; case timer >= 3600 && timer < 86400: tips = parseInt(String(timer / 3600)) + '小时前'; break; case timer >= 86400 && timer < 2592000: tips = parseInt(String(timer / 86400)) + '天前'; break; default: // 如果format为false,则无论什么时间戳,都显示xx之前 if (format === false) { if (timer >= 2592000 && timer < 365 * 86400) { tips = parseInt(String(timer / (86400 * 30))) + '个月前'; } else { tips = parseInt(String(timer / (86400 * 365))) + '年前'; } } else { tips = timeFormat(timestamp, format as string); } } return tips; } export default timeFrom; ================================================ FILE: src/uni_modules/uview-pro/libs/function/toast.ts ================================================ /** * 显示无图标的 Toast 提示 * @param title 提示文本 * @param option 显示时长(毫秒)默认1500 /显示图标,默认为none, */ function toast(title: string, option: number | string | Record = 1500): void { uni.showToast({ title: title, icon: typeof option === 'string' ? option : typeof option === 'object' ? option.icon || 'none' : 'none', duration: typeof option === 'number' ? option : typeof option === 'object' ? option.duration || '1500' : 1500 }); } export default toast; ================================================ FILE: src/uni_modules/uview-pro/libs/function/trim.ts ================================================ /** * 去除字符串空格 * @param str 输入字符串 * @param pos 去除位置,'both' | 'left' | 'right' | 'all',默认'both' * @returns 去除空格后的字符串 */ function trim(str: string, pos: 'both' | 'left' | 'right' | 'all' = 'both'): string { if (pos === 'both') { return str.replace(/^\s+|\s+$/g, ''); } else if (pos === 'left') { return str.replace(/^\s*/, ''); } else if (pos === 'right') { return str.replace(/(\s*$)/g, ''); } else if (pos === 'all') { return str.replace(/\s+/g, ''); } else { return str; } } export default trim; ================================================ FILE: src/uni_modules/uview-pro/libs/function/type2icon.ts ================================================ import type { ThemeType } from '../../types/global'; /** * 根据主题type值,获取对应的图标 * @param type 主题名称, primary|info|error|warning|success,默认success * @param fill 是否使用fill填充实体的图标,默认false * @returns 图标名称字符串 */ function type2icon(type: ThemeType = 'success', fill: boolean = false): string { // 如果非预置值,默认为success if (!['primary', 'info', 'error', 'warning', 'success'].includes(type)) type = 'success'; let iconName = ''; // 目前(2019-12-12),info和primary使用同一个图标 switch (type) { case 'primary': iconName = 'info-circle'; break; case 'info': iconName = 'info-circle'; break; case 'error': iconName = 'close-circle'; break; case 'warning': iconName = 'error-circle'; break; case 'success': iconName = 'checkmark-circle'; break; default: iconName = 'checkmark-circle'; } // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 if (fill) iconName += '-fill'; return iconName; } export default type2icon; ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/index.ts ================================================ export * from './useEmitter'; export * from './useRect'; export * from './useCompRelation'; export * from './useTheme'; export * from './useColor'; export * from './useLocale'; export * from './useDebounce'; export * from './useThrottle'; export * from './useToast'; export * from './useModal'; ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useColor.ts ================================================ /** * 响应式颜色管理 composable * 提供响应式的颜色访问,支持主题切换和暗黑模式 * * 使用方式: * const { color, getColor } = useColor() * // color 是响应式的,可以直接在模板中使用 * // getColor('primary') 返回响应式的颜色值 */ import { computed, type ComputedRef } from 'vue'; import type { ColorType } from '../../types/global'; import configProvider from '../util/config-provider'; /** * 响应式颜色 composable * 返回响应式的颜色对象和获取颜色的方法 */ export function useColor() { // 从 configProvider 获取当前主题的响应式引用 const currentTheme = configProvider.currentThemeRef; const darkModeRef = configProvider.darkModeRef; /** * 获取当前激活模式下的颜色对象(响应式) */ const color = computed(() => { const theme = currentTheme.value; if (!theme) return {} as Record; const isDark = configProvider.isInDarkMode(); const palette = isDark && theme.darkColor && Object.keys(theme.darkColor).length ? theme.darkColor : theme.color || {}; // 合并默认值,确保所有颜色都有值 const defaultPalette = isDark ? (configProvider as any).baseDarkColorTokens || {} : (configProvider as any).baseColorTokens || {}; return { ...defaultPalette, ...palette } as Record; }); /** * 获取指定颜色(响应式) * @param name 颜色名称 * @returns 颜色值 */ const getColor = (name: ColorType): ComputedRef => { return computed(() => { return color.value[name] || ''; }); }; return { color, getColor }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useCompRelation.ts ================================================ import { ref, reactive, getCurrentInstance, onUnmounted, nextTick, computed, onMounted } from 'vue'; import { isDebugMode } from '../config/config'; // 类型定义 interface ParentContext { name: string; addChild: (child: ChildContext) => void; removeChild: (childId: string) => void; broadcast: (event: string, data?: any, childIds?: string | string[]) => void; broadcastToChildren: (componentName: string, event: string, data?: any) => void; getChildren: () => ChildContext[]; getExposed: () => Record; getChildExposed: (childId: string) => Record; getChildrenExposed: () => Array<{ id: string; name: string; exposed: Record }>; getInstance: () => any; } interface ChildContext { id: string; name: string; getChildIndex: () => number; emitToParent: (event: string, data?: any) => void; getParentExposed: () => Record; getInstance: () => any; getExposed: () => Record; } // 符号定义 const PARENT_CONTEXT_SYMBOL = Symbol('parent_context'); // 每个组件实例的 child id 缓存,避免同个组件中多次调用 useChildren 时生成不同 id const CHILD_ID_SYMBOL = Symbol('child_id'); /** * 生成实例唯一ID */ function generateInstanceId(componentName: string): string { return `${componentName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } /** * 查找父组件实例 */ function findParentInstance(name: string, instance: any): any { if (!instance) return null; let parent = instance.parent; while (parent) { const parentName = parent.type?.name || parent.type?.__name; if (parentName === name) { return parent; } parent = parent.parent; } return null; } /** * 获取父组件上下文 */ function getParentContext(name: string, instance: any): ParentContext | null { const parentInstance = findParentInstance(name, instance); return parentInstance?.proxy?.[PARENT_CONTEXT_SYMBOL] || null; } /** * 递归查找所有指定名称的子组件 */ function findAllChildComponents(componentName: string, instance: any): any[] { const components: any[] = []; function traverse(currentInstance: any) { if (!currentInstance?.subTree) return; const subTree = currentInstance.subTree?.children || []; const children = Array.isArray(subTree) ? subTree : [subTree]; children.forEach((vnode: any) => { const child = vnode.component; if (!child) return; const name = child.type?.name || child.type?.__name; if (name === componentName) { components.push(child); } traverse(child); }); } traverse(instance); if (isDebugMode()) console.log(`Found ${components.length} ${componentName} components`); return components; } /** * 父组件 Hook */ export function useParent(componentName?: string) { const instance = getCurrentInstance(); if (!instance) { throw new Error('useParent must be called within setup function'); } const name = componentName || instance.type.name || instance.type.__name; if (!name) { throw new Error('Component name is required for useParent'); } const children = reactive([]); const childrenMap = new Map(); const broadcast = (event: string, data?: any, childIds?: string | string[]) => { const targetChildren = childIds ? ((Array.isArray(childIds) ? childIds : [childIds]) .map(id => childrenMap.get(id)) .filter(Boolean) as ChildContext[]) : Array.from(childrenMap.values()); if (isDebugMode()) console.log(`Parent ${name} broadcasting event: ${event} to ${targetChildren.length} children`); targetChildren.forEach(child => { const exposed = child.getExposed(); if (exposed && typeof exposed[event] === 'function') { try { exposed[event](data); } catch (error) { if (isDebugMode('error')) console.error(`Error calling child method ${event}:`, error); } } }); }; const broadcastToChildren = (componentName: string, event: string, data?: any) => { if (isDebugMode()) console.log(`Parent ${name} broadcasting event: ${event} to all ${componentName} components`); const childComponents = findAllChildComponents(componentName, instance); let successCount = 0; childComponents.forEach(childComponent => { const exposed = childComponent.exposed || childComponent.proxy; if (exposed && typeof exposed[event] === 'function') { try { exposed[event](data); successCount++; } catch (error) { if (isDebugMode('error')) console.error(`Error calling ${componentName} method ${event}:`, error); } } }); if (isDebugMode()) console.log( `Parent ${name} successfully called ${successCount} of ${childComponents.length} ${componentName} components` ); }; const parentContext: ParentContext = { name, addChild(child: ChildContext) { if (!childrenMap.has(child.id)) { childrenMap.set(child.id, child); children.push(child); if (isDebugMode()) console.log(`Parent ${name} added child: ${child.name}`); } }, removeChild(childId: string) { if (childrenMap.has(childId)) { const child = childrenMap.get(childId)!; childrenMap.delete(childId); const index = children.findIndex(c => c.id === childId); if (index > -1) children.splice(index, 1); if (isDebugMode()) console.log(`Parent ${name} removed child: ${childId}`); } }, broadcast, broadcastToChildren, getChildren: () => Array.from(childrenMap.values()), getExposed: () => instance.exposed || {}, getChildExposed(childId: string) { const child = childrenMap.get(childId); return child?.getExposed?.() || {}; }, getChildrenExposed() { return Array.from(childrenMap.values()) .filter(child => child.getExposed) .map(child => ({ id: child.id, name: child.name, exposed: child.getExposed() })) .filter(item => Object.keys(item.exposed).length > 0); }, getInstance: () => instance }; if (instance.proxy) { (instance.proxy as any)[PARENT_CONTEXT_SYMBOL] = parentContext; } onUnmounted(() => { childrenMap.forEach((_, childId) => parentContext.removeChild(childId)); if (instance.proxy) { delete (instance.proxy as any)[PARENT_CONTEXT_SYMBOL]; } if (isDebugMode()) console.log(`Parent ${name} unmounted and cleaned up`); }); return { parentName: name, children, broadcast, broadcastToChildren, getChildren: parentContext.getChildren, getChildExposed: parentContext.getChildExposed, getChildrenExposed: parentContext.getChildrenExposed, getExposed: parentContext.getExposed, getInstance: parentContext.getInstance }; } /** * 子组件 Hook */ export function useChildren(componentName?: string, parentName?: string) { const instance = getCurrentInstance(); if (!instance) { throw new Error('useChildren must be called within setup function'); } const name = componentName || instance.type.name || instance.type.__name; // 生成实例ID,同组件多次使用useChildren会重复创建 // const instanceId = generateInstanceId(name || 'anonymous'); // 尝试从实例上复用已有的 child id,避免同个组件内多次调用 useChildren 导致重复注册 let instanceId: string | undefined = (instance.proxy as any)?.[CHILD_ID_SYMBOL]; if (!instanceId) { instanceId = generateInstanceId(name || 'anonymous'); if (instance.proxy) (instance.proxy as any)[CHILD_ID_SYMBOL] = instanceId; } const parentRef = ref(null); const parentExposed = ref>({}); const createSimulatedParentContext = (parentInstance: any): ParentContext => ({ name: parentInstance?.type?.name || parentInstance?.type?.__name || 'unknown', addChild: () => isDebugMode() && console.log('Simulated parent added child'), removeChild: () => isDebugMode() && console.log('Simulated parent removed child'), broadcast: () => isDebugMode() && console.log('Simulated parent broadcasting'), broadcastToChildren: () => isDebugMode() && console.log('Simulated parent broadcasting to children'), getChildren: () => [], getExposed: () => parentInstance?.exposed || {}, getChildExposed: () => ({}), getChildrenExposed: () => [], getInstance: () => parentInstance }); const getParentExposed = (): Record => { if (parentRef.value) { const exposed = parentRef.value.getExposed(); parentExposed.value = exposed; return exposed; } return {}; }; const getExposed = (): Record => instance.exposed || {}; const findParent = (): ParentContext | null => { if (parentName) { const parentContext = getParentContext(parentName, instance); if (parentContext) { if (!parentContext.getInstance) { parentContext.getInstance = () => findParentInstance(parentName, instance); } return parentContext; } const parentInstance = findParentInstance(parentName, instance); if (parentInstance) { return createSimulatedParentContext(parentInstance); } } let current = instance.parent; while (current) { const context = (current.proxy as any)?.[PARENT_CONTEXT_SYMBOL]; if (context) { if (!context.getInstance) { context.getInstance = () => current; } return context; } current = current.parent; } return instance.parent ? createSimulatedParentContext(instance.parent) : null; }; const linkParent = (): boolean => { const parent = findParent(); if (parent) { parentRef.value = parent; if (parent.addChild && childContext) { parent.addChild(childContext); } getParentExposed(); if (isDebugMode()) console.log(`Child ${name || 'anonymous'} linked to parent ${parent.name}`); return true; } if (isDebugMode()) console.log(`Child ${name || 'anonymous'} no parent found, working in standalone mode`); return false; }; const emitToParent = (event: string, data?: any) => { if (parentRef.value) { const exposed = getParentExposed(); if (exposed && typeof exposed[event] === 'function') { try { exposed[event](data, instanceId, name); } catch (error) { if (isDebugMode('error')) console.error(`Error calling parent method ${event}:`, error); } } } }; const getChildIndex = () => { if (!parentRef.value) return -1; try { const children = parentRef.value.getChildren(); return children.findIndex((child: ChildContext) => child.id === instanceId); } catch (error) { return -1; } }; const childContext: ChildContext = { id: instanceId, name: name || 'anonymous', getChildIndex, emitToParent, getParentExposed, getInstance: () => instance, getExposed }; if (isDebugMode()) console.log(`Child ${name || 'anonymous'} registered, looking for parent`); onMounted(() => { let connected = linkParent(); nextTick(() => { connected = linkParent(); if (!connected) { setTimeout(linkParent, 500); } }); }); onUnmounted(() => { if (parentRef.value?.removeChild) { parentRef.value.removeChild(instanceId); } if (isDebugMode()) console.log(`Child ${name || 'anonymous'} unmounted`); }); return { childId: instanceId, childName: name || 'anonymous', childIndex: computed(getChildIndex), parent: parentRef, emitToParent, getParentExposed, parentExposed: computed(() => parentExposed.value), getExposed }; } /** * 检查父组件是否存在 */ export function hasParent(parentName?: string): boolean { const instance = getCurrentInstance(); if (!instance) return false; if (parentName) { return getParentContext(parentName, instance) !== null; } let current = instance.parent; while (current) { if ((current.proxy as any)?.[PARENT_CONTEXT_SYMBOL]) return true; current = current.parent; } return false; } /** * 获取父组件上下文 */ export function getParentContextByName(parentName: string): ParentContext | null { const instance = getCurrentInstance(); return instance ? getParentContext(parentName, instance) : null; } /** * 热更新清理函数 */ export function cleanupComponentRelations(): void { if (isDebugMode()) console.log('Cleaning up component relations for hot reload'); } // 热更新处理 if (import.meta.hot) { import.meta.hot.accept(() => { if (isDebugMode()) console.log('Hot reload detected, relations will be automatically reconnected'); }); } export default { useParent, useChildren, hasParent, getParentContextByName, cleanupComponentRelations }; ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useDebounce.ts ================================================ export function useDebounce(delay: number = 500) { let timeout: ReturnType | null = null; // 防抖函数 function debounce(callback: () => void, debounceTime?: number) { debounceTime = debounceTime || delay; if (timeout) clearTimeout(timeout); timeout = setTimeout(() => { callback(); }, debounceTime); } return { debounce }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useEmitter.ts ================================================ import { type ComponentInternalInstance, getCurrentInstance } from 'vue'; /** * 将事件名转换为驼峰格式 * @param str 需要转换的字符串 * @description 例如:on-form-change -> onFormChange * @returns */ function formatToCamelCase(str: string): string { return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); } export function useEmitter(name: string) { const instance: ComponentInternalInstance | null | undefined = getCurrentInstance(); /** * 向上查找父组件并派发事件 * @param instance 当前组件实例(setup中可用getCurrentInstance()) * @param componentName 目标组件名 * @param eventName 事件名 * @param params 参数 */ function dispatch(componentName: string, eventName: string, ...params: any[]) { let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined); while (parent) { const name = (parent.type as any)?.name as string | undefined; if (name === componentName) { // 找到目标组件,派发事件 // Vue3未解决,目标组件事件监听失效,待优化,暂时使用下面的方式解决,如果你有好的方式也可以告诉我或者提PR parent.emit && parent.emit(eventName, ...params); // 如果有对应的方法,执行方法 // 这里可以考虑将 eventName 转换为驼峰格式 // 例如:on-form-change -> onFormChange parent.exposed?.[formatToCamelCase(eventName)] && parent.exposed[formatToCamelCase(eventName)](...params); break; } parent = parent.parent; } } /** * 向下递归查找子组件并广播事件 * @param instance 当前组件实例(setup中可用getCurrentInstance()) * @param componentName 目标组件名 * @param eventName 事件名 * @param params 参数 */ function broadcast(componentName: string, eventName: string, ...params: any[]) { if (!instance) return; const subTree = (instance.subTree as any)?.children || []; const children = Array.isArray(subTree) ? subTree : [subTree]; children.forEach((vnode: any) => { const child = vnode.component as ComponentInternalInstance | undefined; if (child) { const name = (child.type as any)?.name as string | undefined; if (name === componentName) { // 找到目标组件,广播事件 // Vue3未解决,目标组件事件监听失效,待优化,暂时使用下面的方式解决,如果你有好的方式也可以告诉我或者提PR child.emit && child.emit(eventName, ...params); // 如果有对应的方法,执行方法 // 这里可以考虑将 eventName 转换为驼峰格式 // 例如:on-form-change -> onFormChange child.exposed?.[formatToCamelCase(eventName)] && child.exposed[formatToCamelCase(eventName)](...params); } else { broadcast.call(child, componentName, eventName, ...params); } } }); } return { dispatch, broadcast }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useLocale.ts ================================================ import configProvider from '../util/config-provider'; /** * 国际化 composable * 提供: * - currentLocale / locales 响应式引用 * - t(key, replacements) 翻译方法 * - setLocale(name) 切换语言 * - initLocales(locales?, defaultName?) 初始化语言包 */ export function useLocale(namespace?: string) { // 创建翻译函数,支持命名空间 const createTranslateFunction = (ns?: string) => { return (key: string, replacements?: any, localeName?: string): string => { // 如果有命名空间,自动添加前缀 const fullKey = ns ? `${ns}.${key}` : key; return configProvider.t(fullKey, replacements, localeName); }; }; return { // 响应式引用 currentLocale: configProvider.currentLocaleRef, locales: configProvider.localesRef, // 方法 t: createTranslateFunction(namespace), setLocale: (name: string) => configProvider.setLocale(name), getLocales: () => configProvider.getLocales(), getCurrentLocale: () => configProvider.getCurrentLocale(), initLocales: (locales?: any[], defaultLocaleName?: string, isForce?: boolean) => configProvider.initLocales(locales, defaultLocaleName, isForce) }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useModal.ts ================================================ import { U_MODAL_EVENT_SHOW, U_MODAL_EVENT_HIDE, U_MODAL_EVENT_CLEAR_LOADING, U_MODAL_GLOBAL_EVENT_SHOW, U_MODAL_GLOBAL_EVENT_HIDE, U_MODAL_GLOBAL_EVENT_CLEAR_LOADING, getEventWithCurrentPage, type ModalPayload } from '../../components/u-modal/service'; export type UseModalShowOptions = ModalPayload; export type UseModal = { /** * 显示 modal * - show('标题') * - show({ title, content, showCancelButton, ... }) */ show: (contentOrOptions: string | UseModalShowOptions) => void; /** * 显示 confirm 类型的 modal(带确认和取消按钮) * - confirm('标题') * - confirm({ title, content, onConfirm, onCancel }) */ confirm: (contentOrOptions: string | UseModalShowOptions) => void; /** 关闭 modal */ close: () => void; /** 清除 loading 状态 */ clearLoading: () => void; }; export type UseModalOptions = { /** 是否使用全局根部 */ global?: boolean; /** 是否使用页面级 或某个页面的 */ page?: boolean | string; }; function normalize(contentOrOptions: string | UseModalShowOptions): UseModalShowOptions { if (typeof contentOrOptions === 'string') { // 如果是简单的字符串,可能是标题或内容 return { content: contentOrOptions }; } return contentOrOptions || {}; } function getPage(optionsOrGlobal: UseModalOptions | boolean): string { if (typeof optionsOrGlobal === 'boolean') { return ''; } if (optionsOrGlobal.page && typeof optionsOrGlobal.page === 'string' && optionsOrGlobal.page !== '') { return optionsOrGlobal.page; } return ''; } /** * Modal 函数式调用 * @description 需要页面/应用中至少存在一个 实例用于承接事件;不影响原 ref 调用方式。 * * 支持两种调用方式: * - 应用级 useModal() / useModal(true) / useModal({ global: true }) * - 页面级 useModal(false) / useModal({ page: true }) / useModal({ page: 'pageId' }) (pageId 应和页面中 的 page 属性一致) */ export function useModal(optionsOrGlobal: UseModalOptions | boolean = true): UseModal { const isGlobal = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === true : !!optionsOrGlobal.global; const isPage = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === false : !!optionsOrGlobal.page; const showEvent = isGlobal ? U_MODAL_GLOBAL_EVENT_SHOW : isPage ? getEventWithCurrentPage(U_MODAL_EVENT_SHOW, getPage(optionsOrGlobal)) : ''; const hideEvent = isGlobal ? U_MODAL_GLOBAL_EVENT_HIDE : isPage ? getEventWithCurrentPage(U_MODAL_EVENT_HIDE, getPage(optionsOrGlobal)) : ''; const clearLoadingEvent = isGlobal ? U_MODAL_GLOBAL_EVENT_CLEAR_LOADING : isPage ? getEventWithCurrentPage(U_MODAL_EVENT_CLEAR_LOADING, getPage(optionsOrGlobal)) : ''; function emitShow(payload: UseModalShowOptions) { if (showEvent) { uni?.$emit && uni.$emit(showEvent, payload); } } function emitHide() { if (hideEvent) { uni?.$emit && uni.$emit(hideEvent); } } function emitClearLoading() { if (clearLoadingEvent) { uni?.$emit && uni.$emit(clearLoadingEvent); } } function show(contentOrOptions: string | UseModalShowOptions) { emitShow(normalize(contentOrOptions)); } function confirm(contentOrOptions: string | UseModalShowOptions) { const options = normalize(contentOrOptions); emitShow({ ...options, showCancelButton: options.showCancelButton ?? true, showConfirmButton: options.showConfirmButton ?? true }); } function clearLoading() { emitClearLoading(); } function close() { emitHide(); } return { show, confirm, close, clearLoading }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useRect.ts ================================================ import { getCurrentInstance, nextTick, ref } from 'vue'; /** * useRect - 获取元素的位置信息(响应式,原生实现) * @param selector 选择器(如 #id 或 .class) * @param all 是否获取所有匹配元素 * @returns rect 响应式的节点信息,refresh 主动刷新方法 */ export function useRect(selector: string | null = null, all = false) { const rect = ref(all ? [] : null); const instance = getCurrentInstance(); async function getRect(realSelector: string | null = null, delay = 0): Promise { realSelector = realSelector || selector; if (!realSelector) return rect.value; await nextTick(); return new Promise(resolve => { setTimeout(() => { uni.createSelectorQuery() .in(instance?.proxy) [all ? 'selectAll' : 'select'](realSelector as string) .boundingClientRect((res: any) => { rect.value = res; resolve(res); }) .exec(); }, delay); }); } function refresh(selector?: string | null, delay?: number): Promise { return getRect(selector, delay); } return { rect, getRect, refresh }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useRouter.ts ================================================ /** * 路由跳转 hooks,基于 route.ts 的 Router 类实现 * 提供 Vue Composition API 风格的路由跳转方法 */ import { ref } from 'vue'; interface RouterConfig { type?: string; url?: string; delta?: number; params?: Record; animationType?: string; animationDuration?: number; intercept?: boolean; } declare const uni: any; const config: RouterConfig = { type: 'navigateTo', url: '', delta: 1, params: {}, animationType: 'pop-in', animationDuration: 300, intercept: false }; // 响应式配置,支持动态修改 const configRef = ref({ ...config }); /** * 判断 url 前面是否有 "/",如果没有则加上 */ const addRootPath = (url: string): string => { return url[0] === '/' ? url : `/${url}`; }; /** * 整合路由参数 */ const mixinParam = (url: string, params: Record): string => { url = url && addRootPath(url); let query = ''; if (/.*\/.*\?.*=.*/.test(url)) { query = uni.$u.queryParams(params, false); return url + '&' + query; } else { query = uni.$u.queryParams(params); return url + query; } }; /** * 执行路由跳转 */ const openPage = (cfg: RouterConfig): void => { const { url = '', type = '', delta = 1, animationDuration = 300 } = cfg; if (type === 'navigateTo' || type === 'to') { uni.navigateTo({ url, animationDuration }); } if (type === 'redirectTo' || type === 'redirect') { uni.redirectTo({ url }); } if (type === 'switchTab' || type === 'tab') { uni.switchTab({ url }); } if (type === 'reLaunch' || type === 'launch') { uni.reLaunch({ url }); } if (type === 'navigateBack' || type === 'back') { uni.navigateBack({ delta }); } }; /** * 路由跳转主方法 */ const route = async (options: string | RouterConfig = {}, params: Record = {}): Promise => { let mergeConfig: RouterConfig = {}; if (typeof options === 'string') { mergeConfig.url = mixinParam(options, params); mergeConfig.type = 'navigateTo'; } else { mergeConfig = uni.$u.deepMerge(configRef.value, options); mergeConfig.url = mixinParam(options.url || '', options.params || {}); } if (params.intercept !== undefined) { configRef.value.intercept = params.intercept; } mergeConfig.params = params; mergeConfig = uni.$u.deepMerge(configRef.value, mergeConfig); if (uni.$u.routeIntercept && typeof uni.$u.routeIntercept === 'function') { const isNext = await new Promise(resolve => { uni.$u.routeIntercept(mergeConfig, resolve); }); isNext && openPage(mergeConfig); } else { openPage(mergeConfig); } }; /** * 跳转到指定页面 */ const to = (url: string, params?: Record): Promise => { return route({ url, type: 'navigateTo' }, params || {}); }; /** * 关闭当前页面,跳转到指定页面 */ const redirect = (url: string, params?: Record): Promise => { return route({ url, type: 'redirectTo' }, params || {}); }; /** * 跳转到 tabBar 页面 */ const tab = (url: string, params?: Record): Promise => { return route({ url, type: 'switchTab' }, params || {}); }; /** * 关闭所有页面,跳转到指定页面 */ const reLaunch = (url: string, params?: Record): Promise => { return route({ url, type: 'reLaunch' }, params || {}); }; /** * 返回上一页 */ const back = (delta: number = 1): Promise => { return route({ type: 'navigateBack', delta }); }; /** * 设置默认路由配置 */ const setConfig = (newConfig: Partial): void => { configRef.value = uni.$u.deepMerge(configRef.value, newConfig); }; /** * 获取当前路由配置 */ const getConfig = (): RouterConfig => { return { ...configRef.value }; }; export function useRouter() { return { // 核心跳转方法 route, // 便捷方法 to, redirect, tab, reLaunch, back, // 配置方法 setConfig, getConfig }; } export default useRouter; ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useTheme.ts ================================================ /** * 主题管理 composable * 提供主题切换、持久化、CSS 变量注入、暗黑模式等功能 * * 使用方式: * const { currentTheme, themes, setTheme, getDarkMode, setDarkMode, isInDarkMode, getAvailableThemes, initTheme } = useTheme() */ import type { DarkMode, Theme } from '../../types/global'; import configProvider, { type DefaultThemeConfig } from '../util/config-provider'; import { defaultThemes } from '../config/theme-tokens'; const THEME_STORAGE_KEY = 'uview-pro-theme'; const DARK_MODE_STORAGE_KEY = 'uview-pro-dark-mode'; const themesRef = configProvider.themesRef; const currentTheme = configProvider.currentThemeRef; const darkModeRef = configProvider.darkModeRef; /** * 保存主题到 Storage */ function saveThemeToStorage(themeName: string) { try { uni.setStorageSync(THEME_STORAGE_KEY, themeName); } catch (e) { console.warn('[useTheme] failed to write storage', e); } } /** * 保存暗黑模式设置到 Storage */ function saveDarkModeToStorage(mode: DarkMode) { try { uni.setStorageSync(DARK_MODE_STORAGE_KEY, mode); } catch (e) { console.warn('[useTheme] failed to write storage', e); } } /** * 设置主题 */ function setTheme(themeName: string) { configProvider.setTheme(themeName); currentTheme.value = configProvider.getCurrentTheme(); saveThemeToStorage(themeName); } /** * 获取当前主题 */ function getCurrentTheme(): Theme | null { return currentTheme.value || configProvider.getCurrentTheme(); } /** * 获取所有可用主题 */ function getAvailableThemes() { return configProvider.getThemes(); } /** * 初始化主题系统 * @param themes 可选的主题列表,如果未提供则尝试从 uni.$u.themes 读取 * @param defaultConfig 可选的默认主题配置,支持字符串(默认主题名)或对象({ defaultTheme?, defaultDarkMode? }) */ export function initTheme(themes?: Theme[], defaultConfig?: string | DefaultThemeConfig, isForce?: boolean) { // 如果有传入主题列表,使用传入的 if (Array.isArray(themes) && themes.length > 0) { configProvider.initTheme(themes, defaultConfig, isForce); return; } // // 若已通过插件或其他方式完成初始化,则不再覆盖,最多按需切换默认主题 // const existingThemes = configProvider.getThemes(); // if (existingThemes.length > 0) { // if (typeof defaultConfig === 'string') { // configProvider.setTheme(defaultConfig); // } else if (defaultConfig && typeof defaultConfig === 'object' && (defaultConfig as any).defaultTheme) { // configProvider.setTheme(defaultConfig.defaultTheme); // } else if (!configProvider.getCurrentTheme()) { // configProvider.setTheme(existingThemes[0].name); // } else { // // 触发一次 apply,便于初始化 CSS 变量 // configProvider.setTheme(configProvider.getCurrentTheme()!.name); // } // return; // } // // 初始化 configProvider(如果运行时提供了内置主题) // try { // const builtin = (typeof uni !== 'undefined' && (uni as any).$u && (uni as any).$u.themes) || []; // if (Array.isArray(builtin) && builtin.length > 0) { // configProvider.initTheme(builtin as Theme[], defaultConfig); // return; // } // } catch (e) { // // ignore // } // 回退到内置默认主题 configProvider.initTheme(defaultThemes as Theme[], defaultConfig); } /** * 初始化暗黑模式 * @param darkMode 暗黑模式设置 * @param isForce 是否强制初始化 */ function initDarkMode(darkMode?: DarkMode, isForce?: boolean) { configProvider.initDarkMode(darkMode, isForce); } /** * 获取当前暗黑模式设置 */ function getDarkMode(): DarkMode { return configProvider.getDarkMode(); } /** * 设置暗黑模式 * @param mode 'auto' (跟随系统) | 'light' (强制亮色) | 'dark' (强制暗黑) */ function setDarkMode(mode: DarkMode) { configProvider.setDarkMode(mode); darkModeRef.value = mode; saveDarkModeToStorage(mode); } /** * 检查当前是否处于暗黑模式 */ function isInDarkMode(): boolean { return configProvider.isInDarkMode(); } /** * 切换暗黑模式(在当前模式的基础上切换) */ function toggleDarkMode() { const current = getDarkMode(); const nextMode = current === 'dark' ? 'light' : 'dark'; setDarkMode(nextMode); } /** * 使用主题的 composable * 返回所有主题相关的响应式引用和方法 */ export function useTheme() { return { // 响应式引用 currentTheme, themes: themesRef, darkMode: darkModeRef, cssVars: configProvider.cssVarsRef, // 主题相关方法 initTheme, setTheme, getCurrentTheme, getAvailableThemes, // 暗黑模式相关方法 initDarkMode, getDarkMode, setDarkMode, isInDarkMode, toggleDarkMode }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useThrottle.ts ================================================ export function useThrottle(delay: number = 500) { let previous: number = 0; // 节流函数 function throttle(callback: () => void, throttleTime?: number) { throttleTime = throttleTime || delay; let now = Date.now(); if (now - previous > throttleTime) { callback(); previous = now; } } return { throttle }; } ================================================ FILE: src/uni_modules/uview-pro/libs/hooks/useToast.ts ================================================ import { U_TOAST_EVENT_HIDE, U_TOAST_EVENT_SHOW, U_TOAST_GLOBAL_EVENT_HIDE, U_TOAST_GLOBAL_EVENT_SHOW, getEventWithCurrentPage, type ToastPayload } from '../../components/u-toast/service'; import type { ThemeType } from '../../types/global'; export type UseToastShowOptions = ToastPayload; export type UseToast = { /** * 显示 toast * - show('文本') * - show({ title, type, duration, ... }) */ show: (titleOrOptions: string | UseToastShowOptions) => void; /** 关闭 toast */ close: () => void; /** 成功 */ success: (titleOrOptions: string | UseToastShowOptions) => void; /** 错误 */ error: (titleOrOptions: string | UseToastShowOptions) => void; /** 警告 */ warning: (titleOrOptions: string | UseToastShowOptions) => void; /** 信息 */ info: (titleOrOptions: string | UseToastShowOptions) => void; /** 加载中(默认常驻,需 close 关闭) */ loading: (titleOrOptions: string | UseToastShowOptions) => void; }; export type UseToastOptions = { /** 是否使用全局根部 ,默认 true;为 false 时走页面级 */ global?: boolean; /** 是否使用页面级 或某个页面的 */ page?: boolean | string; }; function normalize(titleOrOptions: string | UseToastShowOptions): UseToastShowOptions { if (typeof titleOrOptions === 'string') return { title: titleOrOptions }; return titleOrOptions || {}; } function getPage(optionsOrGlobal: UseToastOptions | boolean): string { if (typeof optionsOrGlobal === 'boolean') { return ''; } if (optionsOrGlobal.page && typeof optionsOrGlobal.page === 'string' && optionsOrGlobal.page !== '') { return optionsOrGlobal.page; } return ''; } /** * Toast 函数式调用 * @description 需要页面/应用中至少存在一个 实例用于承接事件;不影响原 ref 调用方式。 * * 支持两种调用方式: * - 应用级 useToast() / useToast(true) / useToast({ global: true }) * - 页面级 useToast(false) / useToast({ page: true }) / useToast({ page: 'pageId' }) (pageId 应和页面中 的 page 属性一致) */ export function useToast(optionsOrGlobal: UseToastOptions | boolean = true): UseToast { const isGlobal = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === true : !!optionsOrGlobal.global; const isPage = typeof optionsOrGlobal === 'boolean' ? optionsOrGlobal === false : !!optionsOrGlobal.page; const showEvent = isGlobal ? U_TOAST_GLOBAL_EVENT_SHOW : isPage ? getEventWithCurrentPage(U_TOAST_EVENT_SHOW, getPage(optionsOrGlobal)) : ''; const hideEvent = isGlobal ? U_TOAST_GLOBAL_EVENT_HIDE : isPage ? getEventWithCurrentPage(U_TOAST_EVENT_HIDE, getPage(optionsOrGlobal)) : ''; function emitShow(payload: UseToastShowOptions) { if (showEvent) { uni?.$emit && uni.$emit(showEvent, payload); } } function emitHide() { if (hideEvent) { uni?.$emit && uni.$emit(hideEvent); } } function show(titleOrOptions: string | UseToastShowOptions) { emitShow(normalize(titleOrOptions)); } function close() { emitHide(); } function withType(type: ThemeType, titleOrOptions: string | UseToastShowOptions) { const options = normalize(titleOrOptions); emitShow({ ...options, type }); } return { show, close, success: (v: any) => withType('success', v), error: (v: any) => withType('error', v), warning: (v: any) => withType('warning', v), info: (v: any) => withType('info', v), loading: (v: any) => { const options = normalize(v); // loading 通常需要常驻,除非用户显式传 duration emitShow({ ...options, loading: true, duration: options.duration ?? 0 }); } }; } ================================================ FILE: src/uni_modules/uview-pro/libs/index.ts ================================================ // post类型对象参数转为get类型url参数 import queryParams from './function/queryParams'; // 路由封装 import route from './function/route'; // 时间格式化 import timeFormat from './function/timeFormat'; // 时间戳格式化,返回多久之前 import timeFrom from './function/timeFrom'; // 颜色渐变相关,colorGradient-颜色渐变,hexToRgb-十六进制颜色转rgb颜色,rgbToHex-rgb转十六进制 import colorGradients from './function/colorGradient'; // 生成全局唯一guid字符串 import guid from './function/guid'; // 主题相关颜色,info|success|warning|primary|default|error,此颜色已在uview.scss中定义,但是为js中也能使用,故也定义一份 import { color } from './config/color'; import { getColor, setColor } from './function/color'; // 根据type获取图标名称 import type2icon from './function/type2icon'; // 打乱数组的顺序 import randomArray from './function/randomArray'; // 对象和数组的深度克隆 import deepClone from './function/deepClone'; // 对象深度拷贝 import deepMerge from './function/deepMerge'; // 添加单位 import addUnit from './function/addUnit'; // 规则检验 import test from './function/test'; // 随机数 import random from './function/random'; // 去除空格 import trim from './function/trim'; // toast提示,对uni.showToast的封装 import toast from './function/toast'; // 获取父组件参数 import getParent from './function/getParent'; // 获取整个父组件 import $parent from './function/$parent'; // 获取sys()和os()工具方法 // 获取设备信息,挂载到$u的sys()(system的缩写)属性中, // 同时把安卓和ios平台的名称"ios"和"android"挂到$u.os()中,方便取用 import { sys, os } from './function/sys'; // 防抖方法 import debounce from './function/debounce'; // 节流方法 import throttle from './function/throttle'; // 获取元素的位置信息 import getRect from './function/getRect'; // 剪贴板 import { clipboard } from './function/clipboard'; // 配置信息 import config from './config/config'; // 各个需要fixed的地方的z-index配置文件 import zIndex from './config/zIndex'; import { mitt } from './util/mitt'; // http相关 import httpPlugin, { Request, http, type RequestOptions, type RequestConfig, type RequestInterceptor, type RequestMeta } from './request/index'; /** * @description 数字格式化 * @param number 要格式化的数字 * @param decimals 保留几位小数 * @param decimalPoint 小数点符号 * @param thousandsSeparator 千分位符号 * @returns 格式化后的数字 */ export function formatPrice( number: number | string, decimals: number = 0, decimalPoint: string = '.', thousandsSeparator: string = ',' ): string { // 辅助函数:四舍五入到指定小数位 function round(num: number, precision: number): string { const factor = Math.pow(10, precision); return (Math.round(num * factor) / factor).toFixed(precision); } let numStr = String(number).replace(/[^0-9+\-Ee.]/g, ''); const n = !isFinite(+numStr) ? 0 : +numStr; const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals); const sep = thousandsSeparator ?? ','; const dec = decimalPoint ?? '.'; let s: string[] = []; s = (prec ? round(n, prec) : Math.round(n).toString()).split('.'); const re = /(-?\d+)(\d{3})/; while (re.test(s[0])) { s[0] = s[0].replace(re, `$1${sep}$2`); } if ((s[1] || '').length < prec) { s[1] = s[1] || ''; s[1] += '0'.repeat(prec - s[1].length); } return s.join(dec); } // 默认的姓名脱敏规则 export function formatName(name: string): string { if (name.length === 2) { return name.charAt(0) + '*'; } else if (name.length > 2) { const masked = '*'.repeat(name.length - 2); return name.charAt(0) + masked + name.charAt(name.length - 1); } else { return name; } } /** * @description 样式转换 * 对象转字符串,或者字符串转对象 * @param {object | string} customStyle 需要转换的目标 * @param {String} target 转换的目的,object-转为对象,string-转为字符串 * @returns {object|string} */ export function addStyle( customStyle: Record | string, target: 'object' | 'string' = 'object' ): Record | string { // 字符串转字符串,对象转对象情形,直接返回 if ( test.empty(customStyle) || (typeof customStyle === 'object' && target === 'object') || (target === 'string' && typeof customStyle === 'string') ) { return customStyle; } // 字符串转对象 if (target === 'object') { // 去除字符串样式中的两端空格 const trimmedStyle = trim(customStyle as string); const styleArray = trimmedStyle.split(';'); const style: Record = {}; for (let i = 0; i < styleArray.length; i++) { if (styleArray[i]) { const item = styleArray[i].split(':'); if (item.length === 2) { style[trim(item[0])] = trim(item[1]); } } } return style; } // 对象转字符串 let string = ''; for (const i in customStyle as Record) { if (Object.prototype.hasOwnProperty.call(customStyle, i)) { const key = i.replace(/([A-Z])/g, '-$1').toLowerCase(); string += `${key}:${(customStyle as Record)[i]};`; } } return trim(string); } /** * 将外部传入的样式格式化为可读的 CSS 样式。 * @param {object | object[]} styles 外部传入的样式对象或数组 * @returns {string} 格式化后的 CSS 样式字符串 */ export function toStyle(...styles: Array | string | null | undefined>): string { // 支持多参数:每个参数可以是 object 或 string,后面的参数优先级更高,会覆盖同名样式 // 如果传入单个数组(兼容旧调用),解构展开 if (styles.length === 1 && Array.isArray(styles[0])) { styles = (styles[0] as any[]).slice(); } // 用于合并样式的 Map,key 使用 kebab-case const map = new Map(); const processString = (str: string) => { if (!str) return; // 移除可能的末尾分号,再按分号分割 const parts = str.split(';'); for (let part of parts) { part = part.trim(); if (!part) continue; const idx = part.indexOf(':'); if (idx === -1) continue; const key = trim(part.slice(0, idx)); const val = trim(part.slice(idx + 1)); if (key === '' || val === '') continue; const k = kebabCase(key); map.set(k, val); } }; const processObject = (obj: Record) => { if (!obj) return; Object.keys(obj).forEach(key => { const val = obj[key]; if (val == null || val === '') return; const k = kebabCase(key); map.set(k, val); }); }; for (const item of styles) { if (item == null || item === '') continue; if (test.string(item)) { processString(item as string); } else if (test.array(item)) { // 若传入数组作为参数,递归处理数组元素 (item as any[]).forEach(el => { if (test.string(el)) processString(el as string); else if (test.object(el)) processObject(el as Record); }); } else if (test.object(item)) { processObject(item as Record); } } if (map.size === 0) return ''; // 按插入顺序构造样式字符串,值转成字符串 const result = Array.from(map.entries()) .map(([k, v]) => `${k}:${String(v)}`) .join(';'); return result ? (result.endsWith(';') ? result : result + ';') : ''; } /** * 将驼峰命名转换为短横线命名。 * @param {string} word 待转换的词条 * @returns {string} 转换后的结果 */ export function kebabCase(word: string): string { // 使用正则表达式匹配所有大写字母,并在前面加上短横线,然后转换为小写 const newWord: string = word .replace(/[A-Z]/g, function (match) { return '-' + match; }) .toLowerCase(); return newWord; } /** * @description 进行延时,以达到可以简写代码的目的 比如: await uni.$u.sleep(20)将会阻塞20ms * @param {number} value 堵塞时间 单位ms 毫秒 * @returns {Promise} 返回promise */ export function sleep(value: number = 30): Promise { return new Promise(resolve => { setTimeout(() => { resolve(true); }, value); }); } export { queryParams, route, timeFormat, timeFrom, guid, color, getColor, setColor, sys, os, type2icon, randomArray, deepClone, deepMerge, addUnit, test, random, trim, toast, debounce, throttle, getRect, getParent, $parent, clipboard, config, zIndex, mitt }; export const $u = { queryParams: queryParams, route: route, timeFormat: timeFormat, date: timeFormat, // 另名date timeFrom, colorGradient: colorGradients.colorGradient, colorToRgba: colorGradients.colorToRgba, guid, color, getColor, setColor, sys, os, type2icon, randomArray, hexToRgb: colorGradients.hexToRgb, rgbToHex: colorGradients.rgbToHex, test, random, deepClone, deepMerge, getParent, $parent, clipboard, addUnit, trim, type: ['primary', 'success', 'error', 'warning', 'info'], http, toast, config, // uView配置信息相关,比如版本号 zIndex, debounce, throttle, mitt: mitt(), getRect, formatPrice, formatName, addStyle, toStyle, kebabCase, sleep }; // 颜色相关方法单独导出 export const { colorGradient, colorToRgba, hexToRgb, rgbToHex } = colorGradients; // http相关导出 export { Request, httpPlugin, http, type RequestOptions, type RequestConfig, type RequestInterceptor, type RequestMeta }; export * from './hooks'; export * from './util/config-provider'; ================================================ FILE: src/uni_modules/uview-pro/libs/request/auto-http.ts ================================================ import deepMerge from '../function/deepMerge'; export function isFunction(f: any): boolean { return typeof f === 'function'; } export function isPromise(p: any): boolean { return !!(p && p.then && p.catch); } export function isArray(arr: any) { return Object.prototype.toString.call(arr) === '[object Array]'; } /** * 构建基础类 */ class Builder { instance: any; constructor(instance: any) { this.instance = instance; } /** * * @param urlConfig url 配置表 * @param extra 其他请求方法对象 * @returns Object */ dispatch(urlConfig: Record, extra: Record = {}): Record { const builder: Record = {}; // 创建 API Object.keys(urlConfig).forEach(name => { builder[name] = this.use.bind(this, urlConfig[name]); }); return { ...builder, ...extra }; } /** * 发送请求 * @param {*} urlConfig : url 配置表 * @demo urlConfig = { login: { url: '/user/login', method: 'GET', loading: true } } * @param {*} config : 开放配置,用户主动配置的 * @demo api.login({ params: { username: "admin" } }) * @returns Promise */ use(urlConfig: Record, config: Record = {}): Promise { // 请求地址 let url = config?.url ?? urlConfig.url; // 兼容 restful url,如果是使用url为function,则为restful格式 if (config.url && isFunction(config.url)) { url = `${urlConfig.url}${config.url()}`; } // 请求类型,get,post,put,delete const method = config?.method ?? urlConfig?.method ?? 'GET'; // 如果有自定义的工厂函数基础类 const options = { ...deepMerge(urlConfig, config), url, method }; if (isFunction(this.instance) || isPromise(this.instance)) { return this.instance(options); } // 如果是使用的 instance // 默认的请求基础类 return this.instance.request(options); } } /** * Http 基础类 */ class AutoHttp { static get Builder() { return Builder; } constructor() {} } export { AutoHttp }; ================================================ FILE: src/uni_modules/uview-pro/libs/request/index.ts ================================================ import deepMerge from '../function/deepMerge'; /** * 请求配置项Meta类型定义 */ export interface RequestMeta { toast?: boolean; loading?: boolean; originalData?: boolean; [key: string]: any; } /** * 请求配置项类型定义 */ export interface RequestConfig { baseUrl?: string; header?: Record; method?: string; dataType?: string; responseType?: string; timeout?: number; meta?: RequestMeta; [key: string]: any; } /** * 忽略的请求参数类型定义 */ const IGNORE_REQUEST_KEYS = ['baseUrl', 'meta']; /** * 请求拦截器类型定义 */ export interface RequestInterceptor { request?: ((options: RequestOptions) => RequestOptions | false) | null; response?: ((response: any) => any | false) | null; } /** * 请求参数类型定义 */ export interface RequestOptions { url: string; header: Record; method: 'GET' | 'POST' | 'OPTIONS' | 'HEAD' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT'; data?: any; dataType?: string; responseType?: string; params?: Record; complete?: (response: any) => void; meta?: RequestMeta; [key: string]: any; } export class Request { public config: RequestConfig; public interceptor: RequestInterceptor; public options?: RequestOptions; constructor() { this.config = { baseUrl: '', // 请求的根域名 header: {}, // 默认的请求头 method: 'POST', // 请求方式 dataType: 'json', // 设置为json,返回后uni.request会对数据进行一次JSON.parse responseType: 'text', // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可 timeout: 60000, meta: { originalData: true, // 是否在拦截器中返回服务端的原始数据,见文档说明 toast: false, // 是否在请求出错时,弹出toast loading: false // 是否显示加载中 } }; this.interceptor = { request: null, response: null }; } /** * 将全局配置合并到本次请求的 options 中 * - 忽略 IGNORE_REQUEST_KEYS 中的字段(如 meta) * - 对 header 使用深合并(全局 header 为默认,options.header 优先) * - 对对象类型的字段尝试深合并,基础类型以 options 值优先 * - 处理 baseUrl:若存在全局 baseUrl 且 options.url 非完整 url(非 http 开头),则合并成完整 URL */ private mergeGlobalConfigToOptions(options: RequestOptions): RequestOptions { const mergedOptions: RequestOptions = { ...options }; for (const key of Object.keys(this.config)) { if (IGNORE_REQUEST_KEYS.includes(key)) { continue; } const cfgVal = this.config[key]; const optVal = options[key]; // 跳过未设置的全局配置 if (cfgVal === undefined) continue; // header 需要做深合并,且以 options.header 为准覆盖同名属性 if (key === 'header') { mergedOptions.header = deepMerge(cfgVal || {}, optVal || {}); continue; } // 针对 method 等枚举字符串,优先使用 options 中的值,否则使用全局配置 if (typeof cfgVal === 'string' || typeof cfgVal === 'number' || typeof cfgVal === 'boolean') { mergedOptions[key] = optVal !== undefined ? optVal : cfgVal; continue; } // 对对象类型的配置(如自定义扩展)尝试做深合并 if (typeof cfgVal === 'object' && !Array.isArray(cfgVal)) { mergedOptions[key] = deepMerge(cfgVal || {}, optVal || {}); continue; } // 其他类型,若 options 未传入则使用全局配置 if (optVal === undefined) { mergedOptions[key] = cfgVal; } } // 如果存在 baseUrl,并且 options.url 为相对地址,则拼接成完整 url const baseUrl = this.config.baseUrl; if ( baseUrl && mergedOptions.url && typeof mergedOptions.url === 'string' && mergedOptions.url.indexOf('http') !== 0 ) { mergedOptions.url = baseUrl + (mergedOptions.url.indexOf('/') === 0 ? mergedOptions.url : `/${mergedOptions.url}`); } // 确保 url 存在,且为 string if (!mergedOptions.url) { mergedOptions.url = ''; } return mergedOptions; } /** * 设置全局默认配置 * @param customConfig 自定义配置 */ setConfig(customConfig: Partial): void { this.config = deepMerge(this.config, customConfig); } /** * 主要请求部分 * @param options 请求参数 */ request(options: RequestOptions): Promise { // 合并 meta 配置,优先级:单次请求 > 全局 const mergedMeta: RequestMeta = { ...this.config.meta, ...(options.meta || {}) }; // 让 options.meta 传递到拦截器 options.meta = mergedMeta; options.url = options.url || ''; options.params = options.params || {}; // 将全局配置合并到本次请求 options 中(注意忽略一些特殊字段如 baseUrl/meta) options = this.mergeGlobalConfigToOptions(options); if (this.interceptor.request && typeof this.interceptor.request === 'function') { const interceptorRequest = this.interceptor.request(options); if (!interceptorRequest) { // 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调 return new Promise(() => {}); } this.options = interceptorRequest; } return new Promise((resolve, reject) => { options.complete = (response: any) => { // 读取 meta 配置 const meta = options.meta || this.config.meta || {}; const originalData = meta.originalData ?? false; // 拦截器处理,加入request的配置参数 response.config = options; if (originalData) { // 判断是否存在拦截器 if (this.interceptor.response && typeof this.interceptor.response === 'function') { const resInterceptors = this.interceptor.response(response); // 如果拦截器不返回false,就将拦截器返回的内容给请求的then回调 if (resInterceptors !== false) { resolve(resInterceptors); } else { // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调 reject(response); } } else { // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据 resolve(response); } } else { if (response.statusCode === 200) { if (this.interceptor.response && typeof this.interceptor.response === 'function') { const resInterceptors = this.interceptor.response(response.data); if (resInterceptors !== false) { resolve(resInterceptors); } else { reject(response.data); } } else { // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调 resolve(response.data); } } else { reject(response); } } }; uni.request(options); }); } get( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ method: 'GET', url, data, header: options.header || {}, meta: options.meta }); } post( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ url, method: 'POST', data, header: options.header || {}, meta: options.meta }); } put( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ url, method: 'PUT', data, header: options.header || {}, meta: options.meta }); } delete( url: string, data: any = {}, options: { header?: Record; meta?: RequestMeta } = {} ): Promise { return this.request({ url, method: 'DELETE', data, header: options.header || {}, meta: options.meta }); } } // 插件化导出,支持 app.use(http, { interceptor }) const httpInstance = new Request(); interface HttpPluginOptions { requestConfig?: Partial; interceptor?: RequestInterceptor; } // 全局导出,支持 import { httpPlugin } from 'uview-pro' const httpPlugin = { install(app: any, options: HttpPluginOptions = {}) { if (options.interceptor) { const { request, response } = options.interceptor; if (request) httpInstance.interceptor.request = request; if (response) httpInstance.interceptor.response = response; } if (options.requestConfig) { httpInstance.setConfig(options.requestConfig); } app.config.globalProperties.$http = httpInstance; } }; // 全局导出,支持 import { http } from 'uview-pro' export { httpInstance as http }; // 插件化导出,支持 app.use(http, { interceptor }) export default httpPlugin; ================================================ FILE: src/uni_modules/uview-pro/libs/store/index.ts ================================================ /** * 支持通过 name 路径批量/单项赋值 Pinia store 的工具方法 * @param store Pinia store 实例 * @param params { name: string, value: any } * name 支持 a.b.c 形式嵌套赋值 */ /** * 用法示例: * setStoreValue(userStore, { name: 'profile.avatar', value: 'xxx.png' }) * setStoreValueTyped(userStore, 'token', 'xxxx') * setStoreValues(userStore, [{ name: 'token', value: 'xxx' }, { name: 'profile.avatar', value: 'img.png' }]) * getStoreValue(userStore, 'profile.avatar') * resetStore(userStore, { token: '', profile: { avatar: '' } }) */ export function setStoreValue(store: T, params: { name: string; value: any }): void { const nameArr = params.name.split('.'); let obj: any = store; if (nameArr.length >= 2) { for (let i = 0; i < nameArr.length - 1; i++) { if (!(nameArr[i] in obj)) { obj[nameArr[i]] = {}; } obj = obj[nameArr[i]]; } obj[nameArr[nameArr.length - 1]] = params.value; } else { (store as any)[params.name] = params.value; } } /** * 类型安全的嵌套属性赋值工具 * @param store Pinia store 实例 * @param path 属性路径(如 profile.avatar) * @param value 赋值内容 */ export function setStoreValueTyped(store: T, path: K, value: T[K]): void; export function setStoreValueTyped(store: T, path: string, value: any): void { const nameArr = path.split('.'); let obj: any = store; if (nameArr.length >= 2) { for (let i = 0; i < nameArr.length - 1; i++) { if (!(nameArr[i] in obj)) { obj[nameArr[i]] = {}; } obj = obj[nameArr[i]]; } obj[nameArr[nameArr.length - 1]] = value; } else { (store as any)[path] = value; } } /** * 批量赋值 Pinia store 工具方法 * @param store Pinia store 实例 * @param values { name: string, value: any }[] */ export function setStoreValues(store: T, values: Array<{ name: string; value: any }>): void { values.forEach(item => setStoreValue(store, item)); } /** * 获取嵌套属性值 * @param store Pinia store 实例 * @param path 属性路径(如 profile.avatar) * @returns 属性值 */ export function getStoreValue(store: T, path: string): any { const nameArr = path.split('.'); let obj: any = store; for (let i = 0; i < nameArr.length; i++) { if (obj == null) return undefined; obj = obj[nameArr[i]]; } return obj; } /** * 重置 Pinia store 为初始值 * @param store Pinia store 实例 * @param initial 初始值对象 */ export function resetStore(store: T, initial: Partial): void { Object.keys(initial).forEach(key => { (store as any)[key] = (initial as any)[key]; }); } ================================================ FILE: src/uni_modules/uview-pro/libs/util/area.ts ================================================ export default [[[{label:"东城区",value:"110101"},{label:"西城区",value:"110102"},{label:"朝阳区",value:"110105"},{label:"丰台区",value:"110106"},{label:"石景山区",value:"110107"},{label:"海淀区",value:"110108"},{label:"门头沟区",value:"110109"},{label:"房山区",value:"110111"},{label:"通州区",value:"110112"},{label:"顺义区",value:"110113"},{label:"昌平区",value:"110114"},{label:"大兴区",value:"110115"},{label:"怀柔区",value:"110116"},{label:"平谷区",value:"110117"},{label:"密云区",value:"110118"},{label:"延庆区",value:"110119"}]],[[{label:"和平区",value:"120101"},{label:"河东区",value:"120102"},{label:"河西区",value:"120103"},{label:"南开区",value:"120104"},{label:"河北区",value:"120105"},{label:"红桥区",value:"120106"},{label:"东丽区",value:"120110"},{label:"西青区",value:"120111"},{label:"津南区",value:"120112"},{label:"北辰区",value:"120113"},{label:"武清区",value:"120114"},{label:"宝坻区",value:"120115"},{label:"滨海新区",value:"120116"},{label:"宁河区",value:"120117"},{label:"静海区",value:"120118"},{label:"蓟州区",value:"120119"}]],[[{label:"长安区",value:"130102"},{label:"桥西区",value:"130104"},{label:"新华区",value:"130105"},{label:"井陉矿区",value:"130107"},{label:"裕华区",value:"130108"},{label:"藁城区",value:"130109"},{label:"鹿泉区",value:"130110"},{label:"栾城区",value:"130111"},{label:"井陉县",value:"130121"},{label:"正定县",value:"130123"},{label:"行唐县",value:"130125"},{label:"灵寿县",value:"130126"},{label:"高邑县",value:"130127"},{label:"深泽县",value:"130128"},{label:"赞皇县",value:"130129"},{label:"无极县",value:"130130"},{label:"平山县",value:"130131"},{label:"元氏县",value:"130132"},{label:"赵县",value:"130133"},{label:"石家庄高新技术产业开发区",value:"130171"},{label:"石家庄循环化工园区",value:"130172"},{label:"辛集市",value:"130181"},{label:"晋州市",value:"130183"},{label:"新乐市",value:"130184"}],[{label:"路南区",value:"130202"},{label:"路北区",value:"130203"},{label:"古冶区",value:"130204"},{label:"开平区",value:"130205"},{label:"丰南区",value:"130207"},{label:"丰润区",value:"130208"},{label:"曹妃甸区",value:"130209"},{label:"滦县",value:"130223"},{label:"滦南县",value:"130224"},{label:"乐亭县",value:"130225"},{label:"迁西县",value:"130227"},{label:"玉田县",value:"130229"},{label:"唐山市芦台经济技术开发区",value:"130271"},{label:"唐山市汉沽管理区",value:"130272"},{label:"唐山高新技术产业开发区",value:"130273"},{label:"河北唐山海港经济开发区",value:"130274"},{label:"遵化市",value:"130281"},{label:"迁安市",value:"130283"}],[{label:"海港区",value:"130302"},{label:"山海关区",value:"130303"},{label:"北戴河区",value:"130304"},{label:"抚宁区",value:"130306"},{label:"青龙满族自治县",value:"130321"},{label:"昌黎县",value:"130322"},{label:"卢龙县",value:"130324"},{label:"秦皇岛市经济技术开发区",value:"130371"},{label:"北戴河新区",value:"130372"}],[{label:"邯山区",value:"130402"},{label:"丛台区",value:"130403"},{label:"复兴区",value:"130404"},{label:"峰峰矿区",value:"130406"},{label:"肥乡区",value:"130407"},{label:"永年区",value:"130408"},{label:"临漳县",value:"130423"},{label:"成安县",value:"130424"},{label:"大名县",value:"130425"},{label:"涉县",value:"130426"},{label:"磁县",value:"130427"},{label:"邱县",value:"130430"},{label:"鸡泽县",value:"130431"},{label:"广平县",value:"130432"},{label:"馆陶县",value:"130433"},{label:"魏县",value:"130434"},{label:"曲周县",value:"130435"},{label:"邯郸经济技术开发区",value:"130471"},{label:"邯郸冀南新区",value:"130473"},{label:"武安市",value:"130481"}],[{label:"桥东区",value:"130502"},{label:"桥西区",value:"130503"},{label:"邢台县",value:"130521"},{label:"临城县",value:"130522"},{label:"内丘县",value:"130523"},{label:"柏乡县",value:"130524"},{label:"隆尧县",value:"130525"},{label:"任县",value:"130526"},{label:"南和县",value:"130527"},{label:"宁晋县",value:"130528"},{label:"巨鹿县",value:"130529"},{label:"新河县",value:"130530"},{label:"广宗县",value:"130531"},{label:"平乡县",value:"130532"},{label:"威县",value:"130533"},{label:"清河县",value:"130534"},{label:"临西县",value:"130535"},{label:"河北邢台经济开发区",value:"130571"},{label:"南宫市",value:"130581"},{label:"沙河市",value:"130582"}],[{label:"竞秀区",value:"130602"},{label:"莲池区",value:"130606"},{label:"满城区",value:"130607"},{label:"清苑区",value:"130608"},{label:"徐水区",value:"130609"},{label:"涞水县",value:"130623"},{label:"阜平县",value:"130624"},{label:"定兴县",value:"130626"},{label:"唐县",value:"130627"},{label:"高阳县",value:"130628"},{label:"容城县",value:"130629"},{label:"涞源县",value:"130630"},{label:"望都县",value:"130631"},{label:"安新县",value:"130632"},{label:"易县",value:"130633"},{label:"曲阳县",value:"130634"},{label:"蠡县",value:"130635"},{label:"顺平县",value:"130636"},{label:"博野县",value:"130637"},{label:"雄县",value:"130638"},{label:"保定高新技术产业开发区",value:"130671"},{label:"保定白沟新城",value:"130672"},{label:"涿州市",value:"130681"},{label:"定州市",value:"130682"},{label:"安国市",value:"130683"},{label:"高碑店市",value:"130684"}],[{label:"桥东区",value:"130702"},{label:"桥西区",value:"130703"},{label:"宣化区",value:"130705"},{label:"下花园区",value:"130706"},{label:"万全区",value:"130708"},{label:"崇礼区",value:"130709"},{label:"张北县",value:"130722"},{label:"康保县",value:"130723"},{label:"沽源县",value:"130724"},{label:"尚义县",value:"130725"},{label:"蔚县",value:"130726"},{label:"阳原县",value:"130727"},{label:"怀安县",value:"130728"},{label:"怀来县",value:"130730"},{label:"涿鹿县",value:"130731"},{label:"赤城县",value:"130732"},{label:"张家口市高新技术产业开发区",value:"130771"},{label:"张家口市察北管理区",value:"130772"},{label:"张家口市塞北管理区",value:"130773"}],[{label:"双桥区",value:"130802"},{label:"双滦区",value:"130803"},{label:"鹰手营子矿区",value:"130804"},{label:"承德县",value:"130821"},{label:"兴隆县",value:"130822"},{label:"滦平县",value:"130824"},{label:"隆化县",value:"130825"},{label:"丰宁满族自治县",value:"130826"},{label:"宽城满族自治县",value:"130827"},{label:"围场满族蒙古族自治县",value:"130828"},{label:"承德高新技术产业开发区",value:"130871"},{label:"平泉市",value:"130881"}],[{label:"新华区",value:"130902"},{label:"运河区",value:"130903"},{label:"沧县",value:"130921"},{label:"青县",value:"130922"},{label:"东光县",value:"130923"},{label:"海兴县",value:"130924"},{label:"盐山县",value:"130925"},{label:"肃宁县",value:"130926"},{label:"南皮县",value:"130927"},{label:"吴桥县",value:"130928"},{label:"献县",value:"130929"},{label:"孟村回族自治县",value:"130930"},{label:"河北沧州经济开发区",value:"130971"},{label:"沧州高新技术产业开发区",value:"130972"},{label:"沧州渤海新区",value:"130973"},{label:"泊头市",value:"130981"},{label:"任丘市",value:"130982"},{label:"黄骅市",value:"130983"},{label:"河间市",value:"130984"}],[{label:"安次区",value:"131002"},{label:"广阳区",value:"131003"},{label:"固安县",value:"131022"},{label:"永清县",value:"131023"},{label:"香河县",value:"131024"},{label:"大城县",value:"131025"},{label:"文安县",value:"131026"},{label:"大厂回族自治县",value:"131028"},{label:"廊坊经济技术开发区",value:"131071"},{label:"霸州市",value:"131081"},{label:"三河市",value:"131082"}],[{label:"桃城区",value:"131102"},{label:"冀州区",value:"131103"},{label:"枣强县",value:"131121"},{label:"武邑县",value:"131122"},{label:"武强县",value:"131123"},{label:"饶阳县",value:"131124"},{label:"安平县",value:"131125"},{label:"故城县",value:"131126"},{label:"景县",value:"131127"},{label:"阜城县",value:"131128"},{label:"河北衡水经济开发区",value:"131171"},{label:"衡水滨湖新区",value:"131172"},{label:"深州市",value:"131182"}]],[[{label:"小店区",value:"140105"},{label:"迎泽区",value:"140106"},{label:"杏花岭区",value:"140107"},{label:"尖草坪区",value:"140108"},{label:"万柏林区",value:"140109"},{label:"晋源区",value:"140110"},{label:"清徐县",value:"140121"},{label:"阳曲县",value:"140122"},{label:"娄烦县",value:"140123"},{label:"山西转型综合改革示范区",value:"140171"},{label:"古交市",value:"140181"}],[{label:"城区",value:"140202"},{label:"矿区",value:"140203"},{label:"南郊区",value:"140211"},{label:"新荣区",value:"140212"},{label:"阳高县",value:"140221"},{label:"天镇县",value:"140222"},{label:"广灵县",value:"140223"},{label:"灵丘县",value:"140224"},{label:"浑源县",value:"140225"},{label:"左云县",value:"140226"},{label:"大同县",value:"140227"},{label:"山西大同经济开发区",value:"140271"}],[{label:"城区",value:"140302"},{label:"矿区",value:"140303"},{label:"郊区",value:"140311"},{label:"平定县",value:"140321"},{label:"盂县",value:"140322"},{label:"山西阳泉经济开发区",value:"140371"}],[{label:"城区",value:"140402"},{label:"郊区",value:"140411"},{label:"长治县",value:"140421"},{label:"襄垣县",value:"140423"},{label:"屯留县",value:"140424"},{label:"平顺县",value:"140425"},{label:"黎城县",value:"140426"},{label:"壶关县",value:"140427"},{label:"长子县",value:"140428"},{label:"武乡县",value:"140429"},{label:"沁县",value:"140430"},{label:"沁源县",value:"140431"},{label:"山西长治高新技术产业园区",value:"140471"},{label:"潞城市",value:"140481"}],[{label:"城区",value:"140502"},{label:"沁水县",value:"140521"},{label:"阳城县",value:"140522"},{label:"陵川县",value:"140524"},{label:"泽州县",value:"140525"},{label:"高平市",value:"140581"}],[{label:"朔城区",value:"140602"},{label:"平鲁区",value:"140603"},{label:"山阴县",value:"140621"},{label:"应县",value:"140622"},{label:"右玉县",value:"140623"},{label:"怀仁县",value:"140624"},{label:"山西朔州经济开发区",value:"140671"}],[{label:"榆次区",value:"140702"},{label:"榆社县",value:"140721"},{label:"左权县",value:"140722"},{label:"和顺县",value:"140723"},{label:"昔阳县",value:"140724"},{label:"寿阳县",value:"140725"},{label:"太谷县",value:"140726"},{label:"祁县",value:"140727"},{label:"平遥县",value:"140728"},{label:"灵石县",value:"140729"},{label:"介休市",value:"140781"}],[{label:"盐湖区",value:"140802"},{label:"临猗县",value:"140821"},{label:"万荣县",value:"140822"},{label:"闻喜县",value:"140823"},{label:"稷山县",value:"140824"},{label:"新绛县",value:"140825"},{label:"绛县",value:"140826"},{label:"垣曲县",value:"140827"},{label:"夏县",value:"140828"},{label:"平陆县",value:"140829"},{label:"芮城县",value:"140830"},{label:"永济市",value:"140881"},{label:"河津市",value:"140882"}],[{label:"忻府区",value:"140902"},{label:"定襄县",value:"140921"},{label:"五台县",value:"140922"},{label:"代县",value:"140923"},{label:"繁峙县",value:"140924"},{label:"宁武县",value:"140925"},{label:"静乐县",value:"140926"},{label:"神池县",value:"140927"},{label:"五寨县",value:"140928"},{label:"岢岚县",value:"140929"},{label:"河曲县",value:"140930"},{label:"保德县",value:"140931"},{label:"偏关县",value:"140932"},{label:"五台山风景名胜区",value:"140971"},{label:"原平市",value:"140981"}],[{label:"尧都区",value:"141002"},{label:"曲沃县",value:"141021"},{label:"翼城县",value:"141022"},{label:"襄汾县",value:"141023"},{label:"洪洞县",value:"141024"},{label:"古县",value:"141025"},{label:"安泽县",value:"141026"},{label:"浮山县",value:"141027"},{label:"吉县",value:"141028"},{label:"乡宁县",value:"141029"},{label:"大宁县",value:"141030"},{label:"隰县",value:"141031"},{label:"永和县",value:"141032"},{label:"蒲县",value:"141033"},{label:"汾西县",value:"141034"},{label:"侯马市",value:"141081"},{label:"霍州市",value:"141082"}],[{label:"离石区",value:"141102"},{label:"文水县",value:"141121"},{label:"交城县",value:"141122"},{label:"兴县",value:"141123"},{label:"临县",value:"141124"},{label:"柳林县",value:"141125"},{label:"石楼县",value:"141126"},{label:"岚县",value:"141127"},{label:"方山县",value:"141128"},{label:"中阳县",value:"141129"},{label:"交口县",value:"141130"},{label:"孝义市",value:"141181"},{label:"汾阳市",value:"141182"}]],[[{label:"新城区",value:"150102"},{label:"回民区",value:"150103"},{label:"玉泉区",value:"150104"},{label:"赛罕区",value:"150105"},{label:"土默特左旗",value:"150121"},{label:"托克托县",value:"150122"},{label:"和林格尔县",value:"150123"},{label:"清水河县",value:"150124"},{label:"武川县",value:"150125"},{label:"呼和浩特金海工业园区",value:"150171"},{label:"呼和浩特经济技术开发区",value:"150172"}],[{label:"东河区",value:"150202"},{label:"昆都仑区",value:"150203"},{label:"青山区",value:"150204"},{label:"石拐区",value:"150205"},{label:"白云鄂博矿区",value:"150206"},{label:"九原区",value:"150207"},{label:"土默特右旗",value:"150221"},{label:"固阳县",value:"150222"},{label:"达尔罕茂明安联合旗",value:"150223"},{label:"包头稀土高新技术产业开发区",value:"150271"}],[{label:"海勃湾区",value:"150302"},{label:"海南区",value:"150303"},{label:"乌达区",value:"150304"}],[{label:"红山区",value:"150402"},{label:"元宝山区",value:"150403"},{label:"松山区",value:"150404"},{label:"阿鲁科尔沁旗",value:"150421"},{label:"巴林左旗",value:"150422"},{label:"巴林右旗",value:"150423"},{label:"林西县",value:"150424"},{label:"克什克腾旗",value:"150425"},{label:"翁牛特旗",value:"150426"},{label:"喀喇沁旗",value:"150428"},{label:"宁城县",value:"150429"},{label:"敖汉旗",value:"150430"}],[{label:"科尔沁区",value:"150502"},{label:"科尔沁左翼中旗",value:"150521"},{label:"科尔沁左翼后旗",value:"150522"},{label:"开鲁县",value:"150523"},{label:"库伦旗",value:"150524"},{label:"奈曼旗",value:"150525"},{label:"扎鲁特旗",value:"150526"},{label:"通辽经济技术开发区",value:"150571"},{label:"霍林郭勒市",value:"150581"}],[{label:"东胜区",value:"150602"},{label:"康巴什区",value:"150603"},{label:"达拉特旗",value:"150621"},{label:"准格尔旗",value:"150622"},{label:"鄂托克前旗",value:"150623"},{label:"鄂托克旗",value:"150624"},{label:"杭锦旗",value:"150625"},{label:"乌审旗",value:"150626"},{label:"伊金霍洛旗",value:"150627"}],[{label:"海拉尔区",value:"150702"},{label:"扎赉诺尔区",value:"150703"},{label:"阿荣旗",value:"150721"},{label:"莫力达瓦达斡尔族自治旗",value:"150722"},{label:"鄂伦春自治旗",value:"150723"},{label:"鄂温克族自治旗",value:"150724"},{label:"陈巴尔虎旗",value:"150725"},{label:"新巴尔虎左旗",value:"150726"},{label:"新巴尔虎右旗",value:"150727"},{label:"满洲里市",value:"150781"},{label:"牙克石市",value:"150782"},{label:"扎兰屯市",value:"150783"},{label:"额尔古纳市",value:"150784"},{label:"根河市",value:"150785"}],[{label:"临河区",value:"150802"},{label:"五原县",value:"150821"},{label:"磴口县",value:"150822"},{label:"乌拉特前旗",value:"150823"},{label:"乌拉特中旗",value:"150824"},{label:"乌拉特后旗",value:"150825"},{label:"杭锦后旗",value:"150826"}],[{label:"集宁区",value:"150902"},{label:"卓资县",value:"150921"},{label:"化德县",value:"150922"},{label:"商都县",value:"150923"},{label:"兴和县",value:"150924"},{label:"凉城县",value:"150925"},{label:"察哈尔右翼前旗",value:"150926"},{label:"察哈尔右翼中旗",value:"150927"},{label:"察哈尔右翼后旗",value:"150928"},{label:"四子王旗",value:"150929"},{label:"丰镇市",value:"150981"}],[{label:"乌兰浩特市",value:"152201"},{label:"阿尔山市",value:"152202"},{label:"科尔沁右翼前旗",value:"152221"},{label:"科尔沁右翼中旗",value:"152222"},{label:"扎赉特旗",value:"152223"},{label:"突泉县",value:"152224"}],[{label:"二连浩特市",value:"152501"},{label:"锡林浩特市",value:"152502"},{label:"阿巴嘎旗",value:"152522"},{label:"苏尼特左旗",value:"152523"},{label:"苏尼特右旗",value:"152524"},{label:"东乌珠穆沁旗",value:"152525"},{label:"西乌珠穆沁旗",value:"152526"},{label:"太仆寺旗",value:"152527"},{label:"镶黄旗",value:"152528"},{label:"正镶白旗",value:"152529"},{label:"正蓝旗",value:"152530"},{label:"多伦县",value:"152531"},{label:"乌拉盖管委会",value:"152571"}],[{label:"阿拉善左旗",value:"152921"},{label:"阿拉善右旗",value:"152922"},{label:"额济纳旗",value:"152923"},{label:"内蒙古阿拉善经济开发区",value:"152971"}]],[[{label:"和平区",value:"210102"},{label:"沈河区",value:"210103"},{label:"大东区",value:"210104"},{label:"皇姑区",value:"210105"},{label:"铁西区",value:"210106"},{label:"苏家屯区",value:"210111"},{label:"浑南区",value:"210112"},{label:"沈北新区",value:"210113"},{label:"于洪区",value:"210114"},{label:"辽中区",value:"210115"},{label:"康平县",value:"210123"},{label:"法库县",value:"210124"},{label:"新民市",value:"210181"}],[{label:"中山区",value:"210202"},{label:"西岗区",value:"210203"},{label:"沙河口区",value:"210204"},{label:"甘井子区",value:"210211"},{label:"旅顺口区",value:"210212"},{label:"金州区",value:"210213"},{label:"普兰店区",value:"210214"},{label:"长海县",value:"210224"},{label:"瓦房店市",value:"210281"},{label:"庄河市",value:"210283"}],[{label:"铁东区",value:"210302"},{label:"铁西区",value:"210303"},{label:"立山区",value:"210304"},{label:"千山区",value:"210311"},{label:"台安县",value:"210321"},{label:"岫岩满族自治县",value:"210323"},{label:"海城市",value:"210381"}],[{label:"新抚区",value:"210402"},{label:"东洲区",value:"210403"},{label:"望花区",value:"210404"},{label:"顺城区",value:"210411"},{label:"抚顺县",value:"210421"},{label:"新宾满族自治县",value:"210422"},{label:"清原满族自治县",value:"210423"}],[{label:"平山区",value:"210502"},{label:"溪湖区",value:"210503"},{label:"明山区",value:"210504"},{label:"南芬区",value:"210505"},{label:"本溪满族自治县",value:"210521"},{label:"桓仁满族自治县",value:"210522"}],[{label:"元宝区",value:"210602"},{label:"振兴区",value:"210603"},{label:"振安区",value:"210604"},{label:"宽甸满族自治县",value:"210624"},{label:"东港市",value:"210681"},{label:"凤城市",value:"210682"}],[{label:"古塔区",value:"210702"},{label:"凌河区",value:"210703"},{label:"太和区",value:"210711"},{label:"黑山县",value:"210726"},{label:"义县",value:"210727"},{label:"凌海市",value:"210781"},{label:"北镇市",value:"210782"}],[{label:"站前区",value:"210802"},{label:"西市区",value:"210803"},{label:"鲅鱼圈区",value:"210804"},{label:"老边区",value:"210811"},{label:"盖州市",value:"210881"},{label:"大石桥市",value:"210882"}],[{label:"海州区",value:"210902"},{label:"新邱区",value:"210903"},{label:"太平区",value:"210904"},{label:"清河门区",value:"210905"},{label:"细河区",value:"210911"},{label:"阜新蒙古族自治县",value:"210921"},{label:"彰武县",value:"210922"}],[{label:"白塔区",value:"211002"},{label:"文圣区",value:"211003"},{label:"宏伟区",value:"211004"},{label:"弓长岭区",value:"211005"},{label:"太子河区",value:"211011"},{label:"辽阳县",value:"211021"},{label:"灯塔市",value:"211081"}],[{label:"双台子区",value:"211102"},{label:"兴隆台区",value:"211103"},{label:"大洼区",value:"211104"},{label:"盘山县",value:"211122"}],[{label:"银州区",value:"211202"},{label:"清河区",value:"211204"},{label:"铁岭县",value:"211221"},{label:"西丰县",value:"211223"},{label:"昌图县",value:"211224"},{label:"调兵山市",value:"211281"},{label:"开原市",value:"211282"}],[{label:"双塔区",value:"211302"},{label:"龙城区",value:"211303"},{label:"朝阳县",value:"211321"},{label:"建平县",value:"211322"},{label:"喀喇沁左翼蒙古族自治县",value:"211324"},{label:"北票市",value:"211381"},{label:"凌源市",value:"211382"}],[{label:"连山区",value:"211402"},{label:"龙港区",value:"211403"},{label:"南票区",value:"211404"},{label:"绥中县",value:"211421"},{label:"建昌县",value:"211422"},{label:"兴城市",value:"211481"}]],[[{label:"南关区",value:"220102"},{label:"宽城区",value:"220103"},{label:"朝阳区",value:"220104"},{label:"二道区",value:"220105"},{label:"绿园区",value:"220106"},{label:"双阳区",value:"220112"},{label:"九台区",value:"220113"},{label:"农安县",value:"220122"},{label:"长春经济技术开发区",value:"220171"},{label:"长春净月高新技术产业开发区",value:"220172"},{label:"长春高新技术产业开发区",value:"220173"},{label:"长春汽车经济技术开发区",value:"220174"},{label:"榆树市",value:"220182"},{label:"德惠市",value:"220183"}],[{label:"昌邑区",value:"220202"},{label:"龙潭区",value:"220203"},{label:"船营区",value:"220204"},{label:"丰满区",value:"220211"},{label:"永吉县",value:"220221"},{label:"吉林经济开发区",value:"220271"},{label:"吉林高新技术产业开发区",value:"220272"},{label:"吉林中国新加坡食品区",value:"220273"},{label:"蛟河市",value:"220281"},{label:"桦甸市",value:"220282"},{label:"舒兰市",value:"220283"},{label:"磐石市",value:"220284"}],[{label:"铁西区",value:"220302"},{label:"铁东区",value:"220303"},{label:"梨树县",value:"220322"},{label:"伊通满族自治县",value:"220323"},{label:"公主岭市",value:"220381"},{label:"双辽市",value:"220382"}],[{label:"龙山区",value:"220402"},{label:"西安区",value:"220403"},{label:"东丰县",value:"220421"},{label:"东辽县",value:"220422"}],[{label:"东昌区",value:"220502"},{label:"二道江区",value:"220503"},{label:"通化县",value:"220521"},{label:"辉南县",value:"220523"},{label:"柳河县",value:"220524"},{label:"梅河口市",value:"220581"},{label:"集安市",value:"220582"}],[{label:"浑江区",value:"220602"},{label:"江源区",value:"220605"},{label:"抚松县",value:"220621"},{label:"靖宇县",value:"220622"},{label:"长白朝鲜族自治县",value:"220623"},{label:"临江市",value:"220681"}],[{label:"宁江区",value:"220702"},{label:"前郭尔罗斯蒙古族自治县",value:"220721"},{label:"长岭县",value:"220722"},{label:"乾安县",value:"220723"},{label:"吉林松原经济开发区",value:"220771"},{label:"扶余市",value:"220781"}],[{label:"洮北区",value:"220802"},{label:"镇赉县",value:"220821"},{label:"通榆县",value:"220822"},{label:"吉林白城经济开发区",value:"220871"},{label:"洮南市",value:"220881"},{label:"大安市",value:"220882"}],[{label:"延吉市",value:"222401"},{label:"图们市",value:"222402"},{label:"敦化市",value:"222403"},{label:"珲春市",value:"222404"},{label:"龙井市",value:"222405"},{label:"和龙市",value:"222406"},{label:"汪清县",value:"222424"},{label:"安图县",value:"222426"}]],[[{label:"道里区",value:"230102"},{label:"南岗区",value:"230103"},{label:"道外区",value:"230104"},{label:"平房区",value:"230108"},{label:"松北区",value:"230109"},{label:"香坊区",value:"230110"},{label:"呼兰区",value:"230111"},{label:"阿城区",value:"230112"},{label:"双城区",value:"230113"},{label:"依兰县",value:"230123"},{label:"方正县",value:"230124"},{label:"宾县",value:"230125"},{label:"巴彦县",value:"230126"},{label:"木兰县",value:"230127"},{label:"通河县",value:"230128"},{label:"延寿县",value:"230129"},{label:"尚志市",value:"230183"},{label:"五常市",value:"230184"}],[{label:"龙沙区",value:"230202"},{label:"建华区",value:"230203"},{label:"铁锋区",value:"230204"},{label:"昂昂溪区",value:"230205"},{label:"富拉尔基区",value:"230206"},{label:"碾子山区",value:"230207"},{label:"梅里斯达斡尔族区",value:"230208"},{label:"龙江县",value:"230221"},{label:"依安县",value:"230223"},{label:"泰来县",value:"230224"},{label:"甘南县",value:"230225"},{label:"富裕县",value:"230227"},{label:"克山县",value:"230229"},{label:"克东县",value:"230230"},{label:"拜泉县",value:"230231"},{label:"讷河市",value:"230281"}],[{label:"鸡冠区",value:"230302"},{label:"恒山区",value:"230303"},{label:"滴道区",value:"230304"},{label:"梨树区",value:"230305"},{label:"城子河区",value:"230306"},{label:"麻山区",value:"230307"},{label:"鸡东县",value:"230321"},{label:"虎林市",value:"230381"},{label:"密山市",value:"230382"}],[{label:"向阳区",value:"230402"},{label:"工农区",value:"230403"},{label:"南山区",value:"230404"},{label:"兴安区",value:"230405"},{label:"东山区",value:"230406"},{label:"兴山区",value:"230407"},{label:"萝北县",value:"230421"},{label:"绥滨县",value:"230422"}],[{label:"尖山区",value:"230502"},{label:"岭东区",value:"230503"},{label:"四方台区",value:"230505"},{label:"宝山区",value:"230506"},{label:"集贤县",value:"230521"},{label:"友谊县",value:"230522"},{label:"宝清县",value:"230523"},{label:"饶河县",value:"230524"}],[{label:"萨尔图区",value:"230602"},{label:"龙凤区",value:"230603"},{label:"让胡路区",value:"230604"},{label:"红岗区",value:"230605"},{label:"大同区",value:"230606"},{label:"肇州县",value:"230621"},{label:"肇源县",value:"230622"},{label:"林甸县",value:"230623"},{label:"杜尔伯特蒙古族自治县",value:"230624"},{label:"大庆高新技术产业开发区",value:"230671"}],[{label:"伊春区",value:"230702"},{label:"南岔区",value:"230703"},{label:"友好区",value:"230704"},{label:"西林区",value:"230705"},{label:"翠峦区",value:"230706"},{label:"新青区",value:"230707"},{label:"美溪区",value:"230708"},{label:"金山屯区",value:"230709"},{label:"五营区",value:"230710"},{label:"乌马河区",value:"230711"},{label:"汤旺河区",value:"230712"},{label:"带岭区",value:"230713"},{label:"乌伊岭区",value:"230714"},{label:"红星区",value:"230715"},{label:"上甘岭区",value:"230716"},{label:"嘉荫县",value:"230722"},{label:"铁力市",value:"230781"}],[{label:"向阳区",value:"230803"},{label:"前进区",value:"230804"},{label:"东风区",value:"230805"},{label:"郊区",value:"230811"},{label:"桦南县",value:"230822"},{label:"桦川县",value:"230826"},{label:"汤原县",value:"230828"},{label:"同江市",value:"230881"},{label:"富锦市",value:"230882"},{label:"抚远市",value:"230883"}],[{label:"新兴区",value:"230902"},{label:"桃山区",value:"230903"},{label:"茄子河区",value:"230904"},{label:"勃利县",value:"230921"}],[{label:"东安区",value:"231002"},{label:"阳明区",value:"231003"},{label:"爱民区",value:"231004"},{label:"西安区",value:"231005"},{label:"林口县",value:"231025"},{label:"牡丹江经济技术开发区",value:"231071"},{label:"绥芬河市",value:"231081"},{label:"海林市",value:"231083"},{label:"宁安市",value:"231084"},{label:"穆棱市",value:"231085"},{label:"东宁市",value:"231086"}],[{label:"爱辉区",value:"231102"},{label:"嫩江县",value:"231121"},{label:"逊克县",value:"231123"},{label:"孙吴县",value:"231124"},{label:"北安市",value:"231181"},{label:"五大连池市",value:"231182"}],[{label:"北林区",value:"231202"},{label:"望奎县",value:"231221"},{label:"兰西县",value:"231222"},{label:"青冈县",value:"231223"},{label:"庆安县",value:"231224"},{label:"明水县",value:"231225"},{label:"绥棱县",value:"231226"},{label:"安达市",value:"231281"},{label:"肇东市",value:"231282"},{label:"海伦市",value:"231283"}],[{label:"加格达奇区",value:"232701"},{label:"松岭区",value:"232702"},{label:"新林区",value:"232703"},{label:"呼中区",value:"232704"},{label:"呼玛县",value:"232721"},{label:"塔河县",value:"232722"},{label:"漠河县",value:"232723"}]],[[{label:"黄浦区",value:"310101"},{label:"徐汇区",value:"310104"},{label:"长宁区",value:"310105"},{label:"静安区",value:"310106"},{label:"普陀区",value:"310107"},{label:"虹口区",value:"310109"},{label:"杨浦区",value:"310110"},{label:"闵行区",value:"310112"},{label:"宝山区",value:"310113"},{label:"嘉定区",value:"310114"},{label:"浦东新区",value:"310115"},{label:"金山区",value:"310116"},{label:"松江区",value:"310117"},{label:"青浦区",value:"310118"},{label:"奉贤区",value:"310120"},{label:"崇明区",value:"310151"}]],[[{label:"玄武区",value:"320102"},{label:"秦淮区",value:"320104"},{label:"建邺区",value:"320105"},{label:"鼓楼区",value:"320106"},{label:"浦口区",value:"320111"},{label:"栖霞区",value:"320113"},{label:"雨花台区",value:"320114"},{label:"江宁区",value:"320115"},{label:"六合区",value:"320116"},{label:"溧水区",value:"320117"},{label:"高淳区",value:"320118"}],[{label:"锡山区",value:"320205"},{label:"惠山区",value:"320206"},{label:"滨湖区",value:"320211"},{label:"梁溪区",value:"320213"},{label:"新吴区",value:"320214"},{label:"江阴市",value:"320281"},{label:"宜兴市",value:"320282"}],[{label:"鼓楼区",value:"320302"},{label:"云龙区",value:"320303"},{label:"贾汪区",value:"320305"},{label:"泉山区",value:"320311"},{label:"铜山区",value:"320312"},{label:"丰县",value:"320321"},{label:"沛县",value:"320322"},{label:"睢宁县",value:"320324"},{label:"徐州经济技术开发区",value:"320371"},{label:"新沂市",value:"320381"},{label:"邳州市",value:"320382"}],[{label:"天宁区",value:"320402"},{label:"钟楼区",value:"320404"},{label:"新北区",value:"320411"},{label:"武进区",value:"320412"},{label:"金坛区",value:"320413"},{label:"溧阳市",value:"320481"}],[{label:"虎丘区",value:"320505"},{label:"吴中区",value:"320506"},{label:"相城区",value:"320507"},{label:"姑苏区",value:"320508"},{label:"吴江区",value:"320509"},{label:"苏州工业园区",value:"320571"},{label:"常熟市",value:"320581"},{label:"张家港市",value:"320582"},{label:"昆山市",value:"320583"},{label:"太仓市",value:"320585"}],[{label:"崇川区",value:"320602"},{label:"港闸区",value:"320611"},{label:"通州区",value:"320612"},{label:"海安县",value:"320621"},{label:"如东县",value:"320623"},{label:"南通经济技术开发区",value:"320671"},{label:"启东市",value:"320681"},{label:"如皋市",value:"320682"},{label:"海门市",value:"320684"}],[{label:"连云区",value:"320703"},{label:"海州区",value:"320706"},{label:"赣榆区",value:"320707"},{label:"东海县",value:"320722"},{label:"灌云县",value:"320723"},{label:"灌南县",value:"320724"},{label:"连云港经济技术开发区",value:"320771"},{label:"连云港高新技术产业开发区",value:"320772"}],[{label:"淮安区",value:"320803"},{label:"淮阴区",value:"320804"},{label:"清江浦区",value:"320812"},{label:"洪泽区",value:"320813"},{label:"涟水县",value:"320826"},{label:"盱眙县",value:"320830"},{label:"金湖县",value:"320831"},{label:"淮安经济技术开发区",value:"320871"}],[{label:"亭湖区",value:"320902"},{label:"盐都区",value:"320903"},{label:"大丰区",value:"320904"},{label:"响水县",value:"320921"},{label:"滨海县",value:"320922"},{label:"阜宁县",value:"320923"},{label:"射阳县",value:"320924"},{label:"建湖县",value:"320925"},{label:"盐城经济技术开发区",value:"320971"},{label:"东台市",value:"320981"}],[{label:"广陵区",value:"321002"},{label:"邗江区",value:"321003"},{label:"江都区",value:"321012"},{label:"宝应县",value:"321023"},{label:"扬州经济技术开发区",value:"321071"},{label:"仪征市",value:"321081"},{label:"高邮市",value:"321084"}],[{label:"京口区",value:"321102"},{label:"润州区",value:"321111"},{label:"丹徒区",value:"321112"},{label:"镇江新区",value:"321171"},{label:"丹阳市",value:"321181"},{label:"扬中市",value:"321182"},{label:"句容市",value:"321183"}],[{label:"海陵区",value:"321202"},{label:"高港区",value:"321203"},{label:"姜堰区",value:"321204"},{label:"泰州医药高新技术产业开发区",value:"321271"},{label:"兴化市",value:"321281"},{label:"靖江市",value:"321282"},{label:"泰兴市",value:"321283"}],[{label:"宿城区",value:"321302"},{label:"宿豫区",value:"321311"},{label:"沭阳县",value:"321322"},{label:"泗阳县",value:"321323"},{label:"泗洪县",value:"321324"},{label:"宿迁经济技术开发区",value:"321371"}]],[[{label:"上城区",value:"330102"},{label:"下城区",value:"330103"},{label:"江干区",value:"330104"},{label:"拱墅区",value:"330105"},{label:"西湖区",value:"330106"},{label:"滨江区",value:"330108"},{label:"萧山区",value:"330109"},{label:"余杭区",value:"330110"},{label:"富阳区",value:"330111"},{label:"临安区",value:"330112"},{label:"桐庐县",value:"330122"},{label:"淳安县",value:"330127"},{label:"建德市",value:"330182"}],[{label:"海曙区",value:"330203"},{label:"江北区",value:"330205"},{label:"北仑区",value:"330206"},{label:"镇海区",value:"330211"},{label:"鄞州区",value:"330212"},{label:"奉化区",value:"330213"},{label:"象山县",value:"330225"},{label:"宁海县",value:"330226"},{label:"余姚市",value:"330281"},{label:"慈溪市",value:"330282"}],[{label:"鹿城区",value:"330302"},{label:"龙湾区",value:"330303"},{label:"瓯海区",value:"330304"},{label:"洞头区",value:"330305"},{label:"永嘉县",value:"330324"},{label:"平阳县",value:"330326"},{label:"苍南县",value:"330327"},{label:"文成县",value:"330328"},{label:"泰顺县",value:"330329"},{label:"温州经济技术开发区",value:"330371"},{label:"瑞安市",value:"330381"},{label:"乐清市",value:"330382"}],[{label:"南湖区",value:"330402"},{label:"秀洲区",value:"330411"},{label:"嘉善县",value:"330421"},{label:"海盐县",value:"330424"},{label:"海宁市",value:"330481"},{label:"平湖市",value:"330482"},{label:"桐乡市",value:"330483"}],[{label:"吴兴区",value:"330502"},{label:"南浔区",value:"330503"},{label:"德清县",value:"330521"},{label:"长兴县",value:"330522"},{label:"安吉县",value:"330523"}],[{label:"越城区",value:"330602"},{label:"柯桥区",value:"330603"},{label:"上虞区",value:"330604"},{label:"新昌县",value:"330624"},{label:"诸暨市",value:"330681"},{label:"嵊州市",value:"330683"}],[{label:"婺城区",value:"330702"},{label:"金东区",value:"330703"},{label:"武义县",value:"330723"},{label:"浦江县",value:"330726"},{label:"磐安县",value:"330727"},{label:"兰溪市",value:"330781"},{label:"义乌市",value:"330782"},{label:"东阳市",value:"330783"},{label:"永康市",value:"330784"}],[{label:"柯城区",value:"330802"},{label:"衢江区",value:"330803"},{label:"常山县",value:"330822"},{label:"开化县",value:"330824"},{label:"龙游县",value:"330825"},{label:"江山市",value:"330881"}],[{label:"定海区",value:"330902"},{label:"普陀区",value:"330903"},{label:"岱山县",value:"330921"},{label:"嵊泗县",value:"330922"}],[{label:"椒江区",value:"331002"},{label:"黄岩区",value:"331003"},{label:"路桥区",value:"331004"},{label:"三门县",value:"331022"},{label:"天台县",value:"331023"},{label:"仙居县",value:"331024"},{label:"温岭市",value:"331081"},{label:"临海市",value:"331082"},{label:"玉环市",value:"331083"}],[{label:"莲都区",value:"331102"},{label:"青田县",value:"331121"},{label:"缙云县",value:"331122"},{label:"遂昌县",value:"331123"},{label:"松阳县",value:"331124"},{label:"云和县",value:"331125"},{label:"庆元县",value:"331126"},{label:"景宁畲族自治县",value:"331127"},{label:"龙泉市",value:"331181"}]],[[{label:"瑶海区",value:"340102"},{label:"庐阳区",value:"340103"},{label:"蜀山区",value:"340104"},{label:"包河区",value:"340111"},{label:"长丰县",value:"340121"},{label:"肥东县",value:"340122"},{label:"肥西县",value:"340123"},{label:"庐江县",value:"340124"},{label:"合肥高新技术产业开发区",value:"340171"},{label:"合肥经济技术开发区",value:"340172"},{label:"合肥新站高新技术产业开发区",value:"340173"},{label:"巢湖市",value:"340181"}],[{label:"镜湖区",value:"340202"},{label:"弋江区",value:"340203"},{label:"鸠江区",value:"340207"},{label:"三山区",value:"340208"},{label:"芜湖县",value:"340221"},{label:"繁昌县",value:"340222"},{label:"南陵县",value:"340223"},{label:"无为县",value:"340225"},{label:"芜湖经济技术开发区",value:"340271"},{label:"安徽芜湖长江大桥经济开发区",value:"340272"}],[{label:"龙子湖区",value:"340302"},{label:"蚌山区",value:"340303"},{label:"禹会区",value:"340304"},{label:"淮上区",value:"340311"},{label:"怀远县",value:"340321"},{label:"五河县",value:"340322"},{label:"固镇县",value:"340323"},{label:"蚌埠市高新技术开发区",value:"340371"},{label:"蚌埠市经济开发区",value:"340372"}],[{label:"大通区",value:"340402"},{label:"田家庵区",value:"340403"},{label:"谢家集区",value:"340404"},{label:"八公山区",value:"340405"},{label:"潘集区",value:"340406"},{label:"凤台县",value:"340421"},{label:"寿县",value:"340422"}],[{label:"花山区",value:"340503"},{label:"雨山区",value:"340504"},{label:"博望区",value:"340506"},{label:"当涂县",value:"340521"},{label:"含山县",value:"340522"},{label:"和县",value:"340523"}],[{label:"杜集区",value:"340602"},{label:"相山区",value:"340603"},{label:"烈山区",value:"340604"},{label:"濉溪县",value:"340621"}],[{label:"铜官区",value:"340705"},{label:"义安区",value:"340706"},{label:"郊区",value:"340711"},{label:"枞阳县",value:"340722"}],[{label:"迎江区",value:"340802"},{label:"大观区",value:"340803"},{label:"宜秀区",value:"340811"},{label:"怀宁县",value:"340822"},{label:"潜山县",value:"340824"},{label:"太湖县",value:"340825"},{label:"宿松县",value:"340826"},{label:"望江县",value:"340827"},{label:"岳西县",value:"340828"},{label:"安徽安庆经济开发区",value:"340871"},{label:"桐城市",value:"340881"}],[{label:"屯溪区",value:"341002"},{label:"黄山区",value:"341003"},{label:"徽州区",value:"341004"},{label:"歙县",value:"341021"},{label:"休宁县",value:"341022"},{label:"黟县",value:"341023"},{label:"祁门县",value:"341024"}],[{label:"琅琊区",value:"341102"},{label:"南谯区",value:"341103"},{label:"来安县",value:"341122"},{label:"全椒县",value:"341124"},{label:"定远县",value:"341125"},{label:"凤阳县",value:"341126"},{label:"苏滁现代产业园",value:"341171"},{label:"滁州经济技术开发区",value:"341172"},{label:"天长市",value:"341181"},{label:"明光市",value:"341182"}],[{label:"颍州区",value:"341202"},{label:"颍东区",value:"341203"},{label:"颍泉区",value:"341204"},{label:"临泉县",value:"341221"},{label:"太和县",value:"341222"},{label:"阜南县",value:"341225"},{label:"颍上县",value:"341226"},{label:"阜阳合肥现代产业园区",value:"341271"},{label:"阜阳经济技术开发区",value:"341272"},{label:"界首市",value:"341282"}],[{label:"埇桥区",value:"341302"},{label:"砀山县",value:"341321"},{label:"萧县",value:"341322"},{label:"灵璧县",value:"341323"},{label:"泗县",value:"341324"},{label:"宿州马鞍山现代产业园区",value:"341371"},{label:"宿州经济技术开发区",value:"341372"}],[{label:"金安区",value:"341502"},{label:"裕安区",value:"341503"},{label:"叶集区",value:"341504"},{label:"霍邱县",value:"341522"},{label:"舒城县",value:"341523"},{label:"金寨县",value:"341524"},{label:"霍山县",value:"341525"}],[{label:"谯城区",value:"341602"},{label:"涡阳县",value:"341621"},{label:"蒙城县",value:"341622"},{label:"利辛县",value:"341623"}],[{label:"贵池区",value:"341702"},{label:"东至县",value:"341721"},{label:"石台县",value:"341722"},{label:"青阳县",value:"341723"}],[{label:"宣州区",value:"341802"},{label:"郎溪县",value:"341821"},{label:"广德县",value:"341822"},{label:"泾县",value:"341823"},{label:"绩溪县",value:"341824"},{label:"旌德县",value:"341825"},{label:"宣城市经济开发区",value:"341871"},{label:"宁国市",value:"341881"}]],[[{label:"鼓楼区",value:"350102"},{label:"台江区",value:"350103"},{label:"仓山区",value:"350104"},{label:"马尾区",value:"350105"},{label:"晋安区",value:"350111"},{label:"闽侯县",value:"350121"},{label:"连江县",value:"350122"},{label:"罗源县",value:"350123"},{label:"闽清县",value:"350124"},{label:"永泰县",value:"350125"},{label:"平潭县",value:"350128"},{label:"福清市",value:"350181"},{label:"长乐市",value:"350182"}],[{label:"思明区",value:"350203"},{label:"海沧区",value:"350205"},{label:"湖里区",value:"350206"},{label:"集美区",value:"350211"},{label:"同安区",value:"350212"},{label:"翔安区",value:"350213"}],[{label:"城厢区",value:"350302"},{label:"涵江区",value:"350303"},{label:"荔城区",value:"350304"},{label:"秀屿区",value:"350305"},{label:"仙游县",value:"350322"}],[{label:"梅列区",value:"350402"},{label:"三元区",value:"350403"},{label:"明溪县",value:"350421"},{label:"清流县",value:"350423"},{label:"宁化县",value:"350424"},{label:"大田县",value:"350425"},{label:"尤溪县",value:"350426"},{label:"沙县",value:"350427"},{label:"将乐县",value:"350428"},{label:"泰宁县",value:"350429"},{label:"建宁县",value:"350430"},{label:"永安市",value:"350481"}],[{label:"鲤城区",value:"350502"},{label:"丰泽区",value:"350503"},{label:"洛江区",value:"350504"},{label:"泉港区",value:"350505"},{label:"惠安县",value:"350521"},{label:"安溪县",value:"350524"},{label:"永春县",value:"350525"},{label:"德化县",value:"350526"},{label:"金门县",value:"350527"},{label:"石狮市",value:"350581"},{label:"晋江市",value:"350582"},{label:"南安市",value:"350583"}],[{label:"芗城区",value:"350602"},{label:"龙文区",value:"350603"},{label:"云霄县",value:"350622"},{label:"漳浦县",value:"350623"},{label:"诏安县",value:"350624"},{label:"长泰县",value:"350625"},{label:"东山县",value:"350626"},{label:"南靖县",value:"350627"},{label:"平和县",value:"350628"},{label:"华安县",value:"350629"},{label:"龙海市",value:"350681"}],[{label:"延平区",value:"350702"},{label:"建阳区",value:"350703"},{label:"顺昌县",value:"350721"},{label:"浦城县",value:"350722"},{label:"光泽县",value:"350723"},{label:"松溪县",value:"350724"},{label:"政和县",value:"350725"},{label:"邵武市",value:"350781"},{label:"武夷山市",value:"350782"},{label:"建瓯市",value:"350783"}],[{label:"新罗区",value:"350802"},{label:"永定区",value:"350803"},{label:"长汀县",value:"350821"},{label:"上杭县",value:"350823"},{label:"武平县",value:"350824"},{label:"连城县",value:"350825"},{label:"漳平市",value:"350881"}],[{label:"蕉城区",value:"350902"},{label:"霞浦县",value:"350921"},{label:"古田县",value:"350922"},{label:"屏南县",value:"350923"},{label:"寿宁县",value:"350924"},{label:"周宁县",value:"350925"},{label:"柘荣县",value:"350926"},{label:"福安市",value:"350981"},{label:"福鼎市",value:"350982"}]],[[{label:"东湖区",value:"360102"},{label:"西湖区",value:"360103"},{label:"青云谱区",value:"360104"},{label:"湾里区",value:"360105"},{label:"青山湖区",value:"360111"},{label:"新建区",value:"360112"},{label:"南昌县",value:"360121"},{label:"安义县",value:"360123"},{label:"进贤县",value:"360124"}],[{label:"昌江区",value:"360202"},{label:"珠山区",value:"360203"},{label:"浮梁县",value:"360222"},{label:"乐平市",value:"360281"}],[{label:"安源区",value:"360302"},{label:"湘东区",value:"360313"},{label:"莲花县",value:"360321"},{label:"上栗县",value:"360322"},{label:"芦溪县",value:"360323"}],[{label:"濂溪区",value:"360402"},{label:"浔阳区",value:"360403"},{label:"柴桑区",value:"360404"},{label:"武宁县",value:"360423"},{label:"修水县",value:"360424"},{label:"永修县",value:"360425"},{label:"德安县",value:"360426"},{label:"都昌县",value:"360428"},{label:"湖口县",value:"360429"},{label:"彭泽县",value:"360430"},{label:"瑞昌市",value:"360481"},{label:"共青城市",value:"360482"},{label:"庐山市",value:"360483"}],[{label:"渝水区",value:"360502"},{label:"分宜县",value:"360521"}],[{label:"月湖区",value:"360602"},{label:"余江县",value:"360622"},{label:"贵溪市",value:"360681"}],[{label:"章贡区",value:"360702"},{label:"南康区",value:"360703"},{label:"赣县区",value:"360704"},{label:"信丰县",value:"360722"},{label:"大余县",value:"360723"},{label:"上犹县",value:"360724"},{label:"崇义县",value:"360725"},{label:"安远县",value:"360726"},{label:"龙南县",value:"360727"},{label:"定南县",value:"360728"},{label:"全南县",value:"360729"},{label:"宁都县",value:"360730"},{label:"于都县",value:"360731"},{label:"兴国县",value:"360732"},{label:"会昌县",value:"360733"},{label:"寻乌县",value:"360734"},{label:"石城县",value:"360735"},{label:"瑞金市",value:"360781"}],[{label:"吉州区",value:"360802"},{label:"青原区",value:"360803"},{label:"吉安县",value:"360821"},{label:"吉水县",value:"360822"},{label:"峡江县",value:"360823"},{label:"新干县",value:"360824"},{label:"永丰县",value:"360825"},{label:"泰和县",value:"360826"},{label:"遂川县",value:"360827"},{label:"万安县",value:"360828"},{label:"安福县",value:"360829"},{label:"永新县",value:"360830"},{label:"井冈山市",value:"360881"}],[{label:"袁州区",value:"360902"},{label:"奉新县",value:"360921"},{label:"万载县",value:"360922"},{label:"上高县",value:"360923"},{label:"宜丰县",value:"360924"},{label:"靖安县",value:"360925"},{label:"铜鼓县",value:"360926"},{label:"丰城市",value:"360981"},{label:"樟树市",value:"360982"},{label:"高安市",value:"360983"}],[{label:"临川区",value:"361002"},{label:"东乡区",value:"361003"},{label:"南城县",value:"361021"},{label:"黎川县",value:"361022"},{label:"南丰县",value:"361023"},{label:"崇仁县",value:"361024"},{label:"乐安县",value:"361025"},{label:"宜黄县",value:"361026"},{label:"金溪县",value:"361027"},{label:"资溪县",value:"361028"},{label:"广昌县",value:"361030"}],[{label:"信州区",value:"361102"},{label:"广丰区",value:"361103"},{label:"上饶县",value:"361121"},{label:"玉山县",value:"361123"},{label:"铅山县",value:"361124"},{label:"横峰县",value:"361125"},{label:"弋阳县",value:"361126"},{label:"余干县",value:"361127"},{label:"鄱阳县",value:"361128"},{label:"万年县",value:"361129"},{label:"婺源县",value:"361130"},{label:"德兴市",value:"361181"}]],[[{label:"历下区",value:"370102"},{label:"市中区",value:"370103"},{label:"槐荫区",value:"370104"},{label:"天桥区",value:"370105"},{label:"历城区",value:"370112"},{label:"长清区",value:"370113"},{label:"章丘区",value:"370114"},{label:"平阴县",value:"370124"},{label:"济阳县",value:"370125"},{label:"商河县",value:"370126"},{label:"济南高新技术产业开发区",value:"370171"}],[{label:"市南区",value:"370202"},{label:"市北区",value:"370203"},{label:"黄岛区",value:"370211"},{label:"崂山区",value:"370212"},{label:"李沧区",value:"370213"},{label:"城阳区",value:"370214"},{label:"即墨区",value:"370215"},{label:"青岛高新技术产业开发区",value:"370271"},{label:"胶州市",value:"370281"},{label:"平度市",value:"370283"},{label:"莱西市",value:"370285"}],[{label:"淄川区",value:"370302"},{label:"张店区",value:"370303"},{label:"博山区",value:"370304"},{label:"临淄区",value:"370305"},{label:"周村区",value:"370306"},{label:"桓台县",value:"370321"},{label:"高青县",value:"370322"},{label:"沂源县",value:"370323"}],[{label:"市中区",value:"370402"},{label:"薛城区",value:"370403"},{label:"峄城区",value:"370404"},{label:"台儿庄区",value:"370405"},{label:"山亭区",value:"370406"},{label:"滕州市",value:"370481"}],[{label:"东营区",value:"370502"},{label:"河口区",value:"370503"},{label:"垦利区",value:"370505"},{label:"利津县",value:"370522"},{label:"广饶县",value:"370523"},{label:"东营经济技术开发区",value:"370571"},{label:"东营港经济开发区",value:"370572"}],[{label:"芝罘区",value:"370602"},{label:"福山区",value:"370611"},{label:"牟平区",value:"370612"},{label:"莱山区",value:"370613"},{label:"长岛县",value:"370634"},{label:"烟台高新技术产业开发区",value:"370671"},{label:"烟台经济技术开发区",value:"370672"},{label:"龙口市",value:"370681"},{label:"莱阳市",value:"370682"},{label:"莱州市",value:"370683"},{label:"蓬莱市",value:"370684"},{label:"招远市",value:"370685"},{label:"栖霞市",value:"370686"},{label:"海阳市",value:"370687"}],[{label:"潍城区",value:"370702"},{label:"寒亭区",value:"370703"},{label:"坊子区",value:"370704"},{label:"奎文区",value:"370705"},{label:"临朐县",value:"370724"},{label:"昌乐县",value:"370725"},{label:"潍坊滨海经济技术开发区",value:"370772"},{label:"青州市",value:"370781"},{label:"诸城市",value:"370782"},{label:"寿光市",value:"370783"},{label:"安丘市",value:"370784"},{label:"高密市",value:"370785"},{label:"昌邑市",value:"370786"}],[{label:"任城区",value:"370811"},{label:"兖州区",value:"370812"},{label:"微山县",value:"370826"},{label:"鱼台县",value:"370827"},{label:"金乡县",value:"370828"},{label:"嘉祥县",value:"370829"},{label:"汶上县",value:"370830"},{label:"泗水县",value:"370831"},{label:"梁山县",value:"370832"},{label:"济宁高新技术产业开发区",value:"370871"},{label:"曲阜市",value:"370881"},{label:"邹城市",value:"370883"}],[{label:"泰山区",value:"370902"},{label:"岱岳区",value:"370911"},{label:"宁阳县",value:"370921"},{label:"东平县",value:"370923"},{label:"新泰市",value:"370982"},{label:"肥城市",value:"370983"}],[{label:"环翠区",value:"371002"},{label:"文登区",value:"371003"},{label:"威海火炬高技术产业开发区",value:"371071"},{label:"威海经济技术开发区",value:"371072"},{label:"威海临港经济技术开发区",value:"371073"},{label:"荣成市",value:"371082"},{label:"乳山市",value:"371083"}],[{label:"东港区",value:"371102"},{label:"岚山区",value:"371103"},{label:"五莲县",value:"371121"},{label:"莒县",value:"371122"},{label:"日照经济技术开发区",value:"371171"},{label:"日照国际海洋城",value:"371172"}],[{label:"莱城区",value:"371202"},{label:"钢城区",value:"371203"}],[{label:"兰山区",value:"371302"},{label:"罗庄区",value:"371311"},{label:"河东区",value:"371312"},{label:"沂南县",value:"371321"},{label:"郯城县",value:"371322"},{label:"沂水县",value:"371323"},{label:"兰陵县",value:"371324"},{label:"费县",value:"371325"},{label:"平邑县",value:"371326"},{label:"莒南县",value:"371327"},{label:"蒙阴县",value:"371328"},{label:"临沭县",value:"371329"},{label:"临沂高新技术产业开发区",value:"371371"},{label:"临沂经济技术开发区",value:"371372"},{label:"临沂临港经济开发区",value:"371373"}],[{label:"德城区",value:"371402"},{label:"陵城区",value:"371403"},{label:"宁津县",value:"371422"},{label:"庆云县",value:"371423"},{label:"临邑县",value:"371424"},{label:"齐河县",value:"371425"},{label:"平原县",value:"371426"},{label:"夏津县",value:"371427"},{label:"武城县",value:"371428"},{label:"德州经济技术开发区",value:"371471"},{label:"德州运河经济开发区",value:"371472"},{label:"乐陵市",value:"371481"},{label:"禹城市",value:"371482"}],[{label:"东昌府区",value:"371502"},{label:"阳谷县",value:"371521"},{label:"莘县",value:"371522"},{label:"茌平县",value:"371523"},{label:"东阿县",value:"371524"},{label:"冠县",value:"371525"},{label:"高唐县",value:"371526"},{label:"临清市",value:"371581"}],[{label:"滨城区",value:"371602"},{label:"沾化区",value:"371603"},{label:"惠民县",value:"371621"},{label:"阳信县",value:"371622"},{label:"无棣县",value:"371623"},{label:"博兴县",value:"371625"},{label:"邹平县",value:"371626"}],[{label:"牡丹区",value:"371702"},{label:"定陶区",value:"371703"},{label:"曹县",value:"371721"},{label:"单县",value:"371722"},{label:"成武县",value:"371723"},{label:"巨野县",value:"371724"},{label:"郓城县",value:"371725"},{label:"鄄城县",value:"371726"},{label:"东明县",value:"371728"},{label:"菏泽经济技术开发区",value:"371771"},{label:"菏泽高新技术开发区",value:"371772"}]],[[{label:"中原区",value:"410102"},{label:"二七区",value:"410103"},{label:"管城回族区",value:"410104"},{label:"金水区",value:"410105"},{label:"上街区",value:"410106"},{label:"惠济区",value:"410108"},{label:"中牟县",value:"410122"},{label:"郑州经济技术开发区",value:"410171"},{label:"郑州高新技术产业开发区",value:"410172"},{label:"郑州航空港经济综合实验区",value:"410173"},{label:"巩义市",value:"410181"},{label:"荥阳市",value:"410182"},{label:"新密市",value:"410183"},{label:"新郑市",value:"410184"},{label:"登封市",value:"410185"}],[{label:"龙亭区",value:"410202"},{label:"顺河回族区",value:"410203"},{label:"鼓楼区",value:"410204"},{label:"禹王台区",value:"410205"},{label:"祥符区",value:"410212"},{label:"杞县",value:"410221"},{label:"通许县",value:"410222"},{label:"尉氏县",value:"410223"},{label:"兰考县",value:"410225"}],[{label:"老城区",value:"410302"},{label:"西工区",value:"410303"},{label:"瀍河回族区",value:"410304"},{label:"涧西区",value:"410305"},{label:"吉利区",value:"410306"},{label:"洛龙区",value:"410311"},{label:"孟津县",value:"410322"},{label:"新安县",value:"410323"},{label:"栾川县",value:"410324"},{label:"嵩县",value:"410325"},{label:"汝阳县",value:"410326"},{label:"宜阳县",value:"410327"},{label:"洛宁县",value:"410328"},{label:"伊川县",value:"410329"},{label:"洛阳高新技术产业开发区",value:"410371"},{label:"偃师市",value:"410381"}],[{label:"新华区",value:"410402"},{label:"卫东区",value:"410403"},{label:"石龙区",value:"410404"},{label:"湛河区",value:"410411"},{label:"宝丰县",value:"410421"},{label:"叶县",value:"410422"},{label:"鲁山县",value:"410423"},{label:"郏县",value:"410425"},{label:"平顶山高新技术产业开发区",value:"410471"},{label:"平顶山市新城区",value:"410472"},{label:"舞钢市",value:"410481"},{label:"汝州市",value:"410482"}],[{label:"文峰区",value:"410502"},{label:"北关区",value:"410503"},{label:"殷都区",value:"410505"},{label:"龙安区",value:"410506"},{label:"安阳县",value:"410522"},{label:"汤阴县",value:"410523"},{label:"滑县",value:"410526"},{label:"内黄县",value:"410527"},{label:"安阳高新技术产业开发区",value:"410571"},{label:"林州市",value:"410581"}],[{label:"鹤山区",value:"410602"},{label:"山城区",value:"410603"},{label:"淇滨区",value:"410611"},{label:"浚县",value:"410621"},{label:"淇县",value:"410622"},{label:"鹤壁经济技术开发区",value:"410671"}],[{label:"红旗区",value:"410702"},{label:"卫滨区",value:"410703"},{label:"凤泉区",value:"410704"},{label:"牧野区",value:"410711"},{label:"新乡县",value:"410721"},{label:"获嘉县",value:"410724"},{label:"原阳县",value:"410725"},{label:"延津县",value:"410726"},{label:"封丘县",value:"410727"},{label:"长垣县",value:"410728"},{label:"新乡高新技术产业开发区",value:"410771"},{label:"新乡经济技术开发区",value:"410772"},{label:"新乡市平原城乡一体化示范区",value:"410773"},{label:"卫辉市",value:"410781"},{label:"辉县市",value:"410782"}],[{label:"解放区",value:"410802"},{label:"中站区",value:"410803"},{label:"马村区",value:"410804"},{label:"山阳区",value:"410811"},{label:"修武县",value:"410821"},{label:"博爱县",value:"410822"},{label:"武陟县",value:"410823"},{label:"温县",value:"410825"},{label:"焦作城乡一体化示范区",value:"410871"},{label:"沁阳市",value:"410882"},{label:"孟州市",value:"410883"}],[{label:"华龙区",value:"410902"},{label:"清丰县",value:"410922"},{label:"南乐县",value:"410923"},{label:"范县",value:"410926"},{label:"台前县",value:"410927"},{label:"濮阳县",value:"410928"},{label:"河南濮阳工业园区",value:"410971"},{label:"濮阳经济技术开发区",value:"410972"}],[{label:"魏都区",value:"411002"},{label:"建安区",value:"411003"},{label:"鄢陵县",value:"411024"},{label:"襄城县",value:"411025"},{label:"许昌经济技术开发区",value:"411071"},{label:"禹州市",value:"411081"},{label:"长葛市",value:"411082"}],[{label:"源汇区",value:"411102"},{label:"郾城区",value:"411103"},{label:"召陵区",value:"411104"},{label:"舞阳县",value:"411121"},{label:"临颍县",value:"411122"},{label:"漯河经济技术开发区",value:"411171"}],[{label:"湖滨区",value:"411202"},{label:"陕州区",value:"411203"},{label:"渑池县",value:"411221"},{label:"卢氏县",value:"411224"},{label:"河南三门峡经济开发区",value:"411271"},{label:"义马市",value:"411281"},{label:"灵宝市",value:"411282"}],[{label:"宛城区",value:"411302"},{label:"卧龙区",value:"411303"},{label:"南召县",value:"411321"},{label:"方城县",value:"411322"},{label:"西峡县",value:"411323"},{label:"镇平县",value:"411324"},{label:"内乡县",value:"411325"},{label:"淅川县",value:"411326"},{label:"社旗县",value:"411327"},{label:"唐河县",value:"411328"},{label:"新野县",value:"411329"},{label:"桐柏县",value:"411330"},{label:"南阳高新技术产业开发区",value:"411371"},{label:"南阳市城乡一体化示范区",value:"411372"},{label:"邓州市",value:"411381"}],[{label:"梁园区",value:"411402"},{label:"睢阳区",value:"411403"},{label:"民权县",value:"411421"},{label:"睢县",value:"411422"},{label:"宁陵县",value:"411423"},{label:"柘城县",value:"411424"},{label:"虞城县",value:"411425"},{label:"夏邑县",value:"411426"},{label:"豫东综合物流产业聚集区",value:"411471"},{label:"河南商丘经济开发区",value:"411472"},{label:"永城市",value:"411481"}],[{label:"浉河区",value:"411502"},{label:"平桥区",value:"411503"},{label:"罗山县",value:"411521"},{label:"光山县",value:"411522"},{label:"新县",value:"411523"},{label:"商城县",value:"411524"},{label:"固始县",value:"411525"},{label:"潢川县",value:"411526"},{label:"淮滨县",value:"411527"},{label:"息县",value:"411528"},{label:"信阳高新技术产业开发区",value:"411571"}],[{label:"川汇区",value:"411602"},{label:"扶沟县",value:"411621"},{label:"西华县",value:"411622"},{label:"商水县",value:"411623"},{label:"沈丘县",value:"411624"},{label:"郸城县",value:"411625"},{label:"淮阳县",value:"411626"},{label:"太康县",value:"411627"},{label:"鹿邑县",value:"411628"},{label:"河南周口经济开发区",value:"411671"},{label:"项城市",value:"411681"}],[{label:"驿城区",value:"411702"},{label:"西平县",value:"411721"},{label:"上蔡县",value:"411722"},{label:"平舆县",value:"411723"},{label:"正阳县",value:"411724"},{label:"确山县",value:"411725"},{label:"泌阳县",value:"411726"},{label:"汝南县",value:"411727"},{label:"遂平县",value:"411728"},{label:"新蔡县",value:"411729"},{label:"河南驻马店经济开发区",value:"411771"}],[{label:"济源市",value:"419001"}]],[[{label:"江岸区",value:"420102"},{label:"江汉区",value:"420103"},{label:"硚口区",value:"420104"},{label:"汉阳区",value:"420105"},{label:"武昌区",value:"420106"},{label:"青山区",value:"420107"},{label:"洪山区",value:"420111"},{label:"东西湖区",value:"420112"},{label:"汉南区",value:"420113"},{label:"蔡甸区",value:"420114"},{label:"江夏区",value:"420115"},{label:"黄陂区",value:"420116"},{label:"新洲区",value:"420117"}],[{label:"黄石港区",value:"420202"},{label:"西塞山区",value:"420203"},{label:"下陆区",value:"420204"},{label:"铁山区",value:"420205"},{label:"阳新县",value:"420222"},{label:"大冶市",value:"420281"}],[{label:"茅箭区",value:"420302"},{label:"张湾区",value:"420303"},{label:"郧阳区",value:"420304"},{label:"郧西县",value:"420322"},{label:"竹山县",value:"420323"},{label:"竹溪县",value:"420324"},{label:"房县",value:"420325"},{label:"丹江口市",value:"420381"}],[{label:"西陵区",value:"420502"},{label:"伍家岗区",value:"420503"},{label:"点军区",value:"420504"},{label:"猇亭区",value:"420505"},{label:"夷陵区",value:"420506"},{label:"远安县",value:"420525"},{label:"兴山县",value:"420526"},{label:"秭归县",value:"420527"},{label:"长阳土家族自治县",value:"420528"},{label:"五峰土家族自治县",value:"420529"},{label:"宜都市",value:"420581"},{label:"当阳市",value:"420582"},{label:"枝江市",value:"420583"}],[{label:"襄城区",value:"420602"},{label:"樊城区",value:"420606"},{label:"襄州区",value:"420607"},{label:"南漳县",value:"420624"},{label:"谷城县",value:"420625"},{label:"保康县",value:"420626"},{label:"老河口市",value:"420682"},{label:"枣阳市",value:"420683"},{label:"宜城市",value:"420684"}],[{label:"梁子湖区",value:"420702"},{label:"华容区",value:"420703"},{label:"鄂城区",value:"420704"}],[{label:"东宝区",value:"420802"},{label:"掇刀区",value:"420804"},{label:"京山县",value:"420821"},{label:"沙洋县",value:"420822"},{label:"钟祥市",value:"420881"}],[{label:"孝南区",value:"420902"},{label:"孝昌县",value:"420921"},{label:"大悟县",value:"420922"},{label:"云梦县",value:"420923"},{label:"应城市",value:"420981"},{label:"安陆市",value:"420982"},{label:"汉川市",value:"420984"}],[{label:"沙市区",value:"421002"},{label:"荆州区",value:"421003"},{label:"公安县",value:"421022"},{label:"监利县",value:"421023"},{label:"江陵县",value:"421024"},{label:"荆州经济技术开发区",value:"421071"},{label:"石首市",value:"421081"},{label:"洪湖市",value:"421083"},{label:"松滋市",value:"421087"}],[{label:"黄州区",value:"421102"},{label:"团风县",value:"421121"},{label:"红安县",value:"421122"},{label:"罗田县",value:"421123"},{label:"英山县",value:"421124"},{label:"浠水县",value:"421125"},{label:"蕲春县",value:"421126"},{label:"黄梅县",value:"421127"},{label:"龙感湖管理区",value:"421171"},{label:"麻城市",value:"421181"},{label:"武穴市",value:"421182"}],[{label:"咸安区",value:"421202"},{label:"嘉鱼县",value:"421221"},{label:"通城县",value:"421222"},{label:"崇阳县",value:"421223"},{label:"通山县",value:"421224"},{label:"赤壁市",value:"421281"}],[{label:"曾都区",value:"421303"},{label:"随县",value:"421321"},{label:"广水市",value:"421381"}],[{label:"恩施市",value:"422801"},{label:"利川市",value:"422802"},{label:"建始县",value:"422822"},{label:"巴东县",value:"422823"},{label:"宣恩县",value:"422825"},{label:"咸丰县",value:"422826"},{label:"来凤县",value:"422827"},{label:"鹤峰县",value:"422828"}],[{label:"仙桃市",value:"429004"},{label:"潜江市",value:"429005"},{label:"天门市",value:"429006"},{label:"神农架林区",value:"429021"}]],[[{label:"芙蓉区",value:"430102"},{label:"天心区",value:"430103"},{label:"岳麓区",value:"430104"},{label:"开福区",value:"430105"},{label:"雨花区",value:"430111"},{label:"望城区",value:"430112"},{label:"长沙县",value:"430121"},{label:"浏阳市",value:"430181"},{label:"宁乡市",value:"430182"}],[{label:"荷塘区",value:"430202"},{label:"芦淞区",value:"430203"},{label:"石峰区",value:"430204"},{label:"天元区",value:"430211"},{label:"株洲县",value:"430221"},{label:"攸县",value:"430223"},{label:"茶陵县",value:"430224"},{label:"炎陵县",value:"430225"},{label:"云龙示范区",value:"430271"},{label:"醴陵市",value:"430281"}],[{label:"雨湖区",value:"430302"},{label:"岳塘区",value:"430304"},{label:"湘潭县",value:"430321"},{label:"湖南湘潭高新技术产业园区",value:"430371"},{label:"湘潭昭山示范区",value:"430372"},{label:"湘潭九华示范区",value:"430373"},{label:"湘乡市",value:"430381"},{label:"韶山市",value:"430382"}],[{label:"珠晖区",value:"430405"},{label:"雁峰区",value:"430406"},{label:"石鼓区",value:"430407"},{label:"蒸湘区",value:"430408"},{label:"南岳区",value:"430412"},{label:"衡阳县",value:"430421"},{label:"衡南县",value:"430422"},{label:"衡山县",value:"430423"},{label:"衡东县",value:"430424"},{label:"祁东县",value:"430426"},{label:"衡阳综合保税区",value:"430471"},{label:"湖南衡阳高新技术产业园区",value:"430472"},{label:"湖南衡阳松木经济开发区",value:"430473"},{label:"耒阳市",value:"430481"},{label:"常宁市",value:"430482"}],[{label:"双清区",value:"430502"},{label:"大祥区",value:"430503"},{label:"北塔区",value:"430511"},{label:"邵东县",value:"430521"},{label:"新邵县",value:"430522"},{label:"邵阳县",value:"430523"},{label:"隆回县",value:"430524"},{label:"洞口县",value:"430525"},{label:"绥宁县",value:"430527"},{label:"新宁县",value:"430528"},{label:"城步苗族自治县",value:"430529"},{label:"武冈市",value:"430581"}],[{label:"岳阳楼区",value:"430602"},{label:"云溪区",value:"430603"},{label:"君山区",value:"430611"},{label:"岳阳县",value:"430621"},{label:"华容县",value:"430623"},{label:"湘阴县",value:"430624"},{label:"平江县",value:"430626"},{label:"岳阳市屈原管理区",value:"430671"},{label:"汨罗市",value:"430681"},{label:"临湘市",value:"430682"}],[{label:"武陵区",value:"430702"},{label:"鼎城区",value:"430703"},{label:"安乡县",value:"430721"},{label:"汉寿县",value:"430722"},{label:"澧县",value:"430723"},{label:"临澧县",value:"430724"},{label:"桃源县",value:"430725"},{label:"石门县",value:"430726"},{label:"常德市西洞庭管理区",value:"430771"},{label:"津市市",value:"430781"}],[{label:"永定区",value:"430802"},{label:"武陵源区",value:"430811"},{label:"慈利县",value:"430821"},{label:"桑植县",value:"430822"}],[{label:"资阳区",value:"430902"},{label:"赫山区",value:"430903"},{label:"南县",value:"430921"},{label:"桃江县",value:"430922"},{label:"安化县",value:"430923"},{label:"益阳市大通湖管理区",value:"430971"},{label:"湖南益阳高新技术产业园区",value:"430972"},{label:"沅江市",value:"430981"}],[{label:"北湖区",value:"431002"},{label:"苏仙区",value:"431003"},{label:"桂阳县",value:"431021"},{label:"宜章县",value:"431022"},{label:"永兴县",value:"431023"},{label:"嘉禾县",value:"431024"},{label:"临武县",value:"431025"},{label:"汝城县",value:"431026"},{label:"桂东县",value:"431027"},{label:"安仁县",value:"431028"},{label:"资兴市",value:"431081"}],[{label:"零陵区",value:"431102"},{label:"冷水滩区",value:"431103"},{label:"祁阳县",value:"431121"},{label:"东安县",value:"431122"},{label:"双牌县",value:"431123"},{label:"道县",value:"431124"},{label:"江永县",value:"431125"},{label:"宁远县",value:"431126"},{label:"蓝山县",value:"431127"},{label:"新田县",value:"431128"},{label:"江华瑶族自治县",value:"431129"},{label:"永州经济技术开发区",value:"431171"},{label:"永州市金洞管理区",value:"431172"},{label:"永州市回龙圩管理区",value:"431173"}],[{label:"鹤城区",value:"431202"},{label:"中方县",value:"431221"},{label:"沅陵县",value:"431222"},{label:"辰溪县",value:"431223"},{label:"溆浦县",value:"431224"},{label:"会同县",value:"431225"},{label:"麻阳苗族自治县",value:"431226"},{label:"新晃侗族自治县",value:"431227"},{label:"芷江侗族自治县",value:"431228"},{label:"靖州苗族侗族自治县",value:"431229"},{label:"通道侗族自治县",value:"431230"},{label:"怀化市洪江管理区",value:"431271"},{label:"洪江市",value:"431281"}],[{label:"娄星区",value:"431302"},{label:"双峰县",value:"431321"},{label:"新化县",value:"431322"},{label:"冷水江市",value:"431381"},{label:"涟源市",value:"431382"}],[{label:"吉首市",value:"433101"},{label:"泸溪县",value:"433122"},{label:"凤凰县",value:"433123"},{label:"花垣县",value:"433124"},{label:"保靖县",value:"433125"},{label:"古丈县",value:"433126"},{label:"永顺县",value:"433127"},{label:"龙山县",value:"433130"},{label:"湖南吉首经济开发区",value:"433172"},{label:"湖南永顺经济开发区",value:"433173"}]],[[{label:"荔湾区",value:"440103"},{label:"越秀区",value:"440104"},{label:"海珠区",value:"440105"},{label:"天河区",value:"440106"},{label:"白云区",value:"440111"},{label:"黄埔区",value:"440112"},{label:"番禺区",value:"440113"},{label:"花都区",value:"440114"},{label:"南沙区",value:"440115"},{label:"从化区",value:"440117"},{label:"增城区",value:"440118"}],[{label:"武江区",value:"440203"},{label:"浈江区",value:"440204"},{label:"曲江区",value:"440205"},{label:"始兴县",value:"440222"},{label:"仁化县",value:"440224"},{label:"翁源县",value:"440229"},{label:"乳源瑶族自治县",value:"440232"},{label:"新丰县",value:"440233"},{label:"乐昌市",value:"440281"},{label:"南雄市",value:"440282"}],[{label:"罗湖区",value:"440303"},{label:"福田区",value:"440304"},{label:"南山区",value:"440305"},{label:"宝安区",value:"440306"},{label:"龙岗区",value:"440307"},{label:"盐田区",value:"440308"},{label:"龙华区",value:"440309"},{label:"坪山区",value:"440310"}],[{label:"香洲区",value:"440402"},{label:"斗门区",value:"440403"},{label:"金湾区",value:"440404"}],[{label:"龙湖区",value:"440507"},{label:"金平区",value:"440511"},{label:"濠江区",value:"440512"},{label:"潮阳区",value:"440513"},{label:"潮南区",value:"440514"},{label:"澄海区",value:"440515"},{label:"南澳县",value:"440523"}],[{label:"禅城区",value:"440604"},{label:"南海区",value:"440605"},{label:"顺德区",value:"440606"},{label:"三水区",value:"440607"},{label:"高明区",value:"440608"}],[{label:"蓬江区",value:"440703"},{label:"江海区",value:"440704"},{label:"新会区",value:"440705"},{label:"台山市",value:"440781"},{label:"开平市",value:"440783"},{label:"鹤山市",value:"440784"},{label:"恩平市",value:"440785"}],[{label:"赤坎区",value:"440802"},{label:"霞山区",value:"440803"},{label:"坡头区",value:"440804"},{label:"麻章区",value:"440811"},{label:"遂溪县",value:"440823"},{label:"徐闻县",value:"440825"},{label:"廉江市",value:"440881"},{label:"雷州市",value:"440882"},{label:"吴川市",value:"440883"}],[{label:"茂南区",value:"440902"},{label:"电白区",value:"440904"},{label:"高州市",value:"440981"},{label:"化州市",value:"440982"},{label:"信宜市",value:"440983"}],[{label:"端州区",value:"441202"},{label:"鼎湖区",value:"441203"},{label:"高要区",value:"441204"},{label:"广宁县",value:"441223"},{label:"怀集县",value:"441224"},{label:"封开县",value:"441225"},{label:"德庆县",value:"441226"},{label:"四会市",value:"441284"}],[{label:"惠城区",value:"441302"},{label:"惠阳区",value:"441303"},{label:"博罗县",value:"441322"},{label:"惠东县",value:"441323"},{label:"龙门县",value:"441324"}],[{label:"梅江区",value:"441402"},{label:"梅县区",value:"441403"},{label:"大埔县",value:"441422"},{label:"丰顺县",value:"441423"},{label:"五华县",value:"441424"},{label:"平远县",value:"441426"},{label:"蕉岭县",value:"441427"},{label:"兴宁市",value:"441481"}],[{label:"城区",value:"441502"},{label:"海丰县",value:"441521"},{label:"陆河县",value:"441523"},{label:"陆丰市",value:"441581"}],[{label:"源城区",value:"441602"},{label:"紫金县",value:"441621"},{label:"龙川县",value:"441622"},{label:"连平县",value:"441623"},{label:"和平县",value:"441624"},{label:"东源县",value:"441625"}],[{label:"江城区",value:"441702"},{label:"阳东区",value:"441704"},{label:"阳西县",value:"441721"},{label:"阳春市",value:"441781"}],[{label:"清城区",value:"441802"},{label:"清新区",value:"441803"},{label:"佛冈县",value:"441821"},{label:"阳山县",value:"441823"},{label:"连山壮族瑶族自治县",value:"441825"},{label:"连南瑶族自治县",value:"441826"},{label:"英德市",value:"441881"},{label:"连州市",value:"441882"}],[{label:"东莞市",value:"441900"}],[{label:"中山市",value:"442000"}],[{label:"湘桥区",value:"445102"},{label:"潮安区",value:"445103"},{label:"饶平县",value:"445122"}],[{label:"榕城区",value:"445202"},{label:"揭东区",value:"445203"},{label:"揭西县",value:"445222"},{label:"惠来县",value:"445224"},{label:"普宁市",value:"445281"}],[{label:"云城区",value:"445302"},{label:"云安区",value:"445303"},{label:"新兴县",value:"445321"},{label:"郁南县",value:"445322"},{label:"罗定市",value:"445381"}]],[[{label:"兴宁区",value:"450102"},{label:"青秀区",value:"450103"},{label:"江南区",value:"450105"},{label:"西乡塘区",value:"450107"},{label:"良庆区",value:"450108"},{label:"邕宁区",value:"450109"},{label:"武鸣区",value:"450110"},{label:"隆安县",value:"450123"},{label:"马山县",value:"450124"},{label:"上林县",value:"450125"},{label:"宾阳县",value:"450126"},{label:"横县",value:"450127"}],[{label:"城中区",value:"450202"},{label:"鱼峰区",value:"450203"},{label:"柳南区",value:"450204"},{label:"柳北区",value:"450205"},{label:"柳江区",value:"450206"},{label:"柳城县",value:"450222"},{label:"鹿寨县",value:"450223"},{label:"融安县",value:"450224"},{label:"融水苗族自治县",value:"450225"},{label:"三江侗族自治县",value:"450226"}],[{label:"秀峰区",value:"450302"},{label:"叠彩区",value:"450303"},{label:"象山区",value:"450304"},{label:"七星区",value:"450305"},{label:"雁山区",value:"450311"},{label:"临桂区",value:"450312"},{label:"阳朔县",value:"450321"},{label:"灵川县",value:"450323"},{label:"全州县",value:"450324"},{label:"兴安县",value:"450325"},{label:"永福县",value:"450326"},{label:"灌阳县",value:"450327"},{label:"龙胜各族自治县",value:"450328"},{label:"资源县",value:"450329"},{label:"平乐县",value:"450330"},{label:"荔浦县",value:"450331"},{label:"恭城瑶族自治县",value:"450332"}],[{label:"万秀区",value:"450403"},{label:"长洲区",value:"450405"},{label:"龙圩区",value:"450406"},{label:"苍梧县",value:"450421"},{label:"藤县",value:"450422"},{label:"蒙山县",value:"450423"},{label:"岑溪市",value:"450481"}],[{label:"海城区",value:"450502"},{label:"银海区",value:"450503"},{label:"铁山港区",value:"450512"},{label:"合浦县",value:"450521"}],[{label:"港口区",value:"450602"},{label:"防城区",value:"450603"},{label:"上思县",value:"450621"},{label:"东兴市",value:"450681"}],[{label:"钦南区",value:"450702"},{label:"钦北区",value:"450703"},{label:"灵山县",value:"450721"},{label:"浦北县",value:"450722"}],[{label:"港北区",value:"450802"},{label:"港南区",value:"450803"},{label:"覃塘区",value:"450804"},{label:"平南县",value:"450821"},{label:"桂平市",value:"450881"}],[{label:"玉州区",value:"450902"},{label:"福绵区",value:"450903"},{label:"容县",value:"450921"},{label:"陆川县",value:"450922"},{label:"博白县",value:"450923"},{label:"兴业县",value:"450924"},{label:"北流市",value:"450981"}],[{label:"右江区",value:"451002"},{label:"田阳县",value:"451021"},{label:"田东县",value:"451022"},{label:"平果县",value:"451023"},{label:"德保县",value:"451024"},{label:"那坡县",value:"451026"},{label:"凌云县",value:"451027"},{label:"乐业县",value:"451028"},{label:"田林县",value:"451029"},{label:"西林县",value:"451030"},{label:"隆林各族自治县",value:"451031"},{label:"靖西市",value:"451081"}],[{label:"八步区",value:"451102"},{label:"平桂区",value:"451103"},{label:"昭平县",value:"451121"},{label:"钟山县",value:"451122"},{label:"富川瑶族自治县",value:"451123"}],[{label:"金城江区",value:"451202"},{label:"宜州区",value:"451203"},{label:"南丹县",value:"451221"},{label:"天峨县",value:"451222"},{label:"凤山县",value:"451223"},{label:"东兰县",value:"451224"},{label:"罗城仫佬族自治县",value:"451225"},{label:"环江毛南族自治县",value:"451226"},{label:"巴马瑶族自治县",value:"451227"},{label:"都安瑶族自治县",value:"451228"},{label:"大化瑶族自治县",value:"451229"}],[{label:"兴宾区",value:"451302"},{label:"忻城县",value:"451321"},{label:"象州县",value:"451322"},{label:"武宣县",value:"451323"},{label:"金秀瑶族自治县",value:"451324"},{label:"合山市",value:"451381"}],[{label:"江州区",value:"451402"},{label:"扶绥县",value:"451421"},{label:"宁明县",value:"451422"},{label:"龙州县",value:"451423"},{label:"大新县",value:"451424"},{label:"天等县",value:"451425"},{label:"凭祥市",value:"451481"}]],[[{label:"秀英区",value:"460105"},{label:"龙华区",value:"460106"},{label:"琼山区",value:"460107"},{label:"美兰区",value:"460108"}],[{label:"海棠区",value:"460202"},{label:"吉阳区",value:"460203"},{label:"天涯区",value:"460204"},{label:"崖州区",value:"460205"}],[{label:"西沙群岛",value:"460321"},{label:"南沙群岛",value:"460322"},{label:"中沙群岛的岛礁及其海域",value:"460323"}],[{label:"儋州市",value:"460400"}],[{label:"五指山市",value:"469001"},{label:"琼海市",value:"469002"},{label:"文昌市",value:"469005"},{label:"万宁市",value:"469006"},{label:"东方市",value:"469007"},{label:"定安县",value:"469021"},{label:"屯昌县",value:"469022"},{label:"澄迈县",value:"469023"},{label:"临高县",value:"469024"},{label:"白沙黎族自治县",value:"469025"},{label:"昌江黎族自治县",value:"469026"},{label:"乐东黎族自治县",value:"469027"},{label:"陵水黎族自治县",value:"469028"},{label:"保亭黎族苗族自治县",value:"469029"},{label:"琼中黎族苗族自治县",value:"469030"}]],[[{label:"万州区",value:"500101"},{label:"涪陵区",value:"500102"},{label:"渝中区",value:"500103"},{label:"大渡口区",value:"500104"},{label:"江北区",value:"500105"},{label:"沙坪坝区",value:"500106"},{label:"九龙坡区",value:"500107"},{label:"南岸区",value:"500108"},{label:"北碚区",value:"500109"},{label:"綦江区",value:"500110"},{label:"大足区",value:"500111"},{label:"渝北区",value:"500112"},{label:"巴南区",value:"500113"},{label:"黔江区",value:"500114"},{label:"长寿区",value:"500115"},{label:"江津区",value:"500116"},{label:"合川区",value:"500117"},{label:"永川区",value:"500118"},{label:"南川区",value:"500119"},{label:"璧山区",value:"500120"},{label:"铜梁区",value:"500151"},{label:"潼南区",value:"500152"},{label:"荣昌区",value:"500153"},{label:"开州区",value:"500154"},{label:"梁平区",value:"500155"},{label:"武隆区",value:"500156"}],[{label:"城口县",value:"500229"},{label:"丰都县",value:"500230"},{label:"垫江县",value:"500231"},{label:"忠县",value:"500233"},{label:"云阳县",value:"500235"},{label:"奉节县",value:"500236"},{label:"巫山县",value:"500237"},{label:"巫溪县",value:"500238"},{label:"石柱土家族自治县",value:"500240"},{label:"秀山土家族苗族自治县",value:"500241"},{label:"酉阳土家族苗族自治县",value:"500242"},{label:"彭水苗族土家族自治县",value:"500243"}]],[[{label:"锦江区",value:"510104"},{label:"青羊区",value:"510105"},{label:"金牛区",value:"510106"},{label:"武侯区",value:"510107"},{label:"成华区",value:"510108"},{label:"龙泉驿区",value:"510112"},{label:"青白江区",value:"510113"},{label:"新都区",value:"510114"},{label:"温江区",value:"510115"},{label:"双流区",value:"510116"},{label:"郫都区",value:"510117"},{label:"金堂县",value:"510121"},{label:"大邑县",value:"510129"},{label:"蒲江县",value:"510131"},{label:"新津县",value:"510132"},{label:"都江堰市",value:"510181"},{label:"彭州市",value:"510182"},{label:"邛崃市",value:"510183"},{label:"崇州市",value:"510184"},{label:"简阳市",value:"510185"}],[{label:"自流井区",value:"510302"},{label:"贡井区",value:"510303"},{label:"大安区",value:"510304"},{label:"沿滩区",value:"510311"},{label:"荣县",value:"510321"},{label:"富顺县",value:"510322"}],[{label:"东区",value:"510402"},{label:"西区",value:"510403"},{label:"仁和区",value:"510411"},{label:"米易县",value:"510421"},{label:"盐边县",value:"510422"}],[{label:"江阳区",value:"510502"},{label:"纳溪区",value:"510503"},{label:"龙马潭区",value:"510504"},{label:"泸县",value:"510521"},{label:"合江县",value:"510522"},{label:"叙永县",value:"510524"},{label:"古蔺县",value:"510525"}],[{label:"旌阳区",value:"510603"},{label:"罗江区",value:"510604"},{label:"中江县",value:"510623"},{label:"广汉市",value:"510681"},{label:"什邡市",value:"510682"},{label:"绵竹市",value:"510683"}],[{label:"涪城区",value:"510703"},{label:"游仙区",value:"510704"},{label:"安州区",value:"510705"},{label:"三台县",value:"510722"},{label:"盐亭县",value:"510723"},{label:"梓潼县",value:"510725"},{label:"北川羌族自治县",value:"510726"},{label:"平武县",value:"510727"},{label:"江油市",value:"510781"}],[{label:"利州区",value:"510802"},{label:"昭化区",value:"510811"},{label:"朝天区",value:"510812"},{label:"旺苍县",value:"510821"},{label:"青川县",value:"510822"},{label:"剑阁县",value:"510823"},{label:"苍溪县",value:"510824"}],[{label:"船山区",value:"510903"},{label:"安居区",value:"510904"},{label:"蓬溪县",value:"510921"},{label:"射洪县",value:"510922"},{label:"大英县",value:"510923"}],[{label:"市中区",value:"511002"},{label:"东兴区",value:"511011"},{label:"威远县",value:"511024"},{label:"资中县",value:"511025"},{label:"内江经济开发区",value:"511071"},{label:"隆昌市",value:"511083"}],[{label:"市中区",value:"511102"},{label:"沙湾区",value:"511111"},{label:"五通桥区",value:"511112"},{label:"金口河区",value:"511113"},{label:"犍为县",value:"511123"},{label:"井研县",value:"511124"},{label:"夹江县",value:"511126"},{label:"沐川县",value:"511129"},{label:"峨边彝族自治县",value:"511132"},{label:"马边彝族自治县",value:"511133"},{label:"峨眉山市",value:"511181"}],[{label:"顺庆区",value:"511302"},{label:"高坪区",value:"511303"},{label:"嘉陵区",value:"511304"},{label:"南部县",value:"511321"},{label:"营山县",value:"511322"},{label:"蓬安县",value:"511323"},{label:"仪陇县",value:"511324"},{label:"西充县",value:"511325"},{label:"阆中市",value:"511381"}],[{label:"东坡区",value:"511402"},{label:"彭山区",value:"511403"},{label:"仁寿县",value:"511421"},{label:"洪雅县",value:"511423"},{label:"丹棱县",value:"511424"},{label:"青神县",value:"511425"}],[{label:"翠屏区",value:"511502"},{label:"南溪区",value:"511503"},{label:"宜宾县",value:"511521"},{label:"江安县",value:"511523"},{label:"长宁县",value:"511524"},{label:"高县",value:"511525"},{label:"珙县",value:"511526"},{label:"筠连县",value:"511527"},{label:"兴文县",value:"511528"},{label:"屏山县",value:"511529"}],[{label:"广安区",value:"511602"},{label:"前锋区",value:"511603"},{label:"岳池县",value:"511621"},{label:"武胜县",value:"511622"},{label:"邻水县",value:"511623"},{label:"华蓥市",value:"511681"}],[{label:"通川区",value:"511702"},{label:"达川区",value:"511703"},{label:"宣汉县",value:"511722"},{label:"开江县",value:"511723"},{label:"大竹县",value:"511724"},{label:"渠县",value:"511725"},{label:"达州经济开发区",value:"511771"},{label:"万源市",value:"511781"}],[{label:"雨城区",value:"511802"},{label:"名山区",value:"511803"},{label:"荥经县",value:"511822"},{label:"汉源县",value:"511823"},{label:"石棉县",value:"511824"},{label:"天全县",value:"511825"},{label:"芦山县",value:"511826"},{label:"宝兴县",value:"511827"}],[{label:"巴州区",value:"511902"},{label:"恩阳区",value:"511903"},{label:"通江县",value:"511921"},{label:"南江县",value:"511922"},{label:"平昌县",value:"511923"},{label:"巴中经济开发区",value:"511971"}],[{label:"雁江区",value:"512002"},{label:"安岳县",value:"512021"},{label:"乐至县",value:"512022"}],[{label:"马尔康市",value:"513201"},{label:"汶川县",value:"513221"},{label:"理县",value:"513222"},{label:"茂县",value:"513223"},{label:"松潘县",value:"513224"},{label:"九寨沟县",value:"513225"},{label:"金川县",value:"513226"},{label:"小金县",value:"513227"},{label:"黑水县",value:"513228"},{label:"壤塘县",value:"513230"},{label:"阿坝县",value:"513231"},{label:"若尔盖县",value:"513232"},{label:"红原县",value:"513233"}],[{label:"康定市",value:"513301"},{label:"泸定县",value:"513322"},{label:"丹巴县",value:"513323"},{label:"九龙县",value:"513324"},{label:"雅江县",value:"513325"},{label:"道孚县",value:"513326"},{label:"炉霍县",value:"513327"},{label:"甘孜县",value:"513328"},{label:"新龙县",value:"513329"},{label:"德格县",value:"513330"},{label:"白玉县",value:"513331"},{label:"石渠县",value:"513332"},{label:"色达县",value:"513333"},{label:"理塘县",value:"513334"},{label:"巴塘县",value:"513335"},{label:"乡城县",value:"513336"},{label:"稻城县",value:"513337"},{label:"得荣县",value:"513338"}],[{label:"西昌市",value:"513401"},{label:"木里藏族自治县",value:"513422"},{label:"盐源县",value:"513423"},{label:"德昌县",value:"513424"},{label:"会理县",value:"513425"},{label:"会东县",value:"513426"},{label:"宁南县",value:"513427"},{label:"普格县",value:"513428"},{label:"布拖县",value:"513429"},{label:"金阳县",value:"513430"},{label:"昭觉县",value:"513431"},{label:"喜德县",value:"513432"},{label:"冕宁县",value:"513433"},{label:"越西县",value:"513434"},{label:"甘洛县",value:"513435"},{label:"美姑县",value:"513436"},{label:"雷波县",value:"513437"}]],[[{label:"南明区",value:"520102"},{label:"云岩区",value:"520103"},{label:"花溪区",value:"520111"},{label:"乌当区",value:"520112"},{label:"白云区",value:"520113"},{label:"观山湖区",value:"520115"},{label:"开阳县",value:"520121"},{label:"息烽县",value:"520122"},{label:"修文县",value:"520123"},{label:"清镇市",value:"520181"}],[{label:"钟山区",value:"520201"},{label:"六枝特区",value:"520203"},{label:"水城县",value:"520221"},{label:"盘州市",value:"520281"}],[{label:"红花岗区",value:"520302"},{label:"汇川区",value:"520303"},{label:"播州区",value:"520304"},{label:"桐梓县",value:"520322"},{label:"绥阳县",value:"520323"},{label:"正安县",value:"520324"},{label:"道真仡佬族苗族自治县",value:"520325"},{label:"务川仡佬族苗族自治县",value:"520326"},{label:"凤冈县",value:"520327"},{label:"湄潭县",value:"520328"},{label:"余庆县",value:"520329"},{label:"习水县",value:"520330"},{label:"赤水市",value:"520381"},{label:"仁怀市",value:"520382"}],[{label:"西秀区",value:"520402"},{label:"平坝区",value:"520403"},{label:"普定县",value:"520422"},{label:"镇宁布依族苗族自治县",value:"520423"},{label:"关岭布依族苗族自治县",value:"520424"},{label:"紫云苗族布依族自治县",value:"520425"}],[{label:"七星关区",value:"520502"},{label:"大方县",value:"520521"},{label:"黔西县",value:"520522"},{label:"金沙县",value:"520523"},{label:"织金县",value:"520524"},{label:"纳雍县",value:"520525"},{label:"威宁彝族回族苗族自治县",value:"520526"},{label:"赫章县",value:"520527"}],[{label:"碧江区",value:"520602"},{label:"万山区",value:"520603"},{label:"江口县",value:"520621"},{label:"玉屏侗族自治县",value:"520622"},{label:"石阡县",value:"520623"},{label:"思南县",value:"520624"},{label:"印江土家族苗族自治县",value:"520625"},{label:"德江县",value:"520626"},{label:"沿河土家族自治县",value:"520627"},{label:"松桃苗族自治县",value:"520628"}],[{label:"兴义市",value:"522301"},{label:"兴仁县",value:"522322"},{label:"普安县",value:"522323"},{label:"晴隆县",value:"522324"},{label:"贞丰县",value:"522325"},{label:"望谟县",value:"522326"},{label:"册亨县",value:"522327"},{label:"安龙县",value:"522328"}],[{label:"凯里市",value:"522601"},{label:"黄平县",value:"522622"},{label:"施秉县",value:"522623"},{label:"三穗县",value:"522624"},{label:"镇远县",value:"522625"},{label:"岑巩县",value:"522626"},{label:"天柱县",value:"522627"},{label:"锦屏县",value:"522628"},{label:"剑河县",value:"522629"},{label:"台江县",value:"522630"},{label:"黎平县",value:"522631"},{label:"榕江县",value:"522632"},{label:"从江县",value:"522633"},{label:"雷山县",value:"522634"},{label:"麻江县",value:"522635"},{label:"丹寨县",value:"522636"}],[{label:"都匀市",value:"522701"},{label:"福泉市",value:"522702"},{label:"荔波县",value:"522722"},{label:"贵定县",value:"522723"},{label:"瓮安县",value:"522725"},{label:"独山县",value:"522726"},{label:"平塘县",value:"522727"},{label:"罗甸县",value:"522728"},{label:"长顺县",value:"522729"},{label:"龙里县",value:"522730"},{label:"惠水县",value:"522731"},{label:"三都水族自治县",value:"522732"}]],[[{label:"五华区",value:"530102"},{label:"盘龙区",value:"530103"},{label:"官渡区",value:"530111"},{label:"西山区",value:"530112"},{label:"东川区",value:"530113"},{label:"呈贡区",value:"530114"},{label:"晋宁区",value:"530115"},{label:"富民县",value:"530124"},{label:"宜良县",value:"530125"},{label:"石林彝族自治县",value:"530126"},{label:"嵩明县",value:"530127"},{label:"禄劝彝族苗族自治县",value:"530128"},{label:"寻甸回族彝族自治县",value:"530129"},{label:"安宁市",value:"530181"}],[{label:"麒麟区",value:"530302"},{label:"沾益区",value:"530303"},{label:"马龙县",value:"530321"},{label:"陆良县",value:"530322"},{label:"师宗县",value:"530323"},{label:"罗平县",value:"530324"},{label:"富源县",value:"530325"},{label:"会泽县",value:"530326"},{label:"宣威市",value:"530381"}],[{label:"红塔区",value:"530402"},{label:"江川区",value:"530403"},{label:"澄江县",value:"530422"},{label:"通海县",value:"530423"},{label:"华宁县",value:"530424"},{label:"易门县",value:"530425"},{label:"峨山彝族自治县",value:"530426"},{label:"新平彝族傣族自治县",value:"530427"},{label:"元江哈尼族彝族傣族自治县",value:"530428"}],[{label:"隆阳区",value:"530502"},{label:"施甸县",value:"530521"},{label:"龙陵县",value:"530523"},{label:"昌宁县",value:"530524"},{label:"腾冲市",value:"530581"}],[{label:"昭阳区",value:"530602"},{label:"鲁甸县",value:"530621"},{label:"巧家县",value:"530622"},{label:"盐津县",value:"530623"},{label:"大关县",value:"530624"},{label:"永善县",value:"530625"},{label:"绥江县",value:"530626"},{label:"镇雄县",value:"530627"},{label:"彝良县",value:"530628"},{label:"威信县",value:"530629"},{label:"水富县",value:"530630"}],[{label:"古城区",value:"530702"},{label:"玉龙纳西族自治县",value:"530721"},{label:"永胜县",value:"530722"},{label:"华坪县",value:"530723"},{label:"宁蒗彝族自治县",value:"530724"}],[{label:"思茅区",value:"530802"},{label:"宁洱哈尼族彝族自治县",value:"530821"},{label:"墨江哈尼族自治县",value:"530822"},{label:"景东彝族自治县",value:"530823"},{label:"景谷傣族彝族自治县",value:"530824"},{label:"镇沅彝族哈尼族拉祜族自治县",value:"530825"},{label:"江城哈尼族彝族自治县",value:"530826"},{label:"孟连傣族拉祜族佤族自治县",value:"530827"},{label:"澜沧拉祜族自治县",value:"530828"},{label:"西盟佤族自治县",value:"530829"}],[{label:"临翔区",value:"530902"},{label:"凤庆县",value:"530921"},{label:"云县",value:"530922"},{label:"永德县",value:"530923"},{label:"镇康县",value:"530924"},{label:"双江拉祜族佤族布朗族傣族自治县",value:"530925"},{label:"耿马傣族佤族自治县",value:"530926"},{label:"沧源佤族自治县",value:"530927"}],[{label:"楚雄市",value:"532301"},{label:"双柏县",value:"532322"},{label:"牟定县",value:"532323"},{label:"南华县",value:"532324"},{label:"姚安县",value:"532325"},{label:"大姚县",value:"532326"},{label:"永仁县",value:"532327"},{label:"元谋县",value:"532328"},{label:"武定县",value:"532329"},{label:"禄丰县",value:"532331"}],[{label:"个旧市",value:"532501"},{label:"开远市",value:"532502"},{label:"蒙自市",value:"532503"},{label:"弥勒市",value:"532504"},{label:"屏边苗族自治县",value:"532523"},{label:"建水县",value:"532524"},{label:"石屏县",value:"532525"},{label:"泸西县",value:"532527"},{label:"元阳县",value:"532528"},{label:"红河县",value:"532529"},{label:"金平苗族瑶族傣族自治县",value:"532530"},{label:"绿春县",value:"532531"},{label:"河口瑶族自治县",value:"532532"}],[{label:"文山市",value:"532601"},{label:"砚山县",value:"532622"},{label:"西畴县",value:"532623"},{label:"麻栗坡县",value:"532624"},{label:"马关县",value:"532625"},{label:"丘北县",value:"532626"},{label:"广南县",value:"532627"},{label:"富宁县",value:"532628"}],[{label:"景洪市",value:"532801"},{label:"勐海县",value:"532822"},{label:"勐腊县",value:"532823"}],[{label:"大理市",value:"532901"},{label:"漾濞彝族自治县",value:"532922"},{label:"祥云县",value:"532923"},{label:"宾川县",value:"532924"},{label:"弥渡县",value:"532925"},{label:"南涧彝族自治县",value:"532926"},{label:"巍山彝族回族自治县",value:"532927"},{label:"永平县",value:"532928"},{label:"云龙县",value:"532929"},{label:"洱源县",value:"532930"},{label:"剑川县",value:"532931"},{label:"鹤庆县",value:"532932"}],[{label:"瑞丽市",value:"533102"},{label:"芒市",value:"533103"},{label:"梁河县",value:"533122"},{label:"盈江县",value:"533123"},{label:"陇川县",value:"533124"}],[{label:"泸水市",value:"533301"},{label:"福贡县",value:"533323"},{label:"贡山独龙族怒族自治县",value:"533324"},{label:"兰坪白族普米族自治县",value:"533325"}],[{label:"香格里拉市",value:"533401"},{label:"德钦县",value:"533422"},{label:"维西傈僳族自治县",value:"533423"}]],[[{label:"城关区",value:"540102"},{label:"堆龙德庆区",value:"540103"},{label:"林周县",value:"540121"},{label:"当雄县",value:"540122"},{label:"尼木县",value:"540123"},{label:"曲水县",value:"540124"},{label:"达孜县",value:"540126"},{label:"墨竹工卡县",value:"540127"},{label:"格尔木藏青工业园区",value:"540171"},{label:"拉萨经济技术开发区",value:"540172"},{label:"西藏文化旅游创意园区",value:"540173"},{label:"达孜工业园区",value:"540174"}],[{label:"桑珠孜区",value:"540202"},{label:"南木林县",value:"540221"},{label:"江孜县",value:"540222"},{label:"定日县",value:"540223"},{label:"萨迦县",value:"540224"},{label:"拉孜县",value:"540225"},{label:"昂仁县",value:"540226"},{label:"谢通门县",value:"540227"},{label:"白朗县",value:"540228"},{label:"仁布县",value:"540229"},{label:"康马县",value:"540230"},{label:"定结县",value:"540231"},{label:"仲巴县",value:"540232"},{label:"亚东县",value:"540233"},{label:"吉隆县",value:"540234"},{label:"聂拉木县",value:"540235"},{label:"萨嘎县",value:"540236"},{label:"岗巴县",value:"540237"}],[{label:"卡若区",value:"540302"},{label:"江达县",value:"540321"},{label:"贡觉县",value:"540322"},{label:"类乌齐县",value:"540323"},{label:"丁青县",value:"540324"},{label:"察雅县",value:"540325"},{label:"八宿县",value:"540326"},{label:"左贡县",value:"540327"},{label:"芒康县",value:"540328"},{label:"洛隆县",value:"540329"},{label:"边坝县",value:"540330"}],[{label:"巴宜区",value:"540402"},{label:"工布江达县",value:"540421"},{label:"米林县",value:"540422"},{label:"墨脱县",value:"540423"},{label:"波密县",value:"540424"},{label:"察隅县",value:"540425"},{label:"朗县",value:"540426"}],[{label:"乃东区",value:"540502"},{label:"扎囊县",value:"540521"},{label:"贡嘎县",value:"540522"},{label:"桑日县",value:"540523"},{label:"琼结县",value:"540524"},{label:"曲松县",value:"540525"},{label:"措美县",value:"540526"},{label:"洛扎县",value:"540527"},{label:"加查县",value:"540528"},{label:"隆子县",value:"540529"},{label:"错那县",value:"540530"},{label:"浪卡子县",value:"540531"}],[{label:"那曲县",value:"542421"},{label:"嘉黎县",value:"542422"},{label:"比如县",value:"542423"},{label:"聂荣县",value:"542424"},{label:"安多县",value:"542425"},{label:"申扎县",value:"542426"},{label:"索县",value:"542427"},{label:"班戈县",value:"542428"},{label:"巴青县",value:"542429"},{label:"尼玛县",value:"542430"},{label:"双湖县",value:"542431"}],[{label:"普兰县",value:"542521"},{label:"札达县",value:"542522"},{label:"噶尔县",value:"542523"},{label:"日土县",value:"542524"},{label:"革吉县",value:"542525"},{label:"改则县",value:"542526"},{label:"措勤县",value:"542527"}]],[[{label:"新城区",value:"610102"},{label:"碑林区",value:"610103"},{label:"莲湖区",value:"610104"},{label:"灞桥区",value:"610111"},{label:"未央区",value:"610112"},{label:"雁塔区",value:"610113"},{label:"阎良区",value:"610114"},{label:"临潼区",value:"610115"},{label:"长安区",value:"610116"},{label:"高陵区",value:"610117"},{label:"鄠邑区",value:"610118"},{label:"蓝田县",value:"610122"},{label:"周至县",value:"610124"}],[{label:"王益区",value:"610202"},{label:"印台区",value:"610203"},{label:"耀州区",value:"610204"},{label:"宜君县",value:"610222"}],[{label:"渭滨区",value:"610302"},{label:"金台区",value:"610303"},{label:"陈仓区",value:"610304"},{label:"凤翔县",value:"610322"},{label:"岐山县",value:"610323"},{label:"扶风县",value:"610324"},{label:"眉县",value:"610326"},{label:"陇县",value:"610327"},{label:"千阳县",value:"610328"},{label:"麟游县",value:"610329"},{label:"凤县",value:"610330"},{label:"太白县",value:"610331"}],[{label:"秦都区",value:"610402"},{label:"杨陵区",value:"610403"},{label:"渭城区",value:"610404"},{label:"三原县",value:"610422"},{label:"泾阳县",value:"610423"},{label:"乾县",value:"610424"},{label:"礼泉县",value:"610425"},{label:"永寿县",value:"610426"},{label:"彬县",value:"610427"},{label:"长武县",value:"610428"},{label:"旬邑县",value:"610429"},{label:"淳化县",value:"610430"},{label:"武功县",value:"610431"},{label:"兴平市",value:"610481"}],[{label:"临渭区",value:"610502"},{label:"华州区",value:"610503"},{label:"潼关县",value:"610522"},{label:"大荔县",value:"610523"},{label:"合阳县",value:"610524"},{label:"澄城县",value:"610525"},{label:"蒲城县",value:"610526"},{label:"白水县",value:"610527"},{label:"富平县",value:"610528"},{label:"韩城市",value:"610581"},{label:"华阴市",value:"610582"}],[{label:"宝塔区",value:"610602"},{label:"安塞区",value:"610603"},{label:"延长县",value:"610621"},{label:"延川县",value:"610622"},{label:"子长县",value:"610623"},{label:"志丹县",value:"610625"},{label:"吴起县",value:"610626"},{label:"甘泉县",value:"610627"},{label:"富县",value:"610628"},{label:"洛川县",value:"610629"},{label:"宜川县",value:"610630"},{label:"黄龙县",value:"610631"},{label:"黄陵县",value:"610632"}],[{label:"汉台区",value:"610702"},{label:"南郑区",value:"610703"},{label:"城固县",value:"610722"},{label:"洋县",value:"610723"},{label:"西乡县",value:"610724"},{label:"勉县",value:"610725"},{label:"宁强县",value:"610726"},{label:"略阳县",value:"610727"},{label:"镇巴县",value:"610728"},{label:"留坝县",value:"610729"},{label:"佛坪县",value:"610730"}],[{label:"榆阳区",value:"610802"},{label:"横山区",value:"610803"},{label:"府谷县",value:"610822"},{label:"靖边县",value:"610824"},{label:"定边县",value:"610825"},{label:"绥德县",value:"610826"},{label:"米脂县",value:"610827"},{label:"佳县",value:"610828"},{label:"吴堡县",value:"610829"},{label:"清涧县",value:"610830"},{label:"子洲县",value:"610831"},{label:"神木市",value:"610881"}],[{label:"汉滨区",value:"610902"},{label:"汉阴县",value:"610921"},{label:"石泉县",value:"610922"},{label:"宁陕县",value:"610923"},{label:"紫阳县",value:"610924"},{label:"岚皋县",value:"610925"},{label:"平利县",value:"610926"},{label:"镇坪县",value:"610927"},{label:"旬阳县",value:"610928"},{label:"白河县",value:"610929"}],[{label:"商州区",value:"611002"},{label:"洛南县",value:"611021"},{label:"丹凤县",value:"611022"},{label:"商南县",value:"611023"},{label:"山阳县",value:"611024"},{label:"镇安县",value:"611025"},{label:"柞水县",value:"611026"}]],[[{label:"城关区",value:"620102"},{label:"七里河区",value:"620103"},{label:"西固区",value:"620104"},{label:"安宁区",value:"620105"},{label:"红古区",value:"620111"},{label:"永登县",value:"620121"},{label:"皋兰县",value:"620122"},{label:"榆中县",value:"620123"},{label:"兰州新区",value:"620171"}],[{label:"嘉峪关市",value:"620201"}],[{label:"金川区",value:"620302"},{label:"永昌县",value:"620321"}],[{label:"白银区",value:"620402"},{label:"平川区",value:"620403"},{label:"靖远县",value:"620421"},{label:"会宁县",value:"620422"},{label:"景泰县",value:"620423"}],[{label:"秦州区",value:"620502"},{label:"麦积区",value:"620503"},{label:"清水县",value:"620521"},{label:"秦安县",value:"620522"},{label:"甘谷县",value:"620523"},{label:"武山县",value:"620524"},{label:"张家川回族自治县",value:"620525"}],[{label:"凉州区",value:"620602"},{label:"民勤县",value:"620621"},{label:"古浪县",value:"620622"},{label:"天祝藏族自治县",value:"620623"}],[{label:"甘州区",value:"620702"},{label:"肃南裕固族自治县",value:"620721"},{label:"民乐县",value:"620722"},{label:"临泽县",value:"620723"},{label:"高台县",value:"620724"},{label:"山丹县",value:"620725"}],[{label:"崆峒区",value:"620802"},{label:"泾川县",value:"620821"},{label:"灵台县",value:"620822"},{label:"崇信县",value:"620823"},{label:"华亭县",value:"620824"},{label:"庄浪县",value:"620825"},{label:"静宁县",value:"620826"},{label:"平凉工业园区",value:"620871"}],[{label:"肃州区",value:"620902"},{label:"金塔县",value:"620921"},{label:"瓜州县",value:"620922"},{label:"肃北蒙古族自治县",value:"620923"},{label:"阿克塞哈萨克族自治县",value:"620924"},{label:"玉门市",value:"620981"},{label:"敦煌市",value:"620982"}],[{label:"西峰区",value:"621002"},{label:"庆城县",value:"621021"},{label:"环县",value:"621022"},{label:"华池县",value:"621023"},{label:"合水县",value:"621024"},{label:"正宁县",value:"621025"},{label:"宁县",value:"621026"},{label:"镇原县",value:"621027"}],[{label:"安定区",value:"621102"},{label:"通渭县",value:"621121"},{label:"陇西县",value:"621122"},{label:"渭源县",value:"621123"},{label:"临洮县",value:"621124"},{label:"漳县",value:"621125"},{label:"岷县",value:"621126"}],[{label:"武都区",value:"621202"},{label:"成县",value:"621221"},{label:"文县",value:"621222"},{label:"宕昌县",value:"621223"},{label:"康县",value:"621224"},{label:"西和县",value:"621225"},{label:"礼县",value:"621226"},{label:"徽县",value:"621227"},{label:"两当县",value:"621228"}],[{label:"临夏市",value:"622901"},{label:"临夏县",value:"622921"},{label:"康乐县",value:"622922"},{label:"永靖县",value:"622923"},{label:"广河县",value:"622924"},{label:"和政县",value:"622925"},{label:"东乡族自治县",value:"622926"},{label:"积石山保安族东乡族撒拉族自治县",value:"622927"}],[{label:"合作市",value:"623001"},{label:"临潭县",value:"623021"},{label:"卓尼县",value:"623022"},{label:"舟曲县",value:"623023"},{label:"迭部县",value:"623024"},{label:"玛曲县",value:"623025"},{label:"碌曲县",value:"623026"},{label:"夏河县",value:"623027"}]],[[{label:"城东区",value:"630102"},{label:"城中区",value:"630103"},{label:"城西区",value:"630104"},{label:"城北区",value:"630105"},{label:"大通回族土族自治县",value:"630121"},{label:"湟中县",value:"630122"},{label:"湟源县",value:"630123"}],[{label:"乐都区",value:"630202"},{label:"平安区",value:"630203"},{label:"民和回族土族自治县",value:"630222"},{label:"互助土族自治县",value:"630223"},{label:"化隆回族自治县",value:"630224"},{label:"循化撒拉族自治县",value:"630225"}],[{label:"门源回族自治县",value:"632221"},{label:"祁连县",value:"632222"},{label:"海晏县",value:"632223"},{label:"刚察县",value:"632224"}],[{label:"同仁县",value:"632321"},{label:"尖扎县",value:"632322"},{label:"泽库县",value:"632323"},{label:"河南蒙古族自治县",value:"632324"}],[{label:"共和县",value:"632521"},{label:"同德县",value:"632522"},{label:"贵德县",value:"632523"},{label:"兴海县",value:"632524"},{label:"贵南县",value:"632525"}],[{label:"玛沁县",value:"632621"},{label:"班玛县",value:"632622"},{label:"甘德县",value:"632623"},{label:"达日县",value:"632624"},{label:"久治县",value:"632625"},{label:"玛多县",value:"632626"}],[{label:"玉树市",value:"632701"},{label:"杂多县",value:"632722"},{label:"称多县",value:"632723"},{label:"治多县",value:"632724"},{label:"囊谦县",value:"632725"},{label:"曲麻莱县",value:"632726"}],[{label:"格尔木市",value:"632801"},{label:"德令哈市",value:"632802"},{label:"乌兰县",value:"632821"},{label:"都兰县",value:"632822"},{label:"天峻县",value:"632823"},{label:"大柴旦行政委员会",value:"632857"},{label:"冷湖行政委员会",value:"632858"},{label:"茫崖行政委员会",value:"632859"}]],[[{label:"兴庆区",value:"640104"},{label:"西夏区",value:"640105"},{label:"金凤区",value:"640106"},{label:"永宁县",value:"640121"},{label:"贺兰县",value:"640122"},{label:"灵武市",value:"640181"}],[{label:"大武口区",value:"640202"},{label:"惠农区",value:"640205"},{label:"平罗县",value:"640221"}],[{label:"利通区",value:"640302"},{label:"红寺堡区",value:"640303"},{label:"盐池县",value:"640323"},{label:"同心县",value:"640324"},{label:"青铜峡市",value:"640381"}],[{label:"原州区",value:"640402"},{label:"西吉县",value:"640422"},{label:"隆德县",value:"640423"},{label:"泾源县",value:"640424"},{label:"彭阳县",value:"640425"}],[{label:"沙坡头区",value:"640502"},{label:"中宁县",value:"640521"},{label:"海原县",value:"640522"}]],[[{label:"天山区",value:"650102"},{label:"沙依巴克区",value:"650103"},{label:"新市区",value:"650104"},{label:"水磨沟区",value:"650105"},{label:"头屯河区",value:"650106"},{label:"达坂城区",value:"650107"},{label:"米东区",value:"650109"},{label:"乌鲁木齐县",value:"650121"},{label:"乌鲁木齐经济技术开发区",value:"650171"},{label:"乌鲁木齐高新技术产业开发区",value:"650172"}],[{label:"独山子区",value:"650202"},{label:"克拉玛依区",value:"650203"},{label:"白碱滩区",value:"650204"},{label:"乌尔禾区",value:"650205"}],[{label:"高昌区",value:"650402"},{label:"鄯善县",value:"650421"},{label:"托克逊县",value:"650422"}],[{label:"伊州区",value:"650502"},{label:"巴里坤哈萨克自治县",value:"650521"},{label:"伊吾县",value:"650522"}],[{label:"昌吉市",value:"652301"},{label:"阜康市",value:"652302"},{label:"呼图壁县",value:"652323"},{label:"玛纳斯县",value:"652324"},{label:"奇台县",value:"652325"},{label:"吉木萨尔县",value:"652327"},{label:"木垒哈萨克自治县",value:"652328"}],[{label:"博乐市",value:"652701"},{label:"阿拉山口市",value:"652702"},{label:"精河县",value:"652722"},{label:"温泉县",value:"652723"}],[{label:"库尔勒市",value:"652801"},{label:"轮台县",value:"652822"},{label:"尉犁县",value:"652823"},{label:"若羌县",value:"652824"},{label:"且末县",value:"652825"},{label:"焉耆回族自治县",value:"652826"},{label:"和静县",value:"652827"},{label:"和硕县",value:"652828"},{label:"博湖县",value:"652829"},{label:"库尔勒经济技术开发区",value:"652871"}],[{label:"阿克苏市",value:"652901"},{label:"温宿县",value:"652922"},{label:"库车县",value:"652923"},{label:"沙雅县",value:"652924"},{label:"新和县",value:"652925"},{label:"拜城县",value:"652926"},{label:"乌什县",value:"652927"},{label:"阿瓦提县",value:"652928"},{label:"柯坪县",value:"652929"}],[{label:"阿图什市",value:"653001"},{label:"阿克陶县",value:"653022"},{label:"阿合奇县",value:"653023"},{label:"乌恰县",value:"653024"}],[{label:"喀什市",value:"653101"},{label:"疏附县",value:"653121"},{label:"疏勒县",value:"653122"},{label:"英吉沙县",value:"653123"},{label:"泽普县",value:"653124"},{label:"莎车县",value:"653125"},{label:"叶城县",value:"653126"},{label:"麦盖提县",value:"653127"},{label:"岳普湖县",value:"653128"},{label:"伽师县",value:"653129"},{label:"巴楚县",value:"653130"},{label:"塔什库尔干塔吉克自治县",value:"653131"}],[{label:"和田市",value:"653201"},{label:"和田县",value:"653221"},{label:"墨玉县",value:"653222"},{label:"皮山县",value:"653223"},{label:"洛浦县",value:"653224"},{label:"策勒县",value:"653225"},{label:"于田县",value:"653226"},{label:"民丰县",value:"653227"}],[{label:"伊宁市",value:"654002"},{label:"奎屯市",value:"654003"},{label:"霍尔果斯市",value:"654004"},{label:"伊宁县",value:"654021"},{label:"察布查尔锡伯自治县",value:"654022"},{label:"霍城县",value:"654023"},{label:"巩留县",value:"654024"},{label:"新源县",value:"654025"},{label:"昭苏县",value:"654026"},{label:"特克斯县",value:"654027"},{label:"尼勒克县",value:"654028"}],[{label:"塔城市",value:"654201"},{label:"乌苏市",value:"654202"},{label:"额敏县",value:"654221"},{label:"沙湾县",value:"654223"},{label:"托里县",value:"654224"},{label:"裕民县",value:"654225"},{label:"和布克赛尔蒙古自治县",value:"654226"}],[{label:"阿勒泰市",value:"654301"},{label:"布尔津县",value:"654321"},{label:"富蕴县",value:"654322"},{label:"福海县",value:"654323"},{label:"哈巴河县",value:"654324"},{label:"青河县",value:"654325"},{label:"吉木乃县",value:"654326"}],[{label:"石河子市",value:"659001"},{label:"阿拉尔市",value:"659002"},{label:"图木舒克市",value:"659003"},{label:"五家渠市",value:"659004"},{label:"铁门关市",value:"659006"}]],[[{label:"台北",value:"660101"}],[{label:"高雄",value:"660201"}],[{label:"基隆",value:"660301"}],[{label:"台中",value:"660401"}],[{label:"台南",value:"660501"}],[{label:"新竹",value:"660601"}],[{label:"嘉义",value:"660701"}],[{label:"宜兰",value:"660801"}],[{label:"桃园",value:"660901"}],[{label:"苗栗",value:"661001"}],[{label:"彰化",value:"661101"}],[{label:"南投",value:"661201"}],[{label:"云林",value:"661301"}],[{label:"屏东",value:"661401"}],[{label:"台东",value:"661501"}],[{label:"花莲",value:"661601"}],[{label:"澎湖",value:"661701"}]],[[{label:"香港岛",value:"670101"}],[{label:"九龙",value:"670201"}],[{label:"新界",value:"670301"}]],[[{label:"澳门半岛",value:"680101"}],[{label:"氹仔岛",value:"680201"}],[{label:"路环岛",value:"680301"}],[{label:"路氹城",value:"680401"}]]]; ================================================ FILE: src/uni_modules/uview-pro/libs/util/async-validator.d.ts ================================================ /** * async-validator 类型声明文件 * 适用于 uView Pro 内置 async-validator.js * 支持 Schema、规则、校验回调、辅助类型等 */ declare type ValidateError = { message: string; field?: string; [key: string]: any; }; declare type ValidateCallback = ( errors?: ValidateError[] | null, fields?: Record | null ) => void; declare interface ValidateRule { type?: string; required?: boolean; message?: string; validator?: ( rule: ValidateRule, value: any, callback: ValidateCallback, source: Record, options: ValidateOptions ) => void | boolean | string | Error | string[] | Promise; asyncValidator?: ( rule: ValidateRule, value: any, callback: ValidateCallback, source: Record, options: ValidateOptions ) => Promise; enum?: any[]; len?: number; min?: number; max?: number; pattern?: RegExp | string; whitespace?: boolean; fields?: Record; defaultField?: ValidateRule | ValidateRule[]; transform?: (value: any) => any; [key: string]: any; } declare interface ValidateOptions { messages?: Record; suppressWarning?: boolean; first?: boolean; firstFields?: boolean | string[]; keys?: string[]; error?: (rule: ValidateRule, msg: string) => ValidateError; [key: string]: any; } declare class Schema { constructor(descriptor: Record); messages(messages?: Record): Record; define(rules: Record): void; validate( source: Record, options?: ValidateOptions | ValidateCallback, callback?: ValidateCallback ): Promise; getType(rule: ValidateRule): string; getValidationMethod(rule: ValidateRule): Function | false; static register(type: string, validator: Function): void; static warning: (...args: any[]) => void; static messages: Record; } export = Schema; export as namespace Schema; ================================================ FILE: src/uni_modules/uview-pro/libs/util/async-validator.js ================================================ function _extends(){return(_extends=Object.assign||function(e){for(var r=1;r()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,url:new RegExp("^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$","i"),hex:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i},types={integer:function(e){return types.number(e)&&parseInt(e,10)===e},float:function(e){return types.number(e)&&!types.integer(e)},array:function(e){return Array.isArray(e)},regexp:function(e){if(e instanceof RegExp)return!0;try{return!!new RegExp(e)}catch(e){return!1}},date:function(e){return"function"==typeof e.getTime&&"function"==typeof e.getMonth&&"function"==typeof e.getYear},number:function(e){return!isNaN(e)&&"number"==typeof+e},object:function(e){return"object"==typeof e&&!types.array(e)},method:function(e){return"function"==typeof e},email:function(e){return"string"==typeof e&&!!e.match(pattern.email)&&e.length<255},url:function(e){return"string"==typeof e&&!!e.match(pattern.url)},hex:function(e){return"string"==typeof e&&!!e.match(pattern.hex)}};function type(e,r,t,n,a){e.required&&void 0===r?required(e,r,t,n,a):(t=e.type,-1<["integer","float","array","regexp","object","method","email","number","date","url","hex"].indexOf(t)?types[t](r)||n.push(format(a.messages.types[t],e.fullField,e.type)):t&&typeof r!==e.type&&n.push(format(a.messages.types[t],e.fullField,e.type)))}function range(e,r,t,n,a){var i="number"==typeof e.len,s="number"==typeof e.min,u="number"==typeof e.max,o=r,l=null,f="number"==typeof r,p="string"==typeof r,d=Array.isArray(r);if(f?l="number":p?l="string":d&&(l="array"),!l)return!1;d&&(o=r.length),p&&(o=r.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"_").length),i?o!==e.len&&n.push(format(a.messages[l].len,e.fullField,e.len)):s&&!u&&oe.max?n.push(format(a.messages[l].max,e.fullField,e.max)):s&&u&&(oe.max)&&n.push(format(a.messages[l].range,e.fullField,e.min,e.max))}var ENUM="enum";function enumerable(e,r,t,n,a){e[ENUM]=Array.isArray(e[ENUM])?e[ENUM]:[],-1===e[ENUM].indexOf(r)&&n.push(format(a.messages[ENUM],e.fullField,e[ENUM].join(", ")))}function pattern$1(e,r,t,n,a){e.pattern&&(e.pattern instanceof RegExp?(e.pattern.lastIndex=0,e.pattern.test(r)||n.push(format(a.messages.pattern.mismatch,e.fullField,r,e.pattern))):"string"==typeof e.pattern&&(new RegExp(e.pattern).test(r)||n.push(format(a.messages.pattern.mismatch,e.fullField,r,e.pattern))))}var rules={required:required,whitespace:whitespace,type:type,range:range,enum:enumerable,pattern:pattern$1};function string(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,"string")&&!e.required)return t();rules.required(e,r,n,i,a,"string"),isEmptyValue(r,"string")||(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a),rules.pattern(e,r,n,i,a),!0===e.whitespace&&rules.whitespace(e,r,n,i,a))}t(i)}function method(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules.type(e,r,n,i,a)}t(i)}function number(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(""===r&&(r=void 0),isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function _boolean(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules.type(e,r,n,i,a)}t(i)}function regexp(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),isEmptyValue(r)||rules.type(e,r,n,i,a)}t(i)}function integer(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function floatFn(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function array(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,"array")&&!e.required)return t();rules.required(e,r,n,i,a,"array"),isEmptyValue(r,"array")||(rules.type(e,r,n,i,a),rules.range(e,r,n,i,a))}t(i)}function object(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules.type(e,r,n,i,a)}t(i)}var ENUM$1="enum";function enumerable$1(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),void 0!==r&&rules[ENUM$1](e,r,n,i,a)}t(i)}function pattern$2(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,"string")&&!e.required)return t();rules.required(e,r,n,i,a),isEmptyValue(r,"string")||rules.pattern(e,r,n,i,a)}t(i)}function date(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a),isEmptyValue(r)||(r="number"==typeof r?new Date(r):r,rules.type(e,r,n,i,a),r&&rules.range(e,r.getTime(),n,i,a))}t(i)}function required$1(e,r,t,n,a){var i=[],s=Array.isArray(r)?"array":typeof r;rules.required(e,r,n,i,a,s),t(i)}function type$1(e,r,t,n,a){var i=e.type,s=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r,i)&&!e.required)return t();rules.required(e,r,n,s,a,i),isEmptyValue(r,i)||rules.type(e,r,n,s,a)}t(s)}function any(e,r,t,n,a){var i=[];if(e.required||!e.required&&n.hasOwnProperty(e.field)){if(isEmptyValue(r)&&!e.required)return t();rules.required(e,r,n,i,a)}t(i)}var validators={string:string,method:method,number:number,boolean:_boolean,regexp:regexp,integer:integer,float:floatFn,array:array,object:object,enum:enumerable$1,pattern:pattern$2,date:date,url:type$1,hex:type$1,email:type$1,required:required$1,any:any};function newMessages(){return{default:"Validation error on field %s",required:"%s is required",enum:"%s must be one of %s",whitespace:"%s cannot be empty",date:{format:"%s date %s is invalid for format %s",parse:"%s date could not be parsed, %s is invalid ",invalid:"%s date %s is invalid"},types:{string:"%s is not a %s",method:"%s is not a %s (function)",array:"%s is not an %s",object:"%s is not an %s",number:"%s is not a %s",date:"%s is not a %s",boolean:"%s is not a %s",integer:"%s is not an %s",float:"%s is not a %s",regexp:"%s is not a valid %s",email:"%s is not a valid %s",url:"%s is not a valid %s",hex:"%s is not a valid %s"},string:{len:"%s must be exactly %s characters",min:"%s must be at least %s characters",max:"%s cannot be longer than %s characters",range:"%s must be between %s and %s characters"},number:{len:"%s must equal %s",min:"%s cannot be less than %s",max:"%s cannot be greater than %s",range:"%s must be between %s and %s"},array:{len:"%s must be exactly %s in length",min:"%s cannot be less than %s in length",max:"%s cannot be greater than %s in length",range:"%s must be between %s and %s in length"},pattern:{mismatch:"%s value %s does not match pattern %s"},clone:function(){var e=JSON.parse(JSON.stringify(this));return e.clone=this.clone,e}}}var messages=newMessages();function Schema(e){this.rules=null,this._messages=messages,this.define(e)}Schema.prototype={messages:function(e){return e&&(this._messages=deepMerge(newMessages(),e)),this._messages},define:function(e){if(!e)throw new Error("Cannot configure a schema with no rules");if("object"!=typeof e||Array.isArray(e))throw new Error("Rules must be an object");var r,t;for(r in this.rules={},e)e.hasOwnProperty(r)&&(t=e[r],this.rules[r]=Array.isArray(t)?t:[t])},validate:function(t,e,r){var n=this;void 0===e&&(e={}),void 0===r&&(r=function(){});var a,i,s=t,p=e,u=r;if("function"==typeof p&&(u=p,p={}),!this.rules||0===Object.keys(this.rules).length)return u&&u(),Promise.resolve();p.messages?((r=this.messages())===messages&&(r=newMessages()),deepMerge(r,p.messages),p.messages=r):p.messages=this.messages();var o={};(p.keys||Object.keys(this.rules)).forEach(function(r){a=n.rules[r],i=s[r],a.forEach(function(e){"function"==typeof e.transform&&(s===t&&(s=_extends({},s)),i=s[r]=e.transform(i)),(e="function"==typeof e?{validator:e}:_extends({},e)).validator=n.getValidationMethod(e),e.field=r,e.fullField=e.fullField||r,e.type=n.getType(e),e.validator&&(o[r]=o[r]||[],o[r].push({rule:e,value:i,source:s,field:r}))})});var d={};return asyncMap(o,p,function(s,u){var e,o=s.rule,l=!("object"!==o.type&&"array"!==o.type||"object"!=typeof o.fields&&"object"!=typeof o.defaultField);function f(e,r){return _extends({},r,{fullField:o.fullField+"."+e})}function r(e){void 0===e&&(e=[]);var t=e;if(Array.isArray(t)||(t=[t]),!p.suppressWarning&&t.length&&Schema.warning("async-validator:",t),t.length&&o.message&&(t=[].concat(o.message)),t=t.map(complementError(o)),p.first&&t.length)return d[o.field]=1,u(t);if(l){if(o.required&&!s.value)return t=o.message?[].concat(o.message).map(complementError(o)):p.error?[p.error(o,format(p.messages.required,o.field))]:[],u(t);var r,n,a={};if(o.defaultField)for(var i in s.value)s.value.hasOwnProperty(i)&&(a[i]=o.defaultField);for(r in a=_extends({},a,{},s.rule.fields))a.hasOwnProperty(r)&&(n=Array.isArray(a[r])?a[r]:[a[r]],a[r]=n.map(f.bind(null,r)));e=new Schema(a);e.messages(p.messages),s.rule.options&&(s.rule.options.messages=p.messages,s.rule.options.error=p.error),e.validate(s.value,s.rule.options||p,function(e){var r=[];t&&t.length&&r.push.apply(r,t),e&&e.length&&r.push.apply(r,e),u(r.length?r:null)})}else u(t)}l=l&&(o.required||!o.required&&s.value),o.field=s.field,o.asyncValidator?e=o.asyncValidator(o,s.value,r,s.source,p):o.validator&&(!0===(e=o.validator(o,s.value,r,s.source,p))?r():!1===e?r(o.message||o.field+" fails"):e instanceof Array?r(e):e instanceof Error&&r(e.message)),e&&e.then&&e.then(function(){return r()},r)},function(e){!function(e){var r,t,n=[],a={};for(r=0;r>=1)f+=this.lunarInfo[b-1900]&c?1:0;return f+this.leapDays(b)},leapMonth:function(b){return 15&this.lunarInfo[b-1900]},leapDays:function(b){return this.leapMonth(b)?65536&this.lunarInfo[b-1900]?30:29:0},monthDays:function(b,f){return 12>f?30:29},solarDays:function(b,f){if(12; const DEFAULT_DARK_TOKENS = (defaultThemes[0]?.darkColor || {}) as Partial; const STRUCTURAL_TOKENS = new Set([ 'bgColor', 'bgWhite', 'bgGrayLight', 'bgGrayDark', 'bgBlack', 'borderColor', 'lightColor', 'mainColor', 'contentColor', 'tipsColor', 'whiteColor', 'blackColor', 'dividerColor', 'maskColor', 'shadowColor' ]); export type DefaultThemeConfig = { /** * 默认主题 */ defaultTheme?: string; /** * 默认暗黑模式 */ defaultDarkMode?: DarkMode; }; /** * ConfigProvider: 管理全局主题 * - init(themes, defaultName): 初始化主题系统 * - setTheme(name): 切换主题并持久化 * - getThemes/getCurrentTheme: 读取当前数据 * - setDarkMode/getDarkMode: 管理暗黑模式 */ export class ConfigProvider { // 响应式状态,供外部直接引用 public themesRef = ref([]); public currentThemeRef = ref(null); public darkModeRef = ref(config.defaultDarkMode); public cssVarsRef = ref>({}); // 国际化 i18n 状态 public localesRef = ref([]); public currentLocaleRef = ref(null); private baseColorTokens: Partial = DEFAULT_LIGHT_TOKENS; private baseDarkColorTokens: Partial = DEFAULT_DARK_TOKENS; private systemDarkModeMediaQuery: MediaQueryList | null = null; private lastAppliedCssKeys: string[] = []; private interval: ReturnType | number = 0; constructor() { // 默认不自动初始化,调用 init 以传入主题列表 this.initSystemDarkModeListener(); } /** * 初始化系统暗黑模式监听器 * 支持 H5、App、小程序等平台 */ private initSystemDarkModeListener() { // H5 平台:使用 matchMedia API try { if (typeof window !== 'undefined' && window.matchMedia) { this.systemDarkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); const listener = () => { if (this.darkModeRef.value === 'auto') { this.applyTheme(this.currentThemeRef.value); } }; if (this.systemDarkModeMediaQuery.addEventListener) { this.systemDarkModeMediaQuery.addEventListener('change', listener); } else if (this.systemDarkModeMediaQuery.addListener) { this.systemDarkModeMediaQuery.addListener(listener); } } } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] H5 system dark mode listener failed', e); } // uni-app 平台:使用 uni.onThemeChange API try { if (typeof uni !== 'undefined' && typeof uni.onThemeChange === 'function') { uni.onThemeChange((res: { theme: string }) => { console.log('[ConfigProvider] system theme changed', res); if (this.darkModeRef.value === 'auto') { // 系统主题变化时,重新应用主题 this.applyTheme(this.currentThemeRef.value); } }); } } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] uni-app system dark mode listener failed', e); } this.initAppEvent(); } /** * App 平台事件监听 * 经测试 uni.onThemeChange 在 App 平台目前没生效,暂时只能通过定时检查 */ private initAppEvent(): void { // #ifdef APP try { if (this.interval) clearInterval(this.interval); this.interval = setInterval(() => { if (this.darkModeRef.value === 'auto') { // 系统主题变化时,重新应用主题 this.applyTheme(this.currentThemeRef.value); } }, 5000); } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] setInterval failed', e); } // #endif } /** * 检测当前是否应该使用暗黑模式 */ private isSystemDarkMode(): boolean { try { if (this.systemDarkModeMediaQuery) { return this.systemDarkModeMediaQuery.matches; } } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] matchMedia check failed', e); } try { return getNativeSystemDarkMode() === 'dark'; } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] native system theme check failed', e); return false; } } /** * 初始化主题系统 * @param themes 可用主题数组 * @param defaultTheme 可选默认主题名 */ initTheme(themes?: Theme[], defaultConfig?: string | DefaultThemeConfig, isForce?: boolean) { const normalizedThemes = this.normalizeThemes(themes); if (!normalizedThemes.length) { if (isDebugMode('warn')) console.warn('[ConfigProvider] init called with empty themes'); return; } // 配置默认主题 if (defaultConfig) { if (typeof defaultConfig === 'string') { config.defaultTheme = defaultConfig || config.defaultTheme; } else if (typeof defaultConfig === 'object') { const { defaultTheme, defaultDarkMode } = defaultConfig; config.defaultTheme = defaultTheme || config.defaultTheme; config.defaultDarkMode = defaultDarkMode || config.defaultDarkMode; } } // 设置主题列表,响应式 this.themesRef.value = normalizedThemes.slice(); // 先尝试从 Storage 读取已保存主题名 const saved = this.readStorage(THEME_STORAGE_KEY); let initialName = saved || config.defaultTheme || this.themesRef.value[0].name; if (isForce && config.defaultTheme) initialName = config.defaultTheme; let found = this.themesRef.value.find(t => t.name === initialName); if (!found) found = this.themesRef.value.find(t => t.name === config.defaultTheme); if (!found) found = this.themesRef.value[0]; // 设置当前主题,响应式 this.currentThemeRef.value = found; // 初始化暗黑模式设置 this.initDarkMode(config.defaultDarkMode, isForce); // 应用主题 this.applyTheme(found); if (isDebugMode()) console.log('[ConfigProvider] initialized, theme=', found.name, 'darkMode=', this.darkModeRef.value); return this; } /** * 初始化暗黑模式设置 * @param darkMode */ initDarkMode(darkMode?: DarkMode, isForce?: boolean) { // 尝试从 Storage 读取暗黑模式设置 const savedDarkMode = this.readStorage(DARK_MODE_STORAGE_KEY); let darkModeValue = savedDarkMode || darkMode || config.defaultDarkMode; if (isForce && darkMode) darkModeValue = darkMode; this.darkModeRef.value = darkModeValue; } /** * 初始化国际化数据 * @param locales 可选的 locale 列表(对象数组,包含 name 字段) * @param defaultLocaleName 可选默认 locale 名称 */ initLocales(locales?: any[], defaultLocaleName?: string, isForce?: boolean) { const normalized = this.normalizeLocales(locales); if (!normalized.length) { if (isDebugMode('warn')) console.warn('[ConfigProvider] initLocales called with empty locales'); return; } this.localesRef.value = normalized.slice(); // 尝试从 Storage 读取已保存 locale 名称 const saved = this.readStorage(LOCALE_STORAGE_KEY); // 根据传入的 defaultLocaleName 或 saved 或 config.defaultLocale 查找 locale let initialName = saved || defaultLocaleName || config.defaultLocale; if (isForce && defaultLocaleName) initialName = defaultLocaleName; let found = this.localesRef.value.find((l: any) => l.name === initialName); if (!found) found = this.localesRef.value.find(l => l.name === config.defaultLocale); if (!found) found = this.localesRef.value[0]; this.currentLocaleRef.value = found; if (isDebugMode()) console.log('[ConfigProvider] locales initialized, locale=', found?.name); return this; } /** * 归一化 locale 配置,保证始终至少有一个默认 locale */ private normalizeLocales(locales?: any[]) { // 获取内置语言包(可能包含 zh-CN / en-US 等) let builtinList: any[] = []; try { builtinList = Object.values(localePack || {}).filter(v => v && typeof v === 'object'); } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] normalizeLocales read builtin failed', e); } // 如果没有传入自定义 locales,直接返回内置列表 if (!Array.isArray(locales) || !locales.length) { return builtinList.slice(); } // 将 builtin 按 name 映射,便于合并 const map = new Map(); builtinList.forEach(item => { if (item && item.name) { map.set(item.name, { ...(item || {}) }); } }); // 合并用户传入的 locales:若 name 相同则对对象字段进行浅合并(嵌套对象尝试合并) locales.forEach(loc => { if (!loc || !loc.name) return; const existing = map.get(loc.name); if (!existing) { // 新增语言直接加入 map.set(loc.name, { ...(loc || {}) }); return; } // 合并:对每个 key,如果是对象且现有为对象,则进行浅合并,否则覆盖 const merged: any = { ...existing }; Object.keys(loc).forEach(k => { const v = (loc as any)[k]; if (v != null && typeof v === 'object' && !Array.isArray(v) && typeof merged[k] === 'object') { merged[k] = { ...(merged[k] || {}), ...(v || {}) }; } else { merged[k] = v; } }); map.set(loc.name, merged); }); return Array.from(map.values()); } /** * 获取所有可用 locale */ getLocales() { return this.localesRef.value.slice(); } /** * 获取当前 locale 对象 */ getCurrentLocale() { return this.currentLocaleRef.value; } /** * 切换 locale 并持久化 */ setLocale(localeName: string) { if (!this.localesRef.value || this.localesRef.value.length === 0) { if (isDebugMode('warn')) console.warn('[ConfigProvider] setLocale called but locales list empty'); return; } const locale = this.localesRef.value.find(l => l.name === localeName); if (!locale) { if (isDebugMode('warn')) console.warn('[ConfigProvider] locale not found:', localeName); return; } this.currentLocaleRef.value = locale; this.writeStorage(LOCALE_STORAGE_KEY, localeName); if (isDebugMode()) console.log('[ConfigProvider] setLocale ->', localeName); } /** * 翻译函数 * 支持 key 路径,例如 'calendar.placeholder' * replacements 支持数组或对象替换占位符 {0} 或 {name} */ t(key: string, replacements?: any, localeName?: string): string { // 如果 locales 尚未初始化,尝试懒初始化,使用内置语言包作为回退 try { if (!Array.isArray(this.localesRef.value) || this.localesRef.value.length === 0) { this.initLocales(); } } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] lazy initLocales failed', e); } const localeObj = (localeName && this.localesRef.value.find(l => l.name === localeName)) || this.currentLocaleRef.value; if (!localeObj) return key; const parts = key.split('.'); let cur: any = localeObj; for (let i = 0; i < parts.length; i++) { if (cur == null) break; cur = cur[parts[i]]; } let text = typeof cur === 'string' ? cur : key; if (replacements != null) { if (Array.isArray(replacements)) { replacements.forEach((val, idx) => { text = text.split(`{${idx}}`).join(String(val)); }); } else if (typeof replacements === 'object') { Object.keys(replacements).forEach(k => { text = text.split(`{${k}}`).join(String(replacements[k])); }); } } return text; } /** * 获取所有可用主题 */ getThemes(): Theme[] { return this.themesRef.value.slice(); } /** * 获取当前主题 */ getCurrentTheme(): Theme | null { return this.currentThemeRef.value; } /** * 切换主题并持久化 */ setTheme(themeName: string) { if (!this.themesRef.value || this.themesRef.value.length === 0) { if (isDebugMode('warn')) console.warn('[ConfigProvider] setTheme called but themes list empty'); return; } const theme = this.themesRef.value.find(t => t.name === themeName); if (!theme) { if (isDebugMode('warn')) console.warn('[ConfigProvider] theme not found:', themeName); return; } this.currentThemeRef.value = theme; // 应用 this.applyTheme(theme); // 持久化 this.writeStorage(THEME_STORAGE_KEY, themeName); if (isDebugMode()) console.log('[ConfigProvider] setTheme ->', themeName); } /** * 运行时更新当前主题颜色并应用(不持久化) * @param colors 主题颜色键值,支持部分更新 */ public setThemeColor(colors: Partial) { if (!colors || Object.keys(colors).length === 0) return; if (!this.currentThemeRef.value) { if (isDebugMode('warn')) console.warn('[ConfigProvider] setThemeColor called but no current theme'); return; } const mode = this.getActiveMode(); if (mode === 'dark') { const existing = this.currentThemeRef.value.darkColor || {}; this.currentThemeRef.value.darkColor = { ...existing, ...colors }; } else { const existing = this.currentThemeRef.value.color || {}; this.currentThemeRef.value.color = { ...existing, ...colors }; } // 重新应用当前主题以同步运行时 color、CSS 变量等 this.applyTheme(this.currentThemeRef.value); if (isDebugMode()) console.log('[ConfigProvider] setThemeColor ->', colors); } /** * 获取当前暗黑模式设置 */ getDarkMode(): DarkMode { return this.darkModeRef.value; } /** * 设置暗黑模式 * @param mode 'auto' (跟随系统) | 'light' (强制亮色) | 'dark' (强制暗黑) */ setDarkMode(mode: DarkMode) { this.darkModeRef.value = mode; // 持久化 this.writeStorage(DARK_MODE_STORAGE_KEY, mode); // 重新应用主题 this.applyTheme(this.currentThemeRef.value); if (isDebugMode()) console.log('[ConfigProvider] setDarkMode ->', mode); } /** * 检查当前是否处于暗黑模式 */ isInDarkMode(): boolean { const mode = this.darkModeRef.value; if (mode === 'dark') return true; if (mode === 'light') return false; // auto 模式下检查系统设置 return this.isSystemDarkMode(); } /** * 归一化主题配置,保证始终至少有一个默认主题 */ private normalizeThemes(themes?: Theme[]): Theme[] { if (Array.isArray(themes) && themes.length) { return this.mergeThemes(defaultThemes, themes); } return defaultThemes.slice(); } private mergeThemes(...lists: Array): Theme[] { const map = new Map(); lists .filter((list): list is Theme[] => Array.isArray(list) && list.length > 0) .forEach(list => { list.forEach(theme => { const normalized = this.ensureDarkVariant({ ...theme, color: this.applyColorFallbacks(theme.color), darkColor: theme.darkColor ? { ...theme.darkColor } : undefined, css: theme.css ? { ...theme.css } : undefined, darkCss: theme.darkCss ? { ...theme.darkCss } : undefined }); map.set(normalized.name, normalized); }); }); return Array.from(map.values()); } private ensureDarkVariant(theme: Theme): Theme { const finalDark = this.buildDarkPalette(theme); return { ...theme, darkColor: this.applyDarkFallbacks(finalDark) }; } private buildDarkPalette(theme: Theme): Partial { const provided = theme.darkColor || {}; const generated = this.generateDarkFromLight(theme.color || {}, provided); return { ...generated, ...provided }; } /** * 应用亮色主题 */ private applyColorFallbacks(color?: Partial): Partial { return { ...(this.baseColorTokens || {}), ...(color || {}) }; } /** * 应用暗黑主题 */ private applyDarkFallbacks(color?: Partial): Partial { return { ...(this.baseDarkColorTokens || {}), ...(color || {}) }; } private filterNonStructuralTokens(palette: Partial): Partial { const result: Partial = {}; Object.entries(palette || {}).forEach(([key, value]) => { if (!this.isStructuralToken(key)) { (result as any)[key] = value; } }); return result; } private generateDarkFromLight(palette: Partial, provided: Partial): Partial { const result: Partial = {}; const nonStructural = this.filterNonStructuralTokens(palette); Object.entries(nonStructural).forEach(([key, value]) => { if (typeof value !== 'string') return; if (provided && Object.prototype.hasOwnProperty.call(provided, key)) { return; } const fallback = (this.baseDarkColorTokens as any)?.[key]; (result as any)[key] = this.createDarkVariantFromLight(value, fallback); }); return result; } private createDarkVariantFromLight(color: string, fallback?: string): string { const normalized = this.normalizeHex(color); const fallbackHex = fallback ? this.normalizeHex(fallback) : null; if (normalized && fallbackHex) { return this.mixHex(normalized, fallbackHex, 0.6); } if (fallbackHex) return fallbackHex; return normalized || color; } private normalizeHex(color: string): string | null { if (!color) return null; const hex = color.trim(); if (/^#([0-9a-fA-F]{6})$/.test(hex)) return hex.toLowerCase(); return null; } private mixHex(fromHex: string, toHex: string, ratio: number): string { const from = this.hexToRgb(fromHex); const to = this.hexToRgb(toHex); if (!from || !to) return toHex; const clamp = (val: number) => Math.min(255, Math.max(0, Math.round(val))); const r = clamp(from.r * (1 - ratio) + to.r * ratio); const g = clamp(from.g * (1 - ratio) + to.g * ratio); const b = clamp(from.b * (1 - ratio) + to.b * ratio); return this.rgbToHex(r, g, b); } private hexToRgb(hex: string): { r: number; g: number; b: number } | null { const match = /^#([0-9a-fA-F]{6})$/.exec(hex); if (!match) return null; return { r: parseInt(match[1].slice(0, 2), 16), g: parseInt(match[1].slice(2, 4), 16), b: parseInt(match[1].slice(4, 6), 16) }; } private rgbToHex(r: number, g: number, b: number): string { const toHex = (val: number) => val.toString(16).padStart(2, '0'); return `#${toHex(r)}${toHex(g)}${toHex(b)}`; } private isStructuralToken(token: string): boolean { return STRUCTURAL_TOKENS.has(token); } /** * 运行时同步主题颜色($u.color) * 更新响应式 color 对象,确保所有使用 $u.color 的地方都能响应式更新 */ private syncRuntimeTheme(palette: Partial) { try { // 合并默认值,确保所有颜色都有值 const defaultPalette = this.getActiveMode() === 'dark' ? this.baseDarkColorTokens : this.baseColorTokens; const mergedPalette = { ...defaultPalette, ...palette }; // 更新响应式 color 对象 Object.keys(mergedPalette).forEach(key => { const value = (mergedPalette as any)[key]; if (value != null) { (reactiveColor as any)[key] = value; } }); // 同步到 uni.$u.color(如果存在) if (typeof uni !== 'undefined' && uni?.$u?.color) { uni.$u.color = reactiveColor; } } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] sync runtime theme failed', e); } } /** * 获取当前激活的模式 */ private getActiveMode(): 'light' | 'dark' { return this.isInDarkMode() ? 'dark' : 'light'; } /** * 获取当前主题的配色方案 */ private getPaletteForMode(theme: Theme, mode: 'light' | 'dark') { if (mode === 'dark') { return theme.darkColor && Object.keys(theme.darkColor).length ? theme.darkColor : theme.color || {}; } return theme.color || {}; } /** * 获取当前主题的CSS变量覆盖 */ private getCssOverrides(theme: Theme, mode: 'light' | 'dark') { if (mode === 'dark') { return (theme.darkCss && Object.keys(theme.darkCss).length ? theme.darkCss : theme.css) || {}; } return theme.css || {}; } /** * 读取Storage key */ private readStorage(key: string): T | null { try { if (typeof uni === 'undefined' || typeof uni.getStorageSync !== 'function') return null; const value = uni.getStorageSync(key); return (value ?? null) as T | null; } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] failed to read storage', e); return null; } } /** * 写入Storage key value */ private writeStorage(key: string, value: any) { try { if (typeof uni === 'undefined' || typeof uni.setStorageSync !== 'function') return; uni.setStorageSync(key, value); } catch (e) { if (isDebugMode('error')) console.error('[ConfigProvider] failed to write storage', e); } } /** * 更新文档主题模式 H5 */ private updateDocumentMode(mode: 'light' | 'dark') { if (typeof document === 'undefined' || !document.documentElement) return; const root = document.documentElement; root.dataset.uThemeMode = mode; root.classList.remove('u-theme-light', 'u-theme-dark'); root.classList.add(`u-theme-${mode}`); } /** * 转换为 CSS 变量名称 */ private toCssVarName(key: string, prefix: string = '--u'): string { const types = config.type; if (types.some(type => key.startsWith(type))) { prefix += '-type'; } const kebab = key .replace(/([a-z0-9])([A-Z])/g, '$1-$2') .replace(/[\s_]+/g, '-') .toLowerCase(); return `${prefix}-${kebab}`; } /** * 添加 RGB 值 */ private attachRgbVar(target: Record, varName: string, value: string) { if (typeof value !== 'string') return; const hex = value.startsWith('#') ? value.slice(1) : ''; if (!/^[0-9a-fA-F]{6}$/.test(hex)) return; const r = parseInt(hex.slice(0, 2), 16); const g = parseInt(hex.slice(2, 4), 16); const b = parseInt(hex.slice(4, 6), 16); target[`${varName}-rgb`] = `${r}, ${g}, ${b}`; } /** * 构建 CSS 变量映射表 * 生成格式: */ private buildCssVarMap(theme: Theme, mode: 'light' | 'dark'): Record { const map: Record = { '--u-theme-mode': mode }; const palette = this.getPaletteForMode(theme, mode); const cssOverrides = this.getCssOverrides(theme, mode); const applyEntry = (key: string, value: string | number | undefined | null) => { if (value == null) return; const strValue = String(value); if (key.startsWith('--')) { map[key] = strValue; this.attachRgbVar(map, key, strValue); return; } const cssVarName = this.toCssVarName(key); // const typeVarName = this.toCssVarName(key, '--u-type'); map[cssVarName] = strValue; // map[typeVarName] = strValue; this.attachRgbVar(map, cssVarName, strValue); // this.attachRgbVar(map, typeVarName, strValue); }; Object.entries(palette || {}).forEach(([key, value]) => applyEntry(key, value as any)); Object.entries(cssOverrides || {}).forEach(([key, value]) => applyEntry(key, value as any)); return map; } /** * 刷新 CSS 变量 H5 */ private flushCssVars(vars: Record) { if (typeof document === 'undefined' || !document.documentElement) return; const root = document.documentElement; this.lastAppliedCssKeys.forEach(key => { root.style.removeProperty(key); }); Object.entries(vars).forEach(([key, value]) => { root.style.setProperty(key, value); }); this.lastAppliedCssKeys = Object.keys(vars); } /** * 将主题应用到运行时: * - 1) 调用 uni.$u.setColor(theme.color) 如果存在 * - 2) 在 H5 环境中,将 css map 注入到 document.documentElement 的 CSS 变量中 * - 3) 支持暗黑模式:根据 darkColor 或 color 应用相应的颜色 */ private applyTheme(theme: Theme | null) { if (!theme) return; const mode = this.getActiveMode(); const palette = this.getPaletteForMode(theme, mode); this.syncRuntimeTheme(palette); const cssVarMap = this.buildCssVarMap(theme, mode); this.cssVarsRef.value = cssVarMap; this.flushCssVars(cssVarMap); this.updateDocumentMode(mode); } } // 单例导出 export const configProvider = new ConfigProvider(); export default configProvider; ================================================ FILE: src/uni_modules/uview-pro/libs/util/emitter.ts ================================================ import { getCurrentInstance, type ComponentInternalInstance } from 'vue'; /** * 适用于 uni-app Vue3 的事件派发/广播工具 * 用法:import { dispatch, broadcast } from './emitter' */ /** * 向上查找父组件并派发事件 * @param instance 当前组件实例(setup中可用getCurrentInstance()) * @param componentName 目标组件名 * @param eventName 事件名 * @param params 参数 */ // 将事件名转换为驼峰格式 // 例如:on-form-change -> onFormChange function formatToCamelCase(str: string): string { return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); } /** * 向上查找父组件 * @param instance 当前组件实例(setup中可用getCurrentInstance()) * @param componentName 目标组件名 * @returns 父组件实例 */ function parent(instance: ComponentInternalInstance | null | undefined = undefined, componentName: string = '') { if (!instance) { instance = getCurrentInstance(); } let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined); if (!componentName) return parent; while (parent) { const name = (parent.type as any)?.name as string | undefined; if (name === componentName) { return parent; } parent = parent.parent; } return null; } /** * 向上查找父组件并派发事件 * @param instance 当前组件实例(setup中可用getCurrentInstance()) * @param componentName 目标组件名 * @param eventName 事件名 * @param params 参数 */ function dispatch( instance: ComponentInternalInstance | null | undefined, componentName: string, eventName: string, ...params: any[] ) { let parent = instance && (instance.parent as ComponentInternalInstance | null | undefined); while (parent) { const name = (parent.type as any)?.name as string | undefined; if (name === componentName) { // 找到目标组件,派发事件 // Vue3未解决,目标组件事件监听失效,待优化,暂时使用下面的方式解决,如果你有好的方式也可以告诉我或者提PR parent.emit && parent.emit(eventName, ...params); // 如果有对应的方法,执行方法 // 这里可以考虑将 eventName 转换为驼峰格式 // 例如:on-form-change -> onFormChange parent.exposed?.[formatToCamelCase(eventName)] && parent.exposed[formatToCamelCase(eventName)](...params); break; } parent = parent.parent; } } /** * 向下递归查找子组件并广播事件 * @param instance 当前组件实例(setup中可用getCurrentInstance()) * @param componentName 目标组件名 * @param eventName 事件名 * @param params 参数 */ function broadcast( instance: ComponentInternalInstance | null | undefined, componentName: string, eventName: string, ...params: any[] ) { if (!instance) return; const subTree = (instance.subTree as any)?.children || []; const children = Array.isArray(subTree) ? subTree : [subTree]; children.forEach((vnode: any) => { const child = vnode.component as ComponentInternalInstance | undefined; if (child) { const name = (child.type as any)?.name as string | undefined; if (name === componentName) { // 找到目标组件,广播事件 // Vue3未解决,目标组件事件监听失效,待优化,暂时使用下面的方式解决,如果你有好的方式也可以告诉我或者提PR child.emit && child.emit(eventName, ...params); // 如果有对应的方法,执行方法 // 这里可以考虑将 eventName 转换为驼峰格式 // 例如:on-form-change -> onFormChange child.exposed?.[formatToCamelCase(eventName)] && child.exposed[formatToCamelCase(eventName)](...params); } else { broadcast(child, componentName, eventName, ...params); } } }); } export { dispatch, broadcast, parent }; ================================================ FILE: src/uni_modules/uview-pro/libs/util/mitt.ts ================================================ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /** * copy to https://github.com/developit/mitt * Expand clear method */ export type EventType = string | symbol; // An event handler can take an optional event argument // and should not return a value export type Handler = (event: T) => void; export type WildcardHandler> = (type: keyof T, event: T[keyof T]) => void; // An array of all currently registered event handlers for a type export type EventHandlerList = Array>; export type WildCardEventHandlerList> = Array>; // A map of event types and their corresponding event handlers. export type EventHandlerMap> = Map< '*' | keyof Events, EventHandlerList | WildCardEventHandlerList >; export interface Emitter> { all: EventHandlerMap; on(type: Key, handler: Handler): void; on(type: '*', handler: WildcardHandler): void; off(type: Key, handler?: Handler): void; off(type: '*', handler: WildcardHandler): void; emit(type: Key, event: Events[Key]): void; emit(type: undefined extends Events[Key] ? Key : never): void; clear(): void; } /** * Mitt: Tiny (~200b) functional event emitter / pubsub. * @name mitt * @returns {Mitt} */ export function mitt>(all?: EventHandlerMap): Emitter { type GenericEventHandler = Handler | WildcardHandler; all = all || new Map(); return { /** * A Map of event names to registered handler functions. */ all, /** * Register an event handler for the given type. * @param {string|symbol} type Type of event to listen for, or `'*'` for all events * @param {Function} handler Function to call in response to given event * @memberOf mitt */ on(type: Key, handler: GenericEventHandler) { const handlers: Array | undefined = all!.get(type); if (handlers) { handlers.push(handler); } else { all!.set(type, [handler] as EventHandlerList); } }, /** * Remove an event handler for the given type. * If `handler` is omitted, all handlers of the given type are removed. * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler) * @param {Function} [handler] Handler function to remove * @memberOf mitt */ off(type: Key, handler?: GenericEventHandler) { const handlers: Array | undefined = all!.get(type); if (handlers) { if (handler) { handlers.splice(handlers.indexOf(handler) >>> 0, 1); } else { all!.set(type, []); } } }, /** * Invoke all handlers for the given type. * If present, `'*'` handlers are invoked after type-matched handlers. * * Note: Manually firing '*' handlers is not supported. * * @param {string|symbol} type The event type to invoke * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @memberOf mitt */ emit(type: Key, evt?: Events[Key]) { let handlers = all!.get(type); if (handlers) { [...(handlers as EventHandlerList)].forEach(handler => { handler(evt as Events[Key]); }); } handlers = all!.get('*'); if (handlers) { [...(handlers as WildCardEventHandlerList)].forEach(handler => { handler(type, evt as Events[Key]); }); } }, /** * Clear all */ clear() { this.all.clear(); } }; } ================================================ FILE: src/uni_modules/uview-pro/libs/util/province.ts ================================================ export default [{label:"北京市",value:"11"},{label:"天津市",value:"12"},{label:"河北省",value:"13"},{label:"山西省",value:"14"},{label:"内蒙古自治区",value:"15"},{label:"辽宁省",value:"21"},{label:"吉林省",value:"22"},{label:"黑龙江省",value:"23"},{label:"上海市",value:"31"},{label:"江苏省",value:"32"},{label:"浙江省",value:"33"},{label:"安徽省",value:"34"},{label:"福建省",value:"35"},{label:"江西省",value:"36"},{label:"山东省",value:"37"},{label:"河南省",value:"41"},{label:"湖北省",value:"42"},{label:"湖南省",value:"43"},{label:"广东省",value:"44"},{label:"广西壮族自治区",value:"45"},{label:"海南省",value:"46"},{label:"重庆市",value:"50"},{label:"四川省",value:"51"},{label:"贵州省",value:"52"},{label:"云南省",value:"53"},{label:"西藏自治区",value:"54"},{label:"陕西省",value:"61"},{label:"甘肃省",value:"62"},{label:"青海省",value:"63"},{label:"宁夏回族自治区",value:"64"},{label:"新疆维吾尔自治区",value:"65"},{label:"台湾",value:"66"},{label:"香港",value:"67"},{label:"澳门",value:"68"}]; ================================================ FILE: src/uni_modules/uview-pro/libs/util/system-theme.ts ================================================ declare const uni: any; type SystemTheme = 'light' | 'dark'; /** * 非 H5 平台获取当前系统主题 */ export function getSystemDarkMode(): SystemTheme { try { if (typeof uni !== 'undefined' && typeof uni.getSystemInfoSync === 'function') { const systemInfo = uni.getSystemInfoSync(); const theme = systemInfo.osTheme || systemInfo.theme || 'light'; if (theme === 'dark') { return 'dark'; } if (theme === 'light') { return 'light'; } } } catch (e) { // 获取失败时默认返回亮色 console.warn('[system-theme] getSystemDarkMode failed', e); } return 'light'; } ================================================ FILE: src/uni_modules/uview-pro/locale/index.ts ================================================ export { default as zhCN } from './lang/zh-CN'; export { default as enUS } from './lang/en-US'; ================================================ FILE: src/uni_modules/uview-pro/locale/lang/en-US.ts ================================================ export default { name: 'en-US', label: 'English', locale: 'en', uActionSheet: { cancelText: 'Cancel' }, uUpload: { uploadText: 'Select File', uploadImage: 'Select Image', uploadVideo: 'Select Video', uploadFile: 'Select File', uploadMedia: 'Select Media', retry: 'Retry', overSize: 'File size exceeds allowed limit', overMaxCount: 'Exceeds maximum allowed number of files', reUpload: 'Re-upload', uploadFailed: 'Upload failed, please try again', modalTitle: 'Notice', modalCancelText: 'Cancel', modalConfirmText: 'Confirm', deleteConfirm: 'Are you sure you want to delete this item?', terminatedRemove: 'Removal cancelled', removeSuccess: 'Removed successfully', previewFailed: 'Failed to preview image', notAllowedExt: 'Files with {ext} format are not allowed', noAction: 'Please configure upload address', fileNotSupported: 'File selection is not supported on this platform', openFailed: 'Unable to open this file' }, uVerificationCode: { startText: 'Get Code', changeText: 'Retry in Xs', endText: 'Retry' }, uSection: { subTitle: 'More' }, uSelect: { cancelText: 'Cancel', confirmText: 'Confirm' }, uSearch: { placeholder: 'Please enter keywords', actionText: 'Search' }, uNoNetwork: { tips: 'Ooops, network disconnected', checkNetwork: 'Please check network or go to', setting: 'Settings', retry: 'Retry', noConnection: 'No network connection', connected: 'Network connected' }, uReadMore: { closeText: 'Read More', openText: 'Collapse' }, uPagination: { prevText: 'Prev', nextText: 'Next' }, uPicker: { cancelText: 'Cancel', confirmText: 'Confirm' }, uModal: { title: 'Notice', content: 'Content', confirmText: 'Confirm', cancelText: 'Cancel' }, uLoadmore: { loadmore: 'Load more', loading: 'Loading...', nomore: 'No more' }, uLink: { mpTips: 'Link copied, please open it in browser' }, uKeyboard: { cancelText: 'Cancel', confirmText: 'Confirm', number: 'Number Keyboard', idCard: 'ID Card Keyboard', plate: 'Plate Keyboard' }, uInput: { placeholder: 'Please enter' }, uCalendar: { startText: 'Start', endText: 'End', toolTip: 'Select date', outOfRange: 'Date out of range', year: '', month: '', sun: 'Sun', mon: 'Mon', tue: 'Tue', wed: 'Wed', thu: 'Thu', fri: 'Fri', sat: 'Sat', confirmText: 'Confirm', to: ' to ', holiday: '休', workday: '班' }, uEmpty: { car: 'Shopping cart is empty', page: 'Page not found', search: 'No search results', address: 'No shipping address', wifi: 'No WiFi', order: 'No orders', coupon: 'No coupons', favor: 'No favorites', permission: 'No permission', history: 'No history', news: 'No news', message: 'No messages', list: 'No list', data: 'No data' }, uCountDown: { day: 'days', hour: 'hours', minute: 'minutes', second: 'Second' }, uFullScreen: { title: 'New Version Available', upgrade: 'Upgrade' } }; ================================================ FILE: src/uni_modules/uview-pro/locale/lang/zh-CN.ts ================================================ export default { name: 'zh-CN', label: '简体中文', locale: 'zh-Hans', uActionSheet: { cancelText: '取消' }, uUpload: { uploadText: '选择文件', uploadImage: '选择图片', uploadVideo: '选择视频', uploadFile: '选择文件', uploadMedia: '选择媒体', retry: '点击重试', overSize: '超出允许的文件大小', overMaxCount: '超出最大允许的文件个数', reUpload: '重新上传', uploadFailed: '上传失败,请重试', modalTitle: '提示', modalCancelText: '取消', modalConfirmText: '确定', deleteConfirm: '您确定要删除此项吗?', terminatedRemove: '已终止移除', removeSuccess: '移除成功', previewFailed: '预览图片失败', notAllowedExt: '不允许选择{ext}格式的文件', noAction: '请配置上传地址', fileNotSupported: '当前平台暂不支持文件选择', openFailed: '无法打开此文件' }, uVerificationCode: { startText: '获取验证码', changeText: 'X秒重新获取', endText: '重新获取' }, uSection: { subTitle: '更多' }, uSelect: { cancelText: '取消', confirmText: '确认' }, uSearch: { placeholder: '请输入关键字', actionText: '搜索' }, uNoNetwork: { tips: '哎呀,网络信号丢失', checkNetwork: '请检查网络,或前往', setting: '设置', retry: '重试', noConnection: '无网络连接', connected: '网络已连接' }, uReadMore: { closeText: '展开阅读全文', openText: '收起' }, uPagination: { prevText: '上一页', nextText: '下一页' }, uPicker: { cancelText: '取消', confirmText: '确认' }, uModal: { title: '提示', content: '内容', confirmText: '确认', cancelText: '取消' }, uLoadmore: { loadmore: '加载更多', loading: '正在加载...', nomore: '没有更多了' }, uLink: { mpTips: '链接已复制,请在浏览器打开' }, uKeyboard: { cancelText: '取消', confirmText: '确认', number: '数字键盘', idCard: '身份证键盘', plate: '车牌号键盘' }, uInput: { placeholder: '请输入内容' }, uCalendar: { startText: '开始', endText: '结束', toolTip: '选择日期', outOfRange: '日期超出范围啦~', year: '年', month: '月', sun: '日', mon: '一', tue: '二', wed: '三', thu: '四', fri: '五', sat: '六', confirmText: '确定', to: '至', holiday: '休', workday: '班' }, uEmpty: { car: '购物车为空', page: '页面不存在', search: '没有搜索结果', address: '没有收货地址', wifi: '没有WiFi', order: '订单为空', coupon: '没有优惠券', favor: '暂无收藏', permission: '无权限', history: '无历史记录', news: '无新闻列表', message: '消息列表为空', list: '列表为空', data: '数据为空' }, uCountDown: { day: '天', hour: '时', minute: '分', second: '秒' }, uFullScreen: { title: '发现新版本', upgrade: '升级' } }; ================================================ FILE: src/uni_modules/uview-pro/package.json ================================================ { "id": "uview-pro", "name": "uview-pro", "displayName": "【支持鸿蒙】uView Pro|基于Vue3+TS的高质量UI组件库,支持多主题、暗黑模式、多语言", "version": "0.6.0-beta.1", "description": "uView Pro是基于Vue3+TS的多平台UI框架,提供80+高质量组件、便捷工具和常用模板,支持多主题、暗黑模式、多语言,支持H5/APP/鸿蒙/小程序多端开发。已在鸿蒙应用商店上架,欢迎体验!", "main": "index.ts", "module": "index.ts", "browser": "index.ts", "keywords": [ "uview-pro", "vue3", "多主题", "暗黑模式", "多语言" ], "author": "anyup", "license": "MIT", "repository": "https://github.com/anyup/uview-pro", "engines": { "HBuilderX": "^4.07", "uni-app": "^4.07", "uni-app-x": "" }, "dcloudext": { "type": "component-vue", "sale": { "regular": { "price": "0.00" }, "sourcecode": { "price": "0.00" } }, "contact": { "qq": "491302297" }, "declaration": { "ads": "无", "data": "无", "permissions": "无" }, "npmurl": "https://www.npmjs.com/package/uview-pro", "darkmode": "√", "i18n": "√", "widescreen": "√" }, "uni_modules": { "dependencies": [], "encrypt": [], "platforms": { "cloud": { "tcb": "√", "aliyun": "√", "alipay": "√" }, "client": { "uni-app": { "vue": { "vue2": "x", "vue3": "√" }, "web": { "safari": "√", "chrome": "√" }, "app": { "vue": "√", "nvue": "-", "android": "√", "ios": "√", "harmony": "√" }, "mp": { "weixin": "√", "alipay": "√", "toutiao": "√", "baidu": "-", "kuaishou": "-", "jd": "-", "harmony": "√", "qq": "√", "lark": "-", "xhs": "-" }, "quickapp": { "huawei": "-", "union": "-" } }, "uni-app-x": { "web": { "safari": "-", "chrome": "-" }, "app": { "android": "-", "ios": "-", "harmony": "-" }, "mp": { "weixin": "-" } } } } } } ================================================ FILE: src/uni_modules/uview-pro/readme.md ================================================

logo

uView Pro

uni-app Vue3 多平台快速开发的 UI 框架

[![star](https://gitee.com/anyup/uView-Pro/badge/star.svg)](https://gitee.com/anyup/uView-Pro) [![fork](https://gitee.com/anyup/uView-Pro/badge/fork.svg)](https://gitee.com/anyup/uView-Pro) [![stars](https://img.shields.io/github/stars/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro) [![forks](https://img.shields.io/github/forks/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro) [![issues](https://img.shields.io/github/issues/anyup/uView-Pro?style=flat-square&logo=GitHub)](https://github.com/anyup/uView-Pro/issues) [![downloads](https://img.shields.io/npm/dm/uview-pro?logo=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Fuview-pro&style=flat-square)](https://www.npmjs.com/package/uview-pro) [![npm version](https://img.shields.io/npm/v/uview-pro)](https://www.npmjs.com/package/uview-pro) [![Website](https://img.shields.io/badge/uView%20Pro-docs-blue?style=flat-square)](https://uviewpro.cn) [![node version](https://img.shields.io/badge/node-%3E%3D18-green)](https://nodejs.org/) [![pnpm version](https://img.shields.io/badge/pnpm-%3E%3D7.30-green)](https://pnpm.io/) [![license](https://img.shields.io/github/license/anyup/uView-Pro?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License) ## 说明 `uView UI`,是 [uni-app](https://uniapp.dcloud.io/) 生态优秀的 UI 框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水。 `uView Pro`,是全面支持 Vue3.0、TypeScript 的 uni-app 生态框架,uView Pro 的基线版本是基于 uView 1.8.8 修改,使用 TypeScript 完全重构,已覆盖 Android、iOS、鸿蒙以及微信/头条/支付宝等主流小程序平台,真正实现“一套代码,多端运行”,支持多主题系统、暗黑模式与国际化(i18n)。 ## [官方文档:https://uviewpro.cn](https://uviewpro.cn) ## [快速启动模板:https://starter.uviewpro.cn](https://starter.uviewpro.cn) ## 特性 - 兼容安卓,iOS,微信小程序,H5,QQ 小程序,百度小程序,支付宝小程序,头条小程序 - 70+精选组件,功能丰富,多端兼容,让您快速集成,开箱即用 - 众多贴心的 JS 利器,让您飞镖在手,召之即来,百步穿杨 - 众多的常用页面和布局,让您专注逻辑,事半功倍 - 详尽的文档支持,现代化的演示效果 - 按需引入,精简打包体积 ## 鸿蒙预览 🎉🎉 uView Pro 鸿蒙端应用已正式上线华为鸿蒙应用市场,为您提供完整的业务场景演示平台,包含组件库、模板示例、场景案例等,支持一键复制下载,帮助开发者快速上手并体验组件的实际应用价值! > 系统要求:仅支持 HarmonyOS 5.0 及以上版本设备
鸿蒙应用
(浏览器扫码)
## 手机预览 您可以通过**微信**或**手机浏览器**扫描以下二维码,查看最佳的演示效果。
微信小程序
(微信扫码)
支付宝小程序
(支付宝扫码)
H5
(浏览器扫码)
Android
(浏览器扫码)
运行示例工程,请[下载源码](https://github.com/anyup/uview-pro)后,在项目根目录执行以下命令: ```bash pnpm install pnpm dev ``` ## 链接 - [Github](https://github.com/anyup/uview-pro) - [Gitee](https://gitee.com/anyup/uview-pro) - [官方文档](https://uviewpro.cn) - [更新日志](https://github.com/anyup/uView-Pro/blob/master/src/uni_modules/uview-pro/changelog.md) ## 交流反馈 欢迎通过各种方式来交流反馈,让 uView Pro 更好的为大家服务: [欢迎交流反馈](https://uviewpro.cn/zh/resource/about.html) ## 捐赠 uView Pro 开源不易,如果您认为 `uView Pro` 帮到了您的开发工作,您可以捐赠 `uView Pro`: [欢迎捐赠留名](https://uviewpro.cn/zh/reward/donation.html) ## 关于 PR 我们非常乐意接受各位的优质 PR,但在此之前我希望您了解 `uView Pro` 是一个需要兼容多个平台的(小程序、h5、iOS App、Android App)包括 nvue 页面、vue 页面。 所以希望在您修复 bug 并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢! ## 安装配置 `uView Pro` 支持 `npm` 和 `uni_modules` 两种主流安装方式,配置方式高度一致。无论采用哪种方式,均可通过 `easycom` 实现组件自动引入,极大提升开发效率。以下为统一的配置说明: ### 1. 安装 uView Pro - npm 安装: ```bash npm install uview-pro # 或 yarn add uview-pro # 或 pnpm add uview-pro ``` - uni_modules 安装: 通过 HBuilderX 插件市场或手动下载,将 uView Pro 放入 `uni_modules` 目录。 [插件市场:https://ext.dcloud.net.cn/plugin?id=24633](https://ext.dcloud.net.cn/plugin?id=24633) ### 2. 引入 uView Pro 主库 在 `main.ts` 中引入并注册 uView Pro: ```js import { createSSRApp } from 'vue'; // npm 方式 import uViewPro from 'uview-pro'; // uni_modules 方式 // import uViewPro from "@/uni_modules/uview-pro"; export function createApp() { const app = createSSRApp(App); app.use(uViewPro); return { app }; } ``` ### 3. 引入全局样式 在 `uni.scss` 中引入主题样式: ```scss /* npm 方式 */ @import 'uview-pro/theme.scss'; /* uni_modules 方式 */ /* @import "@/uni_modules/uview-pro/theme.scss"; */ ``` 在 `App.vue` 首行引入基础样式: ```scss ``` ### 4. 配置 easycom 自动引入组件 在 `pages.json` 中配置 `easycom` 规则,实现组件自动引入: ```json { "easycom": { "autoscan": true, "custom": { // npm 方式 "^u-(.*)": "uview-pro/components/u-$1/u-$1.vue" // uni_modules 方式 // "^u-(.*)": "@/uni_modules/uview-pro/components/u-$1/u-$1.vue" } }, "pages": [] } ``` **温馨提示** - 1.修改 `easycom` 规则后需重启 HX 或重新编译项目。 - 2.请确保 `pages.json` 中只有一个 easycom 字段,否则请自行合并多个规则。 - 3.一定要放在 `custom` 内,否则无效。 ### 5. Volar 类型提示支持 如需在 `CLI` 项目中获得 `Volar` 的全局类型提示,请在 `tsconfig.json` 中添加: ```json { "compilerOptions": { // npm 方式 "types": ["uview-pro/types"] // uni_modules 方式 // "types": ["@/uni_modules/uview-pro/types"] } } ``` > HBuilderX 项目暂不支持 `tsconfig.json` 的 `types` 配置,`CLI` 项目推荐配置以获得最佳 `TS` 体验。 ### 6. 组件使用 配置完成后,无需 `import` 和 `components` 注册,可直接在 `SFC` 中使用 `uView Pro` 组件: ```vue ``` 请通过[快速上手](https://uviewpro.cn/zh/components/quickstart.html)了解更详细的内容 ## 贡献者 Contributors ## 版权信息 `uView Pro` 遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将 `uView Pro` 应用到您的产品中。 ## 鸣谢 再次感谢 `uView UI` 开发团队,以及所有为 `uView UI` 的贡献者,以及所有为 `uView Pro` 的贡献者。 - [Github](https://github.com/anyup/uview-pro) - [Gitee](https://gitee.com/anyup/uview-pro) - [uView UI 1.0](https://github.com/umicro/uView) - [uView UI 2.0](https://github.com/umicro/uView2.0) ================================================ FILE: src/uni_modules/uview-pro/theme.scss ================================================ // 此文件为uView的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于 // uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大, // 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入 :root, page { /* 纯色 */ --u-white-color: #ffffff; --u-white-color-rgb: 255, 255, 255; --u-black-color: #000000; --u-black-color-rgb: 0, 0, 0; // 字体色 --u-main-color: #303133; --u-main-color-rgb: 48, 49, 51; --u-content-color: #606266; --u-content-color-rgb: 96, 98, 102; --u-tips-color: #909399; --u-tips-color-rgb: 144, 147, 153; --u-light-color: #c0c4cc; --u-light-color-rgb: 192, 196, 204; // 边框色 --u-border-color: #dcdfe6; --u-border-color-rgb: 220, 223, 230; --u-divider-color: #e4e7ed; --u-divider-color-rgb: 228, 231, 237; // 遮罩色 --u-mask-color: rgba(0, 0, 0, 0.4); --u-shadow-color: rgba(0, 0, 0, 0.1); /* 背景色 */ --u-bg-color: #f3f4f6; --u-bg-color-rgb: 243, 244, 246; --u-bg-white: #ffffff; --u-bg-white-rgb: 255, 255, 255; --u-bg-gray-light: #f1f1f1; --u-bg-gray-light-rgb: 241, 241, 241; --u-bg-gray-dark: #2f343c; --u-bg-gray-dark-rgb: 47, 52, 60; --u-bg-black: #000000; --u-bg-black-rgb: 0, 0, 0; /* 主色 */ --u-type-primary: #2979ff; --u-type-primary-rgb: 41, 121, 255; --u-type-primary-disabled: #a0cfff; --u-type-primary-disabled-rgb: 160, 207, 255; --u-type-primary-dark: #2b85e4; --u-type-primary-dark-rgb: 43, 133, 228; --u-type-primary-light: #ecf5ff; --u-type-primary-light-rgb: 236, 245, 255; /* 警告色 */ --u-type-warning: #ff9900; --u-type-warning-rgb: 255, 153, 0; --u-type-warning-disabled: #fcbd71; --u-type-warning-disabled-rgb: 252, 189, 113; --u-type-warning-dark: #f29100; --u-type-warning-dark-rgb: 242, 145, 0; --u-type-warning-light: #fdf6ec; --u-type-warning-light-rgb: 253, 246, 236; /* 成功色 */ --u-type-success: #19be6b; --u-type-success-rgb: 25, 190, 107; --u-type-success-disabled: #71d5a1; --u-type-success-disabled-rgb: 113, 213, 161; --u-type-success-dark: #18b566; --u-type-success-dark-rgb: 24, 181, 102; --u-type-success-light: #dbf1e1; --u-type-success-light-rgb: 219, 241, 225; /* 错误色 */ --u-type-error: #fa3534; --u-type-error-rgb: 250, 53, 52; --u-type-error-disabled: #fab6b6; --u-type-error-disabled-rgb: 250, 182, 182; --u-type-error-dark: #dd6161; --u-type-error-dark-rgb: 221, 97, 97; --u-type-error-light: #fef0f0; --u-type-error-light-rgb: 254, 240, 240; /* 信息色 */ --u-type-info: #909399; --u-type-info-rgb: 144, 147, 153; --u-type-info-disabled: #c8c9cc; --u-type-info-disabled-rgb: 200, 201, 204; --u-type-info-dark: #82848a; --u-type-info-dark-rgb: 130, 132, 138; --u-type-info-light: #f4f4f5; --u-type-info-light-rgb: 244, 244, 245; } // 纯色 $u-white-color: var(--u-white-color); $u-black-color: var(--u-black-color); // 字体色 $u-main-color: var(--u-main-color); $u-content-color: var(--u-content-color); $u-tips-color: var(--u-tips-color); $u-light-color: var(--u-light-color); // 边框色 $u-border-color: var(--u-border-color); $u-divider-color: var(--u-divider-color); // 遮罩色 $u-mask-color: var(--u-mask-color); $u-shadow-color: var(--u-shadow-color); // 背景色 $u-bg-color: var(--u-bg-color); $u-bg-white: var(--u-bg-white); $u-bg-gray-light: var(--u-bg-gray-light); $u-bg-gray-dark: var(--u-bg-gray-dark); $u-bg-black: var(--u-bg-black); // 主色 $u-type-primary: var(--u-type-primary); $u-type-primary-light: var(--u-type-primary-light); $u-type-primary-disabled: var(--u-type-primary-disabled); $u-type-primary-dark: var(--u-type-primary-dark); // 警告色 $u-type-warning: var(--u-type-warning); $u-type-warning-disabled: var(--u-type-warning-disabled); $u-type-warning-dark: var(--u-type-warning-dark); $u-type-warning-light: var(--u-type-warning-light); // 成功色 $u-type-success: var(--u-type-success); $u-type-success-disabled: var(--u-type-success-disabled); $u-type-success-dark: var(--u-type-success-dark); $u-type-success-light: var(--u-type-success-light); // 错误色 $u-type-error: var(--u-type-error); $u-type-error-disabled: var(--u-type-error-disabled); $u-type-error-dark: var(--u-type-error-dark); $u-type-error-light: var(--u-type-error-light); // 信息色 $u-type-info: var(--u-type-info); $u-type-info-disabled: var(--u-type-info-disabled); $u-type-info-dark: var(--u-type-info-dark); $u-type-info-light: var(--u-type-info-light); ================================================ FILE: src/uni_modules/uview-pro/types/components.d.ts ================================================ declare module 'vue' { export interface GlobalComponents { uActionSheet: (typeof import('../components/u-action-sheet/u-action-sheet.vue'))['default']; uActionSheetItem: (typeof import('../components/u-action-sheet-item/u-action-sheet-item.vue'))['default']; uAlertTips: (typeof import('../components/u-alert-tips/u-alert-tips.vue'))['default']; uAvatar: (typeof import('../components/u-avatar/u-avatar.vue'))['default']; uAvatarCropper: (typeof import('../components/u-avatar-cropper/u-avatar-cropper.vue'))['default']; uBackTop: (typeof import('../components/u-back-top/u-back-top.vue'))['default']; uBadge: (typeof import('../components/u-badge/u-badge.vue'))['default']; uButton: (typeof import('../components/u-button/u-button.vue'))['default']; uCalendar: (typeof import('../components/u-calendar/u-calendar.vue'))['default']; uCard: (typeof import('../components/u-card/u-card.vue'))['default']; uCarKeyboard: (typeof import('../components/u-car-keyboard/u-car-keyboard.vue'))['default']; uCellGroup: (typeof import('../components/u-cell-group/u-cell-group.vue'))['default']; uCellItem: (typeof import('../components/u-cell-item/u-cell-item.vue'))['default']; uCheckbox: (typeof import('../components/u-checkbox/u-checkbox.vue'))['default']; uCheckboxGroup: (typeof import('../components/u-checkbox-group/u-checkbox-group.vue'))['default']; uCircleProgress: (typeof import('../components/u-circle-progress/u-circle-progress.vue'))['default']; uCitySelect: (typeof import('../components/u-city-select/u-city-select.vue'))['default']; uCol: (typeof import('../components/u-col/u-col.vue'))['default']; uCollapse: (typeof import('../components/u-collapse/u-collapse.vue'))['default']; uCollapseItem: (typeof import('../components/u-collapse-item/u-collapse-item.vue'))['default']; uColumnNotice: (typeof import('../components/u-column-notice/u-column-notice.vue'))['default']; uCountDown: (typeof import('../components/u-count-down/u-count-down.vue'))['default']; uCountTo: (typeof import('../components/u-count-to/u-count-to.vue'))['default']; uDivider: (typeof import('../components/u-divider/u-divider.vue'))['default']; uDropdown: (typeof import('../components/u-dropdown/u-dropdown.vue'))['default']; uDropdownItem: (typeof import('../components/u-dropdown-item/u-dropdown-item.vue'))['default']; uEmpty: (typeof import('../components/u-empty/u-empty.vue'))['default']; uField: (typeof import('../components/u-field/u-field.vue'))['default']; uForm: (typeof import('../components/u-form/u-form.vue'))['default']; uFormItem: (typeof import('../components/u-form-item/u-form-item.vue'))['default']; uFullScreen: (typeof import('../components/u-full-screen/u-full-screen.vue'))['default']; uGap: (typeof import('../components/u-gap/u-gap.vue'))['default']; uGrid: (typeof import('../components/u-grid/u-grid.vue'))['default']; uGridItem: (typeof import('../components/u-grid-item/u-grid-item.vue'))['default']; uIcon: (typeof import('../components/u-icon/u-icon.vue'))['default']; uImage: (typeof import('../components/u-image/u-image.vue'))['default']; uIndexAnchor: (typeof import('../components/u-index-anchor/u-index-anchor.vue'))['default']; uIndexList: (typeof import('../components/u-index-list/u-index-list.vue'))['default']; uInput: (typeof import('../components/u-input/u-input.vue'))['default']; uKeyboard: (typeof import('../components/u-keyboard/u-keyboard.vue'))['default']; uLazyLoad: (typeof import('../components/u-lazy-load/u-lazy-load.vue'))['default']; uLine: (typeof import('../components/u-line/u-line.vue'))['default']; uLineProgress: (typeof import('../components/u-line-progress/u-line-progress.vue'))['default']; uLink: (typeof import('../components/u-link/u-link.vue'))['default']; uLoadmore: (typeof import('../components/u-loadmore/u-loadmore.vue'))['default']; uLoading: (typeof import('../components/u-loading/u-loading.vue'))['default']; uLoadingPopup: (typeof import('../components/u-loading-popup/u-loading-popup.vue'))['default']; uMask: (typeof import('../components/u-mask/u-mask.vue'))['default']; uMessageInput: (typeof import('../components/u-message-input/u-message-input.vue'))['default']; uModal: (typeof import('../components/u-modal/u-modal.vue'))['default']; uNavbar: (typeof import('../components/u-navbar/u-navbar.vue'))['default']; uNoNetwork: (typeof import('../components/u-no-network/u-no-network.vue'))['default']; uNoticeBar: (typeof import('../components/u-notice-bar/u-notice-bar.vue'))['default']; uNumberBox: (typeof import('../components/u-number-box/u-number-box.vue'))['default']; uNumberKeyboard: (typeof import('../components/u-number-keyboard/u-number-keyboard.vue'))['default']; uPicker: (typeof import('../components/u-picker/u-picker.vue'))['default']; uPopup: (typeof import('../components/u-popup/u-popup.vue'))['default']; uRadio: (typeof import('../components/u-radio/u-radio.vue'))['default']; uRadioGroup: (typeof import('../components/u-radio-group/u-radio-group.vue'))['default']; uRate: (typeof import('../components/u-rate/u-rate.vue'))['default']; uReadMore: (typeof import('../components/u-read-more/u-read-more.vue'))['default']; uRow: (typeof import('../components/u-row/u-row.vue'))['default']; uRowNotice: (typeof import('../components/u-row-notice/u-row-notice.vue'))['default']; uSearch: (typeof import('../components/u-search/u-search.vue'))['default']; uSection: (typeof import('../components/u-section/u-section.vue'))['default']; uSelect: (typeof import('../components/u-select/u-select.vue'))['default']; uSkeleton: (typeof import('../components/u-skeleton/u-skeleton.vue'))['default']; uSlider: (typeof import('../components/u-slider/u-slider.vue'))['default']; uStep: (typeof import('../components/u-steps/u-step.vue'))['default']; uSteps: (typeof import('../components/u-steps/u-steps.vue'))['default']; uSticky: (typeof import('../components/u-sticky/u-sticky.vue'))['default']; uSubsection: (typeof import('../components/u-subsection/u-subsection.vue'))['default']; uSwipeAction: (typeof import('../components/u-swipe-action/u-swipe-action.vue'))['default']; uSwiper: (typeof import('../components/u-swiper/u-swiper.vue'))['default']; uSwitch: (typeof import('../components/u-switch/u-switch.vue'))['default']; uTabbar: (typeof import('../components/u-tabbar/u-tabbar.vue'))['default']; uTable: (typeof import('../components/u-table/u-table.vue'))['default']; uTabs: (typeof import('../components/u-tabs/u-tabs.vue'))['default']; uTabsSwiper: (typeof import('../components/u-tabs-swiper/u-tabs-swiper.vue'))['default']; uTag: (typeof import('../components/u-tag/u-tag.vue'))['default']; uTd: (typeof import('../components/u-td/u-td.vue'))['default']; uTh: (typeof import('../components/u-th/u-th.vue'))['default']; uTimeLine: (typeof import('../components/u-time-line/u-time-line.vue'))['default']; uTimeLineItem: (typeof import('../components/u-time-line-item/u-time-line-item.vue'))['default']; uToast: (typeof import('../components/u-toast/u-toast.vue'))['default']; uTopTips: (typeof import('../components/u-top-tips/u-top-tips.vue'))['default']; uTransition: (typeof import('../components/u-transition/u-transition.vue'))['default']; uTr: (typeof import('../components/u-tr/u-tr.vue'))['default']; uUpload: (typeof import('../components/u-upload/u-upload.vue'))['default']; uVerificationCode: (typeof import('../components/u-verification-code/u-verification-code.vue'))['default']; uWaterfall: (typeof import('../components/u-waterfall/u-waterfall.vue'))['default']; uText: (typeof import('../components/u-text/u-text.vue'))['default']; uRootPortal: (typeof import('../components/u-root-portal/u-root-portal.vue'))['default']; uStatusBar: (typeof import('../components/u-status-bar/u-status-bar.vue'))['default']; uSafeBottom: (typeof import('../components/u-safe-bottom/u-safe-bottom.vue'))['default']; uTextarea: (typeof import('../components/u-textarea/u-textarea.vue'))['default']; uFab: (typeof import('../components/u-fab/u-fab.vue'))['default']; uPagination: (typeof import('../components/u-pagination/u-pagination.vue'))['default']; uConfigProvider: (typeof import('../components/u-config-provider/u-config-provider.vue'))['default']; } } export {}; ================================================ FILE: src/uni_modules/uview-pro/types/global.d.ts ================================================ export type ThemeType = 'primary' | 'info' | 'error' | 'warning' | 'success' | 'default'; export type SizeType = 'default' | 'small' | 'large'; export type ImgMode = 'aspectFit' | 'aspectFill' | 'widthFix' | 'top' | 'bottom' | 'center' | 'scaleToFill'; export type Direction = 'horizontal' | 'vertical'; export type Sex = 'man' | 'woman'; export type Shape = 'circle' | 'square'; export type Effect = 'linear' | 'ease' | 'ease-in' | 'ease-in-out' | 'ease-out' | 'step-start' | 'step-end'; export type TextAlign = 'left' | 'center' | 'right'; export type JustifyType = 'start' | 'end' | 'center' | 'around' | 'between'; export type AlignType = 'top' | 'center' | 'bottom'; export type ScrollDirection = 'row' | 'column'; export type PlayState = 'play' | 'paused'; export type OptionType = { label: string; value: any }; // action-sheet 操作项类型 export type ActionSheetItem = { text: string; subText?: string; color?: string; fontSize?: string | number; disabled?: boolean; }; // action-sheet 底部提示类型 export type ActionSheetTips = { text: string; color?: string; fontSize?: string | number; }; // avatar-cropper 裁剪矩形框的样式 export type AvatarCropperBoundStyle = { lineWidth: number; borderColor: string; mask: string; }; // badge 角标类型 export type BadgeSize = 'default' | 'mini'; // button 按钮类型 export type ButtonType = 'primary' | 'info' | 'error' | 'warning' | 'success' | 'default'; // button 按钮尺寸 export type ButtonSize = SizeType | 'default' | 'medium' | 'mini'; // button 按钮 form-type export type ButtonFormType = '' | 'submit' | 'reset'; // button 按钮 scope export type ButtonScope = 'phoneNumber' | 'userInfo'; // button 按钮open-type export type ButtonOpenType = | 'feedback' | 'share' | 'getUserInfo' | 'contact' | 'getPhoneNumber' | 'launchApp' | 'openSetting' | 'chooseAvatar' | 'getAuthorize' | 'lifestyle' | 'contactShare' | 'openGroupProfile' | 'openGuildProfile' | 'openPublicProfile' | 'shareMessageToFriend' | 'addFriend' | 'addColorSign' | 'addGroupApp' | 'addToFavorites' | 'chooseAddress' | 'chooseInvoiceTitle' | 'login' | 'subscribe' | 'favorite' | 'watchLater' | 'openProfile' | 'agreePrivacyAuthorization'; // calendar 组件 mode export type CalendarMode = 'date' | 'range'; // calendar 农历数据类型定义 export type CalendarLunarItem = { dayCn: string; weekCn: string; monthCn: string; day: number; week: number; month: number; year: number; }; // calendar 事件类型定义,单个日期 export type CalendarChangeDate = { year: number; month: number; day: number; days: number; result: string; week: string; isToday: boolean; lunar: CalendarLunarItem | null; // getLunar 返回类型,建议后续补充具体类型 }; // calendar 事件类型定义,范围选择 export type CalendarChangeRange = { startYear: number; startMonth: number; startDay: number; startDate: string; startWeek: string; endYear: number; endMonth: number; endDay: number; endDate: string; endWeek: string; startLunar: CalendarLunarItem | null; endLunar: CalendarLunarItem | null; }; // CellItem 右侧箭头方向,可选值:right|up|down,默认为right export type CellItemArrowDirection = 'right' | 'up' | 'down'; export type FormRuleItem = { required?: boolean; message?: string; trigger?: string | string[]; min?: number; max?: number; pattern?: RegExp; type?: string; validator?: (rule: any, value: any, callback: any) => boolean; asyncValidator?: (rule: any, value: any, callback: any) => void; fields?: FormRules; defaultField?: FormRuleItem; }; export type FormRules = Record; export type InputType = | 'text' | 'number' | 'idcard' | 'digit' | 'password' | 'textarea' | 'phone' | 'url' | 'email' | 'safe-password' | 'name' | 'nickname' | 'bank-card' | 'tel' | 'select'; export type InputAlign = 'left' | 'center' | 'right'; export type InputConfirmType = 'send' | 'search' | 'next' | 'go' | 'done'; export type InputLabelPosition = 'left' | 'top'; export type TextareaBorder = 'surround' | 'none' | 'bottom'; export type FormErrorType = 'message' | 'border' | 'border-bottom' | 'none' | 'toast'; export type IconLabelPosition = 'left' | 'top' | 'right' | 'bottom'; export type LineDirection = 'row' | 'column'; export type LineBorderStyle = 'solid' | 'dashed' | 'dotted'; export type LoadmoreText = { loadmore: string; loading: string; nomore: string; }; export type LoadmoreStatus = 'loadmore' | 'loading' | 'nomore'; export type LoadmoreIconType = 'circle' | 'flower'; export type MessageInputMode = 'box' | 'bottomLine' | 'middleLine'; export type NumberKeyboardMode = 'number' | 'card'; /** * PickerMode 选择器模式类型 * 模式选择,region-地区类型,time-时间类型,selector-单列模式,multiSelector-多列模 */ export type PickerMode = 'region' | 'time' | 'selector' | 'multiSelector'; /** * PickerParams 选择器参数类型 */ export type PickerParams = { year?: boolean; month?: boolean; day?: boolean; hour?: boolean; minute?: boolean; second?: boolean; province?: boolean; city?: boolean; area?: boolean; timestamp?: boolean; }; export type PopupMode = 'left' | 'right' | 'top' | 'bottom' | 'center' | 'inline'; export type PopupCloseIconPos = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'; // Row水平排列方式,可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`) export type RowJustify = | 'start' | 'flex-start' | 'end' | 'flex-end' | 'center' | 'around' | 'space-around' | 'between' | 'space-between'; // Row垂直对齐方式,可选值为top、center、bottom export type RowAlign = 'top' | 'center' | 'bottom'; // search 组件形状 export type SearchShape = 'round' | 'square'; // select 组件 mode single-column-单列,mutil-column-多列,mutil-column-auto-多列联动 export type SelectMode = 'single-column' | 'mutil-column' | 'mutil-column-auto'; // select 组件 list item export type SelectListItem = { label: string; value: string | number; children?: SelectListItem[]; extra?: any; [key: string]: any; }; // Step 组件 mode export type StepsListItem = { name: string; icon?: string; desc?: string; [key: string]: any; }; // Step 组件 mode export type StepMode = 'dot' | 'number'; // Step 组件 direction export type StepDirection = 'row' | 'column'; // Subsection 组件 list item export type SubsectionListItem = { name: string; width?: number; [key: string]: any; }; // Subsection 组件 mode export type SubsectionMode = 'button' | 'subsection'; // swipeAction 操作项类型 export type SwipeActionOption = { /** 按钮显示的文字 */ text: string; /** 按钮自定义样式 */ style?: Record; }; // swiper 组件 mode export type SwiperMode = 'round' | 'dot' | 'rect' | 'number' | 'none'; // swiper 组件 indicatorPos export type SwiperIndicatorPosition = | 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight'; // tabs 组件 props export type TabsItem = { [key: string]: any; name?: string | number; count?: string | number; hidden?: boolean; }; // tabs-swiper 组件 list item export type TabsSwiperListItem = { [key: string]: any; name?: string | number; count?: string | number; }; // tabs-swiper 组件 autoCenterMode export type TabsSwiperAutoCenterMode = 'window'; // tag 组件 mode export type TagMode = 'light' | 'dark' | 'plain'; // tag 组件 shape export type TagShape = 'square' | 'circle' | 'circleLeft' | 'circleRight'; // tag 组件 size export type TagSize = 'default' | 'mini'; // toast 组件 position export type ToastPosition = 'top' | 'center' | 'bottom'; export type UploadSizeType = 'original' | 'compressed'; export type UploadSourceType = 'album' | 'camera'; /** * 上传文件类型 * @description image-图片, video-视频, file-文件, media-媒体(图片+视频), all-所有文件 */ export type UploadAcceptType = 'image' | 'video' | 'file' | 'media' | 'all'; /** * 上传文件项 */ export interface UploadFileItem { url?: string; path?: string; name?: string; size?: number; type?: string; fileType?: 'image' | 'video' | 'file'; progress?: number; error?: boolean; response?: any; uploadTask?: any; file?: any; thumb?: string; [key: string]: any; } // fab 组件 position export type FabPosition = | 'left-top' | 'right-top' | 'left-bottom' | 'right-bottom' | 'left-center' | 'right-center' | 'top-center' | 'bottom-center'; // fab 组件 direction export type FabDirection = 'top' | 'bottom' | 'left' | 'right'; // fab 组件 gap export type FabGap = Partial>; // Transition 组件 export type TransitionPreset = | 'fade' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'zoom-in' | 'zoom-out'; // Transition 组件 duration export type TransitionDuration = { enter?: number; leave?: number; }; export type ColorType = | 'primary' | 'primaryDark' | 'primaryDisabled' | 'primaryLight' | 'bgColor' | 'bgWhite' | 'bgGrayLight' | 'bgGrayDark' | 'bgBlack' | 'info' | 'infoDark' | 'infoDisabled' | 'infoLight' | 'warning' | 'warningDark' | 'warningDisabled' | 'warningLight' | 'error' | 'errorDark' | 'errorDisabled' | 'errorLight' | 'success' | 'successDark' | 'successDisabled' | 'successLight' | 'mainColor' | 'contentColor' | 'tipsColor' | 'lightColor' | 'borderColor' | 'whiteColor' | 'blackColor' | 'dividerColor' | 'maskColor' | 'shadowColor'; // 自定义主题色 export type ThemeColor = Partial>; export type DarkMode = 'auto' | 'light' | 'dark'; export type Theme = { name: string; label?: string; description?: string; /** * 亮色模式下的令牌(会同步到 $u.color 和 CSS 变量) */ color: Partial; /** * 暗黑模式下的令牌,未提供时回退到 color */ darkColor?: Partial; /** * 需要直接注入的 CSS 变量(亮色) */ css?: Record; /** * 需要直接注入的 CSS 变量(暗黑) */ darkCss?: Record; }; export type Themes = { themes: Theme[]; defaultTheme?: string; defaultDarkMode?: DarkMode; isForce?: boolean; }; export type Locales = { locales: Locale[]; defaultLocale?: string; isForce?: boolean; }; export type Locale = { name: string; [key: string]: any; }; export type DebugMode = 'log' | 'warn' | 'error' | 'info'; export interface UViewProOptions { theme?: ThemeColor | Theme[] | Themes; locale?: string | Locale[] | Locales; debugMode?: boolean | DebugMode | DebugMode[]; // 可扩展更多配置项 } // pagination 组件,分页方向 export type PaginationDirection = 'prev' | 'next'; // pagination 组件,change 参数 export type PaginationChangePayload = { type: PaginationDirection; current: number; }; // tabbar 组件 Item export type TabbarItem = { text?: string; pagePath?: string; iconPath?: string; selectedIconPath?: string; count?: number; isDot?: boolean; customIcon?: boolean | string; midButton?: boolean; iconSize?: string | number; textSize?: string | number; gap?: string | number; /** 自定义宽度,优先级高于自动计算的宽度 */ width?: string | number; }; ================================================ FILE: src/uni_modules/uview-pro/types/ignore-errors.d.ts ================================================ // 忽略 uview-pro 组件库内部的 TypeScript 错误 // 这些错误不影响组件的正常使用和类型提示 // 忽略 WeCropper 相关的类型错误 declare module 'weCropper' { export class WeCropper { constructor(params: any); [key: string]: any; } } // 忽略 base64 模块的类型错误 declare module 'base64' { export function encode(data: any): string; export function decode(data: string): any; } // 忽略其他内部模块的类型错误 declare module 'uview-pro/components/*' { const component: any; export default component; } // 忽略工具函数的类型错误 declare module 'uview-pro/libs/function/*' { const func: any; export default func; } export {}; ================================================ FILE: src/uni_modules/uview-pro/types/index.d.ts ================================================ /// /// import { $u } from '../libs'; // uview-pro 模块类型声明 declare module 'uview-pro' { // 导出安装函数 export function install(): void; } // 全局类型扩展 declare global { interface Uni { $u: typeof $u; } } export {}; ================================================ FILE: src/uni_modules/uview-pro/types/uni-app.d.ts ================================================ // /src/uni_modules/uview-pro/types/uni-app.d.ts // 扩展全局 HTMLAttributes 以支持 uni-app/小程序自定义属性 import 'vue'; declare module 'vue' { export interface GlobalComponents { // UniApp core/native tags view: any; 'scroll-view': any; swiper: any; 'swiper-item': any; image: any; 'rich-text': any; canvas: any; block: any; // Basic HTML shims often used by uni-app compiler text: any; } interface HTMLAttributes { // 支持小程序/uni-app 特有属性 'hover-class'?: string; 'hover-stop-propagation'?: boolean; 'hover-start-time'?: number; 'hover-stay-time'?: number; animation?: string; 'data-*'?: any; catchtap?: (e: any) => void; catchlongpress?: (e: any) => void; catchtouchstart?: (e: any) => void; catchtouchmove?: (e: any) => void; catchtouchend?: (e: any) => void; catchtouchcancel?: (e: any) => void; // 其他常用 uni-app 事件和属性可按需补充 src?: string; } } // 兼容 JSX/TSX 场景 declare global { namespace JSX { interface IntrinsicAttributes { 'hover-class'?: string; 'hover-stop-propagation'?: boolean; 'hover-start-time'?: number; 'hover-stay-time'?: number; animation?: string; 'data-*'?: any; catchtap?: (e: any) => void; catchlongpress?: (e: any) => void; catchtouchstart?: (e: any) => void; catchtouchmove?: (e: any) => void; catchtouchend?: (e: any) => void; catchtouchcancel?: (e: any) => void; src?: string; } interface IntrinsicElements { [elem: string]: any; } } } export {}; ================================================ FILE: src/uni_modules/zero-markdown-view/changelog.md ================================================ ## 3.0.0(2025-07-17) ### 新增 aiMode 模式 ### aiMode模式 优化流式输出以及排版 ## 2.1.0(2025-05-23) - 新增latex公式支持 - 代码块高亮支持增加除js外的语法 - 注意:包体积增加了,建议在分包内使用 ## 2.0.5(2024-04-24) - 流式输出代码块解决方案 ## 2.0.4(2023-12-06) - 长按复制代码改为点击代码块复制 ## 2.0.3(2023-10-30) doc: 文档说明 ## 2.0.2(2023-10-30) - 新增长按复制代码-仅小程序可用 - 新增代码块语言显示 ## 2.0.1(2023-10-27) ##支持vue2,vue3 ## 2.0.0(2022-11-01) 使用mp-html自带的插件,重新生成uniapp包,大幅减少插件体积 ## 1.0.0(2022-09-13) 首次发布 ================================================ FILE: src/uni_modules/zero-markdown-view/components/mp-html/highlight/config.js ================================================ export default { // copyByLongPress: false, // 是否需要长按代码块时显示复制代码内容菜单 copyByClickCode: true, // 点击代码块复制 showLanguageName: true, // 是否在代码块右上角显示语言的名称 // showLineNumber: false // 是否显示行号,需要重新打包mp-html } ================================================ FILE: src/uni_modules/zero-markdown-view/components/mp-html/highlight/index.js ================================================ /** * @fileoverview highlight 插件 * Include prismjs (https://prismjs.com) */ import prism from "./prism.min"; import config from "./config"; import Parser from "../parser"; function Highlight(vm) { this.vm = vm; } Highlight.prototype.onParse = function (node, vm) { if (node.name === "pre") { if (vm.options.editable) { node.attrs.class = (node.attrs.class || "") + " hl-pre"; return; } let i; for (i = node.children.length; i--; ) { if (node.children[i].name === "code") break; } if (i === -1) return; const code = node.children[i]; let className = code.attrs.class + " " + node.attrs.class; i = className.indexOf("language-"); if (i === -1) { i = className.indexOf("lang-"); if (i === -1) { className = "language-text"; i = 9; } else { i += 5; } } else { i += 9; } let j; for (j = i; j < className.length; j++) { if (className[j] === " ") break; } const lang = className.substring(i, j); if (code.children.length) { const text = this.vm.getText(code.children).replace(/&/g, "&"); if (!text) return; if (node.c) { node.c = undefined; } if (prism.languages[lang]) { code.children = new Parser(this.vm).parse( // 加一层 pre 保留空白符 "
" +
            prism
              .highlight(text, prism.languages[lang], lang)
              .replace(/token /g, "hl-") +
            "
" )[0].children; } node.attrs.class = "hl-pre"; code.attrs.class = "hl-code"; code.attrs.style = "display:block;overflow: auto;"; if (config.showLanguageName) { node.children.push({ name: "div", attrs: { class: "hl-language", style: "user-select:none;position:absolute;top:0;right:2px;font-size:10px;", }, children: [ { type: "text", text: lang, }, ], }); } if (config.copyByClickCode) { node.attrs.style += (node.attrs.style || "") + ";user-select:none"; node.attrs["data-content"] = text; node.children.push({ name: "div", attrs: { class: "hl-copy", style: "user-select:none;position:absolute;top:0;right:3px;font-size:10px;", }, // children: [{ // type: 'text', // text: '复制' // }] }); vm.expose(); } if (config.showLineNumber) { const line = text.split("\n").length; const children = []; for (let k = line; k--; ) { children.push({ name: "span", attrs: { class: "span", }, }); } node.children.push({ name: "span", attrs: { class: "line-numbers-rows", }, children, }); } } } }; export default Highlight; ================================================ FILE: src/uni_modules/zero-markdown-view/components/mp-html/latex/index.js ================================================ /** * @fileoverview latex 插件 * katex.min.js来源 https://github.com/rojer95/katex-mini */ import parse from './katex.min' function Latex () { } Latex.prototype.onParse = function (node, vm) { // $...$包裹的内容为latex公式 if (!vm.options.editable && node.type === 'text' && node.text.includes('$')) { const part = node.text.split(/(\${1,2})/) const children = [] let status = 0 for (let i = 0; i < part.length; i++) { if (i % 2 === 0) { // 文本内容 if (part[i]) { if (status === 0) { children.push({ type: 'text', text: part[i] }) } else { if (status === 1) { // 行内公式 const nodes = parse.default(part[i]) children.push({ name: 'span', attrs: {}, l: 'T', f: 'display:inline-block', children: nodes }) } else { // 块公式 const nodes = parse.default(part[i], { displayMode: true }) children.push({ name: 'div', attrs: { style: 'text-align:center' }, children: nodes }) } } } } else { // 分隔符 if (part[i] === '$' && part[i + 2] === '$') { // 行内公式 status = 1 part[i + 2] = '' } else if (part[i] === '$$' && part[i + 2] === '$$') { // 块公式 status = 2 part[i + 2] = '' } else { if (part[i] && part[i] !== '$$') { // 普通$符号 part[i + 1] = part[i] + part[i + 1] } // 重置状态 status = 0 } } } delete node.type delete node.text node.name = 'span' node.attrs = {} node.children = children } } export default Latex ================================================ FILE: src/uni_modules/zero-markdown-view/components/mp-html/markdown/index.js ================================================ /** * @fileoverview markdown 插件 * Include marked (https://github.com/markedjs/marked) * Include github-markdown-css (https://github.com/sindresorhus/github-markdown-css) */ import marked from './marked.min' let index = 0 function Markdown (vm) { this.vm = vm vm._ids = {} } Markdown.prototype.onUpdate = function (content) { if (this.vm.markdown) { return marked(content) } } Markdown.prototype.onParse = function (node, vm) { if (vm.options.markdown) { // 中文 id 需要转换,否则无法跳转 if (vm.options.useAnchor && node.attrs && /[\u4e00-\u9fa5]/.test(node.attrs.id)) { const id = 't' + index++ this.vm._ids[node.attrs.id] = id node.attrs.id = id } if (node.name === 'p' || node.name === 'table' || node.name === 'tr' || node.name === 'th' || node.name === 'td' || node.name === 'blockquote' || node.name === 'pre' || node.name === 'code') { node.attrs.class = `md-${node.name} ${node.attrs.class || ''}` } } } export default Markdown ================================================ FILE: src/uni_modules/zero-markdown-view/components/mp-html/mp-html.vue ================================================ ================================================ FILE: src/uni_modules/zero-markdown-view/components/mp-html/node/node.vue ================================================